refactor: untangle bootstrapContext into makeConsole/makeLibs/runLibrary
Remove the shared-mutable-state dance where each db library was run in the handler context via `context.sql = x; run; module.exports = null`. Split into three single-purpose functions: - makeConsole(structureId, routeId) — the logs-table-backed console - runLibrary(sql, source, console) — eval one library in its own context - makeLibs(structureId, console) — the require() targets map Libraries are still evaluated eagerly per request (no laziness), and still see `sql` and `console`, so behavior is preserved. Verified the prime db library's top-level console.log still fires on a live request. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d01f1411c5
commit
d34c917ef9
1 changed files with 39 additions and 37 deletions
78
index.js
78
index.js
|
|
@ -83,53 +83,55 @@ async function saveFile(structureId, req, uploadedFile, asset=false) {
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
function bootstrapContext(structureId, routeId, initContext) {
|
// A console whose log() mirrors to stdout and to the structure's logs table.
|
||||||
const allDbInstances = {};
|
function makeConsole(structureId, routeId) {
|
||||||
function getDb(alias) {
|
return {
|
||||||
return allDbInstances[alias];
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo wrap template in data-bliss-edit-template thing since ws can't take us to the editor on a component basis?? maybe...
|
|
||||||
// for now just designing with component approach
|
|
||||||
const eta = model.getTemplater(structureId);
|
|
||||||
const structure = model.getStructure(structureId)
|
|
||||||
const __urlPrefix = structure.route_prefix;
|
|
||||||
|
|
||||||
const libs = { eta, db: getDb, push: webPush, files: { saveFile: (...args) => saveFile(structureId, ...args) } };
|
|
||||||
|
|
||||||
let dbs = model.getDbsForStructure(structureId);
|
|
||||||
let context = vm.createContext({
|
|
||||||
...initContext,
|
|
||||||
require: function (str) {
|
|
||||||
return libs[str];
|
|
||||||
},
|
|
||||||
module: { exports: null },
|
|
||||||
console: {
|
|
||||||
log: function (...content) {
|
log: function (...content) {
|
||||||
content.forEach((c) => console.log(c));
|
content.forEach((c) => console.log(c));
|
||||||
model.createLog(structureId, routeId, inspectArgs(content));
|
model.createLog(structureId, routeId, inspectArgs(content));
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate a db's "library" script with `sql` and `console` bound, returning
|
||||||
|
// its exports. Each library runs in its own context so nothing leaks between dbs.
|
||||||
|
function runLibrary(sql, librarySource, console) {
|
||||||
|
const libContext = vm.createContext({ sql, console, module: { exports: null } });
|
||||||
|
vm.runInContext(librarySource, libContext);
|
||||||
|
return libContext.module.exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `require(name)` targets available to a user handler.
|
||||||
|
function makeLibs(structureId, console) {
|
||||||
|
const dbs = {};
|
||||||
|
for (let appDb of model.getDbsForStructure(structureId)) {
|
||||||
|
const sql = model.getDbInstance(appDb.id);
|
||||||
|
dbs[appDb.alias] = { library: runLibrary(sql, appDb.library, console), sql };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
eta: model.getTemplater(structureId),
|
||||||
|
db: (alias) => dbs[alias],
|
||||||
|
push: webPush,
|
||||||
|
files: { saveFile: (...args) => saveFile(structureId, ...args) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function bootstrapContext(structureId, routeId, initContext) {
|
||||||
|
const structure = model.getStructure(structureId);
|
||||||
|
const console = makeConsole(structureId, routeId);
|
||||||
|
const libs = makeLibs(structureId, console);
|
||||||
|
|
||||||
|
return vm.createContext({
|
||||||
|
...initContext,
|
||||||
|
require: (name) => libs[name],
|
||||||
|
module: { exports: null },
|
||||||
|
console,
|
||||||
vapidPublicKey: vapidPublicKey,
|
vapidPublicKey: vapidPublicKey,
|
||||||
fetch: fetch,
|
fetch: fetch,
|
||||||
clearTimeout: clearTimeout,
|
clearTimeout: clearTimeout,
|
||||||
setTimeout: setTimeout,
|
setTimeout: setTimeout,
|
||||||
route: function (url) {
|
route: makeRoute(structure),
|
||||||
return withPrefix(__urlPrefix, url);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
for (let appDb of dbs) {
|
|
||||||
let dbInstance = model.getDbInstance(appDb.id);
|
|
||||||
context.sql = dbInstance;
|
|
||||||
vm.runInContext(appDb.library, context);
|
|
||||||
allDbInstances[appDb.alias] = {
|
|
||||||
library: context.module.exports,
|
|
||||||
sql: dbInstance,
|
|
||||||
};
|
|
||||||
context.module.exports = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function withPrefix(prefix, url) {
|
function withPrefix(prefix, url) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue