@barefootjs/jsx 0.18.5 → 0.19.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/adapters/dangerous-inner-html.d.ts +77 -0
- package/dist/adapters/dangerous-inner-html.d.ts.map +1 -0
- package/dist/adapters/loop-bound-names.d.ts +22 -0
- package/dist/adapters/loop-bound-names.d.ts.map +1 -0
- package/dist/adapters/parsed-expr-emitter.d.ts.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/expression-parser.d.ts +8 -0
- package/dist/expression-parser.d.ts.map +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1002 -284
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-inner-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-loop-child-arm.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/loop-child-arm.d.ts +9 -0
- package/dist/ir-to-client-js/control-flow/plan/loop-child-arm.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts +9 -0
- package/dist/ir-to-client-js/control-flow/plan/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/shared.d.ts +45 -3
- package/dist/ir-to-client-js/control-flow/shared.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/loop-child-arm.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/loop.d.ts +1 -0
- package/dist/ir-to-client-js/control-flow/stringify/loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/reactive-effects.d.ts +10 -0
- package/dist/ir-to-client-js/control-flow/stringify/reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/skeleton-paths.d.ts +38 -0
- package/dist/ir-to-client-js/control-flow/stringify/skeleton-paths.d.ts.map +1 -0
- package/dist/ir-to-client-js/control-flow/stringify/template-parse.d.ts +19 -0
- package/dist/ir-to-client-js/control-flow/stringify/template-parse.d.ts.map +1 -1
- package/dist/ir-to-client-js/csr-substitute.d.ts +23 -0
- package/dist/ir-to-client-js/csr-substitute.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +42 -0
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/imports.d.ts +2 -2
- package/dist/ir-to-client-js/imports.d.ts.map +1 -1
- package/dist/ir-to-client-js/phases/props-extraction.d.ts +0 -1
- package/dist/ir-to-client-js/phases/props-extraction.d.ts.map +1 -1
- package/dist/ir-to-client-js/plan/static-array-child-init.d.ts +20 -1
- package/dist/ir-to-client-js/plan/static-array-child-init.d.ts.map +1 -1
- package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
- package/dist/ir-to-client-js/stringify/static-array-child-init.d.ts +1 -1
- package/dist/ir-to-client-js/types.d.ts +21 -0
- package/dist/ir-to-client-js/types.d.ts.map +1 -1
- package/dist/jsx-to-ir.d.ts.map +1 -1
- package/dist/signal-init-eval.d.ts +82 -0
- package/dist/signal-init-eval.d.ts.map +1 -0
- package/dist/static-literal.d.ts +45 -0
- package/dist/static-literal.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +19 -13
- package/src/__tests__/client-js-generation.test.ts +40 -0
- package/src/__tests__/create-selector.test.ts +110 -0
- package/src/__tests__/csr-template-loop-shadowing.test.ts +214 -0
- package/src/__tests__/dangerous-inner-html-resolver.test.ts +197 -0
- package/src/__tests__/inner-loop-svg-namespace.test.ts +245 -0
- package/src/__tests__/loop-bound-names.test.ts +102 -0
- package/src/__tests__/loop-plan-classification.test.ts +2 -0
- package/src/__tests__/map-function-reference.test.ts +303 -0
- package/src/__tests__/nested-loop-index-param.test.ts +285 -0
- package/src/__tests__/props-destructuring.test.ts +61 -8
- package/src/__tests__/signal-init-eval.test.ts +138 -0
- package/src/__tests__/static-array-inner-loop-index-param.test.ts +180 -0
- package/src/__tests__/static-literal.test.ts +126 -0
- package/src/__tests__/string-concat-identifier.test.ts +55 -0
- package/src/adapters/dangerous-inner-html.ts +186 -0
- package/src/adapters/loop-bound-names.ts +80 -0
- package/src/adapters/parsed-expr-emitter.ts +9 -0
- package/src/analyzer.ts +36 -22
- package/src/expression-parser.ts +33 -0
- package/src/index.ts +20 -3
- package/src/ir-to-client-js/collect-elements.ts +15 -3
- package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +21 -4
- package/src/ir-to-client-js/control-flow/plan/build-loop-child-arm.ts +13 -1
- package/src/ir-to-client-js/control-flow/plan/build-loop.ts +1 -0
- package/src/ir-to-client-js/control-flow/plan/loop-child-arm.ts +9 -0
- package/src/ir-to-client-js/control-flow/plan/loop.ts +9 -0
- package/src/ir-to-client-js/control-flow/shared.ts +103 -6
- package/src/ir-to-client-js/control-flow/stringify/inner-loop.ts +11 -2
- package/src/ir-to-client-js/control-flow/stringify/loop-child-arm.ts +5 -0
- package/src/ir-to-client-js/control-flow/stringify/loop.ts +53 -10
- package/src/ir-to-client-js/control-flow/stringify/reactive-effects.ts +25 -4
- package/src/ir-to-client-js/control-flow/stringify/skeleton-paths.ts +70 -0
- package/src/ir-to-client-js/control-flow/stringify/template-parse.ts +25 -1
- package/src/ir-to-client-js/csr-substitute.ts +53 -0
- package/src/ir-to-client-js/html-template.ts +235 -2
- package/src/ir-to-client-js/imports.ts +1 -0
- package/src/ir-to-client-js/phases/props-extraction.ts +5 -9
- package/src/ir-to-client-js/plan/build-static-array-child-init.ts +12 -1
- package/src/ir-to-client-js/plan/static-array-child-init.ts +20 -1
- package/src/ir-to-client-js/reactivity.ts +6 -0
- package/src/ir-to-client-js/stringify/static-array-child-init.ts +11 -6
- package/src/ir-to-client-js/types.ts +21 -0
- package/src/jsx-to-ir.ts +230 -39
- package/src/signal-init-eval.ts +165 -0
- package/src/static-literal.ts +128 -0
package/dist/index.js
CHANGED
|
@@ -197,6 +197,24 @@ import ts8 from "typescript";
|
|
|
197
197
|
|
|
198
198
|
// src/expression-parser.ts
|
|
199
199
|
import ts2 from "typescript";
|
|
200
|
+
var PARSED_EXPR_KINDS = [
|
|
201
|
+
"identifier",
|
|
202
|
+
"literal",
|
|
203
|
+
"call",
|
|
204
|
+
"member",
|
|
205
|
+
"index-access",
|
|
206
|
+
"binary",
|
|
207
|
+
"unary",
|
|
208
|
+
"conditional",
|
|
209
|
+
"logical",
|
|
210
|
+
"template-literal",
|
|
211
|
+
"arrow",
|
|
212
|
+
"regex",
|
|
213
|
+
"array-literal",
|
|
214
|
+
"object-literal",
|
|
215
|
+
"array-method",
|
|
216
|
+
"unsupported"
|
|
217
|
+
];
|
|
200
218
|
var UNSUPPORTED_METHODS = new Set([
|
|
201
219
|
"filter",
|
|
202
220
|
"map",
|
|
@@ -2942,6 +2960,29 @@ function extractFreeIdentifiersFromText(text) {
|
|
|
2942
2960
|
const expr = ts4.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
|
|
2943
2961
|
return extractFreeIdentifiersFromNode(expr);
|
|
2944
2962
|
}
|
|
2963
|
+
function extractFreeIdentifiersFromStatementText(text) {
|
|
2964
|
+
if (!text || text.trim().length === 0)
|
|
2965
|
+
return new Set;
|
|
2966
|
+
const sf = ts4.createSourceFile("__free_ids_stmt__.ts", text, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TS);
|
|
2967
|
+
return extractFreeIdentifiersFromNode(sf);
|
|
2968
|
+
}
|
|
2969
|
+
function extractFreeIdentifiersFromTemplateText(template) {
|
|
2970
|
+
if (!template || template.length === 0)
|
|
2971
|
+
return new Set;
|
|
2972
|
+
const sf = ts4.createSourceFile("__free_ids_template__.ts", `(\`${template}\`);`, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TS);
|
|
2973
|
+
const stmt = sf.statements[0];
|
|
2974
|
+
if (!stmt || !ts4.isExpressionStatement(stmt))
|
|
2975
|
+
return new Set;
|
|
2976
|
+
const expr = ts4.isParenthesizedExpression(stmt.expression) ? stmt.expression.expression : stmt.expression;
|
|
2977
|
+
if (!ts4.isTemplateExpression(expr))
|
|
2978
|
+
return new Set;
|
|
2979
|
+
const ids = new Set;
|
|
2980
|
+
for (const span of expr.templateSpans) {
|
|
2981
|
+
for (const id of extractFreeIdentifiersFromNode(span.expression))
|
|
2982
|
+
ids.add(id);
|
|
2983
|
+
}
|
|
2984
|
+
return ids;
|
|
2985
|
+
}
|
|
2945
2986
|
function extractMemoBodyExpr(computation) {
|
|
2946
2987
|
const arrowMatch = computation.match(/^\(\)\s*=>\s*(.+)$/s);
|
|
2947
2988
|
if (!arrowMatch)
|
|
@@ -3470,6 +3511,133 @@ function buildLoopSkeletonTemplate(node, safe) {
|
|
|
3470
3511
|
return assertNever(node);
|
|
3471
3512
|
}
|
|
3472
3513
|
}
|
|
3514
|
+
var SKELETON_PATH_HAZARD_TAGS = new Set([
|
|
3515
|
+
"table",
|
|
3516
|
+
"thead",
|
|
3517
|
+
"tbody",
|
|
3518
|
+
"tfoot",
|
|
3519
|
+
"caption",
|
|
3520
|
+
"colgroup",
|
|
3521
|
+
"col",
|
|
3522
|
+
"select",
|
|
3523
|
+
"optgroup",
|
|
3524
|
+
"p",
|
|
3525
|
+
"pre",
|
|
3526
|
+
"textarea",
|
|
3527
|
+
"listing",
|
|
3528
|
+
"template",
|
|
3529
|
+
"math"
|
|
3530
|
+
]);
|
|
3531
|
+
var SKELETON_PATH_FORCE_CLOSE_GROUPS = [
|
|
3532
|
+
new Set(["a"]),
|
|
3533
|
+
new Set(["button"]),
|
|
3534
|
+
new Set(["form"]),
|
|
3535
|
+
new Set(["option"]),
|
|
3536
|
+
new Set(["h1", "h2", "h3", "h4", "h5", "h6"]),
|
|
3537
|
+
new Set(["dd", "dt"]),
|
|
3538
|
+
new Set(["li"])
|
|
3539
|
+
];
|
|
3540
|
+
function skeletonForceCloseGroup(tag) {
|
|
3541
|
+
return SKELETON_PATH_FORCE_CLOSE_GROUPS.findIndex((group) => group.has(tag));
|
|
3542
|
+
}
|
|
3543
|
+
function computeSkeletonSlotPaths(node, safe) {
|
|
3544
|
+
const state = { elementPaths: new Map, textMarkerPaths: new Map, bailed: false };
|
|
3545
|
+
walkSkeletonPathNode(node, [], safe, state, new Set);
|
|
3546
|
+
if (state.bailed)
|
|
3547
|
+
return null;
|
|
3548
|
+
return { elementPaths: state.elementPaths, textMarkerPaths: state.textMarkerPaths };
|
|
3549
|
+
}
|
|
3550
|
+
function walkSkeletonPathNode(node, path, safe, state, forceCloseAncestors) {
|
|
3551
|
+
if (state.bailed || node.type !== "element")
|
|
3552
|
+
return;
|
|
3553
|
+
if (SKELETON_PATH_HAZARD_TAGS.has(node.tag)) {
|
|
3554
|
+
state.bailed = true;
|
|
3555
|
+
return;
|
|
3556
|
+
}
|
|
3557
|
+
const groupIdx = skeletonForceCloseGroup(node.tag);
|
|
3558
|
+
if (groupIdx >= 0 && forceCloseAncestors.has(groupIdx)) {
|
|
3559
|
+
state.bailed = true;
|
|
3560
|
+
return;
|
|
3561
|
+
}
|
|
3562
|
+
const flatChildren = flattenSkeletonChildren(node.children);
|
|
3563
|
+
if (VOID_ELEMENTS.has(node.tag) && flatChildren.length > 0) {
|
|
3564
|
+
state.bailed = true;
|
|
3565
|
+
return;
|
|
3566
|
+
}
|
|
3567
|
+
if (node.tag === "tr" && hasForeignTableRowContent(flatChildren)) {
|
|
3568
|
+
state.bailed = true;
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3571
|
+
if (node.slotId)
|
|
3572
|
+
state.elementPaths.set(node.slotId, path);
|
|
3573
|
+
const nextAncestors = groupIdx >= 0 ? new Set([...forceCloseAncestors, groupIdx]) : forceCloseAncestors;
|
|
3574
|
+
walkSkeletonPathChildren(flatChildren, path, safe, state, nextAncestors);
|
|
3575
|
+
}
|
|
3576
|
+
function hasForeignTableRowContent(children) {
|
|
3577
|
+
for (const child of children) {
|
|
3578
|
+
if (child.type === "text") {
|
|
3579
|
+
if (child.value.trim() !== "")
|
|
3580
|
+
return true;
|
|
3581
|
+
continue;
|
|
3582
|
+
}
|
|
3583
|
+
if (child.type === "element" && child.tag !== "td" && child.tag !== "th") {
|
|
3584
|
+
return true;
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
return false;
|
|
3588
|
+
}
|
|
3589
|
+
function flattenSkeletonChildren(children) {
|
|
3590
|
+
const out = [];
|
|
3591
|
+
for (const child of children) {
|
|
3592
|
+
if (child.type === "fragment") {
|
|
3593
|
+
out.push(...flattenSkeletonChildren(child.children));
|
|
3594
|
+
} else {
|
|
3595
|
+
out.push(child);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
return out;
|
|
3599
|
+
}
|
|
3600
|
+
function walkSkeletonPathChildren(children, parentPath, safe, state, forceCloseAncestors) {
|
|
3601
|
+
let idx = 0;
|
|
3602
|
+
let pendingText = false;
|
|
3603
|
+
for (const child of children) {
|
|
3604
|
+
if (state.bailed)
|
|
3605
|
+
return;
|
|
3606
|
+
switch (child.type) {
|
|
3607
|
+
case "text": {
|
|
3608
|
+
if (child.value === "")
|
|
3609
|
+
continue;
|
|
3610
|
+
if (!pendingText)
|
|
3611
|
+
idx += 1;
|
|
3612
|
+
pendingText = true;
|
|
3613
|
+
continue;
|
|
3614
|
+
}
|
|
3615
|
+
case "expression": {
|
|
3616
|
+
if (child.expr === "null" || child.expr === "undefined")
|
|
3617
|
+
continue;
|
|
3618
|
+
if (!child.slotId || !safe.reactiveTextSlotIds.has(child.slotId)) {
|
|
3619
|
+
state.bailed = true;
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
state.textMarkerPaths.set(child.slotId, [...parentPath, idx]);
|
|
3623
|
+
idx += 2;
|
|
3624
|
+
pendingText = false;
|
|
3625
|
+
continue;
|
|
3626
|
+
}
|
|
3627
|
+
case "element": {
|
|
3628
|
+
walkSkeletonPathNode(child, [...parentPath, idx], safe, state, forceCloseAncestors);
|
|
3629
|
+
idx += 1;
|
|
3630
|
+
pendingText = false;
|
|
3631
|
+
continue;
|
|
3632
|
+
}
|
|
3633
|
+
case "fragment":
|
|
3634
|
+
continue;
|
|
3635
|
+
default:
|
|
3636
|
+
state.bailed = true;
|
|
3637
|
+
return;
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3473
3641
|
function irToPlaceholderTemplate(node, restSpreadNames, loopDepth = 0, loopParams) {
|
|
3474
3642
|
const recurse = (n) => irToPlaceholderTemplate(n, restSpreadNames, loopDepth, loopParams);
|
|
3475
3643
|
const wrapExpr = (expr) => wrapExprWithLoopParams(expr, loopParams);
|
|
@@ -4112,7 +4280,28 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4112
4280
|
return `\${renderChild('${nameForRegistryRef(node.name)}', ${propsExpr}${keyArg || (slotArg ? ", undefined" : "")}${slotArg})}`;
|
|
4113
4281
|
}
|
|
4114
4282
|
case "loop": {
|
|
4115
|
-
|
|
4283
|
+
const boundHere = new Set(opts.loopBoundNames ?? []);
|
|
4284
|
+
if (node.paramBindings && node.paramBindings.length > 0) {
|
|
4285
|
+
for (const b of node.paramBindings)
|
|
4286
|
+
boundHere.add(b.name);
|
|
4287
|
+
} else if (!node.param.startsWith("[") && !node.param.startsWith("{")) {
|
|
4288
|
+
boundHere.add(node.param);
|
|
4289
|
+
}
|
|
4290
|
+
if (node.index)
|
|
4291
|
+
boundHere.add(node.index);
|
|
4292
|
+
const childEnv = {
|
|
4293
|
+
...env,
|
|
4294
|
+
substitutions: new Map([...env.substitutions].filter(([name]) => !boundHere.has(name)))
|
|
4295
|
+
};
|
|
4296
|
+
const recurseInLoopBody = (n) => generateCsrTemplateWithOpts(n, {
|
|
4297
|
+
...opts,
|
|
4298
|
+
insideLoop: true,
|
|
4299
|
+
loopDepth: loopDepth + 1,
|
|
4300
|
+
inHoistedChildren: false,
|
|
4301
|
+
loopBoundNames: boundHere,
|
|
4302
|
+
csrEnv: childEnv
|
|
4303
|
+
});
|
|
4304
|
+
let childTemplate = node.children.map(recurseInLoopBody).join("");
|
|
4116
4305
|
if (node.bodyIsItemConditional && node.key) {
|
|
4117
4306
|
childTemplate = `${itemAnchorTemplate(node.key)}${childTemplate}`;
|
|
4118
4307
|
}
|
|
@@ -4126,7 +4315,7 @@ function generateCsrTemplateWithOpts(node, opts) {
|
|
|
4126
4315
|
if (node.flatMapCallback) {
|
|
4127
4316
|
let body = node.flatMapCallback.templateBody ?? node.flatMapCallback.body;
|
|
4128
4317
|
for (const frag of node.flatMapCallback.fragments) {
|
|
4129
|
-
const renderedIr =
|
|
4318
|
+
const renderedIr = recurseInLoopBody(frag.ir);
|
|
4130
4319
|
body = body.replace(frag.placeholder, `\`${renderedIr}\``);
|
|
4131
4320
|
}
|
|
4132
4321
|
body = applyPropsRewrite(body, propsObjectName ?? null);
|
|
@@ -5086,6 +5275,8 @@ function needsTypeBasedDetection(source) {
|
|
|
5086
5275
|
return true;
|
|
5087
5276
|
if (/\.map\s*\(/.test(source))
|
|
5088
5277
|
return true;
|
|
5278
|
+
if (source.includes("createSelector"))
|
|
5279
|
+
return true;
|
|
5089
5280
|
return false;
|
|
5090
5281
|
}
|
|
5091
5282
|
function findBrandPackageImportLoc(sourceFile, filePath) {
|
|
@@ -6062,6 +6253,7 @@ var CLIENT_EXPORTS = new Set([
|
|
|
6062
6253
|
"createEffect",
|
|
6063
6254
|
"createDisposableEffect",
|
|
6064
6255
|
"createMemo",
|
|
6256
|
+
"createSelector",
|
|
6065
6257
|
"createRoot",
|
|
6066
6258
|
"onCleanup",
|
|
6067
6259
|
"onMount",
|
|
@@ -6845,12 +7037,13 @@ function extractProps(param, ctx) {
|
|
|
6845
7037
|
continue;
|
|
6846
7038
|
}
|
|
6847
7039
|
const sourcePropName = element.propertyName && ts8.isIdentifier(element.propertyName) ? element.propertyName.text : localName;
|
|
6848
|
-
const
|
|
7040
|
+
const member = memberTypes?.get(sourcePropName);
|
|
7041
|
+
const resolvedType = member?.type ?? { kind: "unknown", raw: "unknown" };
|
|
6849
7042
|
const defaultContainsArrow = element.initializer ? nodeContainsArrow(element.initializer) : false;
|
|
6850
7043
|
ctx.propsParams.push({
|
|
6851
7044
|
name: localName,
|
|
6852
7045
|
type: resolvedType,
|
|
6853
|
-
optional: !!element.initializer,
|
|
7046
|
+
optional: !!member?.optional || !!element.initializer,
|
|
6854
7047
|
defaultValue,
|
|
6855
7048
|
defaultContainsArrow: defaultContainsArrow || undefined
|
|
6856
7049
|
});
|
|
@@ -6915,11 +7108,12 @@ function collectMemberTypes(typeNode, ctx) {
|
|
|
6915
7108
|
const fromMembers = (members) => {
|
|
6916
7109
|
const map = new Map;
|
|
6917
7110
|
for (const member of members) {
|
|
6918
|
-
if (ts8.isPropertySignature(member) && member.name
|
|
6919
|
-
const info = typeNodeToTypeInfo(member.type, ctx.sourceFile);
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
7111
|
+
if (ts8.isPropertySignature(member) && member.name) {
|
|
7112
|
+
const info = member.type ? typeNodeToTypeInfo(member.type, ctx.sourceFile) : null;
|
|
7113
|
+
map.set(member.name.getText(ctx.sourceFile), {
|
|
7114
|
+
type: info && isResolvablePrimitive(info) ? info : null,
|
|
7115
|
+
optional: !!member.questionToken
|
|
7116
|
+
});
|
|
6923
7117
|
}
|
|
6924
7118
|
}
|
|
6925
7119
|
return map;
|
|
@@ -8148,9 +8342,15 @@ function exprHasFunctionCalls(expr) {
|
|
|
8148
8342
|
return found;
|
|
8149
8343
|
}
|
|
8150
8344
|
function rewriteBarePropRefs2(text, expr, ctx) {
|
|
8151
|
-
|
|
8345
|
+
let propNames = getDestructuredPropNames(ctx);
|
|
8152
8346
|
if (!propNames)
|
|
8153
8347
|
return;
|
|
8348
|
+
if (ctx.loopParams.size > 0) {
|
|
8349
|
+
const filtered = new Set([...propNames].filter((n) => !ctx.loopParams.has(n)));
|
|
8350
|
+
if (filtered.size === 0)
|
|
8351
|
+
return;
|
|
8352
|
+
propNames = filtered;
|
|
8353
|
+
}
|
|
8154
8354
|
const extraPropRefs = collectBranchLocalPropRefsViaSubstitution(expr, ctx);
|
|
8155
8355
|
return rewriteBarePropRefs(text, expr, propNames, extraPropRefs);
|
|
8156
8356
|
}
|
|
@@ -8316,26 +8516,29 @@ function makeBindingEnv(ctx) {
|
|
|
8316
8516
|
function parseValueExpr(trimmed) {
|
|
8317
8517
|
return parseExpression(trimmed.startsWith("{") ? `(${trimmed})` : trimmed);
|
|
8318
8518
|
}
|
|
8319
|
-
|
|
8519
|
+
var EMPTY_BOUND = new Set;
|
|
8520
|
+
function attachParsedExpressions(node, analyzer, bound = EMPTY_BOUND) {
|
|
8521
|
+
const parse2 = (trimmed) => resolveCallbackMethodFunctionReferences(parseExpression(trimmed), analyzer, bound);
|
|
8522
|
+
const parseValue = (trimmed) => resolveCallbackMethodFunctionReferences(parseValueExpr(trimmed), analyzer, bound);
|
|
8320
8523
|
if (node.type === "expression") {
|
|
8321
8524
|
const trimmed = node.expr.trim();
|
|
8322
8525
|
if (trimmed)
|
|
8323
|
-
node.parsed =
|
|
8526
|
+
node.parsed = parse2(trimmed);
|
|
8324
8527
|
} else if (node.type === "conditional" || node.type === "if-statement") {
|
|
8325
8528
|
const trimmed = node.condition.trim();
|
|
8326
8529
|
if (trimmed)
|
|
8327
|
-
node.parsedCondition =
|
|
8530
|
+
node.parsedCondition = parse2(trimmed);
|
|
8328
8531
|
}
|
|
8329
8532
|
if (node.type === "element") {
|
|
8330
8533
|
for (const attr of node.attrs) {
|
|
8331
8534
|
if (attr.value.kind === "expression") {
|
|
8332
8535
|
const trimmed = attr.value.expr.trim();
|
|
8333
8536
|
if (trimmed)
|
|
8334
|
-
attr.value.parsed =
|
|
8537
|
+
attr.value.parsed = parseValue(trimmed);
|
|
8335
8538
|
} else if (attr.value.kind === "spread") {
|
|
8336
8539
|
const trimmed = attr.value.expr.trim();
|
|
8337
8540
|
if (trimmed)
|
|
8338
|
-
attr.value.parsed =
|
|
8541
|
+
attr.value.parsed = parse2(trimmed);
|
|
8339
8542
|
}
|
|
8340
8543
|
}
|
|
8341
8544
|
} else if (node.type === "component") {
|
|
@@ -8343,14 +8546,14 @@ function attachParsedExpressions(node) {
|
|
|
8343
8546
|
if (prop.value.kind === "expression") {
|
|
8344
8547
|
const trimmed = prop.value.expr.trim();
|
|
8345
8548
|
if (trimmed)
|
|
8346
|
-
prop.value.parsed =
|
|
8549
|
+
prop.value.parsed = parseValue(trimmed);
|
|
8347
8550
|
}
|
|
8348
8551
|
}
|
|
8349
8552
|
} else if (node.type === "provider") {
|
|
8350
8553
|
if (node.valueProp.value.kind === "expression") {
|
|
8351
8554
|
const trimmed = node.valueProp.value.expr.trim();
|
|
8352
8555
|
if (trimmed)
|
|
8353
|
-
node.valueProp.value.parsed =
|
|
8556
|
+
node.valueProp.value.parsed = parseValue(trimmed);
|
|
8354
8557
|
}
|
|
8355
8558
|
}
|
|
8356
8559
|
switch (node.type) {
|
|
@@ -8359,47 +8562,51 @@ function attachParsedExpressions(node) {
|
|
|
8359
8562
|
case "fragment":
|
|
8360
8563
|
case "provider":
|
|
8361
8564
|
for (const child of node.children)
|
|
8362
|
-
attachParsedExpressions(child);
|
|
8565
|
+
attachParsedExpressions(child, analyzer, bound);
|
|
8363
8566
|
break;
|
|
8364
8567
|
case "async":
|
|
8365
|
-
attachParsedExpressions(node.fallback);
|
|
8568
|
+
attachParsedExpressions(node.fallback, analyzer, bound);
|
|
8366
8569
|
for (const child of node.children)
|
|
8367
|
-
attachParsedExpressions(child);
|
|
8570
|
+
attachParsedExpressions(child, analyzer, bound);
|
|
8368
8571
|
break;
|
|
8369
8572
|
case "loop": {
|
|
8370
8573
|
const trimmedArray = node.array.trim();
|
|
8371
8574
|
if (trimmedArray)
|
|
8372
|
-
node.arrayParsed =
|
|
8575
|
+
node.arrayParsed = parse2(trimmedArray);
|
|
8576
|
+
const loopBound = new Set(bound);
|
|
8577
|
+
loopBound.add(node.param);
|
|
8578
|
+
if (node.index)
|
|
8579
|
+
loopBound.add(node.index);
|
|
8373
8580
|
for (const child of node.children)
|
|
8374
|
-
attachParsedExpressions(child);
|
|
8581
|
+
attachParsedExpressions(child, analyzer, loopBound);
|
|
8375
8582
|
if (node.childComponent) {
|
|
8376
8583
|
for (const child of node.childComponent.children)
|
|
8377
|
-
attachParsedExpressions(child);
|
|
8584
|
+
attachParsedExpressions(child, analyzer, loopBound);
|
|
8378
8585
|
}
|
|
8379
8586
|
for (const nested of node.nestedComponents ?? []) {
|
|
8380
8587
|
for (const child of nested.children)
|
|
8381
|
-
attachParsedExpressions(child);
|
|
8588
|
+
attachParsedExpressions(child, analyzer, loopBound);
|
|
8382
8589
|
}
|
|
8383
8590
|
for (const frag of node.flatMapCallback?.fragments ?? []) {
|
|
8384
|
-
attachParsedExpressions(frag.ir);
|
|
8591
|
+
attachParsedExpressions(frag.ir, analyzer, loopBound);
|
|
8385
8592
|
}
|
|
8386
8593
|
break;
|
|
8387
8594
|
}
|
|
8388
8595
|
case "conditional":
|
|
8389
|
-
attachParsedExpressions(node.whenTrue);
|
|
8390
|
-
attachParsedExpressions(node.whenFalse);
|
|
8596
|
+
attachParsedExpressions(node.whenTrue, analyzer, bound);
|
|
8597
|
+
attachParsedExpressions(node.whenFalse, analyzer, bound);
|
|
8391
8598
|
break;
|
|
8392
8599
|
case "if-statement":
|
|
8393
|
-
attachParsedExpressions(node.consequent);
|
|
8600
|
+
attachParsedExpressions(node.consequent, analyzer, bound);
|
|
8394
8601
|
if (node.alternate)
|
|
8395
|
-
attachParsedExpressions(node.alternate);
|
|
8602
|
+
attachParsedExpressions(node.alternate, analyzer, bound);
|
|
8396
8603
|
break;
|
|
8397
8604
|
}
|
|
8398
8605
|
}
|
|
8399
8606
|
function jsxToIR(analyzer) {
|
|
8400
8607
|
const root = buildIRRoot(analyzer);
|
|
8401
8608
|
if (root)
|
|
8402
|
-
attachParsedExpressions(root);
|
|
8609
|
+
attachParsedExpressions(root, analyzer);
|
|
8403
8610
|
return root;
|
|
8404
8611
|
}
|
|
8405
8612
|
function buildIRRoot(analyzer) {
|
|
@@ -9486,8 +9693,8 @@ function extractSortComparator(callback, _method, ctx) {
|
|
|
9486
9693
|
};
|
|
9487
9694
|
}
|
|
9488
9695
|
function resolveSortComparatorIdentifier(name, ctx) {
|
|
9489
|
-
const constInfo = findLocalConst(name, ctx);
|
|
9490
|
-
const fnInfo = findLocalFunction(name, ctx);
|
|
9696
|
+
const constInfo = findLocalConst(name, ctx.analyzer);
|
|
9697
|
+
const fnInfo = findLocalFunction(name, ctx.analyzer);
|
|
9491
9698
|
if (constInfo && fnInfo)
|
|
9492
9699
|
return null;
|
|
9493
9700
|
if (constInfo) {
|
|
@@ -9500,6 +9707,72 @@ function resolveSortComparatorIdentifier(name, ctx) {
|
|
|
9500
9707
|
}
|
|
9501
9708
|
return null;
|
|
9502
9709
|
}
|
|
9710
|
+
function resolveCallbackMethodFunctionReferenceIdentifier(name, analyzer) {
|
|
9711
|
+
const constInfo = findLocalConst(name, analyzer);
|
|
9712
|
+
const fnInfo = findLocalFunction(name, analyzer);
|
|
9713
|
+
if (constInfo && fnInfo)
|
|
9714
|
+
return null;
|
|
9715
|
+
if (constInfo) {
|
|
9716
|
+
const ast = parseConstInitializer(constInfo);
|
|
9717
|
+
return ast && (ts11.isArrowFunction(ast) || ts11.isFunctionExpression(ast)) ? ast : null;
|
|
9718
|
+
}
|
|
9719
|
+
if (fnInfo) {
|
|
9720
|
+
const ast = parseFunctionInfoAsExpr(fnInfo);
|
|
9721
|
+
return ast && (ts11.isArrowFunction(ast) || ts11.isFunctionExpression(ast)) ? ast : null;
|
|
9722
|
+
}
|
|
9723
|
+
return null;
|
|
9724
|
+
}
|
|
9725
|
+
function resolveCallbackMethodFunctionReferences(expr, analyzer, bound = EMPTY_BOUND) {
|
|
9726
|
+
function visit2(e, bound2) {
|
|
9727
|
+
switch (e.kind) {
|
|
9728
|
+
case "literal":
|
|
9729
|
+
case "identifier":
|
|
9730
|
+
case "regex":
|
|
9731
|
+
case "unsupported":
|
|
9732
|
+
return e;
|
|
9733
|
+
case "call": {
|
|
9734
|
+
const callee = visit2(e.callee, bound2);
|
|
9735
|
+
const args = e.args.map((a) => visit2(a, bound2));
|
|
9736
|
+
if (callee.kind === "member" && !callee.computed && CALLBACK_METHODS.has(callee.property) && args[0]?.kind === "identifier" && !bound2.has(args[0].name)) {
|
|
9737
|
+
const resolved = resolveCallbackMethodFunctionReferenceIdentifier(args[0].name, analyzer);
|
|
9738
|
+
const arrow = resolved ? tsNodeToParsedExpr(resolved) : null;
|
|
9739
|
+
if (arrow && arrow.kind === "arrow")
|
|
9740
|
+
args[0] = arrow;
|
|
9741
|
+
}
|
|
9742
|
+
return { ...e, callee, args };
|
|
9743
|
+
}
|
|
9744
|
+
case "member":
|
|
9745
|
+
return { ...e, object: visit2(e.object, bound2) };
|
|
9746
|
+
case "index-access":
|
|
9747
|
+
return { ...e, object: visit2(e.object, bound2), index: visit2(e.index, bound2) };
|
|
9748
|
+
case "binary":
|
|
9749
|
+
case "logical":
|
|
9750
|
+
return { ...e, left: visit2(e.left, bound2), right: visit2(e.right, bound2) };
|
|
9751
|
+
case "unary":
|
|
9752
|
+
return { ...e, argument: visit2(e.argument, bound2) };
|
|
9753
|
+
case "conditional":
|
|
9754
|
+
return { ...e, test: visit2(e.test, bound2), consequent: visit2(e.consequent, bound2), alternate: visit2(e.alternate, bound2) };
|
|
9755
|
+
case "template-literal":
|
|
9756
|
+
return { ...e, parts: e.parts.map((p) => p.type === "expression" ? { ...p, expr: visit2(p.expr, bound2) } : p) };
|
|
9757
|
+
case "array-literal":
|
|
9758
|
+
return { ...e, elements: e.elements.map((el) => visit2(el, bound2)) };
|
|
9759
|
+
case "array-method":
|
|
9760
|
+
return {
|
|
9761
|
+
...e,
|
|
9762
|
+
object: visit2(e.object, bound2),
|
|
9763
|
+
args: e.args.map((a) => visit2(a, bound2)),
|
|
9764
|
+
...e.method === "flat" && e.depthExpr ? { depthExpr: visit2(e.depthExpr, bound2) } : {}
|
|
9765
|
+
};
|
|
9766
|
+
case "object-literal":
|
|
9767
|
+
return { ...e, properties: e.properties.map((p) => ({ ...p, value: visit2(p.value, bound2) })) };
|
|
9768
|
+
case "arrow": {
|
|
9769
|
+
const inner = e.params.length === 0 ? bound2 : new Set([...bound2, ...e.params]);
|
|
9770
|
+
return { ...e, body: visit2(e.body, inner) };
|
|
9771
|
+
}
|
|
9772
|
+
}
|
|
9773
|
+
}
|
|
9774
|
+
return visit2(expr, bound);
|
|
9775
|
+
}
|
|
9503
9776
|
function extractFilterPredicate(callback, ctx) {
|
|
9504
9777
|
if (!ts11.isArrowFunction(callback))
|
|
9505
9778
|
return { result: null };
|
|
@@ -9967,13 +10240,11 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
9967
10240
|
setArray(innerSort.array);
|
|
9968
10241
|
}
|
|
9969
10242
|
} else {
|
|
9970
|
-
|
|
9971
|
-
arrayExpr = filterInfo.array;
|
|
10243
|
+
setArray(filterInfo.array);
|
|
9972
10244
|
}
|
|
9973
10245
|
}
|
|
9974
10246
|
} else {
|
|
9975
|
-
|
|
9976
|
-
arrayExpr = chainSource;
|
|
10247
|
+
setArray(chainSource);
|
|
9977
10248
|
}
|
|
9978
10249
|
const callback = node.arguments[0];
|
|
9979
10250
|
let param = "item";
|
|
@@ -10523,7 +10794,7 @@ function parseTemplateLiteral(expr, ctx) {
|
|
|
10523
10794
|
}
|
|
10524
10795
|
function tryResolveTemplateSpanFromConst(expr, ctx) {
|
|
10525
10796
|
if (ts11.isIdentifier(expr)) {
|
|
10526
|
-
const constInfo = findLocalConst(expr.text, ctx);
|
|
10797
|
+
const constInfo = findLocalConst(expr.text, ctx.analyzer);
|
|
10527
10798
|
if (!constInfo)
|
|
10528
10799
|
return null;
|
|
10529
10800
|
const ast = parseConstInitializer(constInfo);
|
|
@@ -10537,7 +10808,7 @@ function tryResolveTemplateSpanFromConst(expr, ctx) {
|
|
|
10537
10808
|
if (ts11.isElementAccessExpression(expr)) {
|
|
10538
10809
|
if (!ts11.isIdentifier(expr.expression))
|
|
10539
10810
|
return null;
|
|
10540
|
-
const constInfo = findLocalConst(expr.expression.text, ctx);
|
|
10811
|
+
const constInfo = findLocalConst(expr.expression.text, ctx.analyzer);
|
|
10541
10812
|
if (!constInfo)
|
|
10542
10813
|
return null;
|
|
10543
10814
|
const ast = parseConstInitializer(constInfo);
|
|
@@ -10563,16 +10834,16 @@ function tryResolveTemplateSpanFromConst(expr, ctx) {
|
|
|
10563
10834
|
}
|
|
10564
10835
|
return null;
|
|
10565
10836
|
}
|
|
10566
|
-
function findLocalConst(name,
|
|
10567
|
-
const matches =
|
|
10837
|
+
function findLocalConst(name, analyzer) {
|
|
10838
|
+
const matches = analyzer.localConstants.filter((c) => c.name === name);
|
|
10568
10839
|
if (matches.length === 0)
|
|
10569
10840
|
return;
|
|
10570
10841
|
const fnScoped = matches.filter((c) => !c.isModule);
|
|
10571
10842
|
const pool = fnScoped.length > 0 ? fnScoped : matches;
|
|
10572
10843
|
return pool[pool.length - 1];
|
|
10573
10844
|
}
|
|
10574
|
-
function findLocalFunction(name,
|
|
10575
|
-
const matches =
|
|
10845
|
+
function findLocalFunction(name, analyzer) {
|
|
10846
|
+
const matches = analyzer.localFunctions.filter((f) => f.name === name);
|
|
10576
10847
|
if (matches.length === 0)
|
|
10577
10848
|
return;
|
|
10578
10849
|
const fnScoped = matches.filter((f) => !f.isModule);
|
|
@@ -10614,7 +10885,9 @@ function hasDynamicTagBinding(name, sourceFile) {
|
|
|
10614
10885
|
return found;
|
|
10615
10886
|
}
|
|
10616
10887
|
function tryResolveIdentifierAsTemplateLiteral(ident, ctx) {
|
|
10617
|
-
|
|
10888
|
+
if (ctx.loopParams.has(ident.text))
|
|
10889
|
+
return null;
|
|
10890
|
+
const constInfo = findLocalConst(ident.text, ctx.analyzer);
|
|
10618
10891
|
if (!constInfo)
|
|
10619
10892
|
return null;
|
|
10620
10893
|
const ast = parseConstInitializer(constInfo);
|
|
@@ -10711,8 +10984,8 @@ function tryDesugarInterleaveTaggedTemplate(expr, ctx) {
|
|
|
10711
10984
|
return rewritten ?? expr;
|
|
10712
10985
|
}
|
|
10713
10986
|
function resolveInterleaveTagIdentifier(name, ctx) {
|
|
10714
|
-
const constInfo = findLocalConst(name, ctx);
|
|
10715
|
-
const fnInfo = findLocalFunction(name, ctx);
|
|
10987
|
+
const constInfo = findLocalConst(name, ctx.analyzer);
|
|
10988
|
+
const fnInfo = findLocalFunction(name, ctx.analyzer);
|
|
10716
10989
|
if (constInfo && fnInfo)
|
|
10717
10990
|
return null;
|
|
10718
10991
|
if (constInfo) {
|
|
@@ -11466,6 +11739,7 @@ function collectLoopChildEventsWithNesting(node, initialNestingStack = []) {
|
|
|
11466
11739
|
depth: scope.nestingStack.length + 1,
|
|
11467
11740
|
array: l.array,
|
|
11468
11741
|
param: l.param,
|
|
11742
|
+
index: l.index,
|
|
11469
11743
|
key: l.key,
|
|
11470
11744
|
markerId: l.markerId,
|
|
11471
11745
|
containerSlotId: scope.lastElementSlotId,
|
|
@@ -11556,73 +11830,224 @@ function collectLoopChildReactiveAttrs(node, ctx, loopParam, loopParamBindings)
|
|
|
11556
11830
|
return attrs;
|
|
11557
11831
|
}
|
|
11558
11832
|
|
|
11559
|
-
// src/ir-to-client-js/
|
|
11560
|
-
var
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11565
|
-
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11570
|
-
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11833
|
+
// src/ir-to-client-js/control-flow/stringify/template-parse.ts
|
|
11834
|
+
var SVG_ROOT_TAGS = new Set([
|
|
11835
|
+
"svg",
|
|
11836
|
+
"path",
|
|
11837
|
+
"circle",
|
|
11838
|
+
"rect",
|
|
11839
|
+
"line",
|
|
11840
|
+
"polyline",
|
|
11841
|
+
"polygon",
|
|
11842
|
+
"ellipse",
|
|
11843
|
+
"text",
|
|
11844
|
+
"tspan",
|
|
11845
|
+
"textPath",
|
|
11846
|
+
"g",
|
|
11847
|
+
"defs",
|
|
11848
|
+
"use",
|
|
11849
|
+
"symbol",
|
|
11850
|
+
"switch",
|
|
11851
|
+
"clipPath",
|
|
11852
|
+
"mask",
|
|
11853
|
+
"marker",
|
|
11854
|
+
"pattern",
|
|
11855
|
+
"linearGradient",
|
|
11856
|
+
"radialGradient",
|
|
11857
|
+
"stop",
|
|
11858
|
+
"image",
|
|
11859
|
+
"foreignObject",
|
|
11860
|
+
"filter",
|
|
11861
|
+
"feBlend",
|
|
11862
|
+
"feColorMatrix",
|
|
11863
|
+
"feComposite",
|
|
11864
|
+
"feFlood",
|
|
11865
|
+
"feGaussianBlur",
|
|
11866
|
+
"feMerge",
|
|
11867
|
+
"feMergeNode",
|
|
11868
|
+
"feMorphology",
|
|
11869
|
+
"feOffset",
|
|
11870
|
+
"feTurbulence",
|
|
11871
|
+
"animate",
|
|
11872
|
+
"animateTransform",
|
|
11873
|
+
"animateMotion"
|
|
11874
|
+
]);
|
|
11875
|
+
function templateRootIsSvg(template) {
|
|
11876
|
+
const stripped = stripLeadingNonContent(template);
|
|
11877
|
+
const m = stripped.match(/^<\s*([A-Za-z][A-Za-z0-9-]*)/);
|
|
11878
|
+
if (m) {
|
|
11879
|
+
const tag = m[1];
|
|
11880
|
+
if (SVG_ROOT_TAGS.has(tag))
|
|
11881
|
+
return true;
|
|
11882
|
+
return SVG_ROOT_TAGS.has(tag.toLowerCase());
|
|
11594
11883
|
}
|
|
11884
|
+
const branches = extractConditionalBranchTemplates(stripped);
|
|
11885
|
+
if (branches === null || branches.length === 0)
|
|
11886
|
+
return false;
|
|
11887
|
+
return branches.every(templateRootIsSvg);
|
|
11595
11888
|
}
|
|
11596
|
-
function
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
11604
|
-
|
|
11605
|
-
|
|
11606
|
-
|
|
11889
|
+
function multiRootTemplateNeedsSvgWrap(template) {
|
|
11890
|
+
const m = stripLeadingNonContent(template).match(/^<\s*([A-Za-z][A-Za-z0-9-]*)/);
|
|
11891
|
+
if (m && m[1].toLowerCase() === "svg")
|
|
11892
|
+
return false;
|
|
11893
|
+
return templateRootIsSvg(template);
|
|
11894
|
+
}
|
|
11895
|
+
function stripLeadingNonContent(template) {
|
|
11896
|
+
let s = template.trimStart();
|
|
11897
|
+
while (s.startsWith("<!--")) {
|
|
11898
|
+
const end = s.indexOf("-->");
|
|
11899
|
+
if (end < 0)
|
|
11900
|
+
return s;
|
|
11901
|
+
s = s.slice(end + 3).trimStart();
|
|
11607
11902
|
}
|
|
11608
|
-
|
|
11609
|
-
return staticCount;
|
|
11610
|
-
const parts = staticCount > 0 ? [String(staticCount), ...dynamic] : dynamic;
|
|
11611
|
-
return parts.length === 1 ? parts[0] : `(${parts.join(" + ")})`;
|
|
11903
|
+
return s;
|
|
11612
11904
|
}
|
|
11613
|
-
function
|
|
11614
|
-
|
|
11905
|
+
function extractConditionalBranchTemplates(template) {
|
|
11906
|
+
if (!template.startsWith("${"))
|
|
11907
|
+
return null;
|
|
11908
|
+
const exprEnd = findInterpolationEnd(template, 2);
|
|
11909
|
+
if (exprEnd < 0)
|
|
11910
|
+
return null;
|
|
11911
|
+
const trailing = stripLeadingNonContent(template.slice(exprEnd + 1));
|
|
11912
|
+
if (trailing.length > 0)
|
|
11913
|
+
return null;
|
|
11914
|
+
const expr = template.slice(2, exprEnd);
|
|
11915
|
+
return findTopLevelTemplateLiterals(expr);
|
|
11615
11916
|
}
|
|
11616
|
-
function
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
11625
|
-
|
|
11917
|
+
function emitTemplateCloneInline(template) {
|
|
11918
|
+
if (templateRootIsSvg(template)) {
|
|
11919
|
+
return `const __tpl = document.createElement('template'); __tpl.innerHTML = \`<svg>${template}</svg>\`; return __tpl.content.firstElementChild.firstElementChild.cloneNode(true)`;
|
|
11920
|
+
}
|
|
11921
|
+
return `const __tpl = document.createElement('template'); __tpl.innerHTML = \`${template}\`; return __tpl.content.firstElementChild.cloneNode(true)`;
|
|
11922
|
+
}
|
|
11923
|
+
function emitHoistedTemplateDecl(lines, indent, tplVar, skeletonTemplate) {
|
|
11924
|
+
const isSvg = templateRootIsSvg(skeletonTemplate);
|
|
11925
|
+
const html = isSvg ? `<svg>${skeletonTemplate}</svg>` : skeletonTemplate;
|
|
11926
|
+
lines.push(`${indent}const ${tplVar} = document.createElement('template')`);
|
|
11927
|
+
lines.push(`${indent}${tplVar}.innerHTML = \`${html}\``);
|
|
11928
|
+
}
|
|
11929
|
+
function hoistedCloneExpr(tplVar, skeletonTemplate) {
|
|
11930
|
+
return templateRootIsSvg(skeletonTemplate) ? `${tplVar}.content.firstElementChild.firstElementChild.cloneNode(true)` : `${tplVar}.content.firstElementChild.cloneNode(true)`;
|
|
11931
|
+
}
|
|
11932
|
+
function emitTemplateCloneLines(template, indent) {
|
|
11933
|
+
if (templateRootIsSvg(template)) {
|
|
11934
|
+
return [
|
|
11935
|
+
`${indent}const __tpl = document.createElement('template')`,
|
|
11936
|
+
`${indent}__tpl.innerHTML = \`<svg>${template}</svg>\``,
|
|
11937
|
+
`${indent}return __tpl.content.firstElementChild.firstElementChild.cloneNode(true)`
|
|
11938
|
+
];
|
|
11939
|
+
}
|
|
11940
|
+
return [
|
|
11941
|
+
`${indent}const __tpl = document.createElement('template')`,
|
|
11942
|
+
`${indent}__tpl.innerHTML = \`${template}\``,
|
|
11943
|
+
`${indent}return __tpl.content.firstElementChild.cloneNode(true)`
|
|
11944
|
+
];
|
|
11945
|
+
}
|
|
11946
|
+
function emitLoopItemElementSetup(lines, opts) {
|
|
11947
|
+
const { template, bodyIsMultiRoot, indent, singleRootLayout } = opts;
|
|
11948
|
+
const innerIndent = indent + " ";
|
|
11949
|
+
if (bodyIsMultiRoot) {
|
|
11950
|
+
lines.push(`${indent}let __el, __extras`);
|
|
11951
|
+
lines.push(`${indent}if (__existing) {`);
|
|
11952
|
+
lines.push(`${innerIndent}__el = __existing`);
|
|
11953
|
+
lines.push(`${indent}} else {`);
|
|
11954
|
+
for (const ln of emitMultiRootTemplateCloneLines(template, innerIndent, "__el", "__extras")) {
|
|
11955
|
+
lines.push(ln);
|
|
11956
|
+
}
|
|
11957
|
+
lines.push(`${innerIndent}__el.__bfExtras = __extras`);
|
|
11958
|
+
lines.push(`${indent}}`);
|
|
11959
|
+
return;
|
|
11960
|
+
}
|
|
11961
|
+
if (singleRootLayout === "inline") {
|
|
11962
|
+
const cloneExpr = emitTemplateCloneInline(template);
|
|
11963
|
+
lines.push(`${indent}const __el = __existing ?? (() => { ${cloneExpr} })()`);
|
|
11964
|
+
return;
|
|
11965
|
+
}
|
|
11966
|
+
lines.push(`${indent}const __el = __existing ?? (() => {`);
|
|
11967
|
+
for (const ln of emitTemplateCloneLines(template, innerIndent))
|
|
11968
|
+
lines.push(ln);
|
|
11969
|
+
lines.push(`${indent}})()`);
|
|
11970
|
+
}
|
|
11971
|
+
function emitMultiRootTemplateCloneLines(template, indent, varEl, varExtras) {
|
|
11972
|
+
const isSvg = multiRootTemplateNeedsSvgWrap(template);
|
|
11973
|
+
const innerHtmlExpr = isSvg ? `\`<svg>${template}</svg>\`` : `\`${template}\``;
|
|
11974
|
+
const parentExpr = isSvg ? `__tpl.content.firstElementChild` : `__tpl.content`;
|
|
11975
|
+
return [
|
|
11976
|
+
`${indent}const __tpl = document.createElement('template')`,
|
|
11977
|
+
`${indent}__tpl.innerHTML = ${innerHtmlExpr}`,
|
|
11978
|
+
`${indent}${varEl} = ${parentExpr}.firstElementChild.cloneNode(true)`,
|
|
11979
|
+
`${indent}${varExtras} = []`,
|
|
11980
|
+
`${indent}{ let __sib = ${parentExpr}.firstElementChild.nextElementSibling; while (__sib) { ${varExtras}.push(__sib.cloneNode(true)); __sib = __sib.nextElementSibling } }`
|
|
11981
|
+
];
|
|
11982
|
+
}
|
|
11983
|
+
|
|
11984
|
+
// src/ir-to-client-js/collect-elements.ts
|
|
11985
|
+
var EMPTY_RENDER_EXPRS = new Set(["null", "undefined", "false", "''", '""', "``"]);
|
|
11986
|
+
function domElementCount(node) {
|
|
11987
|
+
switch (node.type) {
|
|
11988
|
+
case "element":
|
|
11989
|
+
case "component":
|
|
11990
|
+
case "provider":
|
|
11991
|
+
case "async":
|
|
11992
|
+
return 1;
|
|
11993
|
+
case "text":
|
|
11994
|
+
return 0;
|
|
11995
|
+
case "expression":
|
|
11996
|
+
return EMPTY_RENDER_EXPRS.has(node.expr.trim()) ? 0 : null;
|
|
11997
|
+
case "loop":
|
|
11998
|
+
if (node.bodyIsItemConditional || node.method === "flatMap")
|
|
11999
|
+
return null;
|
|
12000
|
+
return `(${buildLoopChainExpr({
|
|
12001
|
+
base: node.array,
|
|
12002
|
+
sortComparator: node.sortComparator,
|
|
12003
|
+
filterPredicate: node.filterPredicate,
|
|
12004
|
+
chainOrder: node.chainOrder
|
|
12005
|
+
})}).length`;
|
|
12006
|
+
case "conditional": {
|
|
12007
|
+
const t = domElementCount(node.whenTrue);
|
|
12008
|
+
const f = domElementCount(node.whenFalse);
|
|
12009
|
+
if (t === null || f === null)
|
|
12010
|
+
return null;
|
|
12011
|
+
if (typeof t === "number" && typeof f === "number" && t === f)
|
|
12012
|
+
return t;
|
|
12013
|
+
return `(${node.condition} ? ${t} : ${f})`;
|
|
12014
|
+
}
|
|
12015
|
+
case "fragment":
|
|
12016
|
+
return sumElementCounts(node.children);
|
|
12017
|
+
default:
|
|
12018
|
+
return null;
|
|
12019
|
+
}
|
|
12020
|
+
}
|
|
12021
|
+
function sumElementCounts(nodes) {
|
|
12022
|
+
let staticCount = 0;
|
|
12023
|
+
const dynamic = [];
|
|
12024
|
+
for (const n of nodes) {
|
|
12025
|
+
const c = domElementCount(n);
|
|
12026
|
+
if (c === null)
|
|
12027
|
+
return null;
|
|
12028
|
+
if (typeof c === "number")
|
|
12029
|
+
staticCount += c;
|
|
12030
|
+
else
|
|
12031
|
+
dynamic.push(c);
|
|
12032
|
+
}
|
|
12033
|
+
if (dynamic.length === 0)
|
|
12034
|
+
return staticCount;
|
|
12035
|
+
const parts = staticCount > 0 ? [String(staticCount), ...dynamic] : dynamic;
|
|
12036
|
+
return parts.length === 1 ? parts[0] : `(${parts.join(" + ")})`;
|
|
12037
|
+
}
|
|
12038
|
+
function legacyElementCount(node) {
|
|
12039
|
+
return node.type === "element" || node.type === "component" || node.type === "provider" || node.type === "async" || node.type === "text" || node.type === "expression" && !node.reactive || node.type === "conditional" ? 1 : 0;
|
|
12040
|
+
}
|
|
12041
|
+
function computeLoopSiblingOffsets(root) {
|
|
12042
|
+
const offsets = new Map;
|
|
12043
|
+
const recordRun = (children, preceding) => {
|
|
12044
|
+
for (const child of children) {
|
|
12045
|
+
if (child.type === "loop") {
|
|
12046
|
+
if (preceding.length > 0 && !offsets.has(child)) {
|
|
12047
|
+
offsets.set(child, [...preceding]);
|
|
12048
|
+
}
|
|
12049
|
+
preceding.push(child);
|
|
12050
|
+
} else if (child.type === "fragment" || child.type === "provider" || child.type === "async") {
|
|
11626
12051
|
recordRun(child.children, preceding);
|
|
11627
12052
|
} else {
|
|
11628
12053
|
preceding.push(child);
|
|
@@ -11734,6 +12159,7 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
11734
12159
|
arrayFreeIdentifiers: n.arrayFreeIdentifiers,
|
|
11735
12160
|
param: n.param,
|
|
11736
12161
|
paramBindings: n.paramBindings,
|
|
12162
|
+
index: n.index,
|
|
11737
12163
|
key: n.key,
|
|
11738
12164
|
markerId: n.markerId,
|
|
11739
12165
|
bodyIsMultiRoot: n.bodyIsMultiRoot,
|
|
@@ -11931,6 +12357,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
11931
12357
|
let template = "";
|
|
11932
12358
|
let staticItemTemplate;
|
|
11933
12359
|
let skeletonTemplate;
|
|
12360
|
+
let skeletonPaths;
|
|
11934
12361
|
if (l.childComponent) {
|
|
11935
12362
|
template = "";
|
|
11936
12363
|
if (l.isStaticArray && l.children[0]) {
|
|
@@ -11942,10 +12369,14 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
11942
12369
|
if (l.isStaticArray) {
|
|
11943
12370
|
staticItemTemplate = useElementReconciliation ? irToPlaceholderTemplate(l.children[0], buildRestSpreadNames(ctx), 0) : irToHtmlTemplate(l.children[0], buildRestSpreadNames(ctx), 0);
|
|
11944
12371
|
} else if (!useElementReconciliation && !l.bodyIsMultiRoot && !l.bodyIsItemConditional) {
|
|
11945
|
-
|
|
12372
|
+
const skeletonSafeSlots = {
|
|
11946
12373
|
reactiveAttrKeys: new Set(bindings.reactiveAttrs.map((a) => `${a.childSlotId}::${a.attrName}`)),
|
|
11947
12374
|
reactiveTextSlotIds: new Set(bindings.reactiveTexts.map((t) => t.slotId))
|
|
11948
|
-
}
|
|
12375
|
+
};
|
|
12376
|
+
skeletonTemplate = buildLoopSkeletonTemplate(l.children[0], skeletonSafeSlots) ?? undefined;
|
|
12377
|
+
if (skeletonTemplate && !templateRootIsSvg(skeletonTemplate)) {
|
|
12378
|
+
skeletonPaths = computeSkeletonSlotPaths(l.children[0], skeletonSafeSlots) ?? undefined;
|
|
12379
|
+
}
|
|
11949
12380
|
}
|
|
11950
12381
|
}
|
|
11951
12382
|
ctx.loopElements.push({
|
|
@@ -11965,6 +12396,7 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
11965
12396
|
template,
|
|
11966
12397
|
staticItemTemplate,
|
|
11967
12398
|
skeletonTemplate,
|
|
12399
|
+
skeletonPaths,
|
|
11968
12400
|
childEventHandlers: childHandlers,
|
|
11969
12401
|
bindings,
|
|
11970
12402
|
childComponent: l.childComponent,
|
|
@@ -12755,6 +13187,7 @@ var RUNTIME_IMPORT_CANDIDATES = [
|
|
|
12755
13187
|
"__slot",
|
|
12756
13188
|
"__bfSlot",
|
|
12757
13189
|
"__bfText",
|
|
13190
|
+
"tAfter",
|
|
12758
13191
|
"beginTurn",
|
|
12759
13192
|
"endTurn"
|
|
12760
13193
|
];
|
|
@@ -14571,13 +15004,6 @@ function emitPropsExtraction(lines, ctx, neededProps, propUsage) {
|
|
|
14571
15004
|
lines.push(` const ${propName} = ${PROPS_PARAM}.${propName} ?? []`);
|
|
14572
15005
|
} else if (propHasPropertyAccess(usage) && !propsUsedAsConditions.has(propName)) {
|
|
14573
15006
|
lines.push(` const ${propName} = ${PROPS_PARAM}.${propName} ?? {}`);
|
|
14574
|
-
} else if (prop?.optional && prop?.type) {
|
|
14575
|
-
const inferredDefault = inferDefaultValue(prop.type);
|
|
14576
|
-
if (inferredDefault !== "undefined") {
|
|
14577
|
-
lines.push(` const ${propName} = ${PROPS_PARAM}.${propName} ?? ${inferredDefault}`);
|
|
14578
|
-
} else {
|
|
14579
|
-
lines.push(` const ${propName} = ${PROPS_PARAM}.${propName}`);
|
|
14580
|
-
}
|
|
14581
15007
|
} else {
|
|
14582
15008
|
lines.push(` const ${propName} = ${PROPS_PARAM}.${propName}`);
|
|
14583
15009
|
}
|
|
@@ -14625,9 +15051,63 @@ import { BF_SCOPE as BF_SCOPE2, BF_HOST, BF_AT } from "@barefootjs/shared";
|
|
|
14625
15051
|
function loopKeyFn(loop) {
|
|
14626
15052
|
if (loop.key === null)
|
|
14627
15053
|
return "null";
|
|
14628
|
-
const params =
|
|
15054
|
+
const params = `${loop.param}${loop.index ? `, ${loop.index}` : ""}`;
|
|
14629
15055
|
return `(${params}) => String(${loop.key})`;
|
|
14630
15056
|
}
|
|
15057
|
+
function nestedLoopReferencesIndex(inner, comps, events) {
|
|
15058
|
+
const index = inner.index;
|
|
15059
|
+
if (!index)
|
|
15060
|
+
return false;
|
|
15061
|
+
const exprRefs = (text, precomputed) => {
|
|
15062
|
+
if (precomputed)
|
|
15063
|
+
return precomputed.has(index);
|
|
15064
|
+
if (!text)
|
|
15065
|
+
return false;
|
|
15066
|
+
return extractFreeIdentifiersFromText(text).has(index);
|
|
15067
|
+
};
|
|
15068
|
+
if (exprRefs(inner.key))
|
|
15069
|
+
return true;
|
|
15070
|
+
for (const t of inner.bindings.reactiveTexts) {
|
|
15071
|
+
if (exprRefs(t.expression, t.freeIdentifiers))
|
|
15072
|
+
return true;
|
|
15073
|
+
}
|
|
15074
|
+
for (const a of inner.bindings.reactiveAttrs) {
|
|
15075
|
+
if (exprRefs(a.expression, a.freeIdentifiers))
|
|
15076
|
+
return true;
|
|
15077
|
+
}
|
|
15078
|
+
if (inner.mapPreamble && extractFreeIdentifiersFromStatementText(inner.mapPreamble).has(index))
|
|
15079
|
+
return true;
|
|
15080
|
+
if (inner.template && extractFreeIdentifiersFromTemplateText(inner.template).has(index))
|
|
15081
|
+
return true;
|
|
15082
|
+
for (const ev of events) {
|
|
15083
|
+
if (exprRefs(ev.handler))
|
|
15084
|
+
return true;
|
|
15085
|
+
}
|
|
15086
|
+
for (const r of inner.bindings.refs) {
|
|
15087
|
+
if (exprRefs(r.callback))
|
|
15088
|
+
return true;
|
|
15089
|
+
}
|
|
15090
|
+
for (const c of comps) {
|
|
15091
|
+
for (const p of c.props) {
|
|
15092
|
+
if (exprRefs(attrValueToString(p.value)))
|
|
15093
|
+
return true;
|
|
15094
|
+
}
|
|
15095
|
+
if (c.children?.length) {
|
|
15096
|
+
const childrenExpr = irChildrenToJsExpr(c.children);
|
|
15097
|
+
if (childrenExpr && exprRefs(childrenExpr))
|
|
15098
|
+
return true;
|
|
15099
|
+
}
|
|
15100
|
+
}
|
|
15101
|
+
return false;
|
|
15102
|
+
}
|
|
15103
|
+
function nestedLoopIndexAlias(inner, syntheticIndexVar, paramHead, comps, events) {
|
|
15104
|
+
const index = inner.index;
|
|
15105
|
+
if (!index || index === paramHead)
|
|
15106
|
+
return null;
|
|
15107
|
+
if (!nestedLoopReferencesIndex(inner, comps, events))
|
|
15108
|
+
return null;
|
|
15109
|
+
return `const ${index} = ${syntheticIndexVar}`;
|
|
15110
|
+
}
|
|
14631
15111
|
function buildChildRefBindings(refs, loopParam, loopParamBindings) {
|
|
14632
15112
|
if (refs.length === 0)
|
|
14633
15113
|
return [];
|
|
@@ -14808,6 +15288,7 @@ function buildOuterNestedPlan(elem, comp) {
|
|
|
14808
15288
|
}
|
|
14809
15289
|
function buildInnerLoopNestedPlan(elem, innerLoop, innerComps) {
|
|
14810
15290
|
const outerIndexParam = elem.index || "__idx";
|
|
15291
|
+
const innerIndexParam = innerLoop.index || "__innerIdx";
|
|
14811
15292
|
const comps = innerComps.map((comp) => ({
|
|
14812
15293
|
componentName: comp.name,
|
|
14813
15294
|
selector: buildCompSelector(comp),
|
|
@@ -14824,7 +15305,8 @@ function buildInnerLoopNestedPlan(elem, innerLoop, innerComps) {
|
|
|
14824
15305
|
innerContainerSlotId: innerLoop.containerSlotId ?? null,
|
|
14825
15306
|
innerArrayExpr: innerLoop.array,
|
|
14826
15307
|
innerParam: innerLoop.param,
|
|
14827
|
-
|
|
15308
|
+
innerIndexParam,
|
|
15309
|
+
innerOffsetExpr: buildLoopChildIndexExpr(innerIndexParam, innerLoop.offset),
|
|
14828
15310
|
innerPreludeStatements: innerLoop.mapPreamble ? [innerLoop.mapPreamble] : [],
|
|
14829
15311
|
depth: innerLoop.depth,
|
|
14830
15312
|
comps
|
|
@@ -14841,9 +15323,11 @@ function buildComponentRootedInnerLoopPlan(elem, innerLoop, innerComps) {
|
|
|
14841
15323
|
containerVar: `_${varSlotId(elem.slotId)}`,
|
|
14842
15324
|
outerArrayExpr: elem.array,
|
|
14843
15325
|
outerParam: elem.param,
|
|
15326
|
+
outerIndexParam: elem.index,
|
|
14844
15327
|
outerPreludeStatements: elem.mapPreamble ? [elem.mapPreamble] : [],
|
|
14845
15328
|
innerArrayExpr: innerLoop.array,
|
|
14846
15329
|
innerParam: innerLoop.param,
|
|
15330
|
+
innerIndexParam: innerLoop.index,
|
|
14847
15331
|
innerPreludeStatements: innerLoop.mapPreamble ? [innerLoop.mapPreamble] : [],
|
|
14848
15332
|
depth: innerLoop.depth,
|
|
14849
15333
|
comps
|
|
@@ -14936,6 +15420,7 @@ function emitInnerLoopNested(lines, plan) {
|
|
|
14936
15420
|
innerContainerSlotId,
|
|
14937
15421
|
innerArrayExpr,
|
|
14938
15422
|
innerParam,
|
|
15423
|
+
innerIndexParam,
|
|
14939
15424
|
innerOffsetExpr,
|
|
14940
15425
|
innerPreludeStatements,
|
|
14941
15426
|
depth,
|
|
@@ -14954,7 +15439,7 @@ function emitInnerLoopNested(lines, plan) {
|
|
|
14954
15439
|
} else {
|
|
14955
15440
|
lines.push(` const __ic = __outerEl`);
|
|
14956
15441
|
}
|
|
14957
|
-
lines.push(` ${innerArrayExpr}.forEach((${innerParam},
|
|
15442
|
+
lines.push(` ${innerArrayExpr}.forEach((${innerParam}, ${innerIndexParam}) => {`);
|
|
14958
15443
|
lines.push(` const __innerEl = __ic.children[${innerOffsetExpr}]`);
|
|
14959
15444
|
lines.push(` if (!__innerEl) return`);
|
|
14960
15445
|
for (const stmt of innerPreludeStatements) {
|
|
@@ -14975,9 +15460,11 @@ function emitComponentRootedInnerLoop(lines, plan) {
|
|
|
14975
15460
|
containerVar,
|
|
14976
15461
|
outerArrayExpr,
|
|
14977
15462
|
outerParam,
|
|
15463
|
+
outerIndexParam,
|
|
14978
15464
|
outerPreludeStatements,
|
|
14979
15465
|
innerArrayExpr,
|
|
14980
15466
|
innerParam,
|
|
15467
|
+
innerIndexParam,
|
|
14981
15468
|
innerPreludeStatements,
|
|
14982
15469
|
depth,
|
|
14983
15470
|
comps
|
|
@@ -14991,11 +15478,11 @@ function emitComponentRootedInnerLoop(lines, plan) {
|
|
|
14991
15478
|
lines.push(` const ${scopesVar(i)} = qsaChildScopes(${containerVar}, ${comp.selector})`);
|
|
14992
15479
|
lines.push(` let ${cursorVar(i)} = 0`);
|
|
14993
15480
|
});
|
|
14994
|
-
lines.push(` ${outerArrayExpr}.forEach((${outerParam}) => {`);
|
|
15481
|
+
lines.push(` ${outerArrayExpr}.forEach((${outerParam}${outerIndexParam ? `, ${outerIndexParam}` : ""}) => {`);
|
|
14995
15482
|
for (const stmt of outerPreludeStatements) {
|
|
14996
15483
|
lines.push(` ${stmt}`);
|
|
14997
15484
|
}
|
|
14998
|
-
lines.push(` ${innerArrayExpr}.forEach((${innerParam}) => {`);
|
|
15485
|
+
lines.push(` ${innerArrayExpr}.forEach((${innerParam}${innerIndexParam ? `, ${innerIndexParam}` : ""}) => {`);
|
|
14999
15486
|
for (const stmt of innerPreludeStatements) {
|
|
15000
15487
|
lines.push(` ${stmt}`);
|
|
15001
15488
|
}
|
|
@@ -15147,6 +15634,7 @@ function buildBranchInnerLoopsPlan(args) {
|
|
|
15147
15634
|
...ev,
|
|
15148
15635
|
handler: wrapInner(ev.handler)
|
|
15149
15636
|
}));
|
|
15637
|
+
const indexAlias = nestedLoopIndexAlias(inner, `__bidxbr_${i}`, paramHead, inner.childComponents ?? [], inner.bindings.events);
|
|
15150
15638
|
const reactiveTexts = inner.bindings.reactiveTexts.map((text) => ({
|
|
15151
15639
|
slotId: text.slotId,
|
|
15152
15640
|
wrappedExpression: wrapBoth(text.expression),
|
|
@@ -15161,6 +15649,7 @@ function buildBranchInnerLoopsPlan(args) {
|
|
|
15161
15649
|
keyFn: loopKeyFn(inner),
|
|
15162
15650
|
paramHead,
|
|
15163
15651
|
paramUnwrap,
|
|
15652
|
+
indexAlias,
|
|
15164
15653
|
wrappedTemplate: inner.template,
|
|
15165
15654
|
wrappedKey,
|
|
15166
15655
|
keyDepth: 1,
|
|
@@ -15402,7 +15891,7 @@ function buildInnerLoopsPlan(args) {
|
|
|
15402
15891
|
const containerExpr = inner.containerSlotId ? `qsa(${parentElVar}, '[bf="${inner.containerSlotId}"]')` : parentElVar;
|
|
15403
15892
|
const refsParent = !!outerLoopParam && (inner.arrayFreeIdentifiers?.has(outerLoopParam) ?? false);
|
|
15404
15893
|
const useReactive = refsParent && !!inner.template;
|
|
15405
|
-
const emit = useReactive ? buildReactiveEmit(inner, level, wrapOuter) : buildStaticEmit(inner, level);
|
|
15894
|
+
const emit = useReactive ? buildReactiveEmit(inner, level, wrapOuter, uidSuffix) : buildStaticEmit(inner, level, uidSuffix);
|
|
15406
15895
|
const arrayExpr = useReactive ? wrapOuter(inner.array) : inner.array;
|
|
15407
15896
|
const childLevelsPlan = childLevels.length > 0 ? buildInnerLoopsPlan({
|
|
15408
15897
|
levels: childLevels,
|
|
@@ -15428,7 +15917,7 @@ function buildInnerLoopsPlan(args) {
|
|
|
15428
15917
|
}
|
|
15429
15918
|
return plan;
|
|
15430
15919
|
}
|
|
15431
|
-
function buildReactiveEmit(inner, level, wrapOuter) {
|
|
15920
|
+
function buildReactiveEmit(inner, level, wrapOuter, uidSuffix) {
|
|
15432
15921
|
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings);
|
|
15433
15922
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(inner.param, inner.paramBindings);
|
|
15434
15923
|
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings) : null;
|
|
@@ -15475,6 +15964,9 @@ function buildReactiveEmit(inner, level, wrapOuter) {
|
|
|
15475
15964
|
};
|
|
15476
15965
|
});
|
|
15477
15966
|
const preludeStatements = [];
|
|
15967
|
+
const indexAlias = nestedLoopIndexAlias(inner, `__innerIdx${uidSuffix}`, paramHead, level.comps, level.events);
|
|
15968
|
+
if (indexAlias)
|
|
15969
|
+
preludeStatements.push(indexAlias);
|
|
15478
15970
|
if (paramUnwrap)
|
|
15479
15971
|
preludeStatements.push(paramUnwrap);
|
|
15480
15972
|
if (inner.mapPreamble)
|
|
@@ -15495,8 +15987,13 @@ function buildReactiveEmit(inner, level, wrapOuter) {
|
|
|
15495
15987
|
childRefs
|
|
15496
15988
|
};
|
|
15497
15989
|
}
|
|
15498
|
-
function buildStaticEmit(inner, level) {
|
|
15499
|
-
const preludeStatements =
|
|
15990
|
+
function buildStaticEmit(inner, level, uidSuffix) {
|
|
15991
|
+
const preludeStatements = [];
|
|
15992
|
+
const indexAlias = nestedLoopIndexAlias(inner, `__innerIdx${uidSuffix}`, inner.param, level.comps, level.events);
|
|
15993
|
+
if (indexAlias)
|
|
15994
|
+
preludeStatements.push(indexAlias);
|
|
15995
|
+
if (inner.mapPreamble)
|
|
15996
|
+
preludeStatements.push(inner.mapPreamble);
|
|
15500
15997
|
return {
|
|
15501
15998
|
mode: "static",
|
|
15502
15999
|
rawKey: inner.key ?? null,
|
|
@@ -15999,151 +16496,6 @@ function emitReactiveChildProps(lines, ctx) {
|
|
|
15999
16496
|
}
|
|
16000
16497
|
}
|
|
16001
16498
|
|
|
16002
|
-
// src/ir-to-client-js/control-flow/stringify/template-parse.ts
|
|
16003
|
-
var SVG_ROOT_TAGS = new Set([
|
|
16004
|
-
"svg",
|
|
16005
|
-
"path",
|
|
16006
|
-
"circle",
|
|
16007
|
-
"rect",
|
|
16008
|
-
"line",
|
|
16009
|
-
"polyline",
|
|
16010
|
-
"polygon",
|
|
16011
|
-
"ellipse",
|
|
16012
|
-
"text",
|
|
16013
|
-
"tspan",
|
|
16014
|
-
"textPath",
|
|
16015
|
-
"g",
|
|
16016
|
-
"defs",
|
|
16017
|
-
"use",
|
|
16018
|
-
"symbol",
|
|
16019
|
-
"switch",
|
|
16020
|
-
"clipPath",
|
|
16021
|
-
"mask",
|
|
16022
|
-
"marker",
|
|
16023
|
-
"pattern",
|
|
16024
|
-
"linearGradient",
|
|
16025
|
-
"radialGradient",
|
|
16026
|
-
"stop",
|
|
16027
|
-
"image",
|
|
16028
|
-
"foreignObject",
|
|
16029
|
-
"filter",
|
|
16030
|
-
"feBlend",
|
|
16031
|
-
"feColorMatrix",
|
|
16032
|
-
"feComposite",
|
|
16033
|
-
"feFlood",
|
|
16034
|
-
"feGaussianBlur",
|
|
16035
|
-
"feMerge",
|
|
16036
|
-
"feMergeNode",
|
|
16037
|
-
"feMorphology",
|
|
16038
|
-
"feOffset",
|
|
16039
|
-
"feTurbulence",
|
|
16040
|
-
"animate",
|
|
16041
|
-
"animateTransform",
|
|
16042
|
-
"animateMotion"
|
|
16043
|
-
]);
|
|
16044
|
-
function templateRootIsSvg(template) {
|
|
16045
|
-
const stripped = stripLeadingNonContent(template);
|
|
16046
|
-
const m = stripped.match(/^<\s*([A-Za-z][A-Za-z0-9-]*)/);
|
|
16047
|
-
if (m) {
|
|
16048
|
-
const tag = m[1];
|
|
16049
|
-
if (SVG_ROOT_TAGS.has(tag))
|
|
16050
|
-
return true;
|
|
16051
|
-
return SVG_ROOT_TAGS.has(tag.toLowerCase());
|
|
16052
|
-
}
|
|
16053
|
-
const branches = extractConditionalBranchTemplates(stripped);
|
|
16054
|
-
if (branches === null || branches.length === 0)
|
|
16055
|
-
return false;
|
|
16056
|
-
return branches.every(templateRootIsSvg);
|
|
16057
|
-
}
|
|
16058
|
-
function stripLeadingNonContent(template) {
|
|
16059
|
-
let s = template.trimStart();
|
|
16060
|
-
while (s.startsWith("<!--")) {
|
|
16061
|
-
const end = s.indexOf("-->");
|
|
16062
|
-
if (end < 0)
|
|
16063
|
-
return s;
|
|
16064
|
-
s = s.slice(end + 3).trimStart();
|
|
16065
|
-
}
|
|
16066
|
-
return s;
|
|
16067
|
-
}
|
|
16068
|
-
function extractConditionalBranchTemplates(template) {
|
|
16069
|
-
if (!template.startsWith("${"))
|
|
16070
|
-
return null;
|
|
16071
|
-
const exprEnd = findInterpolationEnd(template, 2);
|
|
16072
|
-
if (exprEnd < 0)
|
|
16073
|
-
return null;
|
|
16074
|
-
const trailing = stripLeadingNonContent(template.slice(exprEnd + 1));
|
|
16075
|
-
if (trailing.length > 0)
|
|
16076
|
-
return null;
|
|
16077
|
-
const expr = template.slice(2, exprEnd);
|
|
16078
|
-
return findTopLevelTemplateLiterals(expr);
|
|
16079
|
-
}
|
|
16080
|
-
function emitTemplateCloneInline(template) {
|
|
16081
|
-
if (templateRootIsSvg(template)) {
|
|
16082
|
-
return `const __tpl = document.createElement('template'); __tpl.innerHTML = \`<svg>${template}</svg>\`; return __tpl.content.firstElementChild.firstElementChild.cloneNode(true)`;
|
|
16083
|
-
}
|
|
16084
|
-
return `const __tpl = document.createElement('template'); __tpl.innerHTML = \`${template}\`; return __tpl.content.firstElementChild.cloneNode(true)`;
|
|
16085
|
-
}
|
|
16086
|
-
function emitHoistedTemplateDecl(lines, indent, tplVar, skeletonTemplate) {
|
|
16087
|
-
const isSvg = templateRootIsSvg(skeletonTemplate);
|
|
16088
|
-
const html = isSvg ? `<svg>${skeletonTemplate}</svg>` : skeletonTemplate;
|
|
16089
|
-
lines.push(`${indent}const ${tplVar} = document.createElement('template')`);
|
|
16090
|
-
lines.push(`${indent}${tplVar}.innerHTML = \`${html}\``);
|
|
16091
|
-
}
|
|
16092
|
-
function hoistedCloneExpr(tplVar, skeletonTemplate) {
|
|
16093
|
-
return templateRootIsSvg(skeletonTemplate) ? `${tplVar}.content.firstElementChild.firstElementChild.cloneNode(true)` : `${tplVar}.content.firstElementChild.cloneNode(true)`;
|
|
16094
|
-
}
|
|
16095
|
-
function emitTemplateCloneLines(template, indent) {
|
|
16096
|
-
if (templateRootIsSvg(template)) {
|
|
16097
|
-
return [
|
|
16098
|
-
`${indent}const __tpl = document.createElement('template')`,
|
|
16099
|
-
`${indent}__tpl.innerHTML = \`<svg>${template}</svg>\``,
|
|
16100
|
-
`${indent}return __tpl.content.firstElementChild.firstElementChild.cloneNode(true)`
|
|
16101
|
-
];
|
|
16102
|
-
}
|
|
16103
|
-
return [
|
|
16104
|
-
`${indent}const __tpl = document.createElement('template')`,
|
|
16105
|
-
`${indent}__tpl.innerHTML = \`${template}\``,
|
|
16106
|
-
`${indent}return __tpl.content.firstElementChild.cloneNode(true)`
|
|
16107
|
-
];
|
|
16108
|
-
}
|
|
16109
|
-
function emitLoopItemElementSetup(lines, opts) {
|
|
16110
|
-
const { template, bodyIsMultiRoot, indent, singleRootLayout } = opts;
|
|
16111
|
-
const innerIndent = indent + " ";
|
|
16112
|
-
if (bodyIsMultiRoot) {
|
|
16113
|
-
lines.push(`${indent}let __el, __extras`);
|
|
16114
|
-
lines.push(`${indent}if (__existing) {`);
|
|
16115
|
-
lines.push(`${innerIndent}__el = __existing`);
|
|
16116
|
-
lines.push(`${indent}} else {`);
|
|
16117
|
-
for (const ln of emitMultiRootTemplateCloneLines(template, innerIndent, "__el", "__extras")) {
|
|
16118
|
-
lines.push(ln);
|
|
16119
|
-
}
|
|
16120
|
-
lines.push(`${innerIndent}__el.__bfExtras = __extras`);
|
|
16121
|
-
lines.push(`${indent}}`);
|
|
16122
|
-
return;
|
|
16123
|
-
}
|
|
16124
|
-
if (singleRootLayout === "inline") {
|
|
16125
|
-
const cloneExpr = emitTemplateCloneInline(template);
|
|
16126
|
-
lines.push(`${indent}const __el = __existing ?? (() => { ${cloneExpr} })()`);
|
|
16127
|
-
return;
|
|
16128
|
-
}
|
|
16129
|
-
lines.push(`${indent}const __el = __existing ?? (() => {`);
|
|
16130
|
-
for (const ln of emitTemplateCloneLines(template, innerIndent))
|
|
16131
|
-
lines.push(ln);
|
|
16132
|
-
lines.push(`${indent}})()`);
|
|
16133
|
-
}
|
|
16134
|
-
function emitMultiRootTemplateCloneLines(template, indent, varEl, varExtras) {
|
|
16135
|
-
const isSvg = templateRootIsSvg(template);
|
|
16136
|
-
const innerHtmlExpr = isSvg ? `\`<svg>${template}</svg>\`` : `\`${template}\``;
|
|
16137
|
-
const parentExpr = isSvg ? `__tpl.content.firstElementChild` : `__tpl.content`;
|
|
16138
|
-
return [
|
|
16139
|
-
`${indent}const __tpl = document.createElement('template')`,
|
|
16140
|
-
`${indent}__tpl.innerHTML = ${innerHtmlExpr}`,
|
|
16141
|
-
`${indent}${varEl} = ${parentExpr}.firstElementChild.cloneNode(true)`,
|
|
16142
|
-
`${indent}${varExtras} = []`,
|
|
16143
|
-
`${indent}{ let __sib = ${parentExpr}.firstElementChild.nextElementSibling; while (__sib) { ${varExtras}.push(__sib.cloneNode(true)); __sib = __sib.nextElementSibling } }`
|
|
16144
|
-
];
|
|
16145
|
-
}
|
|
16146
|
-
|
|
16147
16499
|
// src/ir-to-client-js/control-flow/stringify/loop-child-arm.ts
|
|
16148
16500
|
function stringifyBranchEventBindings(lines, plan, indent) {
|
|
16149
16501
|
for (const slot of plan) {
|
|
@@ -16165,6 +16517,9 @@ function stringifyBranchInnerLoops(lines, plan, indent, pc) {
|
|
|
16165
16517
|
const uid = inner.uidSuffix;
|
|
16166
16518
|
lines.push(`${indent}{ const __bic${uid} = ${inner.containerExpr}`);
|
|
16167
16519
|
lines.push(`${indent}if (__bic${uid}) mapArray(() => ${inner.arrayExpr} || [], __bic${uid}, ${inner.keyFn}, (${inner.paramHead}, __bidx${uid}, __existing) => {`);
|
|
16520
|
+
if (inner.indexAlias) {
|
|
16521
|
+
lines.push(`${indent} ${inner.indexAlias}`);
|
|
16522
|
+
}
|
|
16168
16523
|
if (inner.paramUnwrap) {
|
|
16169
16524
|
lines.push(`${indent} ${inner.paramUnwrap}`);
|
|
16170
16525
|
}
|
|
@@ -16229,13 +16584,15 @@ function stringifyLoopChildArm(lines, arm, armIndent, pc) {
|
|
|
16229
16584
|
|
|
16230
16585
|
// src/ir-to-client-js/control-flow/stringify/reactive-effects.ts
|
|
16231
16586
|
function stringifyReactiveEffects(lines, plan, opts) {
|
|
16232
|
-
const { indent, elVar, bodyIsMultiRoot } = opts;
|
|
16587
|
+
const { indent, elVar, bodyIsMultiRoot, elementIndexBySlot, textIndexBySlot } = opts;
|
|
16233
16588
|
const lookup = bodyIsMultiRoot ? "qsaItem" : "qsa";
|
|
16234
16589
|
const pc = plan.profileComponentName;
|
|
16235
16590
|
const bindingBfId = (slotId) => profileBindingId(pc, slotId);
|
|
16236
16591
|
for (const slot of plan.attrSlots) {
|
|
16237
16592
|
const varName = `__ra_${varSlotId(slot.slotId)}`;
|
|
16238
|
-
|
|
16593
|
+
const pIdx = elementIndexBySlot?.get(slot.slotId);
|
|
16594
|
+
const lookupExpr = pIdx !== undefined ? `__p ? __p[${pIdx}] : ${lookup}(${elVar}, '[bf="${slot.slotId}"]')` : `${lookup}(${elVar}, '[bf="${slot.slotId}"]')`;
|
|
16595
|
+
lines.push(`${indent}{ const ${varName} = ${lookupExpr}`);
|
|
16239
16596
|
lines.push(`${indent}if (${varName}) {`);
|
|
16240
16597
|
for (const attr of slot.attrs) {
|
|
16241
16598
|
lines.push(`${indent} createEffect(() => {`);
|
|
@@ -16247,15 +16604,19 @@ function stringifyReactiveEffects(lines, plan, opts) {
|
|
|
16247
16604
|
lines.push(`${indent}} }`);
|
|
16248
16605
|
}
|
|
16249
16606
|
for (const text of plan.outerTexts) {
|
|
16250
|
-
emitOuterText(lines, indent, elVar, text, bindingBfId(text.slotId));
|
|
16607
|
+
emitOuterText(lines, indent, elVar, text, bindingBfId(text.slotId), textIndexBySlot?.get(text.slotId));
|
|
16251
16608
|
}
|
|
16252
16609
|
for (const cond of plan.conditionals) {
|
|
16253
16610
|
emitOuterConditional(lines, indent, elVar, cond, pc);
|
|
16254
16611
|
}
|
|
16255
16612
|
}
|
|
16256
|
-
function emitOuterText(lines, indent, elVar, text, bfId = "") {
|
|
16613
|
+
function emitOuterText(lines, indent, elVar, text, bfId = "", pIdx) {
|
|
16257
16614
|
const varName = `__rt_${varSlotId(text.slotId)}`;
|
|
16258
|
-
|
|
16615
|
+
if (pIdx !== undefined) {
|
|
16616
|
+
lines.push(`${indent}{ const ${varName} = __p ? tAfter(__p[${pIdx}]) : $t(${elVar}, '${text.slotId}')[0]`);
|
|
16617
|
+
} else {
|
|
16618
|
+
lines.push(`${indent}{ const [${varName}] = $t(${elVar}, '${text.slotId}')`);
|
|
16619
|
+
}
|
|
16259
16620
|
lines.push(`${indent}if (${varName}) createEffect(() => { ${varName}.textContent = String(${text.wrappedExpression}) }${bfId}) }`);
|
|
16260
16621
|
}
|
|
16261
16622
|
function emitOuterConditional(lines, indent, elVar, cond, pc) {
|
|
@@ -16287,6 +16648,41 @@ function emitArmText(lines, indent, text, pc) {
|
|
|
16287
16648
|
lines.push(`${indent}if (${varName}) createEffect(() => { ${varName}.textContent = String(${text.wrappedExpression}) }${profileBindingId(pc, text.slotId)}) }`);
|
|
16288
16649
|
}
|
|
16289
16650
|
|
|
16651
|
+
// src/ir-to-client-js/control-flow/stringify/skeleton-paths.ts
|
|
16652
|
+
function pathExpr(base, path) {
|
|
16653
|
+
let expr = base;
|
|
16654
|
+
for (const idx of path) {
|
|
16655
|
+
expr += ".firstChild";
|
|
16656
|
+
if (idx > 0)
|
|
16657
|
+
expr += ".nextSibling".repeat(idx);
|
|
16658
|
+
}
|
|
16659
|
+
return expr;
|
|
16660
|
+
}
|
|
16661
|
+
function buildSkeletonPathPlan(skeletonPaths, elVar, opts) {
|
|
16662
|
+
const arrayElems = [];
|
|
16663
|
+
const elementIndexBySlot = new Map;
|
|
16664
|
+
const textIndexBySlot = new Map;
|
|
16665
|
+
for (const slotId of opts.elementSlotIds) {
|
|
16666
|
+
if (elementIndexBySlot.has(slotId))
|
|
16667
|
+
continue;
|
|
16668
|
+
const path = skeletonPaths.elementPaths.get(slotId);
|
|
16669
|
+
if (!path)
|
|
16670
|
+
continue;
|
|
16671
|
+
elementIndexBySlot.set(slotId, arrayElems.length);
|
|
16672
|
+
arrayElems.push(pathExpr(elVar, path));
|
|
16673
|
+
}
|
|
16674
|
+
for (const slotId of opts.textSlotIds) {
|
|
16675
|
+
if (textIndexBySlot.has(slotId))
|
|
16676
|
+
continue;
|
|
16677
|
+
const path = skeletonPaths.textMarkerPaths.get(slotId);
|
|
16678
|
+
if (!path)
|
|
16679
|
+
continue;
|
|
16680
|
+
textIndexBySlot.set(slotId, arrayElems.length);
|
|
16681
|
+
arrayElems.push(pathExpr(elVar, path));
|
|
16682
|
+
}
|
|
16683
|
+
return { arrayElems, elementIndexBySlot, textIndexBySlot };
|
|
16684
|
+
}
|
|
16685
|
+
|
|
16290
16686
|
// src/ir-to-client-js/control-flow/stringify/component-loop.ts
|
|
16291
16687
|
function stringifyComponentLoop(lines, plan) {
|
|
16292
16688
|
const {
|
|
@@ -16346,11 +16742,13 @@ function emitNestedInit(lines, indent, parentVar, nc) {
|
|
|
16346
16742
|
function emitLoopChildRefs(lines, refs, opts) {
|
|
16347
16743
|
if (refs.length === 0)
|
|
16348
16744
|
return;
|
|
16349
|
-
const { indent, elVar, bodyIsMultiRoot } = opts;
|
|
16745
|
+
const { indent, elVar, bodyIsMultiRoot, elementIndexBySlot } = opts;
|
|
16350
16746
|
const lookup = bodyIsMultiRoot ? "qsaItem" : "qsa";
|
|
16351
16747
|
for (const ref of refs) {
|
|
16352
16748
|
const varName = `__rf_${varSlotId(ref.childSlotId)}`;
|
|
16353
|
-
|
|
16749
|
+
const pIdx = elementIndexBySlot?.get(ref.childSlotId);
|
|
16750
|
+
const lookupExpr = pIdx !== undefined ? `__p ? __p[${pIdx}] : ${lookup}(${elVar}, '[bf="${ref.childSlotId}"]')` : `${lookup}(${elVar}, '[bf="${ref.childSlotId}"]')`;
|
|
16751
|
+
lines.push(`${indent}{ const ${varName} = ${lookupExpr}`);
|
|
16354
16752
|
lines.push(`${indent}if (${varName}) ${emitRefCall(ref.callback, varName)} }`);
|
|
16355
16753
|
}
|
|
16356
16754
|
}
|
|
@@ -16430,10 +16828,31 @@ function stringifyPlainLoop(lines, plan, topIndent = " ") {
|
|
|
16430
16828
|
singleRootLayout: "inline"
|
|
16431
16829
|
});
|
|
16432
16830
|
}
|
|
16831
|
+
let pathPlan = null;
|
|
16832
|
+
if (hoistedTpl && plan.skeletonPaths) {
|
|
16833
|
+
const elementSlotIds = [
|
|
16834
|
+
...reactiveEffects?.attrSlots.map((s) => s.slotId) ?? [],
|
|
16835
|
+
...childRefs.map((r) => r.childSlotId)
|
|
16836
|
+
];
|
|
16837
|
+
const textSlotIds = reactiveEffects?.outerTexts.map((t) => t.slotId) ?? [];
|
|
16838
|
+
if (elementSlotIds.length > 0 || textSlotIds.length > 0) {
|
|
16839
|
+
const built = buildSkeletonPathPlan(plan.skeletonPaths, "__el", { elementSlotIds, textSlotIds });
|
|
16840
|
+
if (built.arrayElems.length > 0) {
|
|
16841
|
+
pathPlan = built;
|
|
16842
|
+
lines.push(`${bodyIndent}const __p = __existing ? null : [${built.arrayElems.join(", ")}]`);
|
|
16843
|
+
}
|
|
16844
|
+
}
|
|
16845
|
+
}
|
|
16433
16846
|
if (reactiveEffects !== null) {
|
|
16434
|
-
stringifyReactiveEffects(lines, reactiveEffects, {
|
|
16847
|
+
stringifyReactiveEffects(lines, reactiveEffects, {
|
|
16848
|
+
indent: bodyIndent,
|
|
16849
|
+
elVar: "__el",
|
|
16850
|
+
bodyIsMultiRoot,
|
|
16851
|
+
elementIndexBySlot: pathPlan?.elementIndexBySlot,
|
|
16852
|
+
textIndexBySlot: pathPlan?.textIndexBySlot
|
|
16853
|
+
});
|
|
16435
16854
|
}
|
|
16436
|
-
emitLoopChildRefs(lines, childRefs, { indent: bodyIndent, elVar: "__el", bodyIsMultiRoot });
|
|
16855
|
+
emitLoopChildRefs(lines, childRefs, { indent: bodyIndent, elVar: "__el", bodyIsMultiRoot, elementIndexBySlot: pathPlan?.elementIndexBySlot });
|
|
16437
16856
|
lines.push(`${bodyIndent}return __el`);
|
|
16438
16857
|
lines.push(`${topIndent}}, '${markerId}'${loopBfId})`);
|
|
16439
16858
|
}
|
|
@@ -16500,12 +16919,14 @@ function stringifyStaticLoop(lines, plan) {
|
|
|
16500
16919
|
lines.push(` let __iterEl = ${containerVar}.children[${childIndexExpr}]`);
|
|
16501
16920
|
if (csrMaterialize) {
|
|
16502
16921
|
lines.push(` if (!__iterEl) {`);
|
|
16922
|
+
const isSvg = csrMaterialize.bodyIsMultiRoot ? multiRootTemplateNeedsSvgWrap(csrMaterialize.itemTemplate) : templateRootIsSvg(csrMaterialize.itemTemplate);
|
|
16923
|
+
const itemHtml = isSvg ? `<svg>${csrMaterialize.itemTemplate}</svg>` : csrMaterialize.itemTemplate;
|
|
16503
16924
|
if (csrMaterialize.bodyIsMultiRoot) {
|
|
16504
16925
|
lines.push(` const __mtpl = document.createElement('template')`);
|
|
16505
|
-
lines.push(` __mtpl.innerHTML = \`${
|
|
16926
|
+
lines.push(` __mtpl.innerHTML = \`${itemHtml}\``);
|
|
16506
16927
|
lines.push(` const __anchor = ${containerVar}.children[${childIndexExpr}] ?? null`);
|
|
16507
16928
|
lines.push(` let __first = null`);
|
|
16508
|
-
lines.push(` let __sib = __mtpl.content.firstElementChild`);
|
|
16929
|
+
lines.push(` let __sib = __mtpl.content${isSvg ? ".firstElementChild" : ""}.firstElementChild`);
|
|
16509
16930
|
lines.push(` while (__sib) {`);
|
|
16510
16931
|
lines.push(` const __next = __sib.nextElementSibling`);
|
|
16511
16932
|
lines.push(` const __cloned = __sib.cloneNode(true)`);
|
|
@@ -16516,8 +16937,8 @@ function stringifyStaticLoop(lines, plan) {
|
|
|
16516
16937
|
lines.push(` __iterEl = __first`);
|
|
16517
16938
|
} else {
|
|
16518
16939
|
lines.push(` const __tpl = document.createElement('template')`);
|
|
16519
|
-
lines.push(` __tpl.innerHTML = \`${
|
|
16520
|
-
lines.push(` const __cloned = __tpl.content.firstElementChild`);
|
|
16940
|
+
lines.push(` __tpl.innerHTML = \`${itemHtml}\``);
|
|
16941
|
+
lines.push(` const __cloned = __tpl.content${isSvg ? ".firstElementChild" : ""}.firstElementChild`);
|
|
16521
16942
|
lines.push(` if (__cloned) {`);
|
|
16522
16943
|
lines.push(` const __anchor = ${containerVar}.children[${childIndexExpr}] ?? null`);
|
|
16523
16944
|
lines.push(` ${containerVar}.insertBefore(__cloned, __anchor)`);
|
|
@@ -16584,7 +17005,10 @@ function emitReactive(lines, inner, indent, pc) {
|
|
|
16584
17005
|
lines.push(`${innerIndent} __innerEl${uid}.__bfExtras = __innerExtras${uid}`);
|
|
16585
17006
|
lines.push(`${indent} }`);
|
|
16586
17007
|
} else {
|
|
16587
|
-
|
|
17008
|
+
const isSvg = templateRootIsSvg(emit.wrappedTemplate);
|
|
17009
|
+
const innerHtml = isSvg ? `<svg>${emit.wrappedTemplate}</svg>` : emit.wrappedTemplate;
|
|
17010
|
+
const childPath = isSvg ? ".firstElementChild.firstElementChild" : ".firstElementChild";
|
|
17011
|
+
lines.push(`${indent} let __innerEl${uid} = __existing ?? (() => { const __t = document.createElement('template'); __t.innerHTML = \`${innerHtml}\`; return __t.content${childPath}.cloneNode(true) })()`);
|
|
16588
17012
|
}
|
|
16589
17013
|
if (emit.wrappedKey) {
|
|
16590
17014
|
lines.push(`${indent} __innerEl${uid}.setAttribute('${keyAttrName(inner.keyDepth)}', String(${emit.wrappedKey}))`);
|
|
@@ -17143,6 +17567,7 @@ function buildPlainLoopPlan(elem, profileComponentName) {
|
|
|
17143
17567
|
mapPreambleWrapped: elem.mapPreamble ? wrap(elem.mapPreamble) : "",
|
|
17144
17568
|
template: elem.template,
|
|
17145
17569
|
skeletonTemplate: elem.skeletonTemplate,
|
|
17570
|
+
skeletonPaths: elem.skeletonPaths,
|
|
17146
17571
|
reactiveEffects: hasReactive2 ? buildLoopReactiveEffectsPlan(elem, profileComponentName) : null,
|
|
17147
17572
|
childRefs: buildChildRefBindings(elem.bindings.refs, elem.param, elem.paramBindings),
|
|
17148
17573
|
bodyIsMultiRoot: elem.bodyIsMultiRoot ?? false,
|
|
@@ -20116,6 +20541,8 @@ function isStringTypedOperand(expr, isStringName) {
|
|
|
20116
20541
|
if (expr.kind === "member" && expr.object.kind === "identifier" && expr.object.name === "props") {
|
|
20117
20542
|
return isStringName(expr.property);
|
|
20118
20543
|
}
|
|
20544
|
+
if (expr.kind === "identifier")
|
|
20545
|
+
return isStringName(expr.name);
|
|
20119
20546
|
if (expr.kind === "binary" && expr.op === "+") {
|
|
20120
20547
|
return isStringTypedOperand(expr.left, isStringName) || isStringTypedOperand(expr.right, isStringName);
|
|
20121
20548
|
}
|
|
@@ -20175,6 +20602,221 @@ function emitParsedExpr(expr, emitter) {
|
|
|
20175
20602
|
}
|
|
20176
20603
|
}
|
|
20177
20604
|
}
|
|
20605
|
+
// src/adapters/loop-bound-names.ts
|
|
20606
|
+
function collectLoopBoundNames(ir) {
|
|
20607
|
+
const names = new Set;
|
|
20608
|
+
const visit3 = (node) => {
|
|
20609
|
+
if (!node)
|
|
20610
|
+
return;
|
|
20611
|
+
switch (node.type) {
|
|
20612
|
+
case "element":
|
|
20613
|
+
case "component":
|
|
20614
|
+
case "fragment":
|
|
20615
|
+
case "provider":
|
|
20616
|
+
for (const child of node.children)
|
|
20617
|
+
visit3(child);
|
|
20618
|
+
break;
|
|
20619
|
+
case "async":
|
|
20620
|
+
visit3(node.fallback);
|
|
20621
|
+
for (const child of node.children)
|
|
20622
|
+
visit3(child);
|
|
20623
|
+
break;
|
|
20624
|
+
case "loop":
|
|
20625
|
+
names.add(node.param);
|
|
20626
|
+
if (node.index)
|
|
20627
|
+
names.add(node.index);
|
|
20628
|
+
for (const binding of node.paramBindings ?? [])
|
|
20629
|
+
names.add(binding.name);
|
|
20630
|
+
if (node.filterPredicate)
|
|
20631
|
+
names.add(node.filterPredicate.param);
|
|
20632
|
+
for (const child of node.children)
|
|
20633
|
+
visit3(child);
|
|
20634
|
+
if (node.childComponent) {
|
|
20635
|
+
for (const child of node.childComponent.children)
|
|
20636
|
+
visit3(child);
|
|
20637
|
+
}
|
|
20638
|
+
for (const nested of node.nestedComponents ?? []) {
|
|
20639
|
+
for (const child of nested.children)
|
|
20640
|
+
visit3(child);
|
|
20641
|
+
}
|
|
20642
|
+
for (const frag of node.flatMapCallback?.fragments ?? []) {
|
|
20643
|
+
visit3(frag.ir);
|
|
20644
|
+
}
|
|
20645
|
+
break;
|
|
20646
|
+
case "conditional":
|
|
20647
|
+
visit3(node.whenTrue);
|
|
20648
|
+
visit3(node.whenFalse);
|
|
20649
|
+
break;
|
|
20650
|
+
case "if-statement":
|
|
20651
|
+
visit3(node.consequent);
|
|
20652
|
+
if (node.alternate)
|
|
20653
|
+
visit3(node.alternate);
|
|
20654
|
+
break;
|
|
20655
|
+
case "text":
|
|
20656
|
+
case "expression":
|
|
20657
|
+
case "slot":
|
|
20658
|
+
break;
|
|
20659
|
+
}
|
|
20660
|
+
};
|
|
20661
|
+
visit3(ir.root);
|
|
20662
|
+
return names;
|
|
20663
|
+
}
|
|
20664
|
+
// src/signal-init-eval.ts
|
|
20665
|
+
var BLOCKED_GLOBALS = [
|
|
20666
|
+
"globalThis",
|
|
20667
|
+
"window",
|
|
20668
|
+
"document",
|
|
20669
|
+
"Date",
|
|
20670
|
+
"Math",
|
|
20671
|
+
"crypto",
|
|
20672
|
+
"performance",
|
|
20673
|
+
"fetch",
|
|
20674
|
+
"setTimeout",
|
|
20675
|
+
"setInterval",
|
|
20676
|
+
"require",
|
|
20677
|
+
"process",
|
|
20678
|
+
"Function"
|
|
20679
|
+
];
|
|
20680
|
+
function isTransportable(value, ancestors = new Set) {
|
|
20681
|
+
if (value === null)
|
|
20682
|
+
return true;
|
|
20683
|
+
const t = typeof value;
|
|
20684
|
+
if (t === "boolean" || t === "number" || t === "string")
|
|
20685
|
+
return true;
|
|
20686
|
+
if (t !== "object")
|
|
20687
|
+
return false;
|
|
20688
|
+
if (ancestors.has(value))
|
|
20689
|
+
return false;
|
|
20690
|
+
ancestors.add(value);
|
|
20691
|
+
try {
|
|
20692
|
+
if (Array.isArray(value)) {
|
|
20693
|
+
if (Object.keys(value).length !== value.length)
|
|
20694
|
+
return false;
|
|
20695
|
+
return value.every((el) => el !== undefined && isTransportable(el, ancestors));
|
|
20696
|
+
}
|
|
20697
|
+
const proto = Object.getPrototypeOf(value);
|
|
20698
|
+
if (proto !== Object.prototype && proto !== null)
|
|
20699
|
+
return false;
|
|
20700
|
+
return Object.values(value).every((v) => isTransportable(v, ancestors));
|
|
20701
|
+
} finally {
|
|
20702
|
+
ancestors.delete(value);
|
|
20703
|
+
}
|
|
20704
|
+
}
|
|
20705
|
+
function tryEvaluateSignalInit(expr, props) {
|
|
20706
|
+
const src = expr.trim();
|
|
20707
|
+
if (src === "")
|
|
20708
|
+
return { ok: false };
|
|
20709
|
+
let fn;
|
|
20710
|
+
try {
|
|
20711
|
+
fn = new Function("props", ...BLOCKED_GLOBALS, `'use strict'; return (
|
|
20712
|
+
${src}
|
|
20713
|
+
);`);
|
|
20714
|
+
} catch {
|
|
20715
|
+
return { ok: false };
|
|
20716
|
+
}
|
|
20717
|
+
try {
|
|
20718
|
+
const value = fn(props ?? {});
|
|
20719
|
+
if (value === undefined)
|
|
20720
|
+
return { ok: true, value: undefined };
|
|
20721
|
+
return isTransportable(value) ? { ok: true, value } : { ok: false };
|
|
20722
|
+
} catch {
|
|
20723
|
+
return { ok: false };
|
|
20724
|
+
}
|
|
20725
|
+
}
|
|
20726
|
+
function evaluateSignalInit(expr, props) {
|
|
20727
|
+
const result = tryEvaluateSignalInit(expr, props);
|
|
20728
|
+
return result.ok && result.value !== undefined ? result.value : null;
|
|
20729
|
+
}
|
|
20730
|
+
// src/static-literal.ts
|
|
20731
|
+
function evaluateStaticLiteral(expr, bindings) {
|
|
20732
|
+
switch (expr.kind) {
|
|
20733
|
+
case "literal":
|
|
20734
|
+
return { value: expr.value };
|
|
20735
|
+
case "template-literal": {
|
|
20736
|
+
let out = "";
|
|
20737
|
+
for (const part of expr.parts) {
|
|
20738
|
+
if (part.type === "string") {
|
|
20739
|
+
out += part.value;
|
|
20740
|
+
continue;
|
|
20741
|
+
}
|
|
20742
|
+
const resolved = evaluateStaticLiteral(part.expr, bindings);
|
|
20743
|
+
if (!resolved)
|
|
20744
|
+
return null;
|
|
20745
|
+
out += String(resolved.value);
|
|
20746
|
+
}
|
|
20747
|
+
return { value: out };
|
|
20748
|
+
}
|
|
20749
|
+
case "array-literal": {
|
|
20750
|
+
const values = [];
|
|
20751
|
+
for (const element of expr.elements) {
|
|
20752
|
+
const resolved = evaluateStaticLiteral(element, bindings);
|
|
20753
|
+
if (!resolved)
|
|
20754
|
+
return null;
|
|
20755
|
+
values.push(resolved.value);
|
|
20756
|
+
}
|
|
20757
|
+
return { value: values };
|
|
20758
|
+
}
|
|
20759
|
+
case "object-literal": {
|
|
20760
|
+
const out = {};
|
|
20761
|
+
for (const prop of expr.properties) {
|
|
20762
|
+
const resolved = evaluateStaticLiteral(prop.value, bindings);
|
|
20763
|
+
if (!resolved)
|
|
20764
|
+
return null;
|
|
20765
|
+
out[prop.key] = resolved.value;
|
|
20766
|
+
}
|
|
20767
|
+
return { value: out };
|
|
20768
|
+
}
|
|
20769
|
+
case "unary": {
|
|
20770
|
+
const resolved = evaluateStaticLiteral(expr.argument, bindings);
|
|
20771
|
+
if (!resolved)
|
|
20772
|
+
return null;
|
|
20773
|
+
if (expr.op === "-")
|
|
20774
|
+
return typeof resolved.value === "number" ? { value: -resolved.value } : null;
|
|
20775
|
+
if (expr.op === "+")
|
|
20776
|
+
return typeof resolved.value === "number" ? { value: +resolved.value } : null;
|
|
20777
|
+
if (expr.op === "!")
|
|
20778
|
+
return { value: !resolved.value };
|
|
20779
|
+
return null;
|
|
20780
|
+
}
|
|
20781
|
+
case "identifier":
|
|
20782
|
+
return bindings?.has(expr.name) ? { value: bindings.get(expr.name) } : null;
|
|
20783
|
+
case "member": {
|
|
20784
|
+
const base = evaluateStaticLiteral(expr.object, bindings);
|
|
20785
|
+
if (!base || base.value === null || typeof base.value !== "object")
|
|
20786
|
+
return null;
|
|
20787
|
+
return { value: base.value[expr.property] };
|
|
20788
|
+
}
|
|
20789
|
+
case "index-access": {
|
|
20790
|
+
const base = evaluateStaticLiteral(expr.object, bindings);
|
|
20791
|
+
const index = evaluateStaticLiteral(expr.index, bindings);
|
|
20792
|
+
if (!base || !index || !Array.isArray(base.value) || typeof index.value !== "number")
|
|
20793
|
+
return null;
|
|
20794
|
+
return { value: base.value[index.value] };
|
|
20795
|
+
}
|
|
20796
|
+
default:
|
|
20797
|
+
return null;
|
|
20798
|
+
}
|
|
20799
|
+
}
|
|
20800
|
+
function isFullyStaticLiteral(expr) {
|
|
20801
|
+
return evaluateStaticLiteral(expr) !== null;
|
|
20802
|
+
}
|
|
20803
|
+
function resolveStaticLoopSource(arrayParsed, localConstants, opts) {
|
|
20804
|
+
if (!arrayParsed)
|
|
20805
|
+
return null;
|
|
20806
|
+
let target = arrayParsed;
|
|
20807
|
+
if (arrayParsed.kind === "identifier") {
|
|
20808
|
+
if (opts?.isNameShadowed?.(arrayParsed.name))
|
|
20809
|
+
return null;
|
|
20810
|
+
const local = localConstants?.find((c) => c.name === arrayParsed.name);
|
|
20811
|
+
if (!local || local.isModule || !local.parsed)
|
|
20812
|
+
return null;
|
|
20813
|
+
target = local.parsed;
|
|
20814
|
+
}
|
|
20815
|
+
const resolved = evaluateStaticLiteral(target);
|
|
20816
|
+
if (!resolved || !Array.isArray(resolved.value))
|
|
20817
|
+
return null;
|
|
20818
|
+
return resolved.value;
|
|
20819
|
+
}
|
|
20178
20820
|
// src/query-href-lowering.ts
|
|
20179
20821
|
function matchQueryHrefCall(callee, args, localNames) {
|
|
20180
20822
|
if (callee.kind !== "identifier" || !localNames.has(callee.name))
|
|
@@ -20310,6 +20952,71 @@ function emitAttrValue(value, emitter, name) {
|
|
|
20310
20952
|
}
|
|
20311
20953
|
}
|
|
20312
20954
|
}
|
|
20955
|
+
// src/adapters/dangerous-inner-html.ts
|
|
20956
|
+
var DANGEROUS_INNER_HTML_ATTR = "dangerouslySetInnerHTML";
|
|
20957
|
+
function isDangerousInnerHtmlAttr(attr) {
|
|
20958
|
+
return attr.name === DANGEROUS_INNER_HTML_ATTR;
|
|
20959
|
+
}
|
|
20960
|
+
function resolveDangerousInnerHtml(element) {
|
|
20961
|
+
const attr = element.attrs.find(isDangerousInnerHtmlAttr);
|
|
20962
|
+
if (!attr)
|
|
20963
|
+
return null;
|
|
20964
|
+
if (attr.clientOnly)
|
|
20965
|
+
return null;
|
|
20966
|
+
if (attr.value.kind !== "expression") {
|
|
20967
|
+
return { kind: "dynamic", expr: "", loc: attr.loc };
|
|
20968
|
+
}
|
|
20969
|
+
const parsed = attr.value.parsed ?? parseExpression(attr.value.expr.trim());
|
|
20970
|
+
const html = staticHtmlLiteral(parsed);
|
|
20971
|
+
if (html !== null)
|
|
20972
|
+
return { kind: "static", html };
|
|
20973
|
+
return { kind: "dynamic", expr: attr.value.expr, loc: attr.loc };
|
|
20974
|
+
}
|
|
20975
|
+
function staticHtmlLiteral(parsed) {
|
|
20976
|
+
if (parsed.kind !== "object-literal")
|
|
20977
|
+
return null;
|
|
20978
|
+
if (parsed.properties.length !== 1)
|
|
20979
|
+
return null;
|
|
20980
|
+
const [prop] = parsed.properties;
|
|
20981
|
+
if (prop.shorthand)
|
|
20982
|
+
return null;
|
|
20983
|
+
if (prop.key !== "__html")
|
|
20984
|
+
return null;
|
|
20985
|
+
if (prop.value.kind !== "literal" || prop.value.literalType !== "string")
|
|
20986
|
+
return null;
|
|
20987
|
+
return prop.value.value;
|
|
20988
|
+
}
|
|
20989
|
+
var TEMPLATE_METACHAR_PATTERNS = {
|
|
20990
|
+
blade: /\{\{|\{!!|<\?|@\w|<\/?\s*x[-:]/,
|
|
20991
|
+
erb: /<%/,
|
|
20992
|
+
"go-template": /\{\{/,
|
|
20993
|
+
jinja: /\{\{|\{%|\{#/,
|
|
20994
|
+
minijinja: /\{\{|\{%|\{#/,
|
|
20995
|
+
mojolicious: /<%|^\s*%/m,
|
|
20996
|
+
twig: /\{\{|\{%|\{#/,
|
|
20997
|
+
xslate: /<:|^\s*:/m
|
|
20998
|
+
};
|
|
20999
|
+
function dangerousInnerHtmlMetacharViolation(html, adapterId) {
|
|
21000
|
+
const pattern = TEMPLATE_METACHAR_PATTERNS[adapterId];
|
|
21001
|
+
if (!pattern) {
|
|
21002
|
+
return `no template-metacharacter guard is defined for adapter '${adapterId}' — refusing rather than splicing unguarded`;
|
|
21003
|
+
}
|
|
21004
|
+
if (!pattern.test(html))
|
|
21005
|
+
return null;
|
|
21006
|
+
return `the literal HTML contains a sequence ${adapterId}'s own template compiler would interpret (not inert text once spliced into the template)`;
|
|
21007
|
+
}
|
|
21008
|
+
function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
|
|
21009
|
+
const detail = reason ? ` — ${reason}.` : "";
|
|
21010
|
+
return {
|
|
21011
|
+
code: "BF101",
|
|
21012
|
+
severity: "error",
|
|
21013
|
+
message: `dangerouslySetInnerHTML requires a compile-time string literal __html value on template adapters (e.g. { __html: '...' })${expr ? `: ${expr.trim()}` : ""}${detail}`,
|
|
21014
|
+
loc,
|
|
21015
|
+
suggestion: {
|
|
21016
|
+
message: "Dynamic or signal-derived HTML for dangerouslySetInnerHTML is only supported on Hono/CSR today (tracked separately: https://github.com/piconic-ai/barefootjs/issues/2215). Use an inline string literal, or defer it to the client with /* @client */ (e.g. dangerouslySetInnerHTML={/* @client */ { __html: expr }}) so hydration sets it instead of SSR."
|
|
21017
|
+
}
|
|
21018
|
+
};
|
|
21019
|
+
}
|
|
20313
21020
|
// src/combine-client-js.ts
|
|
20314
21021
|
import ts19 from "typescript";
|
|
20315
21022
|
var CHILD_PLACEHOLDER_RE = /import '\/\* @bf-child:(\w+) \*\/'/g;
|
|
@@ -23151,6 +23858,7 @@ function profileToJSON(profile) {
|
|
|
23151
23858
|
registerBuiltinLoweringPlugins();
|
|
23152
23859
|
export {
|
|
23153
23860
|
tsNodeToParsedExpr,
|
|
23861
|
+
tryEvaluateSignalInit,
|
|
23154
23862
|
traceUpdatePath,
|
|
23155
23863
|
testAdapter,
|
|
23156
23864
|
stringifyParsedExpr,
|
|
@@ -23158,7 +23866,9 @@ export {
|
|
|
23158
23866
|
serializeParsedExpr,
|
|
23159
23867
|
searchParamsLocalNames,
|
|
23160
23868
|
rewriteImportsForTemplate,
|
|
23869
|
+
resolveStaticLoopSource,
|
|
23161
23870
|
resolveSetters,
|
|
23871
|
+
resolveDangerousInnerHtml,
|
|
23162
23872
|
resetCompilerCounters,
|
|
23163
23873
|
renderImportMapHtml,
|
|
23164
23874
|
registerLoweringPlugin,
|
|
@@ -23193,6 +23903,8 @@ export {
|
|
|
23193
23903
|
isStringConcatBinary,
|
|
23194
23904
|
isLowerableObjectRestDestructure,
|
|
23195
23905
|
isLowerableLoopDestructure,
|
|
23906
|
+
isFullyStaticLiteral,
|
|
23907
|
+
isDangerousInnerHtmlAttr,
|
|
23196
23908
|
isBooleanAttr,
|
|
23197
23909
|
importsSearchParams,
|
|
23198
23910
|
identifierPath,
|
|
@@ -23233,6 +23945,8 @@ export {
|
|
|
23233
23945
|
extractFunctionParams,
|
|
23234
23946
|
extractArrowBodyExpression,
|
|
23235
23947
|
exprToString,
|
|
23948
|
+
evaluateStaticLiteral,
|
|
23949
|
+
evaluateSignalInit,
|
|
23236
23950
|
evaluateProfileGates,
|
|
23237
23951
|
evalStringArrayJoin,
|
|
23238
23952
|
envSignalReaderFor,
|
|
@@ -23245,6 +23959,8 @@ export {
|
|
|
23245
23959
|
diffStaticBudget,
|
|
23246
23960
|
diffProfiles,
|
|
23247
23961
|
describeFallback,
|
|
23962
|
+
dangerousInnerHtmlMetacharViolation,
|
|
23963
|
+
dangerousInnerHtmlDiagnostic,
|
|
23248
23964
|
createProgramForFile,
|
|
23249
23965
|
createProgramForCorpus,
|
|
23250
23966
|
createError,
|
|
@@ -23253,6 +23969,7 @@ export {
|
|
|
23253
23969
|
compileJSX,
|
|
23254
23970
|
combineParentChildClientJs,
|
|
23255
23971
|
collectModuleStringConsts,
|
|
23972
|
+
collectLoopBoundNames,
|
|
23256
23973
|
collectContextConsumers,
|
|
23257
23974
|
buildWhyUpdate,
|
|
23258
23975
|
buildStaticBudget,
|
|
@@ -23283,6 +24000,7 @@ export {
|
|
|
23283
24000
|
SourceMapGenerator,
|
|
23284
24001
|
REACTIVE_PRIMITIVES,
|
|
23285
24002
|
PROFILE_SCHEMA_VERSION,
|
|
24003
|
+
PARSED_EXPR_KINDS,
|
|
23286
24004
|
JsxAdapter,
|
|
23287
24005
|
ErrorCodes,
|
|
23288
24006
|
ENV_SIGNAL_READERS,
|