Files
rose-ash/shared/static/scripts/sx-browser.js
giles 7d7de86034
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m54s
Fix stepper client-side [object Object] flash and missing CSSX styles
Three issues in the stepper island's client-side rendering:

1. do-step used eval-expr with empty env for ~cssx/tw spreads — component
   not found, result leaked as [object Object]. Fixed: call ~cssx/tw
   directly (in scope from island env) with trampoline.

2. steps-to-preview excluded spreads — SSR preview had no styling.
   Fixed: include spreads in the tree so both SSR and client render
   with CSSX classes.

3. build-children used named let (let loop ...) which produces
   unresolved Thunks in render mode due to the named-let compiler
   desugaring interacting with the render/eval boundary. Fixed:
   rewrote as plain recursive function bc-loop avoiding named let.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:11:06 +00:00

8340 lines
401 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* sx-ref.js — Generated from reference SX evaluator specification.
*
* Bootstrap-compiled from shared/sx/ref/{eval,render,primitives}.sx
* Compare against hand-written sx.js for correctness verification.
*
* DO NOT EDIT — regenerate with: python bootstrap_js.py
*/
;(function(global) {
"use strict";
// =========================================================================
// Types
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-25T00:09:53Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
function Symbol(name) { this.name = name; }
Symbol.prototype.toString = function() { return this.name; };
Symbol.prototype._sym = true;
function Keyword(name) { this.name = name; }
Keyword.prototype.toString = function() { return ":" + this.name; };
Keyword.prototype._kw = true;
function Lambda(params, body, closure, name) {
this.params = params;
this.body = body;
this.closure = closure || {};
this.name = name || null;
}
Lambda.prototype._lambda = true;
function Component(name, params, hasChildren, body, closure, affinity) {
this.name = name;
this.params = params;
this.hasChildren = hasChildren;
this.body = body;
this.closure = closure || {};
this.affinity = affinity || "auto";
}
Component.prototype._component = true;
function Island(name, params, hasChildren, body, closure) {
this.name = name;
this.params = params;
this.hasChildren = hasChildren;
this.body = body;
this.closure = closure || {};
}
Island.prototype._island = true;
function Macro(params, restParam, body, closure, name) {
this.params = params;
this.restParam = restParam;
this.body = body;
this.closure = closure || {};
this.name = name || null;
}
Macro.prototype._macro = true;
function Thunk(expr, env) { this.expr = expr; this.env = env; }
Thunk.prototype._thunk = true;
function RawHTML(html) { this.html = html; }
RawHTML.prototype._raw = true;
function SxSpread(attrs) { this.attrs = attrs || {}; }
SxSpread.prototype._spread = true;
var _scopeStacks = {};
function isSym(x) { return x != null && x._sym === true; }
function isKw(x) { return x != null && x._kw === true; }
function merge() {
var out = {};
for (var i = 0; i < arguments.length; i++) {
var d = arguments[i];
if (d) for (var k in d) out[k] = d[k];
}
return out;
}
function sxOr() {
for (var i = 0; i < arguments.length; i++) {
if (isSxTruthy(arguments[i])) return arguments[i];
}
return arguments.length ? arguments[arguments.length - 1] : false;
}
// =========================================================================
// Platform interface — JS implementation
// =========================================================================
function typeOf(x) {
if (isNil(x)) return "nil";
if (typeof x === "number") return "number";
if (typeof x === "string") return "string";
if (typeof x === "boolean") return "boolean";
if (x._sym) return "symbol";
if (x._kw) return "keyword";
if (x._thunk) return "thunk";
if (x._lambda) return "lambda";
if (x._component) return "component";
if (x._island) return "island";
if (x._spread) return "spread";
if (x._macro) return "macro";
if (x._raw) return "raw-html";
if (x._sx_expr) return "sx-expr";
if (typeof Node !== "undefined" && x instanceof Node) return "dom-node";
if (Array.isArray(x)) return "list";
if (typeof x === "object") return "dict";
return "unknown";
}
function symbolName(s) { return s.name; }
function keywordName(k) { return k.name; }
function makeSymbol(n) { return new Symbol(n); }
function makeKeyword(n) { return new Keyword(n); }
function makeLambda(params, body, env) { return new Lambda(params, body, env); }
function makeComponent(name, params, hasChildren, body, env, affinity) {
return new Component(name, params, hasChildren, body, env, affinity);
}
function makeMacro(params, restParam, body, env, name) {
return new Macro(params, restParam, body, env, name);
}
function makeThunk(expr, env) { return new Thunk(expr, env); }
function makeSpread(attrs) { return new SxSpread(attrs || {}); }
function isSpread(x) { return x != null && x._spread === true; }
function spreadAttrs(s) { return s && s._spread ? s.attrs : {}; }
function scopePush(name, value) {
if (!_scopeStacks[name]) _scopeStacks[name] = [];
_scopeStacks[name].push({value: value !== undefined ? value : NIL, emitted: [], dedup: false});
}
function scopePop(name) {
if (_scopeStacks[name] && _scopeStacks[name].length) _scopeStacks[name].pop();
}
// Aliases — provide-push!/provide-pop! map to scope-push!/scope-pop!
var providePush = scopePush;
var providePop = scopePop;
function sxContext(name) {
if (_scopeStacks[name] && _scopeStacks[name].length) {
return _scopeStacks[name][_scopeStacks[name].length - 1].value;
}
if (arguments.length > 1) return arguments[1];
throw new Error("No provider for: " + name);
}
function sxEmit(name, value) {
if (_scopeStacks[name] && _scopeStacks[name].length) {
var entry = _scopeStacks[name][_scopeStacks[name].length - 1];
if (entry.dedup && entry.emitted.indexOf(value) !== -1) return NIL;
entry.emitted.push(value);
}
return NIL;
}
function sxEmitted(name) {
if (_scopeStacks[name] && _scopeStacks[name].length) {
return _scopeStacks[name][_scopeStacks[name].length - 1].emitted.slice();
}
return [];
}
function sxCollect(bucket, value) {
if (!_scopeStacks[bucket] || !_scopeStacks[bucket].length) {
if (!_scopeStacks[bucket]) _scopeStacks[bucket] = [];
_scopeStacks[bucket].push({value: NIL, emitted: [], dedup: true});
}
var entry = _scopeStacks[bucket][_scopeStacks[bucket].length - 1];
if (entry.emitted.indexOf(value) === -1) entry.emitted.push(value);
}
function sxCollected(bucket) {
return sxEmitted(bucket);
}
function sxClearCollected(bucket) {
if (_scopeStacks[bucket] && _scopeStacks[bucket].length) {
_scopeStacks[bucket][_scopeStacks[bucket].length - 1].emitted = [];
}
}
function lambdaParams(f) { return f.params; }
function lambdaBody(f) { return f.body; }
function lambdaClosure(f) { return f.closure; }
function lambdaName(f) { return f.name; }
function setLambdaName(f, n) { f.name = n; }
function componentParams(c) { return c.params; }
function componentBody(c) { return c.body; }
function componentClosure(c) { return c.closure; }
function componentHasChildren(c) { return c.hasChildren; }
function componentName(c) { return c.name; }
function componentAffinity(c) { return c.affinity || "auto"; }
function componentParamTypes(c) { return (c && c._paramTypes) ? c._paramTypes : NIL; }
function componentSetParamTypes_b(c, t) { if (c) c._paramTypes = t; return NIL; }
function macroParams(m) { return m.params; }
function macroRestParam(m) { return m.restParam; }
function macroBody(m) { return m.body; }
function macroClosure(m) { return m.closure; }
function isThunk(x) { return x != null && x._thunk === true; }
function thunkExpr(t) { return t.expr; }
function thunkEnv(t) { return t.env; }
function isCallable(x) { return typeof x === "function" || (x != null && x._lambda === true); }
function isLambda(x) { return x != null && x._lambda === true; }
function isComponent(x) { return x != null && x._component === true; }
function isIsland(x) { return x != null && x._island === true; }
function isMacro(x) { return x != null && x._macro === true; }
function isIdentical(a, b) { return a === b; }
// Island platform
function makeIsland(name, params, hasChildren, body, env) {
return new Island(name, params, hasChildren, body, env);
}
// JSON / dict helpers for island state serialization
function jsonSerialize(obj) {
return JSON.stringify(obj);
}
function isEmptyDict(d) {
if (!d || typeof d !== "object") return true;
for (var k in d) if (d.hasOwnProperty(k)) return false;
return true;
}
function envHas(env, name) { return name in env; }
function envGet(env, name) { return env[name]; }
function envBind(env, name, val) {
// Direct property set — creates or overwrites on THIS env only.
// Used by let, define, defcomp, lambda param binding.
env[name] = val;
}
function envSet(env, name, val) {
// Walk prototype chain to find where the variable is defined (for set!)
var obj = env;
while (obj !== null && obj !== Object.prototype) {
if (obj.hasOwnProperty(name)) { obj[name] = val; return; }
obj = Object.getPrototypeOf(obj);
}
// Not found in any parent scope — set on the immediate env
env[name] = val;
}
function envExtend(env) { return Object.create(env); }
function envMerge(base, overlay) {
// Same env or overlay is descendant of base — just extend, no copy.
// This prevents set! inside lambdas from modifying shadow copies.
if (base === overlay) return Object.create(base);
var p = overlay;
for (var d = 0; p && p !== Object.prototype && d < 100; d++) {
if (p === base) return Object.create(base);
p = Object.getPrototypeOf(p);
}
// General case: extend base, copy ONLY overlay properties that don't
// exist in the base chain (avoids shadowing closure bindings).
var child = Object.create(base);
if (overlay) {
for (var k in overlay) {
if (overlay.hasOwnProperty(k) && !(k in base)) child[k] = overlay[k];
}
}
return child;
}
function dictSet(d, k, v) { d[k] = v; return v; }
function dictGet(d, k) { var v = d[k]; return v !== undefined ? v : NIL; }
// Render-expression detection — lets the evaluator delegate to the active adapter.
// Matches HTML tags, SVG tags, <>, raw!, ~components, html: prefix, custom elements.
// Placeholder — overridden by transpiled version from render.sx
function isRenderExpr(expr) { return false; }
// Render dispatch — call the active adapter's render function.
// Set by each adapter when loaded; defaults to identity (no rendering).
var _renderExprFn = null;
// Render mode flag — set by render-to-html/aser, checked by eval-list.
// When false, render expressions fall through to evalCall.
var _renderMode = false;
function renderActiveP() { return _renderMode; }
function setRenderActiveB(val) { _renderMode = !!val; }
function renderExpr(expr, env) {
if (_renderExprFn) return _renderExprFn(expr, env);
// No adapter loaded — fall through to evalCall
return evalCall(first(expr), rest(expr), env);
}
function stripPrefix(s, prefix) {
return s.indexOf(prefix) === 0 ? s.slice(prefix.length) : s;
}
function error(msg) { throw new Error(msg); }
function inspect(x) { return JSON.stringify(x); }
function debugLog() { console.error.apply(console, ["[sx-debug]"].concat(Array.prototype.slice.call(arguments))); }
// =========================================================================
// Primitives
// =========================================================================
var PRIMITIVES = {};
// core.arithmetic
PRIMITIVES["+"] = function() { var s = 0; for (var i = 0; i < arguments.length; i++) s += arguments[i]; return s; };
PRIMITIVES["-"] = function(a, b) { return arguments.length === 1 ? -a : a - b; };
PRIMITIVES["*"] = function() { var s = 1; for (var i = 0; i < arguments.length; i++) s *= arguments[i]; return s; };
PRIMITIVES["/"] = function(a, b) { return a / b; };
PRIMITIVES["mod"] = function(a, b) { return a % b; };
PRIMITIVES["inc"] = function(n) { return n + 1; };
PRIMITIVES["dec"] = function(n) { return n - 1; };
PRIMITIVES["abs"] = Math.abs;
PRIMITIVES["floor"] = Math.floor;
PRIMITIVES["ceil"] = Math.ceil;
PRIMITIVES["round"] = function(x, n) {
if (n === undefined || n === 0) return Math.round(x);
var f = Math.pow(10, n); return Math.round(x * f) / f;
};
PRIMITIVES["min"] = Math.min;
PRIMITIVES["max"] = Math.max;
PRIMITIVES["sqrt"] = Math.sqrt;
PRIMITIVES["pow"] = Math.pow;
PRIMITIVES["clamp"] = function(x, lo, hi) { return Math.max(lo, Math.min(hi, x)); };
// core.comparison
PRIMITIVES["="] = function(a, b) { return a === b; };
PRIMITIVES["!="] = function(a, b) { return a !== b; };
PRIMITIVES["<"] = function(a, b) { return a < b; };
PRIMITIVES[">"] = function(a, b) { return a > b; };
PRIMITIVES["<="] = function(a, b) { return a <= b; };
PRIMITIVES[">="] = function(a, b) { return a >= b; };
// core.logic
PRIMITIVES["not"] = function(x) { return !isSxTruthy(x); };
// core.predicates
PRIMITIVES["nil?"] = isNil;
PRIMITIVES["number?"] = function(x) { return typeof x === "number"; };
PRIMITIVES["string?"] = function(x) { return typeof x === "string"; };
PRIMITIVES["list?"] = Array.isArray;
PRIMITIVES["dict?"] = function(x) { return x !== null && typeof x === "object" && !Array.isArray(x) && !x._sym && !x._kw; };
PRIMITIVES["empty?"] = function(c) { return isNil(c) || (Array.isArray(c) ? c.length === 0 : typeof c === "string" ? c.length === 0 : Object.keys(c).length === 0); };
PRIMITIVES["contains?"] = function(c, k) {
if (typeof c === "string") return c.indexOf(String(k)) !== -1;
if (Array.isArray(c)) return c.indexOf(k) !== -1;
return k in c;
};
PRIMITIVES["odd?"] = function(n) { return n % 2 !== 0; };
PRIMITIVES["even?"] = function(n) { return n % 2 === 0; };
PRIMITIVES["zero?"] = function(n) { return n === 0; };
PRIMITIVES["boolean?"] = function(x) { return x === true || x === false; };
PRIMITIVES["symbol?"] = function(x) { return x != null && x._sym === true; };
PRIMITIVES["keyword?"] = function(x) { return x != null && x._kw === true; };
PRIMITIVES["component-affinity"] = componentAffinity;
// core.strings
PRIMITIVES["str"] = function() {
var p = [];
for (var i = 0; i < arguments.length; i++) {
var v = arguments[i]; if (isNil(v)) continue; p.push(String(v));
}
return p.join("");
};
PRIMITIVES["upper"] = function(s) { return String(s).toUpperCase(); };
PRIMITIVES["lower"] = function(s) { return String(s).toLowerCase(); };
PRIMITIVES["trim"] = function(s) { return String(s).trim(); };
PRIMITIVES["split"] = function(s, sep) { return String(s).split(sep || " "); };
PRIMITIVES["join"] = function(sep, coll) { return coll.join(sep); };
PRIMITIVES["replace"] = function(s, old, nw) { return s.split(old).join(nw); };
PRIMITIVES["index-of"] = function(s, needle, from) { return String(s).indexOf(needle, from || 0); };
PRIMITIVES["starts-with?"] = function(s, p) { return String(s).indexOf(p) === 0; };
PRIMITIVES["ends-with?"] = function(s, p) { var str = String(s); return str.indexOf(p, str.length - p.length) !== -1; };
PRIMITIVES["slice"] = function(c, a, b) { if (!c || typeof c.slice !== "function") { console.error("[sx-debug] slice called on non-sliceable:", typeof c, c, "a=", a, "b=", b, new Error().stack); return []; } return b !== undefined ? c.slice(a, b) : c.slice(a); };
PRIMITIVES["substring"] = function(s, a, b) { return String(s).substring(a, b); };
PRIMITIVES["char-from-code"] = function(n) { return String.fromCharCode(n); };
PRIMITIVES["string-length"] = function(s) { return String(s).length; };
var stringLength = PRIMITIVES["string-length"];
PRIMITIVES["string-contains?"] = function(s, sub) { return String(s).indexOf(String(sub)) !== -1; };
PRIMITIVES["concat"] = function() {
var out = [];
for (var i = 0; i < arguments.length; i++) if (!isNil(arguments[i])) out = out.concat(arguments[i]);
return out;
};
// core.collections
PRIMITIVES["list"] = function() { return Array.prototype.slice.call(arguments); };
PRIMITIVES["dict"] = function() {
var d = {};
for (var i = 0; i < arguments.length - 1; i += 2) d[arguments[i]] = arguments[i + 1];
return d;
};
PRIMITIVES["range"] = function(a, b, step) {
var r = []; step = step || 1;
for (var i = a; step > 0 ? i < b : i > b; i += step) r.push(i);
return r;
};
PRIMITIVES["get"] = function(c, k, def) { var v = (c && c[k]); return v !== undefined ? v : (def !== undefined ? def : NIL); };
PRIMITIVES["len"] = function(c) { return Array.isArray(c) ? c.length : typeof c === "string" ? c.length : Object.keys(c).length; };
PRIMITIVES["first"] = function(c) { return c && c.length > 0 ? c[0] : NIL; };
PRIMITIVES["last"] = function(c) { return c && c.length > 0 ? c[c.length - 1] : NIL; };
PRIMITIVES["rest"] = function(c) { if (c && typeof c.slice !== "function") { console.error("[sx-debug] rest called on non-sliceable:", typeof c, c, new Error().stack); return []; } return c ? c.slice(1) : []; };
PRIMITIVES["nth"] = function(c, n) { return c && n >= 0 && n < c.length ? c[n] : NIL; };
PRIMITIVES["cons"] = function(x, c) { return [x].concat(c || []); };
PRIMITIVES["append"] = function(c, x) { return (c || []).concat(Array.isArray(x) ? x : [x]); };
PRIMITIVES["append!"] = function(arr, x) { arr.push(x); return arr; };
PRIMITIVES["chunk-every"] = function(c, n) {
var r = []; for (var i = 0; i < c.length; i += n) r.push(c.slice(i, i + n)); return r;
};
PRIMITIVES["zip-pairs"] = function(c) {
var r = []; for (var i = 0; i < c.length - 1; i++) r.push([c[i], c[i + 1]]); return r;
};
PRIMITIVES["reverse"] = function(c) { return Array.isArray(c) ? c.slice().reverse() : String(c).split("").reverse().join(""); };
PRIMITIVES["flatten"] = function(c) {
var out = [];
function walk(a) { for (var i = 0; i < a.length; i++) Array.isArray(a[i]) ? walk(a[i]) : out.push(a[i]); }
walk(c || []); return out;
};
// core.dict
PRIMITIVES["keys"] = function(d) { return Object.keys(d || {}); };
PRIMITIVES["vals"] = function(d) { var r = []; for (var k in d) r.push(d[k]); return r; };
PRIMITIVES["merge"] = function() {
var out = {};
for (var i = 0; i < arguments.length; i++) { var d = arguments[i]; if (d && !isNil(d)) for (var k in d) out[k] = d[k]; }
return out;
};
PRIMITIVES["assoc"] = function(d) {
var out = {}; if (d && !isNil(d)) for (var k in d) out[k] = d[k];
for (var i = 1; i < arguments.length - 1; i += 2) out[arguments[i]] = arguments[i + 1];
return out;
};
PRIMITIVES["dissoc"] = function(d) {
var out = {}; for (var k in d) out[k] = d[k];
for (var i = 1; i < arguments.length; i++) delete out[arguments[i]];
return out;
};
PRIMITIVES["dict-set!"] = function(d, k, v) { d[k] = v; return v; };
PRIMITIVES["has-key?"] = function(d, k) { return d !== null && d !== undefined && k in d; };
PRIMITIVES["into"] = function(target, coll) {
if (Array.isArray(target)) return Array.isArray(coll) ? coll.slice() : Object.entries(coll);
var r = {}; for (var i = 0; i < coll.length; i++) { var p = coll[i]; if (Array.isArray(p) && p.length >= 2) r[p[0]] = p[1]; }
return r;
};
// stdlib.format
PRIMITIVES["format-decimal"] = function(v, p) { return Number(v).toFixed(p || 2); };
PRIMITIVES["parse-int"] = function(v, d) { var n = parseInt(v, 10); return isNaN(n) ? (d || 0) : n; };
PRIMITIVES["format-date"] = function(s, fmt) {
if (!s) return "";
try {
var d = new Date(s);
if (isNaN(d.getTime())) return String(s);
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var short_months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
return fmt.replace(/%-d/g, d.getDate()).replace(/%d/g, ("0"+d.getDate()).slice(-2))
.replace(/%B/g, months[d.getMonth()]).replace(/%b/g, short_months[d.getMonth()])
.replace(/%Y/g, d.getFullYear()).replace(/%m/g, ("0"+(d.getMonth()+1)).slice(-2))
.replace(/%H/g, ("0"+d.getHours()).slice(-2)).replace(/%M/g, ("0"+d.getMinutes()).slice(-2));
} catch (e) { return String(s); }
};
PRIMITIVES["parse-datetime"] = function(s) { return s ? String(s) : NIL; };
// stdlib.text
PRIMITIVES["pluralize"] = function(n, s, p) {
if (s || (p && p !== "s")) return n == 1 ? (s || "") : (p || "s");
return n == 1 ? "" : "s";
};
PRIMITIVES["escape"] = function(s) {
return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;");
};
PRIMITIVES["strip-tags"] = function(s) { return String(s).replace(/<[^>]+>/g, ""); };
// stdlib.debug
PRIMITIVES["assert"] = function(cond, msg) {
if (!isSxTruthy(cond)) throw new Error("Assertion error: " + (msg || "Assertion failed"));
return true;
};
// stdlib.spread — spread + collect + scope primitives
PRIMITIVES["make-spread"] = makeSpread;
PRIMITIVES["spread?"] = isSpread;
PRIMITIVES["spread-attrs"] = spreadAttrs;
PRIMITIVES["collect!"] = sxCollect;
PRIMITIVES["collected"] = sxCollected;
PRIMITIVES["clear-collected!"] = sxClearCollected;
// scope — unified render-time dynamic scope
PRIMITIVES["scope-push!"] = scopePush;
PRIMITIVES["scope-pop!"] = scopePop;
// provide-push!/provide-pop! — aliases for scope-push!/scope-pop!
PRIMITIVES["provide-push!"] = providePush;
PRIMITIVES["provide-pop!"] = providePop;
PRIMITIVES["context"] = sxContext;
PRIMITIVES["emit!"] = sxEmit;
PRIMITIVES["emitted"] = sxEmitted;
// Aliases for aser adapter (avoids CEK special form conflict on server)
var scopeEmit = sxEmit;
function scopePeek(name) {
if (_scopeStacks[name] && _scopeStacks[name].length) {
return _scopeStacks[name][_scopeStacks[name].length - 1].value;
}
return NIL;
}
PRIMITIVES["scope-emit!"] = scopeEmit;
PRIMITIVES["scope-peek"] = scopePeek;
PRIMITIVES["scope-emitted"] = sxEmitted;
PRIMITIVES["scope-collected"] = sxCollected;
PRIMITIVES["scope-clear-collected!"] = sxClearCollected;
// ---- VM stack primitives ----
// The VM spec (vm.sx) requires these array-like operations.
// In JS, a plain Array serves as the stack.
PRIMITIVES["make-vm-stack"] = function(size) {
var a = new Array(size);
for (var i = 0; i < size; i++) a[i] = NIL;
return a;
};
PRIMITIVES["vm-stack-get"] = function(stack, idx) { return stack[idx]; };
PRIMITIVES["vm-stack-set!"] = function(stack, idx, value) { stack[idx] = value; return NIL; };
PRIMITIVES["vm-stack-length"] = function(stack) { return stack.length; };
PRIMITIVES["vm-stack-copy!"] = function(src, dst, count) {
for (var i = 0; i < count; i++) dst[i] = src[i];
return NIL;
};
PRIMITIVES["get-primitive"] = function(name) {
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;
};
PRIMITIVES["set-nth!"] = function(lst, idx, val) {
lst[idx] = val;
return NIL;
};
PRIMITIVES["env-parent"] = function(env) {
if (env && Object.getPrototypeOf(env) !== Object.prototype &&
Object.getPrototypeOf(env) !== null)
return Object.getPrototypeOf(env);
return NIL;
};
function isPrimitive(name) { return name in PRIMITIVES; }
function getPrimitive(name) { return PRIMITIVES[name]; }
// Higher-order helpers used by the transpiled code
function map(fn, coll) { return coll.map(fn); }
function mapIndexed(fn, coll) { return coll.map(function(item, i) { return fn(i, item); }); }
function filter(fn, coll) { return coll.filter(function(x) { return isSxTruthy(fn(x)); }); }
function reduce(fn, init, coll) {
var acc = init;
for (var i = 0; i < coll.length; i++) acc = fn(acc, coll[i]);
return acc;
}
function some(fn, coll) {
for (var i = 0; i < coll.length; i++) { var r = fn(coll[i]); if (isSxTruthy(r)) return r; }
return NIL;
}
function forEach(fn, coll) { for (var i = 0; i < coll.length; i++) fn(coll[i]); return NIL; }
function isEvery(fn, coll) {
for (var i = 0; i < coll.length; i++) { if (!isSxTruthy(fn(coll[i]))) return false; }
return true;
}
function mapDict(fn, d) { var r = {}; for (var k in d) r[k] = fn(k, d[k]); return r; }
// Predicate aliases used by transpiled code
// Both naming conventions: isX (from js-renames) and x_p (from js-mangle of x?)
var isNumber = PRIMITIVES["number?"]; var number_p = isNumber;
var isString = PRIMITIVES["string?"]; var string_p = isString;
var isBoolean = PRIMITIVES["boolean?"]; var boolean_p = isBoolean;
var isDict = PRIMITIVES["dict?"];
var isList = PRIMITIVES["list?"]; var list_p = isList;
var isKeyword = PRIMITIVES["keyword?"]; var keyword_p = isKeyword;
var isSymbol = PRIMITIVES["symbol?"]; var symbol_p = isSymbol;
// List primitives used directly by transpiled code
var len = PRIMITIVES["len"];
var first = PRIMITIVES["first"];
var last = PRIMITIVES["last"];
var rest = PRIMITIVES["rest"];
var nth = PRIMITIVES["nth"];
var cons = PRIMITIVES["cons"];
var append = PRIMITIVES["append"];
var isEmpty = PRIMITIVES["empty?"];
var contains = PRIMITIVES["contains?"];
var startsWith = PRIMITIVES["starts-with?"];
var slice = PRIMITIVES["slice"];
var concat = PRIMITIVES["concat"];
var str = PRIMITIVES["str"];
var join = PRIMITIVES["join"];
var keys = PRIMITIVES["keys"];
var get = PRIMITIVES["get"];
var assoc = PRIMITIVES["assoc"];
var range = PRIMITIVES["range"];
var floor = PRIMITIVES["floor"];
var pow = PRIMITIVES["pow"];
var mod = PRIMITIVES["mod"];
var indexOf_ = PRIMITIVES["index-of"];
var hasKey = PRIMITIVES["has-key?"];
function zip(a, b) { var r = []; for (var i = 0; i < Math.min(a.length, b.length); i++) r.push([a[i], b[i]]); return r; }
function append_b(arr, x) { arr.push(x); return arr; }
var apply = function(f, args) {
if (isLambda(f)) return trampoline(callLambda(f, args, lambdaClosure(f)));
return f.apply(null, args);
};
// Additional primitive aliases used by adapter/engine transpiled code
var split = PRIMITIVES["split"];
var trim = PRIMITIVES["trim"];
var upper = PRIMITIVES["upper"];
var lower = PRIMITIVES["lower"];
var replace_ = function(s, old, nw) { return s.split(old).join(nw); };
var endsWith = PRIMITIVES["ends-with?"];
var parseInt_ = PRIMITIVES["parse-int"];
var dict_fn = PRIMITIVES["dict"];
// HTML rendering helpers
// escape-html and escape-attr are now library functions defined in render.sx
function rawHtmlContent(r) { return r.html; }
function makeRawHtml(s) { return { _raw: true, html: s }; }
function makeSxExpr(s) { return { _sx_expr: true, source: s }; }
function sxExprSource(x) { return x && x.source ? x.source : String(x); }
// Placeholders — overridden by transpiled spec from parser.sx / adapter-sx.sx
function serialize(val) { return String(val); }
function isSpecialForm(n) { return false; }
function isHoForm(n) { return false; }
// -----------------------------------------------------------------------
// Host FFI — the irreducible web platform primitives
// All DOM/browser operations are built on these in web/lib/dom.sx
// -----------------------------------------------------------------------
PRIMITIVES["host-global"] = function(name) {
if (typeof globalThis !== "undefined" && name in globalThis) return globalThis[name];
if (typeof window !== "undefined" && name in window) return window[name];
return NIL;
};
PRIMITIVES["host-get"] = function(obj, prop) {
if (obj == null || obj === NIL) return NIL;
var v = obj[prop];
return v === undefined || v === null ? NIL : v;
};
PRIMITIVES["host-set!"] = function(obj, prop, val) {
if (obj != null && obj !== NIL) obj[prop] = val === NIL ? null : val;
};
PRIMITIVES["host-call"] = function() {
var obj = arguments[0], method = arguments[1];
var args = [];
for (var i = 2; i < arguments.length; i++) {
var a = arguments[i];
args.push(a === NIL ? null : a);
}
if (obj == null || obj === NIL) {
// Global function call
var fn = typeof globalThis !== "undefined" ? globalThis[method] : window[method];
if (typeof fn === "function") return fn.apply(null, args);
return NIL;
}
if (typeof obj[method] === "function") {
try { return obj[method].apply(obj, args); }
catch(e) { return NIL; }
}
return NIL;
};
PRIMITIVES["host-new"] = function() {
var name = arguments[0];
var args = Array.prototype.slice.call(arguments, 1).map(function(a) { return a === NIL ? null : a; });
var Ctor = typeof globalThis !== "undefined" ? globalThis[name] : window[name];
if (typeof Ctor !== "function") return NIL;
// Support 0-4 args (covers all practical cases)
switch (args.length) {
case 0: return new Ctor();
case 1: return new Ctor(args[0]);
case 2: return new Ctor(args[0], args[1]);
case 3: return new Ctor(args[0], args[1], args[2]);
default: return new Ctor(args[0], args[1], args[2], args[3]);
}
};
PRIMITIVES["host-callback"] = function(fn) {
// Wrap SX function/lambda as a native JS callback
if (typeof fn === "function") return fn;
if (fn && fn._type === "lambda") {
return function() {
var a = Array.prototype.slice.call(arguments);
return cekCall(fn, a);
};
}
return function() {};
};
PRIMITIVES["host-typeof"] = function(obj) {
if (obj == null || obj === NIL) return "nil";
if (obj instanceof Element) return "element";
if (obj instanceof Text) return "text";
if (obj instanceof DocumentFragment) return "fragment";
if (obj instanceof Document) return "document";
if (obj instanceof Event) return "event";
if (obj instanceof Promise) return "promise";
if (obj instanceof AbortController) return "abort-controller";
return typeof obj;
};
PRIMITIVES["host-await"] = function(promise, callback) {
if (promise && typeof promise.then === "function") {
var cb = typeof callback === "function" ? callback :
(callback && callback._type === "lambda") ?
function(v) { return cekCall(callback, [v]); } : function() {};
promise.then(cb);
}
};
// Aliases for transpiled dom.sx / browser.sx code (transpiler mangles host-* names)
var hostGlobal = PRIMITIVES["host-global"];
var hostGet = PRIMITIVES["host-get"];
var hostSet = PRIMITIVES["host-set!"];
var hostCall = PRIMITIVES["host-call"];
var hostNew = PRIMITIVES["host-new"];
var hostCallback = PRIMITIVES["host-callback"];
var hostTypeof = PRIMITIVES["host-typeof"];
var hostAwait = PRIMITIVES["host-await"];
// processBindings and evalCond — now specced in render.sx, bootstrapped above
function isDefinitionForm(name) {
return name === "define" || name === "defcomp" || name === "defmacro" ||
name === "defstyle" || name === "defhandler" ||
name === "deftype" || name === "defeffect";
}
function indexOf_(s, ch) {
return typeof s === "string" ? s.indexOf(ch) : -1;
}
function dictHas(d, k) { return d != null && k in d; }
function dictDelete(d, k) { delete d[k]; }
function forEachIndexed(fn, coll) {
for (var i = 0; i < coll.length; i++) fn(i, coll[i]);
return NIL;
}
// =========================================================================
// Performance overrides — evaluator hot path
// =========================================================================
// Override parseKeywordArgs: imperative loop instead of reduce+assoc
parseKeywordArgs = function(rawArgs, env) {
var kwargs = {};
var children = [];
for (var i = 0; i < rawArgs.length; i++) {
var arg = rawArgs[i];
if (arg && arg._kw && (i + 1) < rawArgs.length) {
kwargs[arg.name] = trampoline(evalExpr(rawArgs[i + 1], env));
i++;
} else {
children.push(trampoline(evalExpr(arg, env)));
}
}
return [kwargs, children];
};
// Override callComponent: use prototype chain env, imperative kwarg binding
callComponent = function(comp, rawArgs, env) {
var kwargs = {};
var children = [];
for (var i = 0; i < rawArgs.length; i++) {
var arg = rawArgs[i];
if (arg && arg._kw && (i + 1) < rawArgs.length) {
kwargs[arg.name] = trampoline(evalExpr(rawArgs[i + 1], env));
i++;
} else {
children.push(trampoline(evalExpr(arg, env)));
}
}
var local = Object.create(componentClosure(comp));
for (var k in env) if (env.hasOwnProperty(k)) local[k] = env[k];
var params = componentParams(comp);
for (var j = 0; j < params.length; j++) {
var p = params[j];
local[p] = p in kwargs ? kwargs[p] : NIL;
}
if (componentHasChildren(comp)) {
local["children"] = children;
}
return makeThunk(componentBody(comp), local);
};
// =========================================================================
// Platform: deps module — component dependency analysis
// =========================================================================
function componentDeps(c) {
return c.deps ? c.deps.slice() : [];
}
function componentSetDeps(c, deps) {
c.deps = deps;
}
function componentCssClasses(c) {
return c.cssClasses ? c.cssClasses.slice() : [];
}
function envComponents(env) {
var names = [];
for (var k in env) {
var v = env[k];
if (v && (v._component || v._macro)) names.push(k);
}
return names;
}
function regexFindAll(pattern, source) {
var re = new RegExp(pattern, "g");
var results = [];
var m;
while ((m = re.exec(source)) !== null) {
if (m[1] !== undefined) results.push(m[1]);
else results.push(m[0]);
}
return results;
}
function scanCssClasses(source) {
var classes = {};
var result = [];
var m;
var re1 = /:class\s+"([^"]*)"/g;
while ((m = re1.exec(source)) !== null) {
var parts = m[1].split(/\s+/);
for (var i = 0; i < parts.length; i++) {
if (parts[i] && !classes[parts[i]]) {
classes[parts[i]] = true;
result.push(parts[i]);
}
}
}
var re2 = /:class\s+\(str\s+((?:"[^"]*"\s*)+)\)/g;
while ((m = re2.exec(source)) !== null) {
var re3 = /"([^"]*)"/g;
var m2;
while ((m2 = re3.exec(m[1])) !== null) {
var parts2 = m2[1].split(/\s+/);
for (var j = 0; j < parts2.length; j++) {
if (parts2[j] && !classes[parts2[j]]) {
classes[parts2[j]] = true;
result.push(parts2[j]);
}
}
}
}
var re4 = /;;\s*@css\s+(.+)/g;
while ((m = re4.exec(source)) !== null) {
var parts3 = m[1].split(/\s+/);
for (var k = 0; k < parts3.length; k++) {
if (parts3[k] && !classes[parts3[k]]) {
classes[parts3[k]] = true;
result.push(parts3[k]);
}
}
}
return result;
}
function componentIoRefs(c) {
return c.ioRefs ? c.ioRefs.slice() : [];
}
function componentSetIoRefs(c, refs) {
c.ioRefs = refs;
}
// =========================================================================
// Platform interface — Parser
// =========================================================================
// Character classification derived from the grammar:
// ident-start → [a-zA-Z_~*+\-><=/!?&]
// ident-char → ident-start + [0-9.:\/\#,]
var _identStartRe = /[a-zA-Z_~*+\-><=/!?&]/;
var _identCharRe = /[a-zA-Z0-9_~*+\-><=/!?.:&/#,]/;
function isIdentStart(ch) { return _identStartRe.test(ch); }
function isIdentChar(ch) { return _identCharRe.test(ch); }
function parseNumber(s) { return Number(s); }
function escapeString(s) {
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\t/g, "\\t");
}
function sxExprSource(e) { return typeof e === "string" ? e : (e && e.source ? e.source : String(e)); }
var charFromCode = PRIMITIVES["char-from-code"];
// String/number utilities needed by transpiled spec code (content-hash etc)
PRIMITIVES["char-code-at"] = function(s, i) { return s.charCodeAt(i); };
var charCodeAt = PRIMITIVES["char-code-at"];
PRIMITIVES["to-hex"] = function(n) { return (n >>> 0).toString(16); };
var toHex = PRIMITIVES["to-hex"];
// =========================================================================
// Platform: CEK module — explicit CEK machine
// =========================================================================
// Continuation type — callable as JS function so isCallable/apply work.
// CEK is the canonical evaluator; continuations are always available.
function Continuation(fn) {
var c = function(value) { return fn(value !== undefined ? value : NIL); };
c.fn = fn;
c._continuation = true;
c.call = function(value) { return fn(value !== undefined ? value : NIL); };
return c;
}
PRIMITIVES["continuation?"] = function(x) { return x != null && x._continuation === true; };
// Standalone aliases for primitives used by cek.sx / frames.sx
var inc = PRIMITIVES["inc"];
var dec = PRIMITIVES["dec"];
var zip_pairs = PRIMITIVES["zip-pairs"];
var continuation_p = PRIMITIVES["continuation?"];
function makeCekContinuation(captured, restKont) {
var c = new Continuation(function(v) { return v !== undefined ? v : NIL; });
c._cek_data = {"captured": captured, "rest-kont": restKont};
return c;
}
function continuationData(c) {
return (c && c._cek_data) ? c._cek_data : {};
}
// === Transpiled from evaluator (frames + eval + CEK) ===
// make-cek-state
var makeCekState = function(control, env, kont) { return {"control": control, "env": env, "kont": kont, "value": NIL, "phase": "eval"}; };
PRIMITIVES["make-cek-state"] = makeCekState;
// make-cek-value
var makeCekValue = function(value, env, kont) { return {"control": NIL, "env": env, "kont": kont, "value": value, "phase": "continue"}; };
PRIMITIVES["make-cek-value"] = makeCekValue;
// cek-terminal?
var cekTerminal_p = function(state) { return (isSxTruthy((get(state, "phase") == "continue")) && isEmpty(get(state, "kont"))); };
PRIMITIVES["cek-terminal?"] = cekTerminal_p;
// cek-control
var cekControl = function(s) { return get(s, "control"); };
PRIMITIVES["cek-control"] = cekControl;
// cek-env
var cekEnv = function(s) { return get(s, "env"); };
PRIMITIVES["cek-env"] = cekEnv;
// cek-kont
var cekKont = function(s) { return get(s, "kont"); };
PRIMITIVES["cek-kont"] = cekKont;
// cek-phase
var cekPhase = function(s) { return get(s, "phase"); };
PRIMITIVES["cek-phase"] = cekPhase;
// cek-value
var cekValue = function(s) { return get(s, "value"); };
PRIMITIVES["cek-value"] = cekValue;
// make-if-frame
var makeIfFrame = function(thenExpr, elseExpr, env) { return {"else": elseExpr, "env": env, "type": "if", "then": thenExpr}; };
PRIMITIVES["make-if-frame"] = makeIfFrame;
// make-when-frame
var makeWhenFrame = function(bodyExprs, env) { return {"body": bodyExprs, "env": env, "type": "when"}; };
PRIMITIVES["make-when-frame"] = makeWhenFrame;
// make-begin-frame
var makeBeginFrame = function(remaining, env) { return {"env": env, "type": "begin", "remaining": remaining}; };
PRIMITIVES["make-begin-frame"] = makeBeginFrame;
// make-let-frame
var makeLetFrame = function(name, remaining, body, local) { return {"body": body, "env": local, "type": "let", "remaining": remaining, "name": name}; };
PRIMITIVES["make-let-frame"] = makeLetFrame;
// make-define-frame
var makeDefineFrame = function(name, env, hasEffects, effectList) { return {"env": env, "effect-list": effectList, "has-effects": hasEffects, "type": "define", "name": name}; };
PRIMITIVES["make-define-frame"] = makeDefineFrame;
// make-set-frame
var makeSetFrame = function(name, env) { return {"env": env, "type": "set", "name": name}; };
PRIMITIVES["make-set-frame"] = makeSetFrame;
// make-arg-frame
var makeArgFrame = function(f, evaled, remaining, env, rawArgs, headName) { return {"env": env, "head-name": sxOr(headName, NIL), "evaled": evaled, "type": "arg", "f": f, "remaining": remaining, "raw-args": rawArgs}; };
PRIMITIVES["make-arg-frame"] = makeArgFrame;
// make-call-frame
var makeCallFrame = function(f, args, env) { return {"args": args, "env": env, "type": "call", "f": f}; };
PRIMITIVES["make-call-frame"] = makeCallFrame;
// make-cond-frame
var makeCondFrame = function(remaining, env, scheme_p) { return {"scheme": scheme_p, "env": env, "type": "cond", "remaining": remaining}; };
PRIMITIVES["make-cond-frame"] = makeCondFrame;
// make-case-frame
var makeCaseFrame = function(matchVal, remaining, env) { return {"match-val": matchVal, "env": env, "type": "case", "remaining": remaining}; };
PRIMITIVES["make-case-frame"] = makeCaseFrame;
// make-thread-frame
var makeThreadFrame = function(remaining, env) { return {"env": env, "type": "thread", "remaining": remaining}; };
PRIMITIVES["make-thread-frame"] = makeThreadFrame;
// make-map-frame
var makeMapFrame = function(f, remaining, results, env) { return {"indexed": false, "env": env, "results": results, "type": "map", "f": f, "remaining": remaining}; };
PRIMITIVES["make-map-frame"] = makeMapFrame;
// make-map-indexed-frame
var makeMapIndexedFrame = function(f, remaining, results, env) { return {"indexed": true, "env": env, "results": results, "type": "map", "f": f, "remaining": remaining}; };
PRIMITIVES["make-map-indexed-frame"] = makeMapIndexedFrame;
// make-filter-frame
var makeFilterFrame = function(f, remaining, results, currentItem, env) { return {"current-item": currentItem, "env": env, "results": results, "type": "filter", "f": f, "remaining": remaining}; };
PRIMITIVES["make-filter-frame"] = makeFilterFrame;
// make-reduce-frame
var makeReduceFrame = function(f, remaining, env) { return {"env": env, "type": "reduce", "f": f, "remaining": remaining}; };
PRIMITIVES["make-reduce-frame"] = makeReduceFrame;
// make-for-each-frame
var makeForEachFrame = function(f, remaining, env) { return {"env": env, "type": "for-each", "f": f, "remaining": remaining}; };
PRIMITIVES["make-for-each-frame"] = makeForEachFrame;
// make-some-frame
var makeSomeFrame = function(f, remaining, env) { return {"env": env, "type": "some", "f": f, "remaining": remaining}; };
PRIMITIVES["make-some-frame"] = makeSomeFrame;
// make-every-frame
var makeEveryFrame = function(f, remaining, env) { return {"env": env, "type": "every", "f": f, "remaining": remaining}; };
PRIMITIVES["make-every-frame"] = makeEveryFrame;
// make-scope-frame
var makeScopeFrame = function(name, remaining, env) { return {"env": env, "type": "scope", "remaining": remaining, "name": name}; };
PRIMITIVES["make-scope-frame"] = makeScopeFrame;
// make-provide-frame
var makeProvideFrame = function(name, value, remaining, env) { return {"env": env, "value": value, "type": "provide", "remaining": remaining, "name": name}; };
PRIMITIVES["make-provide-frame"] = makeProvideFrame;
// make-scope-acc-frame
var makeScopeAccFrame = function(name, value, remaining, env) { return {"env": env, "value": sxOr(value, NIL), "type": "scope-acc", "remaining": remaining, "emitted": [], "name": name}; };
PRIMITIVES["make-scope-acc-frame"] = makeScopeAccFrame;
// make-reset-frame
var makeResetFrame = function(env) { return {"env": env, "type": "reset"}; };
PRIMITIVES["make-reset-frame"] = makeResetFrame;
// make-dict-frame
var makeDictFrame = function(remaining, results, env) { return {"env": env, "results": results, "type": "dict", "remaining": remaining}; };
PRIMITIVES["make-dict-frame"] = makeDictFrame;
// make-and-frame
var makeAndFrame = function(remaining, env) { return {"env": env, "type": "and", "remaining": remaining}; };
PRIMITIVES["make-and-frame"] = makeAndFrame;
// make-or-frame
var makeOrFrame = function(remaining, env) { return {"env": env, "type": "or", "remaining": remaining}; };
PRIMITIVES["make-or-frame"] = makeOrFrame;
// make-dynamic-wind-frame
var makeDynamicWindFrame = function(phase, bodyThunk, afterThunk, env) { return {"env": env, "phase": phase, "after-thunk": afterThunk, "type": "dynamic-wind", "body-thunk": bodyThunk}; };
PRIMITIVES["make-dynamic-wind-frame"] = makeDynamicWindFrame;
// make-reactive-reset-frame
var makeReactiveResetFrame = function(env, updateFn, firstRender_p) { return {"first-render": firstRender_p, "update-fn": updateFn, "env": env, "type": "reactive-reset"}; };
PRIMITIVES["make-reactive-reset-frame"] = makeReactiveResetFrame;
// make-deref-frame
var makeDerefFrame = function(env) { return {"env": env, "type": "deref"}; };
PRIMITIVES["make-deref-frame"] = makeDerefFrame;
// make-ho-setup-frame
var makeHoSetupFrame = function(hoType, remainingArgs, evaledArgs, env) { return {"ho-type": hoType, "env": env, "evaled": evaledArgs, "type": "ho-setup", "remaining": remainingArgs}; };
PRIMITIVES["make-ho-setup-frame"] = makeHoSetupFrame;
// frame-type
var frameType = function(f) { return get(f, "type"); };
PRIMITIVES["frame-type"] = frameType;
// kont-push
var kontPush = function(frame, kont) { return cons(frame, kont); };
PRIMITIVES["kont-push"] = kontPush;
// kont-top
var kontTop = function(kont) { return first(kont); };
PRIMITIVES["kont-top"] = kontTop;
// kont-pop
var kontPop = function(kont) { return rest(kont); };
PRIMITIVES["kont-pop"] = kontPop;
// kont-empty?
var kontEmpty_p = function(kont) { return isEmpty(kont); };
PRIMITIVES["kont-empty?"] = kontEmpty_p;
// kont-capture-to-reset
var kontCaptureToReset = function(kont) { var scan = function(k, captured) { return (isSxTruthy(isEmpty(k)) ? error("shift without enclosing reset") : (function() {
var frame = first(k);
return (isSxTruthy(sxOr((frameType(frame) == "reset"), (frameType(frame) == "reactive-reset"))) ? [captured, rest(k)] : scan(rest(k), append(captured, [frame])));
})()); };
PRIMITIVES["scan"] = scan;
return scan(kont, []); };
PRIMITIVES["kont-capture-to-reset"] = kontCaptureToReset;
// kont-find-provide
var kontFindProvide = function(kont, name) { return (isSxTruthy(isEmpty(kont)) ? NIL : (function() {
var frame = first(kont);
return (isSxTruthy((isSxTruthy((frameType(frame) == "provide")) && (get(frame, "name") == name))) ? frame : kontFindProvide(rest(kont), name));
})()); };
PRIMITIVES["kont-find-provide"] = kontFindProvide;
// kont-find-scope-acc
var kontFindScopeAcc = function(kont, name) { return (isSxTruthy(isEmpty(kont)) ? NIL : (function() {
var frame = first(kont);
return (isSxTruthy((isSxTruthy((frameType(frame) == "scope-acc")) && (get(frame, "name") == name))) ? frame : kontFindScopeAcc(rest(kont), name));
})()); };
PRIMITIVES["kont-find-scope-acc"] = kontFindScopeAcc;
// has-reactive-reset-frame?
var hasReactiveResetFrame_p = function(kont) { return (isSxTruthy(isEmpty(kont)) ? false : (isSxTruthy((frameType(first(kont)) == "reactive-reset")) ? true : hasReactiveResetFrame_p(rest(kont)))); };
PRIMITIVES["has-reactive-reset-frame?"] = hasReactiveResetFrame_p;
// kont-capture-to-reactive-reset
var kontCaptureToReactiveReset = function(kont) { var scan = function(k, captured) { return (isSxTruthy(isEmpty(k)) ? error("reactive deref without enclosing reactive-reset") : (function() {
var frame = first(k);
return (isSxTruthy((frameType(frame) == "reactive-reset")) ? [captured, frame, rest(k)] : scan(rest(k), append(captured, [frame])));
})()); };
PRIMITIVES["scan"] = scan;
return scan(kont, []); };
PRIMITIVES["kont-capture-to-reactive-reset"] = kontCaptureToReactiveReset;
// *custom-special-forms*
var _customSpecialForms = {};
PRIMITIVES["*custom-special-forms*"] = _customSpecialForms;
// register-special-form!
var registerSpecialForm = function(name, handler) { return dictSet(_customSpecialForms, name, handler); };
PRIMITIVES["register-special-form!"] = registerSpecialForm;
// *render-check*
var _renderCheck = NIL;
PRIMITIVES["*render-check*"] = _renderCheck;
// *render-fn*
var _renderFn = NIL;
PRIMITIVES["*render-fn*"] = _renderFn;
// trampoline
var trampoline = function(val) { return (function() {
var result = val;
return (isSxTruthy(isThunk(result)) ? trampoline(evalExpr(thunkExpr(result), thunkEnv(result))) : result);
})(); };
PRIMITIVES["trampoline"] = trampoline;
// *strict*
var _strict_ = false;
PRIMITIVES["*strict*"] = _strict_;
// set-strict!
var setStrict_b = function(val) { return (_strict_ = val); };
PRIMITIVES["set-strict!"] = setStrict_b;
// *prim-param-types*
var _primParamTypes_ = NIL;
PRIMITIVES["*prim-param-types*"] = _primParamTypes_;
// set-prim-param-types!
var setPrimParamTypes_b = function(types) { return (_primParamTypes_ = types); };
PRIMITIVES["set-prim-param-types!"] = setPrimParamTypes_b;
// value-matches-type?
var valueMatchesType_p = function(val, expectedType) { return (isSxTruthy((expectedType == "any")) ? true : (isSxTruthy((expectedType == "number")) ? isNumber(val) : (isSxTruthy((expectedType == "string")) ? isString(val) : (isSxTruthy((expectedType == "boolean")) ? boolean_p(val) : (isSxTruthy((expectedType == "nil")) ? isNil(val) : (isSxTruthy((expectedType == "list")) ? isList(val) : (isSxTruthy((expectedType == "dict")) ? isDict(val) : (isSxTruthy((expectedType == "lambda")) ? isLambda(val) : (isSxTruthy((expectedType == "symbol")) ? (typeOf(val) == "symbol") : (isSxTruthy((expectedType == "keyword")) ? (typeOf(val) == "keyword") : (isSxTruthy((isSxTruthy(isString(expectedType)) && endsWith(expectedType, "?"))) ? sxOr(isNil(val), valueMatchesType_p(val, slice(expectedType, 0, (stringLength(expectedType) - 1)))) : true))))))))))); };
PRIMITIVES["value-matches-type?"] = valueMatchesType_p;
// strict-check-args
var strictCheckArgs = function(name, args) { return (isSxTruthy((isSxTruthy(_strict_) && _primParamTypes_)) ? (function() {
var spec = get(_primParamTypes_, name);
return (isSxTruthy(spec) ? (function() {
var positional = get(spec, "positional");
var restType = get(spec, "rest-type");
if (isSxTruthy(positional)) {
{ var _c = mapIndexed(function(i, p) { return [i, p]; }, positional); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; (function() {
var idx = first(pair);
var param = nth(pair, 1);
var pName = first(param);
var pType = nth(param, 1);
return (isSxTruthy((idx < len(args))) ? (function() {
var val = nth(args, idx);
return (isSxTruthy(!isSxTruthy(valueMatchesType_p(val, pType))) ? error((String("Type error: ") + String(name) + String(" expected ") + String(pType) + String(" for param ") + String(pName) + String(", got ") + String(typeOf(val)) + String(" (") + String((String(val))) + String(")"))) : NIL);
})() : NIL);
})(); } }
}
return (isSxTruthy((isSxTruthy(restType) && (len(args) > len(sxOr(positional, []))))) ? forEach(function(pair) { return (function() {
var idx = first(pair);
var val = nth(pair, 1);
return (isSxTruthy(!isSxTruthy(valueMatchesType_p(val, restType))) ? error((String("Type error: ") + String(name) + String(" expected ") + String(restType) + String(" for rest arg ") + String(idx) + String(", got ") + String(typeOf(val)) + String(" (") + String((String(val))) + String(")"))) : NIL);
})(); }, mapIndexed(function(i, v) { return [i, v]; }, slice(args, len(sxOr(positional, []))))) : NIL);
})() : NIL);
})() : NIL); };
PRIMITIVES["strict-check-args"] = strictCheckArgs;
// eval-expr
var evalExpr = function(expr, env) { return NIL; };
PRIMITIVES["eval-expr"] = evalExpr;
// call-lambda
var callLambda = function(f, args, callerEnv) { return (function() {
var params = lambdaParams(f);
var local = envMerge(lambdaClosure(f), callerEnv);
return (isSxTruthy((len(args) > len(params))) ? error((String(sxOr(lambdaName(f), "lambda")) + String(" expects ") + String(len(params)) + String(" args, got ") + String(len(args)))) : (forEach(function(pair) { return envBind(local, first(pair), nth(pair, 1)); }, zip(params, args)), forEach(function(p) { return envBind(local, p, NIL); }, slice(params, len(args))), makeThunk(lambdaBody(f), local)));
})(); };
PRIMITIVES["call-lambda"] = callLambda;
// call-component
var callComponent = function(comp, rawArgs, env) { return (function() {
var parsed = parseKeywordArgs(rawArgs, env);
var kwargs = first(parsed);
var children = nth(parsed, 1);
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, sxOr(dictGet(kwargs, p), NIL)); } }
if (isSxTruthy(componentHasChildren(comp))) {
envBind(local, "children", children);
}
return makeThunk(componentBody(comp), local);
})(); };
PRIMITIVES["call-component"] = callComponent;
// parse-keyword-args
var parseKeywordArgs = function(rawArgs, env) { return (function() {
var kwargs = {};
var children = [];
var i = 0;
reduce(function(state, arg) { return (function() {
var idx = get(state, "i");
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (idx + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((idx + 1) < len(rawArgs)))) ? (dictSet(kwargs, keywordName(arg), trampoline(evalExpr(nth(rawArgs, (idx + 1)), env))), assoc(state, "skip", true, "i", (idx + 1))) : (append_b(children, trampoline(evalExpr(arg, env))), assoc(state, "i", (idx + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, rawArgs);
return [kwargs, children];
})(); };
PRIMITIVES["parse-keyword-args"] = parseKeywordArgs;
// cond-scheme?
var condScheme_p = function(clauses) { return isEvery(function(c) { return (isSxTruthy((typeOf(c) == "list")) && (len(c) == 2)); }, clauses); };
PRIMITIVES["cond-scheme?"] = condScheme_p;
// is-else-clause?
var isElseClause = function(test) { return sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else")))); };
PRIMITIVES["is-else-clause?"] = isElseClause;
// sf-named-let
var sfNamedLet = function(args, env) { return (function() {
var loopName = symbolName(first(args));
var bindings = nth(args, 1);
var body = slice(args, 2);
var params = [];
var inits = [];
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { params.push((isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding)));
return append_b(inits, nth(binding, 1)); }, bindings) : reduce(function(acc, pairIdx) { return (append_b(params, (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)))), append_b(inits, nth(bindings, ((pairIdx * 2) + 1)))); }, NIL, range(0, (len(bindings) / 2))));
return (function() {
var loopBody = (isSxTruthy((len(body) == 1)) ? first(body) : cons(makeSymbol("begin"), body));
var loopFn = makeLambda(params, loopBody, env);
loopFn.name = loopName;
envBind(lambdaClosure(loopFn), loopName, loopFn);
return (function() {
var initVals = map(function(e) { return trampoline(evalExpr(e, env)); }, inits);
return callLambda(loopFn, initVals, env);
})();
})();
})(); };
PRIMITIVES["sf-named-let"] = sfNamedLet;
// sf-lambda
var sfLambda = function(args, env) { return (function() {
var paramsExpr = first(args);
var bodyExprs = rest(args);
var body = (isSxTruthy((len(bodyExprs) == 1)) ? first(bodyExprs) : cons(makeSymbol("begin"), bodyExprs));
var paramNames = map(function(p) { return (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : (isSxTruthy((isSxTruthy((typeOf(p) == "list")) && isSxTruthy((len(p) == 3)) && isSxTruthy((typeOf(nth(p, 1)) == "keyword")) && (keywordName(nth(p, 1)) == "as"))) ? symbolName(first(p)) : p)); }, paramsExpr);
return makeLambda(paramNames, body, env);
})(); };
PRIMITIVES["sf-lambda"] = sfLambda;
// sf-defcomp
var sfDefcomp = function(args, env) { return (function() {
var nameSym = first(args);
var paramsRaw = nth(args, 1);
var body = last(args);
var compName = stripPrefix(symbolName(nameSym), "~");
var parsed = parseCompParams(paramsRaw);
var params = first(parsed);
var hasChildren = nth(parsed, 1);
var paramTypes = nth(parsed, 2);
var affinity = defcompKwarg(args, "affinity", "auto");
return (function() {
var comp = makeComponent(compName, params, hasChildren, body, env, affinity);
var effects = defcompKwarg(args, "effects", NIL);
if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(paramTypes))) && !isSxTruthy(isEmpty(keys(paramTypes)))))) {
componentSetParamTypes_b(comp, paramTypes);
}
if (isSxTruthy(!isSxTruthy(isNil(effects)))) {
(function() {
var effectList = (isSxTruthy((typeOf(effects) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effects) : [(String(effects))]);
var effectAnns = (isSxTruthy(envHas(env, "*effect-annotations*")) ? envGet(env, "*effect-annotations*") : {});
effectAnns[symbolName(nameSym)] = effectList;
return envBind(env, "*effect-annotations*", effectAnns);
})();
}
envBind(env, symbolName(nameSym), comp);
return comp;
})();
})(); };
PRIMITIVES["sf-defcomp"] = sfDefcomp;
// defcomp-kwarg
var defcompKwarg = function(args, key, default_) { return (function() {
var end = (len(args) - 1);
var result = default_;
{ var _c = range(2, end, 1); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(nth(args, i)) == "keyword")) && isSxTruthy((keywordName(nth(args, i)) == key)) && ((i + 1) < end)))) {
(function() {
var val = nth(args, (i + 1));
return (result = (isSxTruthy((typeOf(val) == "keyword")) ? keywordName(val) : val));
})();
} } }
return result;
})(); };
PRIMITIVES["defcomp-kwarg"] = defcompKwarg;
// parse-comp-params
var parseCompParams = function(paramsExpr) { return (function() {
var params = [];
var paramTypes = {};
var hasChildren = false;
var inKey = false;
{ var _c = paramsExpr; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; (isSxTruthy((isSxTruthy((typeOf(p) == "list")) && isSxTruthy((len(p) == 3)) && isSxTruthy((typeOf(first(p)) == "symbol")) && isSxTruthy((typeOf(nth(p, 1)) == "keyword")) && (keywordName(nth(p, 1)) == "as"))) ? (function() {
var name = symbolName(first(p));
var ptype = nth(p, 2);
return (function() {
var typeVal = (isSxTruthy((typeOf(ptype) == "symbol")) ? symbolName(ptype) : ptype);
return (isSxTruthy(!isSxTruthy(hasChildren)) ? (append_b(params, name), dictSet(paramTypes, name, typeVal)) : NIL);
})();
})() : (isSxTruthy((typeOf(p) == "symbol")) ? (function() {
var name = symbolName(p);
return (isSxTruthy((name == "&key")) ? (inKey = true) : (isSxTruthy((name == "&rest")) ? (hasChildren = true) : (isSxTruthy((name == "&children")) ? (hasChildren = true) : (isSxTruthy(hasChildren) ? NIL : (isSxTruthy(inKey) ? append_b(params, name) : append_b(params, name))))));
})() : NIL)); } }
return [params, hasChildren, paramTypes];
})(); };
PRIMITIVES["parse-comp-params"] = parseCompParams;
// sf-defisland
var sfDefisland = function(args, env) { return (function() {
var nameSym = first(args);
var paramsRaw = nth(args, 1);
var body = last(args);
var compName = stripPrefix(symbolName(nameSym), "~");
var parsed = parseCompParams(paramsRaw);
var params = first(parsed);
var hasChildren = nth(parsed, 1);
return (function() {
var island = makeIsland(compName, params, hasChildren, body, env);
envBind(env, symbolName(nameSym), island);
return island;
})();
})(); };
PRIMITIVES["sf-defisland"] = sfDefisland;
// sf-defmacro
var sfDefmacro = function(args, env) { return (function() {
var nameSym = first(args);
var paramsRaw = nth(args, 1);
var body = nth(args, 2);
var parsed = parseMacroParams(paramsRaw);
var params = first(parsed);
var restParam = nth(parsed, 1);
return (function() {
var mac = makeMacro(params, restParam, body, env, symbolName(nameSym));
envBind(env, symbolName(nameSym), mac);
return mac;
})();
})(); };
PRIMITIVES["sf-defmacro"] = sfDefmacro;
// parse-macro-params
var parseMacroParams = function(paramsExpr) { return (function() {
var params = [];
var restParam = NIL;
reduce(function(state, p) { return (isSxTruthy((isSxTruthy((typeOf(p) == "symbol")) && (symbolName(p) == "&rest"))) ? assoc(state, "in-rest", true) : (isSxTruthy(get(state, "in-rest")) ? ((restParam = (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : p)), state) : (append_b(params, (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : p)), state))); }, {["in-rest"]: false}, paramsExpr);
return [params, restParam];
})(); };
PRIMITIVES["parse-macro-params"] = parseMacroParams;
// qq-expand
var qqExpand = function(template, env) { return (isSxTruthy(!isSxTruthy((typeOf(template) == "list"))) ? template : (isSxTruthy(isEmpty(template)) ? [] : (function() {
var head = first(template);
return (isSxTruthy((isSxTruthy((typeOf(head) == "symbol")) && (symbolName(head) == "unquote"))) ? trampoline(evalExpr(nth(template, 1), env)) : reduce(function(result, item) { return (isSxTruthy((isSxTruthy((typeOf(item) == "list")) && isSxTruthy((len(item) == 2)) && isSxTruthy((typeOf(first(item)) == "symbol")) && (symbolName(first(item)) == "splice-unquote"))) ? (function() {
var spliced = trampoline(evalExpr(nth(item, 1), env));
return (isSxTruthy((typeOf(spliced) == "list")) ? concat(result, spliced) : (isSxTruthy(isNil(spliced)) ? result : concat(result, [spliced])));
})() : concat(result, [qqExpand(item, env)])); }, [], template));
})())); };
PRIMITIVES["qq-expand"] = qqExpand;
// sf-letrec
var sfLetrec = function(args, env) { return (function() {
var bindings = first(args);
var body = rest(args);
var local = envExtend(env);
var names = [];
var valExprs = [];
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { return (function() {
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
names.push(vname);
valExprs.push(nth(binding, 1));
return envBind(local, vname, NIL);
})(); }, bindings) : reduce(function(acc, pairIdx) { return (function() {
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
names.push(vname);
valExprs.push(valExpr);
return envBind(local, vname, NIL);
})(); }, NIL, range(0, (len(bindings) / 2))));
(function() {
var values = map(function(e) { return trampoline(evalExpr(e, local)); }, valExprs);
{ var _c = zip(names, values); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; envBind(local, first(pair), nth(pair, 1)); } }
return forEach(function(val) { return (isSxTruthy(isLambda(val)) ? forEach(function(n) { return envBind(lambdaClosure(val), n, envGet(local, n)); }, names) : NIL); }, values);
})();
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
return makeThunk(last(body), local);
})(); };
PRIMITIVES["sf-letrec"] = sfLetrec;
// step-sf-letrec
var stepSfLetrec = function(args, env, kont) { return (function() {
var thk = sfLetrec(args, env);
return makeCekState(thunkExpr(thk), thunkEnv(thk), kont);
})(); };
PRIMITIVES["step-sf-letrec"] = stepSfLetrec;
// sf-dynamic-wind
var sfDynamicWind = function(args, env) { return (function() {
var before = trampoline(evalExpr(first(args), env));
var body = trampoline(evalExpr(nth(args, 1), env));
var after = trampoline(evalExpr(nth(args, 2), env));
return dynamicWindCall(before, body, after, env);
})(); };
PRIMITIVES["sf-dynamic-wind"] = sfDynamicWind;
// sf-scope
var sfScope = function(args, env) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var rest = slice(args, 1);
var val = NIL;
var bodyExprs = NIL;
(isSxTruthy((isSxTruthy((len(rest) >= 2)) && isSxTruthy((typeOf(first(rest)) == "keyword")) && (keywordName(first(rest)) == "value"))) ? ((val = trampoline(evalExpr(nth(rest, 1), env))), (bodyExprs = slice(rest, 2))) : (bodyExprs = rest));
scopePush(name, val);
return (function() {
var result = NIL;
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; result = trampoline(evalExpr(e, env)); } }
scopePop(name);
return result;
})();
})(); };
PRIMITIVES["sf-scope"] = sfScope;
// sf-provide
var sfProvide = function(args, env) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var val = trampoline(evalExpr(nth(args, 1), env));
var bodyExprs = slice(args, 2);
var result = NIL;
scopePush(name, val);
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; result = trampoline(evalExpr(e, env)); } }
scopePop(name);
return result;
})(); };
PRIMITIVES["sf-provide"] = sfProvide;
// expand-macro
var expandMacro = function(mac, rawArgs, env) { return (function() {
var local = envMerge(macroClosure(mac), env);
{ var _c = mapIndexed(function(i, p) { return [p, i]; }, macroParams(mac)); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; envBind(local, first(pair), (isSxTruthy((nth(pair, 1) < len(rawArgs))) ? nth(rawArgs, nth(pair, 1)) : NIL)); } }
if (isSxTruthy(macroRestParam(mac))) {
envBind(local, macroRestParam(mac), slice(rawArgs, len(macroParams(mac))));
}
return trampoline(evalExpr(macroBody(mac), local));
})(); };
PRIMITIVES["expand-macro"] = expandMacro;
// cek-run
var cekRun = function(state) { return (isSxTruthy(cekTerminal_p(state)) ? cekValue(state) : cekRun(cekStep(state))); };
PRIMITIVES["cek-run"] = cekRun;
// cek-step
var cekStep = function(state) { return (isSxTruthy((cekPhase(state) == "eval")) ? stepEval(state) : stepContinue(state)); };
PRIMITIVES["cek-step"] = cekStep;
// step-eval
var stepEval = function(state) { return (function() {
var expr = cekControl(state);
var env = cekEnv(state);
var kont = cekKont(state);
return (function() { var _m = typeOf(expr); if (_m == "number") return makeCekValue(expr, env, kont); if (_m == "string") return makeCekValue(expr, env, kont); if (_m == "boolean") return makeCekValue(expr, env, kont); if (_m == "nil") return makeCekValue(NIL, env, kont); if (_m == "symbol") return (function() {
var name = symbolName(expr);
return (function() {
var val = (isSxTruthy(envHas(env, name)) ? envGet(env, name) : (isSxTruthy(isPrimitive(name)) ? getPrimitive(name) : (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : error((String("Undefined symbol: ") + String(name))))))));
if (isSxTruthy((isSxTruthy(isNil(val)) && startsWith(name, "~")))) {
debugLog("Component not found:", name);
}
return makeCekValue(val, env, kont);
})();
})(); if (_m == "keyword") return makeCekValue(keywordName(expr), env, kont); if (_m == "dict") return (function() {
var ks = keys(expr);
return (isSxTruthy(isEmpty(ks)) ? makeCekValue({}, env, kont) : (function() {
var firstKey = first(ks);
var remainingEntries = [];
{ var _c = rest(ks); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; remainingEntries.push([k, get(expr, k)]); } }
return makeCekState(get(expr, firstKey), env, kontPush(makeDictFrame(remainingEntries, [[firstKey]], env), kont));
})());
})(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? makeCekValue([], env, kont) : stepEvalList(expr, env, kont)); return makeCekValue(expr, env, kont); })();
})(); };
PRIMITIVES["step-eval"] = stepEval;
// step-eval-list
var stepEvalList = function(expr, env, kont) { return (function() {
var head = first(expr);
var args = rest(expr);
return (isSxTruthy(!isSxTruthy(sxOr((typeOf(head) == "symbol"), (typeOf(head) == "lambda"), (typeOf(head) == "list")))) ? (isSxTruthy(isEmpty(expr)) ? makeCekValue([], env, kont) : makeCekState(first(expr), env, kontPush(makeMapFrame(NIL, rest(expr), [], env), kont))) : (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
var name = symbolName(head);
return (isSxTruthy((name == "if")) ? stepSfIf(args, env, kont) : (isSxTruthy((name == "when")) ? stepSfWhen(args, env, kont) : (isSxTruthy((name == "cond")) ? stepSfCond(args, env, kont) : (isSxTruthy((name == "case")) ? stepSfCase(args, env, kont) : (isSxTruthy((name == "and")) ? stepSfAnd(args, env, kont) : (isSxTruthy((name == "or")) ? stepSfOr(args, env, kont) : (isSxTruthy((name == "let")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "let*")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "lambda")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "fn")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "define")) ? stepSfDefine(args, env, kont) : (isSxTruthy((name == "defcomp")) ? makeCekValue(sfDefcomp(args, env), env, kont) : (isSxTruthy((name == "defisland")) ? makeCekValue(sfDefisland(args, env), env, kont) : (isSxTruthy((name == "defmacro")) ? makeCekValue(sfDefmacro(args, env), env, kont) : (isSxTruthy((name == "begin")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "do")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "quote")) ? makeCekValue((isSxTruthy(isEmpty(args)) ? NIL : first(args)), env, kont) : (isSxTruthy((name == "quasiquote")) ? makeCekValue(qqExpand(first(args), env), env, kont) : (isSxTruthy((name == "->")) ? stepSfThreadFirst(args, env, kont) : (isSxTruthy((name == "set!")) ? stepSfSet(args, env, kont) : (isSxTruthy((name == "letrec")) ? stepSfLetrec(args, env, kont) : (isSxTruthy((name == "reset")) ? stepSfReset(args, env, kont) : (isSxTruthy((name == "shift")) ? stepSfShift(args, env, kont) : (isSxTruthy((name == "deref")) ? stepSfDeref(args, env, kont) : (isSxTruthy((name == "scope")) ? stepSfScope(args, env, kont) : (isSxTruthy((name == "provide")) ? stepSfProvide(args, env, kont) : (isSxTruthy((name == "context")) ? stepSfContext(args, env, kont) : (isSxTruthy((name == "emit!")) ? stepSfEmit(args, env, kont) : (isSxTruthy((name == "emitted")) ? stepSfEmitted(args, env, kont) : (isSxTruthy((name == "dynamic-wind")) ? makeCekValue(sfDynamicWind(args, env), env, kont) : (isSxTruthy((name == "map")) ? stepHoMap(args, env, kont) : (isSxTruthy((name == "map-indexed")) ? stepHoMapIndexed(args, env, kont) : (isSxTruthy((name == "filter")) ? stepHoFilter(args, env, kont) : (isSxTruthy((name == "reduce")) ? stepHoReduce(args, env, kont) : (isSxTruthy((name == "some")) ? stepHoSome(args, env, kont) : (isSxTruthy((name == "every?")) ? stepHoEvery(args, env, kont) : (isSxTruthy((name == "for-each")) ? stepHoForEach(args, env, kont) : (isSxTruthy(dictHas(_customSpecialForms, name)) ? makeCekValue((get(_customSpecialForms, name))(args, env), env, kont) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
var mac = envGet(env, name);
return makeCekState(expandMacro(mac, args, env), env, kont);
})() : (isSxTruthy((isSxTruthy(_renderCheck) && _renderCheck(expr, env))) ? makeCekValue(_renderFn(expr, env), env, kont) : stepEvalCall(head, args, env, kont)))))))))))))))))))))))))))))))))))))))));
})() : stepEvalCall(head, args, env, kont)));
})(); };
PRIMITIVES["step-eval-list"] = stepEvalList;
// step-sf-if
var stepSfIf = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeIfFrame(nth(args, 1), (isSxTruthy((len(args) > 2)) ? nth(args, 2) : NIL), env), kont)); };
PRIMITIVES["step-sf-if"] = stepSfIf;
// step-sf-when
var stepSfWhen = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeWhenFrame(rest(args), env), kont)); };
PRIMITIVES["step-sf-when"] = stepSfWhen;
// step-sf-begin
var stepSfBegin = function(args, env, kont) { return (isSxTruthy(isEmpty(args)) ? makeCekValue(NIL, env, kont) : (isSxTruthy((len(args) == 1)) ? makeCekState(first(args), env, kont) : makeCekState(first(args), env, kontPush(makeBeginFrame(rest(args), env), kont)))); };
PRIMITIVES["step-sf-begin"] = stepSfBegin;
// step-sf-let
var stepSfLet = function(args, env, kont) { return (isSxTruthy((typeOf(first(args)) == "symbol")) ? makeCekValue(sfNamedLet(args, env), env, kont) : (function() {
var bindings = first(args);
var body = rest(args);
var local = envExtend(env);
return (isSxTruthy(isEmpty(bindings)) ? stepSfBegin(body, local, kont) : (function() {
var firstBinding = (isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? first(bindings) : [first(bindings), nth(bindings, 1)]);
var restBindings = (isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? rest(bindings) : (function() {
var pairs = [];
reduce(function(acc, i) { return append_b(pairs, [nth(bindings, (i * 2)), nth(bindings, ((i * 2) + 1))]); }, NIL, range(1, (len(bindings) / 2)));
return pairs;
})());
return (function() {
var vname = (isSxTruthy((typeOf(first(firstBinding)) == "symbol")) ? symbolName(first(firstBinding)) : first(firstBinding));
return makeCekState(nth(firstBinding, 1), local, kontPush(makeLetFrame(vname, restBindings, body, local), kont));
})();
})());
})()); };
PRIMITIVES["step-sf-let"] = stepSfLet;
// step-sf-define
var stepSfDefine = function(args, env, kont) { return (function() {
var nameSym = first(args);
var hasEffects = (isSxTruthy((len(args) >= 4)) && isSxTruthy((typeOf(nth(args, 1)) == "keyword")) && (keywordName(nth(args, 1)) == "effects"));
var valIdx = (isSxTruthy((isSxTruthy((len(args) >= 4)) && isSxTruthy((typeOf(nth(args, 1)) == "keyword")) && (keywordName(nth(args, 1)) == "effects"))) ? 3 : 1);
var effectList = (isSxTruthy((isSxTruthy((len(args) >= 4)) && isSxTruthy((typeOf(nth(args, 1)) == "keyword")) && (keywordName(nth(args, 1)) == "effects"))) ? nth(args, 2) : NIL);
return makeCekState(nth(args, valIdx), env, kontPush(makeDefineFrame(symbolName(nameSym), env, hasEffects, effectList), kont));
})(); };
PRIMITIVES["step-sf-define"] = stepSfDefine;
// step-sf-set!
var stepSfSet = function(args, env, kont) { return makeCekState(nth(args, 1), env, kontPush(makeSetFrame(symbolName(first(args)), env), kont)); };
PRIMITIVES["step-sf-set!"] = stepSfSet;
// step-sf-and
var stepSfAnd = function(args, env, kont) { return (isSxTruthy(isEmpty(args)) ? makeCekValue(true, env, kont) : makeCekState(first(args), env, kontPush(makeAndFrame(rest(args), env), kont))); };
PRIMITIVES["step-sf-and"] = stepSfAnd;
// step-sf-or
var stepSfOr = function(args, env, kont) { return (isSxTruthy(isEmpty(args)) ? makeCekValue(false, env, kont) : makeCekState(first(args), env, kontPush(makeOrFrame(rest(args), env), kont))); };
PRIMITIVES["step-sf-or"] = stepSfOr;
// step-sf-cond
var stepSfCond = function(args, env, kont) { return (function() {
var scheme_p = condScheme_p(args);
return (isSxTruthy(scheme_p) ? (isSxTruthy(isEmpty(args)) ? makeCekValue(NIL, env, kont) : (function() {
var clause = first(args);
var test = first(clause);
return (isSxTruthy(isElseClause(test)) ? makeCekState(nth(clause, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, true), kont)));
})()) : (isSxTruthy((len(args) < 2)) ? makeCekValue(NIL, env, kont) : (function() {
var test = first(args);
return (isSxTruthy(isElseClause(test)) ? makeCekState(nth(args, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, false), kont)));
})()));
})(); };
PRIMITIVES["step-sf-cond"] = stepSfCond;
// step-sf-case
var stepSfCase = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeCaseFrame(NIL, rest(args), env), kont)); };
PRIMITIVES["step-sf-case"] = stepSfCase;
// step-sf-thread-first
var stepSfThreadFirst = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeThreadFrame(rest(args), env), kont)); };
PRIMITIVES["step-sf-thread-first"] = stepSfThreadFirst;
// step-sf-lambda
var stepSfLambda = function(args, env, kont) { return makeCekValue(sfLambda(args, env), env, kont); };
PRIMITIVES["step-sf-lambda"] = stepSfLambda;
// step-sf-scope
var stepSfScope = function(args, env, kont) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var restArgs = slice(args, 1);
var val = NIL;
var body = NIL;
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((val = trampoline(evalExpr(nth(restArgs, 1), env))), (body = slice(restArgs, 2))) : (body = restArgs));
return (isSxTruthy(isEmpty(body)) ? makeCekValue(NIL, env, kont) : makeCekState(first(body), env, kontPush(makeScopeAccFrame(name, val, rest(body), env), kont)));
})(); };
PRIMITIVES["step-sf-scope"] = stepSfScope;
// step-sf-provide
var stepSfProvide = function(args, env, kont) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var val = trampoline(evalExpr(nth(args, 1), env));
var body = slice(args, 2);
return (isSxTruthy(isEmpty(body)) ? makeCekValue(NIL, env, kont) : makeCekState(first(body), env, kontPush(makeProvideFrame(name, val, rest(body), env), kont)));
})(); };
PRIMITIVES["step-sf-provide"] = stepSfProvide;
// step-sf-context
var stepSfContext = function(args, env, kont) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var defaultVal = (isSxTruthy((len(args) >= 2)) ? trampoline(evalExpr(nth(args, 1), env)) : NIL);
var frame = kontFindProvide(kont, name);
return makeCekValue((isSxTruthy(isNil(frame)) ? defaultVal : get(frame, "value")), env, kont);
})(); };
PRIMITIVES["step-sf-context"] = stepSfContext;
// step-sf-emit
var stepSfEmit = function(args, env, kont) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var val = trampoline(evalExpr(nth(args, 1), env));
var frame = kontFindScopeAcc(kont, name);
if (isSxTruthy(frame)) {
frame["emitted"] = append(get(frame, "emitted"), [val]);
}
return makeCekValue(NIL, env, kont);
})(); };
PRIMITIVES["step-sf-emit"] = stepSfEmit;
// step-sf-emitted
var stepSfEmitted = function(args, env, kont) { return (function() {
var name = trampoline(evalExpr(first(args), env));
var frame = kontFindScopeAcc(kont, name);
return makeCekValue((isSxTruthy(isNil(frame)) ? [] : get(frame, "emitted")), env, kont);
})(); };
PRIMITIVES["step-sf-emitted"] = stepSfEmitted;
// step-sf-reset
var stepSfReset = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeResetFrame(env), kont)); };
PRIMITIVES["step-sf-reset"] = stepSfReset;
// step-sf-shift
var stepSfShift = function(args, env, kont) { return (function() {
var kName = symbolName(first(args));
var body = nth(args, 1);
var capturedResult = kontCaptureToReset(kont);
var captured = first(capturedResult);
var restKont = nth(capturedResult, 1);
return (function() {
var k = makeCekContinuation(captured, restKont);
return (function() {
var shiftEnv = envExtend(env);
envBind(shiftEnv, kName, k);
return makeCekState(body, shiftEnv, restKont);
})();
})();
})(); };
PRIMITIVES["step-sf-shift"] = stepSfShift;
// step-sf-deref
var stepSfDeref = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeDerefFrame(env), kont)); };
PRIMITIVES["step-sf-deref"] = stepSfDeref;
// cek-call
var cekCall = function(f, args) { return (function() {
var a = (isSxTruthy(isNil(args)) ? [] : args);
return (isSxTruthy(isNil(f)) ? NIL : (isSxTruthy(sxOr(isLambda(f), isCallable(f))) ? cekRun(continueWithCall(f, a, makeEnv(), a, [])) : NIL));
})(); };
PRIMITIVES["cek-call"] = cekCall;
// reactive-shift-deref
var reactiveShiftDeref = function(sig, env, kont) { return (function() {
var scanResult = kontCaptureToReactiveReset(kont);
var capturedFrames = first(scanResult);
var resetFrame = nth(scanResult, 1);
var remainingKont = nth(scanResult, 2);
var updateFn = get(resetFrame, "update-fn");
return (function() {
var subDisposers = [];
return (function() {
var subscriber = function() { { var _c = subDisposers; for (var _i = 0; _i < _c.length; _i++) { var d = _c[_i]; cekCall(d, NIL); } }
subDisposers = [];
return (function() {
var newReset = makeReactiveResetFrame(env, updateFn, false);
var newKont = concat(capturedFrames, [newReset], remainingKont);
return withIslandScope(function(d) { return append_b(subDisposers, d); }, function() { return cekRun(makeCekValue(signalValue(sig), env, newKont)); });
})(); };
signalAddSub(sig, subscriber);
registerInScope(function() { signalRemoveSub(sig, subscriber);
return forEach(function(d) { return cekCall(d, NIL); }, subDisposers); });
return (function() {
var initialKont = concat(capturedFrames, [resetFrame], remainingKont);
return makeCekValue(signalValue(sig), env, initialKont);
})();
})();
})();
})(); };
PRIMITIVES["reactive-shift-deref"] = reactiveShiftDeref;
// step-eval-call
var stepEvalCall = function(head, args, env, kont) { return (function() {
var hname = (isSxTruthy((typeOf(head) == "symbol")) ? symbolName(head) : NIL);
return makeCekState(head, env, kontPush(makeArgFrame(NIL, [], args, env, args, hname), kont));
})(); };
PRIMITIVES["step-eval-call"] = stepEvalCall;
// ho-form-name?
var hoFormName_p = function(name) { return sxOr((name == "map"), (name == "map-indexed"), (name == "filter"), (name == "reduce"), (name == "some"), (name == "every?"), (name == "for-each")); };
PRIMITIVES["ho-form-name?"] = hoFormName_p;
// ho-fn?
var hoFn_p = function(v) { return sxOr(isCallable(v), isLambda(v)); };
PRIMITIVES["ho-fn?"] = hoFn_p;
// ho-swap-args
var hoSwapArgs = function(hoType, evaled) { return (isSxTruthy((hoType == "reduce")) ? (function() {
var a = first(evaled);
var b = nth(evaled, 1);
return (isSxTruthy((isSxTruthy(!isSxTruthy(hoFn_p(a))) && hoFn_p(b))) ? [b, nth(evaled, 2), a] : evaled);
})() : (function() {
var a = first(evaled);
var b = nth(evaled, 1);
return (isSxTruthy((isSxTruthy(!isSxTruthy(hoFn_p(a))) && hoFn_p(b))) ? [b, a] : evaled);
})()); };
PRIMITIVES["ho-swap-args"] = hoSwapArgs;
// ho-setup-dispatch
var hoSetupDispatch = function(hoType, evaled, env, kont) { return (function() {
var ordered = hoSwapArgs(hoType, evaled);
return (function() {
var f = first(ordered);
return (isSxTruthy((hoType == "map")) ? (function() {
var coll = nth(ordered, 1);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue([], env, kont) : continueWithCall(f, [first(coll)], env, [], kontPush(makeMapFrame(f, rest(coll), [], env), kont)));
})() : (isSxTruthy((hoType == "map-indexed")) ? (function() {
var coll = nth(ordered, 1);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue([], env, kont) : continueWithCall(f, [0, first(coll)], env, [], kontPush(makeMapIndexedFrame(f, rest(coll), [], env), kont)));
})() : (isSxTruthy((hoType == "filter")) ? (function() {
var coll = nth(ordered, 1);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue([], env, kont) : continueWithCall(f, [first(coll)], env, [], kontPush(makeFilterFrame(f, rest(coll), [], first(coll), env), kont)));
})() : (isSxTruthy((hoType == "reduce")) ? (function() {
var init = nth(ordered, 1);
var coll = nth(ordered, 2);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue(init, env, kont) : continueWithCall(f, [init, first(coll)], env, [], kontPush(makeReduceFrame(f, rest(coll), env), kont)));
})() : (isSxTruthy((hoType == "some")) ? (function() {
var coll = nth(ordered, 1);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue(false, env, kont) : continueWithCall(f, [first(coll)], env, [], kontPush(makeSomeFrame(f, rest(coll), env), kont)));
})() : (isSxTruthy((hoType == "every")) ? (function() {
var coll = nth(ordered, 1);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue(true, env, kont) : continueWithCall(f, [first(coll)], env, [], kontPush(makeEveryFrame(f, rest(coll), env), kont)));
})() : (isSxTruthy((hoType == "for-each")) ? (function() {
var coll = nth(ordered, 1);
return (isSxTruthy(isEmpty(coll)) ? makeCekValue(NIL, env, kont) : continueWithCall(f, [first(coll)], env, [], kontPush(makeForEachFrame(f, rest(coll), env), kont)));
})() : error((String("Unknown HO type: ") + String(hoType))))))))));
})();
})(); };
PRIMITIVES["ho-setup-dispatch"] = hoSetupDispatch;
// step-ho-map
var stepHoMap = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("map", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-map"] = stepHoMap;
// step-ho-map-indexed
var stepHoMapIndexed = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("map-indexed", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-map-indexed"] = stepHoMapIndexed;
// step-ho-filter
var stepHoFilter = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("filter", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-filter"] = stepHoFilter;
// step-ho-reduce
var stepHoReduce = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("reduce", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-reduce"] = stepHoReduce;
// step-ho-some
var stepHoSome = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("some", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-some"] = stepHoSome;
// step-ho-every
var stepHoEvery = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("every", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-every"] = stepHoEvery;
// step-ho-for-each
var stepHoForEach = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeHoSetupFrame("for-each", rest(args), [], env), kont)); };
PRIMITIVES["step-ho-for-each"] = stepHoForEach;
// step-continue
var stepContinue = function(state) { return (function() {
var value = cekValue(state);
var env = cekEnv(state);
var kont = cekKont(state);
return (isSxTruthy(kontEmpty_p(kont)) ? state : (function() {
var frame = kontTop(kont);
var restK = kontPop(kont);
var ft = frameType(frame);
return (isSxTruthy((ft == "if")) ? (isSxTruthy((isSxTruthy(value) && !isSxTruthy(isNil(value)))) ? makeCekState(get(frame, "then"), get(frame, "env"), restK) : (isSxTruthy(isNil(get(frame, "else"))) ? makeCekValue(NIL, env, restK) : makeCekState(get(frame, "else"), get(frame, "env"), restK))) : (isSxTruthy((ft == "when")) ? (isSxTruthy((isSxTruthy(value) && !isSxTruthy(isNil(value)))) ? (function() {
var body = get(frame, "body");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(body)) ? makeCekValue(NIL, fenv, restK) : (isSxTruthy((len(body) == 1)) ? makeCekState(first(body), fenv, restK) : makeCekState(first(body), fenv, kontPush(makeBeginFrame(rest(body), fenv), restK))));
})() : makeCekValue(NIL, env, restK)) : (isSxTruthy((ft == "begin")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : (isSxTruthy((len(remaining) == 1)) ? makeCekState(first(remaining), fenv, restK) : makeCekState(first(remaining), fenv, kontPush(makeBeginFrame(rest(remaining), fenv), restK))));
})() : (isSxTruthy((ft == "let")) ? (function() {
var name = get(frame, "name");
var remaining = get(frame, "remaining");
var body = get(frame, "body");
var local = get(frame, "env");
envBind(local, name, value);
return (isSxTruthy(isEmpty(remaining)) ? stepSfBegin(body, local, restK) : (function() {
var nextBinding = first(remaining);
var vname = (isSxTruthy((typeOf(first(nextBinding)) == "symbol")) ? symbolName(first(nextBinding)) : first(nextBinding));
return makeCekState(nth(nextBinding, 1), local, kontPush(makeLetFrame(vname, rest(remaining), body, local), restK));
})());
})() : (isSxTruthy((ft == "define")) ? (function() {
var name = get(frame, "name");
var fenv = get(frame, "env");
var hasEffects = get(frame, "has-effects");
var effectList = get(frame, "effect-list");
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
value.name = name;
}
envBind(fenv, name, value);
if (isSxTruthy(hasEffects)) {
(function() {
var effectNames = (isSxTruthy((typeOf(effectList) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effectList) : [(String(effectList))]);
var effectAnns = (isSxTruthy(envHas(fenv, "*effect-annotations*")) ? envGet(fenv, "*effect-annotations*") : {});
effectAnns[name] = effectNames;
return envBind(fenv, "*effect-annotations*", effectAnns);
})();
}
return makeCekValue(value, fenv, restK);
})() : (isSxTruthy((ft == "set")) ? (function() {
var name = get(frame, "name");
var fenv = get(frame, "env");
envSet(fenv, name, value);
return makeCekValue(value, env, restK);
})() : (isSxTruthy((ft == "and")) ? (isSxTruthy(!isSxTruthy(value)) ? makeCekValue(value, env, restK) : (function() {
var remaining = get(frame, "remaining");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, env, restK) : makeCekState(first(remaining), get(frame, "env"), (isSxTruthy((len(remaining) == 1)) ? restK : kontPush(makeAndFrame(rest(remaining), get(frame, "env")), restK))));
})()) : (isSxTruthy((ft == "or")) ? (isSxTruthy(value) ? makeCekValue(value, env, restK) : (function() {
var remaining = get(frame, "remaining");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(false, env, restK) : makeCekState(first(remaining), get(frame, "env"), (isSxTruthy((len(remaining) == 1)) ? restK : kontPush(makeOrFrame(rest(remaining), get(frame, "env")), restK))));
})()) : (isSxTruthy((ft == "cond")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
var scheme_p = get(frame, "scheme");
return (isSxTruthy(scheme_p) ? (isSxTruthy(value) ? makeCekState(nth(first(remaining), 1), fenv, restK) : (function() {
var nextClauses = rest(remaining);
return (isSxTruthy(isEmpty(nextClauses)) ? makeCekValue(NIL, fenv, restK) : (function() {
var nextClause = first(nextClauses);
var nextTest = first(nextClause);
return (isSxTruthy(isElseClause(nextTest)) ? makeCekState(nth(nextClause, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(nextClauses, fenv, true), restK)));
})());
})()) : (isSxTruthy(value) ? makeCekState(nth(remaining, 1), fenv, restK) : (function() {
var next = slice(remaining, 2);
return (isSxTruthy((len(next) < 2)) ? makeCekValue(NIL, fenv, restK) : (function() {
var nextTest = first(next);
return (isSxTruthy(isElseClause(nextTest)) ? makeCekState(nth(next, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(next, fenv, false), restK)));
})());
})()));
})() : (isSxTruthy((ft == "case")) ? (function() {
var matchVal = get(frame, "match-val");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isNil(matchVal)) ? sfCaseStepLoop(value, remaining, fenv, restK) : sfCaseStepLoop(matchVal, remaining, fenv, restK));
})() : (isSxTruthy((ft == "thread")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : (function() {
var form = first(remaining);
var restForms = rest(remaining);
var newKont = (isSxTruthy(isEmpty(rest(remaining))) ? restK : kontPush(makeThreadFrame(rest(remaining), fenv), restK));
return (isSxTruthy((isSxTruthy((typeOf(form) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(form))) && isSxTruthy((typeOf(first(form)) == "symbol")) && hoFormName_p(symbolName(first(form))))) ? makeCekState(cons(first(form), cons([new Symbol("quote"), value], rest(form))), fenv, newKont) : (function() {
var result = (isSxTruthy((typeOf(form) == "list")) ? (function() {
var f = trampoline(evalExpr(first(form), fenv));
var rargs = map(function(a) { return trampoline(evalExpr(a, fenv)); }, rest(form));
var allArgs = cons(value, rargs);
return (isSxTruthy((isSxTruthy(isCallable(f)) && !isSxTruthy(isLambda(f)))) ? apply(f, allArgs) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, allArgs, fenv)) : error((String("-> form not callable: ") + String(inspect(f))))));
})() : (function() {
var f = trampoline(evalExpr(form, fenv));
return (isSxTruthy((isSxTruthy(isCallable(f)) && !isSxTruthy(isLambda(f)))) ? f(value) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, [value], fenv)) : error((String("-> form not callable: ") + String(inspect(f))))));
})());
return (isSxTruthy(isEmpty(restForms)) ? makeCekValue(result, fenv, restK) : makeCekValue(result, fenv, kontPush(makeThreadFrame(restForms, fenv), restK)));
})());
})());
})() : (isSxTruthy((ft == "arg")) ? (function() {
var f = get(frame, "f");
var evaled = get(frame, "evaled");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
var rawArgs = get(frame, "raw-args");
var hname = get(frame, "head-name");
return (isSxTruthy(isNil(f)) ? ((isSxTruthy((isSxTruthy(_strict_) && hname)) ? strictCheckArgs(hname, []) : NIL), (isSxTruthy(isEmpty(remaining)) ? continueWithCall(value, [], fenv, rawArgs, restK) : makeCekState(first(remaining), fenv, kontPush(makeArgFrame(value, [], rest(remaining), fenv, rawArgs, hname), restK)))) : (function() {
var newEvaled = append(evaled, [value]);
return (isSxTruthy(isEmpty(remaining)) ? ((isSxTruthy((isSxTruthy(_strict_) && hname)) ? strictCheckArgs(hname, newEvaled) : NIL), continueWithCall(f, newEvaled, fenv, rawArgs, restK)) : makeCekState(first(remaining), fenv, kontPush(makeArgFrame(f, newEvaled, rest(remaining), fenv, rawArgs, hname), restK)));
})());
})() : (isSxTruthy((ft == "dict")) ? (function() {
var remaining = get(frame, "remaining");
var results = get(frame, "results");
var fenv = get(frame, "env");
return (function() {
var lastResult = last(results);
var completed = append(slice(results, 0, (len(results) - 1)), [[first(lastResult), value]]);
return (isSxTruthy(isEmpty(remaining)) ? (function() {
var d = {};
{ var _c = completed; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; d[first(pair)] = nth(pair, 1); } }
return makeCekValue(d, fenv, restK);
})() : (function() {
var nextEntry = first(remaining);
return makeCekState(nth(nextEntry, 1), fenv, kontPush(makeDictFrame(rest(remaining), append(completed, [[first(nextEntry)]]), fenv), restK));
})());
})();
})() : (isSxTruthy((ft == "ho-setup")) ? (function() {
var hoType = get(frame, "ho-type");
var remaining = get(frame, "remaining");
var evaled = append(get(frame, "evaled"), [value]);
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? hoSetupDispatch(hoType, evaled, fenv, restK) : makeCekState(first(remaining), fenv, kontPush(makeHoSetupFrame(hoType, rest(remaining), evaled, fenv), restK)));
})() : (isSxTruthy((ft == "reset")) ? makeCekValue(value, env, restK) : (isSxTruthy((ft == "deref")) ? (function() {
var val = value;
var fenv = get(frame, "env");
return (isSxTruthy(!isSxTruthy(isSignal(val))) ? makeCekValue(val, fenv, restK) : (isSxTruthy(hasReactiveResetFrame_p(restK)) ? reactiveShiftDeref(val, fenv, restK) : ((function() {
var ctx = sxContext("sx-reactive", NIL);
return (isSxTruthy(ctx) ? (function() {
var depList = get(ctx, "deps");
var notifyFn = get(ctx, "notify");
return (isSxTruthy(!isSxTruthy(contains(depList, val))) ? (append_b(depList, val), signalAddSub(val, notifyFn)) : NIL);
})() : NIL);
})(), makeCekValue(signalValue(val), fenv, restK))));
})() : (isSxTruthy((ft == "reactive-reset")) ? (function() {
var updateFn = get(frame, "update-fn");
var first_p = get(frame, "first-render");
if (isSxTruthy((isSxTruthy(updateFn) && !isSxTruthy(first_p)))) {
cekCall(updateFn, [value]);
}
return makeCekValue(value, env, restK);
})() : (isSxTruthy((ft == "scope")) ? (function() {
var name = get(frame, "name");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? (scopePop(name), makeCekValue(value, fenv, restK)) : makeCekState(first(remaining), fenv, kontPush(makeScopeFrame(name, rest(remaining), fenv), restK)));
})() : (isSxTruthy((ft == "provide")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : makeCekState(first(remaining), fenv, kontPush(makeProvideFrame(get(frame, "name"), get(frame, "value"), rest(remaining), fenv), restK)));
})() : (isSxTruthy((ft == "scope-acc")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : makeCekState(first(remaining), fenv, kontPush((function() {
var newFrame = makeScopeAccFrame(get(frame, "name"), get(frame, "value"), rest(remaining), fenv);
newFrame["emitted"] = get(frame, "emitted");
return newFrame;
})(), restK)));
})() : (isSxTruthy((ft == "map")) ? (function() {
var f = get(frame, "f");
var remaining = get(frame, "remaining");
var results = get(frame, "results");
var indexed = get(frame, "indexed");
var fenv = get(frame, "env");
return (function() {
var newResults = append(results, [value]);
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(newResults, fenv, restK) : (function() {
var callArgs = (isSxTruthy(indexed) ? [len(newResults), first(remaining)] : [first(remaining)]);
var nextFrame = (isSxTruthy(indexed) ? makeMapIndexedFrame(f, rest(remaining), newResults, fenv) : makeMapFrame(f, rest(remaining), newResults, fenv));
return continueWithCall(f, callArgs, fenv, [], kontPush(nextFrame, restK));
})());
})();
})() : (isSxTruthy((ft == "filter")) ? (function() {
var f = get(frame, "f");
var remaining = get(frame, "remaining");
var results = get(frame, "results");
var currentItem = get(frame, "current-item");
var fenv = get(frame, "env");
return (function() {
var newResults = (isSxTruthy(value) ? append(results, [currentItem]) : results);
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(newResults, fenv, restK) : continueWithCall(f, [first(remaining)], fenv, [], kontPush(makeFilterFrame(f, rest(remaining), newResults, first(remaining), fenv), restK)));
})();
})() : (isSxTruthy((ft == "reduce")) ? (function() {
var f = get(frame, "f");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : continueWithCall(f, [value, first(remaining)], fenv, [], kontPush(makeReduceFrame(f, rest(remaining), fenv), restK)));
})() : (isSxTruthy((ft == "for-each")) ? (function() {
var f = get(frame, "f");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(NIL, fenv, restK) : continueWithCall(f, [first(remaining)], fenv, [], kontPush(makeForEachFrame(f, rest(remaining), fenv), restK)));
})() : (isSxTruthy((ft == "some")) ? (function() {
var f = get(frame, "f");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(value) ? makeCekValue(value, fenv, restK) : (isSxTruthy(isEmpty(remaining)) ? makeCekValue(false, fenv, restK) : continueWithCall(f, [first(remaining)], fenv, [], kontPush(makeSomeFrame(f, rest(remaining), fenv), restK))));
})() : (isSxTruthy((ft == "every")) ? (function() {
var f = get(frame, "f");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(!isSxTruthy(value)) ? makeCekValue(false, fenv, restK) : (isSxTruthy(isEmpty(remaining)) ? makeCekValue(true, fenv, restK) : continueWithCall(f, [first(remaining)], fenv, [], kontPush(makeEveryFrame(f, rest(remaining), fenv), restK))));
})() : error((String("Unknown frame type: ") + String(ft)))))))))))))))))))))))))))));
})());
})(); };
PRIMITIVES["step-continue"] = stepContinue;
// continue-with-call
var continueWithCall = function(f, args, env, rawArgs, kont) { return (isSxTruthy(continuation_p(f)) ? (function() {
var arg = (isSxTruthy(isEmpty(args)) ? NIL : first(args));
var contData = continuationData(f);
return (function() {
var captured = get(contData, "captured");
return (function() {
var result = cekRun(makeCekValue(arg, env, captured));
return makeCekValue(result, env, kont);
})();
})();
})() : (isSxTruthy((isSxTruthy(isCallable(f)) && isSxTruthy(!isSxTruthy(isLambda(f))) && isSxTruthy(!isSxTruthy(isComponent(f))) && !isSxTruthy(isIsland(f)))) ? makeCekValue(apply(f, args), env, kont) : (isSxTruthy(isLambda(f)) ? (function() {
var params = lambdaParams(f);
var local = envMerge(lambdaClosure(f), env);
return (isSxTruthy((len(args) > len(params))) ? error((String(sxOr(lambdaName(f), "lambda")) + String(" expects ") + String(len(params)) + String(" args, got ") + String(len(args)))) : (forEach(function(pair) { return envBind(local, first(pair), nth(pair, 1)); }, zip(params, args)), forEach(function(p) { return envBind(local, p, NIL); }, slice(params, len(args))), makeCekState(lambdaBody(f), local, kont)));
})() : (isSxTruthy(sxOr(isComponent(f), isIsland(f))) ? (function() {
var parsed = parseKeywordArgs(rawArgs, env);
var kwargs = first(parsed);
var children = nth(parsed, 1);
var local = envMerge(componentClosure(f), env);
{ var _c = componentParams(f); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, sxOr(dictGet(kwargs, p), NIL)); } }
if (isSxTruthy(componentHasChildren(f))) {
envBind(local, "children", children);
}
return makeCekState(componentBody(f), local, kont);
})() : error((String("Not callable: ") + String(inspect(f)))))))); };
PRIMITIVES["continue-with-call"] = continueWithCall;
// sf-case-step-loop
var sfCaseStepLoop = function(matchVal, clauses, env, kont) { return (isSxTruthy((len(clauses) < 2)) ? makeCekValue(NIL, env, kont) : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(isElseClause(test)) ? makeCekState(body, env, kont) : (function() {
var testVal = trampoline(evalExpr(test, env));
return (isSxTruthy((matchVal == testVal)) ? makeCekState(body, env, kont) : sfCaseStepLoop(matchVal, slice(clauses, 2), env, kont));
})());
})()); };
PRIMITIVES["sf-case-step-loop"] = sfCaseStepLoop;
// eval-expr-cek
var evalExprCek = function(expr, env) { return cekRun(makeCekState(expr, env, [])); };
PRIMITIVES["eval-expr-cek"] = evalExprCek;
// trampoline-cek
var trampolineCek = function(val) { return (isSxTruthy(isThunk(val)) ? evalExprCek(thunkExpr(val), thunkEnv(val)) : val); };
PRIMITIVES["trampoline-cek"] = trampolineCek;
// eval-expr
var evalExpr = function(expr, env) { return cekRun(makeCekState(expr, env, [])); };
PRIMITIVES["eval-expr"] = evalExpr;
// trampoline
var trampoline = function(val) { return (isSxTruthy(isThunk(val)) ? evalExpr(thunkExpr(val), thunkEnv(val)) : val); };
PRIMITIVES["trampoline"] = trampoline;
// === Transpiled from freeze (serializable state boundaries) ===
// freeze-registry
var freezeRegistry = {};
PRIMITIVES["freeze-registry"] = freezeRegistry;
// freeze-signal
var freezeSignal = function(name, sig) { return (function() {
var scopeName = sxContext("sx-freeze-scope", NIL);
return (isSxTruthy(scopeName) ? (function() {
var entries = sxOr(get(freezeRegistry, scopeName), []);
entries.push({["name"]: name, ["signal"]: sig});
return dictSet(freezeRegistry, scopeName, entries);
})() : NIL);
})(); };
PRIMITIVES["freeze-signal"] = freezeSignal;
// freeze-scope
var freezeScope = function(name, bodyFn) { scopePush("sx-freeze-scope", name);
freezeRegistry[name] = [];
cekCall(bodyFn, NIL);
scopePop("sx-freeze-scope");
return NIL; };
PRIMITIVES["freeze-scope"] = freezeScope;
// cek-freeze-scope
var cekFreezeScope = function(name) { return (function() {
var entries = sxOr(get(freezeRegistry, name), []);
var signalsDict = {};
{ var _c = entries; for (var _i = 0; _i < _c.length; _i++) { var entry = _c[_i]; signalsDict[get(entry, "name")] = signalValue(get(entry, "signal")); } }
return {["name"]: name, ["signals"]: signalsDict};
})(); };
PRIMITIVES["cek-freeze-scope"] = cekFreezeScope;
// cek-freeze-all
var cekFreezeAll = function() { return map(function(name) { return cekFreezeScope(name); }, keys(freezeRegistry)); };
PRIMITIVES["cek-freeze-all"] = cekFreezeAll;
// cek-thaw-scope
var cekThawScope = function(name, frozen) { return (function() {
var entries = sxOr(get(freezeRegistry, name), []);
var values = get(frozen, "signals");
return (isSxTruthy(values) ? forEach(function(entry) { return (function() {
var sigName = get(entry, "name");
var sig = get(entry, "signal");
var val = get(values, sigName);
return (isSxTruthy(!isSxTruthy(isNil(val))) ? reset_b(sig, val) : NIL);
})(); }, entries) : NIL);
})(); };
PRIMITIVES["cek-thaw-scope"] = cekThawScope;
// cek-thaw-all
var cekThawAll = function(frozenList) { return forEach(function(frozen) { return cekThawScope(get(frozen, "name"), frozen); }, frozenList); };
PRIMITIVES["cek-thaw-all"] = cekThawAll;
// freeze-to-sx
var freezeToSx = function(name) { return sxSerialize(cekFreezeScope(name)); };
PRIMITIVES["freeze-to-sx"] = freezeToSx;
// thaw-from-sx
var thawFromSx = function(sxText) { return (function() {
var parsed = sxParse(sxText);
return (isSxTruthy(!isSxTruthy(isEmpty(parsed))) ? (function() {
var frozen = first(parsed);
return cekThawScope(get(frozen, "name"), frozen);
})() : NIL);
})(); };
PRIMITIVES["thaw-from-sx"] = thawFromSx;
// === Transpiled from content (content-addressed computation) ===
// content-store
var contentStore = {};
PRIMITIVES["content-store"] = contentStore;
// content-hash
var contentHash = function(sxText) { return (function() {
var hash = 5381;
{ var _c = range(0, len(sxText)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; hash = (((hash * 33) + charCodeAt(sxText, i)) % 4294967296); } }
return toHex(hash);
})(); };
PRIMITIVES["content-hash"] = contentHash;
// content-put
var contentPut = function(sxText) { return (function() {
var cid = contentHash(sxText);
contentStore[cid] = sxText;
return cid;
})(); };
PRIMITIVES["content-put"] = contentPut;
// content-get
var contentGet = function(cid) { return get(contentStore, cid); };
PRIMITIVES["content-get"] = contentGet;
// freeze-to-cid
var freezeToCid = function(scopeName) { return (function() {
var sxText = freezeToSx(scopeName);
return contentPut(sxText);
})(); };
PRIMITIVES["freeze-to-cid"] = freezeToCid;
// thaw-from-cid
var thawFromCid = function(cid) { return (function() {
var sxText = contentGet(cid);
return (isSxTruthy(sxText) ? (thawFromSx(sxText), true) : NIL);
})(); };
PRIMITIVES["thaw-from-cid"] = thawFromCid;
// === Transpiled from render (core) ===
// HTML_TAGS
var HTML_TAGS = ["html", "head", "body", "title", "meta", "link", "script", "style", "noscript", "header", "nav", "main", "section", "article", "aside", "footer", "h1", "h2", "h3", "h4", "h5", "h6", "hgroup", "div", "p", "blockquote", "pre", "figure", "figcaption", "address", "details", "summary", "a", "span", "em", "strong", "small", "b", "i", "u", "s", "mark", "sub", "sup", "abbr", "cite", "code", "kbd", "samp", "var", "time", "br", "wbr", "hr", "ul", "ol", "li", "dl", "dt", "dd", "table", "thead", "tbody", "tfoot", "tr", "th", "td", "caption", "colgroup", "col", "form", "input", "textarea", "select", "option", "optgroup", "button", "label", "fieldset", "legend", "output", "datalist", "img", "video", "audio", "source", "picture", "canvas", "iframe", "svg", "math", "path", "circle", "ellipse", "rect", "line", "polyline", "polygon", "text", "tspan", "g", "defs", "use", "clipPath", "mask", "pattern", "linearGradient", "radialGradient", "stop", "filter", "feGaussianBlur", "feOffset", "feBlend", "feColorMatrix", "feComposite", "feMerge", "feMergeNode", "feTurbulence", "feComponentTransfer", "feFuncR", "feFuncG", "feFuncB", "feFuncA", "feDisplacementMap", "feFlood", "feImage", "feMorphology", "feSpecularLighting", "feDiffuseLighting", "fePointLight", "feSpotLight", "feDistantLight", "animate", "animateTransform", "foreignObject", "template", "slot", "dialog", "menu"];
PRIMITIVES["HTML_TAGS"] = HTML_TAGS;
// VOID_ELEMENTS
var VOID_ELEMENTS = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"];
PRIMITIVES["VOID_ELEMENTS"] = VOID_ELEMENTS;
// BOOLEAN_ATTRS
var BOOLEAN_ATTRS = ["async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected"];
PRIMITIVES["BOOLEAN_ATTRS"] = BOOLEAN_ATTRS;
// *definition-form-extensions*
var _definitionFormExtensions_ = [];
PRIMITIVES["*definition-form-extensions*"] = _definitionFormExtensions_;
// definition-form?
var isDefinitionForm = function(name) { return sxOr((name == "define"), (name == "defcomp"), (name == "defisland"), (name == "defmacro"), (name == "defstyle"), (name == "deftype"), (name == "defeffect"), contains(_definitionFormExtensions_, name)); };
PRIMITIVES["definition-form?"] = isDefinitionForm;
// parse-element-args
var parseElementArgs = function(args, env) { return (function() {
var attrs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
attrs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return [attrs, children];
})(); };
PRIMITIVES["parse-element-args"] = parseElementArgs;
// render-attrs
var renderAttrs = function(attrs) { return join("", map(function(key) { return (function() {
var val = dictGet(attrs, key);
return (isSxTruthy((isSxTruthy(contains(BOOLEAN_ATTRS, key)) && val)) ? (String(" ") + String(key)) : (isSxTruthy((isSxTruthy(contains(BOOLEAN_ATTRS, key)) && !isSxTruthy(val))) ? "" : (isSxTruthy(isNil(val)) ? "" : (String(" ") + String(key) + String("=\"") + String(escapeAttr((String(val)))) + String("\"")))));
})(); }, keys(attrs))); };
PRIMITIVES["render-attrs"] = renderAttrs;
// eval-cond
var evalCond = function(clauses, env) { return (isSxTruthy(condScheme_p(clauses)) ? evalCondScheme(clauses, env) : evalCondClojure(clauses, env)); };
PRIMITIVES["eval-cond"] = evalCond;
// eval-cond-scheme
var evalCondScheme = function(clauses, env) { return (isSxTruthy(isEmpty(clauses)) ? NIL : (function() {
var clause = first(clauses);
var test = first(clause);
var body = nth(clause, 1);
return (isSxTruthy(isElseClause(test)) ? body : (isSxTruthy(trampoline(evalExpr(test, env))) ? body : evalCondScheme(rest(clauses), env)));
})()); };
PRIMITIVES["eval-cond-scheme"] = evalCondScheme;
// eval-cond-clojure
var evalCondClojure = function(clauses, env) { return (isSxTruthy((len(clauses) < 2)) ? NIL : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(isElseClause(test)) ? body : (isSxTruthy(trampoline(evalExpr(test, env))) ? body : evalCondClojure(slice(clauses, 2), env)));
})()); };
PRIMITIVES["eval-cond-clojure"] = evalCondClojure;
// process-bindings
var processBindings = function(bindings, env) { return (function() {
var local = envExtend(env);
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(pair) == "list")) && (len(pair) >= 2)))) {
(function() {
var name = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
return envBind(local, name, trampoline(evalExpr(nth(pair, 1), local)));
})();
} } }
return local;
})(); };
PRIMITIVES["process-bindings"] = processBindings;
// is-render-expr?
var isRenderExpr = function(expr) { return (isSxTruthy(sxOr(!isSxTruthy((typeOf(expr) == "list")), isEmpty(expr))) ? false : (function() {
var h = first(expr);
return (isSxTruthy(!isSxTruthy((typeOf(h) == "symbol"))) ? false : (function() {
var n = symbolName(h);
return sxOr((n == "<>"), (n == "raw!"), startsWith(n, "~"), startsWith(n, "html:"), contains(HTML_TAGS, n), (isSxTruthy((indexOf_(n, "-") > 0)) && isSxTruthy((len(expr) > 1)) && (typeOf(nth(expr, 1)) == "keyword")));
})());
})()); };
PRIMITIVES["is-render-expr?"] = isRenderExpr;
// merge-spread-attrs
var mergeSpreadAttrs = function(target, spreadDict) { return forEach(function(key) { return (function() {
var val = dictGet(spreadDict, key);
return (isSxTruthy((key == "class")) ? (function() {
var existing = dictGet(target, "class");
return dictSet(target, "class", (isSxTruthy((isSxTruthy(existing) && !isSxTruthy((existing == "")))) ? (String(existing) + String(" ") + String(val)) : val));
})() : (isSxTruthy((key == "style")) ? (function() {
var existing = dictGet(target, "style");
return dictSet(target, "style", (isSxTruthy((isSxTruthy(existing) && !isSxTruthy((existing == "")))) ? (String(existing) + String(";") + String(val)) : val));
})() : dictSet(target, key, val)));
})(); }, keys(spreadDict)); };
PRIMITIVES["merge-spread-attrs"] = mergeSpreadAttrs;
// escape-html
var escapeHtml = function(s) { return (function() {
var r = (String(s));
r = replace_(r, "&", "&amp;");
r = replace_(r, "<", "&lt;");
r = replace_(r, ">", "&gt;");
r = replace_(r, "\"", "&quot;");
return r;
})(); };
PRIMITIVES["escape-html"] = escapeHtml;
// escape-attr
var escapeAttr = function(s) { return escapeHtml(s); };
PRIMITIVES["escape-attr"] = escapeAttr;
// === Transpiled from web-forms (defstyle, deftype, defeffect, defrelation) ===
// parse-key-params
var parseKeyParams = function(paramsExpr) { return (function() {
var params = [];
{ var _c = paramsExpr; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; if (isSxTruthy((typeOf(p) == "symbol"))) {
(function() {
var name = symbolName(p);
return (isSxTruthy(!isSxTruthy((name == "&key"))) ? append_b(params, name) : NIL);
})();
} } }
return params;
})(); };
PRIMITIVES["parse-key-params"] = parseKeyParams;
// parse-handler-args
var parseHandlerArgs = function(args) { return (function() {
var opts = {};
var params = [];
var body = NIL;
var i = 0;
var n = len(args);
var done = false;
{ var _c = range(0, n); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; if (isSxTruthy((isSxTruthy(!isSxTruthy(done)) && (idx == i)))) {
(function() {
var arg = nth(args, idx);
return (isSxTruthy((typeOf(arg) == "keyword")) ? ((isSxTruthy(((idx + 1) < n)) ? (function() {
var val = nth(args, (idx + 1));
return dictSet(opts, keywordName(arg), (isSxTruthy((typeOf(val) == "keyword")) ? keywordName(val) : val));
})() : NIL), (i = (idx + 2))) : (isSxTruthy((typeOf(arg) == "list")) ? ((params = parseKeyParams(arg)), (isSxTruthy(((idx + 1) < n)) ? (body = nth(args, (idx + 1))) : NIL), (done = true)) : ((body = arg), (done = true))));
})();
} } }
return {["opts"]: opts, ["params"]: params, ["body"]: body};
})(); };
PRIMITIVES["parse-handler-args"] = parseHandlerArgs;
// (register-special-form! ...)
registerSpecialForm("defhandler", function(args, env) { return (function() {
var nameSym = first(args);
var name = symbolName(first(args));
var parsed = parseHandlerArgs(rest(args));
var opts = get(parsed, "opts");
var params = get(parsed, "params");
var body = get(parsed, "body");
return (function() {
var hdef = {["__type"]: "handler", ["name"]: name, ["params"]: params, ["body"]: body, ["closure"]: env, ["path"]: sxOr(get(opts, "path"), NIL), ["method"]: sxOr(get(opts, "method"), "get"), ["csrf"]: (function() {
var v = get(opts, "csrf");
return (isSxTruthy(isNil(v)) ? true : v);
})(), ["returns"]: sxOr(get(opts, "returns"), "element")};
envBind(env, (String("handler:") + String(name)), hdef);
return hdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defquery", function(args, env) { return (function() {
var name = symbolName(first(args));
var paramsRaw = nth(args, 1);
var params = parseKeyParams(paramsRaw);
var hasDoc = (isSxTruthy((len(args) >= 4)) && (typeOf(nth(args, 2)) == "string"));
var doc = (isSxTruthy(hasDoc) ? nth(args, 2) : "");
var body = (isSxTruthy(hasDoc) ? nth(args, 3) : nth(args, 2));
return (function() {
var qdef = {["__type"]: "query", ["name"]: name, ["params"]: params, ["doc"]: doc, ["body"]: body, ["closure"]: env};
envBind(env, (String("query:") + String(name)), qdef);
return qdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defaction", function(args, env) { return (function() {
var name = symbolName(first(args));
var paramsRaw = nth(args, 1);
var params = parseKeyParams(paramsRaw);
var hasDoc = (isSxTruthy((len(args) >= 4)) && (typeOf(nth(args, 2)) == "string"));
var doc = (isSxTruthy(hasDoc) ? nth(args, 2) : "");
var body = (isSxTruthy(hasDoc) ? nth(args, 3) : nth(args, 2));
return (function() {
var adef = {["__type"]: "action", ["name"]: name, ["params"]: params, ["doc"]: doc, ["body"]: body, ["closure"]: env};
envBind(env, (String("action:") + String(name)), adef);
return adef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defpage", function(args, env) { return (function() {
var name = symbolName(first(args));
var slots = {};
var n = len(args);
{ var _c = range(0, ((n - 1) / 2)); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; (function() {
var kIdx = (1 + (idx * 2));
var vIdx = (2 + (idx * 2));
return (isSxTruthy((isSxTruthy((kIdx < n)) && isSxTruthy((vIdx < n)) && (typeOf(nth(args, kIdx)) == "keyword"))) ? dictSet(slots, keywordName(nth(args, kIdx)), nth(args, vIdx)) : NIL);
})(); } }
return (function() {
var pdef = {["__type"]: "page", ["name"]: name, ["path"]: sxOr(get(slots, "path"), ""), ["auth"]: sxOr(get(slots, "auth"), "public"), ["layout"]: get(slots, "layout"), ["data"]: get(slots, "data"), ["content"]: get(slots, "content"), ["filter"]: get(slots, "filter"), ["aside"]: get(slots, "aside"), ["menu"]: get(slots, "menu"), ["stream"]: get(slots, "stream"), ["fallback"]: get(slots, "fallback"), ["shell"]: get(slots, "shell"), ["closure"]: env};
envBind(env, (String("page:") + String(name)), pdef);
return pdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defrelation", function(args, env) { return (function() {
var name = symbolName(first(args));
var slots = {};
var n = len(args);
{ var _c = range(0, ((n - 1) / 2)); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; (function() {
var kIdx = (1 + (idx * 2));
var vIdx = (2 + (idx * 2));
return (isSxTruthy((isSxTruthy((kIdx < n)) && isSxTruthy((vIdx < n)) && (typeOf(nth(args, kIdx)) == "keyword"))) ? dictSet(slots, keywordName(nth(args, kIdx)), nth(args, vIdx)) : NIL);
})(); } }
return (function() {
var rdef = {["__type"]: "relation", ["name"]: name, ["slots"]: slots, ["closure"]: env};
envBind(env, (String("relation:") + String(name)), rdef);
return rdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defstyle", function(args, env) { return (function() {
var nameSym = first(args);
var value = trampoline(evalExpr(nth(args, 1), env));
envBind(env, symbolName(nameSym), value);
return value;
})(); });
// normalize-type-body
var normalizeTypeBody = function(body) { return (isSxTruthy(isNil(body)) ? "nil" : (isSxTruthy((typeOf(body) == "symbol")) ? symbolName(body) : (isSxTruthy((typeOf(body) == "string")) ? body : (isSxTruthy((typeOf(body) == "keyword")) ? keywordName(body) : (isSxTruthy((typeOf(body) == "dict")) ? mapDict(function(k, v) { return normalizeTypeBody(v); }, body) : (isSxTruthy((typeOf(body) == "list")) ? (isSxTruthy(isEmpty(body)) ? "any" : (function() {
var headName = (isSxTruthy((typeOf(first(body)) == "symbol")) ? symbolName(first(body)) : (String(first(body))));
return (isSxTruthy((headName == "union")) ? cons("or", map(normalizeTypeBody, rest(body))) : cons(headName, map(normalizeTypeBody, rest(body))));
})()) : (String(body)))))))); };
PRIMITIVES["normalize-type-body"] = normalizeTypeBody;
// (register-special-form! ...)
registerSpecialForm("deftype", function(args, env) { return (function() {
var nameOrForm = first(args);
var bodyExpr = nth(args, 1);
var typeName = NIL;
var typeParams = [];
(isSxTruthy((typeOf(nameOrForm) == "symbol")) ? (typeName = symbolName(nameOrForm)) : (isSxTruthy((typeOf(nameOrForm) == "list")) ? ((typeName = symbolName(first(nameOrForm))), (typeParams = map(function(p) { return (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : (String(p))); }, rest(nameOrForm)))) : NIL));
return (function() {
var body = normalizeTypeBody(bodyExpr);
var registry = (isSxTruthy(envHas(env, "*type-registry*")) ? envGet(env, "*type-registry*") : {});
registry[typeName] = {"body": body, "params": typeParams, "name": typeName};
envBind(env, "*type-registry*", registry);
return NIL;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defeffect", function(args, env) { return (function() {
var effectName = (isSxTruthy((typeOf(first(args)) == "symbol")) ? symbolName(first(args)) : (String(first(args))));
var registry = (isSxTruthy(envHas(env, "*effect-registry*")) ? envGet(env, "*effect-registry*") : []);
if (isSxTruthy(!isSxTruthy(contains(registry, effectName)))) {
registry.push(effectName);
}
envBind(env, "*effect-registry*", registry);
return NIL;
})(); });
// WEB_FORM_NAMES
var WEB_FORM_NAMES = ["defhandler", "defpage", "defquery", "defaction", "defrelation", "defstyle", "deftype", "defeffect"];
PRIMITIVES["WEB_FORM_NAMES"] = WEB_FORM_NAMES;
// === Transpiled from parser ===
// sx-parse
var sxParse = function(source) { return (function() {
var pos = 0;
var lenSrc = len(source);
var skipComment = function() { while(true) { if (isSxTruthy((isSxTruthy((pos < lenSrc)) && !isSxTruthy((nth(source, pos) == "\n"))))) { pos = (pos + 1);
continue; } else { return NIL; } } };
PRIMITIVES["skip-comment"] = skipComment;
var skipWs = function() { while(true) { if (isSxTruthy((pos < lenSrc))) { { var ch = nth(source, pos);
if (isSxTruthy(sxOr((ch == " "), (ch == "\t"), (ch == "\n"), (ch == "\r")))) { pos = (pos + 1);
continue; } else if (isSxTruthy((ch == ";"))) { pos = (pos + 1);
skipComment();
continue; } else { return NIL; } } } else { return NIL; } } };
PRIMITIVES["skip-ws"] = skipWs;
var hexDigitValue = function(ch) { return indexOf_("0123456789abcdef", lower(ch)); };
PRIMITIVES["hex-digit-value"] = hexDigitValue;
var readString = function() { pos = (pos + 1);
return (function() {
var buf = "";
var readStrLoop = function() { while(true) { if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated string"); } else { { var ch = nth(source, pos);
if (isSxTruthy((ch == "\""))) { pos = (pos + 1);
return NIL; } else if (isSxTruthy((ch == "\\"))) { pos = (pos + 1);
{ var esc = nth(source, pos);
if (isSxTruthy((esc == "u"))) { pos = (pos + 1);
{ var d0 = hexDigitValue(nth(source, pos));
var _ = (pos = (pos + 1));
var d1 = hexDigitValue(nth(source, pos));
var _ = (pos = (pos + 1));
var d2 = hexDigitValue(nth(source, pos));
var _ = (pos = (pos + 1));
var d3 = hexDigitValue(nth(source, pos));
var _ = (pos = (pos + 1));
buf = (String(buf) + String(charFromCode(((((d0 * 4096) + (d1 * 256)) + (d2 * 16)) + d3))));
continue; } } else { buf = (String(buf) + String((isSxTruthy((esc == "n")) ? "\n" : (isSxTruthy((esc == "t")) ? "\t" : (isSxTruthy((esc == "r")) ? "\r" : esc)))));
pos = (pos + 1);
continue; } } } else { buf = (String(buf) + String(ch));
pos = (pos + 1);
continue; } } } } };
PRIMITIVES["read-str-loop"] = readStrLoop;
readStrLoop();
return buf;
})(); };
PRIMITIVES["read-string"] = readString;
var readIdent = function() { return (function() {
var start = pos;
var readIdentLoop = function() { while(true) { if (isSxTruthy((isSxTruthy((pos < lenSrc)) && isIdentChar(nth(source, pos))))) { pos = (pos + 1);
continue; } else { return NIL; } } };
PRIMITIVES["read-ident-loop"] = readIdentLoop;
readIdentLoop();
return slice(source, start, pos);
})(); };
PRIMITIVES["read-ident"] = readIdent;
var readKeyword = function() { pos = (pos + 1);
return makeKeyword(readIdent()); };
PRIMITIVES["read-keyword"] = readKeyword;
var readNumber = function() { return (function() {
var start = pos;
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (nth(source, pos) == "-")))) {
pos = (pos + 1);
}
var readDigits = function() { while(true) { if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (function() {
var c = nth(source, pos);
return (isSxTruthy((c >= "0")) && (c <= "9"));
})()))) { pos = (pos + 1);
continue; } else { return NIL; } } };
PRIMITIVES["read-digits"] = readDigits;
readDigits();
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (nth(source, pos) == ".")))) {
pos = (pos + 1);
readDigits();
}
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && sxOr((nth(source, pos) == "e"), (nth(source, pos) == "E"))))) {
pos = (pos + 1);
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && sxOr((nth(source, pos) == "+"), (nth(source, pos) == "-"))))) {
pos = (pos + 1);
}
readDigits();
}
return parseNumber(slice(source, start, pos));
})(); };
PRIMITIVES["read-number"] = readNumber;
var readSymbol = function() { return (function() {
var name = readIdent();
return (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : makeSymbol(name))));
})(); };
PRIMITIVES["read-symbol"] = readSymbol;
var readList = function(closeCh) { return (function() {
var items = [];
var readListLoop = function() { while(true) { skipWs();
if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated list"); } else { if (isSxTruthy((nth(source, pos) == closeCh))) { pos = (pos + 1);
return NIL; } else { items.push(readExpr());
continue; } } } };
PRIMITIVES["read-list-loop"] = readListLoop;
readListLoop();
return items;
})(); };
PRIMITIVES["read-list"] = readList;
var readMap = function() { return (function() {
var result = {};
var readMapLoop = function() { while(true) { skipWs();
if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated map"); } else { if (isSxTruthy((nth(source, pos) == "}"))) { pos = (pos + 1);
return NIL; } else { { var keyExpr = readExpr();
var keyStr = (isSxTruthy((typeOf(keyExpr) == "keyword")) ? keywordName(keyExpr) : (String(keyExpr)));
var valExpr = readExpr();
result[keyStr] = valExpr;
continue; } } } } };
PRIMITIVES["read-map-loop"] = readMapLoop;
readMapLoop();
return result;
})(); };
PRIMITIVES["read-map"] = readMap;
var readRawString = function() { return (function() {
var buf = "";
var rawLoop = function() { while(true) { if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated raw string"); } else { { var ch = nth(source, pos);
if (isSxTruthy((ch == "|"))) { pos = (pos + 1);
return NIL; } else { buf = (String(buf) + String(ch));
pos = (pos + 1);
continue; } } } } };
PRIMITIVES["raw-loop"] = rawLoop;
rawLoop();
return buf;
})(); };
PRIMITIVES["read-raw-string"] = readRawString;
var readExpr = function() { while(true) { skipWs();
if (isSxTruthy((pos >= lenSrc))) { return error("Unexpected end of input"); } else { { var ch = nth(source, pos);
if (isSxTruthy((ch == "("))) { pos = (pos + 1);
return readList(")"); } else if (isSxTruthy((ch == "["))) { pos = (pos + 1);
return readList("]"); } else if (isSxTruthy((ch == "{"))) { pos = (pos + 1);
return readMap(); } else if (isSxTruthy((ch == "\""))) { return readString(); } else if (isSxTruthy((ch == ":"))) { return readKeyword(); } else if (isSxTruthy((ch == "'"))) { pos = (pos + 1);
return [makeSymbol("quote"), readExpr()]; } else if (isSxTruthy((ch == "`"))) { pos = (pos + 1);
return [makeSymbol("quasiquote"), readExpr()]; } else if (isSxTruthy((ch == ","))) { pos = (pos + 1);
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (nth(source, pos) == "@")))) { pos = (pos + 1);
return [makeSymbol("splice-unquote"), readExpr()]; } else { return [makeSymbol("unquote"), readExpr()]; } } else if (isSxTruthy((ch == "#"))) { pos = (pos + 1);
if (isSxTruthy((pos >= lenSrc))) { return error("Unexpected end of input after #"); } else { { var dispatchCh = nth(source, pos);
if (isSxTruthy((dispatchCh == ";"))) { pos = (pos + 1);
readExpr();
continue; } else if (isSxTruthy((dispatchCh == "|"))) { pos = (pos + 1);
return readRawString(); } else if (isSxTruthy((dispatchCh == "'"))) { pos = (pos + 1);
return [makeSymbol("quote"), readExpr()]; } else if (isSxTruthy(isIdentStart(dispatchCh))) { { var macroName = readIdent();
{ var handler = readerMacroGet(macroName);
if (isSxTruthy(handler)) { return handler(readExpr()); } else { return error((String("Unknown reader macro: #") + String(macroName))); } } } } else { return error((String("Unknown reader macro: #") + String(dispatchCh))); } } } } else if (isSxTruthy(sxOr((isSxTruthy((ch >= "0")) && (ch <= "9")), (isSxTruthy((ch == "-")) && isSxTruthy(((pos + 1) < lenSrc)) && (function() {
var nextCh = nth(source, (pos + 1));
return (isSxTruthy((nextCh >= "0")) && (nextCh <= "9"));
})())))) { return readNumber(); } else if (isSxTruthy((isSxTruthy((ch == ".")) && isSxTruthy(((pos + 2) < lenSrc)) && isSxTruthy((nth(source, (pos + 1)) == ".")) && (nth(source, (pos + 2)) == ".")))) { pos = (pos + 3);
return makeSymbol("..."); } else if (isSxTruthy(isIdentStart(ch))) { return readSymbol(); } else { return error((String("Unexpected character: ") + String(ch))); } } } } };
PRIMITIVES["read-expr"] = readExpr;
return (function() {
var exprs = [];
var parseLoop = function() { while(true) { skipWs();
if (isSxTruthy((pos < lenSrc))) { exprs.push(readExpr());
continue; } else { return NIL; } } };
PRIMITIVES["parse-loop"] = parseLoop;
parseLoop();
return exprs;
})();
})(); };
PRIMITIVES["sx-parse"] = sxParse;
// sx-serialize
var sxSerialize = function(val) { return (function() { var _m = typeOf(val); if (_m == "nil") return "nil"; if (_m == "boolean") return (isSxTruthy(val) ? "true" : "false"); if (_m == "number") return (String(val)); if (_m == "string") return (String("\"") + String(escapeString(val)) + String("\"")); if (_m == "symbol") return symbolName(val); if (_m == "keyword") return (String(":") + String(keywordName(val))); if (_m == "list") return (String("(") + String(join(" ", map(sxSerialize, val))) + String(")")); if (_m == "dict") return sxSerializeDict(val); if (_m == "sx-expr") return sxExprSource(val); if (_m == "spread") return (String("(make-spread ") + String(sxSerializeDict(spreadAttrs(val))) + String(")")); return (String(val)); })(); };
PRIMITIVES["sx-serialize"] = sxSerialize;
// sx-serialize-dict
var sxSerializeDict = function(d) { return (String("{") + String(join(" ", reduce(function(acc, key) { return concat(acc, [(String(":") + String(key)), sxSerialize(dictGet(d, key))]); }, [], keys(d)))) + String("}")); };
PRIMITIVES["sx-serialize-dict"] = sxSerializeDict;
// serialize
var serialize = sxSerialize;
PRIMITIVES["serialize"] = serialize;
// === Transpiled from adapter-html ===
// 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 (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 (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
var RENDER_HTML_FORMS = ["if", "when", "cond", "case", "let", "let*", "letrec", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "deftype", "defeffect", "map", "map-indexed", "filter", "for-each", "scope", "provide"];
PRIMITIVES["RENDER_HTML_FORMS"] = RENDER_HTML_FORMS;
// render-html-form?
var isRenderHtmlForm = function(name) { return contains(RENDER_HTML_FORMS, name); };
PRIMITIVES["render-html-form?"] = isRenderHtmlForm;
// render-list-to-html
var renderListToHtml = function(expr, env) { return (isSxTruthy(isEmpty(expr)) ? "" : (function() {
var head = first(expr);
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? join("", map(function(x) { return renderValueToHtml(x, env); }, expr)) : (function() {
var name = symbolName(head);
var args = rest(expr);
return (isSxTruthy((name == "<>")) ? join("", map(function(x) { return renderToHtml(x, env); }, args)) : (isSxTruthy((name == "raw!")) ? join("", map(function(x) { return (String(trampoline(evalExpr(x, env)))); }, args)) : (isSxTruthy((name == "lake")) ? renderHtmlLake(args, env) : (isSxTruthy((name == "marsh")) ? renderHtmlMarsh(args, env) : (isSxTruthy(sxOr((name == "portal"), (name == "error-boundary"), (name == "promise-delayed"))) ? join("", map(function(x) { return renderToHtml(x, env); }, args)) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderHtmlElement(name, args, env) : (isSxTruthy((isSxTruthy(startsWith(name, "~")) && isSxTruthy(envHas(env, name)) && isIsland(envGet(env, name)))) ? renderHtmlIsland(envGet(env, name), args, env) : (isSxTruthy(startsWith(name, "~")) ? (function() {
var val = envGet(env, name);
return (isSxTruthy(isComponent(val)) ? renderHtmlComponent(val, args, env) : (isSxTruthy(isMacro(val)) ? renderToHtml(expandMacro(val, args, env), env) : error((String("Unknown component: ") + String(name)))));
})() : (isSxTruthy(isRenderHtmlForm(name)) ? dispatchHtmlForm(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToHtml(expandMacro(envGet(env, name), args, env), env) : renderValueToHtml(trampoline(evalExpr(expr, env)), env)))))))))));
})());
})()); };
PRIMITIVES["render-list-to-html"] = renderListToHtml;
// dispatch-html-form
var dispatchHtmlForm = function(name, expr, env) { return (isSxTruthy((name == "if")) ? (function() {
var condVal = trampoline(evalExpr(nth(expr, 1), env));
return (isSxTruthy(condVal) ? renderToHtml(nth(expr, 2), env) : (isSxTruthy((len(expr) > 3)) ? renderToHtml(nth(expr, 3), env) : ""));
})() : (isSxTruthy((name == "when")) ? (isSxTruthy(!isSxTruthy(trampoline(evalExpr(nth(expr, 1), env)))) ? "" : (isSxTruthy((len(expr) == 3)) ? renderToHtml(nth(expr, 2), env) : join("", map(function(i) { return renderToHtml(nth(expr, i), env); }, range(2, len(expr)))))) : (isSxTruthy((name == "cond")) ? (function() {
var branch = evalCond(rest(expr), env);
return (isSxTruthy(branch) ? renderToHtml(branch, env) : "");
})() : (isSxTruthy((name == "case")) ? renderToHtml(trampoline(evalExpr(expr, env)), env) : (isSxTruthy((name == "letrec")) ? (function() {
var bindings = nth(expr, 1);
var body = slice(expr, 2);
var local = envExtend(env);
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; (function() {
var pname = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
return envBind(local, pname, NIL);
})(); } }
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; (function() {
var pname = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
return envSet(local, pname, trampoline(evalExpr(nth(pair, 1), local)));
})(); } }
if (isSxTruthy((len(body) > 1))) {
{ var _c = init(body); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
}
return renderToHtml(last(body), local);
})() : (isSxTruthy(sxOr((name == "let"), (name == "let*"))) ? (function() {
var local = processBindings(nth(expr, 1), env);
return (isSxTruthy((len(expr) == 3)) ? renderToHtml(nth(expr, 2), local) : join("", map(function(i) { return renderToHtml(nth(expr, i), local); }, range(2, len(expr)))));
})() : (isSxTruthy(sxOr((name == "begin"), (name == "do"))) ? (isSxTruthy((len(expr) == 2)) ? renderToHtml(nth(expr, 1), env) : join("", map(function(i) { return renderToHtml(nth(expr, i), env); }, range(1, len(expr))))) : (isSxTruthy(isDefinitionForm(name)) ? (trampoline(evalExpr(expr, env)), "") : (isSxTruthy((name == "map")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
return join("", map(function(item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [item], env) : renderToHtml(apply(f, [item]), env)); }, coll));
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
return join("", mapIndexed(function(i, item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [i, item], env) : renderToHtml(apply(f, [i, item]), env)); }, coll));
})() : (isSxTruthy((name == "filter")) ? renderToHtml(trampoline(evalExpr(expr, env)), env) : (isSxTruthy((name == "for-each")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
return join("", map(function(item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [item], env) : renderToHtml(apply(f, [item]), env)); }, coll));
})() : (isSxTruthy((name == "scope")) ? (function() {
var scopeName = trampoline(evalExpr(nth(expr, 1), env));
var restArgs = slice(expr, 2);
var scopeVal = NIL;
var bodyExprs = NIL;
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((scopeVal = trampoline(evalExpr(nth(restArgs, 1), env))), (bodyExprs = slice(restArgs, 2))) : (bodyExprs = restArgs));
scopePush(scopeName, scopeVal);
return (function() {
var result = (isSxTruthy((len(bodyExprs) == 1)) ? renderToHtml(first(bodyExprs), env) : join("", map(function(e) { return renderToHtml(e, env); }, bodyExprs)));
scopePop(scopeName);
return result;
})();
})() : (isSxTruthy((name == "provide")) ? (function() {
var provName = trampoline(evalExpr(nth(expr, 1), env));
var provVal = trampoline(evalExpr(nth(expr, 2), env));
var bodyStart = 3;
var bodyCount = (len(expr) - 3);
scopePush(provName, provVal);
return (function() {
var result = (isSxTruthy((bodyCount == 1)) ? renderToHtml(nth(expr, bodyStart), env) : join("", map(function(i) { return renderToHtml(nth(expr, i), env); }, range(bodyStart, (bodyStart + bodyCount)))));
scopePop(provName);
return result;
})();
})() : renderValueToHtml(trampoline(evalExpr(expr, env)), env))))))))))))))); };
PRIMITIVES["dispatch-html-form"] = dispatchHtmlForm;
// render-lambda-html
var renderLambdaHtml = function(f, args, env) { return (function() {
var local = envMerge(lambdaClosure(f), env);
forEachIndexed(function(i, p) { return envBind(local, p, nth(args, i)); }, lambdaParams(f));
return renderToHtml(lambdaBody(f), local);
})(); };
PRIMITIVES["render-lambda-html"] = renderLambdaHtml;
// render-html-component
var renderHtmlComponent = function(comp, args, env) { return (function() {
var kwargs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
kwargs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
if (isSxTruthy(componentHasChildren(comp))) {
envBind(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
}
return renderToHtml(componentBody(comp), local);
})();
})(); };
PRIMITIVES["render-html-component"] = renderHtmlComponent;
// render-html-element
var renderHtmlElement = function(tag, args, env) { return (function() {
var parsed = parseElementArgs(args, env);
var attrs = first(parsed);
var children = nth(parsed, 1);
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); } }
scopePop("element-attrs");
return (String("<") + String(tag) + String(renderAttrs(attrs)) + String(">") + String(content) + String("</") + String(tag) + String(">"));
})()));
})(); };
PRIMITIVES["render-html-element"] = renderHtmlElement;
// render-html-lake
var renderHtmlLake = function(args, env) { return (function() {
var lakeId = NIL;
var lakeTag = "div";
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var kname = keywordName(arg);
var kval = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
(isSxTruthy((kname == "id")) ? (lakeId = kval) : (isSxTruthy((kname == "tag")) ? (lakeTag = kval) : NIL));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var lakeAttrs = {["data-sx-lake"]: sxOr(lakeId, "")};
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); } }
scopePop("element-attrs");
return (String("<") + String(lakeTag) + String(renderAttrs(lakeAttrs)) + String(">") + String(content) + String("</") + String(lakeTag) + String(">"));
})();
})();
})(); };
PRIMITIVES["render-html-lake"] = renderHtmlLake;
// render-html-marsh
var renderHtmlMarsh = function(args, env) { return (function() {
var marshId = NIL;
var marshTag = "div";
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var kname = keywordName(arg);
var kval = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
(isSxTruthy((kname == "id")) ? (marshId = kval) : (isSxTruthy((kname == "tag")) ? (marshTag = kval) : (isSxTruthy((kname == "transform")) ? NIL : NIL)));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var marshAttrs = {["data-sx-marsh"]: sxOr(marshId, "")};
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); } }
scopePop("element-attrs");
return (String("<") + String(marshTag) + String(renderAttrs(marshAttrs)) + String(">") + String(content) + String("</") + String(marshTag) + String(">"));
})();
})();
})(); };
PRIMITIVES["render-html-marsh"] = renderHtmlMarsh;
// render-html-island
var renderHtmlIsland = function(island, args, env) { return (function() {
var kwargs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
kwargs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var local = envMerge(componentClosure(island), env);
var islandName = componentName(island);
{ var _c = componentParams(island); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
if (isSxTruthy(componentHasChildren(island))) {
envBind(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
}
return (function() {
var bodyHtml = renderToHtml(componentBody(island), local);
var stateSx = serializeIslandState(kwargs);
return (String("<span data-sx-island=\"") + String(escapeAttr(islandName)) + String("\"") + String((isSxTruthy(stateSx) ? (String(" data-sx-state=\"") + String(escapeAttr(stateSx)) + String("\"")) : "")) + String(">") + String(bodyHtml) + String("</span>"));
})();
})();
})(); };
PRIMITIVES["render-html-island"] = renderHtmlIsland;
// serialize-island-state
var serializeIslandState = function(kwargs) { return (isSxTruthy(isEmptyDict(kwargs)) ? NIL : sxSerialize(kwargs)); };
PRIMITIVES["serialize-island-state"] = serializeIslandState;
// === Transpiled from adapter-sx ===
// render-to-sx
var renderToSx = function(expr, env) { return (function() {
var result = aser(expr, env);
return (isSxTruthy((typeOf(result) == "sx-expr")) ? sxExprSource(result) : (isSxTruthy((typeOf(result) == "string")) ? result : serialize(result)));
})(); };
PRIMITIVES["render-to-sx"] = renderToSx;
// aser
var aser = function(expr, env) { setRenderActiveB(true);
return (function() {
var result = (function() { var _m = typeOf(expr); if (_m == "number") return expr; if (_m == "string") return expr; if (_m == "boolean") return expr; if (_m == "nil") return NIL; if (_m == "symbol") return (function() {
var name = symbolName(expr);
return (isSxTruthy(envHas(env, name)) ? envGet(env, name) : (isSxTruthy(isPrimitive(name)) ? getPrimitive(name) : (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : error((String("Undefined symbol: ") + String(name))))))));
})(); if (_m == "keyword") return keywordName(expr); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? [] : aserList(expr, env)); if (_m == "spread") return (scopeEmit("element-attrs", spreadAttrs(expr)), NIL); return expr; })();
return (isSxTruthy(isSpread(result)) ? (scopeEmit("element-attrs", spreadAttrs(result)), NIL) : result);
})(); };
PRIMITIVES["aser"] = aser;
// aser-list
var aserList = function(expr, env) { return (function() {
var head = first(expr);
var args = rest(expr);
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? map(function(x) { return aser(x, env); }, expr) : (function() {
var name = symbolName(head);
return (isSxTruthy((name == "<>")) ? aserFragment(args, env) : (isSxTruthy((name == "raw!")) ? aserCall("raw!", args, env) : (isSxTruthy(startsWith(name, "~")) ? (function() {
var comp = (isSxTruthy(envHas(env, name)) ? envGet(env, name) : NIL);
var expandAll = (isSxTruthy(envHas(env, "expand-components?")) ? expandComponents_p() : false);
return (isSxTruthy((isSxTruthy(comp) && isMacro(comp))) ? aser(expandMacro(comp, args, env), env) : (isSxTruthy((isSxTruthy(comp) && isSxTruthy(isComponent(comp)) && isSxTruthy(!isSxTruthy(isIsland(comp))) && isSxTruthy(sxOr(expandAll, (componentAffinity(comp) == "server"))) && !isSxTruthy((componentAffinity(comp) == "client")))) ? aserExpandComponent(comp, args, env) : aserCall(name, args, env)));
})() : (isSxTruthy((name == "lake")) ? aserCall(name, args, env) : (isSxTruthy((name == "marsh")) ? aserCall(name, args, env) : (isSxTruthy(contains(HTML_TAGS, name)) ? aserCall(name, args, env) : (isSxTruthy(sxOr(isSpecialForm(name), isHoForm(name))) ? aserSpecial(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? aser(expandMacro(envGet(env, name), args, env), env) : (function() {
var f = trampoline(evalExpr(head, env));
var evaledArgs = map(function(a) { return trampoline(evalExpr(a, env)); }, args);
return (isSxTruthy((isSxTruthy(isCallable(f)) && isSxTruthy(!isSxTruthy(isLambda(f))) && isSxTruthy(!isSxTruthy(isComponent(f))) && !isSxTruthy(isIsland(f)))) ? apply(f, evaledArgs) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, evaledArgs, env)) : (isSxTruthy(isComponent(f)) ? aserCall((String("~") + String(componentName(f))), args, env) : (isSxTruthy(isIsland(f)) ? aserCall((String("~") + String(componentName(f))), args, env) : error((String("Not callable: ") + String(inspect(f))))))));
})()))))))));
})());
})(); };
PRIMITIVES["aser-list"] = aserList;
// aser-reserialize
var aserReserialize = function(val) { return (isSxTruthy(!isSxTruthy((typeOf(val) == "list"))) ? serialize(val) : (isSxTruthy(isEmpty(val)) ? "()" : (function() {
var head = first(val);
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? serialize(val) : (function() {
var tag = symbolName(head);
var parts = [tag];
var args = rest(val);
var skip = false;
var i = 0;
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var arg = _c[_i]; (isSxTruthy(skip) ? ((skip = false), (i = (i + 1))) : (isSxTruthy((isSxTruthy((typeOf(arg) == "string")) && isSxTruthy(((i + 1) < len(args))) && isSxTruthy(!isSxTruthy(contains(arg, " "))) && sxOr(startsWith(arg, "class"), startsWith(arg, "id"), startsWith(arg, "sx-"), startsWith(arg, "data-"), startsWith(arg, "style"), startsWith(arg, "href"), startsWith(arg, "src"), startsWith(arg, "type"), startsWith(arg, "name"), startsWith(arg, "value"), startsWith(arg, "placeholder"), startsWith(arg, "action"), startsWith(arg, "method"), startsWith(arg, "target"), startsWith(arg, "role"), startsWith(arg, "for"), startsWith(arg, "on")))) ? (append_b(parts, (String(":") + String(arg))), append_b(parts, serialize(nth(args, (i + 1)))), (skip = true), (i = (i + 1))) : (append_b(parts, aserReserialize(arg)), (i = (i + 1))))); } }
return (String("(") + String(join(" ", parts)) + String(")"));
})());
})())); };
PRIMITIVES["aser-reserialize"] = aserReserialize;
// aser-fragment
var aserFragment = function(children, env) { return (function() {
var parts = [];
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; (function() {
var result = aser(c, env);
return (isSxTruthy(isNil(result)) ? NIL : (isSxTruthy((typeOf(result) == "sx-expr")) ? append_b(parts, sxExprSource(result)) : (isSxTruthy((typeOf(result) == "list")) ? forEach(function(item) { return (isSxTruthy(!isSxTruthy(isNil(item))) ? (isSxTruthy((typeOf(item) == "sx-expr")) ? append_b(parts, sxExprSource(item)) : append_b(parts, aserReserialize(item))) : NIL); }, result) : append_b(parts, serialize(result)))));
})(); } }
return (isSxTruthy(isEmpty(parts)) ? "" : (isSxTruthy((len(parts) == 1)) ? makeSxExpr(first(parts)) : makeSxExpr((String("(<> ") + String(join(" ", parts)) + String(")")))));
})(); };
PRIMITIVES["aser-fragment"] = aserFragment;
// aser-call
var aserCall = function(name, args, env) { return (function() {
var attrParts = [];
var childParts = [];
var skip = false;
var i = 0;
scopePush("element-attrs", NIL);
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var arg = _c[_i]; (isSxTruthy(skip) ? ((skip = false), (i = (i + 1))) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((i + 1) < len(args)))) ? (function() {
var val = aser(nth(args, (i + 1)), env);
if (isSxTruthy(!isSxTruthy(isNil(val)))) {
attrParts.push((String(":") + String(keywordName(arg))));
(isSxTruthy((typeOf(val) == "sx-expr")) ? append_b(attrParts, sxExprSource(val)) : append_b(attrParts, serialize(val)));
}
skip = true;
return (i = (i + 1));
})() : (function() {
var val = aser(arg, env);
if (isSxTruthy(!isSxTruthy(isNil(val)))) {
(isSxTruthy((typeOf(val) == "sx-expr")) ? append_b(childParts, sxExprSource(val)) : (isSxTruthy((typeOf(val) == "list")) ? forEach(function(item) { return (isSxTruthy(!isSxTruthy(isNil(item))) ? (isSxTruthy((typeOf(item) == "sx-expr")) ? append_b(childParts, sxExprSource(item)) : append_b(childParts, serialize(item))) : NIL); }, val) : append_b(childParts, serialize(val))));
}
return (i = (i + 1));
})())); } }
{ var _c = scopePeek("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; { var _c = keys(spreadDict); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; (function() {
var v = dictGet(spreadDict, k);
attrParts.push((String(":") + String(k)));
return append_b(attrParts, serialize(v));
})(); } } } }
scopePop("element-attrs");
return (function() {
var parts = concat([name], attrParts, childParts);
return makeSxExpr((String("(") + String(join(" ", parts)) + String(")")));
})();
})(); };
PRIMITIVES["aser-call"] = aserCall;
// aser-expand-component
var aserExpandComponent = function(comp, args, env) { return (function() {
var params = componentParams(comp);
var local = envMerge(env, componentClosure(comp));
var i = 0;
var skip = false;
var children = [];
{ var _c = params; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, NIL); } }
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var arg = _c[_i]; (isSxTruthy(skip) ? ((skip = false), (i = (i + 1))) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((i + 1) < len(args)))) ? (envBind(local, keywordName(arg), aser(nth(args, (i + 1)), env)), (skip = true), (i = (i + 1))) : (append_b(children, arg), (i = (i + 1))))); } }
if (isSxTruthy(componentHasChildren(comp))) {
(function() {
var aseredChildren = map(function(c) { return aser(c, env); }, children);
return envBind(local, "children", (isSxTruthy((len(aseredChildren) == 1)) ? first(aseredChildren) : aseredChildren));
})();
}
return aser(componentBody(comp), local);
})(); };
PRIMITIVES["aser-expand-component"] = aserExpandComponent;
// SPECIAL_FORM_NAMES
var SPECIAL_FORM_NAMES = ["if", "when", "cond", "case", "and", "or", "let", "let*", "lambda", "fn", "define", "defcomp", "defmacro", "defstyle", "defhandler", "defpage", "defquery", "defaction", "defrelation", "begin", "do", "quote", "quasiquote", "->", "set!", "letrec", "dynamic-wind", "defisland", "deftype", "defeffect", "scope", "provide", "context", "emit!", "emitted"];
PRIMITIVES["SPECIAL_FORM_NAMES"] = SPECIAL_FORM_NAMES;
// HO_FORM_NAMES
var HO_FORM_NAMES = ["map", "map-indexed", "filter", "reduce", "some", "every?", "for-each"];
PRIMITIVES["HO_FORM_NAMES"] = HO_FORM_NAMES;
// special-form?
var isSpecialForm = function(name) { return contains(SPECIAL_FORM_NAMES, name); };
PRIMITIVES["special-form?"] = isSpecialForm;
// ho-form?
var isHoForm = function(name) { return contains(HO_FORM_NAMES, name); };
PRIMITIVES["ho-form?"] = isHoForm;
// aser-special
var aserSpecial = function(name, expr, env) { return (function() {
var args = rest(expr);
return (isSxTruthy((name == "if")) ? (isSxTruthy(trampoline(evalExpr(first(args), env))) ? aser(nth(args, 1), env) : (isSxTruthy((len(args) > 2)) ? aser(nth(args, 2), env) : NIL)) : (isSxTruthy((name == "when")) ? (isSxTruthy(!isSxTruthy(trampoline(evalExpr(first(args), env)))) ? NIL : (function() {
var result = NIL;
{ var _c = rest(args); for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
return result;
})()) : (isSxTruthy((name == "cond")) ? (function() {
var branch = evalCond(args, env);
return (isSxTruthy(branch) ? aser(branch, env) : NIL);
})() : (isSxTruthy((name == "case")) ? (function() {
var matchVal = trampoline(evalExpr(first(args), env));
var clauses = rest(args);
return evalCaseAser(matchVal, clauses, env);
})() : (isSxTruthy(sxOr((name == "let"), (name == "let*"))) ? (function() {
var local = processBindings(first(args), env);
var result = NIL;
{ var _c = rest(args); for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, local); } }
return result;
})() : (isSxTruthy(sxOr((name == "begin"), (name == "do"))) ? (function() {
var result = NIL;
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
return result;
})() : (isSxTruthy((name == "and")) ? (function() {
var result = true;
some(function(arg) { result = trampoline(evalExpr(arg, env));
return !isSxTruthy(result); }, args);
return result;
})() : (isSxTruthy((name == "or")) ? (function() {
var result = false;
some(function(arg) { result = trampoline(evalExpr(arg, env));
return result; }, args);
return result;
})() : (isSxTruthy((name == "map")) ? (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return map(function(item) { return (isSxTruthy(isLambda(f)) ? (function() {
var local = envMerge(lambdaClosure(f), env);
envBind(local, first(lambdaParams(f)), item);
return aser(lambdaBody(f), local);
})() : cekCall(f, [item])); }, coll);
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return mapIndexed(function(i, item) { return (isSxTruthy(isLambda(f)) ? (function() {
var local = envMerge(lambdaClosure(f), env);
envBind(local, first(lambdaParams(f)), i);
envBind(local, nth(lambdaParams(f), 1), item);
return aser(lambdaBody(f), local);
})() : cekCall(f, [i, item])); }, coll);
})() : (isSxTruthy((name == "for-each")) ? (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
var results = [];
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (isSxTruthy(isLambda(f)) ? (function() {
var local = envMerge(lambdaClosure(f), env);
envBind(local, first(lambdaParams(f)), item);
return append_b(results, aser(lambdaBody(f), local));
})() : cekCall(f, [item])); } }
return (isSxTruthy(isEmpty(results)) ? NIL : results);
})() : (isSxTruthy((name == "defisland")) ? (trampoline(evalExpr(expr, env)), serialize(expr)) : (isSxTruthy(sxOr((name == "define"), (name == "defcomp"), (name == "defmacro"), (name == "defstyle"), (name == "defhandler"), (name == "defpage"), (name == "defquery"), (name == "defaction"), (name == "defrelation"), (name == "deftype"), (name == "defeffect"))) ? (trampoline(evalExpr(expr, env)), NIL) : (isSxTruthy((name == "scope")) ? (function() {
var scopeName = trampoline(evalExpr(first(args), env));
var restArgs = rest(args);
var scopeVal = NIL;
var bodyArgs = NIL;
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((scopeVal = trampoline(evalExpr(nth(restArgs, 1), env))), (bodyArgs = slice(restArgs, 2))) : (bodyArgs = restArgs));
scopePush(scopeName, scopeVal);
return (function() {
var result = NIL;
{ var _c = bodyArgs; for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
scopePop(scopeName);
return result;
})();
})() : (isSxTruthy((name == "provide")) ? (function() {
var provName = trampoline(evalExpr(first(args), env));
var provVal = trampoline(evalExpr(nth(args, 1), env));
var result = NIL;
scopePush(provName, provVal);
{ var _c = slice(args, 2); for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
scopePop(provName);
return result;
})() : (isSxTruthy((name == "context")) ? (function() {
var ctxName = trampoline(evalExpr(first(args), env));
var defaultVal = (isSxTruthy((len(args) >= 2)) ? trampoline(evalExpr(nth(args, 1), env)) : NIL);
return (function() {
var val = scopePeek(ctxName);
return (isSxTruthy(isNil(val)) ? defaultVal : val);
})();
})() : (isSxTruthy((name == "emit!")) ? (function() {
var emitName = trampoline(evalExpr(first(args), env));
var emitVal = trampoline(evalExpr(nth(args, 1), env));
scopeEmit(emitName, emitVal);
return NIL;
})() : (isSxTruthy((name == "emitted")) ? (function() {
var emitName = trampoline(evalExpr(first(args), env));
return sxOr(scopePeek(emitName), []);
})() : trampoline(evalExpr(expr, env))))))))))))))))))));
})(); };
PRIMITIVES["aser-special"] = aserSpecial;
// eval-case-aser
var evalCaseAser = function(matchVal, clauses, env) { return (isSxTruthy((len(clauses) < 2)) ? NIL : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == ":else"), (symbolName(test) == "else"))))) ? aser(body, env) : (isSxTruthy((matchVal == trampoline(evalExpr(test, env)))) ? aser(body, env) : evalCaseAser(matchVal, slice(clauses, 2), env)));
})()); };
PRIMITIVES["eval-case-aser"] = evalCaseAser;
// === Transpiled from adapter-dom ===
// SVG_NS
var SVG_NS = "http://www.w3.org/2000/svg";
PRIMITIVES["SVG_NS"] = SVG_NS;
// MATH_NS
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
PRIMITIVES["MATH_NS"] = MATH_NS;
// dom-on
var domOn = function(el, name, handler) { return domListen(el, name, (isSxTruthy(isLambda(handler)) ? (isSxTruthy((0 == len(lambdaParams(handler)))) ? function() { trampoline(callLambda(handler, []));
return runPostRenderHooks(); } : function(e) { trampoline(callLambda(handler, [e]));
return runPostRenderHooks(); }) : handler)); };
PRIMITIVES["dom-on"] = domOn;
// render-to-dom
var renderToDom = function(expr, env, ns) { setRenderActiveB(true);
return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragment(); if (_m == "boolean") return createFragment(); if (_m == "raw-html") return domParseHtml(rawHtmlContent(expr)); if (_m == "string") return createTextNode(expr); if (_m == "number") return createTextNode((String(expr))); if (_m == "symbol") return renderToDom(trampoline(evalExpr(expr, env)), env, ns); if (_m == "keyword") return createTextNode(keywordName(expr)); if (_m == "dom-node") return expr; if (_m == "spread") return (sxEmit("element-attrs", spreadAttrs(expr)), expr); if (_m == "dict") return createFragment(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? createFragment() : renderDomList(expr, env, ns)); return (isSxTruthy(isSignal(expr)) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? reactiveText(expr) : createTextNode((String(deref(expr))))) : createTextNode((String(expr)))); })(); };
PRIMITIVES["render-to-dom"] = renderToDom;
// render-dom-list
var renderDomList = function(expr, env, ns) { return (function() {
var head = first(expr);
return (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
var name = symbolName(head);
var args = rest(expr);
return (isSxTruthy((name == "raw!")) ? renderDomRaw(args, env) : (isSxTruthy((name == "<>")) ? renderDomFragment(args, env, ns) : (isSxTruthy((name == "lake")) ? renderDomLake(args, env, ns) : (isSxTruthy((name == "marsh")) ? renderDomMarsh(args, env, ns) : (isSxTruthy(startsWith(name, "html:")) ? renderDomElement(slice(name, 5), args, env, ns) : (isSxTruthy(isRenderDomForm(name)) ? (isSxTruthy((isSxTruthy(contains(HTML_TAGS, name)) && sxOr((isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword")), ns))) ? renderDomElement(name, args, env, ns) : dispatchRenderForm(name, expr, env, ns)) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToDom(expandMacro(envGet(env, name), args, env), env, ns) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderDomElement(name, args, env, ns) : (isSxTruthy((isSxTruthy(startsWith(name, "~")) && isSxTruthy(envHas(env, name)) && isIsland(envGet(env, name)))) ? renderDomIsland(envGet(env, name), args, env, ns) : (isSxTruthy(startsWith(name, "~")) ? (function() {
var comp = envGet(env, name);
return (isSxTruthy(isComponent(comp)) ? renderDomComponent(comp, args, env, ns) : renderDomUnknownComponent(name));
})() : (isSxTruthy((isSxTruthy((indexOf_(name, "-") > 0)) && isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword"))) ? renderDomElement(name, args, env, ns) : (isSxTruthy(ns) ? renderDomElement(name, args, env, ns) : (isSxTruthy((isSxTruthy((name == "deref")) && sxContext("sx-island-scope", NIL))) ? (function() {
var sigOrVal = trampoline(evalExpr(first(args), env));
return (isSxTruthy(isSignal(sigOrVal)) ? reactiveText(sigOrVal) : createTextNode((String(deref(sigOrVal)))));
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns))))))))))))));
})() : (isSxTruthy(sxOr(isLambda(head), (typeOf(head) == "list"))) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (function() {
var frag = createFragment();
{ var _c = expr; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; (function() {
var result = renderToDom(x, env, ns);
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(frag, result) : NIL);
})(); } }
return frag;
})()));
})(); };
PRIMITIVES["render-dom-list"] = renderDomList;
// render-dom-element
var renderDomElement = function(tag, args, env, ns) { return (function() {
var newNs = (isSxTruthy((tag == "svg")) ? SVG_NS : (isSxTruthy((tag == "math")) ? MATH_NS : ns));
var el = domCreateElement(tag, newNs);
scopePush("element-attrs", NIL);
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var attrName = keywordName(arg);
var attrExpr = nth(args, (get(state, "i") + 1));
(isSxTruthy(startsWith(attrName, "on-")) ? (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return (isSxTruthy(isCallable(attrVal)) ? domOn(el, slice(attrName, 3), attrVal) : NIL);
})() : (isSxTruthy((attrName == "bind")) ? (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return (isSxTruthy(isSignal(attrVal)) ? bindInput(el, attrVal) : NIL);
})() : (isSxTruthy((attrName == "ref")) ? (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return dictSet(attrVal, "current", el);
})() : (isSxTruthy((attrName == "key")) ? (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return domSetAttr(el, "key", (String(attrVal)));
})() : (isSxTruthy(sxContext("sx-island-scope", NIL)) ? reactiveAttr(el, attrName, function() { return trampoline(evalExpr(attrExpr, env)); }) : (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return (isSxTruthy(sxOr(isNil(attrVal), (attrVal == false))) ? NIL : (isSxTruthy(contains(BOOLEAN_ATTRS, attrName)) ? (isSxTruthy(attrVal) ? domSetAttr(el, attrName, "") : NIL) : (isSxTruthy((attrVal == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(attrVal))))));
})())))));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : ((isSxTruthy(!isSxTruthy(contains(VOID_ELEMENTS, tag))) ? (function() {
var child = renderToDom(arg, env, newNs);
return (isSxTruthy((isSxTruthy(isSpread(child)) && sxContext("sx-island-scope", NIL))) ? reactiveSpread(el, function() { return renderToDom(arg, env, newNs); }) : (isSxTruthy(isSpread(child)) ? NIL : domAppend(el, child)));
})() : NIL), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; { var _c = keys(spreadDict); for (var _i = 0; _i < _c.length; _i++) { var key = _c[_i]; (function() {
var val = dictGet(spreadDict, key);
return (isSxTruthy((key == "class")) ? (function() {
var existing = domGetAttr(el, "class");
return domSetAttr(el, "class", (isSxTruthy((isSxTruthy(existing) && !isSxTruthy((existing == "")))) ? (String(existing) + String(" ") + String(val)) : val));
})() : (isSxTruthy((key == "style")) ? (function() {
var existing = domGetAttr(el, "style");
return domSetAttr(el, "style", (isSxTruthy((isSxTruthy(existing) && !isSxTruthy((existing == "")))) ? (String(existing) + String(";") + String(val)) : val));
})() : domSetAttr(el, key, (String(val)))));
})(); } } } }
scopePop("element-attrs");
return el;
})(); };
PRIMITIVES["render-dom-element"] = renderDomElement;
// render-dom-component
var renderDomComponent = function(comp, args, env, ns) { return (function() {
var kwargs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
kwargs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
if (isSxTruthy(componentHasChildren(comp))) {
(function() {
var childFrag = createFragment();
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; (function() {
var result = renderToDom(c, env, ns);
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(childFrag, result) : NIL);
})(); } }
return envBind(local, "children", childFrag);
})();
}
return renderToDom(componentBody(comp), local, ns);
})();
})(); };
PRIMITIVES["render-dom-component"] = renderDomComponent;
// render-dom-fragment
var renderDomFragment = function(args, env, ns) { return (function() {
var frag = createFragment();
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; (function() {
var result = renderToDom(x, env, ns);
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(frag, result) : NIL);
})(); } }
return frag;
})(); };
PRIMITIVES["render-dom-fragment"] = renderDomFragment;
// render-dom-raw
var renderDomRaw = function(args, env) { return (function() {
var frag = createFragment();
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var arg = _c[_i]; (function() {
var val = trampoline(evalExpr(arg, env));
return (isSxTruthy((typeOf(val) == "string")) ? domAppend(frag, domParseHtml(val)) : (isSxTruthy((typeOf(val) == "dom-node")) ? domAppend(frag, domClone(val)) : (isSxTruthy(!isSxTruthy(isNil(val))) ? domAppend(frag, createTextNode((String(val)))) : NIL)));
})(); } }
return frag;
})(); };
PRIMITIVES["render-dom-raw"] = renderDomRaw;
// render-dom-unknown-component
var renderDomUnknownComponent = function(name) { return error((String("Unknown component: ") + String(name))); };
PRIMITIVES["render-dom-unknown-component"] = renderDomUnknownComponent;
// RENDER_DOM_FORMS
var RENDER_DOM_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "map", "map-indexed", "filter", "for-each", "portal", "error-boundary", "scope", "provide"];
PRIMITIVES["RENDER_DOM_FORMS"] = RENDER_DOM_FORMS;
// render-dom-form?
var isRenderDomForm = function(name) { return contains(RENDER_DOM_FORMS, name); };
PRIMITIVES["render-dom-form?"] = isRenderDomForm;
// dispatch-render-form
var dispatchRenderForm = function(name, expr, env, ns) { return (isSxTruthy((name == "if")) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? (function() {
var marker = createComment("r-if");
var currentNodes = [];
var initialResult = NIL;
effect(function() { return (function() {
var result = (function() {
var condVal = trampoline(evalExpr(nth(expr, 1), env));
return (isSxTruthy(condVal) ? renderToDom(nth(expr, 2), env, ns) : (isSxTruthy((len(expr) > 3)) ? renderToDom(nth(expr, 3), env, ns) : createFragment()));
})();
return (isSxTruthy(domParent(marker)) ? (forEach(function(n) { return domRemove(n); }, currentNodes), (currentNodes = (isSxTruthy(domIsFragment(result)) ? domChildNodes(result) : [result])), domInsertAfter(marker, result)) : (initialResult = result));
})(); });
return (isSxTruthy(isSpread(initialResult)) ? initialResult : (function() {
var frag = createFragment();
domAppend(frag, marker);
if (isSxTruthy(initialResult)) {
currentNodes = (isSxTruthy(domIsFragment(initialResult)) ? domChildNodes(initialResult) : [initialResult]);
domAppend(frag, initialResult);
}
return frag;
})());
})() : (function() {
var condVal = trampoline(evalExpr(nth(expr, 1), env));
return (isSxTruthy(condVal) ? renderToDom(nth(expr, 2), env, ns) : (isSxTruthy((len(expr) > 3)) ? renderToDom(nth(expr, 3), env, ns) : createFragment()));
})()) : (isSxTruthy((name == "when")) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? (function() {
var marker = createComment("r-when");
var currentNodes = [];
var initialResult = NIL;
effect(function() { return (isSxTruthy(domParent(marker)) ? (forEach(function(n) { return domRemove(n); }, currentNodes), (currentNodes = []), (isSxTruthy(trampoline(evalExpr(nth(expr, 1), env))) ? (function() {
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
currentNodes = domChildNodes(frag);
return domInsertAfter(marker, frag);
})() : NIL)) : (isSxTruthy(trampoline(evalExpr(nth(expr, 1), env))) ? (function() {
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
currentNodes = domChildNodes(frag);
return (initialResult = frag);
})() : NIL)); });
return (isSxTruthy(isSpread(initialResult)) ? initialResult : (function() {
var frag = createFragment();
domAppend(frag, marker);
if (isSxTruthy(initialResult)) {
domAppend(frag, initialResult);
}
return frag;
})());
})() : (isSxTruthy(!isSxTruthy(trampoline(evalExpr(nth(expr, 1), env)))) ? createFragment() : (function() {
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
return frag;
})())) : (isSxTruthy((name == "cond")) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? (function() {
var marker = createComment("r-cond");
var currentNodes = [];
var initialResult = NIL;
effect(function() { return (function() {
var branch = evalCond(rest(expr), env);
return (isSxTruthy(domParent(marker)) ? (forEach(function(n) { return domRemove(n); }, currentNodes), (currentNodes = []), (isSxTruthy(branch) ? (function() {
var result = renderToDom(branch, env, ns);
currentNodes = (isSxTruthy(domIsFragment(result)) ? domChildNodes(result) : [result]);
return domInsertAfter(marker, result);
})() : NIL)) : (isSxTruthy(branch) ? (function() {
var result = renderToDom(branch, env, ns);
currentNodes = (isSxTruthy(domIsFragment(result)) ? domChildNodes(result) : [result]);
return (initialResult = result);
})() : NIL));
})(); });
return (isSxTruthy(isSpread(initialResult)) ? initialResult : (function() {
var frag = createFragment();
domAppend(frag, marker);
if (isSxTruthy(initialResult)) {
domAppend(frag, initialResult);
}
return frag;
})());
})() : (function() {
var branch = evalCond(rest(expr), env);
return (isSxTruthy(branch) ? renderToDom(branch, env, ns) : createFragment());
})()) : (isSxTruthy((name == "case")) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (isSxTruthy(sxOr((name == "let"), (name == "let*"))) ? (function() {
var local = processBindings(nth(expr, 1), env);
return (isSxTruthy((len(expr) == 3)) ? renderToDom(nth(expr, 2), local, ns) : (function() {
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; (function() {
var result = renderToDom(nth(expr, i), local, ns);
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(frag, result) : NIL);
})(); } }
return frag;
})());
})() : (isSxTruthy(sxOr((name == "begin"), (name == "do"))) ? (isSxTruthy((len(expr) == 2)) ? renderToDom(nth(expr, 1), env, ns) : (function() {
var frag = createFragment();
{ var _c = range(1, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; (function() {
var result = renderToDom(nth(expr, i), env, ns);
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(frag, result) : NIL);
})(); } }
return frag;
})()) : (isSxTruthy(isDefinitionForm(name)) ? (trampoline(evalExpr(expr, env)), createFragment()) : (isSxTruthy((name == "map")) ? (function() {
var collExpr = nth(expr, 2);
return (isSxTruthy((isSxTruthy(sxContext("sx-island-scope", NIL)) && isSxTruthy((typeOf(collExpr) == "list")) && isSxTruthy((len(collExpr) > 1)) && isSxTruthy((typeOf(first(collExpr)) == "symbol")) && (symbolName(first(collExpr)) == "deref"))) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var sig = trampoline(evalExpr(nth(collExpr, 1), env));
return (isSxTruthy(isSignal(sig)) ? reactiveList(f, sig, env, ns) : (function() {
var coll = deref(sig);
var frag = createFragment();
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [item], env, ns) : renderToDom(apply(f, [item]), env, ns));
return domAppend(frag, val);
})(); } }
return frag;
})());
})() : (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [item], env, ns) : renderToDom(apply(f, [item]), env, ns));
return domAppend(frag, val);
})(); } }
return frag;
})());
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
forEachIndexed(function(i, item) { return (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [i, item], env, ns) : renderToDom(apply(f, [i, item]), env, ns));
return domAppend(frag, val);
})(); }, coll);
return frag;
})() : (isSxTruthy((name == "filter")) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (isSxTruthy((name == "portal")) ? renderDomPortal(rest(expr), env, ns) : (isSxTruthy((name == "error-boundary")) ? renderDomErrorBoundary(rest(expr), env, ns) : (isSxTruthy((name == "for-each")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [item], env, ns) : renderToDom(apply(f, [item]), env, ns));
return domAppend(frag, val);
})(); } }
return frag;
})() : (isSxTruthy((name == "scope")) ? (function() {
var scopeName = trampoline(evalExpr(nth(expr, 1), env));
var restArgs = slice(expr, 2);
var scopeVal = NIL;
var bodyExprs = NIL;
var frag = createFragment();
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((scopeVal = trampoline(evalExpr(nth(restArgs, 1), env))), (bodyExprs = slice(restArgs, 2))) : (bodyExprs = restArgs));
scopePush(scopeName, scopeVal);
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; domAppend(frag, renderToDom(e, env, ns)); } }
scopePop(scopeName);
return frag;
})() : (isSxTruthy((name == "provide")) ? (function() {
var provName = trampoline(evalExpr(nth(expr, 1), env));
var provVal = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
scopePush(provName, provVal);
{ var _c = range(3, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
scopePop(provName);
return frag;
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns)))))))))))))))); };
PRIMITIVES["dispatch-render-form"] = dispatchRenderForm;
// render-lambda-dom
var renderLambdaDom = function(f, args, env, ns) { return (function() {
var local = envMerge(lambdaClosure(f), env);
forEachIndexed(function(i, p) { return envBind(local, p, nth(args, i)); }, lambdaParams(f));
return renderToDom(lambdaBody(f), local, ns);
})(); };
PRIMITIVES["render-lambda-dom"] = renderLambdaDom;
// render-dom-island
var renderDomIsland = function(island, args, env, ns) { return (function() {
var kwargs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
kwargs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var local = envMerge(componentClosure(island), env);
var islandName = componentName(island);
{ var _c = componentParams(island); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
if (isSxTruthy(componentHasChildren(island))) {
(function() {
var childFrag = createFragment();
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(childFrag, renderToDom(c, env, ns)); } }
return envBind(local, "children", childFrag);
})();
}
return (function() {
var container = domCreateElement("span", NIL);
var disposers = [];
domSetAttr(container, "data-sx-island", islandName);
markProcessed(container, "island-hydrated");
return (function() {
var bodyDom = withIslandScope(function(disposable) { return append_b(disposers, disposable); }, function() { return renderToDom(componentBody(island), local, ns); });
domAppend(container, bodyDom);
domSetData(container, "sx-disposers", disposers);
return container;
})();
})();
})();
})(); };
PRIMITIVES["render-dom-island"] = renderDomIsland;
// render-dom-lake
var renderDomLake = function(args, env, ns) { return (function() {
var lakeId = NIL;
var lakeTag = "div";
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var kname = keywordName(arg);
var kval = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
(isSxTruthy((kname == "id")) ? (lakeId = kval) : (isSxTruthy((kname == "tag")) ? (lakeTag = kval) : NIL));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var el = domCreateElement(lakeTag, NIL);
domSetAttr(el, "data-sx-lake", sxOr(lakeId, ""));
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(el, renderToDom(c, env, ns)); } }
return el;
})();
})(); };
PRIMITIVES["render-dom-lake"] = renderDomLake;
// render-dom-marsh
var renderDomMarsh = function(args, env, ns) { return (function() {
var marshId = NIL;
var marshTag = "div";
var marshTransform = NIL;
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var kname = keywordName(arg);
var kval = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
(isSxTruthy((kname == "id")) ? (marshId = kval) : (isSxTruthy((kname == "tag")) ? (marshTag = kval) : (isSxTruthy((kname == "transform")) ? (marshTransform = kval) : NIL)));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var el = domCreateElement(marshTag, NIL);
domSetAttr(el, "data-sx-marsh", sxOr(marshId, ""));
if (isSxTruthy(marshTransform)) {
domSetData(el, "sx-marsh-transform", marshTransform);
}
domSetData(el, "sx-marsh-env", env);
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(el, renderToDom(c, env, ns)); } }
return el;
})();
})(); };
PRIMITIVES["render-dom-marsh"] = renderDomMarsh;
// reactive-text
var reactiveText = function(sig) { return (function() {
var node = createTextNode((String(deref(sig))));
effect(function() { return domSetTextContent(node, (String(deref(sig)))); });
return node;
})(); };
PRIMITIVES["reactive-text"] = reactiveText;
// reactive-attr
var reactiveAttr = function(el, attrName, computeFn) { (function() {
var existing = sxOr(domGetAttr(el, "data-sx-reactive-attrs"), "");
var updated = (isSxTruthy(isEmpty(existing)) ? attrName : (String(existing) + String(",") + String(attrName)));
return domSetAttr(el, "data-sx-reactive-attrs", updated);
})();
return effect(function() { return (function() {
var raw = computeFn();
return (function() {
var val = (isSxTruthy(isSignal(raw)) ? deref(raw) : raw);
return (isSxTruthy(sxOr(isNil(val), (val == false))) ? domRemoveAttr(el, attrName) : (isSxTruthy((val == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(val)))));
})();
})(); }); };
PRIMITIVES["reactive-attr"] = reactiveAttr;
// reactive-spread
var reactiveSpread = function(el, renderFn) { return (function() {
var prevClasses = [];
var prevExtraKeys = [];
(function() {
var existing = sxOr(domGetAttr(el, "data-sx-reactive-attrs"), "");
return domSetAttr(el, "data-sx-reactive-attrs", (isSxTruthy(isEmpty(existing)) ? "_spread" : (String(existing) + String(",_spread"))));
})();
return effect(function() { if (isSxTruthy(!isSxTruthy(isEmpty(prevClasses)))) {
(function() {
var current = sxOr(domGetAttr(el, "class"), "");
var tokens = filter(function(c) { return !isSxTruthy((c == "")); }, split(current, " "));
var kept = filter(function(c) { return !isSxTruthy(some(function(pc) { return (pc == c); }, prevClasses)); }, tokens);
return (isSxTruthy(isEmpty(kept)) ? domRemoveAttr(el, "class") : domSetAttr(el, "class", join(" ", kept)));
})();
}
{ var _c = prevExtraKeys; for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; domRemoveAttr(el, k); } }
return (function() {
var result = renderFn();
return (isSxTruthy(isSpread(result)) ? (function() {
var attrs = spreadAttrs(result);
var clsStr = sxOr(dictGet(attrs, "class"), "");
var newClasses = filter(function(c) { return !isSxTruthy((c == "")); }, split(clsStr, " "));
var extraKeys = filter(function(k) { return !isSxTruthy((k == "class")); }, keys(attrs));
prevClasses = newClasses;
prevExtraKeys = extraKeys;
if (isSxTruthy(!isSxTruthy(isEmpty(newClasses)))) {
(function() {
var current = sxOr(domGetAttr(el, "class"), "");
return domSetAttr(el, "class", (isSxTruthy((isSxTruthy(current) && !isSxTruthy((current == "")))) ? (String(current) + String(" ") + String(clsStr)) : clsStr));
})();
}
{ var _c = extraKeys; for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; domSetAttr(el, k, (String(dictGet(attrs, k)))); } }
return runPostRenderHooks();
})() : ((prevClasses = []), (prevExtraKeys = [])));
})(); });
})(); };
PRIMITIVES["reactive-spread"] = reactiveSpread;
// reactive-fragment
var reactiveFragment = function(testFn, renderFn, env, ns) { return (function() {
var marker = createComment("island-fragment");
var currentNodes = [];
effect(function() { { var _c = currentNodes; for (var _i = 0; _i < _c.length; _i++) { var n = _c[_i]; domRemove(n); } }
currentNodes = [];
return (isSxTruthy(testFn()) ? (function() {
var frag = renderFn();
currentNodes = domChildNodes(frag);
return domInsertAfter(marker, frag);
})() : NIL); });
return marker;
})(); };
PRIMITIVES["reactive-fragment"] = reactiveFragment;
// render-list-item
var renderListItem = function(mapFn, item, env, ns) { return (isSxTruthy(isLambda(mapFn)) ? renderLambdaDom(mapFn, [item], env, ns) : renderToDom(apply(mapFn, [item]), env, ns)); };
PRIMITIVES["render-list-item"] = renderListItem;
// extract-key
var extractKey = function(node, index) { return (function() {
var k = domGetAttr(node, "key");
return (isSxTruthy(k) ? (domRemoveAttr(node, "key"), k) : (function() {
var dk = domGetData(node, "key");
return (isSxTruthy(dk) ? (String(dk)) : (String("__idx_") + String(index)));
})());
})(); };
PRIMITIVES["extract-key"] = extractKey;
// reactive-list
var reactiveList = function(mapFn, itemsSig, env, ns) { return (function() {
var container = createFragment();
var marker = createComment("island-list");
var keyMap = {};
var keyOrder = [];
domAppend(container, marker);
effect(function() { return (function() {
var items = deref(itemsSig);
return (isSxTruthy(domParent(marker)) ? (function() {
var newMap = {};
var newKeys = [];
var hasKeys = false;
forEachIndexed(function(idx, item) { return (function() {
var rendered = renderListItem(mapFn, item, env, ns);
var key = extractKey(rendered, idx);
if (isSxTruthy((isSxTruthy(!isSxTruthy(hasKeys)) && !isSxTruthy(startsWith(key, "__idx_"))))) {
hasKeys = true;
}
(isSxTruthy(dictHas(keyMap, key)) ? dictSet(newMap, key, dictGet(keyMap, key)) : dictSet(newMap, key, rendered));
return append_b(newKeys, key);
})(); }, items);
(isSxTruthy(!isSxTruthy(hasKeys)) ? (domRemoveChildrenAfter(marker), (function() {
var frag = createFragment();
{ var _c = newKeys; for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; domAppend(frag, dictGet(newMap, k)); } }
return domInsertAfter(marker, frag);
})()) : (forEach(function(oldKey) { return (isSxTruthy(!isSxTruthy(dictHas(newMap, oldKey))) ? domRemove(dictGet(keyMap, oldKey)) : NIL); }, keyOrder), (function() {
var cursor = marker;
return forEach(function(k) { return (function() {
var node = dictGet(newMap, k);
var next = domNextSibling(cursor);
if (isSxTruthy(!isSxTruthy(isIdentical(node, next)))) {
domInsertAfter(cursor, node);
}
return (cursor = node);
})(); }, newKeys);
})()));
keyMap = newMap;
return (keyOrder = newKeys);
})() : forEachIndexed(function(idx, item) { return (function() {
var rendered = renderListItem(mapFn, item, env, ns);
var key = extractKey(rendered, idx);
keyMap[key] = rendered;
keyOrder.push(key);
return domAppend(container, rendered);
})(); }, items));
})(); });
return container;
})(); };
PRIMITIVES["reactive-list"] = reactiveList;
// bind-input
var bindInput = function(el, sig) { return (function() {
var inputType = lower(sxOr(domGetAttr(el, "type"), ""));
var isCheckbox = sxOr((inputType == "checkbox"), (inputType == "radio"));
(isSxTruthy(isCheckbox) ? domSetProp(el, "checked", deref(sig)) : domSetProp(el, "value", (String(deref(sig)))));
effect(function() { return (isSxTruthy(isCheckbox) ? domSetProp(el, "checked", deref(sig)) : (function() {
var v = (String(deref(sig)));
return (isSxTruthy((domGetProp(el, "value") != v)) ? domSetProp(el, "value", v) : NIL);
})()); });
return domOn(el, (isSxTruthy(isCheckbox) ? "change" : "input"), function(e) { return (isSxTruthy(isCheckbox) ? reset_b(sig, domGetProp(el, "checked")) : reset_b(sig, domGetProp(el, "value"))); });
})(); };
PRIMITIVES["bind-input"] = bindInput;
// *use-cek-reactive*
var _useCekReactive = true;
PRIMITIVES["*use-cek-reactive*"] = _useCekReactive;
// enable-cek-reactive!
var enableCekReactive = function() { return (_useCekReactive = true); };
PRIMITIVES["enable-cek-reactive!"] = enableCekReactive;
// cek-reactive-text
var cekReactiveText = function(expr, env) { return (function() {
var node = createTextNode("");
var updateFn = function(val) { return domSetTextContent(node, (String(val))); };
return (function() {
var initial = cekRun(makeCekState(expr, env, [makeReactiveResetFrame(env, updateFn, true)]));
domSetTextContent(node, (String(initial)));
return node;
})();
})(); };
PRIMITIVES["cek-reactive-text"] = cekReactiveText;
// cek-reactive-attr
var cekReactiveAttr = function(el, attrName, expr, env) { return (function() {
var updateFn = function(val) { return (isSxTruthy(sxOr(isNil(val), (val == false))) ? domRemoveAttr(el, attrName) : (isSxTruthy((val == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(val))))); };
(function() {
var existing = sxOr(domGetAttr(el, "data-sx-reactive-attrs"), "");
var updated = (isSxTruthy(isEmpty(existing)) ? attrName : (String(existing) + String(",") + String(attrName)));
return domSetAttr(el, "data-sx-reactive-attrs", updated);
})();
return (function() {
var initial = cekRun(makeCekState(expr, env, [makeReactiveResetFrame(env, updateFn, true)]));
return cekCall(updateFn, [initial]);
})();
})(); };
PRIMITIVES["cek-reactive-attr"] = cekReactiveAttr;
// render-dom-portal
var renderDomPortal = function(args, env, ns) { return (function() {
var selector = trampoline(evalExpr(first(args), env));
var target = sxOr(domQuery(selector), domEnsureElement(selector));
return (isSxTruthy(!isSxTruthy(target)) ? createComment((String("portal: ") + String(selector) + String(" (not found)"))) : (function() {
var marker = createComment((String("portal: ") + String(selector)));
var frag = createFragment();
{ var _c = rest(args); for (var _i = 0; _i < _c.length; _i++) { var child = _c[_i]; domAppend(frag, renderToDom(child, env, ns)); } }
(function() {
var portalNodes = domChildNodes(frag);
domAppend(target, frag);
return registerInScope(function() { return forEach(function(n) { return domRemove(n); }, portalNodes); });
})();
return marker;
})());
})(); };
PRIMITIVES["render-dom-portal"] = renderDomPortal;
// render-dom-error-boundary
var renderDomErrorBoundary = function(args, env, ns) { return (function() {
var fallbackExpr = first(args);
var bodyExprs = rest(args);
var container = domCreateElement("div", NIL);
var retryVersion = signal(0);
domSetAttr(container, "data-sx-boundary", "true");
effect(function() { deref(retryVersion);
domSetProp(container, "innerHTML", "");
scopePush("sx-island-scope", NIL);
return tryCatch(function() { (function() {
var frag = createFragment();
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var child = _c[_i]; domAppend(frag, renderToDom(child, env, ns)); } }
return domAppend(container, frag);
})();
return scopePop("sx-island-scope"); }, function(err) { scopePop("sx-island-scope");
return (function() {
var fallbackFn = trampoline(evalExpr(fallbackExpr, env));
var retryFn = function() { return swap_b(retryVersion, function(n) { return (n + 1); }); };
return (function() {
var fallbackDom = (isSxTruthy(isLambda(fallbackFn)) ? renderLambdaDom(fallbackFn, [err, retryFn], env, ns) : renderToDom(apply(fallbackFn, [err, retryFn]), env, ns));
return domAppend(container, fallbackDom);
})();
})(); }); });
return container;
})(); };
PRIMITIVES["render-dom-error-boundary"] = renderDomErrorBoundary;
// === Transpiled from engine ===
// ENGINE_VERBS
var ENGINE_VERBS = ["get", "post", "put", "delete", "patch"];
PRIMITIVES["ENGINE_VERBS"] = ENGINE_VERBS;
// DEFAULT_SWAP
var DEFAULT_SWAP = "outerHTML";
PRIMITIVES["DEFAULT_SWAP"] = DEFAULT_SWAP;
// parse-time
var parseTime = function(s) { return (isSxTruthy(isNil(s)) ? 0 : (isSxTruthy(endsWith(s, "ms")) ? parseInt_(s, 0) : (isSxTruthy(endsWith(s, "s")) ? (parseInt_(replace_(s, "s", ""), 0) * 1000) : parseInt_(s, 0)))); };
PRIMITIVES["parse-time"] = parseTime;
// parse-trigger-spec
var parseTriggerSpec = function(spec) { return (isSxTruthy(isNil(spec)) ? NIL : (function() {
var rawParts = split(spec, ",");
return filter(function(x) { return !isSxTruthy(isNil(x)); }, map(function(part) { return (function() {
var tokens = split(trim(part), " ");
return (isSxTruthy(isEmpty(tokens)) ? NIL : (isSxTruthy((isSxTruthy((first(tokens) == "every")) && (len(tokens) >= 2))) ? {["event"]: "every", ["modifiers"]: {["interval"]: parseTime(nth(tokens, 1))}} : (function() {
var mods = {};
{ var _c = rest(tokens); for (var _i = 0; _i < _c.length; _i++) { var tok = _c[_i]; (isSxTruthy((tok == "once")) ? dictSet(mods, "once", true) : (isSxTruthy((tok == "changed")) ? dictSet(mods, "changed", true) : (isSxTruthy(startsWith(tok, "delay:")) ? dictSet(mods, "delay", parseTime(slice(tok, 6))) : (isSxTruthy(startsWith(tok, "from:")) ? dictSet(mods, "from", slice(tok, 5)) : NIL)))); } }
return {["event"]: first(tokens), ["modifiers"]: mods};
})()));
})(); }, rawParts));
})()); };
PRIMITIVES["parse-trigger-spec"] = parseTriggerSpec;
// default-trigger
var defaultTrigger = function(tagName) { return (isSxTruthy((tagName == "FORM")) ? [{["event"]: "submit", ["modifiers"]: {}}] : (isSxTruthy(sxOr((tagName == "INPUT"), (tagName == "SELECT"), (tagName == "TEXTAREA"))) ? [{["event"]: "change", ["modifiers"]: {}}] : [{["event"]: "click", ["modifiers"]: {}}])); };
PRIMITIVES["default-trigger"] = defaultTrigger;
// get-verb-info
var getVerbInfo = function(el) { return some(function(verb) { return (function() {
var url = domGetAttr(el, (String("sx-") + String(verb)));
return (isSxTruthy(url) ? {["method"]: upper(verb), ["url"]: url} : NIL);
})(); }, ENGINE_VERBS); };
PRIMITIVES["get-verb-info"] = getVerbInfo;
// build-request-headers
var buildRequestHeaders = function(el, loadedComponents, cssHash) { return (function() {
var headers = {["SX-Request"]: "true", ["SX-Current-URL"]: browserLocationHref()};
(function() {
var targetSel = domGetAttr(el, "sx-target");
return (isSxTruthy(targetSel) ? dictSet(headers, "SX-Target", targetSel) : NIL);
})();
(function() {
var compHash = domGetAttr(domQuery("script[data-components][data-hash]"), "data-hash");
return (isSxTruthy(compHash) ? dictSet(headers, "SX-Components-Hash", compHash) : NIL);
})();
if (isSxTruthy(cssHash)) {
headers["SX-Css"] = cssHash;
}
(function() {
var extraH = domGetAttr(el, "sx-headers");
return (isSxTruthy(extraH) ? (function() {
var parsed = parseHeaderValue(extraH);
return (isSxTruthy(parsed) ? forEach(function(key) { return dictSet(headers, key, (String(get(parsed, key)))); }, keys(parsed)) : NIL);
})() : NIL);
})();
return headers;
})(); };
PRIMITIVES["build-request-headers"] = buildRequestHeaders;
// process-response-headers
var processResponseHeaders = function(getHeader) { return {["redirect"]: getHeader("SX-Redirect"), ["refresh"]: getHeader("SX-Refresh"), ["trigger"]: getHeader("SX-Trigger"), ["retarget"]: getHeader("SX-Retarget"), ["reswap"]: getHeader("SX-Reswap"), ["location"]: getHeader("SX-Location"), ["replace-url"]: getHeader("SX-Replace-Url"), ["css-hash"]: getHeader("SX-Css-Hash"), ["trigger-swap"]: getHeader("SX-Trigger-After-Swap"), ["trigger-settle"]: getHeader("SX-Trigger-After-Settle"), ["content-type"]: getHeader("Content-Type"), ["cache-invalidate"]: getHeader("SX-Cache-Invalidate"), ["cache-update"]: getHeader("SX-Cache-Update")}; };
PRIMITIVES["process-response-headers"] = processResponseHeaders;
// parse-swap-spec
var parseSwapSpec = function(rawSwap, globalTransitions_p) { return (function() {
var parts = split(sxOr(rawSwap, DEFAULT_SWAP), " ");
var style = first(parts);
var useTransition = globalTransitions_p;
{ var _c = rest(parts); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; (isSxTruthy((p == "transition:true")) ? (useTransition = true) : (isSxTruthy((p == "transition:false")) ? (useTransition = false) : NIL)); } }
return {["style"]: style, ["transition"]: useTransition};
})(); };
PRIMITIVES["parse-swap-spec"] = parseSwapSpec;
// parse-retry-spec
var parseRetrySpec = function(retryAttr) { return (isSxTruthy(isNil(retryAttr)) ? NIL : (function() {
var parts = split(retryAttr, ":");
return {["strategy"]: first(parts), ["start-ms"]: parseInt_(nth(parts, 1), 1000), ["cap-ms"]: parseInt_(nth(parts, 2), 30000)};
})()); };
PRIMITIVES["parse-retry-spec"] = parseRetrySpec;
// next-retry-ms
var nextRetryMs = function(currentMs, capMs) { return min((currentMs * 2), capMs); };
PRIMITIVES["next-retry-ms"] = nextRetryMs;
// filter-params
var filterParams = function(paramsSpec, allParams) { return (isSxTruthy(isNil(paramsSpec)) ? allParams : (isSxTruthy((paramsSpec == "none")) ? [] : (isSxTruthy((paramsSpec == "*")) ? allParams : (isSxTruthy(startsWith(paramsSpec, "not ")) ? (function() {
var excluded = map(trim, split(slice(paramsSpec, 4), ","));
return filter(function(p) { return !isSxTruthy(contains(excluded, first(p))); }, allParams);
})() : (function() {
var allowed = map(trim, split(paramsSpec, ","));
return filter(function(p) { return contains(allowed, first(p)); }, allParams);
})())))); };
PRIMITIVES["filter-params"] = filterParams;
// resolve-target
var resolveTarget = function(el) { return (function() {
var sel = domGetAttr(el, "sx-target");
return (isSxTruthy(sxOr(isNil(sel), (sel == "this"))) ? el : (isSxTruthy((sel == "closest")) ? domParent(el) : domQuery(sel)));
})(); };
PRIMITIVES["resolve-target"] = resolveTarget;
// apply-optimistic
var applyOptimistic = function(el) { return (function() {
var directive = domGetAttr(el, "sx-optimistic");
return (isSxTruthy(isNil(directive)) ? NIL : (function() {
var target = sxOr(resolveTarget(el), el);
var state = {["target"]: target, ["directive"]: directive};
(isSxTruthy((directive == "remove")) ? (dictSet(state, "opacity", domGetStyle(target, "opacity")), domSetStyle(target, "opacity", "0"), domSetStyle(target, "pointer-events", "none")) : (isSxTruthy((directive == "disable")) ? (dictSet(state, "disabled", domGetProp(target, "disabled")), domSetProp(target, "disabled", true)) : (isSxTruthy(startsWith(directive, "add-class:")) ? (function() {
var cls = slice(directive, 10);
state["add-class"] = cls;
return domAddClass(target, cls);
})() : NIL)));
return state;
})());
})(); };
PRIMITIVES["apply-optimistic"] = applyOptimistic;
// revert-optimistic
var revertOptimistic = function(state) { return (isSxTruthy(state) ? (function() {
var target = get(state, "target");
var directive = get(state, "directive");
return (isSxTruthy((directive == "remove")) ? (domSetStyle(target, "opacity", sxOr(get(state, "opacity"), "")), domSetStyle(target, "pointer-events", "")) : (isSxTruthy((directive == "disable")) ? domSetProp(target, "disabled", sxOr(get(state, "disabled"), false)) : (isSxTruthy(get(state, "add-class")) ? domRemoveClass(target, get(state, "add-class")) : NIL)));
})() : NIL); };
PRIMITIVES["revert-optimistic"] = revertOptimistic;
// find-oob-swaps
var findOobSwaps = function(container) { return (function() {
var results = [];
{ var _c = ["sx-swap-oob", "hx-swap-oob"]; for (var _i = 0; _i < _c.length; _i++) { var attr = _c[_i]; (function() {
var oobEls = domQueryAll(container, (String("[") + String(attr) + String("]")));
return forEach(function(oob) { return (function() {
var swapType = sxOr(domGetAttr(oob, attr), "outerHTML");
var targetId = domId(oob);
domRemoveAttr(oob, attr);
return (isSxTruthy(targetId) ? append_b(results, {["element"]: oob, ["swap-type"]: swapType, ["target-id"]: targetId}) : NIL);
})(); }, oobEls);
})(); } }
return results;
})(); };
PRIMITIVES["find-oob-swaps"] = findOobSwaps;
// morph-node
var morphNode = function(oldNode, newNode) { return (isSxTruthy(sxOr(domHasAttr(oldNode, "sx-preserve"), domHasAttr(oldNode, "sx-ignore"))) ? NIL : (isSxTruthy((isSxTruthy(domHasAttr(oldNode, "data-sx-island")) && isSxTruthy(isProcessed(oldNode, "island-hydrated")) && isSxTruthy(domHasAttr(newNode, "data-sx-island")) && (domGetAttr(oldNode, "data-sx-island") == domGetAttr(newNode, "data-sx-island")))) ? morphIslandChildren(oldNode, newNode) : (isSxTruthy(sxOr(!isSxTruthy((domNodeType(oldNode) == domNodeType(newNode))), !isSxTruthy((domNodeName(oldNode) == domNodeName(newNode))))) ? domReplaceChild(domParent(oldNode), domClone(newNode), oldNode) : (isSxTruthy(sxOr((domNodeType(oldNode) == 3), (domNodeType(oldNode) == 8))) ? (isSxTruthy(!isSxTruthy((domTextContent(oldNode) == domTextContent(newNode)))) ? domSetTextContent(oldNode, domTextContent(newNode)) : NIL) : (isSxTruthy((domNodeType(oldNode) == 1)) ? ((isSxTruthy((isSxTruthy(domHasAttr(oldNode, "data-sx-island")) && isSxTruthy(domHasAttr(newNode, "data-sx-island")) && !isSxTruthy((domGetAttr(oldNode, "data-sx-island") == domGetAttr(newNode, "data-sx-island"))))) ? (disposeIslandsIn(oldNode), clearProcessed(oldNode, "island-hydrated")) : NIL), syncAttrs(oldNode, newNode), (isSxTruthy(!isSxTruthy((isSxTruthy(domIsActiveElement(oldNode)) && domIsInputElement(oldNode)))) ? morphChildren(oldNode, newNode) : NIL)) : NIL))))); };
PRIMITIVES["morph-node"] = morphNode;
// sync-attrs
var syncAttrs = function(oldEl, newEl) { return (function() {
var raStr = sxOr(domGetAttr(oldEl, "data-sx-reactive-attrs"), "");
var reactiveAttrs = (isSxTruthy(isEmpty(raStr)) ? [] : split(raStr, ","));
{ var _c = domAttrList(newEl); for (var _i = 0; _i < _c.length; _i++) { var attr = _c[_i]; (function() {
var name = first(attr);
var val = nth(attr, 1);
return (isSxTruthy((isSxTruthy(!isSxTruthy((domGetAttr(oldEl, name) == val))) && !isSxTruthy(contains(reactiveAttrs, name)))) ? domSetAttr(oldEl, name, val) : NIL);
})(); } }
return forEach(function(attr) { return (function() {
var aname = first(attr);
return (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(newEl, aname))) && isSxTruthy(!isSxTruthy(contains(reactiveAttrs, aname))) && !isSxTruthy((aname == "data-sx-reactive-attrs")))) ? domRemoveAttr(oldEl, aname) : NIL);
})(); }, domAttrList(oldEl));
})(); };
PRIMITIVES["sync-attrs"] = syncAttrs;
// morph-children
var morphChildren = function(oldParent, newParent) { return (function() {
var oldKids = domChildList(oldParent);
var newKids = domChildList(newParent);
var oldById = reduce(function(acc, kid) { return (function() {
var id = domId(kid);
return (isSxTruthy(id) ? (dictSet(acc, id, kid), acc) : acc);
})(); }, {}, oldKids);
var oi = 0;
{ var _c = newKids; for (var _i = 0; _i < _c.length; _i++) { var newChild = _c[_i]; (function() {
var matchId = domId(newChild);
var matchById = (isSxTruthy(matchId) ? dictGet(oldById, matchId) : NIL);
return (isSxTruthy((isSxTruthy(matchById) && !isSxTruthy(isNil(matchById)))) ? ((isSxTruthy((isSxTruthy((oi < len(oldKids))) && !isSxTruthy((matchById == nth(oldKids, oi))))) ? domInsertBefore(oldParent, matchById, (isSxTruthy((oi < len(oldKids))) ? nth(oldKids, oi) : NIL)) : NIL), morphNode(matchById, newChild), (oi = (oi + 1))) : (isSxTruthy((oi < len(oldKids))) ? (function() {
var oldChild = nth(oldKids, oi);
return (isSxTruthy((isSxTruthy(domId(oldChild)) && !isSxTruthy(matchId))) ? domInsertBefore(oldParent, domClone(newChild), oldChild) : (morphNode(oldChild, newChild), (oi = (oi + 1))));
})() : domAppend(oldParent, domClone(newChild))));
})(); } }
return forEach(function(i) { return (isSxTruthy((i >= oi)) ? (function() {
var leftover = nth(oldKids, i);
return (isSxTruthy((isSxTruthy(domIsChildOf(leftover, oldParent)) && isSxTruthy(!isSxTruthy(domHasAttr(leftover, "sx-preserve"))) && !isSxTruthy(domHasAttr(leftover, "sx-ignore")))) ? domRemoveChild(oldParent, leftover) : NIL);
})() : NIL); }, range(oi, len(oldKids)));
})(); };
PRIMITIVES["morph-children"] = morphChildren;
// morph-island-children
var morphIslandChildren = function(oldIsland, newIsland) { return (function() {
var oldLakes = domQueryAll(oldIsland, "[data-sx-lake]");
var newLakes = domQueryAll(newIsland, "[data-sx-lake]");
var oldMarshes = domQueryAll(oldIsland, "[data-sx-marsh]");
var newMarshes = domQueryAll(newIsland, "[data-sx-marsh]");
return (function() {
var newLakeMap = {};
var newMarshMap = {};
{ var _c = newLakes; for (var _i = 0; _i < _c.length; _i++) { var lake = _c[_i]; (function() {
var id = domGetAttr(lake, "data-sx-lake");
return (isSxTruthy(id) ? dictSet(newLakeMap, id, lake) : NIL);
})(); } }
{ var _c = newMarshes; for (var _i = 0; _i < _c.length; _i++) { var marsh = _c[_i]; (function() {
var id = domGetAttr(marsh, "data-sx-marsh");
return (isSxTruthy(id) ? dictSet(newMarshMap, id, marsh) : NIL);
})(); } }
{ var _c = oldLakes; for (var _i = 0; _i < _c.length; _i++) { var oldLake = _c[_i]; (function() {
var id = domGetAttr(oldLake, "data-sx-lake");
return (function() {
var newLake = dictGet(newLakeMap, id);
return (isSxTruthy(newLake) ? (syncAttrs(oldLake, newLake), morphChildren(oldLake, newLake)) : NIL);
})();
})(); } }
{ var _c = oldMarshes; for (var _i = 0; _i < _c.length; _i++) { var oldMarsh = _c[_i]; (function() {
var id = domGetAttr(oldMarsh, "data-sx-marsh");
return (function() {
var newMarsh = dictGet(newMarshMap, id);
return (isSxTruthy(newMarsh) ? morphMarsh(oldMarsh, newMarsh, oldIsland) : NIL);
})();
})(); } }
return processSignalUpdates(newIsland);
})();
})(); };
PRIMITIVES["morph-island-children"] = morphIslandChildren;
// morph-marsh
var morphMarsh = function(oldMarsh, newMarsh, islandEl) { return (function() {
var transform = domGetData(oldMarsh, "sx-marsh-transform");
var env = domGetData(oldMarsh, "sx-marsh-env");
var newHtml = domInnerHtml(newMarsh);
return (isSxTruthy((isSxTruthy(env) && isSxTruthy(newHtml) && !isSxTruthy(isEmpty(newHtml)))) ? (function() {
var parsed = parse(newHtml);
return (function() {
var sxContent = (isSxTruthy(transform) ? cekCall(transform, [parsed]) : parsed);
disposeMarshScope(oldMarsh);
return withMarshScope(oldMarsh, function() { return (function() {
var newDom = renderToDom(sxContent, env, NIL);
domRemoveChildrenAfter(oldMarsh, NIL);
return domAppend(oldMarsh, newDom);
})(); });
})();
})() : (syncAttrs(oldMarsh, newMarsh), morphChildren(oldMarsh, newMarsh)));
})(); };
PRIMITIVES["morph-marsh"] = morphMarsh;
// process-signal-updates
var processSignalUpdates = function(root) { return (function() {
var signalEls = domQueryAll(root, "[data-sx-signal]");
return forEach(function(el) { return (function() {
var spec = domGetAttr(el, "data-sx-signal");
return (isSxTruthy(spec) ? (function() {
var colonIdx = indexOf_(spec, ":");
return (isSxTruthy((colonIdx > 0)) ? (function() {
var storeName = slice(spec, 0, colonIdx);
var rawValue = slice(spec, (colonIdx + 1));
(function() {
var parsed = jsonParse(rawValue);
return reset_b(useStore(storeName), parsed);
})();
return domRemoveAttr(el, "data-sx-signal");
})() : NIL);
})() : NIL);
})(); }, signalEls);
})(); };
PRIMITIVES["process-signal-updates"] = processSignalUpdates;
// swap-dom-nodes
var swapDomNodes = function(target, newNodes, strategy) { return (function() { var _m = strategy; if (_m == "innerHTML") return (isSxTruthy(domIsFragment(newNodes)) ? morphChildren(target, newNodes) : (function() {
var wrapper = domCreateElement("div", NIL);
domAppend(wrapper, newNodes);
return morphChildren(target, wrapper);
})()); if (_m == "outerHTML") return (function() {
var parent = domParent(target);
(isSxTruthy(domIsFragment(newNodes)) ? (function() {
var fc = domFirstChild(newNodes);
return (isSxTruthy(fc) ? (morphNode(target, fc), (function() {
var sib = domNextSibling(fc);
return insertRemainingSiblings(parent, target, sib);
})()) : domRemoveChild(parent, target));
})() : morphNode(target, newNodes));
return parent;
})(); if (_m == "afterend") return domInsertAfter(target, newNodes); if (_m == "beforeend") return domAppend(target, newNodes); if (_m == "afterbegin") return domPrepend(target, newNodes); if (_m == "beforebegin") return domInsertBefore(domParent(target), newNodes, target); if (_m == "delete") return domRemoveChild(domParent(target), target); if (_m == "none") return NIL; return (isSxTruthy(domIsFragment(newNodes)) ? morphChildren(target, newNodes) : (function() {
var wrapper = domCreateElement("div", NIL);
domAppend(wrapper, newNodes);
return morphChildren(target, wrapper);
})()); })(); };
PRIMITIVES["swap-dom-nodes"] = swapDomNodes;
// insert-remaining-siblings
var insertRemainingSiblings = function(parent, refNode, sib) { return (isSxTruthy(sib) ? (function() {
var next = domNextSibling(sib);
domInsertAfter(refNode, sib);
return insertRemainingSiblings(parent, sib, next);
})() : NIL); };
PRIMITIVES["insert-remaining-siblings"] = insertRemainingSiblings;
// swap-html-string
var swapHtmlString = function(target, html, strategy) { return (function() { var _m = strategy; if (_m == "innerHTML") return domSetInnerHtml(target, html); if (_m == "outerHTML") return (function() {
var parent = domParent(target);
domInsertAdjacentHtml(target, "afterend", html);
domRemoveChild(parent, target);
return parent;
})(); if (_m == "afterend") return domInsertAdjacentHtml(target, "afterend", html); if (_m == "beforeend") return domInsertAdjacentHtml(target, "beforeend", html); if (_m == "afterbegin") return domInsertAdjacentHtml(target, "afterbegin", html); if (_m == "beforebegin") return domInsertAdjacentHtml(target, "beforebegin", html); if (_m == "delete") return domRemoveChild(domParent(target), target); if (_m == "none") return NIL; return domSetInnerHtml(target, html); })(); };
PRIMITIVES["swap-html-string"] = swapHtmlString;
// handle-history
var handleHistory = function(el, url, respHeaders) { return (function() {
var pushUrl = domGetAttr(el, "sx-push-url");
var replaceUrl = domGetAttr(el, "sx-replace-url");
var hdrReplace = get(respHeaders, "replace-url");
return (isSxTruthy(hdrReplace) ? browserReplaceState(hdrReplace) : (isSxTruthy((isSxTruthy(pushUrl) && !isSxTruthy((pushUrl == "false")))) ? browserPushState((isSxTruthy((pushUrl == "true")) ? url : pushUrl)) : (isSxTruthy((isSxTruthy(replaceUrl) && !isSxTruthy((replaceUrl == "false")))) ? browserReplaceState((isSxTruthy((replaceUrl == "true")) ? url : replaceUrl)) : NIL)));
})(); };
PRIMITIVES["handle-history"] = handleHistory;
// PRELOAD_TTL
var PRELOAD_TTL = 30000;
PRIMITIVES["PRELOAD_TTL"] = PRELOAD_TTL;
// preload-cache-get
var preloadCacheGet = function(cache, url) { return (function() {
var entry = dictGet(cache, url);
return (isSxTruthy(isNil(entry)) ? NIL : (isSxTruthy(((nowMs() - get(entry, "timestamp")) > PRELOAD_TTL)) ? (dictDelete(cache, url), NIL) : (dictDelete(cache, url), entry)));
})(); };
PRIMITIVES["preload-cache-get"] = preloadCacheGet;
// preload-cache-set
var preloadCacheSet = function(cache, url, text, contentType) { return dictSet(cache, url, {["text"]: text, ["content-type"]: contentType, ["timestamp"]: nowMs()}); };
PRIMITIVES["preload-cache-set"] = preloadCacheSet;
// classify-trigger
var classifyTrigger = function(trigger) { return (function() {
var event = get(trigger, "event");
return (isSxTruthy((event == "every")) ? "poll" : (isSxTruthy((event == "intersect")) ? "intersect" : (isSxTruthy((event == "load")) ? "load" : (isSxTruthy((event == "revealed")) ? "revealed" : "event"))));
})(); };
PRIMITIVES["classify-trigger"] = classifyTrigger;
// should-boost-link?
var shouldBoostLink = function(link) { return (function() {
var href = domGetAttr(link, "href");
return (isSxTruthy(href) && isSxTruthy(!isSxTruthy(startsWith(href, "#"))) && isSxTruthy(!isSxTruthy(startsWith(href, "javascript:"))) && isSxTruthy(!isSxTruthy(startsWith(href, "mailto:"))) && isSxTruthy(browserSameOrigin(href)) && isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-get"))) && isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-post"))) && !isSxTruthy(domHasAttr(link, "sx-disable")));
})(); };
PRIMITIVES["should-boost-link?"] = shouldBoostLink;
// should-boost-form?
var shouldBoostForm = function(form) { return (isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-get"))) && isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-post"))) && !isSxTruthy(domHasAttr(form, "sx-disable"))); };
PRIMITIVES["should-boost-form?"] = shouldBoostForm;
// parse-sse-swap
var parseSseSwap = function(el) { return sxOr(domGetAttr(el, "sx-sse-swap"), "message"); };
PRIMITIVES["parse-sse-swap"] = parseSseSwap;
// === Transpiled from orchestration ===
// _preload-cache
var _preloadCache = {};
PRIMITIVES["_preload-cache"] = _preloadCache;
// _css-hash
var _cssHash = "";
PRIMITIVES["_css-hash"] = _cssHash;
// dispatch-trigger-events
var dispatchTriggerEvents = function(el, headerVal) { return (isSxTruthy(headerVal) ? (function() {
var parsed = tryParseJson(headerVal);
return (isSxTruthy(parsed) ? forEach(function(key) { return domDispatch(el, key, get(parsed, key)); }, keys(parsed)) : forEach(function(name) { return (function() {
var trimmed = trim(name);
return (isSxTruthy(!isSxTruthy(isEmpty(trimmed))) ? domDispatch(el, trimmed, {}) : NIL);
})(); }, split(headerVal, ",")));
})() : NIL); };
PRIMITIVES["dispatch-trigger-events"] = dispatchTriggerEvents;
// init-css-tracking
var initCssTracking = function() { return (function() {
var meta = domQuery("meta[name=\"sx-css-classes\"]");
return (isSxTruthy(meta) ? (function() {
var content = domGetAttr(meta, "content");
return (isSxTruthy(content) ? (_cssHash = content) : NIL);
})() : NIL);
})(); };
PRIMITIVES["init-css-tracking"] = initCssTracking;
// execute-request
var executeRequest = function(el, verbInfo, extraParams) { return (function() {
var info = sxOr(getVerbInfo(el), verbInfo);
return (isSxTruthy(isNil(info)) ? promiseResolve(NIL) : (function() {
var verb = get(info, "method");
var url = get(info, "url");
return (isSxTruthy((function() {
var media = domGetAttr(el, "sx-media");
return (isSxTruthy(media) && !isSxTruthy(browserMediaMatches(media)));
})()) ? promiseResolve(NIL) : (isSxTruthy((function() {
var confirmMsg = domGetAttr(el, "sx-confirm");
return (isSxTruthy(confirmMsg) && !isSxTruthy(browserConfirm(confirmMsg)));
})()) ? promiseResolve(NIL) : (function() {
var promptMsg = domGetAttr(el, "sx-prompt");
var promptVal = (isSxTruthy(promptMsg) ? browserPrompt(promptMsg) : NIL);
return (isSxTruthy((isSxTruthy(promptMsg) && isNil(promptVal))) ? promiseResolve(NIL) : (isSxTruthy(!isSxTruthy(validateForRequest(el))) ? promiseResolve(NIL) : doFetch(el, verb, verb, url, (isSxTruthy(promptVal) ? assoc(sxOr(extraParams, {}), "SX-Prompt", promptVal) : extraParams))));
})()));
})());
})(); };
PRIMITIVES["execute-request"] = executeRequest;
// do-fetch
var doFetch = function(el, verb, method, url, extraParams) { return (function() {
var sync = domGetAttr(el, "sx-sync");
if (isSxTruthy((sync == "replace"))) {
abortPrevious(el);
}
(function() {
var targetEl = resolveTarget(el);
return (isSxTruthy((isSxTruthy(targetEl) && !isSxTruthy(isIdentical(el, targetEl)))) ? abortPreviousTarget(targetEl) : NIL);
})();
return (function() {
var ctrl = newAbortController();
trackController(el, ctrl);
(function() {
var targetEl = resolveTarget(el);
return (isSxTruthy(targetEl) ? trackControllerTarget(targetEl, ctrl) : NIL);
})();
return (function() {
var bodyInfo = buildRequestBody(el, method, url);
var finalUrl = get(bodyInfo, "url");
var body = get(bodyInfo, "body");
var ct = get(bodyInfo, "content-type");
var headers = buildRequestHeaders(el, loadedComponentNames(), _cssHash);
var csrf = csrfToken();
if (isSxTruthy(extraParams)) {
{ var _c = keys(extraParams); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; headers[k] = get(extraParams, k); } }
}
if (isSxTruthy(ct)) {
headers["Content-Type"] = ct;
}
if (isSxTruthy(csrf)) {
headers["X-CSRFToken"] = csrf;
}
return (function() {
var cached = preloadCacheGet(_preloadCache, finalUrl);
var optimisticState = applyOptimistic(el);
var indicator = showIndicator(el);
var disabledElts = disableElements(el);
domAddClass(el, "sx-request");
domSetAttr(el, "aria-busy", "true");
domDispatch(el, "sx:beforeRequest", {["url"]: finalUrl, ["method"]: method});
return fetchRequest({["url"]: finalUrl, ["method"]: method, ["headers"]: headers, ["body"]: body, ["signal"]: controllerSignal(ctrl), ["cross-origin"]: isCrossOrigin(finalUrl), ["preloaded"]: cached}, function(respOk, status, getHeader, text) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(respOk)) ? (domDispatch(el, "sx:responseError", {["status"]: status, ["text"]: text}), (isSxTruthy((isSxTruthy(text) && (len(text) > 0))) ? handleFetchSuccess(el, finalUrl, verb, extraParams, getHeader, text) : handleRetry(el, verb, method, finalUrl, extraParams))) : (domDispatch(el, "sx:afterRequest", {["status"]: status}), handleFetchSuccess(el, finalUrl, verb, extraParams, getHeader, text)))); }, function(err) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(isAbortError(err))) ? (logWarn((String("sx:fetch error ") + String(method) + String(" ") + String(finalUrl) + String(" — ") + String(err))), domDispatch(el, "sx:requestError", {["error"]: err})) : NIL)); });
})();
})();
})();
})(); };
PRIMITIVES["do-fetch"] = doFetch;
// handle-fetch-success
var handleFetchSuccess = function(el, url, verb, extraParams, getHeader, text) { return (function() {
var respHeaders = processResponseHeaders(getHeader);
(function() {
var newHash = get(respHeaders, "css-hash");
return (isSxTruthy(newHash) ? (_cssHash = newHash) : NIL);
})();
dispatchTriggerEvents(el, get(respHeaders, "trigger"));
processCacheDirectives(el, respHeaders, text);
return (isSxTruthy(get(respHeaders, "redirect")) ? browserNavigate(get(respHeaders, "redirect")) : (isSxTruthy(get(respHeaders, "refresh")) ? browserReload() : (isSxTruthy(get(respHeaders, "location")) ? fetchLocation(get(respHeaders, "location")) : (function() {
var targetEl = (isSxTruthy(get(respHeaders, "retarget")) ? domQuery(get(respHeaders, "retarget")) : resolveTarget(el));
var swapSpec = parseSwapSpec(sxOr(get(respHeaders, "reswap"), domGetAttr(el, "sx-swap")), domHasClass(domBody(), "sx-transitions"));
var swapStyle = get(swapSpec, "style");
var useTransition = get(swapSpec, "transition");
var ct = sxOr(get(respHeaders, "content-type"), "");
(isSxTruthy(contains(ct, "text/sx")) ? handleSxResponse(el, targetEl, text, swapStyle, useTransition) : handleHtmlResponse(el, targetEl, text, swapStyle, useTransition));
dispatchTriggerEvents(el, get(respHeaders, "trigger-swap"));
handleHistory(el, url, respHeaders);
setTimeout_(function() { if (isSxTruthy(get(respHeaders, "trigger-settle"))) {
dispatchTriggerEvents(el, get(respHeaders, "trigger-settle"));
}
return processSettleHooks(el); }, 20);
return domDispatch(el, "sx:afterSwap", {["target"]: targetEl, ["swap"]: swapStyle});
})())));
})(); };
PRIMITIVES["handle-fetch-success"] = handleFetchSuccess;
// handle-sx-response
var handleSxResponse = function(el, target, text, swapStyle, useTransition) { return (function() {
var cleaned = stripComponentScripts(text);
return (function() {
var final_ = extractResponseCss(cleaned);
return (function() {
var trimmed = trim(final_);
return (isSxTruthy(!isSxTruthy(isEmpty(trimmed))) ? (function() {
var rendered = sxRender(trimmed);
var container = domCreateElement("div", NIL);
domAppend(container, rendered);
processOobSwaps(container, function(t, oob, s) { disposeIslandsIn(t);
swapDomNodes(t, oob, s);
sxHydrate(t);
return processElements(t); });
return (function() {
var selectSel = domGetAttr(el, "sx-select");
var content = (isSxTruthy(selectSel) ? selectFromContainer(container, selectSel) : childrenToFragment(container));
disposeIslandsIn(target);
return withTransition(useTransition, function() { swapDomNodes(target, content, swapStyle);
return postSwap(target); });
})();
})() : NIL);
})();
})();
})(); };
PRIMITIVES["handle-sx-response"] = handleSxResponse;
// handle-html-response
var handleHtmlResponse = function(el, target, text, swapStyle, useTransition) { return (function() {
var doc = domParseHtmlDocument(text);
return (isSxTruthy(doc) ? (function() {
var selectSel = domGetAttr(el, "sx-select");
disposeIslandsIn(target);
return (isSxTruthy(selectSel) ? (function() {
var html = selectHtmlFromDoc(doc, selectSel);
return withTransition(useTransition, function() { swapHtmlString(target, html, swapStyle);
return postSwap(target); });
})() : (function() {
var container = domCreateElement("div", NIL);
domSetInnerHtml(container, domBodyInnerHtml(doc));
processOobSwaps(container, function(t, oob, s) { disposeIslandsIn(t);
swapDomNodes(t, oob, s);
return postSwap(t); });
hoistHeadElements(container);
return withTransition(useTransition, function() { swapDomNodes(target, childrenToFragment(container), swapStyle);
return postSwap(target); });
})());
})() : NIL);
})(); };
PRIMITIVES["handle-html-response"] = handleHtmlResponse;
// handle-retry
var handleRetry = function(el, verb, method, url, extraParams) { return (function() {
var retryAttr = domGetAttr(el, "sx-retry");
var spec = parseRetrySpec(retryAttr);
return (isSxTruthy(spec) ? (function() {
var currentMs = sxOr(domGetAttr(el, "data-sx-retry-ms"), get(spec, "start-ms"));
return (function() {
var ms = parseInt_(currentMs, get(spec, "start-ms"));
domSetAttr(el, "data-sx-retry-ms", (String(nextRetryMs(ms, get(spec, "cap-ms")))));
return setTimeout_(function() { return doFetch(el, verb, method, url, extraParams); }, ms);
})();
})() : NIL);
})(); };
PRIMITIVES["handle-retry"] = handleRetry;
// bind-triggers
var bindTriggers = function(el, verbInfo) { return (function() {
var triggers = sxOr(parseTriggerSpec(domGetAttr(el, "sx-trigger")), defaultTrigger(domTagName(el)));
return forEach(function(trigger) { return (function() {
var kind = classifyTrigger(trigger);
var mods = get(trigger, "modifiers");
return (isSxTruthy((kind == "poll")) ? setInterval_(function() { return executeRequest(el, NIL, NIL); }, get(mods, "interval")) : (isSxTruthy((kind == "intersect")) ? observeIntersection(el, function() { return executeRequest(el, NIL, NIL); }, false, get(mods, "delay")) : (isSxTruthy((kind == "load")) ? setTimeout_(function() { return executeRequest(el, NIL, NIL); }, sxOr(get(mods, "delay"), 0)) : (isSxTruthy((kind == "revealed")) ? observeIntersection(el, function() { return executeRequest(el, NIL, NIL); }, true, get(mods, "delay")) : (isSxTruthy((kind == "event")) ? bindEvent(el, get(trigger, "event"), mods, verbInfo) : NIL)))));
})(); }, triggers);
})(); };
PRIMITIVES["bind-triggers"] = bindTriggers;
// bind-event
var bindEvent = function(el, eventName, mods, verbInfo) { return (function() {
var timer = NIL;
var lastVal = NIL;
var listenTarget = (isSxTruthy(get(mods, "from")) ? domQuery(get(mods, "from")) : el);
return (isSxTruthy(listenTarget) ? domAddListener(listenTarget, eventName, function(e) { return (function() {
var shouldFire = true;
if (isSxTruthy(get(mods, "changed"))) {
(function() {
var val = elementValue(el);
return (isSxTruthy((val == lastVal)) ? (shouldFire = false) : (lastVal = val));
})();
}
return (isSxTruthy((isSxTruthy(shouldFire) && !isSxTruthy((isSxTruthy((eventName == "click")) && eventModifierKey_p(e))))) ? ((isSxTruthy(sxOr((eventName == "submit"), (isSxTruthy((eventName == "click")) && domHasAttr(el, "href")))) ? preventDefault_(e) : NIL), (function() {
var liveInfo = sxOr(getVerbInfo(el), verbInfo);
var isGetLink = (isSxTruthy((eventName == "click")) && isSxTruthy((get(liveInfo, "method") == "GET")) && isSxTruthy(domHasAttr(el, "href")) && !isSxTruthy(get(mods, "delay")));
var clientRouted = false;
if (isSxTruthy(isGetLink)) {
clientRouted = tryClientRoute(urlPathname(get(liveInfo, "url")), domGetAttr(el, "sx-target"));
}
return (isSxTruthy(clientRouted) ? (browserPushState(get(liveInfo, "url")), browserScrollTo(0, 0)) : ((isSxTruthy(isGetLink) ? logInfo((String("sx:route server fetch ") + String(get(liveInfo, "url")))) : NIL), (isSxTruthy(get(mods, "delay")) ? (clearTimeout_(timer), (timer = setTimeout_(function() { return executeRequest(el, NIL, NIL); }, get(mods, "delay")))) : executeRequest(el, NIL, NIL))));
})()) : NIL);
})(); }, (isSxTruthy(get(mods, "once")) ? {["once"]: true} : NIL)) : NIL);
})(); };
PRIMITIVES["bind-event"] = bindEvent;
// post-swap
var postSwap = function(root) { logInfo((String("post-swap: root=") + String((isSxTruthy(root) ? domTagName(root) : "nil"))));
activateScripts(root);
sxProcessScripts(root);
sxHydrate(root);
sxHydrateIslands(root);
runPostRenderHooks();
return processElements(root); };
PRIMITIVES["post-swap"] = postSwap;
// process-settle-hooks
var processSettleHooks = function(el) { return (function() {
var settleExpr = domGetAttr(el, "sx-on-settle");
return (isSxTruthy((isSxTruthy(settleExpr) && !isSxTruthy(isEmpty(settleExpr)))) ? (function() {
var exprs = sxParse(settleExpr);
return forEach(function(expr) { return evalExpr(expr, envExtend({})); }, exprs);
})() : NIL);
})(); };
PRIMITIVES["process-settle-hooks"] = processSettleHooks;
// activate-scripts
var activateScripts = function(root) { return (isSxTruthy(root) ? (function() {
var scripts = domQueryAll(root, "script");
return forEach(function(dead) { return (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(dead, "data-components"))) && !isSxTruthy(domHasAttr(dead, "data-sx-activated")))) ? (function() {
var live = createScriptClone(dead);
domSetAttr(live, "data-sx-activated", "true");
return domReplaceChild(domParent(dead), live, dead);
})() : NIL); }, scripts);
})() : NIL); };
PRIMITIVES["activate-scripts"] = activateScripts;
// process-oob-swaps
var processOobSwaps = function(container, swapFn) { return (function() {
var oobs = findOobSwaps(container);
return forEach(function(oob) { return (function() {
var targetId = get(oob, "target-id");
var target = domQueryById(targetId);
var oobEl = get(oob, "element");
var swapType = get(oob, "swap-type");
if (isSxTruthy(domParent(oobEl))) {
domRemoveChild(domParent(oobEl), oobEl);
}
return (isSxTruthy(target) ? swapFn(target, oobEl, swapType) : NIL);
})(); }, oobs);
})(); };
PRIMITIVES["process-oob-swaps"] = processOobSwaps;
// hoist-head-elements
var hoistHeadElements = function(container) { { var _c = domQueryAll(container, "style[data-sx-css]"); for (var _i = 0; _i < _c.length; _i++) { var style = _c[_i]; if (isSxTruthy(domParent(style))) {
domRemoveChild(domParent(style), style);
}
domAppendToHead(style); } }
return forEach(function(link) { if (isSxTruthy(domParent(link))) {
domRemoveChild(domParent(link), link);
}
return domAppendToHead(link); }, domQueryAll(container, "link[rel=\"stylesheet\"]")); };
PRIMITIVES["hoist-head-elements"] = hoistHeadElements;
// process-boosted
var processBoosted = function(root) { return forEach(function(container) { return boostDescendants(container); }, domQueryAll(sxOr(root, domBody()), "[sx-boost]")); };
PRIMITIVES["process-boosted"] = processBoosted;
// boost-descendants
var boostDescendants = function(container) { return (function() {
var boostTarget = domGetAttr(container, "sx-boost");
{ var _c = domQueryAll(container, "a[href]"); for (var _i = 0; _i < _c.length; _i++) { var link = _c[_i]; if (isSxTruthy((isSxTruthy(!isSxTruthy(isProcessed(link, "boost"))) && shouldBoostLink(link)))) {
markProcessed(link, "boost");
if (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-target"))) && isSxTruthy(boostTarget) && !isSxTruthy((boostTarget == "true"))))) {
domSetAttr(link, "sx-target", boostTarget);
}
if (isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-swap")))) {
domSetAttr(link, "sx-swap", "innerHTML");
}
if (isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-push-url")))) {
domSetAttr(link, "sx-push-url", "true");
}
bindClientRouteLink(link, domGetAttr(link, "href"));
} } }
return forEach(function(form) { return (isSxTruthy((isSxTruthy(!isSxTruthy(isProcessed(form, "boost"))) && shouldBoostForm(form))) ? (markProcessed(form, "boost"), (function() {
var method = upper(sxOr(domGetAttr(form, "method"), "GET"));
var action = sxOr(domGetAttr(form, "action"), browserLocationHref());
if (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-target"))) && isSxTruthy(boostTarget) && !isSxTruthy((boostTarget == "true"))))) {
domSetAttr(form, "sx-target", boostTarget);
}
if (isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-swap")))) {
domSetAttr(form, "sx-swap", "innerHTML");
}
return bindBoostForm(form, method, action);
})()) : NIL); }, domQueryAll(container, "form"));
})(); };
PRIMITIVES["boost-descendants"] = boostDescendants;
// _page-data-cache
var _pageDataCache = {};
PRIMITIVES["_page-data-cache"] = _pageDataCache;
// _page-data-cache-ttl
var _pageDataCacheTtl = 30000;
PRIMITIVES["_page-data-cache-ttl"] = _pageDataCacheTtl;
// page-data-cache-key
var pageDataCacheKey = function(pageName, params) { return (function() {
var base = pageName;
return (isSxTruthy(sxOr(isNil(params), isEmpty(keys(params)))) ? base : (function() {
var parts = [];
{ var _c = keys(params); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; parts.push((String(k) + String("=") + String(get(params, k)))); } }
return (String(base) + String(":") + String(join("&", parts)));
})());
})(); };
PRIMITIVES["page-data-cache-key"] = pageDataCacheKey;
// page-data-cache-get
var pageDataCacheGet = function(cacheKey) { return (function() {
var entry = get(_pageDataCache, cacheKey);
return (isSxTruthy(isNil(entry)) ? NIL : (isSxTruthy(((nowMs() - get(entry, "ts")) > _pageDataCacheTtl)) ? (dictSet(_pageDataCache, cacheKey, NIL), NIL) : get(entry, "data")));
})(); };
PRIMITIVES["page-data-cache-get"] = pageDataCacheGet;
// page-data-cache-set
var pageDataCacheSet = function(cacheKey, data) { return dictSet(_pageDataCache, cacheKey, {"data": data, "ts": nowMs()}); };
PRIMITIVES["page-data-cache-set"] = pageDataCacheSet;
// invalidate-page-cache
var invalidatePageCache = function(pageName) { { var _c = keys(_pageDataCache); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; if (isSxTruthy(sxOr((k == pageName), startsWith(k, (String(pageName) + String(":")))))) {
_pageDataCache[k] = NIL;
} } }
swPostMessage({"type": "invalidate", "page": pageName});
return logInfo((String("sx:cache invalidate ") + String(pageName))); };
PRIMITIVES["invalidate-page-cache"] = invalidatePageCache;
// invalidate-all-page-cache
var invalidateAllPageCache = function() { _pageDataCache = {};
swPostMessage({"type": "invalidate", "page": "*"});
return logInfo("sx:cache invalidate *"); };
PRIMITIVES["invalidate-all-page-cache"] = invalidateAllPageCache;
// update-page-cache
var updatePageCache = function(pageName, data) { return (function() {
var cacheKey = pageDataCacheKey(pageName, {});
pageDataCacheSet(cacheKey, data);
return logInfo((String("sx:cache update ") + String(pageName)));
})(); };
PRIMITIVES["update-page-cache"] = updatePageCache;
// process-cache-directives
var processCacheDirectives = function(el, respHeaders, responseText) { (function() {
var elInvalidate = domGetAttr(el, "sx-cache-invalidate");
return (isSxTruthy(elInvalidate) ? (isSxTruthy((elInvalidate == "*")) ? invalidateAllPageCache() : invalidatePageCache(elInvalidate)) : NIL);
})();
(function() {
var hdrInvalidate = get(respHeaders, "cache-invalidate");
return (isSxTruthy(hdrInvalidate) ? (isSxTruthy((hdrInvalidate == "*")) ? invalidateAllPageCache() : invalidatePageCache(hdrInvalidate)) : NIL);
})();
return (function() {
var hdrUpdate = get(respHeaders, "cache-update");
return (isSxTruthy(hdrUpdate) ? (function() {
var data = parseSxData(responseText);
return (isSxTruthy(data) ? updatePageCache(hdrUpdate, data) : NIL);
})() : NIL);
})(); };
PRIMITIVES["process-cache-directives"] = processCacheDirectives;
// _optimistic-snapshots
var _optimisticSnapshots = {};
PRIMITIVES["_optimistic-snapshots"] = _optimisticSnapshots;
// optimistic-cache-update
var optimisticCacheUpdate = function(cacheKey, mutator) { return (function() {
var cached = pageDataCacheGet(cacheKey);
return (isSxTruthy(cached) ? (function() {
var predicted = mutator(cached);
_optimisticSnapshots[cacheKey] = cached;
pageDataCacheSet(cacheKey, predicted);
return predicted;
})() : NIL);
})(); };
PRIMITIVES["optimistic-cache-update"] = optimisticCacheUpdate;
// optimistic-cache-revert
var optimisticCacheRevert = function(cacheKey) { return (function() {
var snapshot = get(_optimisticSnapshots, cacheKey);
return (isSxTruthy(snapshot) ? (pageDataCacheSet(cacheKey, snapshot), dictDelete(_optimisticSnapshots, cacheKey), snapshot) : NIL);
})(); };
PRIMITIVES["optimistic-cache-revert"] = optimisticCacheRevert;
// optimistic-cache-confirm
var optimisticCacheConfirm = function(cacheKey) { return dictDelete(_optimisticSnapshots, cacheKey); };
PRIMITIVES["optimistic-cache-confirm"] = optimisticCacheConfirm;
// submit-mutation
var submitMutation = function(pageName, params, actionName, payload, mutatorFn, onComplete) { return (function() {
var cacheKey = pageDataCacheKey(pageName, params);
var predicted = optimisticCacheUpdate(cacheKey, mutatorFn);
if (isSxTruthy(predicted)) {
tryRerenderPage(pageName, params, predicted);
}
return executeAction(actionName, payload, function(result) { if (isSxTruthy(result)) {
pageDataCacheSet(cacheKey, result);
}
optimisticCacheConfirm(cacheKey);
if (isSxTruthy(result)) {
tryRerenderPage(pageName, params, result);
}
logInfo((String("sx:optimistic confirmed ") + String(pageName)));
return (isSxTruthy(onComplete) ? onComplete("confirmed") : NIL); }, function(error) { return (function() {
var reverted = optimisticCacheRevert(cacheKey);
if (isSxTruthy(reverted)) {
tryRerenderPage(pageName, params, reverted);
}
logWarn((String("sx:optimistic reverted ") + String(pageName) + String(": ") + String(error)));
return (isSxTruthy(onComplete) ? onComplete("reverted") : NIL);
})(); });
})(); };
PRIMITIVES["submit-mutation"] = submitMutation;
// _is-online
var _isOnline = true;
PRIMITIVES["_is-online"] = _isOnline;
// _offline-queue
var _offlineQueue = [];
PRIMITIVES["_offline-queue"] = _offlineQueue;
// offline-is-online?
var offlineIsOnline_p = function() { return _isOnline; };
PRIMITIVES["offline-is-online?"] = offlineIsOnline_p;
// offline-set-online!
var offlineSetOnline_b = function(val) { return (_isOnline = val); };
PRIMITIVES["offline-set-online!"] = offlineSetOnline_b;
// offline-queue-mutation
var offlineQueueMutation = function(actionName, payload, pageName, params, mutatorFn) { return (function() {
var cacheKey = pageDataCacheKey(pageName, params);
var entry = {["action"]: actionName, ["payload"]: payload, ["page"]: pageName, ["params"]: params, ["timestamp"]: nowMs(), ["status"]: "pending"};
_offlineQueue.push(entry);
(function() {
var predicted = optimisticCacheUpdate(cacheKey, mutatorFn);
return (isSxTruthy(predicted) ? tryRerenderPage(pageName, params, predicted) : NIL);
})();
logInfo((String("sx:offline queued ") + String(actionName) + String(" (") + String(len(_offlineQueue)) + String(" pending)")));
return entry;
})(); };
PRIMITIVES["offline-queue-mutation"] = offlineQueueMutation;
// offline-sync
var offlineSync = function() { return (function() {
var pending = filter(function(e) { return (get(e, "status") == "pending"); }, _offlineQueue);
return (isSxTruthy(!isSxTruthy(isEmpty(pending))) ? (logInfo((String("sx:offline syncing ") + String(len(pending)) + String(" mutations"))), forEach(function(entry) { return executeAction(get(entry, "action"), get(entry, "payload"), function(result) { entry["status"] = "synced";
return logInfo((String("sx:offline synced ") + String(get(entry, "action")))); }, function(error) { entry["status"] = "failed";
return logWarn((String("sx:offline sync failed ") + String(get(entry, "action")) + String(": ") + String(error))); }); }, pending)) : NIL);
})(); };
PRIMITIVES["offline-sync"] = offlineSync;
// offline-pending-count
var offlinePendingCount = function() { return len(filter(function(e) { return (get(e, "status") == "pending"); }, _offlineQueue)); };
PRIMITIVES["offline-pending-count"] = offlinePendingCount;
// offline-aware-mutation
var offlineAwareMutation = function(pageName, params, actionName, payload, mutatorFn, onComplete) { return (isSxTruthy(_isOnline) ? submitMutation(pageName, params, actionName, payload, mutatorFn, onComplete) : (offlineQueueMutation(actionName, payload, pageName, params, mutatorFn), (isSxTruthy(onComplete) ? onComplete("queued") : NIL))); };
PRIMITIVES["offline-aware-mutation"] = offlineAwareMutation;
// current-page-layout
var currentPageLayout = function() { return (function() {
var pathname = urlPathname(browserLocationHref());
var match = findMatchingRoute(pathname, _pageRoutes);
return (isSxTruthy(isNil(match)) ? "" : sxOr(get(match, "layout"), ""));
})(); };
PRIMITIVES["current-page-layout"] = currentPageLayout;
// swap-rendered-content
var swapRenderedContent = function(target, rendered, pathname) { return (disposeIslandsIn(target), domSetTextContent(target, ""), domAppend(target, rendered), hoistHeadElementsFull(target), processElements(target), sxHydrateElements(target), sxHydrateIslands(target), runPostRenderHooks(), domDispatch(target, "sx:clientRoute", {["pathname"]: pathname}), logInfo((String("sx:route client ") + String(pathname)))); };
PRIMITIVES["swap-rendered-content"] = swapRenderedContent;
// resolve-route-target
var resolveRouteTarget = function(targetSel) { return (isSxTruthy((isSxTruthy(targetSel) && !isSxTruthy((targetSel == "true")))) ? domQuery(targetSel) : NIL); };
PRIMITIVES["resolve-route-target"] = resolveRouteTarget;
// deps-satisfied?
var depsSatisfied_p = function(match) { return (function() {
var deps = get(match, "deps");
var loaded = loadedComponentNames();
return (isSxTruthy(sxOr(isNil(deps), isEmpty(deps))) ? true : isEvery(function(dep) { return contains(loaded, dep); }, deps));
})(); };
PRIMITIVES["deps-satisfied?"] = depsSatisfied_p;
// try-client-route
var tryClientRoute = function(pathname, targetSel) { return (function() {
var match = findMatchingRoute(pathname, _pageRoutes);
return (isSxTruthy(isNil(match)) ? (logInfo((String("sx:route no match (") + String(len(_pageRoutes)) + String(" routes) ") + String(pathname))), false) : (function() {
var targetLayout = sxOr(get(match, "layout"), "");
var curLayout = currentPageLayout();
return (isSxTruthy(!isSxTruthy((targetLayout == curLayout))) ? (logInfo((String("sx:route server (layout: ") + String(curLayout) + String(" -> ") + String(targetLayout) + String(") ") + String(pathname))), false) : (function() {
var contentSrc = get(match, "content");
var closure = sxOr(get(match, "closure"), {});
var params = get(match, "params");
var pageName = get(match, "name");
return (isSxTruthy(sxOr(isNil(contentSrc), isEmpty(contentSrc))) ? (logWarn((String("sx:route no content for ") + String(pathname))), false) : (function() {
var target = resolveRouteTarget(targetSel);
return (isSxTruthy(isNil(target)) ? (logWarn((String("sx:route target not found: ") + String(targetSel))), false) : (isSxTruthy(!isSxTruthy(depsSatisfied_p(match))) ? (logInfo((String("sx:route deps miss for ") + String(pageName))), false) : (function() {
var ioDeps = get(match, "io-deps");
var hasIo = (isSxTruthy(ioDeps) && !isSxTruthy(isEmpty(ioDeps)));
var renderPlan = get(match, "render-plan");
if (isSxTruthy(renderPlan)) {
(function() {
var srv = sxOr(get(renderPlan, "server"), []);
var cli = sxOr(get(renderPlan, "client"), []);
return logInfo((String("sx:route plan ") + String(pageName) + String(" — ") + String(len(srv)) + String(" server, ") + String(len(cli)) + String(" client")));
})();
}
if (isSxTruthy(hasIo)) {
registerIoDeps(ioDeps);
}
return (isSxTruthy(get(match, "stream")) ? (logInfo((String("sx:route streaming ") + String(pathname))), fetchStreaming(target, pathname, buildRequestHeaders(target, loadedComponentNames(), _cssHash)), true) : (isSxTruthy(get(match, "has-data")) ? (function() {
var cacheKey = pageDataCacheKey(pageName, params);
var cached = pageDataCacheGet(cacheKey);
return (isSxTruthy(cached) ? (function() {
var env = merge(closure, params, cached);
return (isSxTruthy(hasIo) ? (logInfo((String("sx:route client+cache+async ") + String(pathname))), tryAsyncEvalContent(contentSrc, env, function(rendered) { return (isSxTruthy(isNil(rendered)) ? (logWarn((String("sx:route cache+async eval failed for ") + String(pathname) + String(" — server fallback"))), fetchAndRestore(target, pathname, buildRequestHeaders(target, loadedComponentNames(), _cssHash), 0)) : swapRenderedContent(target, rendered, pathname)); }), true) : (function() {
var rendered = tryEvalContent(contentSrc, env);
return (isSxTruthy(isNil(rendered)) ? (logWarn((String("sx:route cached eval failed for ") + String(pathname))), false) : (logInfo((String("sx:route client+cache ") + String(pathname))), swapRenderedContent(target, rendered, pathname), true));
})());
})() : (logInfo((String("sx:route client+data ") + String(pathname))), resolvePageData(pageName, params, function(data) { pageDataCacheSet(cacheKey, data);
return (function() {
var env = merge(closure, params, data);
return (isSxTruthy(hasIo) ? tryAsyncEvalContent(contentSrc, env, function(rendered) { return (isSxTruthy(isNil(rendered)) ? (logWarn((String("sx:route data+async eval failed for ") + String(pathname) + String(" — server fallback"))), fetchAndRestore(target, pathname, buildRequestHeaders(target, loadedComponentNames(), _cssHash), 0)) : swapRenderedContent(target, rendered, pathname)); }) : (function() {
var rendered = tryEvalContent(contentSrc, env);
return (isSxTruthy(isNil(rendered)) ? (logWarn((String("sx:route data eval failed for ") + String(pathname) + String(" — server fallback"))), fetchAndRestore(target, pathname, buildRequestHeaders(target, loadedComponentNames(), _cssHash), 0)) : swapRenderedContent(target, rendered, pathname));
})());
})(); }), true));
})() : (isSxTruthy(hasIo) ? (logInfo((String("sx:route client+async ") + String(pathname))), tryAsyncEvalContent(contentSrc, merge(closure, params), function(rendered) { return (isSxTruthy(isNil(rendered)) ? (logWarn((String("sx:route async eval failed for ") + String(pathname) + String(" — server fallback"))), fetchAndRestore(target, pathname, buildRequestHeaders(target, loadedComponentNames(), _cssHash), 0)) : swapRenderedContent(target, rendered, pathname)); }), true) : (function() {
var env = merge(closure, params);
var rendered = tryEvalContent(contentSrc, env);
return (isSxTruthy(isNil(rendered)) ? (logInfo((String("sx:route server (eval failed) ") + String(pathname))), false) : (swapRenderedContent(target, rendered, pathname), true));
})())));
})()));
})());
})());
})());
})(); };
PRIMITIVES["try-client-route"] = tryClientRoute;
// bind-client-route-link
var bindClientRouteLink = function(link, href) { return bindClientRouteClick(link, href, function() { return bindBoostLink(link, href); }); };
PRIMITIVES["bind-client-route-link"] = bindClientRouteLink;
// process-sse
var processSse = function(root) { return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "sse"))) ? (markProcessed(el, "sse"), bindSse(el)) : NIL); }, domQueryAll(sxOr(root, domBody()), "[sx-sse]")); };
PRIMITIVES["process-sse"] = processSse;
// bind-sse
var bindSse = function(el) { return (function() {
var url = domGetAttr(el, "sx-sse");
return (isSxTruthy(url) ? (function() {
var source = eventSourceConnect(url, el);
var eventName = parseSseSwap(el);
return eventSourceListen(source, eventName, function(data) { return bindSseSwap(el, data); });
})() : NIL);
})(); };
PRIMITIVES["bind-sse"] = bindSse;
// bind-sse-swap
var bindSseSwap = function(el, data) { return (function() {
var target = resolveTarget(el);
var swapSpec = parseSwapSpec(domGetAttr(el, "sx-swap"), domHasClass(domBody(), "sx-transitions"));
var swapStyle = get(swapSpec, "style");
var useTransition = get(swapSpec, "transition");
var trimmed = trim(data);
return (isSxTruthy(!isSxTruthy(isEmpty(trimmed))) ? (disposeIslandsIn(target), (isSxTruthy(startsWith(trimmed, "(")) ? (function() {
var rendered = sxRender(trimmed);
var container = domCreateElement("div", NIL);
domAppend(container, rendered);
return withTransition(useTransition, function() { swapDomNodes(target, childrenToFragment(container), swapStyle);
return postSwap(target); });
})() : withTransition(useTransition, function() { swapHtmlString(target, trimmed, swapStyle);
return postSwap(target); }))) : NIL);
})(); };
PRIMITIVES["bind-sse-swap"] = bindSseSwap;
// bind-inline-handlers
var bindInlineHandlers = function(root) { return forEach(function(el) { return forEach(function(attr) { return (function() {
var name = first(attr);
var body = nth(attr, 1);
return (isSxTruthy(startsWith(name, "sx-on:")) ? (function() {
var eventName = slice(name, 6);
return (isSxTruthy(!isSxTruthy(isProcessed(el, (String("on:") + String(eventName))))) ? (markProcessed(el, (String("on:") + String(eventName))), (function() {
var exprs = sxParse(body);
return domOn(el, eventName, function(e) { return (function() {
var handlerEnv = envExtend({});
envBind(handlerEnv, "event", e);
envBind(handlerEnv, "this", el);
envBind(handlerEnv, "detail", eventDetail(e));
return forEach(function(expr) { return evalExpr(expr, handlerEnv); }, exprs);
})(); });
})()) : NIL);
})() : NIL);
})(); }, domAttrList(el)); }, domQueryAll(sxOr(root, domBody()), "[sx-on\\:]")); };
PRIMITIVES["bind-inline-handlers"] = bindInlineHandlers;
// bind-preload-for
var bindPreloadFor = function(el) { return (function() {
var preloadAttr = domGetAttr(el, "sx-preload");
return (isSxTruthy(preloadAttr) ? (function() {
var events = (isSxTruthy((preloadAttr == "mousedown")) ? ["mousedown", "touchstart"] : ["mouseover"]);
var debounceMs = (isSxTruthy((preloadAttr == "mousedown")) ? 0 : 100);
return bindPreload(el, events, debounceMs, function() { return (function() {
var info = getVerbInfo(el);
return (isSxTruthy(info) ? doPreload(get(info, "url"), buildRequestHeaders(el, loadedComponentNames(), _cssHash)) : NIL);
})(); });
})() : NIL);
})(); };
PRIMITIVES["bind-preload-for"] = bindPreloadFor;
// do-preload
var doPreload = function(url, headers) { return (isSxTruthy(isNil(preloadCacheGet(_preloadCache, url))) ? fetchPreload(url, headers, _preloadCache) : NIL); };
PRIMITIVES["do-preload"] = doPreload;
// VERB_SELECTOR
var VERB_SELECTOR = (String("[sx-get],[sx-post],[sx-put],[sx-delete],[sx-patch]"));
PRIMITIVES["VERB_SELECTOR"] = VERB_SELECTOR;
// process-elements
var processElements = function(root) { (function() {
var els = domQueryAll(sxOr(root, domBody()), VERB_SELECTOR);
return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "verb"))) ? (markProcessed(el, "verb"), processOne(el)) : NIL); }, els);
})();
processBoosted(root);
processSse(root);
bindInlineHandlers(root);
return processEmitElements(root); };
PRIMITIVES["process-elements"] = processElements;
// process-one
var processOne = function(el) { return (function() {
var verbInfo = getVerbInfo(el);
return (isSxTruthy(verbInfo) ? (isSxTruthy(!isSxTruthy(domHasAttr(el, "sx-disable"))) ? (bindTriggers(el, verbInfo), bindPreloadFor(el)) : NIL) : NIL);
})(); };
PRIMITIVES["process-one"] = processOne;
// process-emit-elements
var processEmitElements = function(root) { return (function() {
var els = domQueryAll(sxOr(root, domBody()), "[data-sx-emit]");
return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "emit"))) ? (markProcessed(el, "emit"), (function() {
var eventName = domGetAttr(el, "data-sx-emit");
return (isSxTruthy(eventName) ? domOn(el, "click", function(e) { return (function() {
var detailJson = domGetAttr(el, "data-sx-emit-detail");
var detail = (isSxTruthy(detailJson) ? jsonParse(detailJson) : {});
return domDispatch(el, eventName, detail);
})(); }) : NIL);
})()) : NIL); }, els);
})(); };
PRIMITIVES["process-emit-elements"] = processEmitElements;
// handle-popstate
var handlePopstate = function(scrollY) { return (function() {
var url = browserLocationHref();
var boostEl = domQuery("[sx-boost]");
var targetSel = (isSxTruthy(boostEl) ? (function() {
var attr = domGetAttr(boostEl, "sx-boost");
return (isSxTruthy((isSxTruthy(attr) && !isSxTruthy((attr == "true")))) ? attr : NIL);
})() : NIL);
var targetSel = sxOr(targetSel, "#main-panel");
var target = domQuery(targetSel);
var pathname = urlPathname(url);
return (isSxTruthy(target) ? (isSxTruthy(tryClientRoute(pathname, targetSel)) ? browserScrollTo(0, scrollY) : (function() {
var headers = buildRequestHeaders(target, loadedComponentNames(), _cssHash);
return fetchAndRestore(target, url, headers, scrollY);
})()) : NIL);
})(); };
PRIMITIVES["handle-popstate"] = handlePopstate;
// engine-init
var engineInit = function() { return (initCssTracking(), sxProcessScripts(NIL), sxHydrate(NIL), processElements(NIL)); };
PRIMITIVES["engine-init"] = engineInit;
// === Transpiled from boot ===
// HEAD_HOIST_SELECTOR
var HEAD_HOIST_SELECTOR = "meta, title, link[rel='canonical'], script[type='application/ld+json']";
PRIMITIVES["HEAD_HOIST_SELECTOR"] = HEAD_HOIST_SELECTOR;
// hoist-head-elements-full
var hoistHeadElementsFull = function(root) { return (function() {
var els = domQueryAll(root, HEAD_HOIST_SELECTOR);
return forEach(function(el) { return (function() {
var tag = lower(domTagName(el));
return (isSxTruthy((tag == "title")) ? (setDocumentTitle(domTextContent(el)), domRemoveChild(domParent(el), el)) : (isSxTruthy((tag == "meta")) ? ((function() {
var name = domGetAttr(el, "name");
var prop = domGetAttr(el, "property");
if (isSxTruthy(name)) {
removeHeadElement((String("meta[name=\"") + String(name) + String("\"]")));
}
return (isSxTruthy(prop) ? removeHeadElement((String("meta[property=\"") + String(prop) + String("\"]"))) : NIL);
})(), domRemoveChild(domParent(el), el), domAppendToHead(el)) : (isSxTruthy((isSxTruthy((tag == "link")) && (domGetAttr(el, "rel") == "canonical"))) ? (removeHeadElement("link[rel=\"canonical\"]"), domRemoveChild(domParent(el), el), domAppendToHead(el)) : (domRemoveChild(domParent(el), el), domAppendToHead(el)))));
})(); }, els);
})(); };
PRIMITIVES["hoist-head-elements-full"] = hoistHeadElementsFull;
// sx-mount
var sxMount = function(target, source, extraEnv) { return (function() {
var el = resolveMountTarget(target);
return (isSxTruthy(el) ? ((isSxTruthy(isEmpty(domChildList(el))) ? (function() {
var node = sxRenderWithEnv(source, extraEnv);
domSetTextContent(el, "");
domAppend(el, node);
return hoistHeadElementsFull(el);
})() : NIL), processElements(el), sxHydrateElements(el), sxHydrateIslands(el), runPostRenderHooks()) : NIL);
})(); };
PRIMITIVES["sx-mount"] = sxMount;
// resolve-suspense
var resolveSuspense = function(id, sx) { processSxScripts(NIL);
return (function() {
var el = domQuery((String("[data-suspense=\"") + String(id) + String("\"]")));
return (isSxTruthy(el) ? (function() {
var exprs = parse(sx);
var env = getRenderEnv(NIL);
domSetTextContent(el, "");
{ var _c = exprs; for (var _i = 0; _i < _c.length; _i++) { var expr = _c[_i]; domAppend(el, renderToDom(expr, env, NIL)); } }
processElements(el);
sxHydrateElements(el);
sxHydrateIslands(el);
runPostRenderHooks();
return domDispatch(el, "sx:resolved", {"id": id});
})() : logWarn((String("resolveSuspense: no element for id=") + String(id))));
})(); };
PRIMITIVES["resolve-suspense"] = resolveSuspense;
// sx-hydrate-elements
var sxHydrateElements = function(root) { return (function() {
var els = domQueryAll(sxOr(root, domBody()), "[data-sx]");
return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "hydrated"))) ? (markProcessed(el, "hydrated"), sxUpdateElement(el, NIL)) : NIL); }, els);
})(); };
PRIMITIVES["sx-hydrate-elements"] = sxHydrateElements;
// sx-update-element
var sxUpdateElement = function(el, newEnv) { return (function() {
var target = resolveMountTarget(el);
return (isSxTruthy(target) ? (function() {
var source = domGetAttr(target, "data-sx");
return (isSxTruthy(source) ? (function() {
var baseEnv = parseEnvAttr(target);
var env = mergeEnvs(baseEnv, newEnv);
return (function() {
var node = sxRenderWithEnv(source, env);
domSetTextContent(target, "");
domAppend(target, node);
return (isSxTruthy(newEnv) ? storeEnvAttr(target, baseEnv, newEnv) : NIL);
})();
})() : NIL);
})() : NIL);
})(); };
PRIMITIVES["sx-update-element"] = sxUpdateElement;
// sx-render-component
var sxRenderComponent = function(name, kwargs, extraEnv) { return (function() {
var fullName = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
return (function() {
var env = getRenderEnv(extraEnv);
var comp = envGet(env, fullName);
return (isSxTruthy(!isSxTruthy(isComponent(comp))) ? error((String("Unknown component: ") + String(fullName))) : (function() {
var callExpr = [makeSymbol(fullName)];
{ var _c = keys(kwargs); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; callExpr.push(makeKeyword(toKebab(k)));
callExpr.push(dictGet(kwargs, k)); } }
return renderToDom(callExpr, env, NIL);
})());
})();
})(); };
PRIMITIVES["sx-render-component"] = sxRenderComponent;
// process-sx-scripts
var processSxScripts = function(root) { return (function() {
var scripts = querySxScripts(root);
return forEach(function(s) { return (isSxTruthy(!isSxTruthy(isProcessed(s, "script"))) ? (markProcessed(s, "script"), (function() {
var text = domTextContent(s);
return (isSxTruthy(domHasAttr(s, "data-components")) ? processComponentScript(s, text) : (isSxTruthy(sxOr(isNil(text), isEmpty(trim(text)))) ? NIL : (isSxTruthy(domHasAttr(s, "data-init")) ? (function() {
var exprs = sxParse(text);
return forEach(function(expr) { return evalExpr(expr, envExtend({})); }, exprs);
})() : (isSxTruthy(domHasAttr(s, "data-mount")) ? (function() {
var mountSel = domGetAttr(s, "data-mount");
var target = domQuery(mountSel);
return (isSxTruthy(target) ? sxMount(target, text, NIL) : NIL);
})() : sxLoadComponents(text)))));
})()) : NIL); }, scripts);
})(); };
PRIMITIVES["process-sx-scripts"] = processSxScripts;
// process-component-script
var processComponentScript = function(script, text) { return (function() {
var hash = domGetAttr(script, "data-hash");
return (isSxTruthy(isNil(hash)) ? (isSxTruthy((isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))))) ? sxLoadComponents(text) : NIL) : (function() {
var hasInline = (isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))));
(function() {
var cachedHash = localStorageGet("sx-components-hash");
return (isSxTruthy((cachedHash == hash)) ? (isSxTruthy(hasInline) ? (localStorageSet("sx-components-hash", hash), localStorageSet("sx-components-src", text), sxLoadComponents(text), logInfo("components: downloaded (cookie stale)")) : (function() {
var cached = localStorageGet("sx-components-src");
return (isSxTruthy(cached) ? (sxLoadComponents(cached), logInfo((String("components: cached (") + String(hash) + String(")")))) : (clearSxCompCookie(), browserReload()));
})()) : (isSxTruthy(hasInline) ? (localStorageSet("sx-components-hash", hash), localStorageSet("sx-components-src", text), sxLoadComponents(text), logInfo((String("components: downloaded (") + String(hash) + String(")")))) : (localStorageRemove("sx-components-hash"), localStorageRemove("sx-components-src"), clearSxCompCookie(), browserReload())));
})();
return setSxCompCookie(hash);
})());
})(); };
PRIMITIVES["process-component-script"] = processComponentScript;
// _page-routes
var _pageRoutes = [];
PRIMITIVES["_page-routes"] = _pageRoutes;
// process-page-scripts
var processPageScripts = function() { return (function() {
var scripts = queryPageScripts();
logInfo((String("pages: found ") + String(len(scripts)) + String(" script tags")));
{ var _c = scripts; for (var _i = 0; _i < _c.length; _i++) { var s = _c[_i]; if (isSxTruthy(!isSxTruthy(isProcessed(s, "pages")))) {
markProcessed(s, "pages");
(function() {
var text = domTextContent(s);
logInfo((String("pages: script text length=") + String((isSxTruthy(text) ? len(text) : 0))));
return (isSxTruthy((isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))))) ? (function() {
var pages = parse(text);
logInfo((String("pages: parsed ") + String(len(pages)) + String(" entries")));
return forEach(function(page) { return append_b(_pageRoutes, merge(page, {"parsed": parseRoutePattern(get(page, "path"))})); }, pages);
})() : logWarn("pages: script tag is empty"));
})();
} } }
return logInfo((String("pages: ") + String(len(_pageRoutes)) + String(" routes loaded")));
})(); };
PRIMITIVES["process-page-scripts"] = processPageScripts;
// sx-hydrate-islands
var sxHydrateIslands = function(root) { return (function() {
var els = domQueryAll(sxOr(root, domBody()), "[data-sx-island]");
logInfo((String("sx-hydrate-islands: ") + String(len(els)) + String(" island(s) in ") + String((isSxTruthy(root) ? "subtree" : "document"))));
return forEach(function(el) { return (isSxTruthy(isProcessed(el, "island-hydrated")) ? logInfo((String(" skip (already hydrated): ") + String(domGetAttr(el, "data-sx-island")))) : (logInfo((String(" hydrating: ") + String(domGetAttr(el, "data-sx-island")))), markProcessed(el, "island-hydrated"), hydrateIsland(el))); }, els);
})(); };
PRIMITIVES["sx-hydrate-islands"] = sxHydrateIslands;
// hydrate-island
var hydrateIsland = function(el) { return (function() {
var name = domGetAttr(el, "data-sx-island");
var stateSx = sxOr(domGetAttr(el, "data-sx-state"), "{}");
return (function() {
var compName = (String("~") + String(name));
var env = getRenderEnv(NIL);
return (function() {
var comp = envGet(env, compName);
return (isSxTruthy(!isSxTruthy(sxOr(isComponent(comp), isIsland(comp)))) ? logWarn((String("hydrate-island: unknown island ") + String(compName))) : (function() {
var kwargs = sxOr(first(sxParse(stateSx)), {});
var disposers = [];
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
return (function() {
var bodyDom = withIslandScope(function(disposable) { return append_b(disposers, disposable); }, function() { return renderToDom(componentBody(comp), local, NIL); });
domSetTextContent(el, "");
domAppend(el, bodyDom);
domSetData(el, "sx-disposers", disposers);
processElements(el);
return logInfo((String("hydrated island: ") + String(compName) + String(" (") + String(len(disposers)) + String(" disposers)")));
})();
})());
})();
})();
})(); };
PRIMITIVES["hydrate-island"] = hydrateIsland;
// dispose-island
var disposeIsland = function(el) { (function() {
var disposers = domGetData(el, "sx-disposers");
return (isSxTruthy(disposers) ? (forEach(function(d) { return (isSxTruthy(isCallable(d)) ? d() : NIL); }, disposers), domSetData(el, "sx-disposers", NIL)) : NIL);
})();
return clearProcessed(el, "island-hydrated"); };
PRIMITIVES["dispose-island"] = disposeIsland;
// dispose-islands-in
var disposeIslandsIn = function(root) { return (isSxTruthy(root) ? (function() {
var islands = domQueryAll(root, "[data-sx-island]");
return (isSxTruthy((isSxTruthy(islands) && !isSxTruthy(isEmpty(islands)))) ? (function() {
var toDispose = filter(function(el) { return !isSxTruthy(isProcessed(el, "island-hydrated")); }, islands);
return (isSxTruthy(!isSxTruthy(isEmpty(toDispose))) ? (logInfo((String("disposing ") + String(len(toDispose)) + String(" island(s)"))), forEach(disposeIsland, toDispose)) : NIL);
})() : NIL);
})() : NIL); };
PRIMITIVES["dispose-islands-in"] = disposeIslandsIn;
// force-dispose-islands-in
var forceDisposeIslandsIn = function(root) { return (isSxTruthy(root) ? (function() {
var islands = domQueryAll(root, "[data-sx-island]");
return (isSxTruthy((isSxTruthy(islands) && !isSxTruthy(isEmpty(islands)))) ? (logInfo((String("force-disposing ") + String(len(islands)) + String(" island(s)"))), forEach(disposeIsland, islands)) : NIL);
})() : NIL); };
PRIMITIVES["force-dispose-islands-in"] = forceDisposeIslandsIn;
// *pre-render-hooks*
var _preRenderHooks_ = [];
PRIMITIVES["*pre-render-hooks*"] = _preRenderHooks_;
// *post-render-hooks*
var _postRenderHooks_ = [];
PRIMITIVES["*post-render-hooks*"] = _postRenderHooks_;
// register-pre-render-hook
var registerPreRenderHook = function(hookFn) { return append_b(_preRenderHooks_, hookFn); };
PRIMITIVES["register-pre-render-hook"] = registerPreRenderHook;
// register-post-render-hook
var registerPostRenderHook = function(hookFn) { return append_b(_postRenderHooks_, hookFn); };
PRIMITIVES["register-post-render-hook"] = registerPostRenderHook;
// run-pre-render-hooks
var runPreRenderHooks = function() { return forEach(function(hook) { return cekCall(hook, NIL); }, _preRenderHooks_); };
PRIMITIVES["run-pre-render-hooks"] = runPreRenderHooks;
// run-post-render-hooks
var runPostRenderHooks = function() { logInfo("run-post-render-hooks:", len(_postRenderHooks_), "hooks");
return forEach(function(hook) { logInfo(" hook type:", typeOf(hook), "callable:", isCallable(hook), "lambda:", isLambda(hook));
return cekCall(hook, NIL); }, _postRenderHooks_); };
PRIMITIVES["run-post-render-hooks"] = runPostRenderHooks;
// boot-init
var bootInit = function() { return (logInfo((String("sx-browser ") + String(SX_VERSION))), initCssTracking(), processPageScripts(), processSxScripts(NIL), sxHydrateElements(NIL), sxHydrateIslands(NIL), runPostRenderHooks(), processElements(NIL)); };
PRIMITIVES["boot-init"] = bootInit;
// === Transpiled from deps (component dependency analysis) ===
// scan-refs
var scanRefs = function(node) { return (function() {
var refs = [];
scanRefsWalk(node, refs);
return refs;
})(); };
PRIMITIVES["scan-refs"] = scanRefs;
// scan-refs-walk
var scanRefsWalk = function(node, refs) { return (isSxTruthy((typeOf(node) == "symbol")) ? (function() {
var name = symbolName(node);
return (isSxTruthy(startsWith(name, "~")) ? (isSxTruthy(!isSxTruthy(contains(refs, name))) ? append_b(refs, name) : NIL) : NIL);
})() : (isSxTruthy((typeOf(node) == "list")) ? forEach(function(item) { return scanRefsWalk(item, refs); }, node) : (isSxTruthy((typeOf(node) == "dict")) ? forEach(function(key) { return scanRefsWalk(dictGet(node, key), refs); }, keys(node)) : NIL))); };
PRIMITIVES["scan-refs-walk"] = scanRefsWalk;
// transitive-deps-walk
var transitiveDepsWalk = function(n, seen, env) { return (isSxTruthy(!isSxTruthy(contains(seen, n))) ? (append_b(seen, n), (function() {
var val = envGet(env, n);
return (isSxTruthy(sxOr((typeOf(val) == "component"), (typeOf(val) == "island"))) ? forEach(function(ref) { return transitiveDepsWalk(ref, seen, env); }, scanRefs(componentBody(val))) : (isSxTruthy((typeOf(val) == "macro")) ? forEach(function(ref) { return transitiveDepsWalk(ref, seen, env); }, scanRefs(macroBody(val))) : NIL));
})()) : NIL); };
PRIMITIVES["transitive-deps-walk"] = transitiveDepsWalk;
// transitive-deps
var transitiveDeps = function(name, env) { return (function() {
var seen = [];
var key = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
transitiveDepsWalk(key, seen, env);
return filter(function(x) { return !isSxTruthy((x == key)); }, seen);
})(); };
PRIMITIVES["transitive-deps"] = transitiveDeps;
// compute-all-deps
var computeAllDeps = function(env) { return forEach(function(name) { return (function() {
var val = envGet(env, name);
return (isSxTruthy(sxOr((typeOf(val) == "component"), (typeOf(val) == "island"))) ? componentSetDeps(val, transitiveDeps(name, env)) : NIL);
})(); }, envComponents(env)); };
PRIMITIVES["compute-all-deps"] = computeAllDeps;
// scan-components-from-source
var scanComponentsFromSource = function(source) { return (function() {
var matches = regexFindAll("\\(~([a-zA-Z_][a-zA-Z0-9_\\-:/]*)", source);
return map(function(m) { return (String("~") + String(m)); }, matches);
})(); };
PRIMITIVES["scan-components-from-source"] = scanComponentsFromSource;
// components-needed
var componentsNeeded = function(pageSource, env) { return (function() {
var direct = scanComponentsFromSource(pageSource);
var allNeeded = [];
{ var _c = direct; for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; if (isSxTruthy(!isSxTruthy(contains(allNeeded, name)))) {
allNeeded.push(name);
}
(function() {
var val = envGet(env, name);
return (function() {
var deps = (isSxTruthy((isSxTruthy((typeOf(val) == "component")) && !isSxTruthy(isEmpty(componentDeps(val))))) ? componentDeps(val) : transitiveDeps(name, env));
return forEach(function(dep) { return (isSxTruthy(!isSxTruthy(contains(allNeeded, dep))) ? append_b(allNeeded, dep) : NIL); }, deps);
})();
})(); } }
return allNeeded;
})(); };
PRIMITIVES["components-needed"] = componentsNeeded;
// page-component-bundle
var pageComponentBundle = function(pageSource, env) { return componentsNeeded(pageSource, env); };
PRIMITIVES["page-component-bundle"] = pageComponentBundle;
// page-css-classes
var pageCssClasses = function(pageSource, env) { return (function() {
var needed = componentsNeeded(pageSource, env);
var classes = [];
{ var _c = needed; for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; (function() {
var val = envGet(env, name);
return (isSxTruthy((typeOf(val) == "component")) ? forEach(function(cls) { return (isSxTruthy(!isSxTruthy(contains(classes, cls))) ? append_b(classes, cls) : NIL); }, componentCssClasses(val)) : NIL);
})(); } }
{ var _c = scanCssClasses(pageSource); for (var _i = 0; _i < _c.length; _i++) { var cls = _c[_i]; if (isSxTruthy(!isSxTruthy(contains(classes, cls)))) {
classes.push(cls);
} } }
return classes;
})(); };
PRIMITIVES["page-css-classes"] = pageCssClasses;
// scan-io-refs-walk
var scanIoRefsWalk = function(node, ioNames, refs) { return (isSxTruthy((typeOf(node) == "symbol")) ? (function() {
var name = symbolName(node);
return (isSxTruthy(contains(ioNames, name)) ? (isSxTruthy(!isSxTruthy(contains(refs, name))) ? append_b(refs, name) : NIL) : NIL);
})() : (isSxTruthy((typeOf(node) == "list")) ? forEach(function(item) { return scanIoRefsWalk(item, ioNames, refs); }, node) : (isSxTruthy((typeOf(node) == "dict")) ? forEach(function(key) { return scanIoRefsWalk(dictGet(node, key), ioNames, refs); }, keys(node)) : NIL))); };
PRIMITIVES["scan-io-refs-walk"] = scanIoRefsWalk;
// scan-io-refs
var scanIoRefs = function(node, ioNames) { return (function() {
var refs = [];
scanIoRefsWalk(node, ioNames, refs);
return refs;
})(); };
PRIMITIVES["scan-io-refs"] = scanIoRefs;
// transitive-io-refs-walk
var transitiveIoRefsWalk = function(n, seen, allRefs, env, ioNames) { return (isSxTruthy(!isSxTruthy(contains(seen, n))) ? (append_b(seen, n), (function() {
var val = envGet(env, n);
return (isSxTruthy((typeOf(val) == "component")) ? (forEach(function(ref) { return (isSxTruthy(!isSxTruthy(contains(allRefs, ref))) ? append_b(allRefs, ref) : NIL); }, scanIoRefs(componentBody(val), ioNames)), forEach(function(dep) { return transitiveIoRefsWalk(dep, seen, allRefs, env, ioNames); }, scanRefs(componentBody(val)))) : (isSxTruthy((typeOf(val) == "macro")) ? (forEach(function(ref) { return (isSxTruthy(!isSxTruthy(contains(allRefs, ref))) ? append_b(allRefs, ref) : NIL); }, scanIoRefs(macroBody(val), ioNames)), forEach(function(dep) { return transitiveIoRefsWalk(dep, seen, allRefs, env, ioNames); }, scanRefs(macroBody(val)))) : NIL));
})()) : NIL); };
PRIMITIVES["transitive-io-refs-walk"] = transitiveIoRefsWalk;
// transitive-io-refs
var transitiveIoRefs = function(name, env, ioNames) { return (function() {
var allRefs = [];
var seen = [];
var key = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
transitiveIoRefsWalk(key, seen, allRefs, env, ioNames);
return allRefs;
})(); };
PRIMITIVES["transitive-io-refs"] = transitiveIoRefs;
// compute-all-io-refs
var computeAllIoRefs = function(env, ioNames) { return forEach(function(name) { return (function() {
var val = envGet(env, name);
return (isSxTruthy((typeOf(val) == "component")) ? componentSetIoRefs(val, transitiveIoRefs(name, env, ioNames)) : NIL);
})(); }, envComponents(env)); };
PRIMITIVES["compute-all-io-refs"] = computeAllIoRefs;
// component-io-refs-cached
var componentIoRefsCached = function(name, env, ioNames) { return (function() {
var key = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
return (function() {
var val = envGet(env, key);
return (isSxTruthy((isSxTruthy((typeOf(val) == "component")) && isSxTruthy(!isSxTruthy(isNil(componentIoRefs(val)))) && !isSxTruthy(isEmpty(componentIoRefs(val))))) ? componentIoRefs(val) : transitiveIoRefs(name, env, ioNames));
})();
})(); };
PRIMITIVES["component-io-refs-cached"] = componentIoRefsCached;
// component-pure?
var componentPure_p = function(name, env, ioNames) { return (function() {
var key = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
return (function() {
var val = envGet(env, key);
return (isSxTruthy((isSxTruthy((typeOf(val) == "component")) && !isSxTruthy(isNil(componentIoRefs(val))))) ? isEmpty(componentIoRefs(val)) : isEmpty(transitiveIoRefs(name, env, ioNames)));
})();
})(); };
PRIMITIVES["component-pure?"] = componentPure_p;
// render-target
var renderTarget = function(name, env, ioNames) { return (function() {
var key = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
return (function() {
var val = envGet(env, key);
return (isSxTruthy(!isSxTruthy((typeOf(val) == "component"))) ? "server" : (function() {
var affinity = componentAffinity(val);
return (isSxTruthy((affinity == "server")) ? "server" : (isSxTruthy((affinity == "client")) ? "client" : (isSxTruthy(!isSxTruthy(componentPure_p(name, env, ioNames))) ? "server" : "client")));
})());
})();
})(); };
PRIMITIVES["render-target"] = renderTarget;
// page-render-plan
var pageRenderPlan = function(pageSource, env, ioNames) { return (function() {
var needed = componentsNeeded(pageSource, env);
var compTargets = {};
var serverList = [];
var clientList = [];
var ioDeps = [];
{ var _c = needed; for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; (function() {
var target = renderTarget(name, env, ioNames);
compTargets[name] = target;
return (isSxTruthy((target == "server")) ? (append_b(serverList, name), forEach(function(ioRef) { return (isSxTruthy(!isSxTruthy(contains(ioDeps, ioRef))) ? append_b(ioDeps, ioRef) : NIL); }, componentIoRefsCached(name, env, ioNames))) : append_b(clientList, name));
})(); } }
return {"io-deps": ioDeps, "server": serverList, "components": compTargets, "client": clientList};
})(); };
PRIMITIVES["page-render-plan"] = pageRenderPlan;
// env-components
var envComponents = function(env) { return filter(function(k) { return (function() {
var v = envGet(env, k);
return sxOr(isComponent(v), isMacro(v));
})(); }, keys(env)); };
PRIMITIVES["env-components"] = envComponents;
// === Transpiled from page-helpers (pure data transformation helpers) ===
// special-form-category-map
var specialFormCategoryMap = {"defmacro": "Functions & Components", "for-each": "Higher-Order Forms", "defpage": "Domain Definitions", "let": "Binding", "filter": "Higher-Order Forms", "shift": "Continuations", "and": "Control Flow", "set!": "Binding", "map-indexed": "Higher-Order Forms", "dynamic-wind": "Guards", "reduce": "Higher-Order Forms", "cond": "Control Flow", "defquery": "Domain Definitions", "->": "Sequencing & Threading", "let*": "Binding", "define": "Binding", "reset": "Continuations", "case": "Control Flow", "do": "Sequencing & Threading", "map": "Higher-Order Forms", "some": "Higher-Order Forms", "letrec": "Binding", "if": "Control Flow", "quote": "Quoting", "every?": "Higher-Order Forms", "defhandler": "Domain Definitions", "fn": "Functions & Components", "defstyle": "Domain Definitions", "lambda": "Functions & Components", "defaction": "Domain Definitions", "or": "Control Flow", "defcomp": "Functions & Components", "quasiquote": "Quoting", "when": "Control Flow", "begin": "Sequencing & Threading"};
PRIMITIVES["special-form-category-map"] = specialFormCategoryMap;
// extract-define-kwargs
var extractDefineKwargs = function(expr) { return (function() {
var result = {};
var items = slice(expr, 2);
var n = len(items);
{ var _c = range(0, n); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; if (isSxTruthy((isSxTruthy(((idx + 1) < n)) && (typeOf(nth(items, idx)) == "keyword")))) {
(function() {
var key = keywordName(nth(items, idx));
var val = nth(items, (idx + 1));
return dictSet(result, key, (isSxTruthy((typeOf(val) == "list")) ? (String("(") + String(join(" ", map(serialize, val))) + String(")")) : (String(val))));
})();
} } }
return result;
})(); };
PRIMITIVES["extract-define-kwargs"] = extractDefineKwargs;
// categorize-special-forms
var categorizeSpecialForms = function(parsedExprs) { return (function() {
var categories = {};
{ var _c = parsedExprs; for (var _i = 0; _i < _c.length; _i++) { var expr = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(expr) == "list")) && isSxTruthy((len(expr) >= 2)) && isSxTruthy((typeOf(first(expr)) == "symbol")) && (symbolName(first(expr)) == "define-special-form")))) {
(function() {
var name = nth(expr, 1);
var kwargs = extractDefineKwargs(expr);
var category = sxOr(get(specialFormCategoryMap, name), "Other");
if (isSxTruthy(!isSxTruthy(dictHas(categories, category)))) {
categories[category] = [];
}
return append_b(get(categories, category), {"doc": sxOr(get(kwargs, "doc"), ""), "example": sxOr(get(kwargs, "example"), ""), "tail-position": sxOr(get(kwargs, "tail-position"), ""), "syntax": sxOr(get(kwargs, "syntax"), ""), "name": name});
})();
} } }
return categories;
})(); };
PRIMITIVES["categorize-special-forms"] = categorizeSpecialForms;
// build-ref-items-with-href
var buildRefItemsWithHref = function(items, basePath, detailKeys, nFields) { return map(function(item) { return (isSxTruthy((nFields == 3)) ? (function() {
var name = nth(item, 0);
var field2 = nth(item, 1);
var field3 = nth(item, 2);
return {"href": (isSxTruthy((isSxTruthy(field3) && some(function(k) { return (k == name); }, detailKeys))) ? (String(basePath) + String(name)) : NIL), "exists": field3, "desc": field2, "name": name};
})() : (function() {
var name = nth(item, 0);
var desc = nth(item, 1);
return {"href": (isSxTruthy(some(function(k) { return (k == name); }, detailKeys)) ? (String(basePath) + String(name)) : NIL), "desc": desc, "name": name};
})()); }, items); };
PRIMITIVES["build-ref-items-with-href"] = buildRefItemsWithHref;
// build-reference-data
var buildReferenceData = function(slug, rawData, detailKeys) { return (function() { var _m = slug; if (_m == "attributes") return {"req-attrs": buildRefItemsWithHref(get(rawData, "req-attrs"), "/geography/hypermedia/reference/attributes/", detailKeys, 3), "beh-attrs": buildRefItemsWithHref(get(rawData, "beh-attrs"), "/geography/hypermedia/reference/attributes/", detailKeys, 3), "uniq-attrs": buildRefItemsWithHref(get(rawData, "uniq-attrs"), "/geography/hypermedia/reference/attributes/", detailKeys, 3)}; if (_m == "headers") return {"req-headers": buildRefItemsWithHref(get(rawData, "req-headers"), "/geography/hypermedia/reference/headers/", detailKeys, 3), "resp-headers": buildRefItemsWithHref(get(rawData, "resp-headers"), "/geography/hypermedia/reference/headers/", detailKeys, 3)}; if (_m == "events") return {"events-list": buildRefItemsWithHref(get(rawData, "events-list"), "/geography/hypermedia/reference/events/", detailKeys, 2)}; if (_m == "js-api") return {"js-api-list": map(function(item) { return {"desc": nth(item, 1), "name": nth(item, 0)}; }, get(rawData, "js-api-list"))}; return {"req-attrs": buildRefItemsWithHref(get(rawData, "req-attrs"), "/geography/hypermedia/reference/attributes/", detailKeys, 3), "beh-attrs": buildRefItemsWithHref(get(rawData, "beh-attrs"), "/geography/hypermedia/reference/attributes/", detailKeys, 3), "uniq-attrs": buildRefItemsWithHref(get(rawData, "uniq-attrs"), "/geography/hypermedia/reference/attributes/", detailKeys, 3)}; })(); };
PRIMITIVES["build-reference-data"] = buildReferenceData;
// build-attr-detail
var buildAttrDetail = function(slug, detail) { return (isSxTruthy(isNil(detail)) ? {"attr-not-found": true} : {"attr-handler": get(detail, "handler"), "attr-title": slug, "attr-example": get(detail, "example"), "attr-not-found": NIL, "attr-description": get(detail, "description"), "attr-demo": get(detail, "demo"), "attr-wire-id": (isSxTruthy(dictHas(detail, "handler")) ? (String("ref-wire-") + String(replace_(replace_(slug, ":", "-"), "*", "star"))) : NIL)}); };
PRIMITIVES["build-attr-detail"] = buildAttrDetail;
// build-header-detail
var buildHeaderDetail = function(slug, detail) { return (isSxTruthy(isNil(detail)) ? {"header-not-found": true} : {"header-description": get(detail, "description"), "header-demo": get(detail, "demo"), "header-not-found": NIL, "header-title": slug, "header-example": get(detail, "example"), "header-direction": get(detail, "direction")}); };
PRIMITIVES["build-header-detail"] = buildHeaderDetail;
// build-event-detail
var buildEventDetail = function(slug, detail) { return (isSxTruthy(isNil(detail)) ? {"event-not-found": true} : {"event-example": get(detail, "example"), "event-demo": get(detail, "demo"), "event-description": get(detail, "description"), "event-not-found": NIL, "event-title": slug}); };
PRIMITIVES["build-event-detail"] = buildEventDetail;
// build-component-source
var buildComponentSource = function(compData) { return (function() {
var compType = get(compData, "type");
var name = get(compData, "name");
var params = get(compData, "params");
var hasChildren = get(compData, "has-children");
var bodySx = get(compData, "body-sx");
var affinity = get(compData, "affinity");
return (isSxTruthy((compType == "not-found")) ? (String(";; component ") + String(name) + String(" not found")) : (function() {
var paramStrs = (isSxTruthy(isEmpty(params)) ? (isSxTruthy(hasChildren) ? ["&rest", "children"] : []) : (isSxTruthy(hasChildren) ? append(cons("&key", params), ["&rest", "children"]) : cons("&key", params)));
var paramsSx = (String("(") + String(join(" ", paramStrs)) + String(")"));
var formName = (isSxTruthy((compType == "island")) ? "defisland" : "defcomp");
var affinityStr = (isSxTruthy((isSxTruthy((compType == "component")) && isSxTruthy(!isSxTruthy(isNil(affinity))) && !isSxTruthy((affinity == "auto")))) ? (String(" :affinity ") + String(affinity)) : "");
return (String("(") + String(formName) + String(" ") + String(name) + String(" ") + String(paramsSx) + String(affinityStr) + String("\n ") + String(bodySx) + String(")"));
})());
})(); };
PRIMITIVES["build-component-source"] = buildComponentSource;
// build-bundle-analysis
var buildBundleAnalysis = function(pagesRaw, componentsRaw, totalComponents, totalMacros, pureCount, ioCount) { return (function() {
var pagesData = [];
{ var _c = pagesRaw; for (var _i = 0; _i < _c.length; _i++) { var page = _c[_i]; (function() {
var neededNames = get(page, "needed-names");
var n = len(neededNames);
var pct = (isSxTruthy((totalComponents > 0)) ? round(((n / totalComponents) * 100)) : 0);
var savings = (100 - pct);
var pureInPage = 0;
var ioInPage = 0;
var pageIoRefs = [];
var compDetails = [];
{ var _c = neededNames; for (var _i = 0; _i < _c.length; _i++) { var compName = _c[_i]; (function() {
var info = get(componentsRaw, compName);
return (isSxTruthy(!isSxTruthy(isNil(info))) ? ((isSxTruthy(get(info, "is-pure")) ? (pureInPage = (pureInPage + 1)) : ((ioInPage = (ioInPage + 1)), forEach(function(ref) { return (isSxTruthy(!isSxTruthy(some(function(r) { return (r == ref); }, pageIoRefs))) ? append_b(pageIoRefs, ref) : NIL); }, sxOr(get(info, "io-refs"), [])))), append_b(compDetails, {"io-refs": sxOr(get(info, "io-refs"), []), "render-target": get(info, "render-target"), "deps": sxOr(get(info, "deps"), []), "source": get(info, "source"), "name": compName, "is-pure": get(info, "is-pure"), "affinity": get(info, "affinity")})) : NIL);
})(); } }
return append_b(pagesData, {"pure-in-page": pureInPage, "io-refs": len(pageIoRefs), "direct": get(page, "direct"), "needed": n, "io-in-page": ioInPage, "components": compDetails, "savings": savings, "pct": pct, "path": get(page, "path"), "name": get(page, "name")});
})(); } }
return {"total-macros": totalMacros, "pages": pagesData, "io-count": ioCount, "pure-count": pureCount, "total-components": totalComponents};
})(); };
PRIMITIVES["build-bundle-analysis"] = buildBundleAnalysis;
// build-routing-analysis
var buildRoutingAnalysis = function(pagesRaw) { return (function() {
var pagesData = [];
var clientCount = 0;
var serverCount = 0;
{ var _c = pagesRaw; for (var _i = 0; _i < _c.length; _i++) { var page = _c[_i]; (function() {
var hasData = get(page, "has-data");
var contentSrc = sxOr(get(page, "content-src"), "");
var mode = NIL;
var reason = "";
(isSxTruthy(hasData) ? ((mode = "server"), (reason = "Has :data expression — needs server IO"), (serverCount = (serverCount + 1))) : (isSxTruthy(isEmpty(contentSrc)) ? ((mode = "server"), (reason = "No content expression"), (serverCount = (serverCount + 1))) : ((mode = "client"), (clientCount = (clientCount + 1)))));
return append_b(pagesData, {"reason": reason, "mode": mode, "content-expr": (isSxTruthy((len(contentSrc) > 80)) ? (String(slice(contentSrc, 0, 80)) + String("...")) : contentSrc), "has-data": hasData, "path": get(page, "path"), "name": get(page, "name")});
})(); } }
return {"pages": pagesData, "total-pages": (clientCount + serverCount), "server-count": serverCount, "client-count": clientCount};
})(); };
PRIMITIVES["build-routing-analysis"] = buildRoutingAnalysis;
// build-affinity-analysis
var buildAffinityAnalysis = function(demoComponents, pagePlans) { return {"components": demoComponents, "page-plans": pagePlans}; };
PRIMITIVES["build-affinity-analysis"] = buildAffinityAnalysis;
// === Transpiled from router (client-side route matching) ===
// split-path-segments
var splitPathSegments = function(path) { return (function() {
var trimmed = (isSxTruthy(startsWith(path, "/")) ? slice(path, 1) : path);
return (function() {
var trimmed2 = (isSxTruthy((isSxTruthy(!isSxTruthy(isEmpty(trimmed))) && endsWith(trimmed, "/"))) ? slice(trimmed, 0, (len(trimmed) - 1)) : trimmed);
return (isSxTruthy(isEmpty(trimmed2)) ? [] : split(trimmed2, "/"));
})();
})(); };
PRIMITIVES["split-path-segments"] = splitPathSegments;
// make-route-segment
var makeRouteSegment = function(seg) { return (isSxTruthy((isSxTruthy(startsWith(seg, "<")) && endsWith(seg, ">"))) ? (function() {
var paramName = slice(seg, 1, (len(seg) - 1));
return (function() {
var d = {};
d["type"] = "param";
d["value"] = paramName;
return d;
})();
})() : (function() {
var d = {};
d["type"] = "literal";
d["value"] = seg;
return d;
})()); };
PRIMITIVES["make-route-segment"] = makeRouteSegment;
// parse-route-pattern
var parseRoutePattern = function(pattern) { return (function() {
var segments = splitPathSegments(pattern);
return map(makeRouteSegment, segments);
})(); };
PRIMITIVES["parse-route-pattern"] = parseRoutePattern;
// match-route-segments
var matchRouteSegments = function(pathSegs, parsedSegs) { return (isSxTruthy(!isSxTruthy((len(pathSegs) == len(parsedSegs)))) ? NIL : (function() {
var params = {};
var matched = true;
forEachIndexed(function(i, parsedSeg) { return (isSxTruthy(matched) ? (function() {
var pathSeg = nth(pathSegs, i);
var segType = get(parsedSeg, "type");
return (isSxTruthy((segType == "literal")) ? (isSxTruthy(!isSxTruthy((pathSeg == get(parsedSeg, "value")))) ? (matched = false) : NIL) : (isSxTruthy((segType == "param")) ? dictSet(params, get(parsedSeg, "value"), pathSeg) : (matched = false)));
})() : NIL); }, parsedSegs);
return (isSxTruthy(matched) ? params : NIL);
})()); };
PRIMITIVES["match-route-segments"] = matchRouteSegments;
// match-route
var matchRoute = function(path, pattern) { return (function() {
var pathSegs = splitPathSegments(path);
var parsedSegs = parseRoutePattern(pattern);
return matchRouteSegments(pathSegs, parsedSegs);
})(); };
PRIMITIVES["match-route"] = matchRoute;
// find-matching-route
var findMatchingRoute = function(path, routes) { return (function() {
var matchPath = (isSxTruthy(startsWith(path, "/(")) ? sxOr(sxUrlToPath(path), path) : path);
return (function() {
var pathSegs = splitPathSegments(matchPath);
var result = NIL;
{ var _c = routes; for (var _i = 0; _i < _c.length; _i++) { var route = _c[_i]; if (isSxTruthy(isNil(result))) {
(function() {
var params = matchRouteSegments(pathSegs, get(route, "parsed"));
return (isSxTruthy(!isSxTruthy(isNil(params))) ? (function() {
var matched = merge(route, {});
matched["params"] = params;
return (result = matched);
})() : NIL);
})();
} } }
return result;
})();
})(); };
PRIMITIVES["find-matching-route"] = findMatchingRoute;
// _fn-to-segment
var _fnToSegment = function(name) { return (function() { var _m = name; if (_m == "doc") return "docs"; if (_m == "spec") return "specs"; if (_m == "bootstrapper") return "bootstrappers"; if (_m == "test") return "testing"; if (_m == "example") return "examples"; if (_m == "protocol") return "protocols"; if (_m == "essay") return "essays"; if (_m == "plan") return "plans"; if (_m == "reference-detail") return "reference"; return name; })(); };
PRIMITIVES["_fn-to-segment"] = _fnToSegment;
// sx-url-to-path
var sxUrlToPath = function(url) { return (isSxTruthy(!isSxTruthy((isSxTruthy(startsWith(url, "/(")) && endsWith(url, ")")))) ? NIL : (function() {
var inner = slice(url, 2, (len(url) - 1));
return (function() {
var s = replace_(replace_(replace_(inner, ".", "/"), "(", ""), ")", "");
return (function() {
var segs = filter(function(s) { return !isSxTruthy(isEmpty(s)); }, split(s, "/"));
return (String("/") + String(join("/", map(_fnToSegment, segs))));
})();
})();
})()); };
PRIMITIVES["sx-url-to-path"] = sxUrlToPath;
// _count-leading-dots
var _countLeadingDots = function(s) { return (isSxTruthy(isEmpty(s)) ? 0 : (isSxTruthy(startsWith(s, ".")) ? (1 + _countLeadingDots(slice(s, 1))) : 0)); };
PRIMITIVES["_count-leading-dots"] = _countLeadingDots;
// _strip-trailing-close
var _stripTrailingClose = function(s) { return (isSxTruthy(endsWith(s, ")")) ? _stripTrailingClose(slice(s, 0, (len(s) - 1))) : s); };
PRIMITIVES["_strip-trailing-close"] = _stripTrailingClose;
// _index-of-safe
var _indexOfSafe = function(s, needle) { return (function() {
var idx = indexOf_(s, needle);
return (isSxTruthy(sxOr(isNil(idx), (idx < 0))) ? NIL : idx);
})(); };
PRIMITIVES["_index-of-safe"] = _indexOfSafe;
// _last-index-of
var _lastIndexOf = function(s, needle) { return (function() {
var idx = _indexOfSafe(s, needle);
return (isSxTruthy(isNil(idx)) ? NIL : (function() {
var restIdx = _lastIndexOf(slice(s, (idx + 1)), needle);
return (isSxTruthy(isNil(restIdx)) ? idx : ((idx + 1) + restIdx));
})());
})(); };
PRIMITIVES["_last-index-of"] = _lastIndexOf;
// _pop-sx-url-level
var _popSxUrlLevel = function(url) { return (function() {
var stripped = _stripTrailingClose(url);
var closeCount = (len(url) - len(_stripTrailingClose(url)));
return (isSxTruthy((closeCount <= 1)) ? "/" : (function() {
var lastDp = _lastIndexOf(stripped, ".(");
return (isSxTruthy(isNil(lastDp)) ? "/" : (String(slice(stripped, 0, lastDp)) + String(slice(url, (len(url) - (closeCount - 1))))));
})());
})(); };
PRIMITIVES["_pop-sx-url-level"] = _popSxUrlLevel;
// _pop-sx-url-levels
var _popSxUrlLevels = function(url, n) { return (isSxTruthy((n <= 0)) ? url : _popSxUrlLevels(_popSxUrlLevel(url), (n - 1))); };
PRIMITIVES["_pop-sx-url-levels"] = _popSxUrlLevels;
// _split-pos-kw
var _splitPosKw = function(tokens, i, pos, kw) { return (isSxTruthy((i >= len(tokens))) ? {"positional": join(".", pos), "keywords": kw} : (function() {
var tok = nth(tokens, i);
return (isSxTruthy(startsWith(tok, ":")) ? (function() {
var val = (isSxTruthy(((i + 1) < len(tokens))) ? nth(tokens, (i + 1)) : "");
return _splitPosKw(tokens, (i + 2), pos, append(kw, [[tok, val]]));
})() : _splitPosKw(tokens, (i + 1), append(pos, [tok]), kw));
})()); };
PRIMITIVES["_split-pos-kw"] = _splitPosKw;
// _parse-relative-body
var _parseRelativeBody = function(body) { return (isSxTruthy(isEmpty(body)) ? {"positional": "", "keywords": []} : _splitPosKw(split(body, "."), 0, [], [])); };
PRIMITIVES["_parse-relative-body"] = _parseRelativeBody;
// _extract-innermost
var _extractInnermost = function(url) { return (function() {
var stripped = _stripTrailingClose(url);
var suffix = slice(url, len(_stripTrailingClose(url)));
return (function() {
var lastDp = _lastIndexOf(stripped, ".(");
return (isSxTruthy(isNil(lastDp)) ? {"before": "/(", "content": slice(stripped, 2), "suffix": suffix} : {"before": slice(stripped, 0, (lastDp + 2)), "content": slice(stripped, (lastDp + 2)), "suffix": suffix});
})();
})(); };
PRIMITIVES["_extract-innermost"] = _extractInnermost;
// _find-kw-in-tokens
var _findKwInTokens = function(tokens, i, kw) { return (isSxTruthy((i >= len(tokens))) ? NIL : (isSxTruthy((isSxTruthy((nth(tokens, i) == kw)) && ((i + 1) < len(tokens)))) ? nth(tokens, (i + 1)) : _findKwInTokens(tokens, (i + 1), kw))); };
PRIMITIVES["_find-kw-in-tokens"] = _findKwInTokens;
// _find-keyword-value
var _findKeywordValue = function(content, kw) { return _findKwInTokens(split(content, "."), 0, kw); };
PRIMITIVES["_find-keyword-value"] = _findKeywordValue;
// _replace-kw-in-tokens
var _replaceKwInTokens = function(tokens, i, kw, value) { return (isSxTruthy((i >= len(tokens))) ? [] : (isSxTruthy((isSxTruthy((nth(tokens, i) == kw)) && ((i + 1) < len(tokens)))) ? append([kw, value], _replaceKwInTokens(tokens, (i + 2), kw, value)) : cons(nth(tokens, i), _replaceKwInTokens(tokens, (i + 1), kw, value)))); };
PRIMITIVES["_replace-kw-in-tokens"] = _replaceKwInTokens;
// _set-keyword-in-content
var _setKeywordInContent = function(content, kw, value) { return (function() {
var current = _findKeywordValue(content, kw);
return (isSxTruthy(isNil(current)) ? (String(content) + String(".") + String(kw) + String(".") + String(value)) : join(".", _replaceKwInTokens(split(content, "."), 0, kw, value)));
})(); };
PRIMITIVES["_set-keyword-in-content"] = _setKeywordInContent;
// _is-delta-value?
var _isDeltaValue_p = function(s) { return (isSxTruthy(!isSxTruthy(isEmpty(s))) && isSxTruthy((len(s) > 1)) && sxOr(startsWith(s, "+"), startsWith(s, "-"))); };
PRIMITIVES["_is-delta-value?"] = _isDeltaValue_p;
// _apply-delta
var _applyDelta = function(currentStr, deltaStr) { return (function() {
var cur = parseInt_(currentStr, NIL);
var delta = parseInt_(deltaStr, NIL);
return (isSxTruthy(sxOr(isNil(cur), isNil(delta))) ? deltaStr : (String((cur + delta))));
})(); };
PRIMITIVES["_apply-delta"] = _applyDelta;
// _apply-kw-pairs
var _applyKwPairs = function(content, kwPairs) { return (isSxTruthy(isEmpty(kwPairs)) ? content : (function() {
var pair = first(kwPairs);
var kw = first(pair);
var rawVal = nth(pair, 1);
return (function() {
var actualVal = (isSxTruthy(_isDeltaValue_p(rawVal)) ? (function() {
var current = _findKeywordValue(content, kw);
return (isSxTruthy(isNil(current)) ? rawVal : _applyDelta(current, rawVal));
})() : rawVal);
return _applyKwPairs(_setKeywordInContent(content, kw, actualVal), rest(kwPairs));
})();
})()); };
PRIMITIVES["_apply-kw-pairs"] = _applyKwPairs;
// _apply-keywords-to-url
var _applyKeywordsToUrl = function(url, kwPairs) { return (isSxTruthy(isEmpty(kwPairs)) ? url : (function() {
var parts = _extractInnermost(url);
return (function() {
var newContent = _applyKwPairs(get(parts, "content"), kwPairs);
return (String(get(parts, "before")) + String(newContent) + String(get(parts, "suffix")));
})();
})()); };
PRIMITIVES["_apply-keywords-to-url"] = _applyKeywordsToUrl;
// _normalize-relative
var _normalizeRelative = function(url) { return (isSxTruthy(startsWith(url, "(")) ? url : (String("(") + String(url) + String(")"))); };
PRIMITIVES["_normalize-relative"] = _normalizeRelative;
// resolve-relative-url
var resolveRelativeUrl = function(current, relative) { return (function() {
var canonical = _normalizeRelative(relative);
return (function() {
var relInner = slice(canonical, 1, (len(canonical) - 1));
return (function() {
var dots = _countLeadingDots(relInner);
var body = slice(relInner, _countLeadingDots(relInner));
return (isSxTruthy((dots == 0)) ? current : (function() {
var parsed = _parseRelativeBody(body);
var posBody = get(parsed, "positional");
var kwPairs = get(parsed, "keywords");
return (function() {
var afterNav = (isSxTruthy((dots == 1)) ? (isSxTruthy(isEmpty(posBody)) ? current : (function() {
var stripped = _stripTrailingClose(current);
var suffix = slice(current, len(_stripTrailingClose(current)));
return (String(stripped) + String(".") + String(posBody) + String(suffix));
})()) : (function() {
var base = _popSxUrlLevels(current, (dots - 1));
return (isSxTruthy(isEmpty(posBody)) ? base : (isSxTruthy((base == "/")) ? (String("/(") + String(posBody) + String(")")) : (function() {
var stripped = _stripTrailingClose(base);
var suffix = slice(base, len(_stripTrailingClose(base)));
return (String(stripped) + String(".(") + String(posBody) + String(")") + String(suffix));
})()));
})());
return _applyKeywordsToUrl(afterNav, kwPairs);
})();
})());
})();
})();
})(); };
PRIMITIVES["resolve-relative-url"] = resolveRelativeUrl;
// relative-sx-url?
var relativeSxUrl_p = function(url) { return sxOr((isSxTruthy(startsWith(url, "(")) && !isSxTruthy(startsWith(url, "/("))), startsWith(url, ".")); };
PRIMITIVES["relative-sx-url?"] = relativeSxUrl_p;
// _url-special-forms
var _urlSpecialForms = function() { return ["!source", "!inspect", "!diff", "!search", "!raw", "!json"]; };
PRIMITIVES["_url-special-forms"] = _urlSpecialForms;
// url-special-form?
var urlSpecialForm_p = function(name) { return (isSxTruthy(startsWith(name, "!")) && contains(_urlSpecialForms(), name)); };
PRIMITIVES["url-special-form?"] = urlSpecialForm_p;
// parse-sx-url
var parseSxUrl = function(url) { return (isSxTruthy((url == "/")) ? {"raw": url, "type": "home"} : (isSxTruthy(relativeSxUrl_p(url)) ? {"raw": url, "type": "relative"} : (isSxTruthy((isSxTruthy(startsWith(url, "/(!")) && endsWith(url, ")"))) ? (function() {
var inner = slice(url, 2, (len(url) - 1));
return (function() {
var dotPos = _indexOfSafe(inner, ".");
var parenPos = _indexOfSafe(inner, "(");
return (function() {
var endPos = (isSxTruthy((isSxTruthy(isNil(dotPos)) && isNil(parenPos))) ? len(inner) : (isSxTruthy(isNil(dotPos)) ? parenPos : (isSxTruthy(isNil(parenPos)) ? dotPos : min(dotPos, parenPos))));
return (function() {
var formName = slice(inner, 0, endPos);
var restPart = slice(inner, endPos);
return (function() {
var innerExpr = (isSxTruthy(startsWith(restPart, ".")) ? slice(restPart, 1) : restPart);
return {"raw": url, "type": "special-form", "inner": innerExpr, "form": formName};
})();
})();
})();
})();
})() : (isSxTruthy((isSxTruthy(startsWith(url, "/(~")) && endsWith(url, ")"))) ? (function() {
var name = slice(url, 2, (len(url) - 1));
return {"raw": url, "type": "direct-component", "name": name};
})() : (isSxTruthy((isSxTruthy(startsWith(url, "/(")) && endsWith(url, ")"))) ? {"raw": url, "type": "absolute"} : {"raw": url, "type": "path"}))))); };
PRIMITIVES["parse-sx-url"] = parseSxUrl;
// url-special-form-name
var urlSpecialFormName = function(url) { return (function() {
var parsed = parseSxUrl(url);
return (isSxTruthy((get(parsed, "type") == "special-form")) ? get(parsed, "form") : NIL);
})(); };
PRIMITIVES["url-special-form-name"] = urlSpecialFormName;
// url-special-form-inner
var urlSpecialFormInner = function(url) { return (function() {
var parsed = parseSxUrl(url);
return (isSxTruthy((get(parsed, "type") == "special-form")) ? get(parsed, "inner") : NIL);
})(); };
PRIMITIVES["url-special-form-inner"] = urlSpecialFormInner;
// url-to-expr
var urlToExpr = function(urlPath) { return (isSxTruthy(sxOr((urlPath == "/"), isEmpty(urlPath))) ? [] : (function() {
var trimmed = (isSxTruthy(startsWith(urlPath, "/")) ? slice(urlPath, 1) : urlPath);
return (function() {
var sxSource = replace_(trimmed, ".", " ");
return (function() {
var exprs = sxParse(sxSource);
return (isSxTruthy(isEmpty(exprs)) ? [] : first(exprs));
})();
})();
})()); };
PRIMITIVES["url-to-expr"] = urlToExpr;
// auto-quote-unknowns
var autoQuoteUnknowns = function(expr, env) { return (isSxTruthy(!isSxTruthy(isList(expr))) ? expr : (isSxTruthy(isEmpty(expr)) ? expr : cons(first(expr), map(function(child) { return (isSxTruthy(isList(child)) ? autoQuoteUnknowns(child, env) : (isSxTruthy((typeOf(child) == "symbol")) ? (function() {
var name = symbolName(child);
return (isSxTruthy(sxOr(envHas(env, name), startsWith(name, ":"), startsWith(name, "~"), startsWith(name, "!"))) ? child : name);
})() : child)); }, rest(expr))))); };
PRIMITIVES["auto-quote-unknowns"] = autoQuoteUnknowns;
// prepare-url-expr
var prepareUrlExpr = function(urlPath, env) { return (function() {
var expr = urlToExpr(urlPath);
return (isSxTruthy(isEmpty(expr)) ? expr : autoQuoteUnknowns(expr, env));
})(); };
PRIMITIVES["prepare-url-expr"] = prepareUrlExpr;
// === Transpiled from signals (reactive signal runtime) ===
// make-signal
var makeSignal = function(value) { return {["__signal"]: true, ["value"]: value, ["subscribers"]: [], ["deps"]: []}; };
PRIMITIVES["make-signal"] = makeSignal;
// signal?
var isSignal = function(x) { return (isSxTruthy(isDict(x)) && dictHas(x, "__signal")); };
PRIMITIVES["signal?"] = isSignal;
// signal-value
var signalValue = function(s) { return get(s, "value"); };
PRIMITIVES["signal-value"] = signalValue;
// signal-set-value!
var signalSetValue = function(s, v) { return dictSet(s, "value", v); };
PRIMITIVES["signal-set-value!"] = signalSetValue;
// signal-subscribers
var signalSubscribers = function(s) { return get(s, "subscribers"); };
PRIMITIVES["signal-subscribers"] = signalSubscribers;
// signal-add-sub!
var signalAddSub = function(s, f) { return (isSxTruthy(!isSxTruthy(contains(get(s, "subscribers"), f))) ? append_b(get(s, "subscribers"), f) : NIL); };
PRIMITIVES["signal-add-sub!"] = signalAddSub;
// signal-remove-sub!
var signalRemoveSub = function(s, f) { return dictSet(s, "subscribers", filter(function(sub) { return !isSxTruthy(isIdentical(sub, f)); }, get(s, "subscribers"))); };
PRIMITIVES["signal-remove-sub!"] = signalRemoveSub;
// signal-deps
var signalDeps = function(s) { return get(s, "deps"); };
PRIMITIVES["signal-deps"] = signalDeps;
// signal-set-deps!
var signalSetDeps = function(s, deps) { return dictSet(s, "deps", deps); };
PRIMITIVES["signal-set-deps!"] = signalSetDeps;
// signal
var signal = function(initialValue) { return makeSignal(initialValue); };
PRIMITIVES["signal"] = signal;
// deref
var deref = function(s) { return (isSxTruthy(!isSxTruthy(isSignal(s))) ? s : (function() {
var ctx = sxContext("sx-reactive", NIL);
if (isSxTruthy(ctx)) {
(function() {
var depList = get(ctx, "deps");
var notifyFn = get(ctx, "notify");
return (isSxTruthy(!isSxTruthy(contains(depList, s))) ? (append_b(depList, s), signalAddSub(s, notifyFn)) : NIL);
})();
}
return signalValue(s);
})()); };
PRIMITIVES["deref"] = deref;
// reset!
var reset_b = function(s, value) { return (isSxTruthy(isSignal(s)) ? (function() {
var old = signalValue(s);
return (isSxTruthy(!isSxTruthy(isIdentical(old, value))) ? (signalSetValue(s, value), notifySubscribers(s)) : NIL);
})() : NIL); };
PRIMITIVES["reset!"] = reset_b;
// swap!
var swap_b = function(s, f) { var args = Array.prototype.slice.call(arguments, 2); return (isSxTruthy(isSignal(s)) ? (function() {
var old = signalValue(s);
var newVal = apply(f, cons(old, args));
return (isSxTruthy(!isSxTruthy(isIdentical(old, newVal))) ? (signalSetValue(s, newVal), notifySubscribers(s)) : NIL);
})() : NIL); };
PRIMITIVES["swap!"] = swap_b;
// computed
var computed = function(computeFn) { return (function() {
var s = makeSignal(NIL);
var deps = [];
var computeCtx = NIL;
return (function() {
var recompute = function() { { var _c = signalDeps(s); for (var _i = 0; _i < _c.length; _i++) { var dep = _c[_i]; signalRemoveSub(dep, recompute); } }
signalSetDeps(s, []);
return (function() {
var ctx = {["deps"]: [], ["notify"]: recompute};
scopePush("sx-reactive", ctx);
return (function() {
var newVal = cekCall(computeFn, NIL);
scopePop("sx-reactive");
signalSetDeps(s, get(ctx, "deps"));
return (function() {
var old = signalValue(s);
signalSetValue(s, newVal);
return (isSxTruthy(!isSxTruthy(isIdentical(old, newVal))) ? notifySubscribers(s) : NIL);
})();
})();
})(); };
recompute();
registerInScope(function() { return disposeComputed(s); });
return s;
})();
})(); };
PRIMITIVES["computed"] = computed;
// effect
var effect = function(effectFn) { return (function() {
var deps = [];
var disposed = false;
var cleanupFn = NIL;
return (function() {
var runEffect = function() { return (isSxTruthy(!isSxTruthy(disposed)) ? ((isSxTruthy(cleanupFn) ? cekCall(cleanupFn, NIL) : NIL), forEach(function(dep) { return signalRemoveSub(dep, runEffect); }, deps), (deps = []), (function() {
var ctx = {["deps"]: [], ["notify"]: runEffect};
scopePush("sx-reactive", ctx);
return (function() {
var result = cekCall(effectFn, NIL);
scopePop("sx-reactive");
deps = get(ctx, "deps");
return (isSxTruthy(isCallable(result)) ? (cleanupFn = result) : NIL);
})();
})()) : NIL); };
runEffect();
return (function() {
var disposeFn = function() { disposed = true;
if (isSxTruthy(cleanupFn)) {
cekCall(cleanupFn, NIL);
}
{ var _c = deps; for (var _i = 0; _i < _c.length; _i++) { var dep = _c[_i]; signalRemoveSub(dep, runEffect); } }
return (deps = []); };
registerInScope(disposeFn);
return disposeFn;
})();
})();
})(); };
PRIMITIVES["effect"] = effect;
// *batch-depth*
var _batchDepth = 0;
PRIMITIVES["*batch-depth*"] = _batchDepth;
// *batch-queue*
var _batchQueue = [];
PRIMITIVES["*batch-queue*"] = _batchQueue;
// batch
var batch = function(thunk) { _batchDepth = (_batchDepth + 1);
cekCall(thunk, NIL);
_batchDepth = (_batchDepth - 1);
return (isSxTruthy((_batchDepth == 0)) ? (function() {
var queue = _batchQueue;
_batchQueue = [];
return (function() {
var seen = [];
var pending = [];
{ var _c = queue; for (var _i = 0; _i < _c.length; _i++) { var s = _c[_i]; { var _c = signalSubscribers(s); for (var _i = 0; _i < _c.length; _i++) { var sub = _c[_i]; if (isSxTruthy(!isSxTruthy(contains(seen, sub)))) {
seen.push(sub);
pending.push(sub);
} } } } }
return forEach(function(sub) { return sub(); }, pending);
})();
})() : NIL); };
PRIMITIVES["batch"] = batch;
// notify-subscribers
var notifySubscribers = function(s) { return (isSxTruthy((_batchDepth > 0)) ? (isSxTruthy(!isSxTruthy(contains(_batchQueue, s))) ? append_b(_batchQueue, s) : NIL) : flushSubscribers(s)); };
PRIMITIVES["notify-subscribers"] = notifySubscribers;
// flush-subscribers
var flushSubscribers = function(s) { return forEach(function(sub) { return sub(); }, signalSubscribers(s)); };
PRIMITIVES["flush-subscribers"] = flushSubscribers;
// dispose-computed
var disposeComputed = function(s) { return (isSxTruthy(isSignal(s)) ? (forEach(function(dep) { return signalRemoveSub(dep, NIL); }, signalDeps(s)), signalSetDeps(s, [])) : NIL); };
PRIMITIVES["dispose-computed"] = disposeComputed;
// with-island-scope
var withIslandScope = function(scopeFn, bodyFn) { scopePush("sx-island-scope", scopeFn);
return (function() {
var result = bodyFn();
scopePop("sx-island-scope");
return result;
})(); };
PRIMITIVES["with-island-scope"] = withIslandScope;
// register-in-scope
var registerInScope = function(disposable) { return (function() {
var collector = sxContext("sx-island-scope", NIL);
return (isSxTruthy(collector) ? cekCall(collector, [disposable]) : NIL);
})(); };
PRIMITIVES["register-in-scope"] = registerInScope;
// with-marsh-scope
var withMarshScope = function(marshEl, bodyFn) { return (function() {
var disposers = [];
withIslandScope(function(d) { return append_b(disposers, d); }, bodyFn);
return domSetData(marshEl, "sx-marsh-disposers", disposers);
})(); };
PRIMITIVES["with-marsh-scope"] = withMarshScope;
// dispose-marsh-scope
var disposeMarshScope = function(marshEl) { return (function() {
var disposers = domGetData(marshEl, "sx-marsh-disposers");
return (isSxTruthy(disposers) ? (forEach(function(d) { return cekCall(d, NIL); }, disposers), domSetData(marshEl, "sx-marsh-disposers", NIL)) : NIL);
})(); };
PRIMITIVES["dispose-marsh-scope"] = disposeMarshScope;
// *store-registry*
var _storeRegistry = {};
PRIMITIVES["*store-registry*"] = _storeRegistry;
// def-store
var defStore = function(name, initFn) { return (function() {
var registry = _storeRegistry;
if (isSxTruthy(!isSxTruthy(dictHas(registry, name)))) {
_storeRegistry = assoc(registry, name, cekCall(initFn, NIL));
}
return get(_storeRegistry, name);
})(); };
PRIMITIVES["def-store"] = defStore;
// use-store
var useStore = function(name) { return (isSxTruthy(dictHas(_storeRegistry, name)) ? get(_storeRegistry, name) : error((String("Store not found: ") + String(name) + String(". Call (def-store ...) before (use-store ...).")))); };
PRIMITIVES["use-store"] = useStore;
// clear-stores
var clearStores = function() { return (_storeRegistry = {}); };
PRIMITIVES["clear-stores"] = clearStores;
// emit-event
var emitEvent = function(el, eventName, detail) { return domDispatch(el, eventName, detail); };
PRIMITIVES["emit-event"] = emitEvent;
// on-event
var onEvent = function(el, eventName, handler) { return domOn(el, eventName, handler); };
PRIMITIVES["on-event"] = onEvent;
// bridge-event
var bridgeEvent = function(el, eventName, targetSignal, transformFn) { return effect(function() { return (function() {
var remove = domOn(el, eventName, function(e) { return (function() {
var detail = eventDetail(e);
var newVal = (isSxTruthy(transformFn) ? cekCall(transformFn, [detail]) : detail);
return reset_b(targetSignal, newVal);
})(); });
return remove;
})(); }); };
PRIMITIVES["bridge-event"] = bridgeEvent;
// resource
var resource = function(fetchFn) { return (function() {
var state = signal({["loading"]: true, ["data"]: NIL, ["error"]: NIL});
promiseThen(cekCall(fetchFn, NIL), function(data) { return reset_b(state, {["loading"]: false, ["data"]: data, ["error"]: NIL}); }, function(err) { return reset_b(state, {["loading"]: false, ["data"]: NIL, ["error"]: err}); });
return state;
})(); };
PRIMITIVES["resource"] = resource;
// =========================================================================
// Post-transpilation fixups
// =========================================================================
// The reference spec's call-lambda only handles Lambda objects, but HO forms
// (map, reduce, etc.) may receive native primitives. Wrap to handle both.
var _rawCallLambda = callLambda;
callLambda = function(f, args, callerEnv) {
if (typeof f === "function") return f.apply(null, args);
return _rawCallLambda(f, args, callerEnv);
};
// -----------------------------------------------------------------------
// Core primitives that require native JS (cannot be expressed via FFI)
// -----------------------------------------------------------------------
PRIMITIVES["error"] = function(msg) { throw new Error(msg); };
// FFI library functions — defined in dom.sx/browser.sx but not transpiled.
// Registered here so runtime-evaluated SX code (data-init, islands) can use them.
PRIMITIVES["prevent-default"] = preventDefault_;
PRIMITIVES["stop-propagation"] = stopPropagation_;
PRIMITIVES["event-modifier-key?"] = eventModifierKey_p;
PRIMITIVES["element-value"] = elementValue;
PRIMITIVES["error-message"] = errorMessage;
PRIMITIVES["schedule-idle"] = scheduleIdle;
PRIMITIVES["console-log"] = function() {
var args = Array.prototype.slice.call(arguments);
console.log.apply(console, ["[sx]"].concat(args));
return args.length > 0 ? args[0] : NIL;
};
PRIMITIVES["set-cookie"] = function(name, value, days) {
var d = days || 365;
var expires = new Date(Date.now() + d * 864e5).toUTCString();
document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + expires + ";path=/;SameSite=Lax";
return NIL;
};
PRIMITIVES["get-cookie"] = function(name) {
var m = document.cookie.match(new RegExp("(?:^|;\\s*)" + name + "=([^;]*)"));
return m ? decodeURIComponent(m[1]) : NIL;
};
// dom.sx / browser.sx library functions — not transpiled, registered from
// native platform implementations so runtime-eval'd SX code can use them.
if (typeof domBody === "function") PRIMITIVES["dom-body"] = domBody;
if (typeof domQuery === "function") PRIMITIVES["dom-query"] = domQuery;
if (typeof domQueryAll === "function") PRIMITIVES["dom-query-all"] = domQueryAll;
if (typeof domQueryById === "function") PRIMITIVES["dom-query-by-id"] = domQueryById;
if (typeof domSetAttr === "function") PRIMITIVES["dom-set-attr"] = domSetAttr;
if (typeof domGetAttr === "function") PRIMITIVES["dom-get-attr"] = domGetAttr;
if (typeof domRemoveAttr === "function") PRIMITIVES["dom-remove-attr"] = domRemoveAttr;
if (typeof domHasAttr === "function") PRIMITIVES["dom-has-attr?"] = domHasAttr;
if (typeof domAddClass === "function") PRIMITIVES["dom-add-class"] = domAddClass;
if (typeof domRemoveClass === "function") PRIMITIVES["dom-remove-class"] = domRemoveClass;
if (typeof domHasClass === "function") PRIMITIVES["dom-has-class?"] = domHasClass;
if (typeof domClosest === "function") PRIMITIVES["dom-closest"] = domClosest;
if (typeof domMatches === "function") PRIMITIVES["dom-matches?"] = domMatches;
if (typeof domOuterHtml === "function") PRIMITIVES["dom-outer-html"] = domOuterHtml;
if (typeof domInnerHtml === "function") PRIMITIVES["dom-inner-html"] = domInnerHtml;
if (typeof domTextContent === "function") PRIMITIVES["dom-text-content"] = domTextContent;
if (typeof domCreateElement === "function") PRIMITIVES["dom-create-element"] = domCreateElement;
if (typeof domAppend === "function") PRIMITIVES["dom-append"] = domAppend;
if (typeof domAppendToHead === "function") PRIMITIVES["dom-append-to-head"] = domAppendToHead;
if (typeof jsonParse === "function") PRIMITIVES["json-parse"] = jsonParse;
if (typeof nowMs === "function") PRIMITIVES["now-ms"] = nowMs;
PRIMITIVES["log-info"] = logInfo;
PRIMITIVES["log-warn"] = logWarn;
PRIMITIVES["dom-listen"] = domListen;
PRIMITIVES["dom-dispatch"] = domDispatch;
PRIMITIVES["event-detail"] = eventDetail;
PRIMITIVES["create-text-node"] = createTextNode;
PRIMITIVES["dom-set-text-content"] = domSetTextContent;
PRIMITIVES["dom-focus"] = domFocus;
PRIMITIVES["dom-tag-name"] = domTagName;
PRIMITIVES["dom-get-prop"] = domGetProp;
PRIMITIVES["dom-set-prop"] = domSetProp;
PRIMITIVES["reactive-text"] = reactiveText;
PRIMITIVES["set-interval"] = setInterval_;
PRIMITIVES["clear-interval"] = clearInterval_;
PRIMITIVES["promise-then"] = promiseThen;
PRIMITIVES["promise-delayed"] = promiseDelayed;
PRIMITIVES["local-storage-get"] = function(key) {
try { var v = localStorage.getItem(key); return v === null ? NIL : v; }
catch (e) { return NIL; }
};
PRIMITIVES["local-storage-set"] = function(key, val) {
try { localStorage.setItem(key, val); } catch (e) {}
return NIL;
};
PRIMITIVES["local-storage-remove"] = function(key) {
try { localStorage.removeItem(key); } catch (e) {}
return NIL;
};
if (typeof sxParse === "function") PRIMITIVES["sx-parse"] = sxParse;
// Platform deps functions (native JS, not transpiled — need explicit registration)
PRIMITIVES["component-deps"] = componentDeps;
PRIMITIVES["component-set-deps!"] = componentSetDeps;
PRIMITIVES["component-css-classes"] = componentCssClasses;
PRIMITIVES["regex-find-all"] = regexFindAll;
PRIMITIVES["scan-css-classes"] = scanCssClasses;
// Override recursive cekRun with iterative loop (avoids stack overflow)
cekRun = function(state) {
while (!cekTerminal_p(state)) { state = cekStep(state); }
return cekValue(state);
};
// CEK is the canonical evaluator — override evalExpr to use it.
// The tree-walk evaluator (evalExpr from eval.sx) is superseded.
var _treeWalkEvalExpr = evalExpr;
evalExpr = function(expr, env) {
return cekRun(makeCekState(expr, env, []));
};
// CEK never produces thunks — trampoline resolves any legacy thunks
var _treeWalkTrampoline = trampoline;
trampoline = function(val) {
if (isThunk(val)) return evalExpr(thunkExpr(val), thunkEnv(val));
return val;
};
// Platform functions — defined in platform_js.py, not in .sx spec files.
// Spec defines self-register via js-emit-define; these are the platform interface.
PRIMITIVES["type-of"] = typeOf;
PRIMITIVES["symbol-name"] = symbolName;
PRIMITIVES["keyword-name"] = keywordName;
PRIMITIVES["callable?"] = isCallable;
PRIMITIVES["lambda?"] = isLambda;
PRIMITIVES["lambda-name"] = lambdaName;
PRIMITIVES["component?"] = isComponent;
PRIMITIVES["island?"] = isIsland;
PRIMITIVES["make-symbol"] = function(n) { return new Symbol(n); };
PRIMITIVES["is-html-tag?"] = function(n) { return HTML_TAGS.indexOf(n) >= 0; };
function makeEnv() { return merge(componentEnv, PRIMITIVES); }
PRIMITIVES["make-env"] = makeEnv;
// === stdlib.sx (eval'd at runtime, not transpiled) ===
(function() {
var src = ";; ==========================================================================\n;; stdlib.sx — Standard library functions\n;;\n;; Every function here is expressed in SX using the irreducible primitive\n;; set. They are library functions — in band, auditable, portable.\n;;\n;; Depends on: evaluator.sx (special forms)\n;; Must load before: render.sx, freeze.sx, types.sx, user code\n;; ==========================================================================\n\n\n;; Logic + comparison: not, !=, <=, >= stay as primitives.\n;; Replacing them with SX lambdas changes behavior inside shift/reset\n;; because the transpiled evaluator code uses them directly.\n\n(define eq? (fn (a b) (= a b)))\n(define eqv? (fn (a b) (= a b)))\n(define equal? (fn (a b) (= a b)))\n\n\n;; --------------------------------------------------------------------------\n;; Type predicates\n;; --------------------------------------------------------------------------\n\n;; nil? stays as primitive — host's type-of uses it internally.\n\n(define boolean?\n (fn (x) (= (type-of x) \"boolean\")))\n\n(define number?\n (fn (x) (= (type-of x) \"number\")))\n\n(define string?\n (fn (x) (= (type-of x) \"string\")))\n\n(define list?\n (fn (x) (= (type-of x) \"list\")))\n\n(define dict?\n (fn (x) (= (type-of x) \"dict\")))\n\n(define continuation?\n (fn (x) (= (type-of x) \"continuation\")))\n\n(define zero?\n (fn (n) (= n 0)))\n\n(define odd?\n (fn (n) (= (mod n 2) 1)))\n\n(define even?\n (fn (n) (= (mod n 2) 0)))\n\n(define empty?\n (fn (coll) (or (nil? coll) (= (len coll) 0))))\n\n\n;; --------------------------------------------------------------------------\n;; Arithmetic\n;; --------------------------------------------------------------------------\n\n;; inc and dec stay as primitives — used inside continuation contexts.\n\n(define abs\n (fn (x) (if (< x 0) (- x) x)))\n\n(define ceil\n (fn (x)\n (let ((f (floor x)))\n (if (= x f) f (+ f 1)))))\n\n(define round\n (fn (x ndigits)\n (if (nil? ndigits)\n (floor (+ x 0.5))\n (let ((f (pow 10 ndigits)))\n (/ (floor (+ (* x f) 0.5)) f)))))\n\n(define min\n (fn (a b) (if (< a b) a b)))\n\n(define max\n (fn (a b) (if (> a b) a b)))\n\n(define clamp\n (fn (x lo hi) (max lo (min hi x))))\n\n\n;; --------------------------------------------------------------------------\n;; Collection accessors\n;; --------------------------------------------------------------------------\n\n(define first\n (fn (coll)\n (if (and coll (> (len coll) 0)) (get coll 0) nil)))\n\n(define last\n (fn (coll)\n (if (and coll (> (len coll) 0))\n (get coll (- (len coll) 1))\n nil)))\n\n(define rest\n (fn (coll) (if coll (slice coll 1) (list))))\n\n(define nth\n (fn (coll n)\n (if (and coll (>= n 0) (< n (len coll)))\n (get coll n)\n nil)))\n\n(define cons\n (fn (x coll) (concat (list x) (or coll (list)))))\n\n(define append\n (fn (coll x)\n (if (list? x) (concat coll x) (concat coll (list x)))))\n\n\n;; --------------------------------------------------------------------------\n;; Collection transforms\n;; --------------------------------------------------------------------------\n\n(define reverse\n (fn (coll)\n (reduce (fn (acc x) (cons x acc)) (list) coll)))\n\n(define flatten\n (fn (coll)\n (reduce\n (fn (acc x)\n (if (list? x) (concat acc x) (concat acc (list x))))\n (list) coll)))\n\n(define range\n (fn (start end step)\n (let ((s (if (nil? step) 1 step))\n (result (list)))\n (let loop ((i start))\n (when (< i end)\n (append! result i)\n (loop (+ i s))))\n result)))\n\n(define chunk-every\n (fn (coll n)\n (let ((result (list))\n (clen (len coll)))\n (let loop ((i 0))\n (when (< i clen)\n (append! result (slice coll i (min (+ i n) clen)))\n (loop (+ i n))))\n result)))\n\n(define zip-pairs\n (fn (coll)\n (let ((result (list))\n (clen (len coll)))\n (let loop ((i 0))\n (when (< i (- clen 1))\n (append! result (list (get coll i) (get coll (+ i 1))))\n (loop (+ i 1))))\n result)))\n\n\n;; --------------------------------------------------------------------------\n;; Dict operations\n;; --------------------------------------------------------------------------\n\n(define vals\n (fn (d)\n (map (fn (k) (get d k)) (keys d))))\n\n(define has-key?\n (fn (d key)\n (some (fn (k) (= k key)) (keys d))))\n\n(define assoc\n (fn (d key val)\n (let ((result (merge d (dict))))\n (dict-set! result key val)\n result)))\n\n(define dissoc\n (fn (d key)\n (let ((result (dict)))\n (for-each\n (fn (k)\n (when (!= k key)\n (dict-set! result k (get d k))))\n (keys d))\n result)))\n\n(define into\n (fn (target coll)\n (cond\n (list? target)\n (if (list? coll)\n (concat coll (list))\n (let ((result (list)))\n (for-each (fn (k) (append! result (list k (get coll k)))) (keys coll))\n result))\n (dict? target)\n (let ((result (dict)))\n (for-each\n (fn (pair)\n (when (and (list? pair) (>= (len pair) 2))\n (dict-set! result (get pair 0) (get pair 1))))\n coll)\n result)\n :else target)))\n\n\n;; --------------------------------------------------------------------------\n;; String operations\n;; --------------------------------------------------------------------------\n\n(define upcase (fn (s) (upper s)))\n(define downcase (fn (s) (lower s)))\n(define string-length (fn (s) (len s)))\n(define substring (fn (s start end) (slice s start end)))\n\n(define string-contains?\n (fn (s needle) (!= (index-of s needle) -1)))\n\n(define starts-with?\n (fn (s prefix) (= (index-of s prefix) 0)))\n\n(define ends-with?\n (fn (s suffix)\n (let ((slen (len s))\n (plen (len suffix)))\n (if (< slen plen) false\n (= (slice s (- slen plen)) suffix)))))\n\n;; split, join, replace stay as primitives — the stdlib versions cause\n;; stack overflows due to PRIMITIVES entry shadowing in the transpiled output.\n\n(define contains?\n (fn (coll key)\n (cond\n (string? coll) (!= (index-of coll (str key)) -1)\n (dict? coll) (has-key? coll key)\n (list? coll) (some (fn (x) (= x key)) coll)\n :else false)))\n\n\n;; --------------------------------------------------------------------------\n;; Text utilities\n;; --------------------------------------------------------------------------\n\n(define pluralize\n (fn (count singular plural)\n (if (= count 1)\n (or singular \"\")\n (or plural \"s\"))))\n\n(define escape\n (fn (s)\n (let ((r (str s)))\n (set! r (replace r \"&\" \"&amp;\"))\n (set! r (replace r \"<\" \"&lt;\"))\n (set! r (replace r \">\" \"&gt;\"))\n (set! r (replace r \"\\\"\" \"&quot;\"))\n (set! r (replace r \"'\" \"&#x27;\"))\n r)))\n\n(define parse-datetime\n (fn (s) (if s (str s) nil)))\n\n(define assert\n (fn (condition message)\n (when (not condition)\n (error (or message \"Assertion failed\")))\n true))\n";
var forms = sxParse(src);
var tmpEnv = merge({}, PRIMITIVES);
for (var i = 0; i < forms.length; i++) {
trampoline(evalExpr(forms[i], tmpEnv));
}
for (var k in tmpEnv) {
if (!PRIMITIVES[k]) PRIMITIVES[k] = tmpEnv[k];
}
})();
// =========================================================================
// Platform interface — DOM adapter (browser-only)
// =========================================================================
var _hasDom = typeof document !== "undefined";
// Register DOM adapter as the render dispatch target for the evaluator.
_renderExprFn = function(expr, env) { return renderToDom(expr, env, null); };
_renderMode = true; // Browser always evaluates in render context.
// Wire CEK render hooks — evaluator checks _renderCheck/_renderFn instead of
// the old renderActiveP()/isRenderExpr()/renderExpr() triple.
_renderCheck = function(expr, env) { return _renderMode && isRenderExpr(expr); };
_renderFn = function(expr, env) { return renderToDom(expr, env, null); };
var SVG_NS = "http://www.w3.org/2000/svg";
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
function domCreateElement(tag, ns) {
if (!_hasDom) return null;
if (ns && ns !== NIL) return document.createElementNS(ns, tag);
return document.createElement(tag);
}
function createTextNode(s) {
return _hasDom ? document.createTextNode(s) : null;
}
function createComment(s) {
return _hasDom ? document.createComment(s || "") : null;
}
function createFragment() {
return _hasDom ? document.createDocumentFragment() : null;
}
function domAppend(parent, child) {
if (parent && child && !child._spread) parent.appendChild(child);
}
function domPrepend(parent, child) {
if (parent && child) parent.insertBefore(child, parent.firstChild);
}
function domSetAttr(el, name, val) {
if (el && el.setAttribute) el.setAttribute(name, val);
}
function domGetAttr(el, name) {
if (!el || !el.getAttribute) return NIL;
var v = el.getAttribute(name);
return v === null ? NIL : v;
}
function domRemoveAttr(el, name) {
if (el && el.removeAttribute) el.removeAttribute(name);
}
function domHasAttr(el, name) {
return !!(el && el.hasAttribute && el.hasAttribute(name));
}
function domParseHtml(html) {
if (!_hasDom) return null;
var tpl = document.createElement("template");
tpl.innerHTML = html;
return tpl.content;
}
function domClone(node) {
return node && node.cloneNode ? node.cloneNode(true) : node;
}
function domParent(el) { return el ? el.parentNode : null; }
function domId(el) { return el && el.id ? el.id : NIL; }
function domNodeType(el) { return el ? el.nodeType : 0; }
function domNodeName(el) { return el ? el.nodeName : ""; }
function domTextContent(el) { return el ? el.textContent || el.nodeValue || "" : ""; }
function domSetTextContent(el, s) { if (el) { if (el.nodeType === 3 || el.nodeType === 8) el.nodeValue = s; else el.textContent = s; } }
function domIsFragment(el) { return el ? el.nodeType === 11 : false; }
function domIsChildOf(child, parent) { return !!(parent && child && child.parentNode === parent); }
function domIsActiveElement(el) { return _hasDom && el === document.activeElement; }
function domIsInputElement(el) {
if (!el || !el.tagName) return false;
var t = el.tagName;
return t === "INPUT" || t === "TEXTAREA" || t === "SELECT";
}
function domFirstChild(el) { return el ? el.firstChild : null; }
function domNextSibling(el) { return el ? el.nextSibling : null; }
function domChildList(el) {
if (!el || !el.childNodes) return [];
return Array.prototype.slice.call(el.childNodes);
}
function domAttrList(el) {
if (!el || !el.attributes) return [];
var r = [];
for (var i = 0; i < el.attributes.length; i++) {
r.push([el.attributes[i].name, el.attributes[i].value]);
}
return r;
}
function domInsertBefore(parent, node, ref) {
if (parent && node) parent.insertBefore(node, ref || null);
}
function domInsertAfter(ref, node) {
if (ref && ref.parentNode && node && !node._spread) {
ref.parentNode.insertBefore(node, ref.nextSibling);
}
}
function domRemoveChild(parent, child) {
if (parent && child && child.parentNode === parent) parent.removeChild(child);
}
function domReplaceChild(parent, newChild, oldChild) {
if (parent && newChild && oldChild) parent.replaceChild(newChild, oldChild);
}
function domSetInnerHtml(el, html) {
if (el) el.innerHTML = html;
}
function domInsertAdjacentHtml(el, pos, html) {
if (el && el.insertAdjacentHTML) el.insertAdjacentHTML(pos, html);
}
function domGetStyle(el, prop) {
return el && el.style ? el.style[prop] || "" : "";
}
function domSetStyle(el, prop, val) {
if (el && el.style) el.style[prop] = val;
}
function domGetProp(el, name) { return el ? el[name] : NIL; }
function domSetProp(el, name, val) { if (el) el[name] = val; }
// Call a method on an object with correct this binding: (dom-call-method obj "methodName" arg1 arg2 ...)
function domCallMethod() {
var obj = arguments[0], method = arguments[1];
var args = Array.prototype.slice.call(arguments, 2);
if (obj && typeof obj[method] === 'function') {
try { return obj[method].apply(obj, args); }
catch(e) { console.error("[sx] dom-call-method error:", e); return NIL; }
}
return NIL;
}
// Post a message to an iframe's contentWindow without exposing the cross-origin
// Window object to the SX evaluator (which would trigger _thunk access errors).
function domPostMessage(iframe, msg, origin) {
try {
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(msg, origin || '*');
}
} catch(e) { console.error("[sx] domPostMessage error:", e); }
return NIL;
}
function domAddClass(el, cls) {
if (el && el.classList) el.classList.add(cls);
}
function domRemoveClass(el, cls) {
if (el && el.classList) el.classList.remove(cls);
}
function domDispatch(el, name, detail) {
if (!_hasDom || !el) return false;
var evt = new CustomEvent(name, { bubbles: true, cancelable: true, detail: detail || {} });
return el.dispatchEvent(evt);
}
function domListen(el, name, handler) {
if (!_hasDom || !el) return function() {};
// Wrap SX lambdas from runtime-evaluated island code into native fns
// If lambda takes 0 params, call without event arg (convenience for on-click handlers)
var wrapped = isLambda(handler)
? (lambdaParams(handler).length === 0
? function(e) { try { cekCall(handler, NIL); } catch(err) { console.error("[sx-ref] domListen handler error:", name, err); } }
: function(e) { try { cekCall(handler, [e]); } catch(err) { console.error("[sx-ref] domListen handler error:", name, err); } })
: handler;
if (name === "click") logInfo("domListen: click on <" + (el.tagName||"?").toLowerCase() + "> text=" + (el.textContent||"").substring(0,20) + " isLambda=" + isLambda(handler));
var passiveEvents = { touchstart: 1, touchmove: 1, wheel: 1, scroll: 1 };
var opts = passiveEvents[name] ? { passive: true } : undefined;
el.addEventListener(name, wrapped, opts);
return function() { el.removeEventListener(name, wrapped, opts); };
}
function eventDetail(e) {
return (e && e.detail != null) ? e.detail : NIL;
}
function domQuery(sel) {
return _hasDom ? document.querySelector(sel) : null;
}
function domEnsureElement(sel) {
if (!_hasDom) return null;
var el = document.querySelector(sel);
if (el) return el;
// Parse #id selector → create div with that id, append to body
if (sel.charAt(0) === '#') {
el = document.createElement('div');
el.id = sel.slice(1);
document.body.appendChild(el);
return el;
}
return null;
}
function domQueryAll(root, sel) {
if (!root || !root.querySelectorAll) return [];
return Array.prototype.slice.call(root.querySelectorAll(sel));
}
function domTagName(el) { return el && el.tagName ? el.tagName : ""; }
// Island DOM helpers
function domRemove(node) {
if (node && node.parentNode) node.parentNode.removeChild(node);
}
function domChildNodes(el) {
if (!el || !el.childNodes) return [];
return Array.prototype.slice.call(el.childNodes);
}
function domRemoveChildrenAfter(marker) {
if (!marker || !marker.parentNode) return;
var parent = marker.parentNode;
while (marker.nextSibling) parent.removeChild(marker.nextSibling);
}
function domSetData(el, key, val) {
if (el) { if (!el._sxData) el._sxData = {}; el._sxData[key] = val; }
}
function domGetData(el, key) {
return (el && el._sxData) ? (el._sxData[key] != null ? el._sxData[key] : NIL) : NIL;
}
function domInnerHtml(el) {
return (el && el.innerHTML != null) ? el.innerHTML : "";
}
function jsonParse(s) {
try { return JSON.parse(s); } catch(e) { return {}; }
}
// renderDomComponent and renderDomElement are transpiled from
// adapter-dom.sx — no imperative overrides needed.
// =========================================================================
// Platform interface — Engine pure logic (browser + node compatible)
// =========================================================================
function browserLocationHref() {
return typeof location !== "undefined" ? location.href : "";
}
function browserSameOrigin(url) {
try { return new URL(url, location.href).origin === location.origin; }
catch (e) { return true; }
}
function browserPushState(url) {
if (typeof history !== "undefined") {
try { history.pushState({ sxUrl: url, scrollY: typeof window !== "undefined" ? window.scrollY : 0 }, "", url); }
catch (e) {}
}
}
function browserReplaceState(url) {
if (typeof history !== "undefined") {
try { history.replaceState({ sxUrl: url, scrollY: typeof window !== "undefined" ? window.scrollY : 0 }, "", url); }
catch (e) {}
}
}
function nowMs() { return (typeof performance !== "undefined") ? performance.now() : Date.now(); }
function parseHeaderValue(s) {
if (!s) return null;
try {
if (s.charAt(0) === "{" && s.charAt(1) === ":") return parse(s);
return JSON.parse(s);
} catch (e) { return null; }
}
// =========================================================================
// Platform interface — Orchestration (browser-only)
// =========================================================================
// --- Browser/Network ---
function browserNavigate(url) {
if (typeof location !== "undefined") location.assign(url);
}
function browserReload() {
if (typeof location !== "undefined") location.reload();
}
function browserScrollTo(x, y) {
if (typeof window !== "undefined") window.scrollTo(x, y);
}
function browserMediaMatches(query) {
if (typeof window === "undefined") return false;
return window.matchMedia(query).matches;
}
function browserConfirm(msg) {
if (typeof window === "undefined") return false;
return window.confirm(msg);
}
function browserPrompt(msg) {
if (typeof window === "undefined") return NIL;
var r = window.prompt(msg);
return r === null ? NIL : r;
}
function csrfToken() {
if (!_hasDom) return NIL;
var m = document.querySelector('meta[name="csrf-token"]');
return m ? m.getAttribute("content") : NIL;
}
function isCrossOrigin(url) {
try {
var h = new URL(url, location.href).hostname;
return h !== location.hostname &&
(h.indexOf(".rose-ash.com") >= 0 || h.indexOf(".localhost") >= 0);
} catch (e) { return false; }
}
// --- Promises ---
function promiseResolve(val) { return Promise.resolve(val); }
function promiseThen(p, onResolve, onReject) {
if (!p || !p.then) return p;
return onReject ? p.then(onResolve, onReject) : p.then(onResolve);
}
function promiseCatch(p, fn) { return p && p.catch ? p.catch(fn) : p; }
function promiseDelayed(ms, value) {
return new Promise(function(resolve) {
setTimeout(function() { resolve(value); }, ms);
});
}
// --- Abort controllers ---
var _controllers = typeof WeakMap !== "undefined" ? new WeakMap() : null;
function abortPrevious(el) {
if (_controllers) {
var prev = _controllers.get(el);
if (prev) prev.abort();
}
}
function trackController(el, ctrl) {
if (_controllers) _controllers.set(el, ctrl);
}
var _targetControllers = typeof WeakMap !== "undefined" ? new WeakMap() : null;
function abortPreviousTarget(el) {
if (_targetControllers) {
var prev = _targetControllers.get(el);
if (prev) prev.abort();
}
}
function trackControllerTarget(el, ctrl) {
if (_targetControllers) _targetControllers.set(el, ctrl);
}
function newAbortController() {
return typeof AbortController !== "undefined" ? new AbortController() : { signal: null, abort: function() {} };
}
function controllerSignal(ctrl) { return ctrl ? ctrl.signal : null; }
function isAbortError(err) { return err && err.name === "AbortError"; }
// --- Timers ---
function _wrapSxFn(fn) {
if (fn && fn._lambda) {
return function() { return trampoline(callLambda(fn, [], lambdaClosure(fn))); };
}
return fn;
}
function setTimeout_(fn, ms) { return setTimeout(_wrapSxFn(fn), ms || 0); }
function setInterval_(fn, ms) { return setInterval(_wrapSxFn(fn), ms || 1000); }
function clearTimeout_(id) { clearTimeout(id); }
function clearInterval_(id) { clearInterval(id); }
function requestAnimationFrame_(fn) {
var cb = _wrapSxFn(fn);
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(cb);
else setTimeout(cb, 16);
}
// --- Fetch ---
function fetchRequest(config, successFn, errorFn) {
var opts = { method: config.method, headers: config.headers };
if (config.signal) opts.signal = config.signal;
if (config.body && config.method !== "GET") opts.body = config.body;
if (config["cross-origin"]) opts.credentials = "include";
var p = (config.preloaded && config.preloaded !== NIL)
? Promise.resolve({
ok: true, status: 200,
headers: new Headers({ "Content-Type": config.preloaded["content-type"] || "" }),
text: function() { return Promise.resolve(config.preloaded.text); }
})
: fetch(config.url, opts);
return p.then(function(resp) {
return resp.text().then(function(text) {
var getHeader = function(name) {
var v = resp.headers.get(name);
return v === null ? NIL : v;
};
return successFn(resp.ok, resp.status, getHeader, text);
});
}).catch(function(err) {
return errorFn(err);
});
}
function fetchLocation(headerVal) {
if (!_hasDom) return;
var locUrl = headerVal;
try { var obj = JSON.parse(headerVal); locUrl = obj.path || obj; } catch (e) {}
fetch(locUrl, { headers: { "SX-Request": "true" } }).then(function(r) {
return r.text().then(function(t) {
var main = document.getElementById("main-panel");
if (main) {
main.innerHTML = t;
postSwap(main);
try { history.pushState({ sxUrl: locUrl }, "", locUrl); } catch (e) {}
}
});
});
}
function fetchAndRestore(main, url, headers, scrollY) {
var opts = { headers: headers };
try {
var h = new URL(url, location.href).hostname;
if (h !== location.hostname &&
(h.indexOf(".rose-ash.com") >= 0 || h.indexOf(".localhost") >= 0)) {
opts.credentials = "include";
}
} catch (e) {}
fetch(url, opts).then(function(resp) {
return resp.text().then(function(text) {
text = stripComponentScripts(text);
text = extractResponseCss(text);
text = text.trim();
if (text.charAt(0) === "(") {
try {
var dom = sxRender(text);
var container = document.createElement("div");
container.appendChild(dom);
processOobSwaps(container, function(t, oob, s) {
swapDomNodes(t, oob, s);
sxHydrate(t);
processElements(t);
});
var newMain = container.querySelector("#main-panel");
morphChildren(main, newMain || container);
postSwap(main);
if (typeof window !== "undefined") window.scrollTo(0, scrollY || 0);
} catch (err) {
console.error("sx-ref popstate error:", err);
location.reload();
}
} else {
var parser = new DOMParser();
var doc = parser.parseFromString(text, "text/html");
var newMain = doc.getElementById("main-panel");
if (newMain) {
morphChildren(main, newMain);
postSwap(main);
if (typeof window !== "undefined") window.scrollTo(0, scrollY || 0);
} else {
location.reload();
}
}
});
}).catch(function(err) {
logWarn("sx:popstate fetch error " + url + " — " + (err && err.message ? err.message : err));
location.reload();
});
}
function fetchStreaming(target, url, headers) {
// Streaming fetch for multi-stream pages.
// First chunk = OOB SX swap (shell with skeletons).
// Subsequent chunks = __sxResolve script tags filling suspense slots.
var opts = { headers: headers };
try {
var h = new URL(url, location.href).hostname;
if (h !== location.hostname &&
(h.indexOf(".rose-ash.com") >= 0 || h.indexOf(".localhost") >= 0)) {
opts.credentials = "include";
}
} catch (e) {}
fetch(url, opts).then(function(resp) {
if (!resp.ok || !resp.body) {
// Fallback: non-streaming
return resp.text().then(function(text) {
text = stripComponentScripts(text);
text = extractResponseCss(text);
text = text.trim();
if (text.charAt(0) === "(") {
var dom = sxRender(text);
var container = document.createElement("div");
container.appendChild(dom);
processOobSwaps(container, function(t, oob, s) {
swapDomNodes(t, oob, s);
sxHydrate(t);
processElements(t);
});
var newMain = container.querySelector("#main-panel");
morphChildren(target, newMain || container);
postSwap(target);
}
});
}
var reader = resp.body.getReader();
var decoder = new TextDecoder();
var buffer = "";
var initialSwapDone = false;
// Regex to match __sxResolve script tags
var RESOLVE_START = "<script>window.__sxResolve&&window.__sxResolve(";
var RESOLVE_END = ")</script>";
function processResolveScripts() {
// Strip and load any extra component defs before resolve scripts
buffer = stripSxScripts(buffer);
var idx;
while ((idx = buffer.indexOf(RESOLVE_START)) >= 0) {
var endIdx = buffer.indexOf(RESOLVE_END, idx);
if (endIdx < 0) break; // incomplete, wait for more data
var argsStr = buffer.substring(idx + RESOLVE_START.length, endIdx);
buffer = buffer.substring(endIdx + RESOLVE_END.length);
// argsStr is: "stream-id","sx source"
var commaIdx = argsStr.indexOf(",");
if (commaIdx >= 0) {
try {
var id = JSON.parse(argsStr.substring(0, commaIdx));
var sx = JSON.parse(argsStr.substring(commaIdx + 1));
if (typeof Sx !== "undefined" && Sx.resolveSuspense) {
Sx.resolveSuspense(id, sx);
}
} catch (e) {
console.error("[sx-ref] resolve parse error:", e);
}
}
}
}
function pump() {
return reader.read().then(function(result) {
buffer += decoder.decode(result.value || new Uint8Array(), { stream: !result.done });
if (!initialSwapDone) {
// Look for the first resolve script — everything before it is OOB content
var scriptIdx = buffer.indexOf("<script>window.__sxResolve");
// If we found a script tag, or the stream is done, process OOB
var oobEnd = scriptIdx >= 0 ? scriptIdx : (result.done ? buffer.length : -1);
if (oobEnd >= 0) {
var oobContent = buffer.substring(0, oobEnd);
buffer = buffer.substring(oobEnd);
initialSwapDone = true;
// Process OOB SX content (same as fetchAndRestore)
oobContent = stripComponentScripts(oobContent);
// Also strip bare <script type="text/sx"> (extra defs from resolve chunks)
oobContent = stripSxScripts(oobContent);
oobContent = extractResponseCss(oobContent);
oobContent = oobContent.trim();
if (oobContent.charAt(0) === "(") {
try {
var dom = sxRender(oobContent);
var container = document.createElement("div");
container.appendChild(dom);
processOobSwaps(container, function(t, oob, s) {
swapDomNodes(t, oob, s);
sxHydrate(t);
processElements(t);
});
var newMain = container.querySelector("#main-panel");
morphChildren(target, newMain || container);
postSwap(target);
// Dispatch clientRoute so nav links update active state
domDispatch(target, "sx:clientRoute",
{ pathname: new URL(url, location.href).pathname });
} catch (err) {
console.error("[sx-ref] streaming OOB swap error:", err);
}
}
// Process any resolve scripts already in buffer
processResolveScripts();
}
} else {
// Process resolve scripts as they arrive
processResolveScripts();
}
if (!result.done) return pump();
});
}
return pump();
}).catch(function(err) {
console.error("[sx-ref] streaming fetch error:", err);
location.reload();
});
}
function fetchPreload(url, headers, cache) {
fetch(url, { headers: headers }).then(function(resp) {
if (!resp.ok) return;
var ct = resp.headers.get("Content-Type") || "";
return resp.text().then(function(text) {
preloadCacheSet(cache, url, text, ct);
});
}).catch(function(err) {
logInfo("sx:preload error " + url + " — " + (err && err.message ? err.message : err));
});
}
// --- Request body building ---
function buildRequestBody(el, method, url) {
if (!_hasDom) return { body: null, url: url, "content-type": NIL };
var body = null;
var ct = NIL;
var finalUrl = url;
var isJson = el.getAttribute("sx-encoding") === "json";
if (method !== "GET") {
var form = el.closest("form") || (el.tagName === "FORM" ? el : null);
if (form) {
if (isJson) {
var fd = new FormData(form);
var obj = {};
fd.forEach(function(v, k) {
if (obj[k] !== undefined) {
if (!Array.isArray(obj[k])) obj[k] = [obj[k]];
obj[k].push(v);
} else { obj[k] = v; }
});
body = JSON.stringify(obj);
ct = "application/json";
} else {
body = new URLSearchParams(new FormData(form));
ct = "application/x-www-form-urlencoded";
}
}
}
// sx-params
var paramsSpec = el.getAttribute("sx-params");
if (paramsSpec && body instanceof URLSearchParams) {
if (paramsSpec === "none") {
body = new URLSearchParams();
} else if (paramsSpec.indexOf("not ") === 0) {
paramsSpec.substring(4).split(",").forEach(function(k) { body.delete(k.trim()); });
} else if (paramsSpec !== "*") {
var allowed = paramsSpec.split(",").map(function(s) { return s.trim(); });
var filtered = new URLSearchParams();
allowed.forEach(function(k) {
body.getAll(k).forEach(function(v) { filtered.append(k, v); });
});
body = filtered;
}
}
// sx-include
var includeSel = el.getAttribute("sx-include");
if (includeSel && method !== "GET") {
if (!body) body = new URLSearchParams();
document.querySelectorAll(includeSel).forEach(function(inp) {
if (inp.name) body.append(inp.name, inp.value);
});
}
// sx-vals
var valsAttr = el.getAttribute("sx-vals");
if (valsAttr) {
try {
var vals = valsAttr.charAt(0) === "{" && valsAttr.charAt(1) === ":" ? parse(valsAttr) : JSON.parse(valsAttr);
if (method === "GET") {
for (var vk in vals) finalUrl += (finalUrl.indexOf("?") >= 0 ? "&" : "?") + encodeURIComponent(vk) + "=" + encodeURIComponent(vals[vk]);
} else if (body instanceof URLSearchParams) {
for (var vk2 in vals) body.append(vk2, vals[vk2]);
} else if (!body) {
body = new URLSearchParams();
for (var vk3 in vals) body.append(vk3, vals[vk3]);
ct = "application/x-www-form-urlencoded";
}
} catch (e) {}
}
// GET form data → URL
if (method === "GET") {
var form2 = el.closest("form") || (el.tagName === "FORM" ? el : null);
if (form2) {
var qs = new URLSearchParams(new FormData(form2)).toString();
if (qs) finalUrl += (finalUrl.indexOf("?") >= 0 ? "&" : "?") + qs;
}
if ((el.tagName === "INPUT" || el.tagName === "SELECT" || el.tagName === "TEXTAREA") && el.name) {
finalUrl += (finalUrl.indexOf("?") >= 0 ? "&" : "?") + encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value);
}
}
return { body: body, url: finalUrl, "content-type": ct };
}
// --- Loading state ---
function showIndicator(el) {
if (!_hasDom) return NIL;
var sel = el.getAttribute("sx-indicator");
var ind = sel ? (document.querySelector(sel) || el.closest(sel)) : null;
if (ind) { ind.classList.add("sx-request"); ind.style.display = ""; }
return ind || NIL;
}
function disableElements(el) {
if (!_hasDom) return [];
var sel = el.getAttribute("sx-disabled-elt");
if (!sel) return [];
var elts = Array.prototype.slice.call(document.querySelectorAll(sel));
elts.forEach(function(e) { e.disabled = true; });
return elts;
}
function clearLoadingState(el, indicator, disabledElts) {
el.classList.remove("sx-request");
el.removeAttribute("aria-busy");
if (indicator && !isNil(indicator)) {
indicator.classList.remove("sx-request");
indicator.style.display = "none";
}
if (disabledElts) {
for (var i = 0; i < disabledElts.length; i++) disabledElts[i].disabled = false;
}
}
// --- DOM extras ---
function domQueryById(id) {
return _hasDom ? document.getElementById(id) : null;
}
function domMatches(el, sel) {
return el && el.matches ? el.matches(sel) : false;
}
function domClosest(el, sel) {
return el && el.closest ? el.closest(sel) : null;
}
function domBody() {
return _hasDom ? document.body : null;
}
function domHasClass(el, cls) {
return el && el.classList ? el.classList.contains(cls) : false;
}
function domAppendToHead(el) {
if (_hasDom && document.head) document.head.appendChild(el);
}
function domParseHtmlDocument(text) {
if (!_hasDom) return null;
return new DOMParser().parseFromString(text, "text/html");
}
function domOuterHtml(el) {
return el ? el.outerHTML : "";
}
function domBodyInnerHtml(doc) {
return doc && doc.body ? doc.body.innerHTML : "";
}
// --- Events ---
function preventDefault_(e) { if (e && e.preventDefault) e.preventDefault(); }
function stopPropagation_(e) { if (e && e.stopPropagation) e.stopPropagation(); }
function eventModifierKey_p(e) { return !!(e && (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey)); }
function domFocus(el) { if (el && el.focus) el.focus(); }
function tryCatch(tryFn, catchFn) {
var t = _wrapSxFn(tryFn);
var c = catchFn && catchFn._lambda
? function(e) { return trampoline(callLambda(catchFn, [e], lambdaClosure(catchFn))); }
: catchFn;
try { return t(); } catch (e) { return c(e); }
}
function errorMessage(e) {
return e && e.message ? e.message : String(e);
}
function scheduleIdle(fn) {
var cb = _wrapSxFn(fn);
if (typeof cb !== "function") {
console.error("[sx-ref] scheduleIdle: callback not callable, fn type:", typeof fn, "fn:", fn, "_lambda:", fn && fn._lambda);
return;
}
if (typeof requestIdleCallback !== "undefined") requestIdleCallback(cb);
else setTimeout(cb, 0);
}
function elementValue(el) { return el && el.value !== undefined ? el.value : NIL; }
function domAddListener(el, event, fn, opts) {
if (!el || !el.addEventListener) return;
var o = {};
if (opts && !isNil(opts)) {
if (opts.once || opts["once"]) o.once = true;
}
el.addEventListener(event, function(e) {
try { fn(e); } catch (err) { logInfo("EVENT ERROR: " + event + " " + (err && err.message ? err.message : err)); console.error("[sx-ref] event handler error:", event, err); }
}, o);
}
// --- Validation ---
function validateForRequest(el) {
if (!_hasDom) return true;
var attr = el.getAttribute("sx-validate");
if (attr === null) {
var vForm = el.closest("[sx-validate]");
if (vForm) attr = vForm.getAttribute("sx-validate");
}
if (attr === null) return true; // no validation configured
var form = el.tagName === "FORM" ? el : el.closest("form");
if (form && !form.reportValidity()) return false;
if (attr && attr !== "true" && attr !== "") {
var fn = window[attr];
if (typeof fn === "function" && !fn(el)) return false;
}
return true;
}
// --- View Transitions ---
function withTransition(enabled, fn) {
if (enabled && _hasDom && document.startViewTransition) {
document.startViewTransition(fn);
} else {
fn();
}
}
// --- IntersectionObserver ---
function observeIntersection(el, fn, once, delay) {
if (!_hasDom || !("IntersectionObserver" in window)) { fn(); return; }
var fired = false;
var d = isNil(delay) ? 0 : delay;
var obs = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (!entry.isIntersecting) return;
if (once && fired) return;
fired = true;
if (once) obs.unobserve(el);
if (d) setTimeout(fn, d); else fn();
});
});
obs.observe(el);
}
// --- EventSource ---
function eventSourceConnect(url, el) {
var source = new EventSource(url);
source.addEventListener("error", function() { domDispatch(el, "sx:sseError", {}); });
source.addEventListener("open", function() { domDispatch(el, "sx:sseOpen", {}); });
if (typeof MutationObserver !== "undefined") {
var obs = new MutationObserver(function() {
if (!document.body.contains(el)) { source.close(); obs.disconnect(); }
});
obs.observe(document.body, { childList: true, subtree: true });
}
return source;
}
function eventSourceListen(source, event, fn) {
source.addEventListener(event, function(e) { fn(e.data); });
}
// --- Boost bindings ---
function bindBoostLink(el, _href) {
el.addEventListener("click", function(e) {
if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return;
e.preventDefault();
// Re-read href from element at click time (not closed-over value)
var liveHref = el.getAttribute("href") || _href;
console.log("[sx-debug] bindBoostLink click:", liveHref, "el:", el.tagName, el.textContent.slice(0,30));
executeRequest(el, { method: "GET", url: liveHref }).then(function() {
console.log("[sx-debug] boost fetch OK, pushState:", liveHref);
try { history.pushState({ sxUrl: liveHref, scrollY: window.scrollY }, "", liveHref); } catch (err) {}
}).catch(function(err) {
console.error("[sx-debug] boost fetch ERROR:", err);
});
});
}
function bindBoostForm(form, _method, _action) {
form.addEventListener("submit", function(e) {
e.preventDefault();
// Re-read from element at submit time
var liveMethod = (form.getAttribute("method") || _method || "GET").toUpperCase();
var liveAction = form.getAttribute("action") || _action || location.href;
executeRequest(form, { method: liveMethod, url: liveAction }).then(function() {
try { history.pushState({ sxUrl: liveAction, scrollY: window.scrollY }, "", liveAction); } catch (err) {}
}).catch(function(err) {
logWarn("sx:boost form error " + liveMethod + " " + liveAction + " — " + (err && err.message ? err.message : err));
});
});
}
// --- Client-side route bindings ---
function bindClientRouteClick(link, _href, fallbackFn) {
link.addEventListener("click", function(e) {
if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return;
e.preventDefault();
// Re-read href from element at click time (not closed-over value)
var liveHref = link.getAttribute("href") || _href;
var pathname = urlPathname(liveHref);
console.log("[sx-debug] bindClientRouteClick:", pathname, "el:", link.tagName, link.textContent.slice(0,30));
// Find target selector: sx-boost ancestor, explicit sx-target, or #main-panel
var boostEl = link.closest("[sx-boost]");
var targetSel = boostEl ? boostEl.getAttribute("sx-boost") : null;
if (!targetSel || targetSel === "true") {
targetSel = link.getAttribute("sx-target") || "#main-panel";
}
console.log("[sx-debug] targetSel:", targetSel, "trying client route...");
if (tryClientRoute(pathname, targetSel)) {
console.log("[sx-debug] client route SUCCESS, pushState:", liveHref);
try { history.pushState({ sxUrl: liveHref, scrollY: window.scrollY }, "", liveHref); } catch (err) {}
if (typeof window !== "undefined") window.scrollTo(0, 0);
} else {
console.log("[sx-debug] client route FAILED, server fetch:", liveHref);
executeRequest(link, { method: "GET", url: liveHref }).then(function() {
console.log("[sx-debug] server fetch OK, pushState:", liveHref);
try { history.pushState({ sxUrl: liveHref, scrollY: window.scrollY }, "", liveHref); } catch (err) {}
}).catch(function(err) {
console.error("[sx-debug] server fetch ERROR:", err);
});
}
});
}
function tryEvalContent(source, env) {
try {
var merged = merge(componentEnv);
if (env && !isNil(env)) {
var ks = Object.keys(env);
for (var i = 0; i < ks.length; i++) merged[ks[i]] = env[ks[i]];
}
return sxRenderWithEnv(source, merged);
} catch (e) {
logInfo("sx:route eval miss: " + (e && e.message ? e.message : e));
return NIL;
}
}
// Async eval with callback — used for pages with IO deps.
// Calls callback(rendered) when done, callback(null) on failure.
function tryAsyncEvalContent(source, env, callback) {
var merged = merge(componentEnv);
if (env && !isNil(env)) {
var ks = Object.keys(env);
for (var i = 0; i < ks.length; i++) merged[ks[i]] = env[ks[i]];
}
try {
var result = asyncSxRenderWithEnv(source, merged);
if (isPromise(result)) {
result.then(function(rendered) {
callback(rendered);
}).catch(function(e) {
logWarn("sx:async eval miss: " + (e && e.message ? e.message : e));
callback(null);
});
} else {
callback(result);
}
} catch (e) {
logInfo("sx:async eval miss: " + (e && e.message ? e.message : e));
callback(null);
}
}
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 parseSxData(text) {
// Parse SX text into a data value. Returns the first parsed expression,
// or NIL on error. Used by cache update directives.
try {
var exprs = parse(text);
return exprs.length >= 1 ? exprs[0] : NIL;
} catch (e) {
logWarn("sx:cache parse error: " + (e && e.message ? e.message : e));
return NIL;
}
}
function swPostMessage(msg) {
// Send a message to the active service worker (if registered).
// Used to notify SW of cache invalidation.
if (typeof navigator !== "undefined" && navigator.serviceWorker &&
navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage(msg);
}
}
function urlPathname(href) {
try {
return new URL(href, location.href).pathname;
} catch (e) {
// Fallback: strip query/hash
var idx = href.indexOf("?");
if (idx >= 0) href = href.substring(0, idx);
idx = href.indexOf("#");
if (idx >= 0) href = href.substring(0, idx);
return href;
}
}
// --- Preload binding ---
function bindPreload(el, events, debounceMs, fn) {
var timer = null;
events.forEach(function(evt) {
el.addEventListener(evt, function() {
if (debounceMs) {
clearTimeout(timer);
timer = setTimeout(fn, debounceMs);
} else {
fn();
}
}, { passive: true });
});
}
// --- Processing markers ---
var PROCESSED = "_sxBound";
function markProcessed(el, key) { el[PROCESSED + key] = true; }
function isProcessed(el, key) { return !!el[PROCESSED + key]; }
function clearProcessed(el, key) { delete el[PROCESSED + key]; }
// --- Script cloning ---
function createScriptClone(dead) {
var live = document.createElement("script");
for (var i = 0; i < dead.attributes.length; i++)
live.setAttribute(dead.attributes[i].name, dead.attributes[i].value);
live.textContent = dead.textContent;
return live;
}
// --- SX API references ---
function sxRender(source) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
if (SxObj && SxObj.render) return SxObj.render(source);
throw new Error("No SX renderer available");
}
function sxProcessScripts(root) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
var r = (root && root !== NIL) ? root : undefined;
if (SxObj && SxObj.processScripts) SxObj.processScripts(r);
}
function sxHydrate(root) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
var r = (root && root !== NIL) ? root : undefined;
if (SxObj && SxObj.hydrate) SxObj.hydrate(r);
}
function loadedComponentNames() {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
if (!SxObj) return [];
var env = SxObj.componentEnv || (SxObj.getEnv ? SxObj.getEnv() : {});
return Object.keys(env).filter(function(k) { return k.charAt(0) === "~"; });
}
// --- Response processing ---
function stripComponentScripts(text) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
return text.replace(/<script[^>]*type="text\/sx"[^>]*data-components[^>]*>([\s\S]*?)<\/script>/gi,
function(_, defs) { if (SxObj && SxObj.loadComponents) SxObj.loadComponents(defs); return ""; });
}
function stripSxScripts(text) {
// Strip <script type="text/sx">...</script> (without data-components or data-init).
// These contain extra component defs from streaming resolve chunks.
// data-init scripts are preserved for process-sx-scripts to evaluate as side effects.
var SxObj = typeof Sx !== "undefined" ? Sx : null;
return text.replace(/<script[^>]*type="text\/sx"[^>]*>[\s\S]*?<\/script>/gi,
function(match) {
if (/data-init/.test(match)) return match; // preserve data-init scripts
var m = match.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
if (m && SxObj && SxObj.loadComponents) SxObj.loadComponents(m[1]);
return "";
});
}
function extractResponseCss(text) {
if (!_hasDom) return text;
var target = document.getElementById("sx-css");
if (!target) return text;
return text.replace(/<style[^>]*data-sx-css[^>]*>([\s\S]*?)<\/style>/gi,
function(_, css) { target.textContent += css; return ""; });
}
function selectFromContainer(container, sel) {
var frag = document.createDocumentFragment();
sel.split(",").forEach(function(s) {
container.querySelectorAll(s.trim()).forEach(function(m) { frag.appendChild(m); });
});
return frag;
}
function childrenToFragment(container) {
var frag = document.createDocumentFragment();
while (container.firstChild) frag.appendChild(container.firstChild);
return frag;
}
function selectHtmlFromDoc(doc, sel) {
var parts = sel.split(",").map(function(s) { return s.trim(); });
var frags = [];
parts.forEach(function(s) {
doc.querySelectorAll(s).forEach(function(m) { frags.push(m.outerHTML); });
});
return frags.join("");
}
// --- Parsing ---
function tryParseJson(s) {
if (!s) return NIL;
try { return JSON.parse(s); } catch (e) { return NIL; }
}
// =========================================================================
// Platform interface — Boot (mount, hydrate, scripts, cookies)
// =========================================================================
function resolveMountTarget(target) {
if (typeof target === "string") return _hasDom ? document.querySelector(target) : null;
return target;
}
function sxRenderWithEnv(source, extraEnv) {
var env = extraEnv ? merge(componentEnv, extraEnv) : componentEnv;
var exprs = parse(source);
if (!_hasDom) return null;
var frag = document.createDocumentFragment();
for (var i = 0; i < exprs.length; i++) {
var node = renderToDom(exprs[i], env, null);
if (node && !node._spread) frag.appendChild(node);
}
return frag;
}
function getRenderEnv(extraEnv) {
return extraEnv ? merge(componentEnv, extraEnv) : componentEnv;
}
function mergeEnvs(base, newEnv) {
return newEnv ? merge(componentEnv, base, newEnv) : merge(componentEnv, base);
}
function sxLoadComponents(text) {
try {
var exprs = parse(text);
for (var i = 0; i < exprs.length; i++) trampoline(evalExpr(exprs[i], componentEnv));
} catch (err) {
logParseError("loadComponents", text, err);
throw err;
}
}
function setDocumentTitle(s) {
if (_hasDom) document.title = s || "";
}
function removeHeadElement(sel) {
if (!_hasDom) return;
var old = document.head.querySelector(sel);
if (old) old.parentNode.removeChild(old);
}
function querySxScripts(root) {
if (!_hasDom) return [];
var r = (root && root !== NIL) ? root : document;
return Array.prototype.slice.call(
r.querySelectorAll('script[type="text/sx"]'));
}
function queryPageScripts() {
if (!_hasDom) return [];
return Array.prototype.slice.call(
document.querySelectorAll('script[type="text/sx-pages"]'));
}
// --- localStorage ---
function localStorageGet(key) {
try { var v = localStorage.getItem(key); return v === null ? NIL : v; }
catch (e) { return NIL; }
}
function localStorageSet(key, val) {
try { localStorage.setItem(key, val); } catch (e) {}
}
function localStorageRemove(key) {
try { localStorage.removeItem(key); } catch (e) {}
}
// localStorage primitives registered in CEK_FIXUPS_JS for ordering
// --- Cookies ---
function setSxCompCookie(hash) {
if (_hasDom) document.cookie = "sx-comp-hash=" + hash + ";path=/;max-age=31536000;SameSite=Lax";
}
function clearSxCompCookie() {
if (_hasDom) document.cookie = "sx-comp-hash=;path=/;max-age=0;SameSite=Lax";
}
// --- Env helpers ---
function parseEnvAttr(el) {
var attr = el && el.getAttribute ? el.getAttribute("data-sx-env") : null;
if (!attr) return {};
try { return JSON.parse(attr); } catch (e) { return {}; }
}
function storeEnvAttr(el, base, newEnv) {
var merged = merge(base, newEnv);
if (el && el.setAttribute) el.setAttribute("data-sx-env", JSON.stringify(merged));
}
function toKebab(s) { return s.replace(/_/g, "-"); }
// --- Logging ---
function logInfo(msg) {
if (typeof console !== "undefined") console.log("[sx-ref] " + msg);
}
function logWarn(msg) {
if (typeof console !== "undefined") console.warn("[sx-ref] " + msg);
}
function logParseError(label, text, err) {
if (typeof console === "undefined") return;
var msg = err && err.message ? err.message : String(err);
var colMatch = msg.match(/col (\d+)/);
var lineMatch = msg.match(/line (\d+)/);
if (colMatch && text) {
var errLine = lineMatch ? parseInt(lineMatch[1]) : 1;
var errCol = parseInt(colMatch[1]);
var lines = text.split("\n");
var pos = 0;
for (var i = 0; i < errLine - 1 && i < lines.length; i++) pos += lines[i].length + 1;
pos += errCol;
var ws = 80;
var start = Math.max(0, pos - ws);
var end = Math.min(text.length, pos + ws);
console.error("[sx-ref] " + label + ":", msg,
"\n around error (pos ~" + pos + "):",
"\n \u00ab" + text.substring(start, pos) + "\u26d4" + text.substring(pos, end) + "\u00bb");
} else {
console.error("[sx-ref] " + label + ":", msg);
}
}
// =========================================================================
// Async IO: Promise-aware rendering for client-side IO primitives
// =========================================================================
//
// IO primitives (query, current-user, etc.) return Promises on the client.
// asyncRenderToDom walks the component tree; when it encounters an IO
// primitive, it awaits the Promise and continues rendering.
//
// The sync evaluator/renderer is untouched. This is a separate async path
// used only when a page's component tree contains IO references.
var IO_PRIMITIVES = {};
function registerIoPrimitive(name, fn) {
IO_PRIMITIVES[name] = fn;
}
function isPromise(x) {
return x != null && typeof x === "object" && typeof x.then === "function";
}
// Async trampoline: resolves thunks, awaits Promises
function asyncTrampoline(val) {
if (isPromise(val)) return val.then(asyncTrampoline);
if (isThunk(val)) return asyncTrampoline(evalExpr(thunkExpr(val), thunkEnv(val)));
return val;
}
// Async eval: like trampoline(evalExpr(...)) but handles IO primitives
function asyncEval(expr, env) {
// Intercept IO primitive calls at the AST level
if (Array.isArray(expr) && expr.length > 0) {
var head = expr[0];
if (head && head._sym) {
var name = head.name;
if (IO_PRIMITIVES[name]) {
// Evaluate args, then call the IO primitive
return asyncEvalIoCall(name, expr.slice(1), env);
}
}
}
// Non-IO: use sync eval, but result might be a thunk
var result = evalExpr(expr, env);
return asyncTrampoline(result);
}
function asyncEvalIoCall(name, rawArgs, env) {
// Parse keyword args and positional args, evaluating each (may be async)
var kwargs = {};
var args = [];
var promises = [];
var i = 0;
while (i < rawArgs.length) {
var arg = rawArgs[i];
if (arg && arg._kw && (i + 1) < rawArgs.length) {
var kName = arg.name;
var kVal = asyncEval(rawArgs[i + 1], env);
if (isPromise(kVal)) {
(function(k) { promises.push(kVal.then(function(v) { kwargs[k] = v; })); })(kName);
} else {
kwargs[kName] = kVal;
}
i += 2;
} else {
var aVal = asyncEval(arg, env);
if (isPromise(aVal)) {
(function(idx) { promises.push(aVal.then(function(v) { args[idx] = v; })); })(args.length);
args.push(null); // placeholder
} else {
args.push(aVal);
}
i++;
}
}
var ioFn = IO_PRIMITIVES[name];
if (promises.length > 0) {
return Promise.all(promises).then(function() { return ioFn(args, kwargs); });
}
return ioFn(args, kwargs);
}
// Async render-to-dom: returns Promise<Node> or Node
function asyncRenderToDom(expr, env, ns) {
// Literals
if (expr === NIL || expr === null || expr === undefined) return null;
if (expr === true || expr === false) return null;
if (typeof expr === "string") return document.createTextNode(expr);
if (typeof expr === "number") return document.createTextNode(String(expr));
// Symbol -> async eval then render
if (expr && expr._sym) {
var val = asyncEval(expr, env);
if (isPromise(val)) return val.then(function(v) { return asyncRenderToDom(v, env, ns); });
return asyncRenderToDom(val, env, ns);
}
// Keyword
if (expr && expr._kw) return document.createTextNode(expr.name);
// DocumentFragment / DOM nodes pass through
if (expr instanceof DocumentFragment || (expr && expr.nodeType)) return expr;
// Dict -> skip
if (expr && typeof expr === "object" && !Array.isArray(expr)) return null;
// List
if (!Array.isArray(expr) || expr.length === 0) return null;
var head = expr[0];
if (!head) return null;
// Symbol head
if (head._sym) {
var hname = head.name;
// IO primitive
if (IO_PRIMITIVES[hname]) {
var ioResult = asyncEval(expr, env);
if (isPromise(ioResult)) return ioResult.then(function(v) { return asyncRenderToDom(v, env, ns); });
return asyncRenderToDom(ioResult, env, ns);
}
// Fragment
if (hname === "<>") return asyncRenderChildren(expr.slice(1), env, ns);
// raw!
if (hname === "raw!") {
return asyncEvalRaw(expr.slice(1), env);
}
// Special forms that need async handling
if (hname === "if") return asyncRenderIf(expr, env, ns);
if (hname === "when") return asyncRenderWhen(expr, env, ns);
if (hname === "cond") return asyncRenderCond(expr, env, ns);
if (hname === "case") return asyncRenderCase(expr, env, ns);
if (hname === "let" || hname === "let*") return asyncRenderLet(expr, env, ns);
if (hname === "begin" || hname === "do") return asyncRenderChildren(expr.slice(1), env, ns);
if (hname === "map") return asyncRenderMap(expr, env, ns);
if (hname === "map-indexed") return asyncRenderMapIndexed(expr, env, ns);
if (hname === "for-each") return asyncRenderMap(expr, env, ns);
// define/defcomp/defmacro and custom special forms — eval for side effects
if (hname === "define" || hname === "defcomp" || hname === "defmacro" ||
hname === "defstyle" || hname === "defhandler" ||
hname === "deftype" || hname === "defeffect" ||
(typeof _customSpecialForms !== "undefined" && _customSpecialForms[hname])) {
trampoline(evalExpr(expr, env));
return null;
}
// quote
if (hname === "quote") return null;
// lambda/fn
if (hname === "lambda" || hname === "fn") {
trampoline(evalExpr(expr, env));
return null;
}
// and/or — eval and render result
if (hname === "and" || hname === "or" || hname === "->") {
var aoResult = asyncEval(expr, env);
if (isPromise(aoResult)) return aoResult.then(function(v) { return asyncRenderToDom(v, env, ns); });
return asyncRenderToDom(aoResult, env, ns);
}
// set!
if (hname === "set!") {
asyncEval(expr, env);
return null;
}
// Component or Island
if (hname.charAt(0) === "~") {
var comp = env[hname];
if (comp && comp._island) return renderDomIsland(comp, expr.slice(1), env, ns);
if (comp && comp._component) return asyncRenderComponent(comp, expr.slice(1), env, ns);
if (comp && comp._macro) {
var expanded = trampoline(expandMacro(comp, expr.slice(1), env));
return asyncRenderToDom(expanded, env, ns);
}
}
// Macro
if (env[hname] && env[hname]._macro) {
var mac = env[hname];
var expanded = trampoline(expandMacro(mac, expr.slice(1), env));
return asyncRenderToDom(expanded, env, ns);
}
// HTML tag
if (typeof renderDomElement === "function" && contains(HTML_TAGS, hname)) {
return asyncRenderElement(hname, expr.slice(1), env, ns);
}
// html: prefix
if (hname.indexOf("html:") === 0) {
return asyncRenderElement(hname.slice(5), expr.slice(1), env, ns);
}
// Custom element
if (hname.indexOf("-") >= 0 && expr.length > 1 && expr[1] && expr[1]._kw) {
return asyncRenderElement(hname, expr.slice(1), env, ns);
}
// SVG context
if (ns) return asyncRenderElement(hname, expr.slice(1), env, ns);
// Fallback: eval and render
var fResult = asyncEval(expr, env);
if (isPromise(fResult)) return fResult.then(function(v) { return asyncRenderToDom(v, env, ns); });
return asyncRenderToDom(fResult, env, ns);
}
// Non-symbol head: eval call
var cResult = asyncEval(expr, env);
if (isPromise(cResult)) return cResult.then(function(v) { return asyncRenderToDom(v, env, ns); });
return asyncRenderToDom(cResult, env, ns);
}
function asyncRenderChildren(exprs, env, ns) {
var frag = document.createDocumentFragment();
var pending = [];
for (var i = 0; i < exprs.length; i++) {
var result = asyncRenderToDom(exprs[i], env, ns);
if (isPromise(result)) {
// Insert placeholder, replace when resolved
var placeholder = document.createComment("async");
frag.appendChild(placeholder);
(function(ph) {
pending.push(result.then(function(node) {
if (node) ph.parentNode.replaceChild(node, ph);
else ph.parentNode.removeChild(ph);
}));
})(placeholder);
} else if (result && !result._spread) {
frag.appendChild(result);
}
}
if (pending.length > 0) {
return Promise.all(pending).then(function() { return frag; });
}
return frag;
}
function asyncRenderElement(tag, args, env, ns) {
var newNs = tag === "svg" ? SVG_NS : tag === "math" ? MATH_NS : ns;
var el = domCreateElement(tag, newNs);
var pending = [];
var isVoid = contains(VOID_ELEMENTS, tag);
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (arg && arg._kw && (i + 1) < args.length) {
var attrName = arg.name;
var attrVal = asyncEval(args[i + 1], env);
i++;
if (isPromise(attrVal)) {
(function(an, av) {
pending.push(av.then(function(v) {
if (!isNil(v) && v !== false) {
if (contains(BOOLEAN_ATTRS, an)) { if (isSxTruthy(v)) el.setAttribute(an, ""); }
else if (v === true) el.setAttribute(an, "");
else el.setAttribute(an, String(v));
}
}));
})(attrName, attrVal);
} else {
if (!isNil(attrVal) && attrVal !== false) {
if (contains(BOOLEAN_ATTRS, attrName)) {
if (isSxTruthy(attrVal)) el.setAttribute(attrName, "");
} else if (attrVal === true) {
el.setAttribute(attrName, "");
} else {
el.setAttribute(attrName, String(attrVal));
}
}
}
} else if (!isVoid) {
var child = asyncRenderToDom(arg, env, newNs);
if (isPromise(child)) {
var placeholder = document.createComment("async");
el.appendChild(placeholder);
(function(ph) {
pending.push(child.then(function(node) {
if (node) ph.parentNode.replaceChild(node, ph);
else ph.parentNode.removeChild(ph);
}));
})(placeholder);
} else if (child) {
if (child._spread) {
// Spread: merge attrs onto parent element
var sa = child.attrs || {};
for (var sk in sa) {
if (sk === "class") {
var ec = el.getAttribute("class") || "";
el.setAttribute("class", ec ? ec + " " + sa[sk] : sa[sk]);
} else if (sk === "style") {
var es = el.getAttribute("style") || "";
el.setAttribute("style", es ? es + ";" + sa[sk] : sa[sk]);
} else {
el.setAttribute(sk, String(sa[sk]));
}
}
} else {
el.appendChild(child);
}
}
}
}
if (pending.length > 0) return Promise.all(pending).then(function() { return el; });
return el;
}
function asyncRenderComponent(comp, args, env, ns) {
var kwargs = {};
var children = [];
var pending = [];
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (arg && arg._kw && (i + 1) < args.length) {
var kName = arg.name;
var kVal = asyncEval(args[i + 1], env);
if (isPromise(kVal)) {
(function(k) { pending.push(kVal.then(function(v) { kwargs[k] = v; })); })(kName);
} else {
kwargs[kName] = kVal;
}
i++;
} else {
children.push(arg);
}
}
function doRender() {
var local = Object.create(componentClosure(comp));
for (var k in env) if (env.hasOwnProperty(k)) local[k] = env[k];
var params = componentParams(comp);
for (var j = 0; j < params.length; j++) {
local[params[j]] = params[j] in kwargs ? kwargs[params[j]] : NIL;
}
if (componentHasChildren(comp)) {
var childResult = asyncRenderChildren(children, env, ns);
if (isPromise(childResult)) {
return childResult.then(function(childFrag) {
local["children"] = childFrag;
return asyncRenderToDom(componentBody(comp), local, ns);
});
}
local["children"] = childResult;
}
return asyncRenderToDom(componentBody(comp), local, ns);
}
if (pending.length > 0) return Promise.all(pending).then(doRender);
return doRender();
}
function asyncRenderIf(expr, env, ns) {
var cond = asyncEval(expr[1], env);
if (isPromise(cond)) {
return cond.then(function(v) {
return isSxTruthy(v)
? asyncRenderToDom(expr[2], env, ns)
: (expr.length > 3 ? asyncRenderToDom(expr[3], env, ns) : null);
});
}
return isSxTruthy(cond)
? asyncRenderToDom(expr[2], env, ns)
: (expr.length > 3 ? asyncRenderToDom(expr[3], env, ns) : null);
}
function asyncRenderWhen(expr, env, ns) {
var cond = asyncEval(expr[1], env);
if (isPromise(cond)) {
return cond.then(function(v) {
return isSxTruthy(v) ? asyncRenderChildren(expr.slice(2), env, ns) : null;
});
}
return isSxTruthy(cond) ? asyncRenderChildren(expr.slice(2), env, ns) : null;
}
function asyncRenderCond(expr, env, ns) {
var clauses = expr.slice(1);
function step(idx) {
if (idx >= clauses.length) return null;
var clause = clauses[idx];
if (!Array.isArray(clause) || clause.length < 2) return step(idx + 1);
var test = clause[0];
if ((test && test._sym && (test.name === "else" || test.name === ":else")) ||
(test && test._kw && test.name === "else")) {
return asyncRenderToDom(clause[1], env, ns);
}
var v = asyncEval(test, env);
if (isPromise(v)) return v.then(function(r) { return isSxTruthy(r) ? asyncRenderToDom(clause[1], env, ns) : step(idx + 1); });
return isSxTruthy(v) ? asyncRenderToDom(clause[1], env, ns) : step(idx + 1);
}
return step(0);
}
function asyncRenderCase(expr, env, ns) {
var matchVal = asyncEval(expr[1], env);
function doCase(mv) {
var clauses = expr.slice(2);
for (var i = 0; i < clauses.length - 1; i += 2) {
var test = clauses[i];
if ((test && test._kw && test.name === "else") ||
(test && test._sym && (test.name === "else" || test.name === ":else"))) {
return asyncRenderToDom(clauses[i + 1], env, ns);
}
var tv = trampoline(evalExpr(test, env));
if (mv === tv || (typeof mv === "string" && typeof tv === "string" && mv === tv)) {
return asyncRenderToDom(clauses[i + 1], env, ns);
}
}
return null;
}
if (isPromise(matchVal)) return matchVal.then(doCase);
return doCase(matchVal);
}
function asyncRenderLet(expr, env, ns) {
var bindings = expr[1];
var local = Object.create(env);
for (var k in env) if (env.hasOwnProperty(k)) local[k] = env[k];
function bindStep(idx) {
if (!Array.isArray(bindings)) return asyncRenderChildren(expr.slice(2), local, ns);
// Nested pairs: ((a 1) (b 2))
if (bindings.length > 0 && Array.isArray(bindings[0])) {
if (idx >= bindings.length) return asyncRenderChildren(expr.slice(2), local, ns);
var b = bindings[idx];
var vname = b[0]._sym ? b[0].name : String(b[0]);
var val = asyncEval(b[1], local);
if (isPromise(val)) return val.then(function(v) { local[vname] = v; return bindStep(idx + 1); });
local[vname] = val;
return bindStep(idx + 1);
}
// Flat pairs: (a 1 b 2)
if (idx >= bindings.length) return asyncRenderChildren(expr.slice(2), local, ns);
var vn = bindings[idx]._sym ? bindings[idx].name : String(bindings[idx]);
var vv = asyncEval(bindings[idx + 1], local);
if (isPromise(vv)) return vv.then(function(v) { local[vn] = v; return bindStep(idx + 2); });
local[vn] = vv;
return bindStep(idx + 2);
}
return bindStep(0);
}
function asyncRenderMap(expr, env, ns) {
var fn = asyncEval(expr[1], env);
var coll = asyncEval(expr[2], env);
function doMap(f, c) {
if (!Array.isArray(c)) return null;
var frag = document.createDocumentFragment();
var pending = [];
for (var i = 0; i < c.length; i++) {
var item = c[i];
var result;
if (f && f._lambda) {
var lenv = Object.create(f.closure || env);
for (var k in env) if (env.hasOwnProperty(k)) lenv[k] = env[k];
lenv[f.params[0]] = item;
result = asyncRenderToDom(f.body, lenv, null);
} else if (typeof f === "function") {
var r = f(item);
result = isPromise(r) ? r.then(function(v) { return asyncRenderToDom(v, env, null); }) : asyncRenderToDom(r, env, null);
} else {
result = asyncRenderToDom(item, env, null);
}
if (isPromise(result)) {
var ph = document.createComment("async");
frag.appendChild(ph);
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
} else if (result && !result._spread) {
frag.appendChild(result);
}
}
if (pending.length) return Promise.all(pending).then(function() { return frag; });
return frag;
}
if (isPromise(fn) || isPromise(coll)) {
return Promise.all([isPromise(fn) ? fn : Promise.resolve(fn), isPromise(coll) ? coll : Promise.resolve(coll)])
.then(function(r) { return doMap(r[0], r[1]); });
}
return doMap(fn, coll);
}
function asyncRenderMapIndexed(expr, env, ns) {
var fn = asyncEval(expr[1], env);
var coll = asyncEval(expr[2], env);
function doMap(f, c) {
if (!Array.isArray(c)) return null;
var frag = document.createDocumentFragment();
var pending = [];
for (var i = 0; i < c.length; i++) {
var item = c[i];
var result;
if (f && f._lambda) {
var lenv = Object.create(f.closure || env);
for (var k in env) if (env.hasOwnProperty(k)) lenv[k] = env[k];
lenv[f.params[0]] = i;
lenv[f.params[1]] = item;
result = asyncRenderToDom(f.body, lenv, null);
} else if (typeof f === "function") {
var r = f(i, item);
result = isPromise(r) ? r.then(function(v) { return asyncRenderToDom(v, env, null); }) : asyncRenderToDom(r, env, null);
} else {
result = asyncRenderToDom(item, env, null);
}
if (isPromise(result)) {
var ph = document.createComment("async");
frag.appendChild(ph);
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
} else if (result && !result._spread) {
frag.appendChild(result);
}
}
if (pending.length) return Promise.all(pending).then(function() { return frag; });
return frag;
}
if (isPromise(fn) || isPromise(coll)) {
return Promise.all([isPromise(fn) ? fn : Promise.resolve(fn), isPromise(coll) ? coll : Promise.resolve(coll)])
.then(function(r) { return doMap(r[0], r[1]); });
}
return doMap(fn, coll);
}
function asyncEvalRaw(args, env) {
var parts = [];
var pending = [];
for (var i = 0; i < args.length; i++) {
var val = asyncEval(args[i], env);
if (isPromise(val)) {
(function(idx) {
pending.push(val.then(function(v) { parts[idx] = v; }));
})(parts.length);
parts.push(null);
} else {
parts.push(val);
}
}
function assemble() {
var html = "";
for (var j = 0; j < parts.length; j++) {
var p = parts[j];
if (p && p._rawHtml) html += p.html;
else if (typeof p === "string") html += p;
else if (p != null && !isNil(p)) html += String(p);
}
var el = document.createElement("span");
el.innerHTML = html;
var frag = document.createDocumentFragment();
while (el.firstChild) frag.appendChild(el.firstChild);
return frag;
}
if (pending.length) return Promise.all(pending).then(assemble);
return assemble();
}
// Async version of sxRenderWithEnv — returns Promise<DocumentFragment>
function asyncSxRenderWithEnv(source, extraEnv) {
var env = extraEnv ? merge(componentEnv, extraEnv) : componentEnv;
var exprs = parse(source);
if (!_hasDom) return Promise.resolve(null);
return asyncRenderChildren(exprs, env, null);
}
// IO proxy cache: key → { value, expires }
var _ioCache = {};
var IO_CACHE_TTL = 300000; // 5 minutes
// Register a server-proxied IO primitive: fetches from /sx/io/<name>
// Uses GET for short args, POST for long payloads (URL length safety).
// Results are cached client-side by (name + args) with a TTL.
function registerProxiedIo(name) {
registerIoPrimitive(name, function(args, kwargs) {
// Cache key: name + serialized args
var cacheKey = name;
for (var ci = 0; ci < args.length; ci++) cacheKey += "" + String(args[ci]);
for (var ck in kwargs) {
if (kwargs.hasOwnProperty(ck)) cacheKey += "" + ck + "=" + String(kwargs[ck]);
}
var cached = _ioCache[cacheKey];
if (cached && cached.expires > Date.now()) return cached.value;
var url = "/sx/io/" + encodeURIComponent(name);
var qs = [];
for (var i = 0; i < args.length; i++) {
qs.push("_arg" + i + "=" + encodeURIComponent(String(args[i])));
}
for (var k in kwargs) {
if (kwargs.hasOwnProperty(k)) {
qs.push(encodeURIComponent(k) + "=" + encodeURIComponent(String(kwargs[k])));
}
}
var queryStr = qs.join("&");
var fetchOpts;
if (queryStr.length > 1500) {
// POST with JSON body for long payloads
var sArgs = [];
for (var j = 0; j < args.length; j++) sArgs.push(String(args[j]));
var sKwargs = {};
for (var kk in kwargs) {
if (kwargs.hasOwnProperty(kk)) sKwargs[kk] = String(kwargs[kk]);
}
var postHeaders = { "SX-Request": "true", "Content-Type": "application/json" };
var csrf = csrfToken();
if (csrf && csrf !== NIL) postHeaders["X-CSRFToken"] = csrf;
fetchOpts = {
method: "POST",
headers: postHeaders,
body: JSON.stringify({ args: sArgs, kwargs: sKwargs })
};
} else {
if (queryStr) url += "?" + queryStr;
fetchOpts = { headers: { "SX-Request": "true" } };
}
var result = fetch(url, fetchOpts)
.then(function(resp) {
if (!resp.ok) {
logWarn("sx:io " + name + " failed " + resp.status);
return NIL;
}
return resp.text();
})
.then(function(text) {
if (!text || text === "nil") return NIL;
try {
var exprs = parse(text);
var val = exprs.length === 1 ? exprs[0] : exprs;
_ioCache[cacheKey] = { value: val, expires: Date.now() + IO_CACHE_TTL };
return val;
} catch (e) {
logWarn("sx:io " + name + " parse error: " + (e && e.message ? e.message : e));
return NIL;
}
})
.catch(function(e) {
logWarn("sx:io " + name + " network error: " + (e && e.message ? e.message : e));
return NIL;
});
// Cache the in-flight promise too (dedup concurrent calls for same args)
_ioCache[cacheKey] = { value: result, expires: Date.now() + IO_CACHE_TTL };
return result;
});
}
// 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(", "));
}
}
// Parser — compiled from parser.sx (see PLATFORM_PARSER_JS for ident char classes)
var parse = sxParse;
// =========================================================================
// Public API
// =========================================================================
var componentEnv = {};
function loadComponents(source) {
var exprs = parse(source);
for (var i = 0; i < exprs.length; i++) {
trampoline(evalExpr(exprs[i], componentEnv));
}
}
function render(source) {
if (!_hasDom) {
var exprs = parse(source);
var parts = [];
for (var i = 0; i < exprs.length; i++) parts.push(renderToHtml(exprs[i], merge(componentEnv)));
return parts.join("");
}
var exprs = parse(source);
var frag = document.createDocumentFragment();
for (var i = 0; i < exprs.length; i++) { var _r = renderToDom(exprs[i], merge(componentEnv), null); if (_r && !_r._spread) frag.appendChild(_r); }
return frag;
}
function renderToString(source) {
var exprs = parse(source);
var parts = [];
for (var i = 0; i < exprs.length; i++) parts.push(renderToHtml(exprs[i], merge(componentEnv)));
return parts.join("");
}
var Sx = {
VERSION: "ref-2.0",
parse: parse,
parseAll: parse,
eval: function(expr, env) { return trampoline(evalExpr(expr, env || merge(componentEnv))); },
loadComponents: loadComponents,
render: render,
renderToString: renderToString,
serialize: serialize,
NIL: NIL,
Symbol: Symbol,
Keyword: Keyword,
isTruthy: isSxTruthy,
isNil: isNil,
componentEnv: componentEnv,
setRenderActive: function(val) { setRenderActiveB(val); },
renderToHtml: function(expr, env) { return renderToHtml(expr, env || merge(componentEnv)); },
renderToSx: function(expr, env) { return renderToSx(expr, env || merge(componentEnv)); },
renderToDom: _hasDom ? function(expr, env, ns) { return renderToDom(expr, env || merge(componentEnv), ns || null); } : null,
parseTriggerSpec: typeof parseTriggerSpec === "function" ? parseTriggerSpec : null,
parseTime: typeof parseTime === "function" ? parseTime : null,
defaultTrigger: typeof defaultTrigger === "function" ? defaultTrigger : null,
parseSwapSpec: typeof parseSwapSpec === "function" ? parseSwapSpec : null,
parseRetrySpec: typeof parseRetrySpec === "function" ? parseRetrySpec : null,
nextRetryMs: typeof nextRetryMs === "function" ? nextRetryMs : null,
filterParams: typeof filterParams === "function" ? filterParams : null,
morphNode: typeof morphNode === "function" ? morphNode : null,
morphChildren: typeof morphChildren === "function" ? morphChildren : null,
swapDomNodes: typeof swapDomNodes === "function" ? swapDomNodes : null,
process: typeof processElements === "function" ? processElements : null,
executeRequest: typeof executeRequest === "function" ? executeRequest : null,
postSwap: typeof postSwap === "function" ? postSwap : null,
processScripts: typeof processSxScripts === "function" ? processSxScripts : null,
mount: typeof sxMount === "function" ? sxMount : null,
hydrate: typeof sxHydrateElements === "function" ? sxHydrateElements : null,
update: typeof sxUpdateElement === "function" ? sxUpdateElement : null,
renderComponent: typeof sxRenderComponent === "function" ? sxRenderComponent : null,
getEnv: function() { return componentEnv; },
resolveSuspense: typeof resolveSuspense === "function" ? resolveSuspense : null,
hydrateIslands: typeof sxHydrateIslands === "function" ? sxHydrateIslands : null,
disposeIsland: typeof disposeIsland === "function" ? disposeIsland : null,
init: typeof bootInit === "function" ? bootInit : null,
scanRefs: scanRefs,
scanComponentsFromSource: scanComponentsFromSource,
transitiveDeps: transitiveDeps,
computeAllDeps: computeAllDeps,
componentsNeeded: componentsNeeded,
pageComponentBundle: pageComponentBundle,
pageCssClasses: pageCssClasses,
scanIoRefs: scanIoRefs,
transitiveIoRefs: transitiveIoRefs,
computeAllIoRefs: computeAllIoRefs,
componentPure_p: componentPure_p,
categorizeSpecialForms: categorizeSpecialForms,
buildReferenceData: buildReferenceData,
buildAttrDetail: buildAttrDetail,
buildHeaderDetail: buildHeaderDetail,
buildEventDetail: buildEventDetail,
buildComponentSource: buildComponentSource,
buildBundleAnalysis: buildBundleAnalysis,
buildRoutingAnalysis: buildRoutingAnalysis,
buildAffinityAnalysis: buildAffinityAnalysis,
splitPathSegments: splitPathSegments,
parseRoutePattern: parseRoutePattern,
matchRoute: matchRoute,
findMatchingRoute: findMatchingRoute,
urlToExpr: urlToExpr,
autoQuoteUnknowns: autoQuoteUnknowns,
prepareUrlExpr: prepareUrlExpr,
registerIo: typeof registerIoPrimitive === "function" ? registerIoPrimitive : null,
registerIoDeps: typeof registerIoDeps === "function" ? registerIoDeps : null,
asyncRender: typeof asyncSxRenderWithEnv === "function" ? asyncSxRenderWithEnv : null,
asyncRenderToDom: typeof asyncRenderToDom === "function" ? asyncRenderToDom : null,
signal: signal,
deref: deref,
reset: reset_b,
swap: swap_b,
computed: computed,
effect: effect,
batch: batch,
isSignal: isSignal,
makeSignal: makeSignal,
defStore: defStore,
useStore: useStore,
clearStores: clearStores,
emitEvent: emitEvent,
onEvent: onEvent,
bridgeEvent: bridgeEvent,
makeSpread: makeSpread,
isSpread: isSpread,
spreadAttrs: spreadAttrs,
collect: sxCollect,
collected: sxCollected,
clearCollected: sxClearCollected,
scopePush: scopePush,
scopePop: scopePop,
providePush: providePush,
providePop: providePop,
context: sxContext,
emit: sxEmit,
emitted: sxEmitted,
cekRun: cekRun,
makeCekState: makeCekState,
makeCekValue: makeCekValue,
cekStep: cekStep,
cekTerminal: cekTerminal_p,
cekValue: cekValue,
makeReactiveResetFrame: makeReactiveResetFrame,
evalExpr: evalExpr,
_version: "ref-2.0 (boot+browser-lib+dom+dom-lib+engine+html+orchestration+parser+sx, bootstrap-compiled)"
};
// --- Popstate listener ---
if (typeof window !== "undefined") {
window.addEventListener("popstate", function(e) {
handlePopstate(e && e.state ? e.state.scrollY || 0 : 0);
});
}
// --- Auto-init ---
if (typeof document !== "undefined") {
var _sxInit = function() {
bootInit();
// Process any suspense resolutions that arrived before init
if (global.__sxPending) {
for (var pi = 0; pi < global.__sxPending.length; pi++) {
resolveSuspense(global.__sxPending[pi].id, global.__sxPending[pi].sx);
}
global.__sxPending = null;
}
// Set up direct resolution for future chunks
global.__sxResolve = function(id, sx) { resolveSuspense(id, sx); };
// Register service worker for offline data caching
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sx-sw.js", { scope: "/" }).then(function(reg) {
logInfo("sx:sw registered (scope: " + reg.scope + ")");
}).catch(function(err) {
logWarn("sx:sw registration failed: " + (err && err.message ? err.message : err));
});
}
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", _sxInit);
} else {
_sxInit();
}
}
if (typeof module !== "undefined" && module.exports) module.exports = Sx;
else global.Sx = Sx;
})(typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : this);