@leumas/dynamic
The Dynamic layer — a Studio owner's OWN code, added to their own instance. Three parts behind one /api/dynamic prefix: SSR (register components/pages by local path, compile + server-render them...
@leumas/dynamic — the Dynamic layer
A Studio owner's own code, on the instance they own. Three surfaces behind one /api/dynamic prefix; Studio's Dynamic domain is the UI.
- SSR — register a
.jsx/page/file by local path; compile it, server-render it, serve it to
any locally-connected app (React live+hydrated, a plain HTML page, or anything that speaks HTTP).
- Routers — register express routers, whole servers, static folders or proxy targets; answer on
their mount paths from startup.
- Scripts — a per-user script library: write, edit, run with typed props, sandboxed by default.
Full narrative — the design decisions, the consumer snippets, the traps — lives in shared/services/knowledge/build-knowledge/dynamic-layer.md. This file is the map.
Mounting it
import { createDynamicLayer } from '@leumas/dynamic';
// ONLY inside a caps.fileTools block. See "The one gate" below.
const dynamic = createDynamicLayer({
collStore, requireAuth, requireAdmin: requireRole('admin'),
isAdmin: (req) => hasRole(req, 'admin'),
roots: toolRoots, // the host's path allow-list
allowNative: caps.fileTools,
adapters, workDir, onEvent, logger,
});
app.use('/api/dynamic/ssr', dynamic.publicSsrRouter); // pre-gate: public components only
app.use('/api/dynamic', dynamic.router);
// …after every product route:
app.use((req, res, next) => dynamic.dispatch(req, res, next));
dynamic.start({ legacyReadStore }).catch(() => {});
The one gate
Every part of this engine names a file on the host's disk and then executes it. It must mount only where the caller owns the machine — appliance and dev, never platform or control. The engine does not check that itself, on purpose: a capability check in two places eventually disagrees with itself, and the API is where role lives. pnpm check:dynamic asserts the mount stayed there.
What the engine does enforce, everywhere, with no opt-out:
| Rule | Where |
|---|---|
| every path is inside the registered roots; empty list = refuse everything | src/roots.js assertInsideRoots |
| the compiler re-checks every file it reads, not just the entry | src/index.js onFile |
no mount may shadow /auth, /db, /api, /ws… — refused at registration | src/roots.js assertMountPath |
| every execution is a worker or a child process with a hard timeout | src/ssr/render.js, src/scripts/run.js |
Layout
src/roots.js the ONE path allow-list + the reserved mount prefixes
src/routers/ store.js (4 kinds) · mount.js (one dispatcher) · router.js (CRUD)
src/ssr/ store.js · compile.js (sucrase) · render.js + renderWorker.mjs · embed.js · router.js
src/scripts/ store.js (lmx_scripts, extended) · run.js (LMX | child process) · router.js
client/index.jsx <LeumasComponent> — the React consumer. @leumas/dynamic/client
Collections
| Collection | Writes | Why |
|---|---|---|
dynamic_routers | admin (PLATFORM_COLLECTIONS) | a row imports a module into this process, or spawns a program |
ssr_components | admin (PLATFORM_COLLECTIONS) | the server compiles and renders the file it names |
lmx_scripts | member | shared with the LMX Playground. Privilege is on the RUN, not the write |
Environment
| Var | Effect |
|---|---|
DYNAMIC_ROOTS | extra allowed trees (;-separated; ; only on win32 — see rootsFromEnv) |
DYNAMIC_SCRIPTS_EXEC=1 | allows node/python/shell scripts (still needs admin + caps.fileTools) |
DYNAMIC_SSR_TIMEOUT_MS | render deadline (default 5000, max 30000) |
DYNAMIC_SCRIPTS_TIMEOUT_MS | native script deadline (default 30000, max 300000) |
PYTHON_BIN · POWERSHELL_BIN · SHELL_BIN | interpreter overrides for the native lane |
Proving a change
pnpm check:dynamic # structural
pnpm check:dynamic:selftest # proves each check still fires
pnpm smoke:dynamic # 14 live checks against a booted API