Fix CSSX styling: trampoline wiring + scope-emit!/emitted for adapter-html.sx
Root causes of missing CSSX classes in SSR: 1. _sx_trampoline_fn in sx_primitives.ml was never wired — call_any in HO forms (map/filter/for-each) returned unresolved Thunks, so callbacks like render-lambda-html's param binding never executed. Fixed in bootstrap.py FIXUPS: wire Sx_primitives._sx_trampoline_fn after eval_expr. 2. adapter-html.sx used (emit! ...) and (emitted ...) which are CEK special forms (walk kont for ScopeAccFrame), but scope-push!/scope-pop! use the hashtable. CEK frames and hashtable are two different scope systems. Fixed: adapter uses scope-emit!/scope-emitted (hashtable primitives). 3. env-* operations (env-has?, env-get, env-bind!, env-set!, env-extend, env-merge) only accepted Env type. adapter-html.sx passes Dict as env. Fixed: all env ops go through unwrap_env which handles Dict/Nil. Also: fix merge conflict in sx/sx/geography/index.sx, remove duplicate scope primitives from sx_primitives.ml (sx_server.ml registers them). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-24T01:05:46Z";
|
||||
var SX_VERSION = "2026-03-24T02:21:48Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -520,6 +520,7 @@
|
||||
}
|
||||
PRIMITIVES["scope-emit!"] = scopeEmit;
|
||||
PRIMITIVES["scope-peek"] = scopePeek;
|
||||
PRIMITIVES["scope-emitted"] = sxEmitted;
|
||||
|
||||
// ---- VM stack primitives ----
|
||||
// The VM spec (vm.sx) requires these array-like operations.
|
||||
@@ -540,6 +541,11 @@
|
||||
if (name in PRIMITIVES) return PRIMITIVES[name];
|
||||
throw new Error("VM undefined: " + name);
|
||||
};
|
||||
PRIMITIVES["call-primitive"] = function(name, args) {
|
||||
if (!(name in PRIMITIVES)) throw new Error("VM undefined: " + name);
|
||||
var fn = PRIMITIVES[name];
|
||||
return fn.apply(null, Array.isArray(args) ? args : []);
|
||||
};
|
||||
PRIMITIVES["primitive?"] = function(name) {
|
||||
return name in PRIMITIVES;
|
||||
};
|
||||
@@ -2492,11 +2498,11 @@ PRIMITIVES["serialize"] = serialize;
|
||||
|
||||
// render-to-html
|
||||
var renderToHtml = function(expr, env) { setRenderActiveB(true);
|
||||
return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(expr); if (_m == "number") return (String(expr)); if (_m == "boolean") return (isSxTruthy(expr) ? "true" : "false"); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? "" : renderListToHtml(expr, env)); if (_m == "symbol") return renderValueToHtml(trampoline(evalExpr(expr, env)), env); if (_m == "keyword") return escapeHtml(keywordName(expr)); if (_m == "raw-html") return rawHtmlContent(expr); if (_m == "spread") return (sxEmit("element-attrs", spreadAttrs(expr)), ""); if (_m == "thunk") return renderToHtml(thunkExpr(expr), thunkEnv(expr)); return renderValueToHtml(trampoline(evalExpr(expr, env)), env); })(); };
|
||||
return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(expr); if (_m == "number") return (String(expr)); if (_m == "boolean") return (isSxTruthy(expr) ? "true" : "false"); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? "" : renderListToHtml(expr, env)); if (_m == "symbol") return renderValueToHtml(trampoline(evalExpr(expr, env)), env); if (_m == "keyword") return escapeHtml(keywordName(expr)); if (_m == "raw-html") return rawHtmlContent(expr); if (_m == "spread") return (scopeEmit("element-attrs", spreadAttrs(expr)), ""); if (_m == "thunk") return renderToHtml(thunkExpr(expr), thunkEnv(expr)); return renderValueToHtml(trampoline(evalExpr(expr, env)), env); })(); };
|
||||
PRIMITIVES["render-to-html"] = renderToHtml;
|
||||
|
||||
// render-value-to-html
|
||||
var renderValueToHtml = function(val, env) { return (function() { var _m = typeOf(val); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(val); if (_m == "number") return (String(val)); if (_m == "boolean") return (isSxTruthy(val) ? "true" : "false"); if (_m == "list") return renderListToHtml(val, env); if (_m == "raw-html") return rawHtmlContent(val); if (_m == "spread") return (sxEmit("element-attrs", spreadAttrs(val)), ""); if (_m == "thunk") return renderToHtml(thunkExpr(val), thunkEnv(val)); return escapeHtml((String(val))); })(); };
|
||||
var renderValueToHtml = function(val, env) { return (function() { var _m = typeOf(val); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(val); if (_m == "number") return (String(val)); if (_m == "boolean") return (isSxTruthy(val) ? "true" : "false"); if (_m == "list") return renderListToHtml(val, env); if (_m == "raw-html") return rawHtmlContent(val); if (_m == "spread") return (scopeEmit("element-attrs", spreadAttrs(val)), ""); if (_m == "thunk") return renderToHtml(thunkExpr(val), thunkEnv(val)); return escapeHtml((String(val))); })(); };
|
||||
PRIMITIVES["render-value-to-html"] = renderValueToHtml;
|
||||
|
||||
// RENDER_HTML_FORMS
|
||||
@@ -2624,7 +2630,7 @@ PRIMITIVES["render-html-component"] = renderHtmlComponent;
|
||||
var isVoid = contains(VOID_ELEMENTS, tag);
|
||||
return (isSxTruthy(isVoid) ? (String("<") + String(tag) + String(renderAttrs(attrs)) + String(" />")) : (scopePush("element-attrs", NIL), (function() {
|
||||
var content = join("", map(function(c) { return renderToHtml(c, env); }, children));
|
||||
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(attrs, spreadDict); } }
|
||||
{ var _c = scopeEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(attrs, spreadDict); } }
|
||||
scopePop("element-attrs");
|
||||
return (String("<") + String(tag) + String(renderAttrs(attrs)) + String(">") + String(content) + String("</") + String(tag) + String(">"));
|
||||
})()));
|
||||
@@ -2650,7 +2656,7 @@ PRIMITIVES["render-html-element"] = renderHtmlElement;
|
||||
scopePush("element-attrs", NIL);
|
||||
return (function() {
|
||||
var content = join("", map(function(c) { return renderToHtml(c, env); }, children));
|
||||
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(lakeAttrs, spreadDict); } }
|
||||
{ var _c = scopeEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(lakeAttrs, spreadDict); } }
|
||||
scopePop("element-attrs");
|
||||
return (String("<") + String(lakeTag) + String(renderAttrs(lakeAttrs)) + String(">") + String(content) + String("</") + String(lakeTag) + String(">"));
|
||||
})();
|
||||
@@ -2677,7 +2683,7 @@ PRIMITIVES["render-html-lake"] = renderHtmlLake;
|
||||
scopePush("element-attrs", NIL);
|
||||
return (function() {
|
||||
var content = join("", map(function(c) { return renderToHtml(c, env); }, children));
|
||||
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(marshAttrs, spreadDict); } }
|
||||
{ var _c = scopeEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(marshAttrs, spreadDict); } }
|
||||
scopePop("element-attrs");
|
||||
return (String("<") + String(marshTag) + String(renderAttrs(marshAttrs)) + String(">") + String(content) + String("</") + String(marshTag) + String(">"));
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user