Add module context access escape hatch

master
Sven Slootweg 4 months ago
parent d83ed1fe0e
commit cbb3bfcec6

@ -18,6 +18,7 @@ const InvalidObject = require("./invalid-object");
// FIXME: recurseDepth, recurseLabel/recurseGoto
// TODO: Internal queries, but only in modules, and only as a last resort
// TODO: Throw a useful error when trying to $make a non-existent type
// TODO: Refactor using stand-alone utility functions
/* Process design:
@ -235,6 +236,7 @@ module.exports = function createDLayer(options) {
let combinedContext = {
... generatedContext,
... context,
$getModuleContext: getModuleContext,
// FIXME: Figure out a way to annotate errors here with the path at which they occurred, *and* make clear that it was an internal property lookup
$getProperty: getProperty,
$getPropertyPath: function (object, propertyPath) {
@ -261,6 +263,17 @@ module.exports = function createDLayer(options) {
let getContextForModule = loaded.makeContextFactory(combinedContext);
function getModuleContext(moduleName) {
// NOTE: This is an escape hatch to access a module's context from outside of that module; you should not normally need this!
if (loaded.nameToID.has(moduleName)) {
let moduleID = loaded.nameToID.get(moduleName);
console.log({moduleName, moduleID});
return getContextForModule(moduleID);
} else {
throw new Error(`No module named '${moduleName}' has been loaded`);
}
}
function getProperty(object, property, args = {}) {
// TODO: Should this allow a single-argument, property-string-only variant for looking up properties on self?
// FIXME: Validatem

@ -104,9 +104,11 @@ function defaultContext() {
module.exports = function (modules) {
// TODO: Eventually replace hand-crafted merging logic with merge-by-template, once it can support this usecase properly(tm)
// TODO: Fix merge-by-template so that reasonable error messages can be generated here, that are actually aware of eg. the conflicting key
// TODO: Disallow modules with duplicate names? This may be necessary to prevent issues with getModuleContext, which provides name-based context access
let types = createTypeTracker();
let typeExtensions = createExtensionTracker();
let nameToID = new Map(); // TODO: Make this a tracker abstraction?
let contextFactories = syncpipe(modules, [
_ => _.map((module) => [ getModuleID(module), module.makeContext ?? defaultContext ]),
@ -118,6 +120,10 @@ module.exports = function (modules) {
}, {});
for (let module of modules) {
if (module.name != null) {
nameToID.set(module.name, getModuleID(module));
}
for (let [ type, factory ] of Object.entries(module.types ?? {})) {
types.add(module, type, factory);
}
@ -133,6 +139,7 @@ module.exports = function (modules) {
root: schema,
types: types.get(),
extensions: typeExtensions.get(),
nameToID: nameToID,
makeContextFactory: function (baseContext) {
let cache = new Map();

Loading…
Cancel
Save