Phase 4: Client-side rendering of :data pages via abstract resolve-page-data
Spec layer (orchestration.sx): - try-client-route now handles :data pages instead of falling back to server - New abstract primitive resolve-page-data(name, params, callback) — platform decides transport (HTTP, IPC, cache, etc) - Extracted swap-rendered-content and resolve-route-target helpers Platform layer (bootstrap_js.py): - resolvePageData() browser implementation: fetches /sx/data/<name>, parses SX response, calls callback. Other hosts provide their own transport. Server layer (pages.py): - evaluate_page_data() evaluates :data expr, serializes result as SX - auto_mount_page_data() mounts /sx/data/ endpoint with per-page auth - _build_pages_sx now computes component deps for all pages (not just pure) Test page at /isomorphism/data-test exercises the full pipeline. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2637,6 +2637,42 @@ PLATFORM_ORCHESTRATION_JS = """
|
||||
}
|
||||
}
|
||||
|
||||
function resolvePageData(pageName, params, callback) {
|
||||
// Platform implementation: fetch page data via HTTP from /sx/data/ endpoint.
|
||||
// The spec only knows about resolve-page-data(name, params, callback) —
|
||||
// this function provides the concrete transport.
|
||||
var url = "/sx/data/" + encodeURIComponent(pageName);
|
||||
if (params && !isNil(params)) {
|
||||
var qs = [];
|
||||
var ks = Object.keys(params);
|
||||
for (var i = 0; i < ks.length; i++) {
|
||||
var v = params[ks[i]];
|
||||
if (v !== null && v !== undefined && v !== NIL) {
|
||||
qs.push(encodeURIComponent(ks[i]) + "=" + encodeURIComponent(v));
|
||||
}
|
||||
}
|
||||
if (qs.length) url += "?" + qs.join("&");
|
||||
}
|
||||
var headers = { "SX-Request": "true" };
|
||||
fetch(url, { headers: headers }).then(function(resp) {
|
||||
if (!resp.ok) {
|
||||
logWarn("sx:data resolve failed " + resp.status + " for " + pageName);
|
||||
return;
|
||||
}
|
||||
return resp.text().then(function(text) {
|
||||
try {
|
||||
var exprs = parse(text);
|
||||
var data = exprs.length === 1 ? exprs[0] : {};
|
||||
callback(data || {});
|
||||
} catch (e) {
|
||||
logWarn("sx:data parse error for " + pageName + ": " + (e && e.message ? e.message : e));
|
||||
}
|
||||
});
|
||||
}).catch(function(err) {
|
||||
logWarn("sx:data resolve error for " + pageName + ": " + (err && err.message ? err.message : err));
|
||||
});
|
||||
}
|
||||
|
||||
function urlPathname(href) {
|
||||
try {
|
||||
return new URL(href, location.href).pathname;
|
||||
|
||||
Reference in New Issue
Block a user