@jxsuite/runtime 6.2.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime.js +1046 -116
- package/dist/runtime.js.map +10 -7
- package/package.json +3 -2
- package/src/body-eraser.ts +265 -0
- package/src/css.ts +2 -1
- package/src/expression.ts +140 -7
- package/src/runtime.ts +1283 -160
- package/src/types.ts +58 -3
package/dist/runtime.js
CHANGED
|
@@ -1491,6 +1491,9 @@ function isTemplateString(value) {
|
|
|
1491
1491
|
function bodyReturnsValue(body) {
|
|
1492
1492
|
return /\breturn\b[^\S\n]*(?![;}\s]|$)/.test(maskCode(body));
|
|
1493
1493
|
}
|
|
1494
|
+
function isFunctionEntry(value) {
|
|
1495
|
+
return value.$prototype === "Function" || isString2(value.role) && value.role !== "field";
|
|
1496
|
+
}
|
|
1494
1497
|
function maskCode(body) {
|
|
1495
1498
|
if (!/[/'"`]/u.test(body)) {
|
|
1496
1499
|
return body;
|
|
@@ -1508,7 +1511,91 @@ function maskCode(body) {
|
|
|
1508
1511
|
}
|
|
1509
1512
|
var masked = new Map;
|
|
1510
1513
|
var MASKED_LIMIT = 2048;
|
|
1511
|
-
function
|
|
1514
|
+
function templateExpressions(template) {
|
|
1515
|
+
if (!template.includes("${")) {
|
|
1516
|
+
return NO_EXPRESSIONS;
|
|
1517
|
+
}
|
|
1518
|
+
const known = scanned.get(template);
|
|
1519
|
+
if (known !== undefined) {
|
|
1520
|
+
return known;
|
|
1521
|
+
}
|
|
1522
|
+
const found = [];
|
|
1523
|
+
let from = 0;
|
|
1524
|
+
while (from < template.length) {
|
|
1525
|
+
const spans = [];
|
|
1526
|
+
scanCode(template.slice(from), spans);
|
|
1527
|
+
let unclosed = -1;
|
|
1528
|
+
for (let i = 0;i < spans.length; i += 2) {
|
|
1529
|
+
const start = from + (spans[i] ?? 0);
|
|
1530
|
+
const end = spans[i + 1] ?? -1;
|
|
1531
|
+
if (end === -1) {
|
|
1532
|
+
unclosed = start;
|
|
1533
|
+
break;
|
|
1534
|
+
}
|
|
1535
|
+
found.push(expressionAt(template, start, from + end));
|
|
1536
|
+
}
|
|
1537
|
+
if (unclosed === -1) {
|
|
1538
|
+
break;
|
|
1539
|
+
}
|
|
1540
|
+
const end = closeByBraceDepth(template, unclosed);
|
|
1541
|
+
if (end === -1) {
|
|
1542
|
+
from = unclosed + 2;
|
|
1543
|
+
} else {
|
|
1544
|
+
found.push(expressionAt(template, unclosed, end));
|
|
1545
|
+
from = end;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
if (scanned.size >= MASKED_LIMIT) {
|
|
1549
|
+
scanned.clear();
|
|
1550
|
+
}
|
|
1551
|
+
scanned.set(template, found);
|
|
1552
|
+
return found;
|
|
1553
|
+
}
|
|
1554
|
+
var NO_EXPRESSIONS = [];
|
|
1555
|
+
var scanned = new Map;
|
|
1556
|
+
function expressionAt(template, start, end) {
|
|
1557
|
+
return { end, expr: template.slice(start + 2, end - 1), start };
|
|
1558
|
+
}
|
|
1559
|
+
function closeByBraceDepth(template, start) {
|
|
1560
|
+
let depth = 0;
|
|
1561
|
+
for (let at = start + 1;at < template.length; at += 1) {
|
|
1562
|
+
const char = template.charAt(at);
|
|
1563
|
+
if (char === "{") {
|
|
1564
|
+
depth += 1;
|
|
1565
|
+
} else if (char === "}") {
|
|
1566
|
+
depth -= 1;
|
|
1567
|
+
if (depth === 0) {
|
|
1568
|
+
return at + 1;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
return -1;
|
|
1573
|
+
}
|
|
1574
|
+
var BEFORE_OPERAND = new Set("(,=:[!&|?{;+-*%<>~^");
|
|
1575
|
+
function endsUpdateOperator(body, before, at) {
|
|
1576
|
+
return (before === "+" || before === "-") && body.charAt(at - 1) === before;
|
|
1577
|
+
}
|
|
1578
|
+
function regexLiteralEnd(body, at) {
|
|
1579
|
+
let inClass = false;
|
|
1580
|
+
for (let i = at + 1;i < body.length; i += 1) {
|
|
1581
|
+
const char = body.charAt(i);
|
|
1582
|
+
if (char === `
|
|
1583
|
+
`) {
|
|
1584
|
+
return -1;
|
|
1585
|
+
}
|
|
1586
|
+
if (char === "\\") {
|
|
1587
|
+
i += 1;
|
|
1588
|
+
} else if (char === "[") {
|
|
1589
|
+
inClass = true;
|
|
1590
|
+
} else if (char === "]") {
|
|
1591
|
+
inClass = false;
|
|
1592
|
+
} else if (char === "/" && !inClass) {
|
|
1593
|
+
return i + 1;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
return -1;
|
|
1597
|
+
}
|
|
1598
|
+
function scanCode(body, spans) {
|
|
1512
1599
|
const out = body.split("");
|
|
1513
1600
|
const blank = (at) => {
|
|
1514
1601
|
if (out[at] !== undefined && out[at] !== `
|
|
@@ -1517,7 +1604,9 @@ function scanCode(body) {
|
|
|
1517
1604
|
}
|
|
1518
1605
|
};
|
|
1519
1606
|
const substitutions = [];
|
|
1520
|
-
let inTemplate =
|
|
1607
|
+
let inTemplate = spans !== undefined;
|
|
1608
|
+
let before = "";
|
|
1609
|
+
let beforeAt = -1;
|
|
1521
1610
|
let at = 0;
|
|
1522
1611
|
while (at < body.length) {
|
|
1523
1612
|
const char = body.charAt(at);
|
|
@@ -1526,12 +1615,17 @@ function scanCode(body) {
|
|
|
1526
1615
|
blank(at);
|
|
1527
1616
|
blank(at + 1);
|
|
1528
1617
|
at += 2;
|
|
1529
|
-
} else if (char === "`") {
|
|
1618
|
+
} else if (char === "`" && !(spans && substitutions.length === 0)) {
|
|
1530
1619
|
inTemplate = false;
|
|
1620
|
+
before = char;
|
|
1531
1621
|
at += 1;
|
|
1532
1622
|
} else if (char === "$" && body.charAt(at + 1) === "{") {
|
|
1623
|
+
if (substitutions.length === 0) {
|
|
1624
|
+
spans?.push(at, -1);
|
|
1625
|
+
}
|
|
1533
1626
|
substitutions.push(0);
|
|
1534
1627
|
inTemplate = false;
|
|
1628
|
+
before = "{";
|
|
1535
1629
|
at += 2;
|
|
1536
1630
|
} else {
|
|
1537
1631
|
blank(at);
|
|
@@ -1560,10 +1654,18 @@ function scanCode(body) {
|
|
|
1560
1654
|
blank(at);
|
|
1561
1655
|
at += 1;
|
|
1562
1656
|
}
|
|
1657
|
+
before = char;
|
|
1563
1658
|
at += 1;
|
|
1564
1659
|
} else if (char === "`") {
|
|
1565
1660
|
inTemplate = true;
|
|
1566
1661
|
at += 1;
|
|
1662
|
+
} else if (spans && char === "/" && BEFORE_OPERAND.has(before) && !endsUpdateOperator(body, before, beforeAt) && regexLiteralEnd(body, at) > 0) {
|
|
1663
|
+
const stop = regexLiteralEnd(body, at);
|
|
1664
|
+
for (at += 1;at < stop - 1; at += 1) {
|
|
1665
|
+
blank(at);
|
|
1666
|
+
}
|
|
1667
|
+
before = "/";
|
|
1668
|
+
at = stop;
|
|
1567
1669
|
} else {
|
|
1568
1670
|
const open = substitutions.length - 1;
|
|
1569
1671
|
if (open >= 0 && char === "{") {
|
|
@@ -1572,10 +1674,17 @@ function scanCode(body) {
|
|
|
1572
1674
|
if (substitutions[open] === 0) {
|
|
1573
1675
|
substitutions.pop();
|
|
1574
1676
|
inTemplate = true;
|
|
1677
|
+
if (spans && substitutions.length === 0) {
|
|
1678
|
+
spans[spans.length - 1] = at + 1;
|
|
1679
|
+
}
|
|
1575
1680
|
} else {
|
|
1576
1681
|
substitutions[open] = (substitutions[open] ?? 1) - 1;
|
|
1577
1682
|
}
|
|
1578
1683
|
}
|
|
1684
|
+
if (char.trim() !== "") {
|
|
1685
|
+
before = char;
|
|
1686
|
+
beforeAt = at;
|
|
1687
|
+
}
|
|
1579
1688
|
at += 1;
|
|
1580
1689
|
}
|
|
1581
1690
|
}
|
|
@@ -2222,12 +2331,77 @@ function withPageLocale(path, args, state) {
|
|
|
2222
2331
|
filled[index] = locale;
|
|
2223
2332
|
return filled;
|
|
2224
2333
|
}
|
|
2334
|
+
function windowRoot() {
|
|
2335
|
+
const root = globalThis.window;
|
|
2336
|
+
return root ?? globalThis;
|
|
2337
|
+
}
|
|
2225
2338
|
function isBlessedGlobal(ref) {
|
|
2226
2339
|
return ref.startsWith("window#/") && BLESSED_GLOBALS.has(ref.slice("window#/".length));
|
|
2227
2340
|
}
|
|
2228
2341
|
function isMutating(op) {
|
|
2229
2342
|
return MUTATING_OPS.has(op);
|
|
2230
2343
|
}
|
|
2344
|
+
function operandMutates(operand) {
|
|
2345
|
+
if (Array.isArray(operand)) {
|
|
2346
|
+
return operand.some((item) => operandMutates(item));
|
|
2347
|
+
}
|
|
2348
|
+
if (operand === undefined || !isNodeOperand(operand)) {
|
|
2349
|
+
return false;
|
|
2350
|
+
}
|
|
2351
|
+
return isMutating(operand.operator) || [operand.target, operand.value, operand.initial, operand.default].some((part) => operandMutates(part)) || Object.values(operand.cases ?? {}).some((part) => operandMutates(part));
|
|
2352
|
+
}
|
|
2353
|
+
function isPureNamedFormula(def) {
|
|
2354
|
+
return isNamedFormulaDef(def) && !operandMutates(def.$expression);
|
|
2355
|
+
}
|
|
2356
|
+
var OUTSIDE_SCOPE_REF = /^(?:\$args\/|\$reduce\/|\$map\/|window#\/|document#\/|event#\/)/;
|
|
2357
|
+
function collectScopeReads(operand, into) {
|
|
2358
|
+
if (Array.isArray(operand)) {
|
|
2359
|
+
for (const item of operand) {
|
|
2360
|
+
collectScopeReads(item, into);
|
|
2361
|
+
}
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
if (operand === undefined || !isNonNullObject(operand)) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
if (isRefOperand(operand)) {
|
|
2368
|
+
if (!OUTSIDE_SCOPE_REF.test(operand.$ref)) {
|
|
2369
|
+
const path = operand.$ref.replace(/^(?:#\/state\/|parent#\/)/, "");
|
|
2370
|
+
into.add(refSegments(path)[0] ?? "");
|
|
2371
|
+
}
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
if (isNodeOperand(operand)) {
|
|
2375
|
+
const parts = [operand.target, operand.value, operand.initial, operand.default];
|
|
2376
|
+
for (const part of [...parts, ...Object.values(operand.cases ?? {})]) {
|
|
2377
|
+
collectScopeReads(part, into);
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
function formulaScopeReads(def) {
|
|
2382
|
+
const reads = new Set;
|
|
2383
|
+
collectScopeReads(def.$expression, reads);
|
|
2384
|
+
return [...reads];
|
|
2385
|
+
}
|
|
2386
|
+
function inheritableFormulas(projectState) {
|
|
2387
|
+
const candidates = new Map;
|
|
2388
|
+
for (const [key, def] of Object.entries(projectState ?? {})) {
|
|
2389
|
+
if (!key.startsWith("$") && isPureNamedFormula(def)) {
|
|
2390
|
+
candidates.set(key, def);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
let settled = false;
|
|
2394
|
+
while (!settled) {
|
|
2395
|
+
settled = true;
|
|
2396
|
+
for (const [key, def] of candidates) {
|
|
2397
|
+
if (formulaScopeReads(def).some((read) => !candidates.has(read))) {
|
|
2398
|
+
candidates.delete(key);
|
|
2399
|
+
settled = false;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
return Object.fromEntries(candidates);
|
|
2404
|
+
}
|
|
2231
2405
|
var MAX_CALL_DEPTH = 64;
|
|
2232
2406
|
var MAX_REPORT_DEPTH = 64;
|
|
2233
2407
|
function subTrace(trace, seg) {
|
|
@@ -2321,7 +2495,7 @@ function resolveExprRef(ref, state, event, iterCtx) {
|
|
|
2321
2495
|
return readPath(state, ref.slice("parent#/".length));
|
|
2322
2496
|
}
|
|
2323
2497
|
if (ref.startsWith("window#/")) {
|
|
2324
|
-
return readPath(
|
|
2498
|
+
return readPath(windowRoot(), ref.slice("window#/".length));
|
|
2325
2499
|
}
|
|
2326
2500
|
if (ref.startsWith("document#/")) {
|
|
2327
2501
|
return readPath(globalThis.document, ref.slice("document#/".length));
|
|
@@ -2437,9 +2611,10 @@ function evaluateNode(node, state, event, iterCtx, trace) {
|
|
|
2437
2611
|
if (helper) {
|
|
2438
2612
|
return helper(...withPageLocale(globalPath, argValues, state));
|
|
2439
2613
|
}
|
|
2440
|
-
const
|
|
2614
|
+
const root = windowRoot();
|
|
2615
|
+
const fn = readPath(root, globalPath);
|
|
2441
2616
|
const lastSlash = globalPath.lastIndexOf("/");
|
|
2442
|
-
const thisArg = lastSlash === -1 ?
|
|
2617
|
+
const thisArg = lastSlash === -1 ? root : readPath(root, globalPath.slice(0, lastSlash));
|
|
2443
2618
|
return fn.apply(thisArg, argValues);
|
|
2444
2619
|
}
|
|
2445
2620
|
const callee = resolveExprRef(calleeRef, state, event, iterCtx);
|
|
@@ -2573,6 +2748,96 @@ function evaluateOperand(operand, state, event, iterCtx) {
|
|
|
2573
2748
|
return resolveOperand(operand, state, event, iterCtx);
|
|
2574
2749
|
}
|
|
2575
2750
|
|
|
2751
|
+
// ../schema/src/function-role.ts
|
|
2752
|
+
var LIFECYCLE_KEYS = new Set(["onMount", "onUnmount", "onAdopted"]);
|
|
2753
|
+
function collectCallableKeys(doc) {
|
|
2754
|
+
const keys = new Set;
|
|
2755
|
+
const seen = new Set;
|
|
2756
|
+
const addStateRef = (ref) => {
|
|
2757
|
+
if (ref.startsWith("#/state/")) {
|
|
2758
|
+
keys.add(ref.slice("#/state/".length).split("/")[0]);
|
|
2759
|
+
}
|
|
2760
|
+
};
|
|
2761
|
+
const visit = (node) => {
|
|
2762
|
+
if (isString2(node)) {
|
|
2763
|
+
for (const call of node.matchAll(/\bstate\.([A-Za-z_$][\w$]*)\s*\(/gu)) {
|
|
2764
|
+
keys.add(call[1]);
|
|
2765
|
+
}
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
if (Array.isArray(node)) {
|
|
2769
|
+
if (!seen.has(node)) {
|
|
2770
|
+
seen.add(node);
|
|
2771
|
+
for (const item of node) {
|
|
2772
|
+
visit(item);
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
return;
|
|
2776
|
+
}
|
|
2777
|
+
if (!isJsonObject(node) || seen.has(node)) {
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
seen.add(node);
|
|
2781
|
+
if (node.operator === "call" && isRef2(node.target)) {
|
|
2782
|
+
addStateRef(node.target.$ref);
|
|
2783
|
+
}
|
|
2784
|
+
for (const [key, value] of Object.entries(node)) {
|
|
2785
|
+
if (key === "$defs") {
|
|
2786
|
+
continue;
|
|
2787
|
+
}
|
|
2788
|
+
if (key.startsWith("on") && isRef2(value)) {
|
|
2789
|
+
addStateRef(value.$ref);
|
|
2790
|
+
}
|
|
2791
|
+
visit(value);
|
|
2792
|
+
}
|
|
2793
|
+
};
|
|
2794
|
+
visit(doc);
|
|
2795
|
+
for (const hook of LIFECYCLE_KEYS) {
|
|
2796
|
+
if (isJsonObject(doc.state) && hook in doc.state) {
|
|
2797
|
+
keys.add(hook);
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
return keys;
|
|
2801
|
+
}
|
|
2802
|
+
function declaresBodyAndSrc(def) {
|
|
2803
|
+
return "body" in def && "$src" in def;
|
|
2804
|
+
}
|
|
2805
|
+
function handlerParamNames(def) {
|
|
2806
|
+
const list = ["state"];
|
|
2807
|
+
for (const name of paramNames(def.parameters ?? def.arguments)) {
|
|
2808
|
+
if (name !== "state") {
|
|
2809
|
+
list.push(name);
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
return list;
|
|
2813
|
+
}
|
|
2814
|
+
function functionEntryRole(key, def, callableKeys) {
|
|
2815
|
+
if (hasStructuredBody(def)) {
|
|
2816
|
+
return "callable";
|
|
2817
|
+
}
|
|
2818
|
+
if (paramNames(def.parameters ?? def.arguments).length > 0) {
|
|
2819
|
+
return "callable";
|
|
2820
|
+
}
|
|
2821
|
+
if (isString2(def.body)) {
|
|
2822
|
+
return bodyReturnsValue(def.body) ? "computed" : "callable";
|
|
2823
|
+
}
|
|
2824
|
+
if (def.$src) {
|
|
2825
|
+
return callableKeys().has(key) ? "callable" : "computed";
|
|
2826
|
+
}
|
|
2827
|
+
return "callable";
|
|
2828
|
+
}
|
|
2829
|
+
function classifyFunctionEntries(doc) {
|
|
2830
|
+
const roles = new Map;
|
|
2831
|
+
let callable = null;
|
|
2832
|
+
const callableKeys = () => callable ??= collectCallableKeys(doc);
|
|
2833
|
+
for (const [key, def] of Object.entries(doc.state ?? {})) {
|
|
2834
|
+
if (isFunctionDef(def)) {
|
|
2835
|
+
roles.set(key, functionEntryRole(key, def, callableKeys));
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
return roles;
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2576
2841
|
// ../schema/src/asset-paths.ts
|
|
2577
2842
|
var URL_TERMINATOR = String.raw`"'\s<>()\\`;
|
|
2578
2843
|
function parseSrcset(value) {
|
|
@@ -2701,6 +2966,205 @@ async function runStatements(statements, state, event, opts = {}) {
|
|
|
2701
2966
|
}
|
|
2702
2967
|
}
|
|
2703
2968
|
|
|
2969
|
+
// src/body-eraser.ts
|
|
2970
|
+
var eraser = null;
|
|
2971
|
+
var moduleLoader = null;
|
|
2972
|
+
var loader = null;
|
|
2973
|
+
var loading = null;
|
|
2974
|
+
var erased = new Map;
|
|
2975
|
+
function setBodyEraser(fn) {
|
|
2976
|
+
eraser = fn;
|
|
2977
|
+
erased.clear();
|
|
2978
|
+
if (!fn) {
|
|
2979
|
+
loading = null;
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
function setModuleLoader(fn) {
|
|
2983
|
+
moduleLoader = fn;
|
|
2984
|
+
if (!fn) {
|
|
2985
|
+
loading = null;
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
function canLoadModules() {
|
|
2989
|
+
return moduleLoader !== null || loader !== null;
|
|
2990
|
+
}
|
|
2991
|
+
function fetchEraser(load) {
|
|
2992
|
+
loading ??= load().then((module) => {
|
|
2993
|
+
if (loader !== load) {
|
|
2994
|
+
return;
|
|
2995
|
+
}
|
|
2996
|
+
if (!eraser) {
|
|
2997
|
+
setBodyEraser(module.eraseBody);
|
|
2998
|
+
}
|
|
2999
|
+
if (!moduleLoader && module.loadModule) {
|
|
3000
|
+
setModuleLoader(module.loadModule);
|
|
3001
|
+
}
|
|
3002
|
+
});
|
|
3003
|
+
return loading;
|
|
3004
|
+
}
|
|
3005
|
+
async function moduleLoaderFor() {
|
|
3006
|
+
if (!moduleLoader && loader) {
|
|
3007
|
+
await fetchEraser(loader);
|
|
3008
|
+
}
|
|
3009
|
+
return moduleLoader;
|
|
3010
|
+
}
|
|
3011
|
+
function setBodyEraserLoader(load) {
|
|
3012
|
+
loader = load;
|
|
3013
|
+
loading = null;
|
|
3014
|
+
}
|
|
3015
|
+
function compiles(text) {
|
|
3016
|
+
for (const source of [text, `return async function () {
|
|
3017
|
+
${text}
|
|
3018
|
+
}`]) {
|
|
3019
|
+
try {
|
|
3020
|
+
Reflect.construct(Function, [source]);
|
|
3021
|
+
return true;
|
|
3022
|
+
} catch {}
|
|
3023
|
+
}
|
|
3024
|
+
return false;
|
|
3025
|
+
}
|
|
3026
|
+
var GENERIC_CALL = /<[^<>]*>\s*[(`]/u;
|
|
3027
|
+
function bodyNeedsEraser(text) {
|
|
3028
|
+
return GENERIC_CALL.test(text) || !compiles(text);
|
|
3029
|
+
}
|
|
3030
|
+
function* bodiesOf(value) {
|
|
3031
|
+
if (Array.isArray(value)) {
|
|
3032
|
+
for (const item of value) {
|
|
3033
|
+
yield* bodiesOf(item);
|
|
3034
|
+
}
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
if (!isJsonObject(value)) {
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
const isFunction = isFunctionEntry(value);
|
|
3041
|
+
for (const [key, child] of Object.entries(value)) {
|
|
3042
|
+
if (isFunction && key === "body") {
|
|
3043
|
+
if (isString2(child)) {
|
|
3044
|
+
yield child;
|
|
3045
|
+
} else if (Array.isArray(child) && child.every((line) => isString2(line))) {
|
|
3046
|
+
yield child.join(`
|
|
3047
|
+
`);
|
|
3048
|
+
} else {
|
|
3049
|
+
yield* bodiesOf(child);
|
|
3050
|
+
}
|
|
3051
|
+
} else if (isFunction && (key === "getter" || key === "setter") && isJsonObject(child)) {
|
|
3052
|
+
if (isString2(child.body)) {
|
|
3053
|
+
yield child.body;
|
|
3054
|
+
}
|
|
3055
|
+
} else {
|
|
3056
|
+
yield* bodiesOf(child);
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
async function prepareBodies(doc) {
|
|
3061
|
+
const load = loader;
|
|
3062
|
+
if (eraser || !load) {
|
|
3063
|
+
return;
|
|
3064
|
+
}
|
|
3065
|
+
const tree = doc;
|
|
3066
|
+
if (!bodiesOf(tree).some((body) => bodyNeedsEraser(body))) {
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
3069
|
+
await fetchEraser(load);
|
|
3070
|
+
}
|
|
3071
|
+
function javaScriptOf(body, where) {
|
|
3072
|
+
if (!eraser) {
|
|
3073
|
+
return body;
|
|
3074
|
+
}
|
|
3075
|
+
let code = erased.get(body);
|
|
3076
|
+
if (code === undefined) {
|
|
3077
|
+
const result = eraser(body);
|
|
3078
|
+
const refused = result.problems.find((problem) => problem.kind === "unsupported");
|
|
3079
|
+
if (refused) {
|
|
3080
|
+
throw new SyntaxError(`Jx: ${where} cannot run: ${refused.message}`);
|
|
3081
|
+
}
|
|
3082
|
+
({ code } = result);
|
|
3083
|
+
erased.set(body, code);
|
|
3084
|
+
}
|
|
3085
|
+
return code;
|
|
3086
|
+
}
|
|
3087
|
+
function compileBody(params, body, where) {
|
|
3088
|
+
const code = javaScriptOf(body, where);
|
|
3089
|
+
try {
|
|
3090
|
+
return new Function(...params, code);
|
|
3091
|
+
} catch (error) {
|
|
3092
|
+
if (!(error instanceof SyntaxError) || eraser) {
|
|
3093
|
+
throw error;
|
|
3094
|
+
}
|
|
3095
|
+
throw new SyntaxError(`Jx: ${where} does not compile as JavaScript (${error.message}). A function body may be ` + `TypeScript: give this page an eraser with setBodyEraser(eraseBody), eraseBody from ` + `@jxsuite/erase/browser.`, { cause: error });
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
|
|
3099
|
+
// ../schema/src/document-scripts.ts
|
|
3100
|
+
var SCRIPT_SPECIFIER_PREFIX = "jx-script:";
|
|
3101
|
+
var CLIENT_SCRIPT_REF = "#client";
|
|
3102
|
+
var SERVER_SCRIPT_REF = "#server";
|
|
3103
|
+
var TYPESCRIPT_PATH = /\.[cm]?ts$/iu;
|
|
3104
|
+
function isTypeScriptPath(pathname) {
|
|
3105
|
+
return TYPESCRIPT_PATH.test(pathname);
|
|
3106
|
+
}
|
|
3107
|
+
function scriptRefSide(src) {
|
|
3108
|
+
if (src === CLIENT_SCRIPT_REF) {
|
|
3109
|
+
return "client";
|
|
3110
|
+
}
|
|
3111
|
+
if (src === SERVER_SCRIPT_REF) {
|
|
3112
|
+
return "server";
|
|
3113
|
+
}
|
|
3114
|
+
return null;
|
|
3115
|
+
}
|
|
3116
|
+
function normalizedPath(path) {
|
|
3117
|
+
return path.replaceAll("\\", "/").replace(/^(?:\.\/)+/, "");
|
|
3118
|
+
}
|
|
3119
|
+
function scriptSpecifier(path, side) {
|
|
3120
|
+
return `${SCRIPT_SPECIFIER_PREFIX}${normalizedPath(path)}#${side}`;
|
|
3121
|
+
}
|
|
3122
|
+
function isScriptSpecifier(src) {
|
|
3123
|
+
return src.startsWith(SCRIPT_SPECIFIER_PREFIX);
|
|
3124
|
+
}
|
|
3125
|
+
function parseScriptSpecifier(src) {
|
|
3126
|
+
if (!isScriptSpecifier(src)) {
|
|
3127
|
+
return null;
|
|
3128
|
+
}
|
|
3129
|
+
const rest = src.slice(SCRIPT_SPECIFIER_PREFIX.length);
|
|
3130
|
+
const hash = rest.lastIndexOf("#");
|
|
3131
|
+
if (hash <= 0) {
|
|
3132
|
+
return null;
|
|
3133
|
+
}
|
|
3134
|
+
const side = rest.slice(hash + 1);
|
|
3135
|
+
if (side !== "client" && side !== "server") {
|
|
3136
|
+
return null;
|
|
3137
|
+
}
|
|
3138
|
+
return { path: rest.slice(0, hash), side };
|
|
3139
|
+
}
|
|
3140
|
+
function qualifiedValue(value, path) {
|
|
3141
|
+
if (Array.isArray(value)) {
|
|
3142
|
+
const items = value.map((item) => qualifiedValue(item, path));
|
|
3143
|
+
return items.some((item, index) => item !== value[index]) ? items : value;
|
|
3144
|
+
}
|
|
3145
|
+
if (!isJsonObject(value)) {
|
|
3146
|
+
return value;
|
|
3147
|
+
}
|
|
3148
|
+
let copy = null;
|
|
3149
|
+
for (const [key, member] of Object.entries(value)) {
|
|
3150
|
+
let next = member;
|
|
3151
|
+
if (key === "$src" && isString2(member)) {
|
|
3152
|
+
const side = scriptRefSide(member);
|
|
3153
|
+
next = side === null ? member : scriptSpecifier(path, side);
|
|
3154
|
+
} else if (key !== "$script") {
|
|
3155
|
+
next = qualifiedValue(member, path);
|
|
3156
|
+
}
|
|
3157
|
+
if (next !== member) {
|
|
3158
|
+
copy ??= { ...value };
|
|
3159
|
+
copy[key] = next;
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
return copy === null ? value : copy;
|
|
3163
|
+
}
|
|
3164
|
+
function qualifyScripts(doc, path) {
|
|
3165
|
+
return qualifiedValue(doc, path);
|
|
3166
|
+
}
|
|
3167
|
+
|
|
2704
3168
|
// src/cookie.ts
|
|
2705
3169
|
var HOST_PREFIX = "__Host-";
|
|
2706
3170
|
var SECURE_PREFIX = "__Secure-";
|
|
@@ -2739,7 +3203,6 @@ function serializeCookie(name, value, options) {
|
|
|
2739
3203
|
}
|
|
2740
3204
|
return parts.join("; ");
|
|
2741
3205
|
}
|
|
2742
|
-
|
|
2743
3206
|
// src/runtime.ts
|
|
2744
3207
|
var SUPPORTED_SCHEMA_VERSION = 1;
|
|
2745
3208
|
var _schemaVersionWarned = false;
|
|
@@ -2783,10 +3246,11 @@ function assertHostScope(scope) {
|
|
|
2783
3246
|
}
|
|
2784
3247
|
}
|
|
2785
3248
|
}
|
|
2786
|
-
async function mount(
|
|
3249
|
+
async function mount(source, target, options = {}) {
|
|
2787
3250
|
const hostScope = options.scope ? hostScopeOf(options.scope) : {};
|
|
2788
3251
|
assertHostScope(hostScope);
|
|
2789
3252
|
const base = options.base ? new URL(options.base, location.href).href : location.href;
|
|
3253
|
+
const doc = inlineDocument(source, base);
|
|
2790
3254
|
const ctx = {
|
|
2791
3255
|
base,
|
|
2792
3256
|
media: options.media ?? doc.$media ?? null,
|
|
@@ -2822,6 +3286,15 @@ async function mount(doc, target, options = {}) {
|
|
|
2822
3286
|
if (options.onNodeMoved) {
|
|
2823
3287
|
renderOptions.onNodeMoved = options.onNodeMoved;
|
|
2824
3288
|
}
|
|
3289
|
+
if (options.rowLimit !== undefined) {
|
|
3290
|
+
renderOptions.rowLimit = options.rowLimit;
|
|
3291
|
+
}
|
|
3292
|
+
if (options.emptyRow) {
|
|
3293
|
+
renderOptions.emptyRow = options.emptyRow;
|
|
3294
|
+
}
|
|
3295
|
+
if (options.onListReconciled) {
|
|
3296
|
+
renderOptions.onListReconciled = options.onListReconciled;
|
|
3297
|
+
}
|
|
2825
3298
|
const { result: root, stop } = runScoped(() => renderNode(doc, scope, renderOptions));
|
|
2826
3299
|
ctx.root = root;
|
|
2827
3300
|
let mounted = false;
|
|
@@ -2863,16 +3336,17 @@ function responseContentType(res) {
|
|
|
2863
3336
|
}
|
|
2864
3337
|
async function resolve(source, ctx) {
|
|
2865
3338
|
if (!isString2(source)) {
|
|
3339
|
+
await prepareBodies(source);
|
|
2866
3340
|
return source;
|
|
2867
3341
|
}
|
|
2868
3342
|
const served = ctx?.resolver?.(source);
|
|
2869
3343
|
if (served) {
|
|
2870
|
-
return served;
|
|
3344
|
+
return withOwnScripts(await served, source);
|
|
2871
3345
|
}
|
|
2872
3346
|
if (_resolveCache.has(source)) {
|
|
2873
3347
|
return _resolveCache.get(source);
|
|
2874
3348
|
}
|
|
2875
|
-
const
|
|
3349
|
+
const fetched = fetch(source).then(async (res) => {
|
|
2876
3350
|
if (!res.ok) {
|
|
2877
3351
|
throw new Error(`Jx: failed to fetch ${source} (${res.status})`);
|
|
2878
3352
|
}
|
|
@@ -2888,6 +3362,11 @@ async function resolve(source, ctx) {
|
|
|
2888
3362
|
}
|
|
2889
3363
|
return await res.json();
|
|
2890
3364
|
});
|
|
3365
|
+
const p = fetched.then(async (read) => {
|
|
3366
|
+
const doc = withOwnScripts(read, source);
|
|
3367
|
+
await prepareBodies(doc);
|
|
3368
|
+
return doc;
|
|
3369
|
+
});
|
|
2891
3370
|
_resolveCache.set(source, p);
|
|
2892
3371
|
return p;
|
|
2893
3372
|
}
|
|
@@ -2917,6 +3396,10 @@ var _autoRequestConfig = { skip: false };
|
|
|
2917
3396
|
function setSkipAutoRequests(v) {
|
|
2918
3397
|
_autoRequestConfig.skip = v;
|
|
2919
3398
|
}
|
|
3399
|
+
var _remoteLookupHandler = null;
|
|
3400
|
+
function setRemoteLookupHandler(handler) {
|
|
3401
|
+
_remoteLookupHandler = handler;
|
|
3402
|
+
}
|
|
2920
3403
|
var _resolveToken = null;
|
|
2921
3404
|
function setResolveToken(token) {
|
|
2922
3405
|
_resolveToken = token || null;
|
|
@@ -2973,8 +3456,20 @@ function setCanvasDelinkCommands(on) {
|
|
|
2973
3456
|
_canvasDelinkCommands = on;
|
|
2974
3457
|
}
|
|
2975
3458
|
var _canvasInsideStampedHost = false;
|
|
3459
|
+
function insideStampedHost(inside, fn) {
|
|
3460
|
+
const was = _canvasInsideStampedHost;
|
|
3461
|
+
_canvasInsideStampedHost = inside;
|
|
3462
|
+
try {
|
|
3463
|
+
return fn();
|
|
3464
|
+
} finally {
|
|
3465
|
+
_canvasInsideStampedHost = was;
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
2976
3468
|
function canvasStamped(el) {
|
|
2977
|
-
return _canvasInsideStampedHost || el
|
|
3469
|
+
return _canvasInsideStampedHost || carriesCanvasStamp(el);
|
|
3470
|
+
}
|
|
3471
|
+
function carriesCanvasStamp(el) {
|
|
3472
|
+
return el.dataset.jxPath !== undefined || el.dataset.jxEchoPath !== undefined;
|
|
2978
3473
|
}
|
|
2979
3474
|
function canvasAttrName(el, key) {
|
|
2980
3475
|
if (_canvasDelinkAnchors && key === "href" && (el.tagName === "A" || el.tagName === "AREA")) {
|
|
@@ -3072,7 +3567,8 @@ function boundPropKey(key, val, state) {
|
|
|
3072
3567
|
}
|
|
3073
3568
|
return sub;
|
|
3074
3569
|
}
|
|
3075
|
-
async function buildScope(
|
|
3570
|
+
async function buildScope(source, parentScope = {}, base = location.href, ctx) {
|
|
3571
|
+
const doc = inlineDocument(source, base);
|
|
3076
3572
|
const dispatchRoot = () => ctx?.root ?? null;
|
|
3077
3573
|
const raw = {};
|
|
3078
3574
|
const defs = doc.state ?? {};
|
|
@@ -3159,7 +3655,11 @@ async function buildScope(doc, parentScope = {}, base = location.href, ctx) {
|
|
|
3159
3655
|
}
|
|
3160
3656
|
}
|
|
3161
3657
|
}
|
|
3658
|
+
const roles = classifyFunctionEntries(doc);
|
|
3162
3659
|
for (const [key, def] of Object.entries(defs)) {
|
|
3660
|
+
if (isFunctionDef(def) && declaresBodyAndSrc(def)) {
|
|
3661
|
+
throw new Error(`Jx: '${key}' declares both body and $src — these are mutually exclusive`);
|
|
3662
|
+
}
|
|
3163
3663
|
if (hasStructuredBody(def)) {
|
|
3164
3664
|
const { body } = def;
|
|
3165
3665
|
if (Array.isArray(def.parameters) && def.parameters.length > 0) {
|
|
@@ -3175,7 +3675,7 @@ async function buildScope(doc, parentScope = {}, base = location.href, ctx) {
|
|
|
3175
3675
|
state[key] = handler;
|
|
3176
3676
|
}
|
|
3177
3677
|
} else if (isFunctionDef(def)) {
|
|
3178
|
-
state[key] = await resolveFunction(def, state, key, base);
|
|
3678
|
+
state[key] = await resolveFunction(def, state, key, roles.get(key) ?? "callable", base);
|
|
3179
3679
|
}
|
|
3180
3680
|
}
|
|
3181
3681
|
for (const [key, def] of Object.entries(defs)) {
|
|
@@ -3282,6 +3782,7 @@ function bindTemplate(source, run, fallback) {
|
|
|
3282
3782
|
run();
|
|
3283
3783
|
heldTemplateErrors.delete(run);
|
|
3284
3784
|
} catch (error) {
|
|
3785
|
+
_templateThrows += 1;
|
|
3285
3786
|
const thrown = error instanceof Error ? error : new Error(String(error));
|
|
3286
3787
|
if (_templateErrorHandler) {
|
|
3287
3788
|
_templateErrorHandler(thrown, source);
|
|
@@ -3294,6 +3795,8 @@ function bindTemplate(source, run, fallback) {
|
|
|
3294
3795
|
}
|
|
3295
3796
|
});
|
|
3296
3797
|
}
|
|
3798
|
+
var _templateThrows = 0;
|
|
3799
|
+
var _listRedraws = 0;
|
|
3297
3800
|
function rowContext(state) {
|
|
3298
3801
|
return state.$map;
|
|
3299
3802
|
}
|
|
@@ -3301,19 +3804,8 @@ function isSingleExpression(str) {
|
|
|
3301
3804
|
if (!str.startsWith("${") || !str.endsWith("}")) {
|
|
3302
3805
|
return false;
|
|
3303
3806
|
}
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
const c = str[i];
|
|
3307
|
-
if (c === "{") {
|
|
3308
|
-
depth += 1;
|
|
3309
|
-
} else if (c === "}") {
|
|
3310
|
-
depth -= 1;
|
|
3311
|
-
if (depth === 0) {
|
|
3312
|
-
return i === str.length - 1;
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3315
|
-
}
|
|
3316
|
-
return false;
|
|
3807
|
+
const [only, ...more] = templateExpressions(str);
|
|
3808
|
+
return only !== undefined && more.length === 0 && only.start === 0 && only.end === str.length;
|
|
3317
3809
|
}
|
|
3318
3810
|
function evaluateValueTemplate(str, state) {
|
|
3319
3811
|
if (!isSingleExpression(str)) {
|
|
@@ -3326,6 +3818,9 @@ function evaluateValueTemplate(str, state) {
|
|
|
3326
3818
|
}
|
|
3327
3819
|
return fn(...templateArgs(state));
|
|
3328
3820
|
}
|
|
3821
|
+
function evaluateTemplateValue(str, scope) {
|
|
3822
|
+
return evaluateValueTemplate(str, scope);
|
|
3823
|
+
}
|
|
3329
3824
|
var _npmModuleResolver = null;
|
|
3330
3825
|
function setNpmModuleResolver(resolver) {
|
|
3331
3826
|
_npmModuleResolver = resolver;
|
|
@@ -3336,6 +3831,13 @@ async function importSource(src, base) {
|
|
|
3336
3831
|
const specifier = src.slice(NPM_SCHEME.length);
|
|
3337
3832
|
return importModule(_npmModuleResolver?.(specifier) ?? specifier);
|
|
3338
3833
|
}
|
|
3834
|
+
const typed = typeScriptSource(src, base);
|
|
3835
|
+
if (typed !== null && (canLoadModules() || isScriptSpecifier(src))) {
|
|
3836
|
+
const loaded = await importTypeScript(typed, src, base);
|
|
3837
|
+
if (loaded) {
|
|
3838
|
+
return loaded;
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3339
3841
|
if (base) {
|
|
3340
3842
|
try {
|
|
3341
3843
|
return await importModule(new URL(src, base).href);
|
|
@@ -3345,6 +3847,70 @@ async function importSource(src, base) {
|
|
|
3345
3847
|
}
|
|
3346
3848
|
return importModule(src);
|
|
3347
3849
|
}
|
|
3850
|
+
var FETCHED_SCHEMES = new Set(["http:", "https:"]);
|
|
3851
|
+
function typeScriptSource(src, base) {
|
|
3852
|
+
if (isScriptSpecifier(src)) {
|
|
3853
|
+
return src;
|
|
3854
|
+
}
|
|
3855
|
+
if (scriptRefSide(src) !== null) {
|
|
3856
|
+
throw new Error(`Jx: $src "${src}" names the script of the document it is written in, and that document ` + `has no $script`);
|
|
3857
|
+
}
|
|
3858
|
+
const from = base ?? location.href;
|
|
3859
|
+
if (!URL.canParse(src, from)) {
|
|
3860
|
+
return null;
|
|
3861
|
+
}
|
|
3862
|
+
const url = new URL(src, from);
|
|
3863
|
+
return FETCHED_SCHEMES.has(url.protocol) && isTypeScriptPath(url.pathname) ? url.href : null;
|
|
3864
|
+
}
|
|
3865
|
+
async function importTypeScript(specifier, src, base) {
|
|
3866
|
+
const load = await moduleLoaderFor();
|
|
3867
|
+
if (load) {
|
|
3868
|
+
const module = await load(specifier, {
|
|
3869
|
+
base,
|
|
3870
|
+
resolveNpm: _npmModuleResolver,
|
|
3871
|
+
text: _documentScripts.get(src)
|
|
3872
|
+
});
|
|
3873
|
+
return module;
|
|
3874
|
+
}
|
|
3875
|
+
if (isScriptSpecifier(src)) {
|
|
3876
|
+
throw new Error(`Jx: ${parseScriptSpecifier(src)?.path ?? src} has a script, and this page has nothing ` + `that can load one. Give it a module loader with setModuleLoader(loadModule), loadModule ` + `from @jxsuite/erase/browser, or let setBodyEraserLoader fetch that file when it is needed.`);
|
|
3877
|
+
}
|
|
3878
|
+
return null;
|
|
3879
|
+
}
|
|
3880
|
+
var _documentScripts = new Map;
|
|
3881
|
+
function withOwnScripts(doc, source) {
|
|
3882
|
+
if (!doc.$script) {
|
|
3883
|
+
return doc;
|
|
3884
|
+
}
|
|
3885
|
+
const address = URL.canParse(source, location.href) ? new URL(source, location.href).href : source;
|
|
3886
|
+
const { client } = doc.$script;
|
|
3887
|
+
const specifier = scriptSpecifier(address, "client");
|
|
3888
|
+
if (isString2(client) && _documentScripts.get(specifier) !== client) {
|
|
3889
|
+
if (_documentScripts.has(specifier) && !_hostSeeded.has(specifier)) {
|
|
3890
|
+
_moduleCache.delete(specifier);
|
|
3891
|
+
}
|
|
3892
|
+
_documentScripts.set(specifier, client);
|
|
3893
|
+
}
|
|
3894
|
+
const own = qualifyScripts(doc, address);
|
|
3895
|
+
_addressed.set(own, own);
|
|
3896
|
+
return own;
|
|
3897
|
+
}
|
|
3898
|
+
var _addressed = new WeakMap;
|
|
3899
|
+
var _inlineCount = 0;
|
|
3900
|
+
function inlineDocument(doc, base) {
|
|
3901
|
+
if (!doc.$script) {
|
|
3902
|
+
return doc;
|
|
3903
|
+
}
|
|
3904
|
+
let own = _addressed.get(doc);
|
|
3905
|
+
if (!own) {
|
|
3906
|
+
_inlineCount += 1;
|
|
3907
|
+
const address = new URL(base, location.href);
|
|
3908
|
+
address.hash = `jx-inline-${_inlineCount}`;
|
|
3909
|
+
own = withOwnScripts(doc, address.href);
|
|
3910
|
+
_addressed.set(doc, own);
|
|
3911
|
+
}
|
|
3912
|
+
return own;
|
|
3913
|
+
}
|
|
3348
3914
|
function importModule(specifier) {
|
|
3349
3915
|
return import(specifier);
|
|
3350
3916
|
}
|
|
@@ -3388,12 +3954,31 @@ function seededModule(src) {
|
|
|
3388
3954
|
_moduleLoaders.set(src, load);
|
|
3389
3955
|
return load;
|
|
3390
3956
|
}
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3957
|
+
function acquireModule(src, base) {
|
|
3958
|
+
const seeded = seededModule(src);
|
|
3959
|
+
if (seeded) {
|
|
3960
|
+
return seeded;
|
|
3961
|
+
}
|
|
3962
|
+
const loading = importSource(src, base);
|
|
3963
|
+
loading.then((mod) => {
|
|
3964
|
+
_moduleCache.set(src, mod);
|
|
3965
|
+
}, () => {});
|
|
3966
|
+
return loading;
|
|
3967
|
+
}
|
|
3968
|
+
function exportedFunction(def, key, src, mod) {
|
|
3969
|
+
const exportName = def.$export ?? key;
|
|
3970
|
+
const candidate = mod[exportName] ?? mod.default?.[exportName];
|
|
3971
|
+
if (!isFunction2(candidate)) {
|
|
3972
|
+
throw new TypeError(`Jx: export "${exportName}" not found or not a function in "${src}"`);
|
|
3394
3973
|
}
|
|
3974
|
+
return candidate;
|
|
3975
|
+
}
|
|
3976
|
+
async function importFunctionExport(def, key, src, base) {
|
|
3977
|
+
return exportedFunction(def, key, src, await acquireModule(src, base));
|
|
3978
|
+
}
|
|
3979
|
+
async function resolveFunction(def, state, key, role, base) {
|
|
3395
3980
|
if (!def.body && !def.$src) {
|
|
3396
|
-
const params =
|
|
3981
|
+
const params = handlerParamNames(def);
|
|
3397
3982
|
const noop = new Function(...params, "");
|
|
3398
3983
|
Object.defineProperty(noop, "name", {
|
|
3399
3984
|
configurable: true,
|
|
@@ -3403,48 +3988,37 @@ async function resolveFunction(def, state, key, base) {
|
|
|
3403
3988
|
}
|
|
3404
3989
|
let fn;
|
|
3405
3990
|
if (isString2(def.body)) {
|
|
3406
|
-
const params =
|
|
3407
|
-
fn =
|
|
3991
|
+
const params = handlerParamNames(def);
|
|
3992
|
+
fn = compileBody(params, def.body, `'${key}'`);
|
|
3993
|
+
Object.defineProperty(fn, "name", {
|
|
3994
|
+
configurable: true,
|
|
3995
|
+
value: def.name ?? key
|
|
3996
|
+
});
|
|
3997
|
+
} else if (def.$lazy === true && def.$src) {
|
|
3998
|
+
const { $src: src } = def;
|
|
3999
|
+
if (role === "computed") {
|
|
4000
|
+
throw new Error(`Jx: "${key}" declares "$lazy": true but is used as a computed value, not called. A lazily loaded function resolves to a promise; a computed must resolve now. Remove "$lazy", or call ${key}() from a handler instead of binding its value.`);
|
|
4001
|
+
}
|
|
4002
|
+
let loaded;
|
|
4003
|
+
const load = () => loaded ??= importFunctionExport(def, key, src, base);
|
|
4004
|
+
fn = (...args) => load().then((target) => target(...args));
|
|
3408
4005
|
Object.defineProperty(fn, "name", {
|
|
3409
4006
|
configurable: true,
|
|
3410
4007
|
value: def.name ?? key
|
|
3411
4008
|
});
|
|
4009
|
+
return fn;
|
|
3412
4010
|
} else {
|
|
3413
|
-
|
|
3414
|
-
if (!src) {
|
|
4011
|
+
if (!def.$src) {
|
|
3415
4012
|
throw new Error(`Jx: '${key}' has neither body nor $src`);
|
|
3416
4013
|
}
|
|
3417
|
-
const
|
|
3418
|
-
|
|
3419
|
-
const seeded = seededModule(src);
|
|
3420
|
-
if (seeded instanceof Promise) {
|
|
3421
|
-
mod = await seeded;
|
|
3422
|
-
} else if (seeded) {
|
|
3423
|
-
mod = seeded;
|
|
3424
|
-
} else {
|
|
3425
|
-
mod = await importSource(src, base);
|
|
3426
|
-
_moduleCache.set(src, mod);
|
|
3427
|
-
}
|
|
3428
|
-
const candidate = mod[exportName] ?? mod.default?.[exportName];
|
|
3429
|
-
if (!isFunction2(candidate)) {
|
|
3430
|
-
throw new TypeError(`Jx: export "${exportName}" not found or not a function in "${src}"`);
|
|
3431
|
-
}
|
|
3432
|
-
fn = candidate;
|
|
3433
|
-
}
|
|
3434
|
-
const hasParams = (def.parameters ?? def.arguments ?? []).length > 0;
|
|
3435
|
-
let isComputed = false;
|
|
3436
|
-
if (!hasParams) {
|
|
3437
|
-
isComputed = isString2(def.body) ? bodyReturnsValue(def.body) : fn.length <= 1 && bodyReturnsValue(fn.toString());
|
|
4014
|
+
const acquired = acquireModule(def.$src, base);
|
|
4015
|
+
fn = exportedFunction(def, key, def.$src, acquired instanceof Promise ? await acquired : acquired);
|
|
3438
4016
|
}
|
|
3439
|
-
if (
|
|
4017
|
+
if (role === "computed") {
|
|
3440
4018
|
return computed(() => fn(state));
|
|
3441
4019
|
}
|
|
3442
4020
|
return fn;
|
|
3443
4021
|
}
|
|
3444
|
-
function resolveParamNames(def) {
|
|
3445
|
-
const names = def.parameters ? paramNames(def.parameters) : def.arguments ?? [];
|
|
3446
|
-
return names.length > 0 && names[0] === "state" ? names : ["state", ...names];
|
|
3447
|
-
}
|
|
3448
4022
|
var RESERVED_KEYS = new Set([
|
|
3449
4023
|
"$schema",
|
|
3450
4024
|
"$id",
|
|
@@ -3459,6 +4033,7 @@ var RESERVED_KEYS = new Set([
|
|
|
3459
4033
|
"$prototype",
|
|
3460
4034
|
"$src",
|
|
3461
4035
|
"$export",
|
|
4036
|
+
"$script",
|
|
3462
4037
|
"$media",
|
|
3463
4038
|
"$map",
|
|
3464
4039
|
"timing",
|
|
@@ -3593,6 +4168,8 @@ function renderNode(def, state, options) {
|
|
|
3593
4168
|
const childOpts = options || childNs ? { ...options, _ns: childNs, _path: [...path, "children", i] } : undefined;
|
|
3594
4169
|
if (isMappedArray(child)) {
|
|
3595
4170
|
renderMappedArrayInto(el, child, localState, childOpts);
|
|
4171
|
+
} else if (isString2(child) && isSingleExpression(child)) {
|
|
4172
|
+
renderTemplatedChild(el, child, localState, childOpts);
|
|
3596
4173
|
} else {
|
|
3597
4174
|
el.append(renderNode(child, localState, childOpts));
|
|
3598
4175
|
}
|
|
@@ -3607,7 +4184,6 @@ function renderNode(def, state, options) {
|
|
|
3607
4184
|
return el;
|
|
3608
4185
|
}
|
|
3609
4186
|
function renderComputedChildren(el, template, state, options) {
|
|
3610
|
-
const path = options._path ?? [];
|
|
3611
4187
|
let live = null;
|
|
3612
4188
|
const retire = () => {
|
|
3613
4189
|
el.replaceChildren();
|
|
@@ -3620,21 +4196,62 @@ function renderComputedChildren(el, template, state, options) {
|
|
|
3620
4196
|
if (!Array.isArray(nodes)) {
|
|
3621
4197
|
return;
|
|
3622
4198
|
}
|
|
3623
|
-
|
|
3624
|
-
live
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
scope.run(() => {
|
|
3628
|
-
for (const [i, child] of nodes.entries()) {
|
|
3629
|
-
el.append(renderNode(child, state, { ...options, _path: [...path, i] }));
|
|
3630
|
-
}
|
|
3631
|
-
});
|
|
3632
|
-
} finally {
|
|
3633
|
-
resetTracking();
|
|
3634
|
-
}
|
|
4199
|
+
live = effectScope(true);
|
|
4200
|
+
drawTemplateNodes(live, nodes, state, options, (node) => {
|
|
4201
|
+
el.append(node);
|
|
4202
|
+
});
|
|
3635
4203
|
}, retire);
|
|
3636
4204
|
onScopeDispose(() => live?.stop(), true);
|
|
3637
4205
|
}
|
|
4206
|
+
function drawTemplateNodes(scope, nodes, state, options, place) {
|
|
4207
|
+
const path = options?._path ?? [];
|
|
4208
|
+
const members = [...nodes];
|
|
4209
|
+
pauseTracking();
|
|
4210
|
+
try {
|
|
4211
|
+
scope.run(() => {
|
|
4212
|
+
for (const [i, child] of members.entries()) {
|
|
4213
|
+
place(renderNode(child, state, options ? { ...options, _path: [...path, i] } : undefined));
|
|
4214
|
+
}
|
|
4215
|
+
});
|
|
4216
|
+
} finally {
|
|
4217
|
+
resetTracking();
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
function renderTemplatedChild(parent, template, state, options) {
|
|
4221
|
+
const anchor = document.createTextNode(template);
|
|
4222
|
+
parent.append(anchor);
|
|
4223
|
+
let live = null;
|
|
4224
|
+
let drawn = [];
|
|
4225
|
+
const retire = () => {
|
|
4226
|
+
for (const node of drawn) {
|
|
4227
|
+
node.remove();
|
|
4228
|
+
}
|
|
4229
|
+
drawn = [];
|
|
4230
|
+
live?.stop();
|
|
4231
|
+
live = null;
|
|
4232
|
+
};
|
|
4233
|
+
bindTemplate(template, () => {
|
|
4234
|
+
const value = evaluateValueTemplate(template, state);
|
|
4235
|
+
retire();
|
|
4236
|
+
if (!Array.isArray(value)) {
|
|
4237
|
+
anchor.textContent = templateText(value);
|
|
4238
|
+
return;
|
|
4239
|
+
}
|
|
4240
|
+
anchor.textContent = "";
|
|
4241
|
+
live = effectScope(true);
|
|
4242
|
+
drawTemplateNodes(live, value, state, options, (node) => {
|
|
4243
|
+
drawn.push(node);
|
|
4244
|
+
anchor.before(node);
|
|
4245
|
+
});
|
|
4246
|
+
}, () => {
|
|
4247
|
+
retire();
|
|
4248
|
+
anchor.textContent = "";
|
|
4249
|
+
});
|
|
4250
|
+
onScopeDispose(() => live?.stop(), true);
|
|
4251
|
+
}
|
|
4252
|
+
function templateText(value) {
|
|
4253
|
+
return `${value}`;
|
|
4254
|
+
}
|
|
3638
4255
|
function applyProperties(el, def, state) {
|
|
3639
4256
|
for (const [key, val] of Object.entries(def)) {
|
|
3640
4257
|
if (RESERVED_KEYS.has(key)) {
|
|
@@ -3659,6 +4276,9 @@ function bindHandler(el, key, val, state) {
|
|
|
3659
4276
|
}
|
|
3660
4277
|
return true;
|
|
3661
4278
|
}
|
|
4279
|
+
if (isFunctionDef(val) && declaresBodyAndSrc(val)) {
|
|
4280
|
+
throw new Error(`Jx: inline '${key}' handler declares both body and $src — these are mutually exclusive`);
|
|
4281
|
+
}
|
|
3662
4282
|
if (hasStructuredBody(val)) {
|
|
3663
4283
|
const { body } = val;
|
|
3664
4284
|
el.addEventListener(type, (e) => {
|
|
@@ -3667,8 +4287,8 @@ function bindHandler(el, key, val, state) {
|
|
|
3667
4287
|
return true;
|
|
3668
4288
|
}
|
|
3669
4289
|
if (isFunctionDef(val) && isString2(val.body)) {
|
|
3670
|
-
const params =
|
|
3671
|
-
const fn =
|
|
4290
|
+
const params = handlerParamNames(val);
|
|
4291
|
+
const fn = compileBody(params, val.body, `the ${type} handler`);
|
|
3672
4292
|
el.addEventListener(type, (e) => fn(scope, e));
|
|
3673
4293
|
return true;
|
|
3674
4294
|
}
|
|
@@ -4005,10 +4625,14 @@ function applyStyleInto(el, styleDef, mediaQueries, state, live) {
|
|
|
4005
4625
|
const scope = effectScope();
|
|
4006
4626
|
scope.run(() => {
|
|
4007
4627
|
for (const { name, value } of sources) {
|
|
4008
|
-
|
|
4009
|
-
const resolved = isRef2(value) ? resolveRef(value.$ref, state) : evaluateTemplate(value, state);
|
|
4628
|
+
const write = (resolved) => {
|
|
4010
4629
|
el.style.setProperty(name, canvasStyleValue(String(resolved ?? "")));
|
|
4011
|
-
}
|
|
4630
|
+
};
|
|
4631
|
+
if (isRef2(value)) {
|
|
4632
|
+
effect(() => write(resolveRef(value.$ref, state)));
|
|
4633
|
+
} else {
|
|
4634
|
+
bindTemplate(value, () => write(evaluateTemplate(value, state)));
|
|
4635
|
+
}
|
|
4012
4636
|
}
|
|
4013
4637
|
});
|
|
4014
4638
|
entry.stop = () => scope.stop();
|
|
@@ -4062,6 +4686,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4062
4686
|
const { items: itemsSrc, map: mapDef, filter: filterRef, sort: sortRef, key: keyRef } = arrayDef;
|
|
4063
4687
|
const keyPointer = isRef2(keyRef) ? keyRef.$ref : null;
|
|
4064
4688
|
const instancePath = _instancePath;
|
|
4689
|
+
const insideStamped = _canvasInsideStampedHost;
|
|
4065
4690
|
let warned = false;
|
|
4066
4691
|
const warnOnce = (message) => {
|
|
4067
4692
|
if (!warned) {
|
|
@@ -4083,7 +4708,9 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4083
4708
|
const scope = effectScope(true);
|
|
4084
4709
|
const childOpts = options ? { ...options, _path: [...path, "map", index] } : undefined;
|
|
4085
4710
|
const node = scope.run(() => renderNode(mapDef, child, childOpts));
|
|
4086
|
-
|
|
4711
|
+
const row = { key, map, node, scope };
|
|
4712
|
+
listRows.set(node, row);
|
|
4713
|
+
return row;
|
|
4087
4714
|
};
|
|
4088
4715
|
const reconcile = (list, keys) => {
|
|
4089
4716
|
const previous = new Map;
|
|
@@ -4138,8 +4765,17 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4138
4765
|
items = [...unsorted].toSorted(compare);
|
|
4139
4766
|
}
|
|
4140
4767
|
}
|
|
4141
|
-
|
|
4142
|
-
const
|
|
4768
|
+
let list = Array.isArray(items) && mapDef ? items : [];
|
|
4769
|
+
const count = list.length;
|
|
4770
|
+
const placeholder = count === 0 && mapDef ? options?.emptyRow?.(arrayDef, path) : undefined;
|
|
4771
|
+
if (placeholder !== undefined) {
|
|
4772
|
+
list = [placeholder];
|
|
4773
|
+
}
|
|
4774
|
+
const limit = options?.rowLimit;
|
|
4775
|
+
if (isNumber(limit) && limit >= 0 && list.length > limit) {
|
|
4776
|
+
list = list.slice(0, Math.floor(limit));
|
|
4777
|
+
}
|
|
4778
|
+
const keys = placeholder === undefined ? list.map((item, index) => mappedRowKey(keyPointer, item, index, warnOnce)) : list.map(() => EMPTY_ROW_KEY);
|
|
4143
4779
|
const seen = new Set;
|
|
4144
4780
|
for (let i = 0;i < keys.length; i++) {
|
|
4145
4781
|
if (seen.has(keys[i])) {
|
|
@@ -4151,7 +4787,13 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4151
4787
|
}
|
|
4152
4788
|
pauseTracking();
|
|
4153
4789
|
try {
|
|
4154
|
-
underInstancePath(reexpand(instancePath), () => reconcile(list, keys));
|
|
4790
|
+
underInstancePath(reexpand(instancePath), () => insideStampedHost(insideStamped, () => reconcile(list, keys)));
|
|
4791
|
+
options?.onListReconciled?.(path, {
|
|
4792
|
+
count,
|
|
4793
|
+
empty: count === 0,
|
|
4794
|
+
nodes: rows.map((row) => row.node),
|
|
4795
|
+
rendered: rows.length
|
|
4796
|
+
});
|
|
4155
4797
|
} finally {
|
|
4156
4798
|
resetTracking();
|
|
4157
4799
|
}
|
|
@@ -4160,6 +4802,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4160
4802
|
let stopped = false;
|
|
4161
4803
|
const runner = effect(update, {
|
|
4162
4804
|
scheduler: () => {
|
|
4805
|
+
_listRedraws += 1;
|
|
4163
4806
|
if (queued) {
|
|
4164
4807
|
return;
|
|
4165
4808
|
}
|
|
@@ -4180,6 +4823,21 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4180
4823
|
rows = [];
|
|
4181
4824
|
}, true);
|
|
4182
4825
|
}
|
|
4826
|
+
var EMPTY_ROW_KEY = Object.freeze({ emptyRow: true });
|
|
4827
|
+
var listRows = new WeakMap;
|
|
4828
|
+
function replaceListRow(current, next, stop) {
|
|
4829
|
+
const row = listRows.get(current);
|
|
4830
|
+
if (!row || row.node !== current) {
|
|
4831
|
+
return false;
|
|
4832
|
+
}
|
|
4833
|
+
row.node.replaceWith(next);
|
|
4834
|
+
row.scope.stop();
|
|
4835
|
+
listRows.delete(current);
|
|
4836
|
+
row.node = next;
|
|
4837
|
+
row.scope = { stop: () => stop?.() };
|
|
4838
|
+
listRows.set(next, row);
|
|
4839
|
+
return true;
|
|
4840
|
+
}
|
|
4183
4841
|
function mappedRowKey(pointer, item, index, warnOnce) {
|
|
4184
4842
|
if (pointer === null) {
|
|
4185
4843
|
return index;
|
|
@@ -4216,6 +4874,7 @@ function renderSwitch(def, state, options) {
|
|
|
4216
4874
|
const path = options?._path ?? [];
|
|
4217
4875
|
const container = document.createElement(resolveTagName(def.tagName, state));
|
|
4218
4876
|
const instancePath = _instancePath;
|
|
4877
|
+
const insideStamped = _canvasInsideStampedHost;
|
|
4219
4878
|
if (options?.onNodeCreated) {
|
|
4220
4879
|
options.onNodeCreated(container, path, def, state);
|
|
4221
4880
|
}
|
|
@@ -4258,18 +4917,18 @@ function renderSwitch(def, state, options) {
|
|
|
4258
4917
|
if (gen !== generation) {
|
|
4259
4918
|
return;
|
|
4260
4919
|
}
|
|
4261
|
-
const childScope = await buildScope(doc, {}, href, options?._ctx);
|
|
4920
|
+
const childScope = await buildScope(withProjectFormulas(doc), {}, href, options?._ctx);
|
|
4262
4921
|
if (gen !== generation) {
|
|
4263
4922
|
return;
|
|
4264
4923
|
}
|
|
4265
4924
|
container.replaceChildren();
|
|
4266
|
-
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(doc, childScope, childOpts))));
|
|
4925
|
+
underInstancePath(reexpand(instancePath), () => insideStampedHost(insideStamped, () => scope.run(() => container.append(renderNode(doc, childScope, childOpts)))));
|
|
4267
4926
|
}).catch((error) => console.error("Jx $switch: failed to load external case", caseDef.$ref, error));
|
|
4268
4927
|
return;
|
|
4269
4928
|
}
|
|
4270
4929
|
pauseTracking();
|
|
4271
4930
|
try {
|
|
4272
|
-
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(caseDef, state, childOpts))));
|
|
4931
|
+
underInstancePath(reexpand(instancePath), () => insideStampedHost(insideStamped, () => scope.run(() => container.append(renderNode(caseDef, state, childOpts)))));
|
|
4273
4932
|
} finally {
|
|
4274
4933
|
resetTracking();
|
|
4275
4934
|
}
|
|
@@ -4305,18 +4964,46 @@ async function resolvePrototype(def, state, key, base, ctx) {
|
|
|
4305
4964
|
clearTimeout(debounceTimer);
|
|
4306
4965
|
}
|
|
4307
4966
|
});
|
|
4967
|
+
const request = (signal) => fetch(url, {
|
|
4968
|
+
method: def.method ?? "GET",
|
|
4969
|
+
...signal && { signal },
|
|
4970
|
+
...def.headers && { headers: def.headers },
|
|
4971
|
+
...def.body && {
|
|
4972
|
+
body: isNonNullObject(def.body) ? JSON.stringify(def.body) : def.body
|
|
4973
|
+
}
|
|
4974
|
+
}).then((r) => r.ok ? r.json() : Promise.reject(r.statusText));
|
|
4308
4975
|
const doFetch = () => {
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4976
|
+
const handler = _remoteLookupHandler;
|
|
4977
|
+
let lookup;
|
|
4978
|
+
if (handler) {
|
|
4979
|
+
const answer = handler({
|
|
4980
|
+
key,
|
|
4981
|
+
kind: "request",
|
|
4982
|
+
request: {
|
|
4983
|
+
method: def.method ?? "GET",
|
|
4984
|
+
url,
|
|
4985
|
+
...def.headers && { headers: def.headers },
|
|
4986
|
+
...def.body !== undefined && { body: def.body }
|
|
4987
|
+
},
|
|
4988
|
+
scope: state
|
|
4989
|
+
}, () => request());
|
|
4990
|
+
if (answer === null) {
|
|
4991
|
+
return;
|
|
4992
|
+
}
|
|
4993
|
+
if (!(answer instanceof Promise)) {
|
|
4994
|
+
s.value = answer.value;
|
|
4995
|
+
return;
|
|
4996
|
+
}
|
|
4997
|
+
lookup = answer;
|
|
4998
|
+
} else {
|
|
4999
|
+
lookup = request(controller.signal);
|
|
5000
|
+
}
|
|
5001
|
+
holdTemplateErrorsFor(lookup.then((d) => {
|
|
5002
|
+
if (!controller.signal.aborted) {
|
|
5003
|
+
s.value = d;
|
|
4315
5004
|
}
|
|
4316
|
-
}).then((r) => r.ok ? r.json() : Promise.reject(r.statusText)).then((d) => {
|
|
4317
|
-
s.value = d;
|
|
4318
5005
|
}).catch((error) => {
|
|
4319
|
-
if (!(error instanceof Error && error.name === "AbortError")) {
|
|
5006
|
+
if (!controller.signal.aborted && !(error instanceof Error && error.name === "AbortError")) {
|
|
4320
5007
|
s.value = { error: String(error) };
|
|
4321
5008
|
}
|
|
4322
5009
|
}));
|
|
@@ -4534,6 +5221,7 @@ async function resolveClassJson(def, state, key, base) {
|
|
|
4534
5221
|
} catch {
|
|
4535
5222
|
return resolveViaDevProxy(def, state, key, base);
|
|
4536
5223
|
}
|
|
5224
|
+
await prepareBodies(classDef);
|
|
4537
5225
|
if (classDef.$implementation) {
|
|
4538
5226
|
const schemaStr = JSON.stringify(classDef);
|
|
4539
5227
|
if (schemaStr.includes('"#/$context/')) {
|
|
@@ -4567,6 +5255,7 @@ function classFromSchema(classDef) {
|
|
|
4567
5255
|
const rawCtor = classDef.$defs?.constructor;
|
|
4568
5256
|
const ctor = isCtorDef(rawCtor) ? rawCtor : undefined;
|
|
4569
5257
|
const methods = classDef.$defs?.methods ?? {};
|
|
5258
|
+
const className = classDef.title ?? "a class";
|
|
4570
5259
|
|
|
4571
5260
|
class DynClass {
|
|
4572
5261
|
constructor(config = {}) {
|
|
@@ -4586,7 +5275,7 @@ function classFromSchema(classDef) {
|
|
|
4586
5275
|
if (ctor?.body) {
|
|
4587
5276
|
const bodyStr = Array.isArray(ctor.body) ? ctor.body.join(`
|
|
4588
5277
|
`) : ctor.body;
|
|
4589
|
-
const init =
|
|
5278
|
+
const init = compileBody(["config"], bodyStr, `the constructor of ${className}`);
|
|
4590
5279
|
init.call(this, config);
|
|
4591
5280
|
}
|
|
4592
5281
|
}
|
|
@@ -4605,20 +5294,20 @@ function classFromSchema(classDef) {
|
|
|
4605
5294
|
if (typedMethod.role === "accessor") {
|
|
4606
5295
|
const descriptor = {};
|
|
4607
5296
|
if (typedMethod.getter) {
|
|
4608
|
-
descriptor.get =
|
|
5297
|
+
descriptor.get = compileBody([], typedMethod.getter.body ?? "", `the getter ${name} of ${className}`);
|
|
4609
5298
|
}
|
|
4610
5299
|
if (typedMethod.setter) {
|
|
4611
5300
|
const sp = (typedMethod.setter.parameters ?? []).map((p) => p.$ref?.split("/").pop() ?? "v");
|
|
4612
|
-
descriptor.set =
|
|
5301
|
+
descriptor.set = compileBody(sp, typedMethod.setter.body ?? "", `the setter ${name} of ${className}`);
|
|
4613
5302
|
}
|
|
4614
5303
|
Object.defineProperty(DynClass.prototype, name, {
|
|
4615
5304
|
...descriptor,
|
|
4616
5305
|
configurable: true
|
|
4617
5306
|
});
|
|
4618
5307
|
} else if (typedMethod.scope === "static") {
|
|
4619
|
-
DynClass[name] =
|
|
5308
|
+
DynClass[name] = compileBody(params, bodyStr, `${name} of ${className}`);
|
|
4620
5309
|
} else {
|
|
4621
|
-
DynClass.prototype[name] =
|
|
5310
|
+
DynClass.prototype[name] = compileBody(params, bodyStr, `${name} of ${className}`);
|
|
4622
5311
|
}
|
|
4623
5312
|
}
|
|
4624
5313
|
Object.defineProperty(DynClass, "name", {
|
|
@@ -4665,24 +5354,46 @@ async function resolveViaDevProxy(def, state, key, base) {
|
|
|
4665
5354
|
}
|
|
4666
5355
|
return s;
|
|
4667
5356
|
}
|
|
4668
|
-
function latestServerCall(s, invoke, label) {
|
|
5357
|
+
function latestServerCall(s, invoke, label, describe) {
|
|
4669
5358
|
let seq = 0;
|
|
4670
5359
|
return (args) => {
|
|
4671
5360
|
seq += 1;
|
|
4672
5361
|
const n = seq;
|
|
4673
|
-
|
|
5362
|
+
const run = () => new Promise((settle) => {
|
|
4674
5363
|
settle(invoke(args));
|
|
4675
|
-
})
|
|
5364
|
+
});
|
|
5365
|
+
const answer = _remoteLookupHandler ? _remoteLookupHandler(describe(args), run) : run();
|
|
5366
|
+
if (answer === null) {
|
|
5367
|
+
return;
|
|
5368
|
+
}
|
|
5369
|
+
if (!(answer instanceof Promise)) {
|
|
5370
|
+
s.value = answer.value;
|
|
5371
|
+
return;
|
|
5372
|
+
}
|
|
5373
|
+
holdTemplateErrorsFor(answer.then((result) => {
|
|
4676
5374
|
if (n === seq) {
|
|
4677
5375
|
s.value = result;
|
|
4678
5376
|
}
|
|
4679
5377
|
}).catch((error) => {
|
|
4680
|
-
if (n === seq) {
|
|
5378
|
+
if (n === seq && !(error instanceof Error && error.name === "AbortError")) {
|
|
4681
5379
|
console.error(label, error);
|
|
4682
5380
|
}
|
|
4683
5381
|
}));
|
|
4684
5382
|
};
|
|
4685
5383
|
}
|
|
5384
|
+
function serverLookup(def, state, key, args, base) {
|
|
5385
|
+
return {
|
|
5386
|
+
key,
|
|
5387
|
+
kind: "server",
|
|
5388
|
+
request: {
|
|
5389
|
+
$export: def.$export,
|
|
5390
|
+
$src: def.$src,
|
|
5391
|
+
arguments: args,
|
|
5392
|
+
...base !== undefined && { $base: base }
|
|
5393
|
+
},
|
|
5394
|
+
scope: state
|
|
5395
|
+
};
|
|
5396
|
+
}
|
|
4686
5397
|
async function resolveServerFunction(def, state, key, base) {
|
|
4687
5398
|
const src = def.$src;
|
|
4688
5399
|
const exportName = def.$export;
|
|
@@ -4710,7 +5421,7 @@ async function resolveServerFunction(def, state, key, base) {
|
|
|
4710
5421
|
};
|
|
4711
5422
|
const s = ref(null);
|
|
4712
5423
|
if (hasReactiveArg) {
|
|
4713
|
-
const call = latestServerCall(s, fn, "Jx server function:");
|
|
5424
|
+
const call = latestServerCall(s, fn, "Jx server function:", (args) => serverLookup(def, state, key, args, base));
|
|
4714
5425
|
effect(() => {
|
|
4715
5426
|
const args = resolveArgs();
|
|
4716
5427
|
onEffectCleanup(() => {});
|
|
@@ -4747,7 +5458,7 @@ async function resolveServerFunctionViaProxy(def, state, key, base) {
|
|
|
4747
5458
|
return r.json();
|
|
4748
5459
|
});
|
|
4749
5460
|
const s = ref(null);
|
|
4750
|
-
const call = latestServerCall(s, doResolve, "Jx server proxy:");
|
|
5461
|
+
const call = latestServerCall(s, doResolve, "Jx server proxy:", (args) => serverLookup(def, state, key, args, base));
|
|
4751
5462
|
if (hasReactiveArg) {
|
|
4752
5463
|
effect(() => {
|
|
4753
5464
|
const args = resolveArgs();
|
|
@@ -4890,6 +5601,23 @@ async function redefineElement(doc, baseUrl) {
|
|
|
4890
5601
|
}
|
|
4891
5602
|
_elementDefs.set(tagName, { base, doc });
|
|
4892
5603
|
}
|
|
5604
|
+
var _projectFormulas = {};
|
|
5605
|
+
var _withFormulas = new WeakMap;
|
|
5606
|
+
function setProjectFormulas(projectState) {
|
|
5607
|
+
_projectFormulas = inheritableFormulas(projectState);
|
|
5608
|
+
_withFormulas = new WeakMap;
|
|
5609
|
+
}
|
|
5610
|
+
function withProjectFormulas(doc) {
|
|
5611
|
+
const cached = _withFormulas.get(doc);
|
|
5612
|
+
if (cached) {
|
|
5613
|
+
return cached;
|
|
5614
|
+
}
|
|
5615
|
+
const own = doc.state ?? {};
|
|
5616
|
+
const added = Object.entries(_projectFormulas).filter(([key]) => !(key in own));
|
|
5617
|
+
const merged = added.length > 0 ? { ...doc, state: { ...Object.fromEntries(added), ...own } } : doc;
|
|
5618
|
+
_withFormulas.set(doc, merged);
|
|
5619
|
+
return merged;
|
|
5620
|
+
}
|
|
4893
5621
|
function setRootMedia(map) {
|
|
4894
5622
|
_rootMedia = map ?? {};
|
|
4895
5623
|
}
|
|
@@ -5036,7 +5764,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5036
5764
|
_definedSources.add(base);
|
|
5037
5765
|
source_ = await resolve(source);
|
|
5038
5766
|
} else {
|
|
5039
|
-
source_ = source;
|
|
5767
|
+
source_ = inlineDocument(source, new URL(base ?? location.href, location.href).href);
|
|
5040
5768
|
}
|
|
5041
5769
|
base ??= location.href;
|
|
5042
5770
|
const { tagName } = source_;
|
|
@@ -5053,6 +5781,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5053
5781
|
const initialDef = source_;
|
|
5054
5782
|
const initialBase = base;
|
|
5055
5783
|
const observedAttrs = initialDef.observedAttributes ?? [];
|
|
5784
|
+
_observedAttributes.set(tagName, observedAttrs);
|
|
5056
5785
|
const ElementClass = class extends HTMLElement {
|
|
5057
5786
|
_jxInitialized = false;
|
|
5058
5787
|
_state = null;
|
|
@@ -5070,7 +5799,8 @@ async function defineElement(source, baseUrl) {
|
|
|
5070
5799
|
const enclosingPath = _instancePath;
|
|
5071
5800
|
const supplied = {};
|
|
5072
5801
|
const live = _elementDefs.get(tagName) ?? { base: initialBase, doc: initialDef };
|
|
5073
|
-
|
|
5802
|
+
_connectedDefs.set(this, live.doc);
|
|
5803
|
+
const def = withProjectFormulas(live.doc);
|
|
5074
5804
|
const defBase = live.base;
|
|
5075
5805
|
const state = await buildScope(def, {}, defBase, { base: defBase, media: null, root: this });
|
|
5076
5806
|
for (const attr of observedAttrs) {
|
|
@@ -5127,10 +5857,14 @@ async function defineElement(source, baseUrl) {
|
|
|
5127
5857
|
reportUnrendered(this, tagName, error instanceof Error ? error : new Error(String(error)));
|
|
5128
5858
|
return;
|
|
5129
5859
|
}
|
|
5860
|
+
const declared = live.doc.state ?? {};
|
|
5130
5861
|
for (const key of Object.keys(def.state ?? {})) {
|
|
5131
5862
|
if (isPrivateStateKey(key)) {
|
|
5132
5863
|
continue;
|
|
5133
5864
|
}
|
|
5865
|
+
if (!(key in declared) && !(key in supplied)) {
|
|
5866
|
+
continue;
|
|
5867
|
+
}
|
|
5134
5868
|
const native = nativeSetter(this, key);
|
|
5135
5869
|
Object.defineProperty(this, key, {
|
|
5136
5870
|
configurable: true,
|
|
@@ -5156,7 +5890,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5156
5890
|
const children = Array.isArray(def.children) ? def.children : [];
|
|
5157
5891
|
const draw = () => {
|
|
5158
5892
|
const wasInside = _canvasInsideStampedHost;
|
|
5159
|
-
_canvasInsideStampedHost ||= this
|
|
5893
|
+
_canvasInsideStampedHost ||= carriesCanvasStamp(this);
|
|
5160
5894
|
let failure = null;
|
|
5161
5895
|
try {
|
|
5162
5896
|
underInstancePath(ownPath, () => {
|
|
@@ -5246,6 +5980,195 @@ async function defineElement(source, baseUrl) {
|
|
|
5246
5980
|
};
|
|
5247
5981
|
customElements.define(tagName, ElementClass);
|
|
5248
5982
|
}
|
|
5983
|
+
function writeInstanceProp(el, key, resolved) {
|
|
5984
|
+
const value = isString2(resolved) ? canvasAssetValue(el.tagName, key, resolved) : resolved;
|
|
5985
|
+
elementProperties(el)[key] = value;
|
|
5986
|
+
const instanceState = instanceStateOf(el);
|
|
5987
|
+
if (instanceState && key in HTMLElement.prototype && Object.hasOwn(toRaw(instanceState), key)) {
|
|
5988
|
+
instanceState[key] = value;
|
|
5989
|
+
}
|
|
5990
|
+
}
|
|
5991
|
+
var _observedAttributes = new Map;
|
|
5992
|
+
var _connectedDefs = new WeakMap;
|
|
5993
|
+
function drawnByCurrent(el) {
|
|
5994
|
+
const drawn = _connectedDefs.get(el);
|
|
5995
|
+
return drawn !== undefined && drawn === _elementDefs.get(el.localName)?.doc;
|
|
5996
|
+
}
|
|
5997
|
+
function producedElsewhere(entry) {
|
|
5998
|
+
if (!isJsonObject(entry)) {
|
|
5999
|
+
return false;
|
|
6000
|
+
}
|
|
6001
|
+
const { $prototype: prototype } = entry;
|
|
6002
|
+
if (prototype !== undefined) {
|
|
6003
|
+
return prototype !== "Function";
|
|
6004
|
+
}
|
|
6005
|
+
return "$src" in entry || "timing" in entry;
|
|
6006
|
+
}
|
|
6007
|
+
function isScalarProp(value) {
|
|
6008
|
+
return isString2(value) && !isTemplateString(value) || isNumber(value) || isBoolean(value);
|
|
6009
|
+
}
|
|
6010
|
+
var VERBATIM_PROPS = new Set(["id", "lang", "role", "slot", "title"]);
|
|
6011
|
+
function isBoundProp(value) {
|
|
6012
|
+
return isRef2(value) || isTemplateString(value);
|
|
6013
|
+
}
|
|
6014
|
+
function rendersOnce(def, drawing = new Set) {
|
|
6015
|
+
const declared = def.state ?? {};
|
|
6016
|
+
if ("onMount" in declared || Object.values(declared).some((entry) => producedElsewhere(entry))) {
|
|
6017
|
+
return true;
|
|
6018
|
+
}
|
|
6019
|
+
drawing.add(def);
|
|
6020
|
+
const walk = (value, isRoot, redrawn) => {
|
|
6021
|
+
if (Array.isArray(value)) {
|
|
6022
|
+
return value.some((item) => walk(item, false, redrawn));
|
|
6023
|
+
}
|
|
6024
|
+
if (!isNonNullObject(value)) {
|
|
6025
|
+
return false;
|
|
6026
|
+
}
|
|
6027
|
+
const node = Object.fromEntries(Object.entries(value));
|
|
6028
|
+
const { attributes, tagName } = node;
|
|
6029
|
+
if (tagName !== undefined && !isString2(tagName)) {
|
|
6030
|
+
return true;
|
|
6031
|
+
}
|
|
6032
|
+
const attrs = isJsonObject(attributes) ? attributes : {};
|
|
6033
|
+
if (tagName === "slot" && (redrawn || isBoundProp(attrs.name) || isBoundProp(node.name) || isBoundProp(node.textContent) || node.$switch !== undefined)) {
|
|
6034
|
+
return true;
|
|
6035
|
+
}
|
|
6036
|
+
if (isBoundProp(node.innerHTML) || !isRoot && isBoundProp(node.children)) {
|
|
6037
|
+
return true;
|
|
6038
|
+
}
|
|
6039
|
+
const isInstance = !isRoot && isString2(tagName) && tagName.includes("-");
|
|
6040
|
+
const inner = isInstance ? _elementDefs.get(tagName)?.doc : undefined;
|
|
6041
|
+
if (isInstance && handsOverOnce(node, attrs, inner)) {
|
|
6042
|
+
return true;
|
|
6043
|
+
}
|
|
6044
|
+
if (inner && (drawing.has(inner) || rendersOnce(inner, drawing))) {
|
|
6045
|
+
return true;
|
|
6046
|
+
}
|
|
6047
|
+
for (const [key, entry] of Object.entries(node)) {
|
|
6048
|
+
if (isRoot && (key === "state" || key === "$props")) {
|
|
6049
|
+
continue;
|
|
6050
|
+
}
|
|
6051
|
+
if (key === "$props") {
|
|
6052
|
+
if (!isInstance && isJsonObject(entry) && Object.values(entry).some((v) => isRef2(v))) {
|
|
6053
|
+
return true;
|
|
6054
|
+
}
|
|
6055
|
+
continue;
|
|
6056
|
+
}
|
|
6057
|
+
if ((key === "id" || key.startsWith("$") && !RESERVED_KEYS.has(key)) && isRef2(entry)) {
|
|
6058
|
+
return true;
|
|
6059
|
+
}
|
|
6060
|
+
const drawn = key === "cases" && isJsonObject(entry) ? Object.values(entry) : entry;
|
|
6061
|
+
if (walk(drawn, false, redrawn || key === "cases" || key === "map")) {
|
|
6062
|
+
return true;
|
|
6063
|
+
}
|
|
6064
|
+
}
|
|
6065
|
+
return false;
|
|
6066
|
+
};
|
|
6067
|
+
const answer = walk(def, true, false);
|
|
6068
|
+
drawing.delete(def);
|
|
6069
|
+
return answer;
|
|
6070
|
+
}
|
|
6071
|
+
function handsOverOnce(node, attrs, inner) {
|
|
6072
|
+
if (isBoundProp(node.textContent)) {
|
|
6073
|
+
return true;
|
|
6074
|
+
}
|
|
6075
|
+
const kids = Array.isArray(node.children) ? node.children : [];
|
|
6076
|
+
if (kids.some((kid) => isBoundProp(kid) || isMappedArray(kid) || isJsonObject(kid) && (isBoundProp(kid.slot) || isJsonObject(kid.attributes) && isBoundProp(kid.attributes.slot)))) {
|
|
6077
|
+
return true;
|
|
6078
|
+
}
|
|
6079
|
+
const coerced = (given) => Object.entries(given).some(([key, value]) => isBoundProp(value) && (key in HTMLElement.prototype) && key !== "textContent");
|
|
6080
|
+
if (coerced(node) || isJsonObject(node.$props) && coerced(node.$props)) {
|
|
6081
|
+
return true;
|
|
6082
|
+
}
|
|
6083
|
+
const observed = isString2(node.tagName) ? _observedAttributes.get(node.tagName) ?? [] : [];
|
|
6084
|
+
return Object.entries(attrs).some(([name, given]) => {
|
|
6085
|
+
if (!isBoundProp(given)) {
|
|
6086
|
+
return false;
|
|
6087
|
+
}
|
|
6088
|
+
if (name.startsWith("props.")) {
|
|
6089
|
+
return true;
|
|
6090
|
+
}
|
|
6091
|
+
const prop = name.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
6092
|
+
return !inner || prop in (inner.state ?? {}) && !observed.includes(name);
|
|
6093
|
+
});
|
|
6094
|
+
}
|
|
6095
|
+
function mountedFromProps(host, state) {
|
|
6096
|
+
if (isScopeHook(state.onMount) || !drawnByCurrent(host)) {
|
|
6097
|
+
return true;
|
|
6098
|
+
}
|
|
6099
|
+
for (const inner of host.querySelectorAll("*")) {
|
|
6100
|
+
const innerState = instanceStateOf(inner);
|
|
6101
|
+
if (!innerState || !isScopeHook(innerState.onMount) && drawnByCurrent(inner)) {
|
|
6102
|
+
continue;
|
|
6103
|
+
}
|
|
6104
|
+
let owner = inner;
|
|
6105
|
+
while (owner && owner !== host && owner.dataset.jxPath === undefined) {
|
|
6106
|
+
owner = owner.parentElement;
|
|
6107
|
+
}
|
|
6108
|
+
if (owner === host) {
|
|
6109
|
+
return true;
|
|
6110
|
+
}
|
|
6111
|
+
}
|
|
6112
|
+
return false;
|
|
6113
|
+
}
|
|
6114
|
+
function updateInstanceProps(el, before, after) {
|
|
6115
|
+
const state = instanceStateOf(el);
|
|
6116
|
+
const registered = _elementDefs.get(el.localName)?.doc;
|
|
6117
|
+
if (!state || !registered) {
|
|
6118
|
+
return false;
|
|
6119
|
+
}
|
|
6120
|
+
const def = withProjectFormulas(registered);
|
|
6121
|
+
const defaults = declaredDefaults(def);
|
|
6122
|
+
const declared = def.state ?? {};
|
|
6123
|
+
const observed = _observedAttributes.get(el.localName) ?? [];
|
|
6124
|
+
const writes = [];
|
|
6125
|
+
for (const key of new Set([...Object.keys(before ?? {}), ...Object.keys(after ?? {})])) {
|
|
6126
|
+
const was = before?.[key];
|
|
6127
|
+
const now = after?.[key];
|
|
6128
|
+
if (isPrivateStateKey(key) || JSON.stringify(was) === JSON.stringify(now)) {
|
|
6129
|
+
continue;
|
|
6130
|
+
}
|
|
6131
|
+
if (was !== undefined && !isScalarProp(was) || now !== undefined && !isScalarProp(now) || producedElsewhere(declared[key]) || key in declared && !isScalarProp(toRaw(state)[key]) || key === "_state" || key === "_jxInitialized") {
|
|
6132
|
+
return false;
|
|
6133
|
+
}
|
|
6134
|
+
if (key in HTMLElement.prototype && !(VERBATIM_PROPS.has(key) && (key in declared) && isString2(now))) {
|
|
6135
|
+
return false;
|
|
6136
|
+
}
|
|
6137
|
+
if (now !== undefined) {
|
|
6138
|
+
writes.push(() => {
|
|
6139
|
+
writeInstanceProp(el, key, now);
|
|
6140
|
+
});
|
|
6141
|
+
continue;
|
|
6142
|
+
}
|
|
6143
|
+
if (!(key in declared)) {
|
|
6144
|
+
writes.push(() => {
|
|
6145
|
+
Reflect.deleteProperty(el, key);
|
|
6146
|
+
});
|
|
6147
|
+
continue;
|
|
6148
|
+
}
|
|
6149
|
+
const fallback = defaults.get(key);
|
|
6150
|
+
const attribute = key.replaceAll(/[A-Z]/gu, (c) => `-${c.toLowerCase()}`);
|
|
6151
|
+
if (!isScalarProp(fallback) || observed.includes(attribute) && el.hasAttribute(attribute)) {
|
|
6152
|
+
return false;
|
|
6153
|
+
}
|
|
6154
|
+
writes.push(() => {
|
|
6155
|
+
state[key] = fallback;
|
|
6156
|
+
});
|
|
6157
|
+
}
|
|
6158
|
+
if (writes.length === 0 || mountedFromProps(el, state) || rendersOnce(def)) {
|
|
6159
|
+
return false;
|
|
6160
|
+
}
|
|
6161
|
+
const thrown = _templateThrows;
|
|
6162
|
+
const redraws = _listRedraws;
|
|
6163
|
+
try {
|
|
6164
|
+
for (const write of writes) {
|
|
6165
|
+
write();
|
|
6166
|
+
}
|
|
6167
|
+
} catch {
|
|
6168
|
+
return false;
|
|
6169
|
+
}
|
|
6170
|
+
return _templateThrows === thrown && _listRedraws === redraws;
|
|
6171
|
+
}
|
|
5249
6172
|
function renderCustomElementWithProps(def, state, options, path) {
|
|
5250
6173
|
const el = document.createElement(resolveTagName(def.tagName, state));
|
|
5251
6174
|
if (options?.onNodeCreated) {
|
|
@@ -5256,12 +6179,7 @@ function renderCustomElementWithProps(def, state, options, path) {
|
|
|
5256
6179
|
continue;
|
|
5257
6180
|
}
|
|
5258
6181
|
const write = (resolved) => {
|
|
5259
|
-
|
|
5260
|
-
elementProperties(el)[key] = value;
|
|
5261
|
-
const instanceState = instanceStateOf(el);
|
|
5262
|
-
if (instanceState && key in HTMLElement.prototype && Object.hasOwn(toRaw(instanceState), key)) {
|
|
5263
|
-
instanceState[key] = value;
|
|
5264
|
-
}
|
|
6182
|
+
writeInstanceProp(el, key, resolved);
|
|
5265
6183
|
};
|
|
5266
6184
|
if (isRef2(val)) {
|
|
5267
6185
|
const refVal = val;
|
|
@@ -5289,6 +6207,8 @@ function renderCustomElementWithProps(def, state, options, path) {
|
|
|
5289
6207
|
const childOpts = options && path ? { ...options, _path: [...path, "children", i] } : undefined;
|
|
5290
6208
|
if (isMappedArray(child)) {
|
|
5291
6209
|
renderMappedArrayInto(el, child, state, childOpts);
|
|
6210
|
+
} else if (isString2(child) && isSingleExpression(child)) {
|
|
6211
|
+
renderTemplatedChild(el, child, state, childOpts);
|
|
5292
6212
|
} else {
|
|
5293
6213
|
el.append(renderNode(child, state, childOpts));
|
|
5294
6214
|
}
|
|
@@ -5397,6 +6317,7 @@ export {
|
|
|
5397
6317
|
SUPPORTED_SCHEMA_VERSION,
|
|
5398
6318
|
_resetPrivatePropWarnings,
|
|
5399
6319
|
applyStyle,
|
|
6320
|
+
bodyNeedsEraser,
|
|
5400
6321
|
booleanAttrValue,
|
|
5401
6322
|
buildScope,
|
|
5402
6323
|
buildStyleRules,
|
|
@@ -5410,6 +6331,7 @@ export {
|
|
|
5410
6331
|
documentStyleText,
|
|
5411
6332
|
elementDefinition,
|
|
5412
6333
|
enumeratedAttrNames,
|
|
6334
|
+
evaluateTemplateValue,
|
|
5413
6335
|
hasSchemaKeywords,
|
|
5414
6336
|
hashCss,
|
|
5415
6337
|
isDeclarationAtRule,
|
|
@@ -5422,11 +6344,13 @@ export {
|
|
|
5422
6344
|
observeScope,
|
|
5423
6345
|
preloadDocument,
|
|
5424
6346
|
preloadModule,
|
|
6347
|
+
prepareBodies,
|
|
5425
6348
|
pureSchemeOf,
|
|
5426
6349
|
reapplyStyle,
|
|
5427
6350
|
redefineElement,
|
|
5428
6351
|
releaseElementStyles,
|
|
5429
6352
|
renderNode,
|
|
6353
|
+
replaceListRow,
|
|
5430
6354
|
resetDocumentStyles,
|
|
5431
6355
|
resolve,
|
|
5432
6356
|
resolveAtQuery,
|
|
@@ -5436,13 +6360,18 @@ export {
|
|
|
5436
6360
|
resolveTagName,
|
|
5437
6361
|
runScoped,
|
|
5438
6362
|
schemeSelectors,
|
|
6363
|
+
setBodyEraser,
|
|
6364
|
+
setBodyEraserLoader,
|
|
5439
6365
|
setCanvasAssetResolver,
|
|
5440
6366
|
setCanvasDelinkAnchors,
|
|
5441
6367
|
setCanvasDelinkCommands,
|
|
5442
6368
|
setCanvasDelinkPopovers,
|
|
5443
6369
|
setCanvasViewportTranspose,
|
|
5444
6370
|
setDocumentParser,
|
|
6371
|
+
setModuleLoader,
|
|
5445
6372
|
setNpmModuleResolver,
|
|
6373
|
+
setProjectFormulas,
|
|
6374
|
+
setRemoteLookupHandler,
|
|
5446
6375
|
setResolveToken,
|
|
5447
6376
|
setRootMedia,
|
|
5448
6377
|
setSkipAutoRequests,
|
|
@@ -5454,8 +6383,9 @@ export {
|
|
|
5454
6383
|
toCSSText,
|
|
5455
6384
|
transposeCanvasOverlaySelector,
|
|
5456
6385
|
transposeCanvasPopoverSelector,
|
|
5457
|
-
transposeCanvasUnits
|
|
6386
|
+
transposeCanvasUnits,
|
|
6387
|
+
updateInstanceProps
|
|
5458
6388
|
};
|
|
5459
6389
|
|
|
5460
|
-
//# debugId=
|
|
6390
|
+
//# debugId=A3ACE1824EF1406664756E2164756E21
|
|
5461
6391
|
//# sourceMappingURL=runtime.js.map
|