Dynamic IO proxy: derive proxied primitives from component io_refs
Replace hardcoded IO primitive lists on both client and server with data-driven registration. Page registry entries carry :io-deps (list of IO primitive names) instead of :has-io boolean. Client registers proxied IO on demand per page via registerIoDeps(). Server builds allowlist from component analysis. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -344,7 +344,6 @@
|
||||
(log-info (str "sx-browser " SX_VERSION))
|
||||
(init-css-tracking)
|
||||
(init-style-dict)
|
||||
(init-io-primitives)
|
||||
(process-page-scripts)
|
||||
(process-sx-scripts nil)
|
||||
(sx-hydrate-elements nil)
|
||||
|
||||
@@ -385,6 +385,7 @@ class JSEmitter:
|
||||
"try-client-route": "tryClientRoute",
|
||||
"try-eval-content": "tryEvalContent",
|
||||
"try-async-eval-content": "tryAsyncEvalContent",
|
||||
"register-io-deps": "registerIoDeps",
|
||||
"url-pathname": "urlPathname",
|
||||
"bind-inline-handler": "bindInlineHandler",
|
||||
"bind-preload": "bindPreload",
|
||||
@@ -477,7 +478,6 @@ class JSEmitter:
|
||||
"process-sx-scripts": "processSxScripts",
|
||||
"process-component-script": "processComponentScript",
|
||||
"init-style-dict": "initStyleDict",
|
||||
"init-io-primitives": "initIoPrimitives",
|
||||
"SX_VERSION": "SX_VERSION",
|
||||
"boot-init": "bootInit",
|
||||
"resolve-mount-target": "resolveMountTarget",
|
||||
@@ -1733,16 +1733,20 @@ ASYNC_IO_JS = '''
|
||||
});
|
||||
}
|
||||
|
||||
// Register default proxied IO primitives
|
||||
function initIoPrimitives() {
|
||||
var defaults = [
|
||||
"highlight", "current-user", "request-arg", "request-path",
|
||||
"app-url", "asset-url", "config"
|
||||
];
|
||||
for (var i = 0; i < defaults.length; i++) {
|
||||
registerProxiedIo(defaults[i]);
|
||||
// Register IO deps as proxied primitives (idempotent, called per-page)
|
||||
function registerIoDeps(names) {
|
||||
if (!names || !names.length) return;
|
||||
var registered = 0;
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
if (!IO_PRIMITIVES[name]) {
|
||||
registerProxiedIo(name);
|
||||
registered++;
|
||||
}
|
||||
}
|
||||
if (registered > 0) {
|
||||
logInfo("sx:io registered " + registered + " proxied primitives: " + names.join(", "));
|
||||
}
|
||||
logInfo("sx:io registered " + defaults.length + " proxied primitives");
|
||||
}
|
||||
'''
|
||||
|
||||
@@ -3993,6 +3997,7 @@ def public_api_js(has_html, has_sx, has_dom, has_engine, has_orch, has_cssx, has
|
||||
|
||||
if has_dom:
|
||||
api_lines.append(' registerIo: typeof registerIoPrimitive === "function" ? registerIoPrimitive : null,')
|
||||
api_lines.append(' registerIoDeps: typeof registerIoDeps === "function" ? registerIoDeps : null,')
|
||||
api_lines.append(' asyncRender: typeof asyncSxRenderWithEnv === "function" ? asyncSxRenderWithEnv : null,')
|
||||
api_lines.append(' asyncRenderToDom: typeof asyncRenderToDom === "function" ? asyncRenderToDom : null,')
|
||||
api_lines.append(f' _version: "{version}"')
|
||||
|
||||
@@ -648,7 +648,10 @@
|
||||
(do (log-warn (str "sx:route target not found: " target-sel)) false)
|
||||
(if (not (deps-satisfied? match))
|
||||
(do (log-info (str "sx:route deps miss for " page-name)) false)
|
||||
(let ((has-io (get match "has-io")))
|
||||
(let ((io-deps (get match "io-deps"))
|
||||
(has-io (and io-deps (not (empty? io-deps)))))
|
||||
;; Ensure IO deps are registered as proxied primitives
|
||||
(when has-io (register-io-deps io-deps))
|
||||
(if (get match "has-data")
|
||||
;; Data page: check cache, else resolve asynchronously
|
||||
(let ((cache-key (page-data-cache-key page-name params))
|
||||
@@ -1024,6 +1027,8 @@
|
||||
;; (try-eval-content source env) → DOM node or nil (catches eval errors)
|
||||
;; (try-async-eval-content source env callback) → void; async render,
|
||||
;; calls (callback rendered-or-nil). Used for pages with IO deps.
|
||||
;; (register-io-deps names) → void; ensure each IO name is registered
|
||||
;; as a proxied IO primitive on the client. Idempotent.
|
||||
;; (url-pathname href) → extract pathname from URL string
|
||||
;; (resolve-page-data name params cb) → void; resolves data for a named page.
|
||||
;; Platform decides transport (HTTP, cache, IPC, etc). Calls (cb data-dict)
|
||||
|
||||
Reference in New Issue
Block a user