marko 6.3.51 → 6.3.52

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.
Files changed (67) hide show
  1. package/dist/debug/dom/catch.feat.js +1 -1
  2. package/dist/debug/dom/catch.feat.mjs +1 -1
  3. package/dist/debug/dom/controllable-input.feat.js +1 -1
  4. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  5. package/dist/debug/dom/controllable-open.feat.js +1 -1
  6. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  7. package/dist/debug/dom/controllable-select.feat.js +1 -1
  8. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  9. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  10. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  11. package/dist/debug/dom/controllable.feat.js +1 -1
  12. package/dist/debug/dom/controllable.feat.mjs +1 -1
  13. package/dist/debug/dom/dynamic-tag-var.feat.js +2 -3
  14. package/dist/debug/dom/dynamic-tag-var.feat.mjs +2 -3
  15. package/dist/debug/dom/placeholder.feat.js +2 -2
  16. package/dist/debug/dom/placeholder.feat.mjs +2 -2
  17. package/dist/debug/{dom-BAGeiafn.js → dom-BJKb8-wr.js} +22 -27
  18. package/dist/debug/{dom-C55iHvof.mjs → dom-Dq_Yu7MS.mjs} +19 -18
  19. package/dist/debug/dom.js +10 -10
  20. package/dist/debug/dom.mjs +10 -10
  21. package/dist/debug/html.js +56 -40
  22. package/dist/debug/html.mjs +56 -40
  23. package/dist/dom/catch.feat.js +3 -3
  24. package/dist/dom/catch.feat.mjs +1 -1
  25. package/dist/dom/controllable-input.feat.js +1 -1
  26. package/dist/dom/controllable-input.feat.mjs +1 -1
  27. package/dist/dom/controllable-open.feat.js +1 -1
  28. package/dist/dom/controllable-open.feat.mjs +1 -1
  29. package/dist/dom/controllable-select.feat.js +1 -1
  30. package/dist/dom/controllable-select.feat.mjs +1 -1
  31. package/dist/dom/controllable-textarea.feat.js +1 -1
  32. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  33. package/dist/dom/controllable.feat.js +1 -1
  34. package/dist/dom/controllable.feat.mjs +1 -1
  35. package/dist/dom/dynamic-tag-var.feat.js +3 -2
  36. package/dist/dom/dynamic-tag-var.feat.mjs +4 -3
  37. package/dist/dom/placeholder.feat.js +3 -3
  38. package/dist/dom/placeholder.feat.mjs +2 -2
  39. package/dist/dom/resume.d.ts +1 -2
  40. package/dist/{dom-BNmfm4st.js → dom-CzGPOsST.js} +62 -71
  41. package/dist/{dom-BsAS26Ze.mjs → dom-CzfddxCE.mjs} +15 -19
  42. package/dist/dom.d.ts +1 -1
  43. package/dist/dom.js +30 -30
  44. package/dist/dom.mjs +10 -10
  45. package/dist/html/template.d.ts +3 -1
  46. package/dist/html/writer.d.ts +6 -1
  47. package/dist/html.js +40 -25
  48. package/dist/html.mjs +40 -25
  49. package/dist/translator/core/await.d.ts +0 -7
  50. package/dist/translator/core/try.d.ts +0 -7
  51. package/dist/translator/index.d.ts +1 -1
  52. package/dist/translator/index.js +1888 -1656
  53. package/dist/translator/util/binding-has-prop.d.ts +1 -1
  54. package/dist/translator/util/cyclic-memo.d.ts +4 -0
  55. package/dist/translator/util/evaluate.d.ts +2 -0
  56. package/dist/translator/util/optional.d.ts +21 -7
  57. package/dist/translator/util/references.d.ts +53 -21
  58. package/dist/translator/util/runtime.d.ts +3 -1
  59. package/dist/translator/util/sections.d.ts +10 -11
  60. package/dist/translator/util/serialize-guard.d.ts +10 -0
  61. package/dist/translator/util/serialize-reasons.d.ts +10 -11
  62. package/dist/translator/util/set-tag-sections-downstream.d.ts +3 -2
  63. package/dist/translator/util/tag-name-type.d.ts +8 -3
  64. package/dist/translator/visitors/tag/dynamic-tag.d.ts +0 -2
  65. package/index.d.ts +0 -5
  66. package/package.json +3 -3
  67. package/tags-html.d.ts +2 -0
@@ -204,6 +204,58 @@ const Subscriptions$1 = "#Subscriptions";
204
204
  const TagVariable$1 = "#TagVariable";
205
205
  const TagVariableChange$2 = "#TagVariableChange";
206
206
  //#endregion
207
+ //#region src/translator/util/traverse.ts
208
+ const skip = Symbol("skip");
209
+ function traverseReplace(container, key, enter, state) {
210
+ const node = container[key];
211
+ if (node) if (Array.isArray(node)) for (let i = node.length; i--;) traverseReplace(node, i, enter, state);
212
+ else {
213
+ const keys = _marko_compiler.types.VISITOR_KEYS[node.type];
214
+ for (let i = keys.length; i--;) traverseReplace(node, keys[i], enter, state);
215
+ const replacement = enter(node, state);
216
+ if (replacement) container[key] = replacement;
217
+ }
218
+ }
219
+ function traverseContains(node, check) {
220
+ return !!traverseFind(node, check);
221
+ }
222
+ function traverseFind(node, check) {
223
+ if (node) if (Array.isArray(node)) for (const item of node) {
224
+ const found = traverseFind(item, check);
225
+ if (found) return found;
226
+ }
227
+ else {
228
+ switch (check(node)) {
229
+ case true: return node;
230
+ case skip: return;
231
+ }
232
+ for (const key of _marko_compiler.types.VISITOR_KEYS[node.type]) {
233
+ const found = traverseFind(node[key], check);
234
+ if (found) return found;
235
+ }
236
+ }
237
+ }
238
+ function traverseFindAwait(node) {
239
+ return traverseFind(node, (child) => {
240
+ switch (child.type) {
241
+ case "ForOfStatement": return child.await;
242
+ case "FunctionDeclaration":
243
+ case "FunctionExpression":
244
+ case "ArrowFunctionExpression":
245
+ case "ClassMethod":
246
+ case "ObjectMethod":
247
+ case "ClassPrivateMethod": return skip;
248
+ case "AwaitExpression": return true;
249
+ }
250
+ });
251
+ }
252
+ function traverse(visit, node, parent, grandParent) {
253
+ if (node) {
254
+ if (Array.isArray(node)) for (const item of node) traverse(visit, item, parent, grandParent);
255
+ else if (visit(node, parent, grandParent) !== skip) for (const key of _marko_compiler.types.VISITOR_KEYS[node.type]) traverse(visit, node[key], node, parent);
256
+ }
257
+ }
258
+ //#endregion
207
259
  //#region src/translator/util/evaluate.ts
208
260
  function evaluate(value) {
209
261
  let { extra } = value;
@@ -214,14 +266,36 @@ function evaluate(value) {
214
266
  extra.computed = computed.value;
215
267
  extra.confident = true;
216
268
  extra.nullable = computed.value == null;
269
+ extra.pure = true;
217
270
  } else {
218
271
  extra.computed = void 0;
219
272
  extra.confident = false;
220
273
  extra.nullable = isNullableExpr(value);
274
+ extra.pure = !traverseContains(value, isImpure);
221
275
  }
222
276
  }
223
277
  return extra;
224
278
  }
279
+ function isImpure(node) {
280
+ switch (node.type) {
281
+ case "ArrowFunctionExpression":
282
+ case "ClassPrivateMethod":
283
+ case "ClassPrivateProperty":
284
+ case "FunctionExpression": return skip;
285
+ case "ClassMethod":
286
+ case "ObjectMethod": return node.computed && traverseContains(node.key, isImpure) || skip;
287
+ case "ClassAccessorProperty":
288
+ case "ClassProperty": return node.static ? void 0 : node.computed && traverseContains(node.key, isImpure) || skip;
289
+ case "CallExpression": return node.callee.type === "ArrowFunctionExpression" || node.callee.type === "FunctionExpression" ? traverseContains(node.arguments, isImpure) || traverseContains(node.callee.params, isImpure) || traverseContains(node.callee.body, isImpure) || skip : true;
290
+ case "AssignmentExpression":
291
+ case "NewExpression":
292
+ case "OptionalCallExpression":
293
+ case "TaggedTemplateExpression":
294
+ case "ThrowStatement":
295
+ case "UpdateExpression": return true;
296
+ case "UnaryExpression": return node.operator === "delete";
297
+ }
298
+ }
225
299
  function isNullableExpr(expr) {
226
300
  switch (expr.type) {
227
301
  case "ArrayExpression":
@@ -392,58 +466,6 @@ function getCompileStage(file = (0, _marko_compiler_babel_utils.getFile)()) {
392
466
  return file.___compileStage;
393
467
  }
394
468
  //#endregion
395
- //#region src/translator/util/traverse.ts
396
- const skip = Symbol("skip");
397
- function traverseReplace(container, key, enter, state) {
398
- const node = container[key];
399
- if (node) if (Array.isArray(node)) for (let i = node.length; i--;) traverseReplace(node, i, enter, state);
400
- else {
401
- const keys = _marko_compiler.types.VISITOR_KEYS[node.type];
402
- for (let i = keys.length; i--;) traverseReplace(node, keys[i], enter, state);
403
- const replacement = enter(node, state);
404
- if (replacement) container[key] = replacement;
405
- }
406
- }
407
- function traverseContains(node, check) {
408
- return !!traverseFind(node, check);
409
- }
410
- function traverseFind(node, check) {
411
- if (node) if (Array.isArray(node)) for (const item of node) {
412
- const found = traverseFind(item, check);
413
- if (found) return found;
414
- }
415
- else {
416
- switch (check(node)) {
417
- case true: return node;
418
- case skip: return;
419
- }
420
- for (const key of _marko_compiler.types.VISITOR_KEYS[node.type]) {
421
- const found = traverseFind(node[key], check);
422
- if (found) return found;
423
- }
424
- }
425
- }
426
- function traverseFindAwait(node) {
427
- return traverseFind(node, (child) => {
428
- switch (child.type) {
429
- case "ForOfStatement": return child.await;
430
- case "FunctionDeclaration":
431
- case "FunctionExpression":
432
- case "ArrowFunctionExpression":
433
- case "ClassMethod":
434
- case "ObjectMethod":
435
- case "ClassPrivateMethod": return skip;
436
- case "AwaitExpression": return true;
437
- }
438
- });
439
- }
440
- function traverse(visit, node, parent, grandParent) {
441
- if (node) {
442
- if (Array.isArray(node)) for (const item of node) traverse(visit, item, parent, grandParent);
443
- else if (visit(node, parent, grandParent) !== skip) for (const key of _marko_compiler.types.VISITOR_KEYS[node.type]) traverse(visit, node[key], node, parent);
444
- }
445
- }
446
- //#endregion
447
469
  //#region src/translator/util/generate-uid.ts
448
470
  const countsForFile = /* @__PURE__ */ new WeakMap();
449
471
  function generateUid(name = "") {
@@ -703,6 +725,9 @@ var Sorted = class {
703
725
  }
704
726
  return b;
705
727
  }
728
+ filter(data, cb) {
729
+ return filter(data, cb);
730
+ }
706
731
  find(data, item) {
707
732
  if (data !== void 0) {
708
733
  if (Array.isArray(data)) return findSorted(this.compare, data, item);
@@ -757,6 +782,9 @@ function concat(a, b) {
757
782
  }
758
783
  return b;
759
784
  }
785
+ function size(data) {
786
+ return data !== void 0 ? Array.isArray(data) ? data.length : 1 : 0;
787
+ }
760
788
  function filter(data, cb) {
761
789
  if (data !== void 0) {
762
790
  if (Array.isArray(data)) {
@@ -816,6 +844,12 @@ function find(data, cb) {
816
844
  function some(data, cb) {
817
845
  return data !== void 0 ? Array.isArray(data) ? data.some(cb) : !!cb(data, 0) : false;
818
846
  }
847
+ function every(data, cb) {
848
+ return data !== void 0 ? Array.isArray(data) ? data.every(cb) : !!cb(data, 0) : true;
849
+ }
850
+ function reduce(data, cb, initial) {
851
+ return data !== void 0 ? Array.isArray(data) ? data.reduce(cb, initial) : cb(initial, data, 0) : initial;
852
+ }
819
853
  function toArray(data, cb) {
820
854
  return data !== void 0 ? Array.isArray(data) ? data.map(cb) : [cb(data, 0)] : [];
821
855
  }
@@ -914,305 +948,134 @@ function joinRepeatable(compare, a, b) {
914
948
  const compareResult = compare(a, b);
915
949
  return compareResult === 0 ? a : compareResult < 0 ? [a, b] : [b, a];
916
950
  }
917
- //#endregion
918
- //#region src/common/constants/accessor-prefix.ts
919
- var accessor_prefix_exports = /* @__PURE__ */ __exportAll({
920
- BranchScopes: () => "A",
921
- ClosureScopes: () => "B",
922
- ClosureSignalIndex: () => "C",
923
- ConditionalRenderer: () => "D",
924
- ControlledHandler: () => "E",
925
- ControlledObserver: () => "N",
926
- ControlledType: () => "F",
927
- ControlledValue: () => "G",
928
- DynamicHTMLLastChild: () => "H",
929
- EventAttributes: () => "I",
930
- IdFallback: () => "J",
931
- KeyedScopes: () => "O",
932
- Lifecycle: () => "K",
933
- Promise: () => "L",
934
- TagVariableChange: () => "M"
935
- });
936
- //#endregion
937
- //#region src/common/constants/accessor-prop.ts
938
- var accessor_prop_exports = /* @__PURE__ */ __exportAll({
939
- AbortControllers: () => "A",
940
- AbortScopes: () => "B",
941
- AwaitCounter: () => "O",
942
- BranchAccessor: () => "C",
943
- BranchScopes: () => "D",
944
- CatchContent: () => "E",
945
- ClosestBranch: () => "F",
946
- ClosestBranchId: () => "G",
947
- DetachedAwait: () => "V",
948
- EndNode: () => "K",
949
- Gen: () => "H",
950
- Global: () => "$",
951
- Id: () => "L",
952
- Load: () => "X",
953
- LoopIndex: () => "I",
954
- LoopKey: () => "M",
955
- Owner: () => "_",
956
- ParentBranch: () => "N",
957
- PendingEffects: () => "J",
958
- PendingRenders: () => "W",
959
- PendingScopes: () => "Y",
960
- PlaceholderBranch: () => "P",
961
- PlaceholderContent: () => "Q",
962
- Renderer: () => "R",
963
- StartNode: () => "S",
964
- Subscriptions: () => "Z",
965
- TagVariable: () => "T",
966
- TagVariableChange: () => "U"
967
- });
968
- //#endregion
969
- //#region src/translator/util/marko-config.ts
970
- function isOutputHTML() {
971
- return getMarkoOpts().output === "html";
972
- }
973
- function isOutputDOM() {
974
- return getMarkoOpts().output === "dom";
975
- }
976
- function getMarkoOpts() {
977
- return (0, _marko_compiler_babel_utils.getFile)().markoOpts;
978
- }
979
- function isOptimize() {
980
- return getMarkoOpts().optimize;
951
+ function addUnique(data, item) {
952
+ return includes(data, item) ? data : push(data, item);
981
953
  }
982
- function getReadyId(file = (0, _marko_compiler_babel_utils.getFile)()) {
983
- const { markoOpts } = file;
984
- if (!markoOpts.linkAssets) return void 0;
985
- return (markoOpts.optimize ? "_" : "ready:") + (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, file.opts.filename);
954
+ function at(data, index) {
955
+ return Array.isArray(data) ? data[index] : index ? void 0 : data;
986
956
  }
987
- //#endregion
988
- //#region src/translator/util/get-accessor-enums.ts
989
- function getAccessorPrefix() {
990
- return isOptimize() ? accessor_prefix_exports : accessor_prefix_debug_exports;
957
+ function first(data) {
958
+ return Array.isArray(data) ? data[0] : data;
991
959
  }
992
- function getAccessorProp() {
993
- return isOptimize() ? accessor_prop_exports : accessor_prop_debug_exports;
960
+ function rest(data) {
961
+ return Array.isArray(data) ? data.length === 2 ? data[1] : data.slice(1) : void 0;
994
962
  }
995
963
  //#endregion
996
- //#region src/translator/util/serialize-reasons.ts
997
- const sourcesUtil = new Sorted(compareSources);
998
- function isSameReason(a, b) {
999
- return a === b || (a && b ? a !== true && b !== true && compareSources(a, b) === 0 : false);
1000
- }
1001
- function isForceSerialized(section, prop, prefix) {
1002
- return true === (prop ? section.serializeReasons.get(getPropKey(section, prop, prefix)) : section.serializeReason);
1003
- }
1004
- function addSerializeReason(section, reason, prop, prefix) {
1005
- if (reason) {
1006
- if (reason !== true) addProvenance(section, reason, prop && getPropKey(section, prop, prefix));
1007
- if (prop) {
1008
- const key = getPropKey(section, prop, prefix);
1009
- const curReason = section.serializeReasons.get(key);
1010
- if (curReason !== true) if (reason === true) forcePropSerialize(section, key);
1011
- else {
1012
- const newReason = mergeSerializeReasons(curReason, reason);
1013
- if (curReason !== newReason) setPropSerializeReason(section, key, newReason);
1014
- }
1015
- } else {
1016
- const curReason = section.serializeReason;
1017
- if (curReason !== true) if (reason === true) forceSerialize(section);
1018
- else {
1019
- const newReason = mergeSerializeReasons(curReason, reason);
1020
- if (curReason !== newReason) setSerializeReason(section, newReason);
1021
- }
964
+ //#region src/common/errors.ts
965
+ function assertExclusiveAttrs(attrs, onError = throwErr) {
966
+ if (attrs) {
967
+ let exclusiveAttrs;
968
+ if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange");
969
+ if ("checkedValue" in attrs) {
970
+ (exclusiveAttrs ||= []).push("checkedValue");
971
+ if ("checked" in attrs) exclusiveAttrs.push("checked");
972
+ } else if (attrs.checkedValueChange) {
973
+ (exclusiveAttrs ||= []).push("checkedValueChange");
974
+ if ("checked" in attrs) exclusiveAttrs.push("checked");
1022
975
  }
1023
- }
1024
- }
1025
- function addSerializeExpr(section, expr, prop, prefix) {
1026
- if (expr) if (prop) {
1027
- const key = getPropKey(section, prop, prefix);
1028
- if (expr === true) {
1029
- if (section.serializeReasons.get(key) !== true) forcePropSerialize(section, key);
1030
- } else {
1031
- const curExprs = section.propSerializeExprs ??= /* @__PURE__ */ new Map();
1032
- const curExpr = curExprs.get(key);
1033
- curExprs.set(key, curExpr ? concat(curExpr, expr) : expr);
976
+ if (attrs.valueChange) {
977
+ (exclusiveAttrs ||= []).push("valueChange");
978
+ if ("checked" in attrs && !exclusiveAttrs.includes("checked")) exclusiveAttrs.push("checked");
1034
979
  }
1035
- } else if (expr === true) {
1036
- if (section.serializeReason !== true) forceSerialize(section);
1037
- } else {
1038
- const curExpr = section.serializeExprs;
1039
- section.serializeExprs = curExpr ? concat(curExpr, expr) : expr;
980
+ if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
1040
981
  }
1041
982
  }
1042
- function addOwnerSerializeReason(from, to, reason) {
1043
- if (reason) {
1044
- let cur = from;
1045
- while (cur !== to && cur.parent) {
1046
- addSerializeReason(cur, reason, getAccessorProp().Owner);
1047
- cur = cur.parent;
1048
- }
983
+ function throwErr(msg) {
984
+ throw new Error(msg);
985
+ }
986
+ function joinWithAnd(a) {
987
+ switch (a.length) {
988
+ case 0: return "";
989
+ case 1: return a[0];
990
+ case 2: return `${a[0]} and ${a[1]}`;
991
+ default: return `${a.slice(0, -1).join(", ")}, and ${a[a.length - 1]}`;
1049
992
  }
1050
993
  }
1051
- function isReasonDynamic(reason) {
1052
- return !!reason && reason !== true && !reason.state;
994
+ //#endregion
995
+ //#region src/html/content.ts
996
+ function _unescaped(val) {
997
+ return val ? val + "" : val === 0 ? "0" : "";
1053
998
  }
1054
- function isStaticSerializeReason(reason) {
1055
- return !!reason && !isReasonDynamic(reason);
999
+ const unsafeXMLReg = /[<&\r]/g;
1000
+ const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&#13;";
1001
+ const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str;
1002
+ function _escape(val) {
1003
+ return val ? escapeXMLStr(val + "") : val === 0 ? "0" : "";
1056
1004
  }
1057
- function isStateSerializeReason(reason) {
1058
- return !!reason && reason !== true && !!reason.state;
1059
- }
1060
- function getSerializeReason(section, prop, prefix) {
1061
- if (prop) return section.serializeReasons.get(getPropKey(section, prop, prefix));
1062
- else return section.serializeReason;
1063
- }
1064
- function getSerializeSourcesForExpr(expr) {
1065
- return isReferencedExtra(expr) ? getSerializeSourcesForRef(expr.referencedBindings) : void 0;
1005
+ const unsafeScriptReg = /<(\/?script|!--)/gi;
1006
+ const escapeScriptStr = (str) => unsafeScriptReg.test(str) ? str.replace(unsafeScriptReg, "\\x3C$1") : str;
1007
+ function _escape_script(val) {
1008
+ return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
1066
1009
  }
1067
- function getSerializeSourcesForExprs(exprs) {
1068
- if (exprs) if (exprs === true) return exprs;
1069
- else if (Array.isArray(exprs)) {
1070
- let allSources;
1071
- for (const expr of exprs) allSources = mergeSources(allSources, getSerializeSourcesForExpr(expr));
1072
- return allSources;
1073
- } else return getSerializeSourcesForExpr(exprs);
1010
+ const unsafeStyleReg = /<(\/style)/gi;
1011
+ const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str;
1012
+ function _escape_style(val) {
1013
+ return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
1074
1014
  }
1075
- function getSerializeSourcesForRef(ref) {
1076
- if (ref) {
1077
- let allSources;
1078
- if (Array.isArray(ref)) {
1079
- for (const { sources } of ref) allSources = mergeSources(allSources, sources);
1080
- return allSources;
1081
- } else return ref.sources;
1082
- }
1015
+ const unsafeCommentReg = />/g;
1016
+ const escapeCommentStr = (str) => unsafeCommentReg.test(str) ? str.replace(unsafeCommentReg, "&gt;") : str;
1017
+ function _escape_comment(val) {
1018
+ return val ? escapeCommentStr(val + "") : val === 0 ? "0" : "";
1083
1019
  }
1084
- function mapCrossProgramReason(program, reason, exprs) {
1085
- let params;
1086
- let mapped;
1087
- let crossProgram = false;
1088
- forEach(reason.param, (param) => {
1089
- if (param.section.program === program) params = bindingUtil.add(params, param);
1090
- else {
1091
- crossProgram = true;
1092
- mapped = exprs ? mergeSerializeReasons(mapped, getSerializeSourcesForExprs(mapParamBindingToExpr(exprs, param))) : true;
1093
- }
1094
- });
1095
- if (!crossProgram) return reason;
1096
- return mergeRemappedSources(reason, params, mapped);
1020
+ globalThis.setImmediate || globalThis.setTimeout || globalThis.queueMicrotask;
1021
+ //#endregion
1022
+ //#region src/html/attrs.ts
1023
+ function _attr_class(value) {
1024
+ return stringAttr("class", toDelimitedString(value, " ", stringifyClassObject));
1097
1025
  }
1098
- function mapDownstreamReason(program, reason, exprs) {
1099
- let params;
1100
- let mapped;
1101
- let downstream = false;
1102
- forEach(reason.param, (param) => {
1103
- if (param.section.program === program) {
1104
- downstream = true;
1105
- mapped = mergeSerializeReasons(mapped, getSerializeSourcesForExprs(mapParamBindingToExpr(exprs, param)));
1106
- } else params = bindingUtil.add(params, param);
1107
- });
1108
- if (!downstream) return reason;
1109
- return mergeRemappedSources(reason, params, mapped);
1026
+ function _attr_style(value) {
1027
+ return stringAttr("style", toDelimitedString(value, ";", stringifyStyleObject));
1110
1028
  }
1111
- function mergeRemappedSources(reason, params, mapped) {
1112
- if (mapped !== true && (reason.state || reason.global || params)) mapped = mergeSerializeReasons(mapped, createSources(reason.state, params, reason.global));
1113
- return mapped;
1029
+ function _attr(name, value) {
1030
+ return isVoid(value) ? "" : nonVoidAttr(name, value);
1114
1031
  }
1115
- function mergeSerializeReasons(a, b) {
1116
- if (a === true || b === true) return true;
1117
- return mergeSources(a, b);
1032
+ function stringAttr(name, value) {
1033
+ return value && " " + name + attrAssignment(value);
1118
1034
  }
1119
- function applySerializeExprs(section) {
1120
- const propExprs = section.propSerializeExprs;
1121
- if (propExprs) {
1122
- section.propSerializeExprs = void 0;
1123
- for (const [key, exprs] of propExprs) {
1124
- addProvenance(section, getProvenanceForExprs(exprs), key);
1125
- const exprReason = getSerializeSourcesForExprs(exprs);
1126
- if (exprReason) {
1127
- const curReason = section.serializeReasons.get(key);
1128
- const newReason = mergeSerializeReasons(curReason, exprReason);
1129
- if (curReason !== newReason) setPropSerializeReason(section, key, newReason);
1130
- }
1131
- }
1132
- }
1133
- const scopeExprs = section.serializeExprs;
1134
- if (scopeExprs) {
1135
- section.serializeExprs = void 0;
1136
- addProvenance(section, getProvenanceForExprs(scopeExprs));
1137
- const exprReason = getSerializeSourcesForExprs(scopeExprs);
1138
- if (exprReason) {
1139
- const curReason = section.serializeReason;
1140
- const newReason = mergeSerializeReasons(curReason, exprReason);
1141
- if (curReason !== newReason) setSerializeReason(section, newReason);
1142
- }
1035
+ function nonVoidAttr(name, value) {
1036
+ switch (typeof value) {
1037
+ case "string": return " " + name + attrAssignment(value);
1038
+ case "boolean": return " " + name;
1039
+ case "number": return " " + name + "=" + value;
1143
1040
  }
1041
+ return " " + name + attrAssignment(value + "");
1144
1042
  }
1145
- function finalizeSerializeReason(section) {
1146
- some(section.bindings, (binding) => {
1147
- const reason = binding.type === 0 && getSerializeReason(section, binding);
1148
- if (reason) section.domSerializeReasons = reason === true ? true : sourcesUtil.add(section.domSerializeReasons, reason);
1149
- return reason === true;
1150
- });
1151
- const curReason = section.serializeReason;
1152
- let newReason = curReason;
1153
- if (newReason !== true) {
1154
- for (const propReason of section.serializeReasons.values()) {
1155
- if (propReason === true) {
1156
- newReason = true;
1157
- break;
1158
- }
1159
- newReason = mergeSources(newReason, propReason);
1160
- }
1161
- if (newReason && curReason !== newReason) setSerializeReason(section, newReason);
1162
- }
1163
- const propProvenance = section.propSerializeProvenance;
1164
- if (propProvenance) for (const provenance of propProvenance.values()) addProvenance(section, provenance);
1043
+ const singleQuoteAttrReplacements = /['\r]|&(?=[#a-zA-Z])/g;
1044
+ const doubleQuoteAttrReplacements = /["\r]|&(?=[#a-zA-Z])/g;
1045
+ const needsQuotedAttr = /["'>\s]|&[#a-zA-Z]|\/$/g;
1046
+ function attrAssignment(value) {
1047
+ return value ? needsQuotedAttr.test(value) ? value[needsQuotedAttr.lastIndex - 1] === (needsQuotedAttr.lastIndex = 0, "\"") ? "='" + escapeSingleQuotedAttrValue(value) + "'" : "=\"" + escapeDoubleQuotedAttrValue(value) + "\"" : "=" + value : "";
1165
1048
  }
1166
- function addProvenance(section, sources, key) {
1167
- if (!sources) return;
1168
- if (key) {
1169
- const provenance = section.propSerializeProvenance ??= /* @__PURE__ */ new Map();
1170
- provenance.set(key, mergeSources(provenance.get(key), sources));
1171
- } else section.serializeProvenance = mergeSources(section.serializeProvenance, sources);
1049
+ function escapeSingleQuotedAttrValue(value) {
1050
+ return singleQuoteAttrReplacements.test(value) ? value.replace(singleQuoteAttrReplacements, replaceUnsafeSingleQuoteAttrChar) : value;
1172
1051
  }
1173
- function getProvenanceForExprs(exprs) {
1174
- let sources;
1175
- forEach(exprs, (expr) => {
1176
- sources = mergeSources(sources, getSerializeSourcesForExpr(expr));
1177
- forEach(expr.referencedBindingsInFunction, (binding) => {
1178
- sources = mergeSources(sources, getSerializeSourcesForRef(binding));
1179
- });
1180
- });
1181
- return sources;
1052
+ function replaceUnsafeSingleQuoteAttrChar(match) {
1053
+ return match === "'" ? "&#39;" : match === "\r" ? "&#13;" : "&amp;";
1182
1054
  }
1183
- function getPropKey(section, prop, prefix) {
1184
- if (isStrOrSym(prop)) {
1185
- const keys = section.serializePropKeys ??= /* @__PURE__ */ new Map();
1186
- let key = keys.get(prop);
1187
- if (!key) keys.set(prop, key = Symbol(typeof prop === "symbol" ? `Symbol(${prop.description})` : prop));
1188
- if (prefix) throw new Error("Cannot have a scope property reason with a prefix.");
1189
- return key;
1190
- } else {
1191
- const binding = getCanonicalBinding(prop);
1192
- const keys = binding.serializePropKeys ??= /* @__PURE__ */ new Map();
1193
- let key = keys.get(prefix);
1194
- if (!key) keys.set(prefix, key = Symbol((prefix ? typeof prefix === "symbol" ? `Symbol(${prefix.description})` : prefix : "") + binding.name));
1195
- return key;
1196
- }
1055
+ function escapeDoubleQuotedAttrValue(value) {
1056
+ return doubleQuoteAttrReplacements.test(value) ? value.replace(doubleQuoteAttrReplacements, replaceUnsafeDoubleQuoteAttrChar) : value;
1197
1057
  }
1198
- function forceSerialize(section) {
1199
- setSerializeReason(section, true);
1058
+ function replaceUnsafeDoubleQuoteAttrChar(match) {
1059
+ return match === "\"" ? "&#34;" : match === "\r" ? "&#13;" : "&amp;";
1200
1060
  }
1201
- function forcePropSerialize(section, key) {
1202
- setPropSerializeReason(section, key, true);
1061
+ //#endregion
1062
+ //#region src/translator/util/marko-config.ts
1063
+ function isOutputHTML() {
1064
+ return getMarkoOpts().output === "html";
1203
1065
  }
1204
- function isStrOrSym(v) {
1205
- switch (typeof v) {
1206
- case "string":
1207
- case "symbol": return true;
1208
- default: return false;
1209
- }
1066
+ function isOutputDOM() {
1067
+ return getMarkoOpts().output === "dom";
1210
1068
  }
1211
- function setSerializeReason(section, reason) {
1212
- section.serializeReason = reason;
1069
+ function getMarkoOpts() {
1070
+ return (0, _marko_compiler_babel_utils.getFile)().markoOpts;
1213
1071
  }
1214
- function setPropSerializeReason(section, key, reason) {
1215
- section.serializeReasons.set(key, reason);
1072
+ function isOptimize() {
1073
+ return getMarkoOpts().optimize;
1074
+ }
1075
+ function getReadyId(file = (0, _marko_compiler_babel_utils.getFile)()) {
1076
+ const { markoOpts } = file;
1077
+ if (!markoOpts.linkAssets) return void 0;
1078
+ return (markoOpts.optimize ? "_" : "ready:") + (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, file.opts.filename);
1216
1079
  }
1217
1080
  //#endregion
1218
1081
  //#region src/translator/util/state.ts
@@ -1236,976 +1099,1267 @@ function createSectionState(key, init) {
1236
1099
  }];
1237
1100
  }
1238
1101
  //#endregion
1239
- //#region src/translator/util/tag-name-type.ts
1240
- const MARKO_FILE_REG = /^<.*>$|\.marko$/;
1241
- const TAG_NAME_IDENTIFIER_REG$1 = /^[A-Z][a-zA-Z0-9_$]*$/;
1242
- function analyzeTagNameType(tag, allowDynamic) {
1243
- const extra = tag.node.extra ??= {};
1244
- if (extra.tagNameType === void 0) {
1245
- const name = tag.get("name");
1246
- if (name.isStringLiteral()) {
1247
- extra.tagNameType = name.node.value[0] === "@" ? 3 : (0, _marko_compiler_babel_utils.isNativeTag)(tag) ? 0 : 1;
1248
- extra.tagNameNullable = extra.tagNameDynamic = false;
1249
- } else if (name.isTemplateLiteral() && name.node.quasis.length === 1) {
1250
- extra.tagNameType = 0;
1251
- extra.tagNameNullable = extra.tagNameDynamic = false;
1252
- } else if (name.isIdentifier()) {
1253
- analyzeExpressionTagName(name, extra);
1254
- extra.tagNameDynamic = !extra.tagNameImported;
1255
- } else {
1256
- analyzeExpressionTagName(name, extra);
1257
- extra.tagNameDynamic = true;
1258
- }
1259
- if (!extra.tagNameDynamic && extra.tagNameType === 1 && !isCoreTag(tag)) {
1260
- const childFile = (0, _marko_compiler_babel_utils.loadFileForTag)(tag);
1261
- if ((0, _marko_compiler_babel_utils.getTagDef)(tag)?.renderer || childFile?.ast.program.extra.featureType === "class") {
1262
- extra.tagNameType = 2;
1263
- extra.tagNameDynamic = true;
1264
- extra.featureType = "class";
1265
- if (childFile?.ast.program.extra?.hydratesTags) (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
1266
- } else if (!childFile) {
1267
- extra.tagNameType = 2;
1268
- extra.tagNameDynamic = true;
1269
- const tagName = name.node.value;
1270
- extra.tagNameUnresolved = !(TAG_NAME_IDENTIFIER_REG$1.test(tagName) && tag.scope.hasBinding(tagName));
1271
- } else if (childFile !== (0, _marko_compiler_babel_utils.getFile)() && isAnalyzing(childFile)) {
1272
- extra.tagNameType = 2;
1273
- extra.tagNameDynamic = true;
1274
- }
1275
- }
1102
+ //#region src/translator/util/to-property-name.ts
1103
+ function getMemberExpressionPropString(expr) {
1104
+ switch (expr.property.type) {
1105
+ case "StringLiteral": return expr.property.value;
1106
+ case "NumericLiteral": return "" + expr.property.value;
1107
+ case "Identifier":
1108
+ if (expr.computed) return;
1109
+ return expr.property.name;
1276
1110
  }
1277
- return !allowDynamic && extra.tagNameDynamic ? 2 : extra.tagNameType;
1278
1111
  }
1279
- function analyzeExpressionTagName(name, extra) {
1280
- const pending = [name];
1281
- const seen = /* @__PURE__ */ new Set();
1282
- let path;
1283
- let type;
1284
- let nullable = false;
1285
- let tagNameImported;
1286
- let tagNameLoad;
1287
- while ((path = pending.pop()) && type !== 2) {
1288
- if (seen.has(path.node)) continue;
1289
- seen.add(path.node);
1290
- if (path.isConditionalExpression()) {
1291
- pending.push(path.get("consequent"));
1292
- if (path.node.alternate) pending.push(path.get("alternate"));
1293
- } else if (path.isLogicalExpression()) {
1294
- if (path.node.operator === "&&") nullable = true;
1295
- else pending.push(path.get("left"));
1296
- pending.push(path.get("right"));
1297
- } else if (path.isAssignmentExpression()) pending.push(path.get("right"));
1298
- else if (path.isBinaryExpression()) type = path.node.operator !== "+" || type === void 0 || type === 0 ? 0 : 2;
1299
- else if (path.isStringLiteral() || path.isTemplateLiteral()) type = type === void 0 || type === 0 ? 0 : 2;
1300
- else if (path.isNullLiteral()) nullable = true;
1301
- else if (path.isIdentifier()) {
1302
- if (path.node.name === "undefined") {
1303
- nullable = true;
1304
- continue;
1305
- }
1306
- const binding = path.scope.getBinding(path.node.name);
1307
- if (!binding) {
1308
- type = 2;
1309
- continue;
1310
- }
1311
- if (binding.kind === "module") {
1312
- const decl = binding.path.parent;
1313
- if (MARKO_FILE_REG.test(decl.source.value) && decl.specifiers.some((it) => _marko_compiler.types.isImportDefaultSpecifier(it))) {
1314
- const resolvedImport = decl.extra?.tagImport || decl.source.value;
1315
- if (type === void 0) {
1316
- type = 1;
1317
- tagNameImported = resolvedImport;
1318
- tagNameLoad = decl.extra?.loadImport;
1319
- } else if (type === 0) {
1320
- type = 2;
1321
- tagNameImported = void 0;
1322
- } else if (tagNameImported !== resolvedImport) tagNameImported = void 0;
1323
- } else type = 2;
1324
- continue;
1325
- }
1326
- const bindingTag = binding.path;
1327
- if (bindingTag.isMarkoTag() && binding.kind === "local") {
1328
- const bindingTagName = bindingTag.get("name").node.value;
1329
- if (bindingTagName === "const") {
1330
- pending.push(bindingTag.get("attributes")[0].get("value"));
1331
- continue;
1332
- }
1333
- if (bindingTagName === "let") {
1334
- type = 2;
1335
- continue;
1336
- }
1337
- continue;
1338
- }
1339
- type = 2;
1340
- } else type = 2;
1341
- }
1342
- extra.tagNameType = type ?? 2;
1343
- extra.tagNameNullable = nullable;
1344
- if (type === 1 && tagNameImported) {
1345
- extra.tagNameImported = tagNameImported;
1346
- extra.tagNameLoad = tagNameLoad;
1347
- }
1112
+ function isValidPropertyIdentifier(name) {
1113
+ return /^[a-z_$][a-z0-9_$]*$/i.test(name);
1348
1114
  }
1349
- //#endregion
1350
- //#region src/translator/util/sections.ts
1351
- const sectionUtil = new Sorted(function compareSections(a, b) {
1352
- return a.id - b.id;
1353
- });
1354
- function startSection(path) {
1355
- const extra = path.node.extra ??= {};
1356
- let section = extra.section;
1357
- if (!section && (path.type === "Program" || path.get("body").length)) {
1358
- const parentTag = path.parentPath?.isMarkoTag() ? path.parentPath : void 0;
1359
- const parentSection = path.parentPath ? getOrCreateSection(path.parentPath) : void 0;
1360
- const sectionName = parentTag ? generateUid((isCoreTagName(parentTag, "define") && _marko_compiler.types.isIdentifier(parentTag.node.var) ? parentTag.node.var.name : parentTag.get("name").toString()) + "_content") : "";
1361
- const programExtra = (0, _marko_compiler_babel_utils.getProgram)().node.extra ??= {};
1362
- const sections = programExtra.sections ??= [];
1363
- section = extra.section = {
1364
- id: sections.length,
1365
- name: sectionName,
1366
- loc: parentTag?.node.name.loc || void 0,
1367
- depth: parentSection ? parentSection.depth + 1 : 0,
1368
- parent: parentSection,
1369
- program: void 0,
1370
- sectionAccessor: void 0,
1371
- params: void 0,
1372
- referencedLocalClosures: void 0,
1373
- referencedClosures: void 0,
1374
- referencedHoists: void 0,
1375
- bindings: void 0,
1376
- hoisted: void 0,
1377
- hoistedTo: void 0,
1378
- isHoistThrough: void 0,
1379
- serializeReason: void 0,
1380
- serializeReasons: /* @__PURE__ */ new Map(),
1381
- domSerializeReasons: void 0,
1382
- serializeExprs: void 0,
1383
- propSerializeExprs: void 0,
1384
- serializeProvenance: void 0,
1385
- propSerializeProvenance: void 0,
1386
- serializePropKeys: void 0,
1387
- paramReasonGroups: void 0,
1388
- returnValueExpr: void 0,
1389
- returnSerializeReason: void 0,
1390
- content: getContentInfo(path),
1391
- upstreamExpression: void 0,
1392
- downstream: void 0,
1393
- hasAbortSignal: false,
1394
- abortSignalExprs: 0,
1395
- readsOwner: false,
1396
- isBranch: false,
1397
- structure: parentSection && !parentSection.structure ? null : []
1398
- };
1399
- section.program = parentSection ? parentSection.program : section;
1400
- sections.push(section);
1401
- }
1402
- return section;
1403
- }
1404
- function getOrCreateSection(path) {
1405
- let cur = path;
1406
- while (true) {
1407
- if (cur.type === "Program" || cur.type === "MarkoTagBody" && !cur.node.attributeTags && !isNativeNode(cur.parentPath)) return startSection(cur);
1408
- cur = cur.parentPath;
1409
- }
1410
- }
1411
- function getSectionForBody(body) {
1412
- return body.node.extra?.section;
1413
- }
1414
- function getSection(path) {
1415
- let section;
1416
- let currentPath = path;
1417
- while ((section = currentPath.node.extra?.section) === void 0) currentPath = currentPath.parentPath;
1418
- return section;
1115
+ function toPropertyName(name) {
1116
+ if (isValidPropertyIdentifier(name)) return _marko_compiler.types.identifier(name);
1117
+ else if (/^(?:0|[1-9][0-9]*)$/.test(name)) return _marko_compiler.types.numericLiteral(parseInt(name, 10));
1118
+ return _marko_compiler.types.stringLiteral(name);
1419
1119
  }
1420
- const [getScopeIdIdentifier] = createSectionState("scopeIdIdentifier", (section) => generateUidIdentifier(`scope${section.id}_id`));
1421
- const [getSectionParentIsOwner, setSectionParentIsOwner] = createSectionState("parentIsOwner", () => false);
1422
- const [getBranchRendererArgs, setBranchRendererArgs] = createSectionState("rendererExpression");
1423
- function forEachSection(fn) {
1424
- const { sections } = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
1425
- sections?.forEach(fn);
1120
+ function toObjectProperty(name, value) {
1121
+ return _marko_compiler.types.objectProperty(toPropertyName(name), value);
1426
1122
  }
1427
- function forEachSectionReverse(fn) {
1428
- const { sections } = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
1429
- for (let i = sections.length; i--;) fn(sections[i]);
1123
+ function toMemberExpression(object, key, optional) {
1124
+ const prop = toPropertyName(key);
1125
+ const computed = prop.type !== "Identifier";
1126
+ return optional ? _marko_compiler.types.optionalMemberExpression(object, prop, computed, true) : _marko_compiler.types.memberExpression(object, prop, computed);
1430
1127
  }
1431
- function getContentInfo(path) {
1432
- const body = path.get("body");
1433
- const contentInfo = {
1434
- startType: null,
1435
- endType: null,
1436
- singleChild: true
1437
- };
1438
- for (let endIndex = body.length; endIndex--;) {
1439
- const endType = getNodeContentType(body[endIndex], "endType", contentInfo);
1440
- if (endType !== null) {
1441
- contentInfo.endType = endType;
1442
- if (endType === 1) contentInfo.singleChild = false;
1443
- for (let startIndex = 0; startIndex < endIndex; startIndex++) {
1444
- const startType = getNodeContentType(body[startIndex], "startType");
1445
- if (startType !== null) {
1446
- contentInfo.startType = startType;
1447
- contentInfo.singleChild = false;
1448
- return contentInfo;
1449
- }
1450
- }
1451
- contentInfo.startType = getNodeContentType(body[endIndex], "startType");
1452
- return contentInfo;
1453
- }
1128
+ //#endregion
1129
+ //#region src/translator/util/runtime.ts
1130
+ const pureDOMFunctions = /* @__PURE__ */ new Set([
1131
+ "_await_promise",
1132
+ "_await_content",
1133
+ "_child_setup",
1134
+ "_if",
1135
+ "_if_closure",
1136
+ "_show",
1137
+ "_try",
1138
+ "_dynamic_tag",
1139
+ "_dynamic_tag_content",
1140
+ "_content_closures",
1141
+ "_content",
1142
+ "_template",
1143
+ "_closure",
1144
+ "_closure_get",
1145
+ "_or",
1146
+ "_for_closure",
1147
+ "_for_selector",
1148
+ "_for_in",
1149
+ "_for_of",
1150
+ "_for_to",
1151
+ "_for_until",
1152
+ "_hoist",
1153
+ "_let",
1154
+ "_let_change",
1155
+ "_const",
1156
+ "_load_signal",
1157
+ "_load_setup",
1158
+ "_load_template",
1159
+ "_load_visible_trigger",
1160
+ "_load_event_trigger",
1161
+ "_load_idle_trigger",
1162
+ "_load_media_trigger",
1163
+ "_load_race_trigger"
1164
+ ]);
1165
+ const [getRuntimeImports] = createProgramState(() => /* @__PURE__ */ new Map());
1166
+ function importRuntime(name) {
1167
+ if (!isTranslate()) throw new Error(`\`importRuntime(${JSON.stringify(name)})\` may only be called during the translate stage.`);
1168
+ const { output } = getMarkoOpts();
1169
+ const imports = getRuntimeImports();
1170
+ let localName = imports.get(name);
1171
+ if (!localName) {
1172
+ localName = (0, _marko_compiler_babel_utils.importNamed)((0, _marko_compiler_babel_utils.getFile)(), getRuntimePath(output), name).name;
1173
+ imports.set(name, localName);
1454
1174
  }
1455
- return null;
1175
+ return _marko_compiler.types.identifier(localName);
1456
1176
  }
1457
- function getNodeContentType(path, extraMember, contentInfo) {
1458
- switch (path.type) {
1459
- case "MarkoText": return 4;
1460
- case "MarkoPlaceholder": return 2;
1461
- case "MarkoScriptlet":
1462
- case "MarkoComment":
1463
- case "ImportDeclaration":
1464
- case "ExportAllDeclaration":
1465
- case "ExportNamedDeclaration":
1466
- case "ExportDefaultDeclaration": return null;
1467
- case "MarkoTag": {
1468
- const tag = path;
1469
- if (isCoreTag(tag)) switch (tag.node.name.value) {
1470
- case "html-comment": return 0;
1471
- case "html-script":
1472
- case "html-style": return 3;
1473
- case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child)) ? 3 : null;
1474
- case "for":
1475
- case "if":
1476
- case "await":
1477
- case "try": return 1;
1478
- case "show": return 1;
1479
- default: return null;
1480
- }
1481
- else if ((0, _marko_compiler_babel_utils.isNativeTag)(tag)) return 3;
1482
- else if ((0, _marko_compiler_babel_utils.isAttributeTag)(tag)) return null;
1483
- else if (_marko_compiler.types.isStringLiteral(tag.node.name)) {
1484
- const tagSection = (0, _marko_compiler_babel_utils.loadFileForTag)(tag)?.ast.program.extra.section;
1485
- if (tagSection) if (tagSection.content) {
1486
- if (contentInfo && !tagSection.content.singleChild) {
1487
- if (extraMember === "endType") {
1488
- contentInfo.startType = tagSection.content.startType;
1489
- contentInfo.singleChild = false;
1490
- }
1491
- }
1492
- return tagSection.content[extraMember];
1493
- } else return null;
1494
- }
1495
- }
1496
- }
1497
- return 1;
1177
+ function registerRuntimeValue(id, value) {
1178
+ return _marko_compiler.types.assignmentExpression("=", toMemberExpression(importRuntime("_resumed"), id), value);
1498
1179
  }
1499
- function getSectionRegisterReasons(section) {
1500
- if (section.isBranch) return false;
1501
- const { downstream } = section;
1502
- if (downstream?.binding) {
1503
- let downstreamReasons = getAllSerializeReasonsForBinding(downstream.binding, downstream.properties);
1504
- if (downstreamReasons && downstreamReasons !== true) downstreamReasons = mapCrossProgramReason(section.program, downstreamReasons, downstream.exprs);
1505
- if (!downstreamReasons) return false;
1506
- if (isReasonDynamic(downstreamReasons) && !section.serializeReason && !section.serializeReasons.size && !section.parent?.serializeReason && !section.parent?.serializeReasons.size) return false;
1507
- return downstreamReasons;
1508
- } else if (downstream) return false;
1509
- return true;
1180
+ function callRuntime(name, ...args) {
1181
+ const callExpression = _marko_compiler.types.callExpression(importRuntime(name), filterArguments(args));
1182
+ if (isOutputDOM() && pureDOMFunctions.has(name)) return _marko_compiler.types.addComment(callExpression, "leading", "@__PURE__");
1183
+ return callExpression;
1510
1184
  }
1511
- function isImmediateOwner(section, binding) {
1512
- return section.parent?.id === binding.section.id;
1185
+ const domRuntimeFeatures = [
1186
+ "catch",
1187
+ "controllable",
1188
+ "controllable-input",
1189
+ "controllable-open",
1190
+ "controllable-select",
1191
+ "controllable-textarea",
1192
+ "dynamic-tag-var",
1193
+ "placeholder"
1194
+ ];
1195
+ const importedFeatures = /* @__PURE__ */ new WeakMap();
1196
+ function importRuntimeFeature(feature) {
1197
+ if (!isTranslate()) throw new Error(`\`importRuntimeFeature(${JSON.stringify(feature)})\` may only be called during the translate stage.`);
1198
+ const program = (0, _marko_compiler_babel_utils.getProgram)().node;
1199
+ let features = importedFeatures.get(program);
1200
+ if (!features) importedFeatures.set(program, features = /* @__PURE__ */ new Set());
1201
+ if (!features.has(feature)) {
1202
+ features.add(feature);
1203
+ program.body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(`${getRuntimePath("dom")}/${feature}.feat`)));
1204
+ }
1513
1205
  }
1514
- function isDirectClosure(section, closure) {
1515
- return section.isBranch && isImmediateOwner(section, closure);
1206
+ function getHTMLRuntime() {
1207
+ return {
1208
+ _escape,
1209
+ _escape_comment,
1210
+ _unescaped,
1211
+ _attr,
1212
+ _attr_class,
1213
+ _attr_style,
1214
+ _escape_script,
1215
+ _escape_style
1216
+ };
1516
1217
  }
1517
- function isDynamicClosure(section, closure) {
1518
- return !isDirectClosure(section, closure);
1218
+ function getRuntimePath(output) {
1219
+ const { optimize } = getMarkoOpts();
1220
+ return `${runtime_info_default.name}/${optimize ? "" : "debug/"}${output === "html" ? "html" : "dom"}`;
1519
1221
  }
1520
- function getDynamicClosureIndex(closure, closureSection) {
1521
- let index = 0;
1522
- find(closure.closureSections, (section) => {
1523
- if (section === closureSection) return true;
1524
- if (isDynamicClosure(section, closure)) index++;
1525
- return false;
1526
- });
1527
- return index;
1222
+ function filterArguments(args) {
1223
+ const filteredArgs = [];
1224
+ for (let i = args.length; i--;) {
1225
+ const arg = args[i];
1226
+ if (arg || filteredArgs.length) filteredArgs[i] = arg || _marko_compiler.types.unaryExpression("void", _marko_compiler.types.numericLiteral(0));
1227
+ }
1228
+ return filteredArgs;
1528
1229
  }
1529
- function getDirectClosures(section) {
1530
- if (section.isBranch) return filter(section.referencedClosures, (closure) => isImmediateOwner(section, closure));
1230
+ function getCompatRuntimeFile() {
1231
+ const markoOpts = getMarkoOpts();
1232
+ return `marko/${markoOpts.optimize ? "dist" : "src"}/runtime/helpers/tags-compat/${isOutputHTML() ? "html" : "dom"}${markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`;
1531
1233
  }
1532
- function isSameOrChildSection(section, other) {
1533
- do
1534
- if (other === section) return true;
1535
- while (other = other.parent);
1536
- return false;
1234
+ //#endregion
1235
+ //#region src/common/constants/accessor-prefix.ts
1236
+ var accessor_prefix_exports = /* @__PURE__ */ __exportAll({
1237
+ BranchScopes: () => "A",
1238
+ ClosureScopes: () => "B",
1239
+ ClosureSignalIndex: () => "C",
1240
+ ConditionalRenderer: () => "D",
1241
+ ControlledHandler: () => "E",
1242
+ ControlledObserver: () => "N",
1243
+ ControlledType: () => "F",
1244
+ ControlledValue: () => "G",
1245
+ DynamicHTMLLastChild: () => "H",
1246
+ EventAttributes: () => "I",
1247
+ IdFallback: () => "J",
1248
+ KeyedScopes: () => "O",
1249
+ Lifecycle: () => "K",
1250
+ Promise: () => "L",
1251
+ TagVariableChange: () => "M"
1252
+ });
1253
+ //#endregion
1254
+ //#region src/common/constants/accessor-prop.ts
1255
+ var accessor_prop_exports = /* @__PURE__ */ __exportAll({
1256
+ AbortControllers: () => "A",
1257
+ AbortScopes: () => "B",
1258
+ AwaitCounter: () => "O",
1259
+ BranchAccessor: () => "C",
1260
+ BranchScopes: () => "D",
1261
+ CatchContent: () => "E",
1262
+ ClosestBranch: () => "F",
1263
+ ClosestBranchId: () => "G",
1264
+ DetachedAwait: () => "V",
1265
+ EndNode: () => "K",
1266
+ Gen: () => "H",
1267
+ Global: () => "$",
1268
+ Id: () => "L",
1269
+ Load: () => "X",
1270
+ LoopIndex: () => "I",
1271
+ LoopKey: () => "M",
1272
+ Owner: () => "_",
1273
+ ParentBranch: () => "N",
1274
+ PendingEffects: () => "J",
1275
+ PendingRenders: () => "W",
1276
+ PendingScopes: () => "Y",
1277
+ PlaceholderBranch: () => "P",
1278
+ PlaceholderContent: () => "Q",
1279
+ Renderer: () => "R",
1280
+ StartNode: () => "S",
1281
+ Subscriptions: () => "Z",
1282
+ TagVariable: () => "T",
1283
+ TagVariableChange: () => "U"
1284
+ });
1285
+ //#endregion
1286
+ //#region src/translator/util/get-accessor-enums.ts
1287
+ function getAccessorPrefix() {
1288
+ return isOptimize() ? accessor_prefix_exports : accessor_prefix_debug_exports;
1537
1289
  }
1538
- function getCommonSection(section, other) {
1539
- let ancestor = section;
1540
- if (other.depth < section.depth) {
1541
- ancestor = other;
1542
- other = section;
1290
+ function getAccessorProp() {
1291
+ return isOptimize() ? accessor_prop_exports : accessor_prop_debug_exports;
1292
+ }
1293
+ //#endregion
1294
+ //#region src/translator/util/serialize-reasons.ts
1295
+ const sourcesUtil = new Sorted(compareSources);
1296
+ function isSameReason(a, b) {
1297
+ return a === b || (a && b ? a.forced && b.forced || compareSources(a, b) === 0 : false);
1298
+ }
1299
+ function isForceSerialized(section, prop, prefix) {
1300
+ return !!(prop ? section.serializeReasons.get(getPropKey(section, prop, prefix)) : section.serializeReason)?.forced;
1301
+ }
1302
+ function addSerializeReason(section, reason, prop, prefix) {
1303
+ if (reason) {
1304
+ const key = prop && getPropKey(section, prop, prefix);
1305
+ if (key) {
1306
+ const curReason = section.serializeReasons.get(key);
1307
+ const newReason = mergeSerializeReasons(curReason, reason);
1308
+ if (curReason !== newReason) setPropSerializeReason(section, key, newReason);
1309
+ } else {
1310
+ const curReason = section.serializeReason;
1311
+ const newReason = mergeSerializeReasons(curReason, reason);
1312
+ if (curReason !== newReason) setSerializeReason(section, newReason);
1313
+ }
1543
1314
  }
1544
- while (ancestor) {
1545
- if (other === ancestor || !other.parent) return ancestor;
1546
- other = other.parent;
1547
- if (other.depth < ancestor.depth) ancestor = ancestor.parent;
1315
+ }
1316
+ function addSerializeExpr(section, expr, prop, prefix) {
1317
+ if (expr) if (prop) {
1318
+ const key = getPropKey(section, prop, prefix);
1319
+ const curExprs = section.propSerializeExprs ??= /* @__PURE__ */ new Map();
1320
+ const curExpr = curExprs.get(key);
1321
+ curExprs.set(key, curExpr ? concat(curExpr, expr) : expr);
1322
+ } else {
1323
+ const curExpr = section.serializeExprs;
1324
+ section.serializeExprs = curExpr ? concat(curExpr, expr) : expr;
1548
1325
  }
1549
- throw new Error("No common section");
1550
1326
  }
1551
- function finalizeParamSerializeReasonGroups(section) {
1552
- ensureReasonGroups(section.serializeReason);
1553
- for (const reason of section.serializeReasons.values()) ensureReasonGroups(reason);
1327
+ function addOwnerSerializeReason(from, to, reason) {
1328
+ if (reason) for (const section of ancestorSections(from, to)) addSerializeReason(section, reason, getAccessorProp().Owner);
1554
1329
  }
1555
- function ensureReasonGroups(reason) {
1556
- if (isReasonDynamic(reason)) for (const [paramSection, params] of groupParamsBySection(reason.param)) ensureParamReasonGroup(paramSection, params);
1330
+ function isReasonDynamic(reason) {
1331
+ return !!reason && !reason.forced && !reason.state;
1557
1332
  }
1558
- function ensureParamReasonGroup(section, reason) {
1559
- const { paramReasonGroups } = section;
1560
- if (paramReasonGroups) {
1561
- const found = findSorted(compareParamGroups, paramReasonGroups, { reason });
1562
- if (found) return found;
1333
+ function isStaticSerializeReason(reason) {
1334
+ return !!reason && !isReasonDynamic(reason);
1335
+ }
1336
+ function isStateSerializeReason(reason) {
1337
+ return !!reason && !reason.forced && !!reason.state;
1338
+ }
1339
+ function getSerializeReason(section, prop, prefix) {
1340
+ if (prop) return section.serializeReasons.get(getPropKey(section, prop, prefix));
1341
+ else return section.serializeReason;
1342
+ }
1343
+ function getSerializeSourcesForExpr(expr) {
1344
+ const root = getCanonicalExtra(expr);
1345
+ return isReferencedExtra(root) ? getSerializeSourcesForRef(root.referencedBindings) : void 0;
1346
+ }
1347
+ function getSerializeSourcesForExprs(exprs) {
1348
+ if (exprs) {
1349
+ if (exprs === true) return FORCED;
1350
+ return reduce(exprs, mergeExprSources);
1563
1351
  }
1564
- const group = {
1565
- id: Symbol(getDebugNames(reason)),
1566
- reason
1567
- };
1568
- section.paramReasonGroups = paramReasonGroups ? addSorted(compareParamGroups, paramReasonGroups, group) : [group];
1569
1352
  }
1570
- function getParamReasonGroupIndex(section, reason) {
1571
- const index = section.paramReasonGroups && findIndexSorted(compareParamGroups, section.paramReasonGroups, { reason });
1572
- if (index === void 0 || index === -1) throw new Error("Invalid compiler state, cannot ask for a serialize reason group that was not analyzed.");
1573
- return index;
1353
+ function getSerializeSourcesForRef(ref) {
1354
+ return reduce(ref, mergeBindingSources);
1574
1355
  }
1575
- function groupParamsBySection(params) {
1576
- return bindingUtil.groupBy(params, bindingToSection);
1356
+ function mergeExprSources(sources, expr) {
1357
+ return mergeSources(sources, getSerializeSourcesForExpr(expr));
1577
1358
  }
1578
- function bindingToSection(binding) {
1579
- return binding.section;
1359
+ function mergeBindingSources(sources, binding) {
1360
+ return mergeSources(sources, binding.sources);
1580
1361
  }
1581
- function compareParamGroups(a, b) {
1582
- return compareReferences(a.reason, b.reason);
1362
+ function mapParamReason(program, reason, exprs, ownParams) {
1363
+ let params;
1364
+ let mapped;
1365
+ let any = false;
1366
+ forEach(reason.param, (param) => {
1367
+ if (param.section.program === program === ownParams) {
1368
+ any = true;
1369
+ mapped = exprs ? mergeSerializeReasons(mapped, getSerializeSourcesForExprs(mapParamBindingToExpr(exprs, param))) : FORCED;
1370
+ } else params = bindingUtil.add(params, param);
1371
+ });
1372
+ if (!any) return reason;
1373
+ return mergeRemappedSources(reason, params, mapped);
1583
1374
  }
1584
- function isNativeNode(tag) {
1585
- if (isCoreTag(tag)) switch (tag.node.name.value) {
1586
- case "html-comment":
1587
- case "html-script":
1588
- case "html-style":
1589
- case "show": return true;
1590
- case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child));
1591
- default: return false;
1592
- }
1593
- return analyzeTagNameType(tag) === 0;
1375
+ function mergeRemappedSources(reason, params, mapped) {
1376
+ if (reason.state || reason.global || params || reason.forced) mapped = mergeSerializeReasons(mapped, createSources(reason.state, params, reason.global, reason.forced));
1377
+ return mapped;
1594
1378
  }
1595
- //#endregion
1596
- //#region src/translator/visitors/function.ts
1597
- const [getReferencesByFn] = createProgramState(() => /* @__PURE__ */ new Map());
1598
- const [getReferencesByImportedFn] = createProgramState(() => /* @__PURE__ */ new Map());
1599
- var function_default = { analyze(fn) {
1600
- const awaitNode = isMarkoAttribute(fn.parentPath) && _marko_compiler.types.isFunctionExpression(fn.node) && !fn.node.async && traverseFindAwait(fn.node.body);
1601
- if (awaitNode) {
1602
- const file = (0, _marko_compiler_babel_utils.getFile)();
1603
- const start = file.code.indexOf("await", awaitNode.start ?? 0);
1604
- const highlight = start >= 0 && (awaitNode.end == null || start < awaitNode.end) ? (0, _marko_compiler_babel_utils.withLoc)(file, _marko_compiler.types.cloneNode(awaitNode), start, start + 5) : awaitNode;
1605
- throw fn.hub.buildError(highlight, "Attribute methods containing `await` must be `async`. Add `async` before the method name.");
1379
+ function mergeSerializeReasons(a, b) {
1380
+ return mergeSources(a, b);
1381
+ }
1382
+ function applySerializeExprs(section) {
1383
+ const propExprs = section.propSerializeExprs;
1384
+ if (propExprs) {
1385
+ section.propSerializeExprs = void 0;
1386
+ for (const [key, exprs] of propExprs) {
1387
+ const reason = getSerializeSourcesForExprs(exprs);
1388
+ if (reason) {
1389
+ const curReason = section.serializeReasons.get(key);
1390
+ const newReason = mergeSerializeReasons(curReason, reason);
1391
+ if (curReason !== newReason) setPropSerializeReason(section, key, newReason);
1392
+ }
1393
+ }
1606
1394
  }
1607
- if (fn !== getFnRoot(fn)) return;
1608
- const { node } = fn;
1609
- if ((_marko_compiler.types.isObjectMethod(node) || _marko_compiler.types.isClassMethod(node)) && (node.kind === "get" || node.kind === "set")) return;
1610
- const exprRoot = getExprRoot(fn);
1611
- const markoRoot = getMarkoRoot(exprRoot);
1612
- if (!markoRoot || canIgnoreRegister(markoRoot, exprRoot)) return;
1613
- const section = getSection(fn);
1614
- const fnExtra = node.extra ??= {};
1615
- fnExtra.section = section;
1616
- fnExtra.name = node.id?.name || (isMarkoAttribute(markoRoot) ? markoRoot.node.default ? _marko_compiler.types.toIdentifier((markoRoot.parentPath.has("var") ? markoRoot.parentPath.get("var") : markoRoot.parentPath.get("name")).toString()) : markoRoot.node.name : _marko_compiler.types.isVariableDeclarator(fn.parent) && _marko_compiler.types.isIdentifier(fn.parent.id) ? fn.parent.id.name : _marko_compiler.types.isObjectMethod(node) && _marko_compiler.types.isIdentifier(node.key) ? node.key.name : "anonymous");
1617
- reserveExportRegisterId(fnExtra, fn, markoRoot);
1618
- if (isStaticRoot(markoRoot)) {
1619
- const refs = getStaticDeclRefs(fn);
1620
- if (refs === true) registerFunction(fnExtra, true);
1621
- else if (refs.size) getReferencesByFn().set(fnExtra, refs);
1622
- } else if (shouldAlwaysRegister(markoRoot)) registerFunction(fnExtra, true);
1623
- else {
1624
- const refs = /* @__PURE__ */ new Set([exprRoot.node.extra ??= {}]);
1625
- if (getConstTagVarRefs(markoRoot, refs) === true) registerFunction(fnExtra, true);
1626
- else getReferencesByFn().set(fnExtra, refs);
1395
+ const scopeExprs = section.serializeExprs;
1396
+ if (scopeExprs) {
1397
+ section.serializeExprs = void 0;
1398
+ const reason = getSerializeSourcesForExprs(scopeExprs);
1399
+ if (reason) {
1400
+ const curReason = section.serializeReason;
1401
+ const newReason = mergeSerializeReasons(curReason, reason);
1402
+ if (curReason !== newReason) setSerializeReason(section, newReason);
1403
+ }
1627
1404
  }
1628
- } };
1629
- function getConstTagVarRefs(markoRoot, refs, seen = /* @__PURE__ */ new Set()) {
1630
- const tag = getTagFromMarkoRoot(markoRoot);
1631
- if (!tag?.node.var || !isCoreTagName(tag, "const") || seen.has(tag.node)) return refs;
1632
- seen.add(tag.node);
1633
- const ids = tag.get("var").getOuterBindingIdentifiers();
1634
- for (const name in ids) {
1635
- const binding = tag.scope.getBinding(name);
1636
- if (binding && addBindingRefs(binding, refs, seen) === true) return true;
1405
+ }
1406
+ function finalizeSerializeReason(section) {
1407
+ forEach(section.bindings, (binding) => {
1408
+ const reason = binding.type === 0 && getSerializeReason(section, binding);
1409
+ if (reason) section.domSerializeReasons = sourcesUtil.add(section.domSerializeReasons, reason);
1410
+ });
1411
+ const curReason = section.serializeReason;
1412
+ let newReason = curReason;
1413
+ for (const propReason of section.serializeReasons.values()) newReason = mergeSources(newReason, propReason);
1414
+ if (newReason && curReason !== newReason) setSerializeReason(section, newReason);
1415
+ }
1416
+ function getPropKey(section, prop, prefix) {
1417
+ if (isStrOrSym(prop)) {
1418
+ const keys = section.serializePropKeys ??= /* @__PURE__ */ new Map();
1419
+ let key = keys.get(prop);
1420
+ if (!key) keys.set(prop, key = Symbol(typeof prop === "symbol" ? `Symbol(${prop.description})` : prop));
1421
+ if (prefix) throw new Error("Cannot have a scope property reason with a prefix.");
1422
+ return key;
1423
+ } else {
1424
+ const binding = getCanonicalBinding(prop);
1425
+ const keys = binding.serializePropKeys ??= /* @__PURE__ */ new Map();
1426
+ let key = keys.get(prefix);
1427
+ if (!key) keys.set(prefix, key = Symbol((prefix ? typeof prefix === "symbol" ? `Symbol(${prefix.description})` : prefix : "") + binding.name));
1428
+ return key;
1637
1429
  }
1638
- return refs;
1639
1430
  }
1640
- function finalizeFunctionRegistry() {
1641
- for (const [fnExtra, exprExtras] of getReferencesByFn()) {
1642
- const reason = resolveSerializeReason(exprExtras);
1643
- if (reason) registerFunction(fnExtra, reason);
1431
+ function isStrOrSym(v) {
1432
+ switch (typeof v) {
1433
+ case "string":
1434
+ case "symbol": return true;
1435
+ default: return false;
1644
1436
  }
1645
- for (const [importedFn, exprExtras] of getReferencesByImportedFn()) if (resolveSerializeReason(exprExtras)) registerImportedFn(importedFn);
1646
1437
  }
1647
- /**
1648
- * Tracks a function imported from another template that reserved a register id.
1649
- * The importing template registers it (under the reserved id) when its own
1650
- * references reach something serialized.
1651
- */
1652
- function trackImportedFn(importDecl, local, resolved) {
1653
- const binding = importDecl.scope.getBinding(local);
1654
- if (!binding) return;
1655
- const importedFn = {
1656
- ...resolved,
1657
- node: importDecl.node,
1658
- local
1659
- };
1660
- const refs = /* @__PURE__ */ new Set();
1661
- if (addBindingRefs(binding, refs, /* @__PURE__ */ new Set()) === true) registerImportedFn(importedFn);
1662
- else if (refs.size) getReferencesByImportedFn().set(importedFn, refs);
1438
+ function setSerializeReason(section, reason) {
1439
+ section.serializeReason = reason;
1663
1440
  }
1664
- /**
1665
- * Finds the id reserved for an export, following `export ... from` hops. Each
1666
- * template only records the exports it declares, so this resolves on demand:
1667
- * a template in an import cycle is read while it is still analyzing, and would
1668
- * hand out an incomplete map if the ids were pushed ahead of time.
1669
- */
1670
- function resolveRegisteredExport(file, exportName, seen = /* @__PURE__ */ new Set()) {
1671
- const filename = file.opts.filename;
1672
- const key = `${filename}\0${exportName}`;
1673
- if (seen.has(key)) return;
1674
- seen.add(key);
1675
- const reserved = file.ast.program.extra?.registeredExports?.get(exportName);
1676
- if (reserved) return {
1677
- ...reserved,
1678
- filename
1679
- };
1680
- for (const child of file.ast.program.body) {
1681
- if (child.type !== "ExportNamedDeclaration" && child.type !== "ExportAllDeclaration" || !child.source || (child.exportKind || "value") !== "value") continue;
1682
- const sourceFile = (0, _marko_compiler_babel_utils.loadFileForImport)(file, child.source.value);
1683
- if (!sourceFile) continue;
1684
- if (child.type === "ExportAllDeclaration") {
1685
- const resolved = resolveRegisteredExport(sourceFile, exportName, seen);
1686
- if (resolved) return resolved;
1687
- continue;
1441
+ function setPropSerializeReason(section, key, reason) {
1442
+ section.serializeReasons.set(key, reason);
1443
+ }
1444
+ //#endregion
1445
+ //#region src/translator/util/with-comment.ts
1446
+ function withLeadingComment(node, value) {
1447
+ if (value) {
1448
+ const comment = {
1449
+ type: "CommentBlock",
1450
+ value: ` ${value} `
1451
+ };
1452
+ node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
1453
+ }
1454
+ return node;
1455
+ }
1456
+ //#endregion
1457
+ //#region src/translator/util/serialize-guard.ts
1458
+ const [getSectionReasonState] = createSectionState("serializeReasonState", (section) => ({
1459
+ if: createTypeState(),
1460
+ guard: createTypeState(),
1461
+ declarators: [_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(getSharedUid(`scope${section.id}_reason`, section)), callRuntime("_scope_reason"))]
1462
+ }));
1463
+ function buildGroupMask(groups) {
1464
+ let mask = 0;
1465
+ let maskNames = "";
1466
+ let dynamic;
1467
+ const props = [];
1468
+ let needsObject = false;
1469
+ let any = false;
1470
+ for (let i = 0; i < groups.length; i++) {
1471
+ const { value, names } = groups[i];
1472
+ if (value === void 0) continue;
1473
+ any = true;
1474
+ if (value === 0) continue;
1475
+ if (i >= 15) needsObject = true;
1476
+ else if (typeof value === "number") {
1477
+ mask |= value << 1 + 2 * i;
1478
+ if (names) maskNames += maskNames ? ` | ${names}` : names;
1479
+ } else {
1480
+ const shifted = _marko_compiler.types.binaryExpression("<<", value, withLeadingComment(_marko_compiler.types.numericLiteral(1 + 2 * i), names));
1481
+ dynamic = dynamic ? _marko_compiler.types.binaryExpression("|", dynamic, shifted) : shifted;
1688
1482
  }
1689
- for (const specifier of child.specifiers) {
1690
- if (specifier.type !== "ExportSpecifier" || (specifier.exportKind || "value") !== "value" || getExportedName(specifier) !== exportName) continue;
1691
- const resolved = resolveRegisteredExport(sourceFile, specifier.local.name, seen);
1692
- if (resolved) return resolved;
1483
+ props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), names), typeof value === "number" ? _marko_compiler.types.numericLiteral(value) : value));
1484
+ }
1485
+ if (needsObject) return _marko_compiler.types.objectExpression(props);
1486
+ if (!any) return;
1487
+ const literal = mask ? withLeadingComment(_marko_compiler.types.numericLiteral(mask), maskNames) : void 0;
1488
+ return literal && dynamic ? _marko_compiler.types.binaryExpression("|", literal, dynamic) : literal || dynamic || _marko_compiler.types.numericLiteral(0);
1489
+ }
1490
+ function getScopeReasonDeclaration(section) {
1491
+ return _marko_compiler.types.variableDeclaration("const", getSectionReasonState(section).declarators);
1492
+ }
1493
+ function getSerializeGuard(section, reason, optional) {
1494
+ if (!isDynamicSerializeGuard(section, reason)) {
1495
+ if (!reason) return _marko_compiler.types.numericLiteral(0);
1496
+ return optional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.forced ? void 0 : reason.state));
1497
+ }
1498
+ return getOrHoist(reason, true);
1499
+ }
1500
+ function getSerializeGuardForAny(section, reasons, optional) {
1501
+ if (!Array.isArray(reasons)) return getSerializeGuard(section, reasons, optional);
1502
+ for (const reason of reasons) if (!isReasonDynamic(reason)) return optional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.state));
1503
+ let expr;
1504
+ for (const reason of reasons) {
1505
+ const guard = getSerializeGuard(section, reason, false);
1506
+ expr = expr ? _marko_compiler.types.logicalExpression("||", expr, guard) : guard;
1507
+ }
1508
+ return expr;
1509
+ }
1510
+ function getExprIfSerialized(section, reason, expr) {
1511
+ if (!isDynamicSerializeGuard(section, reason)) return reason && expr;
1512
+ const guard = getOrHoist(reason, false);
1513
+ return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
1514
+ }
1515
+ function getOrHoist(reason, isGuard) {
1516
+ const onlySection = getOnlySection(reason.param);
1517
+ if (onlySection) {
1518
+ const state = getSectionReasonState(onlySection);
1519
+ const tracking = isGuard ? state.guard : state.if;
1520
+ const existingFound = sourcesUtil.find(tracking.hoistedReasons, reason);
1521
+ if (existingFound) return _marko_compiler.types.identifier(tracking.names.get(existingFound));
1522
+ const guard = buildGuardExpr(onlySection, reason.param, isGuard);
1523
+ const seenFound = sourcesUtil.find(tracking.seenReasons, reason);
1524
+ if (!seenFound) {
1525
+ const expr = _marko_compiler.types.parenthesizedExpression(guard);
1526
+ tracking.pending.set(reason, expr);
1527
+ tracking.seenReasons = sourcesUtil.add(tracking.seenReasons, reason);
1528
+ return expr;
1529
+ }
1530
+ const name = generateUid(`${isGuard ? "sg" : "si"}__${getDebugNamesAsIdentifier(reason.param)}`);
1531
+ tracking.hoistedReasons = sourcesUtil.add(tracking.hoistedReasons, reason);
1532
+ tracking.names.set(reason, name);
1533
+ state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(name), guard));
1534
+ const pendingParen = tracking.pending.get(seenFound);
1535
+ if (pendingParen) {
1536
+ pendingParen.expression = _marko_compiler.types.identifier(name);
1537
+ tracking.pending.delete(seenFound);
1693
1538
  }
1539
+ return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(name));
1540
+ }
1541
+ let orExpr;
1542
+ for (const [paramsSection, params] of groupParamsBySection(reason.param)) {
1543
+ const expr = buildGuardExpr(paramsSection, params, isGuard);
1544
+ orExpr = orExpr ? _marko_compiler.types.logicalExpression("||", orExpr, expr) : expr;
1694
1545
  }
1546
+ return orExpr;
1695
1547
  }
1696
- function resolveSerializeReason(exprExtras) {
1697
- let reason;
1698
- for (const exprExtra of exprExtras) reason = mergeSerializeReasons(reason, getAllSerializeReasonsForExtra(getCanonicalExtra(exprExtra), true));
1699
- return reason;
1548
+ function buildGuardExpr(paramsSection, params, isGuard) {
1549
+ const serializeIdentifier = _marko_compiler.types.identifier(getSharedUid(`scope${paramsSection.id}_reason`, paramsSection));
1550
+ return paramsSection.paramReasonGroups ? callRuntime(isGuard ? "_serialize_guard" : "_serialize_if", serializeIdentifier, withLeadingComment(_marko_compiler.types.numericLiteral(getParamReasonGroupIndex(paramsSection, params)), getDebugNames(params))) : serializeIdentifier;
1700
1551
  }
1701
- function registerImportedFn({ node, ...importedFn }) {
1702
- const extra = node.extra ??= {};
1703
- extra.registeredImportedFns ??= [];
1704
- extra.registeredImportedFns.push(importedFn);
1705
- (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
1552
+ function getOnlySection(params) {
1553
+ if (params === void 0) return void 0;
1554
+ if (!Array.isArray(params)) return params.section;
1555
+ const { section } = params[0];
1556
+ return section === params[params.length - 1].section ? section : void 0;
1706
1557
  }
1707
- function reserveExportRegisterId(fnExtra, fn, markoRoot) {
1708
- if (!isStaticRoot(markoRoot)) return;
1709
- const exportNames = getExportNames(fn, markoRoot);
1710
- const exportName = exportNames?.find((name) => _marko_compiler.types.isValidIdentifier(name));
1711
- if (!exportName) return;
1712
- const { markoOpts, opts: { filename } } = (0, _marko_compiler_babel_utils.getFile)();
1713
- const programExtra = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
1714
- const registerId = (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, filename, `${fnExtra.section.id}/export/${exportName}`);
1715
- fnExtra.exportRegisterId = registerId;
1716
- programExtra.registeredExports ??= /* @__PURE__ */ new Map();
1717
- for (const name of exportNames) programExtra.registeredExports.set(name, {
1718
- registerId,
1719
- exportName
1720
- });
1558
+ function isDynamicSerializeGuard(section, reason) {
1559
+ return isReasonDynamic(reason) && !isCrossSection(section, reason);
1721
1560
  }
1722
- function getExportNames(fn, markoRoot) {
1723
- const localName = getExportableName(fn);
1724
- if (localName === void 0) return;
1725
- const exportNames = markoRoot.isExportNamedDeclaration() && !markoRoot.node.source ? [localName] : [];
1726
- const binding = fn.scope.getBinding(localName);
1727
- if (binding) for (const ref of binding.referencePaths) {
1728
- const specifier = ref.parent;
1729
- if (specifier?.type === "ExportSpecifier" && (specifier.exportKind || "value") === "value" && !ref.parentPath.parent.source) {
1730
- const exportName = getExportedName(specifier);
1731
- if (exportName !== "default") exportNames.push(exportName);
1561
+ function isCrossSection(section, reason) {
1562
+ return some(reason.param, (param) => !isSameOrChildSection(param.section, section));
1563
+ }
1564
+ function createTypeState() {
1565
+ return {
1566
+ names: /* @__PURE__ */ new Map(),
1567
+ pending: /* @__PURE__ */ new Map(),
1568
+ seenReasons: void 0,
1569
+ hoistedReasons: void 0
1570
+ };
1571
+ }
1572
+ //#endregion
1573
+ //#region src/translator/util/tag-name-type.ts
1574
+ const MARKO_FILE_REG = /^<.*>$|\.marko$/;
1575
+ const TAG_NAME_IDENTIFIER_REG$1 = /^[A-Z][a-zA-Z0-9_$]*$/;
1576
+ function analyzeTagNameType(tag, allowDynamic) {
1577
+ const extra = tag.node.extra ??= {};
1578
+ if (extra.tagNameType === void 0) {
1579
+ const name = tag.get("name");
1580
+ if (name.isStringLiteral()) {
1581
+ extra.tagNameType = name.node.value[0] === "@" ? 3 : (0, _marko_compiler_babel_utils.isNativeTag)(tag) ? 0 : 1;
1582
+ extra.tagNameNullable = extra.tagNameDynamic = false;
1583
+ } else if (name.isTemplateLiteral() && name.node.quasis.length === 1) {
1584
+ extra.tagNameType = 0;
1585
+ extra.tagNameNullable = extra.tagNameDynamic = false;
1586
+ } else if (name.isIdentifier()) {
1587
+ analyzeExpressionTagName(name, extra);
1588
+ extra.tagNameDynamic = !extra.tagNameImported;
1589
+ } else {
1590
+ analyzeExpressionTagName(name, extra);
1591
+ extra.tagNameDynamic = true;
1732
1592
  }
1593
+ if (!extra.tagNameDynamic && extra.tagNameType === 1 && !isCoreTag(tag)) {
1594
+ const childFile = (0, _marko_compiler_babel_utils.loadFileForTag)(tag);
1595
+ if ((0, _marko_compiler_babel_utils.getTagDef)(tag)?.renderer || childFile?.ast.program.extra.featureType === "class") {
1596
+ extra.tagNameType = 2;
1597
+ extra.tagNameDynamic = true;
1598
+ extra.featureType = "class";
1599
+ if (childFile?.ast.program.extra?.hydratesTags) (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
1600
+ } else if (!childFile) {
1601
+ extra.tagNameType = 2;
1602
+ extra.tagNameDynamic = true;
1603
+ const tagName = name.node.value;
1604
+ extra.tagNameUnresolved = !(TAG_NAME_IDENTIFIER_REG$1.test(tagName) && tag.scope.hasBinding(tagName));
1605
+ } else if (childFile !== (0, _marko_compiler_babel_utils.getFile)() && isAnalyzing(childFile)) {
1606
+ extra.tagNameType = 2;
1607
+ extra.tagNameDynamic = true;
1608
+ }
1609
+ }
1610
+ }
1611
+ return !allowDynamic && extra.tagNameDynamic ? 2 : extra.tagNameType;
1612
+ }
1613
+ function analyzeExpressionTagName(name, extra) {
1614
+ const pending = [name];
1615
+ const seen = /* @__PURE__ */ new Set();
1616
+ let path;
1617
+ let type;
1618
+ let nullable = false;
1619
+ let tagNameImported;
1620
+ let tagNameLoad;
1621
+ let tagNameTemplates = [];
1622
+ while ((path = pending.pop()) && type !== 2) {
1623
+ if (seen.has(path.node)) continue;
1624
+ seen.add(path.node);
1625
+ if (path.isConditionalExpression()) {
1626
+ pending.push(path.get("consequent"));
1627
+ if (path.node.alternate) pending.push(path.get("alternate"));
1628
+ } else if (path.isLogicalExpression()) {
1629
+ if (path.node.operator === "&&") nullable = true;
1630
+ else pending.push(path.get("left"));
1631
+ pending.push(path.get("right"));
1632
+ } else if (path.isAssignmentExpression()) pending.push(path.get("right"));
1633
+ else if (path.isBinaryExpression()) type = path.node.operator !== "+" || type === void 0 || type === 0 ? 0 : 2;
1634
+ else if (path.isStringLiteral() || path.isTemplateLiteral()) type = type === void 0 || type === 0 ? 0 : 2;
1635
+ else if (path.isNullLiteral()) nullable = true;
1636
+ else if (path.isIdentifier()) {
1637
+ if (path.node.name === "undefined") {
1638
+ nullable = true;
1639
+ continue;
1640
+ }
1641
+ const binding = path.scope.getBinding(path.node.name);
1642
+ if (!binding) {
1643
+ type = 2;
1644
+ continue;
1645
+ }
1646
+ if (binding.kind === "module") {
1647
+ const decl = binding.path.parent;
1648
+ if (MARKO_FILE_REG.test(decl.source.value) && decl.specifiers.some((it) => _marko_compiler.types.isImportDefaultSpecifier(it))) {
1649
+ const resolvedImport = decl.extra?.tagImport || decl.source.value;
1650
+ if (tagNameTemplates) {
1651
+ const childFile = (0, _marko_compiler_babel_utils.loadFileForImport)((0, _marko_compiler_babel_utils.getFile)(), resolvedImport);
1652
+ const childExtra = childFile?.ast.program.extra;
1653
+ if (!childExtra || isAnalyzing(childFile)) tagNameTemplates = void 0;
1654
+ else if (!tagNameTemplates.includes(childExtra)) tagNameTemplates.push(childExtra);
1655
+ }
1656
+ if (type === void 0) {
1657
+ type = 1;
1658
+ tagNameImported = resolvedImport;
1659
+ tagNameLoad = decl.extra?.loadImport;
1660
+ } else if (type === 0) {
1661
+ type = 2;
1662
+ tagNameImported = void 0;
1663
+ } else if (tagNameImported !== resolvedImport) tagNameImported = void 0;
1664
+ } else type = 2;
1665
+ continue;
1666
+ }
1667
+ const bindingTag = binding.path;
1668
+ if (bindingTag.isMarkoTag() && binding.kind === "local") {
1669
+ const bindingTagName = bindingTag.get("name").node.value;
1670
+ if (bindingTagName === "const") {
1671
+ pending.push(bindingTag.get("attributes")[0].get("value"));
1672
+ continue;
1673
+ }
1674
+ if (bindingTagName === "let") {
1675
+ type = 2;
1676
+ continue;
1677
+ }
1678
+ continue;
1679
+ }
1680
+ type = 2;
1681
+ } else type = 2;
1682
+ }
1683
+ extra.tagNameType = type ?? 2;
1684
+ extra.tagNameNullable = nullable;
1685
+ if (type === 1) {
1686
+ extra.tagNameTemplates = tagNameTemplates;
1687
+ if (tagNameImported) {
1688
+ extra.tagNameImported = tagNameImported;
1689
+ extra.tagNameLoad = tagNameLoad;
1690
+ }
1691
+ }
1692
+ }
1693
+ //#endregion
1694
+ //#region src/translator/util/sections.ts
1695
+ const sectionUtil = new Sorted(function compareSections(a, b) {
1696
+ return a.id - b.id;
1697
+ });
1698
+ function startSection(path) {
1699
+ const extra = path.node.extra ??= {};
1700
+ let section = extra.section;
1701
+ if (!section && (path.type === "Program" || path.get("body").length)) {
1702
+ const parentTag = path.parentPath?.isMarkoTag() ? path.parentPath : void 0;
1703
+ const parentSection = path.parentPath ? getOrCreateSection(path.parentPath) : void 0;
1704
+ const sectionName = parentTag ? generateUid((isCoreTagName(parentTag, "define") && _marko_compiler.types.isIdentifier(parentTag.node.var) ? parentTag.node.var.name : parentTag.get("name").toString()) + "_content") : "";
1705
+ const programExtra = (0, _marko_compiler_babel_utils.getProgram)().node.extra ??= {};
1706
+ const sections = programExtra.sections ??= [];
1707
+ section = extra.section = {
1708
+ id: sections.length,
1709
+ name: sectionName,
1710
+ loc: parentTag?.node.name.loc || void 0,
1711
+ depth: parentSection ? parentSection.depth + 1 : 0,
1712
+ parent: parentSection,
1713
+ program: void 0,
1714
+ sectionAccessor: void 0,
1715
+ params: void 0,
1716
+ referencedLocalClosures: void 0,
1717
+ referencedClosures: void 0,
1718
+ referencedHoists: void 0,
1719
+ bindings: void 0,
1720
+ hoisted: void 0,
1721
+ hoistedTo: void 0,
1722
+ isHoistThrough: void 0,
1723
+ serializeReason: void 0,
1724
+ serializeReasons: /* @__PURE__ */ new Map(),
1725
+ domSerializeReasons: void 0,
1726
+ serializeExprs: void 0,
1727
+ propSerializeExprs: void 0,
1728
+ serializePropKeys: void 0,
1729
+ paramReasonGroups: void 0,
1730
+ returnValueExpr: void 0,
1731
+ returnSerializeReason: void 0,
1732
+ content: getContentInfo(path),
1733
+ upstreamExpression: void 0,
1734
+ downstream: void 0,
1735
+ hasAbortSignal: false,
1736
+ abortSignalExprs: 0,
1737
+ readsOwner: false,
1738
+ isBranch: false,
1739
+ structure: parentSection && !parentSection.structure ? null : []
1740
+ };
1741
+ section.program = parentSection ? parentSection.program : section;
1742
+ sections.push(section);
1733
1743
  }
1734
- return exportNames.length ? exportNames : void 0;
1744
+ return section;
1735
1745
  }
1736
- function getExportableName(fn) {
1737
- const { node, parent } = fn;
1738
- if (node.type === "FunctionDeclaration") return node.id?.name;
1739
- if (_marko_compiler.types.isVariableDeclarator(parent) && parent.init === node && _marko_compiler.types.isIdentifier(parent.id) && _marko_compiler.types.isVariableDeclaration(fn.parentPath.parent, { kind: "const" })) return parent.id.name;
1746
+ function getOrCreateSection(path) {
1747
+ let cur = path;
1748
+ while (true) {
1749
+ if (cur.type === "Program" || cur.type === "MarkoTagBody" && !cur.node.attributeTags && !isNativeNode(cur.parentPath)) return startSection(cur);
1750
+ cur = cur.parentPath;
1751
+ }
1740
1752
  }
1741
- function getExportedName(specifier) {
1742
- const { exported } = specifier;
1743
- return exported.type === "Identifier" ? exported.name : exported.value;
1753
+ function getSectionForBody(body) {
1754
+ return body.node.extra?.section;
1744
1755
  }
1745
- function canIgnoreRegister(markoRoot, exprRoot) {
1746
- return markoRoot.isMarkoPlaceholder() || markoRoot.isMarkoScriptlet() && (!markoRoot.node.static || markoRoot.node.target === "server") || markoRoot.isMarkoTag() && markoRoot.node.name == exprRoot.node || isMarkoAttribute(markoRoot) && (analyzeTagNameType(markoRoot.parentPath) === 0 && /^on[A-Z-]/.test(markoRoot.node.name) && !hasSpreadAttributeAfter(markoRoot) || isCoreTagName(markoRoot.parentPath, "script") || isCoreTagName(markoRoot.parentPath, "lifecycle") || isCoreTagName(markoRoot.parentPath, "for"));
1756
+ function getSection(path) {
1757
+ let section;
1758
+ let currentPath = path;
1759
+ while ((section = currentPath.node.extra?.section) === void 0) currentPath = currentPath.parentPath;
1760
+ return section;
1747
1761
  }
1748
- function getStaticDeclRefs(path, refs = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set()) {
1749
- const decl = getDeclarationRoot(path);
1750
- if (decl && !seen.has(decl.node)) {
1751
- seen.add(decl.node);
1752
- const ids = decl.getOuterBindingIdentifiers();
1753
- if (ids) for (const name in ids) {
1754
- const binding = decl.scope.getBinding(name);
1755
- if (!binding) continue;
1756
- if (addBindingRefs(binding, refs, seen) === true) return true;
1762
+ const [getScopeIdIdentifier] = createSectionState("scopeIdIdentifier", (section) => generateUidIdentifier(`scope${section.id}_id`));
1763
+ const [getSectionParentIsOwner, setSectionParentIsOwner] = createSectionState("parentIsOwner", () => false);
1764
+ const [getBranchRendererArgs, setBranchRendererArgs] = createSectionState("rendererExpression");
1765
+ function forEachSection(fn) {
1766
+ const { sections } = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
1767
+ sections?.forEach(fn);
1768
+ }
1769
+ function* ancestorSections(from, to) {
1770
+ for (let cur = from; cur !== to && cur.parent; cur = cur.parent) yield cur;
1771
+ }
1772
+ function forEachSectionReverse(fn) {
1773
+ const { sections } = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
1774
+ for (let i = sections.length; i--;) fn(sections[i]);
1775
+ }
1776
+ function getContentInfo(path) {
1777
+ const body = path.get("body");
1778
+ const contentInfo = {
1779
+ startType: null,
1780
+ endType: null,
1781
+ singleChild: true
1782
+ };
1783
+ for (let endIndex = body.length; endIndex--;) {
1784
+ const endType = getNodeContentType(body[endIndex], "endType", contentInfo);
1785
+ if (endType !== null) {
1786
+ contentInfo.endType = endType;
1787
+ if (endType === 1) contentInfo.singleChild = false;
1788
+ for (let startIndex = 0; startIndex < endIndex; startIndex++) {
1789
+ const startType = getNodeContentType(body[startIndex], "startType");
1790
+ if (startType !== null) {
1791
+ contentInfo.startType = startType;
1792
+ contentInfo.singleChild = false;
1793
+ return contentInfo;
1794
+ }
1795
+ }
1796
+ contentInfo.startType = getNodeContentType(body[endIndex], "startType");
1797
+ return contentInfo;
1757
1798
  }
1758
1799
  }
1759
- return refs;
1800
+ return null;
1760
1801
  }
1761
- function addBindingRefs(binding, refs, seen) {
1762
- for (const ref of binding.referencePaths) {
1763
- if (isInvokedFunction(ref) || ref.parentPath.type === "Program") continue;
1764
- const exprRoot = getExprRoot(ref);
1765
- const markoRoot = getMarkoRoot(exprRoot);
1766
- if (!markoRoot || canIgnoreRegister(markoRoot, exprRoot)) continue;
1767
- if (isStaticRoot(markoRoot)) {
1768
- if (getStaticDeclRefs(ref, refs, seen) === true) return true;
1769
- } else if (shouldAlwaysRegister(markoRoot)) return true;
1770
- else {
1771
- refs.add(exprRoot.node.extra ??= {});
1772
- if (getConstTagVarRefs(markoRoot, refs, seen) === true) return true;
1802
+ function getNodeContentType(path, extraMember, contentInfo) {
1803
+ switch (path.type) {
1804
+ case "MarkoText": return 4;
1805
+ case "MarkoPlaceholder": return 2;
1806
+ case "MarkoScriptlet":
1807
+ case "MarkoComment":
1808
+ case "ImportDeclaration":
1809
+ case "ExportAllDeclaration":
1810
+ case "ExportNamedDeclaration":
1811
+ case "ExportDefaultDeclaration": return null;
1812
+ case "MarkoTag": {
1813
+ const tag = path;
1814
+ if (isCoreTag(tag)) switch (tag.node.name.value) {
1815
+ case "html-comment": return 0;
1816
+ case "html-script":
1817
+ case "html-style": return 3;
1818
+ case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child)) ? 3 : null;
1819
+ case "for":
1820
+ case "if":
1821
+ case "await":
1822
+ case "try": return 1;
1823
+ case "show": return 1;
1824
+ default: return null;
1825
+ }
1826
+ else if ((0, _marko_compiler_babel_utils.isNativeTag)(tag)) return 3;
1827
+ else if ((0, _marko_compiler_babel_utils.isAttributeTag)(tag)) return null;
1828
+ else if (_marko_compiler.types.isStringLiteral(tag.node.name)) {
1829
+ const tagSection = (0, _marko_compiler_babel_utils.loadFileForTag)(tag)?.ast.program.extra.section;
1830
+ if (tagSection) if (tagSection.content) {
1831
+ if (contentInfo && !tagSection.content.singleChild) {
1832
+ if (extraMember === "endType") {
1833
+ contentInfo.startType = tagSection.content.startType;
1834
+ contentInfo.singleChild = false;
1835
+ }
1836
+ }
1837
+ return tagSection.content[extraMember];
1838
+ } else return null;
1839
+ }
1773
1840
  }
1774
1841
  }
1842
+ return 1;
1775
1843
  }
1776
- function shouldAlwaysRegister(markoRoot) {
1777
- const tag = getTagFromMarkoRoot(markoRoot);
1778
- if (!tag) return false;
1779
- if (isCoreTagName(tag, "let")) return true;
1780
- if (isCoreTagName(tag, "return")) return true;
1781
- return analyzeTagNameType(tag) === 0;
1844
+ function getSectionRegisterReasons(section) {
1845
+ if (section.isBranch) return false;
1846
+ const { downstream } = section;
1847
+ const dynamicTagBinding = getDynamicTagNodeBinding(section);
1848
+ if (dynamicTagBinding) return getSerializeReason(dynamicTagBinding.section, dynamicTagBinding) || false;
1849
+ if (downstream?.binding) {
1850
+ const downstreamReasons = reduce(downstream.binding, (reasons, binding) => {
1851
+ const reason = getAllSerializeReasonsForBinding(binding, downstream.properties);
1852
+ return mergeSerializeReasons(reasons, reason && (downstream.exprs ? mapParamReason(binding.section.program, reason, downstream.exprs, true) : mapParamReason(section.program, reason, void 0, false)));
1853
+ });
1854
+ if (!downstreamReasons) return false;
1855
+ if (isReasonDynamic(downstreamReasons) && !section.serializeReason && !section.serializeReasons.size && !section.parent?.serializeReason && !section.parent?.serializeReasons.size) return false;
1856
+ return downstreamReasons;
1857
+ } else if (downstream) return false;
1858
+ return true;
1782
1859
  }
1783
- function hasSpreadAttributeAfter(attr) {
1784
- const attrs = attr.parent.attributes;
1785
- for (let i = attr.key + 1; i < attrs.length; i++) if (attrs[i].type === "MarkoSpreadAttribute") return true;
1786
- return false;
1860
+ function isSectionRegisterDynamic(section, registerReason) {
1861
+ const dynamicTagBinding = getDynamicTagNodeBinding(section);
1862
+ return !!dynamicTagBinding && registerReason !== true && isDynamicSerializeGuard(dynamicTagBinding.section, registerReason);
1787
1863
  }
1788
- function getTagFromMarkoRoot(markoRoot) {
1789
- let cur = markoRoot;
1790
- do {
1791
- if (cur.isMarkoTag()) return cur;
1792
- cur = cur.parentPath;
1793
- } while (cur);
1864
+ function isSectionRegisterEager(section) {
1865
+ const registerReason = getSectionRegisterReasons(section);
1866
+ return !!registerReason && !isSectionRegisterDynamic(section, registerReason);
1794
1867
  }
1795
- function registerFunction(fnExtra, reason) {
1796
- const { markoOpts, path: program, opts: { filename } } = (0, _marko_compiler_babel_utils.getFile)();
1797
- program.node.extra.isInteractive = true;
1798
- fnExtra.registerReason = reason;
1799
- fnExtra.name = generateUid(fnExtra.name);
1800
- fnExtra.registerId = fnExtra.exportRegisterId ?? (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, filename, `${fnExtra.section.id}/${fnExtra.name.slice(1)}`);
1868
+ function getDynamicTagNodeBinding(section) {
1869
+ const { upstreamExpression } = section;
1870
+ return upstreamExpression?.tagNameType === 0 ? upstreamExpression.nodeBinding : void 0;
1801
1871
  }
1802
- function isMarkoAttribute(path) {
1803
- return path ? path.isMarkoAttribute() : false;
1872
+ function isImmediateOwner(section, binding) {
1873
+ return section.parent?.id === binding.section.id;
1804
1874
  }
1805
- function isStaticRoot(path) {
1806
- switch (path.type) {
1807
- case "MarkoScriptlet": return path.node.static;
1808
- case "ExportDefaultDeclaration":
1809
- case "ExportNamedDeclaration": return true;
1810
- default: return false;
1811
- }
1875
+ function isDirectClosure(section, closure) {
1876
+ return section.isBranch && isImmediateOwner(section, closure);
1812
1877
  }
1813
- //#endregion
1814
- //#region src/translator/util/analyze-errors.ts
1815
- const [getHasAnalyzeErrors, setHasAnalyzeErrors] = createProgramState(() => false);
1816
- function reportAnalyzeError(path, error) {
1817
- if (!(error instanceof Error)) throw error;
1818
- const { label = error.message, loc } = error;
1819
- setHasAnalyzeErrors(true);
1820
- (0, _marko_compiler_babel_utils.diagnosticError)(path, {
1821
- label,
1822
- loc: loc ?? path.node.loc ?? void 0
1878
+ function isDynamicClosure(section, closure) {
1879
+ return !isDirectClosure(section, closure);
1880
+ }
1881
+ function getDynamicClosureIndex(closure, closureSection) {
1882
+ let index = 0;
1883
+ find(closure.closureSections, (section) => {
1884
+ if (section === closureSection) return true;
1885
+ if (isDynamicClosure(section, closure)) index++;
1886
+ return false;
1823
1887
  });
1888
+ return index;
1824
1889
  }
1825
- function hasAnalyzeErrors() {
1826
- return getHasAnalyzeErrors();
1890
+ function getDirectClosures(section) {
1891
+ if (section.isBranch) return bindingUtil.filter(section.referencedClosures, (closure) => isImmediateOwner(section, closure));
1827
1892
  }
1828
- //#endregion
1829
- //#region src/translator/util/asset-imports.ts
1830
- function addAssetImport(request) {
1831
- ((0, _marko_compiler_babel_utils.getFile)().metadata.marko.assetImports ??= /* @__PURE__ */ new Set()).add(request);
1893
+ function isSameOrChildSection(section, other) {
1894
+ do
1895
+ if (other === section) return true;
1896
+ while (other = other.parent);
1897
+ return false;
1832
1898
  }
1833
- function isClientAssetImport(file, request) {
1834
- const { hydrateIncludeImports } = file.markoOpts;
1835
- return typeof hydrateIncludeImports === "function" ? hydrateIncludeImports(request) : !!hydrateIncludeImports?.test(request);
1899
+ function getCommonSection(section, other) {
1900
+ let ancestor = section;
1901
+ if (other.depth < section.depth) {
1902
+ ancestor = other;
1903
+ other = section;
1904
+ }
1905
+ while (ancestor) {
1906
+ if (other === ancestor || !other.parent) return ancestor;
1907
+ other = other.parent;
1908
+ if (other.depth < ancestor.depth) ancestor = ancestor.parent;
1909
+ }
1910
+ throw new Error("No common section");
1836
1911
  }
1837
- //#endregion
1838
- //#region src/translator/util/binding-has-prop.ts
1839
- function isSectionRendererElided(section) {
1840
- return !!section.downstream?.binding && !bindingHasProperty(section.downstream.binding, section.downstream.properties);
1912
+ function finalizeParamSerializeReasonGroups(section) {
1913
+ ensureReasonGroups(section.serializeReason);
1914
+ for (const reason of section.serializeReasons.values()) ensureReasonGroups(reason);
1841
1915
  }
1842
- function bindingHasProperty(binding, properties) {
1843
- if (binding.pruned) return false;
1844
- else if (binding.pruned === void 0) throw new Error("Binding must be pruned before checking properties");
1845
- if (binding.reads.size || !properties) return true;
1846
- let property;
1847
- let rest;
1848
- if (Array.isArray(properties)) {
1849
- property = properties[0];
1850
- rest = properties.length === 2 ? properties[1] : properties.slice(1);
1851
- } else property = properties;
1852
- const propBinding = binding.propertyAliases.get(property);
1853
- if (propBinding && bindingHasProperty(propBinding, rest)) return true;
1854
- for (const alias of binding.aliases) if (bindingHasProperty(alias, properties)) return true;
1855
- return false;
1916
+ function ensureReasonGroups(reason) {
1917
+ if (isReasonDynamic(reason)) for (const [paramSection, params] of groupParamsBySection(reason.param)) ensureParamReasonGroup(paramSection, params);
1856
1918
  }
1857
- //#endregion
1858
- //#region src/translator/util/binding-prop-tree.ts
1859
- const kDirectContent = Symbol("direct content");
1860
- function getBindingPropTree(binding) {
1861
- if (pruneBinding(binding)) return;
1862
- binding.exposed = true;
1863
- const props = {
1864
- binding,
1865
- props: void 0,
1866
- rest: void 0
1867
- };
1868
- if (!binding.reads.size) {
1869
- if (!binding.aliases.size) {
1870
- props.props = Object.create(null);
1871
- for (const [property, alias] of binding.propertyAliases) props.props[property] = getBindingPropTree(alias);
1872
- } else if (binding.aliases.size === 1) {
1873
- const [restAlias] = binding.aliases;
1874
- if (hasSupersetExcludeProperties(binding, restAlias.excludeProperties)) {
1875
- props.rest = getBindingPropTree(restAlias);
1876
- props.props = Object.create(null);
1877
- if (restAlias.type === 2) restAlias.export ??= generateUid(restAlias.name);
1878
- forEach(restAlias.excludeProperties, (property) => {
1879
- const propAlias = binding.propertyAliases.get(property);
1880
- if (propAlias) props.props[property] = getBindingPropTree(propAlias);
1881
- });
1882
- }
1883
- }
1919
+ function ensureParamReasonGroup(section, reason) {
1920
+ const { paramReasonGroups } = section;
1921
+ if (paramReasonGroups) {
1922
+ const found = findSorted(compareParamGroups, paramReasonGroups, { reason });
1923
+ if (found) return found;
1884
1924
  }
1885
- if (binding.type === 2) binding.export ??= generateUid(binding.name);
1886
- if (isDirectContentBinding(binding)) binding.directContentExport ??= generateUid(`${binding.name}_direct`);
1887
- return props;
1888
- }
1889
- function isDirectContentBinding(binding) {
1890
- if (binding.reads.size !== 1) return false;
1891
- const [read] = binding.reads;
1892
- return read[kDirectContent] && read.section === binding.section;
1925
+ const group = {
1926
+ id: Symbol(getDebugNames(reason)),
1927
+ reason
1928
+ };
1929
+ section.paramReasonGroups = paramReasonGroups ? addSorted(compareParamGroups, paramReasonGroups, group) : [group];
1893
1930
  }
1894
- function hasSupersetExcludeProperties(binding, excludeProperties) {
1895
- if (excludeProperties === void 0) return false;
1896
- for (const prop of binding.propertyAliases.keys()) if (!propsUtil.has(excludeProperties, prop)) return false;
1897
- return true;
1931
+ function getParamReasonGroupIndex(section, reason) {
1932
+ const index = section.paramReasonGroups && findIndexSorted(compareParamGroups, section.paramReasonGroups, { reason });
1933
+ if (index === void 0 || index === -1) throw new Error("Invalid compiler state, cannot ask for a serialize reason group that was not analyzed.");
1934
+ return index;
1898
1935
  }
1899
- function getKnownFromPropTree(propTree, name) {
1900
- return propTree === true ? true : propTree.props ? propTree.props[name] || (propTree.rest ? getKnownFromPropTree(propTree.rest, name) : void 0) : includes(propTree.binding.excludeProperties, name) ? void 0 : true;
1936
+ function groupParamsBySection(params) {
1937
+ return bindingUtil.groupBy(params, bindingToSection);
1901
1938
  }
1902
- function getAllKnownPropNames(propTree) {
1903
- const keys = propTree.props ? Object.keys(propTree.props) : [];
1904
- if (propTree.rest?.props) for (const key of Object.keys(propTree.rest.props)) keys.push(key);
1905
- return keys;
1939
+ function bindingToSection(binding) {
1940
+ return binding.section;
1906
1941
  }
1907
- function hasAllKnownProps(propTree) {
1908
- return propTree.props && (!propTree.rest || !!propTree.rest.props);
1942
+ function compareParamGroups(a, b) {
1943
+ return compareReferences(a.reason, b.reason);
1909
1944
  }
1910
- //#endregion
1911
- //#region src/translator/util/resolve-relative-to-entry.ts
1912
- function resolveRelativeToEntry(entryFile, file, req) {
1913
- return file === entryFile ? (0, _marko_compiler_babel_utils.resolveRelativePath)(file, req) : (0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, req[0] === "." ? path.default.join(file.opts.filename, "..", req) : req);
1945
+ function isNativeNode(tag) {
1946
+ if (isCoreTag(tag)) switch (tag.node.name.value) {
1947
+ case "html-comment":
1948
+ case "html-script":
1949
+ case "html-style":
1950
+ case "show": return true;
1951
+ case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child));
1952
+ default: return false;
1953
+ }
1954
+ return analyzeTagNameType(tag) === 0;
1914
1955
  }
1915
1956
  //#endregion
1916
- //#region src/translator/util/entry-builder.ts
1917
- const kState = Symbol();
1918
- const builder = {
1919
- build(entryFile, exportInit) {
1920
- const state = entryFile[kState];
1921
- if (!state) throw entryFile.path.buildCodeFrameError("Unable to build hydrate code, no files were visited before finalizing the build");
1922
- const body = [];
1923
- for (const asset of state.assets) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(asset)));
1924
- if (state.init || state.load) {
1925
- const isPage = entryFile.path.node.extra.page;
1926
- const initHelper = isPage ? "init" : "initEmbedded";
1927
- if (state.init) body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importSpecifier(_marko_compiler.types.identifier(initHelper), _marko_compiler.types.identifier(initHelper))], _marko_compiler.types.stringLiteral(`${runtime_info_default.name}/${entryFile.markoOpts.optimize ? "" : "debug/"}dom`)));
1928
- for (const root of state.roots) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(root)));
1929
- if (!state.init) {
1930
- if (exportInit) body.push(_marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([]))));
1931
- return body;
1932
- }
1933
- const { runtimeId } = entryFile.markoOpts;
1934
- const readyId = !isPage && (0, _marko_compiler_babel_utils.getTemplateId)(entryFile.markoOpts, entryFile.opts.filename);
1935
- const initExpression = _marko_compiler.types.callExpression(_marko_compiler.types.identifier(initHelper), readyId ? runtimeId ? [_marko_compiler.types.stringLiteral(readyId), _marko_compiler.types.stringLiteral(runtimeId)] : [_marko_compiler.types.stringLiteral(readyId)] : runtimeId ? [_marko_compiler.types.stringLiteral(runtimeId)] : []);
1936
- body.push(exportInit ? _marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], initExpression)) : _marko_compiler.types.expressionStatement(initExpression));
1937
- } else {
1938
- for (const asset of state.bundledAssets) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(asset)));
1939
- if (exportInit) body.push(_marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([]))));
1940
- }
1941
- return body;
1942
- },
1943
- visit(file, entryFile, visitChild = (id, bundled = false) => {
1944
- const state = entryFile[kState];
1945
- const resolved = resolveRelativeToEntry(entryFile, file, id);
1946
- const seenBundled = state.visited.get(resolved);
1947
- if (seenBundled === false || seenBundled && bundled) return;
1948
- state.visited.set(resolved, bundled);
1949
- const childFile = (0, _marko_compiler_babel_utils.loadFileForImport)(entryFile, resolved);
1950
- if (childFile) builder.visit(childFile, entryFile);
1951
- }) {
1952
- const state = entryFile[kState] ||= {
1953
- init: false,
1954
- load: false,
1955
- bundled: 0,
1956
- roots: [],
1957
- assets: /* @__PURE__ */ new Set(),
1958
- bundledAssets: /* @__PURE__ */ new Set(),
1959
- visited: /* @__PURE__ */ new Map([[(0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, entryFile.opts.filename), false]])
1960
- };
1961
- const programExtra = file.path.node.extra;
1962
- const { analyzedTags, assetImports } = file.metadata.marko;
1963
- const { loadImports } = programExtra;
1964
- const init = !!(programExtra.isInteractive || programExtra.needsCompat);
1965
- const load = !!programExtra.hasClientStatement;
1966
- const isRoot = !state.bundled && (init || load || !!programExtra.hasResumes);
1967
- if (init) state.init = true;
1968
- if (load) state.load = true;
1969
- if (isRoot) state.roots.push((0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, file.opts.filename));
1970
- if (assetImports) {
1971
- const assets = isRoot || state.bundled ? state.bundledAssets : state.assets;
1972
- for (const request of assetImports) assets.add(resolveRelativeToEntry(entryFile, file, request));
1973
- }
1974
- if (isRoot) state.bundled++;
1975
- for (const tag of analyzedTags ? [...analyzedTags] : []) {
1976
- const lazy = loadImports?.has(tag);
1977
- if (lazy) state.bundled++;
1978
- visitChild(tag, !!state.bundled);
1979
- if (lazy) state.bundled--;
1980
- }
1981
- if (isRoot) state.bundled--;
1957
+ //#region src/translator/visitors/function.ts
1958
+ const [getReferencesByFn] = createProgramState(() => /* @__PURE__ */ new Map());
1959
+ const [getReferencesByImportedFn] = createProgramState(() => /* @__PURE__ */ new Map());
1960
+ var function_default = { analyze(fn) {
1961
+ const awaitNode = isMarkoAttribute(fn.parentPath) && _marko_compiler.types.isFunctionExpression(fn.node) && !fn.node.async && traverseFindAwait(fn.node.body);
1962
+ if (awaitNode) {
1963
+ const file = (0, _marko_compiler_babel_utils.getFile)();
1964
+ const start = file.code.indexOf("await", awaitNode.start ?? 0);
1965
+ const highlight = start >= 0 && (awaitNode.end == null || start < awaitNode.end) ? (0, _marko_compiler_babel_utils.withLoc)(file, _marko_compiler.types.cloneNode(awaitNode), start, start + 5) : awaitNode;
1966
+ throw fn.hub.buildError(highlight, "Attribute methods containing `await` must be `async`. Add `async` before the method name.");
1982
1967
  }
1983
- };
1984
- //#endregion
1985
- //#region src/translator/util/get-style-file.ts
1986
- function getStyleFile(file) {
1987
- const { filename } = file.opts;
1988
- const fs = file.markoOpts.fileSystem;
1989
- const base = getBase(filename);
1990
- const styleMatch = new RegExp(`^(${escapeRegExp(base)}\\.${"index" === base ? "|" : ""})style\\.\\w+$`);
1991
- for (const file of fs.readdirSync(path.default.dirname(filename)).sort()) if (styleMatch.test(file)) return `./${file}`;
1968
+ if (fn !== getFnRoot(fn)) return;
1969
+ const { node } = fn;
1970
+ if ((_marko_compiler.types.isObjectMethod(node) || _marko_compiler.types.isClassMethod(node)) && (node.kind === "get" || node.kind === "set")) return;
1971
+ const exprRoot = getExprRoot(fn);
1972
+ const markoRoot = getMarkoRoot(exprRoot);
1973
+ if (!markoRoot || canIgnoreRegister(markoRoot, exprRoot)) return;
1974
+ const section = getSection(fn);
1975
+ const fnExtra = node.extra ??= {};
1976
+ fnExtra.section = section;
1977
+ fnExtra.exprRoot = exprRoot.node.extra ??= {};
1978
+ fnExtra.name = node.id?.name || (isMarkoAttribute(markoRoot) ? markoRoot.node.default ? _marko_compiler.types.toIdentifier((markoRoot.parentPath.has("var") ? markoRoot.parentPath.get("var") : markoRoot.parentPath.get("name")).toString()) : markoRoot.node.name : _marko_compiler.types.isVariableDeclarator(fn.parent) && _marko_compiler.types.isIdentifier(fn.parent.id) ? fn.parent.id.name : _marko_compiler.types.isObjectMethod(node) && _marko_compiler.types.isIdentifier(node.key) ? node.key.name : "anonymous");
1979
+ reserveExportRegisterId(fnExtra, fn, markoRoot);
1980
+ if (isStaticRoot(markoRoot)) {
1981
+ const refs = getStaticDeclRefs(fn);
1982
+ if (refs === true) registerFunction(fnExtra, FORCED);
1983
+ else if (refs.size) getReferencesByFn().set(fnExtra, refs);
1984
+ } else if (shouldAlwaysRegister(markoRoot)) registerFunction(fnExtra, FORCED);
1985
+ else getReferencesByFn().set(fnExtra, /* @__PURE__ */ new Set([fnExtra.exprRoot]));
1986
+ } };
1987
+ function finalizeFunctionRegistry() {
1988
+ for (const [fnExtra, exprExtras] of getReferencesByFn()) {
1989
+ const reason = resolveSerializeReason(exprExtras);
1990
+ if (reason) registerFunction(fnExtra, reason);
1991
+ }
1992
+ for (const [importedFn, exprExtras] of getReferencesByImportedFn()) if (resolveSerializeReason(exprExtras)) registerImportedFn(importedFn);
1992
1993
  }
1993
1994
  /**
1994
- * Given a filename, gets the base name, strips off the file extension
1995
- * and removes any arc flags (https://github.com/eBay/arc).
1996
- *
1997
- * @example
1998
- * getBase("/dir/foo.marko") // => "foo"
1999
- * getBase("/dir/foo.bar.marko") // => "foo.bar"
2000
- * getBase("/dir/foo[bar].marko") // => "foo"
2001
- * getBase("/dir/foo[bar].baz.marko") // => "foo.baz"
1995
+ * Tracks a function imported from another template that reserved a register id.
1996
+ * The importing template registers it (under the reserved id) when its own
1997
+ * references reach something serialized.
2002
1998
  */
2003
- function getBase(filename) {
2004
- const start = filename.lastIndexOf(path.default.sep) + 1;
2005
- const leftDot = filename.indexOf(".", start);
2006
- if (leftDot === -1) return filename.slice(start);
2007
- const rightDot = filename.lastIndexOf(".");
2008
- const closeBracket = leftDot - 1;
2009
- if (filename[closeBracket] === "]") {
2010
- const openBracket = filename.lastIndexOf("[", closeBracket);
2011
- if (openBracket > start) return filename.slice(start, openBracket) + filename.slice(leftDot, rightDot);
1999
+ function trackImportedFn(importDecl, local, resolved) {
2000
+ const binding = importDecl.scope.getBinding(local);
2001
+ if (!binding) return;
2002
+ const importedFn = {
2003
+ ...resolved,
2004
+ node: importDecl.node,
2005
+ local
2006
+ };
2007
+ const refs = /* @__PURE__ */ new Set();
2008
+ if (addBindingRefs(binding, refs, /* @__PURE__ */ new Set()) === true) registerImportedFn(importedFn);
2009
+ else if (refs.size) getReferencesByImportedFn().set(importedFn, refs);
2010
+ }
2011
+ /**
2012
+ * Finds the id reserved for an export, following `export ... from` hops. Each
2013
+ * template only records the exports it declares, so this resolves on demand:
2014
+ * a template in an import cycle is read while it is still analyzing, and would
2015
+ * hand out an incomplete map if the ids were pushed ahead of time.
2016
+ */
2017
+ function resolveRegisteredExport(file, exportName, seen = /* @__PURE__ */ new Set()) {
2018
+ const filename = file.opts.filename;
2019
+ const key = `${filename}\0${exportName}`;
2020
+ if (seen.has(key)) return;
2021
+ seen.add(key);
2022
+ const reserved = file.ast.program.extra?.registeredExports?.get(exportName);
2023
+ if (reserved) return {
2024
+ ...reserved,
2025
+ filename
2026
+ };
2027
+ for (const child of file.ast.program.body) {
2028
+ if (child.type !== "ExportNamedDeclaration" && child.type !== "ExportAllDeclaration" || !child.source || (child.exportKind || "value") !== "value") continue;
2029
+ const sourceFile = (0, _marko_compiler_babel_utils.loadFileForImport)(file, child.source.value);
2030
+ if (!sourceFile) continue;
2031
+ if (child.type === "ExportAllDeclaration") {
2032
+ const resolved = resolveRegisteredExport(sourceFile, exportName, seen);
2033
+ if (resolved) return resolved;
2034
+ continue;
2035
+ }
2036
+ for (const specifier of child.specifiers) {
2037
+ if (specifier.type !== "ExportSpecifier" || (specifier.exportKind || "value") !== "value" || getExportedName(specifier) !== exportName) continue;
2038
+ const resolved = resolveRegisteredExport(sourceFile, specifier.local.name, seen);
2039
+ if (resolved) return resolved;
2040
+ }
2012
2041
  }
2013
- return filename.slice(start, rightDot);
2014
2042
  }
2015
- const regexpCharsReg = /[\\^$.*+?()[\]{}|]/g;
2016
- function escapeRegExp(str) {
2017
- return str.replace(regexpCharsReg, "\\$&");
2043
+ function resolveSerializeReason(exprExtras) {
2044
+ let reason;
2045
+ for (const exprExtra of exprExtras) reason = mergeSerializeReasons(reason, getRegisterReasonForExtra(getCanonicalExtra(exprExtra)));
2046
+ return reason;
2018
2047
  }
2019
- //#endregion
2020
- //#region src/common/errors.ts
2021
- function assertExclusiveAttrs(attrs, onError = throwErr) {
2022
- if (attrs) {
2023
- let exclusiveAttrs;
2024
- if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange");
2025
- if ("checkedValue" in attrs) {
2026
- (exclusiveAttrs ||= []).push("checkedValue");
2027
- if ("checked" in attrs) exclusiveAttrs.push("checked");
2028
- } else if (attrs.checkedValueChange) {
2029
- (exclusiveAttrs ||= []).push("checkedValueChange");
2030
- if ("checked" in attrs) exclusiveAttrs.push("checked");
2031
- }
2032
- if (attrs.valueChange) {
2033
- (exclusiveAttrs ||= []).push("valueChange");
2034
- if ("checked" in attrs && !exclusiveAttrs.includes("checked")) exclusiveAttrs.push("checked");
2048
+ function registerImportedFn({ node, ...importedFn }) {
2049
+ const extra = node.extra ??= {};
2050
+ extra.registeredImportedFns ??= [];
2051
+ extra.registeredImportedFns.push(importedFn);
2052
+ (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
2053
+ }
2054
+ function reserveExportRegisterId(fnExtra, fn, markoRoot) {
2055
+ if (!isStaticRoot(markoRoot)) return;
2056
+ const exportNames = getExportNames(fn, markoRoot);
2057
+ const exportName = exportNames?.find((name) => _marko_compiler.types.isValidIdentifier(name));
2058
+ if (!exportName) return;
2059
+ const { markoOpts, opts: { filename } } = (0, _marko_compiler_babel_utils.getFile)();
2060
+ const programExtra = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
2061
+ const registerId = (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, filename, `${fnExtra.section.id}/export/${exportName}`);
2062
+ fnExtra.exportRegisterId = registerId;
2063
+ programExtra.registeredExports ??= /* @__PURE__ */ new Map();
2064
+ for (const name of exportNames) programExtra.registeredExports.set(name, {
2065
+ registerId,
2066
+ exportName
2067
+ });
2068
+ }
2069
+ function getExportNames(fn, markoRoot) {
2070
+ const localName = getExportableName(fn);
2071
+ if (localName === void 0) return;
2072
+ const exportNames = markoRoot.isExportNamedDeclaration() && !markoRoot.node.source ? [localName] : [];
2073
+ const binding = fn.scope.getBinding(localName);
2074
+ if (binding) for (const ref of binding.referencePaths) {
2075
+ const specifier = ref.parent;
2076
+ if (specifier?.type === "ExportSpecifier" && (specifier.exportKind || "value") === "value" && !ref.parentPath.parent.source) {
2077
+ const exportName = getExportedName(specifier);
2078
+ if (exportName !== "default") exportNames.push(exportName);
2035
2079
  }
2036
- if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
2037
2080
  }
2081
+ return exportNames.length ? exportNames : void 0;
2038
2082
  }
2039
- function throwErr(msg) {
2040
- throw new Error(msg);
2041
- }
2042
- function joinWithAnd(a) {
2043
- switch (a.length) {
2044
- case 0: return "";
2045
- case 1: return a[0];
2046
- case 2: return `${a[0]} and ${a[1]}`;
2047
- default: return `${a.slice(0, -1).join(", ")}, and ${a[a.length - 1]}`;
2048
- }
2083
+ function getExportableName(fn) {
2084
+ const { node, parent } = fn;
2085
+ if (node.type === "FunctionDeclaration") return node.id?.name;
2086
+ if (_marko_compiler.types.isVariableDeclarator(parent) && parent.init === node && _marko_compiler.types.isIdentifier(parent.id) && _marko_compiler.types.isVariableDeclaration(fn.parentPath.parent, { kind: "const" })) return parent.id.name;
2049
2087
  }
2050
- //#endregion
2051
- //#region src/html/content.ts
2052
- function _unescaped(val) {
2053
- return val ? val + "" : val === 0 ? "0" : "";
2088
+ function getExportedName(specifier) {
2089
+ const { exported } = specifier;
2090
+ return exported.type === "Identifier" ? exported.name : exported.value;
2054
2091
  }
2055
- const unsafeXMLReg = /[<&\r]/g;
2056
- const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : "&#13;";
2057
- const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str;
2058
- function _escape(val) {
2059
- return val ? escapeXMLStr(val + "") : val === 0 ? "0" : "";
2092
+ function canIgnoreRegister(markoRoot, exprRoot) {
2093
+ return markoRoot.isMarkoPlaceholder() || markoRoot.isMarkoScriptlet() && (!markoRoot.node.static || markoRoot.node.target === "server") || markoRoot.isMarkoTag() && markoRoot.node.name == exprRoot.node || isMarkoAttribute(markoRoot) && (analyzeTagNameType(markoRoot.parentPath) === 0 && /^on[A-Z-]/.test(markoRoot.node.name) && !hasSpreadAttributeAfter(markoRoot) || isCoreTagName(markoRoot.parentPath, "script") || isCoreTagName(markoRoot.parentPath, "lifecycle") || isCoreTagName(markoRoot.parentPath, "for"));
2060
2094
  }
2061
- const unsafeScriptReg = /<(\/?script|!--)/gi;
2062
- const escapeScriptStr = (str) => unsafeScriptReg.test(str) ? str.replace(unsafeScriptReg, "\\x3C$1") : str;
2063
- function _escape_script(val) {
2064
- return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
2095
+ function getStaticDeclRefs(path, refs = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set()) {
2096
+ const decl = getDeclarationRoot(path);
2097
+ if (decl && !seen.has(decl.node)) {
2098
+ seen.add(decl.node);
2099
+ const ids = decl.getOuterBindingIdentifiers();
2100
+ if (ids) for (const name in ids) {
2101
+ const binding = decl.scope.getBinding(name);
2102
+ if (!binding) continue;
2103
+ if (addBindingRefs(binding, refs, seen) === true) return true;
2104
+ }
2105
+ }
2106
+ return refs;
2065
2107
  }
2066
- const unsafeStyleReg = /<(\/style)/gi;
2067
- const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str;
2068
- function _escape_style(val) {
2069
- return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
2108
+ function addBindingRefs(binding, refs, seen) {
2109
+ for (const ref of binding.referencePaths) {
2110
+ if (isInvokedFunction(ref) || ref.parentPath.type === "Program") continue;
2111
+ const exprRoot = getExprRoot(ref);
2112
+ const markoRoot = getMarkoRoot(exprRoot);
2113
+ if (!markoRoot || canIgnoreRegister(markoRoot, exprRoot)) continue;
2114
+ if (isStaticRoot(markoRoot)) {
2115
+ if (getStaticDeclRefs(ref, refs, seen) === true) return true;
2116
+ } else if (shouldAlwaysRegister(markoRoot)) return true;
2117
+ else refs.add(exprRoot.node.extra ??= {});
2118
+ }
2070
2119
  }
2071
- const unsafeCommentReg = />/g;
2072
- const escapeCommentStr = (str) => unsafeCommentReg.test(str) ? str.replace(unsafeCommentReg, "&gt;") : str;
2073
- function _escape_comment(val) {
2074
- return val ? escapeCommentStr(val + "") : val === 0 ? "0" : "";
2120
+ function shouldAlwaysRegister(markoRoot) {
2121
+ const tag = getTagFromMarkoRoot(markoRoot);
2122
+ if (!tag) return false;
2123
+ if (isCoreTagName(tag, "let")) return true;
2124
+ if (isCoreTagName(tag, "return")) return true;
2125
+ return analyzeTagNameType(tag) === 0;
2075
2126
  }
2076
- globalThis.setImmediate || globalThis.setTimeout || globalThis.queueMicrotask;
2077
- //#endregion
2078
- //#region src/html/attrs.ts
2079
- function _attr_class(value) {
2080
- return stringAttr("class", toDelimitedString(value, " ", stringifyClassObject));
2127
+ function hasSpreadAttributeAfter(attr) {
2128
+ const attrs = attr.parent.attributes;
2129
+ for (let i = attr.key + 1; i < attrs.length; i++) if (attrs[i].type === "MarkoSpreadAttribute") return true;
2130
+ return false;
2081
2131
  }
2082
- function _attr_style(value) {
2083
- return stringAttr("style", toDelimitedString(value, ";", stringifyStyleObject));
2132
+ function getTagFromMarkoRoot(markoRoot) {
2133
+ let cur = markoRoot;
2134
+ do {
2135
+ if (cur.isMarkoTag()) return cur;
2136
+ cur = cur.parentPath;
2137
+ } while (cur);
2084
2138
  }
2085
- function _attr(name, value) {
2086
- return isVoid(value) ? "" : nonVoidAttr(name, value);
2139
+ function registerFunction(fnExtra, reason) {
2140
+ const { markoOpts, path: program, opts: { filename } } = (0, _marko_compiler_babel_utils.getFile)();
2141
+ program.node.extra.isInteractive = true;
2142
+ fnExtra.registerReason = reason;
2143
+ fnExtra.name = generateUid(fnExtra.name);
2144
+ fnExtra.registerId = fnExtra.exportRegisterId ?? (0, _marko_compiler_babel_utils.getTemplateId)(markoOpts, filename, `${fnExtra.section.id}/${fnExtra.name.slice(1)}`);
2087
2145
  }
2088
- function stringAttr(name, value) {
2089
- return value && " " + name + attrAssignment(value);
2146
+ function isMarkoAttribute(path) {
2147
+ return path ? path.isMarkoAttribute() : false;
2090
2148
  }
2091
- function nonVoidAttr(name, value) {
2092
- switch (typeof value) {
2093
- case "string": return " " + name + attrAssignment(value);
2094
- case "boolean": return " " + name;
2095
- case "number": return " " + name + "=" + value;
2149
+ function isStaticRoot(path) {
2150
+ switch (path.type) {
2151
+ case "MarkoScriptlet": return path.node.static;
2152
+ case "ExportDefaultDeclaration":
2153
+ case "ExportNamedDeclaration": return true;
2154
+ default: return false;
2096
2155
  }
2097
- return " " + name + attrAssignment(value + "");
2098
2156
  }
2099
- const singleQuoteAttrReplacements = /['\r]|&(?=[#a-zA-Z])/g;
2100
- const doubleQuoteAttrReplacements = /["\r]|&(?=[#a-zA-Z])/g;
2101
- const needsQuotedAttr = /["'>\s]|&[#a-zA-Z]|\/$/g;
2102
- function attrAssignment(value) {
2103
- return value ? needsQuotedAttr.test(value) ? value[needsQuotedAttr.lastIndex - 1] === (needsQuotedAttr.lastIndex = 0, "\"") ? "='" + escapeSingleQuotedAttrValue(value) + "'" : "=\"" + escapeDoubleQuotedAttrValue(value) + "\"" : "=" + value : "";
2157
+ //#endregion
2158
+ //#region src/translator/util/analyze-errors.ts
2159
+ const [getHasAnalyzeErrors, setHasAnalyzeErrors] = createProgramState(() => false);
2160
+ function reportAnalyzeError(path, error) {
2161
+ if (!(error instanceof Error)) throw error;
2162
+ const { label = error.message, loc } = error;
2163
+ setHasAnalyzeErrors(true);
2164
+ (0, _marko_compiler_babel_utils.diagnosticError)(path, {
2165
+ label,
2166
+ loc: loc ?? path.node.loc ?? void 0
2167
+ });
2104
2168
  }
2105
- function escapeSingleQuotedAttrValue(value) {
2106
- return singleQuoteAttrReplacements.test(value) ? value.replace(singleQuoteAttrReplacements, replaceUnsafeSingleQuoteAttrChar) : value;
2169
+ function hasAnalyzeErrors() {
2170
+ return getHasAnalyzeErrors();
2107
2171
  }
2108
- function replaceUnsafeSingleQuoteAttrChar(match) {
2109
- return match === "'" ? "&#39;" : match === "\r" ? "&#13;" : "&amp;";
2172
+ //#endregion
2173
+ //#region src/translator/util/asset-imports.ts
2174
+ function addAssetImport(request) {
2175
+ ((0, _marko_compiler_babel_utils.getFile)().metadata.marko.assetImports ??= /* @__PURE__ */ new Set()).add(request);
2110
2176
  }
2111
- function escapeDoubleQuotedAttrValue(value) {
2112
- return doubleQuoteAttrReplacements.test(value) ? value.replace(doubleQuoteAttrReplacements, replaceUnsafeDoubleQuoteAttrChar) : value;
2177
+ function isClientAssetImport(file, request) {
2178
+ const { hydrateIncludeImports } = file.markoOpts;
2179
+ return typeof hydrateIncludeImports === "function" ? hydrateIncludeImports(request) : !!hydrateIncludeImports?.test(request);
2113
2180
  }
2114
- function replaceUnsafeDoubleQuoteAttrChar(match) {
2115
- return match === "\"" ? "&#34;" : match === "\r" ? "&#13;" : "&amp;";
2181
+ //#endregion
2182
+ //#region src/translator/util/binding-has-prop.ts
2183
+ function isSectionRendererElided(section) {
2184
+ return !!section.downstream?.binding && !some(section.downstream.binding, (binding) => bindingHasProperty(binding, section.downstream.properties));
2185
+ }
2186
+ function bindingHasProperty(binding, properties) {
2187
+ if (binding.pruned) return false;
2188
+ else if (binding.pruned === void 0) throw new Error("Binding must be pruned before checking properties");
2189
+ if (binding.reads.size || !properties) return true;
2190
+ const property = first(properties);
2191
+ const propBinding = binding.propertyAliases.get(property);
2192
+ if (propBinding && bindingHasProperty(propBinding, rest(properties))) return true;
2193
+ for (const alias of binding.aliases) if (bindingHasProperty(alias, properties)) return true;
2194
+ return false;
2116
2195
  }
2117
2196
  //#endregion
2118
- //#region src/translator/util/runtime.ts
2119
- const pureDOMFunctions = /* @__PURE__ */ new Set([
2120
- "_await_promise",
2121
- "_await_content",
2122
- "_child_setup",
2123
- "_if",
2124
- "_if_closure",
2125
- "_show",
2126
- "_try",
2127
- "_dynamic_tag",
2128
- "_dynamic_tag_content",
2129
- "_content_closures",
2130
- "_content",
2131
- "_template",
2132
- "_closure",
2133
- "_closure_get",
2134
- "_or",
2135
- "_for_closure",
2136
- "_for_selector",
2137
- "_for_in",
2138
- "_for_of",
2139
- "_for_to",
2140
- "_for_until",
2141
- "_hoist",
2142
- "_let",
2143
- "_let_change",
2144
- "_const",
2145
- "_load_signal",
2146
- "_load_setup",
2147
- "_load_template",
2148
- "_load_visible_trigger",
2149
- "_load_event_trigger",
2150
- "_load_idle_trigger",
2151
- "_load_media_trigger",
2152
- "_load_race_trigger"
2153
- ]);
2154
- const [getRuntimeImports] = createProgramState(() => /* @__PURE__ */ new Map());
2155
- function importRuntime(name) {
2156
- if (!isTranslate()) throw new Error(`\`importRuntime(${JSON.stringify(name)})\` may only be called during the translate stage.`);
2157
- const { output } = getMarkoOpts();
2158
- const imports = getRuntimeImports();
2159
- let localName = imports.get(name);
2160
- if (!localName) {
2161
- localName = (0, _marko_compiler_babel_utils.importNamed)((0, _marko_compiler_babel_utils.getFile)(), getRuntimePath(output), name).name;
2162
- imports.set(name, localName);
2197
+ //#region src/translator/util/binding-prop-tree.ts
2198
+ const kDirectContent = Symbol("direct content");
2199
+ function getBindingPropTree(binding) {
2200
+ if (pruneBinding(binding)) return;
2201
+ binding.exposed = true;
2202
+ const props = {
2203
+ binding,
2204
+ props: void 0,
2205
+ rest: void 0
2206
+ };
2207
+ if (!binding.reads.size) {
2208
+ if (!binding.aliases.size) {
2209
+ props.props = Object.create(null);
2210
+ for (const [property, alias] of binding.propertyAliases) props.props[property] = getBindingPropTree(alias);
2211
+ } else if (binding.aliases.size === 1) {
2212
+ const [restAlias] = binding.aliases;
2213
+ if (hasSupersetExcludeProperties(binding, restAlias.excludeProperties)) {
2214
+ props.rest = getBindingPropTree(restAlias);
2215
+ props.props = Object.create(null);
2216
+ if (restAlias.type === 2) restAlias.export ??= generateUid(restAlias.name);
2217
+ forEach(restAlias.excludeProperties, (property) => {
2218
+ const propAlias = binding.propertyAliases.get(property);
2219
+ if (propAlias) props.props[property] = getBindingPropTree(propAlias);
2220
+ });
2221
+ }
2222
+ }
2163
2223
  }
2164
- return _marko_compiler.types.identifier(localName);
2224
+ if (binding.type === 2) binding.export ??= generateUid(binding.name);
2225
+ if (isDirectContentBinding(binding)) binding.directContentExport ??= generateUid(`${binding.name}_direct`);
2226
+ return props;
2227
+ }
2228
+ function isDirectContentBinding(binding) {
2229
+ if (binding.reads.size !== 1) return false;
2230
+ const [read] = binding.reads;
2231
+ return read[kDirectContent] && read.section === binding.section;
2232
+ }
2233
+ function hasSupersetExcludeProperties(binding, excludeProperties) {
2234
+ if (excludeProperties === void 0) return false;
2235
+ for (const prop of binding.propertyAliases.keys()) if (!propsUtil.has(excludeProperties, prop)) return false;
2236
+ return true;
2237
+ }
2238
+ function getKnownFromPropTree(propTree, name) {
2239
+ return propTree === true ? true : propTree.props ? propTree.props[name] || (propTree.rest ? getKnownFromPropTree(propTree.rest, name) : void 0) : propsUtil.has(propTree.binding.excludeProperties, name) ? void 0 : true;
2165
2240
  }
2166
- function callRuntime(name, ...args) {
2167
- const callExpression = _marko_compiler.types.callExpression(importRuntime(name), filterArguments(args));
2168
- if (isOutputDOM() && pureDOMFunctions.has(name)) return _marko_compiler.types.addComment(callExpression, "leading", "@__PURE__");
2169
- return callExpression;
2241
+ function getAllKnownPropNames(propTree) {
2242
+ const keys = propTree.props ? Object.keys(propTree.props) : [];
2243
+ if (propTree.rest?.props) for (const key of Object.keys(propTree.rest.props)) keys.push(key);
2244
+ return keys;
2170
2245
  }
2171
- const importedFeatures = /* @__PURE__ */ new WeakMap();
2172
- function importRuntimeFeature(feature) {
2173
- if (!isTranslate()) throw new Error(`\`importRuntimeFeature(${JSON.stringify(feature)})\` may only be called during the translate stage.`);
2174
- const program = (0, _marko_compiler_babel_utils.getProgram)().node;
2175
- let features = importedFeatures.get(program);
2176
- if (!features) importedFeatures.set(program, features = /* @__PURE__ */ new Set());
2177
- if (!features.has(feature)) {
2178
- features.add(feature);
2179
- program.body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(`${getRuntimePath("dom")}/${feature}.feat`)));
2180
- }
2246
+ function hasAllKnownProps(propTree) {
2247
+ return propTree.props && (!propTree.rest || !!propTree.rest.props);
2181
2248
  }
2182
- function getHTMLRuntime() {
2183
- return {
2184
- _escape,
2185
- _escape_comment,
2186
- _unescaped,
2187
- _attr,
2188
- _attr_class,
2189
- _attr_style,
2190
- _escape_script,
2191
- _escape_style
2192
- };
2249
+ //#endregion
2250
+ //#region src/translator/util/resolve-relative-to-entry.ts
2251
+ function resolveRelativeToEntry(entryFile, file, req) {
2252
+ return file === entryFile ? (0, _marko_compiler_babel_utils.resolveRelativePath)(file, req) : (0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, req[0] === "." ? path.default.join(file.opts.filename, "..", req) : req);
2193
2253
  }
2194
- function getRuntimePath(output) {
2195
- const { optimize } = getMarkoOpts();
2196
- return `${runtime_info_default.name}/${optimize ? "" : "debug/"}${output === "html" ? "html" : "dom"}`;
2254
+ //#endregion
2255
+ //#region src/translator/util/entry-builder.ts
2256
+ const kState = Symbol();
2257
+ const builder = {
2258
+ build(entryFile, exportInit) {
2259
+ const state = entryFile[kState];
2260
+ if (!state) throw entryFile.path.buildCodeFrameError("Unable to build hydrate code, no files were visited before finalizing the build");
2261
+ const body = [];
2262
+ for (const asset of state.assets) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(asset)));
2263
+ if (state.init || state.load) {
2264
+ const isPage = entryFile.path.node.extra.page;
2265
+ const initHelper = isPage ? "init" : "initEmbedded";
2266
+ if (state.init) body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importSpecifier(_marko_compiler.types.identifier(initHelper), _marko_compiler.types.identifier(initHelper))], _marko_compiler.types.stringLiteral(`${runtime_info_default.name}/${entryFile.markoOpts.optimize ? "" : "debug/"}dom`)));
2267
+ for (const root of state.roots) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(root)));
2268
+ if (!state.init) {
2269
+ if (exportInit) body.push(_marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([]))));
2270
+ return body;
2271
+ }
2272
+ const { runtimeId } = entryFile.markoOpts;
2273
+ const readyId = !isPage && (0, _marko_compiler_babel_utils.getTemplateId)(entryFile.markoOpts, entryFile.opts.filename);
2274
+ const initExpression = _marko_compiler.types.callExpression(_marko_compiler.types.identifier(initHelper), readyId ? runtimeId ? [_marko_compiler.types.stringLiteral(readyId), _marko_compiler.types.stringLiteral(runtimeId)] : [_marko_compiler.types.stringLiteral(readyId)] : runtimeId ? [_marko_compiler.types.stringLiteral(runtimeId)] : []);
2275
+ body.push(exportInit ? _marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], initExpression)) : _marko_compiler.types.expressionStatement(initExpression));
2276
+ } else {
2277
+ for (const asset of state.bundledAssets) body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(asset)));
2278
+ if (exportInit) body.push(_marko_compiler.types.exportDefaultDeclaration(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([]))));
2279
+ }
2280
+ return body;
2281
+ },
2282
+ visit(file, entryFile, visitChild = (id, bundled = false) => {
2283
+ const state = entryFile[kState];
2284
+ const resolved = resolveRelativeToEntry(entryFile, file, id);
2285
+ const seenBundled = state.visited.get(resolved);
2286
+ if (seenBundled === false || seenBundled && bundled) return;
2287
+ state.visited.set(resolved, bundled);
2288
+ const childFile = (0, _marko_compiler_babel_utils.loadFileForImport)(entryFile, resolved);
2289
+ if (childFile) builder.visit(childFile, entryFile);
2290
+ }) {
2291
+ const state = entryFile[kState] ||= {
2292
+ init: false,
2293
+ load: false,
2294
+ bundled: 0,
2295
+ roots: [],
2296
+ assets: /* @__PURE__ */ new Set(),
2297
+ bundledAssets: /* @__PURE__ */ new Set(),
2298
+ visited: /* @__PURE__ */ new Map([[(0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, entryFile.opts.filename), false]])
2299
+ };
2300
+ const programExtra = file.path.node.extra;
2301
+ const { analyzedTags, assetImports } = file.metadata.marko;
2302
+ const { loadImports } = programExtra;
2303
+ const init = !!(programExtra.isInteractive || programExtra.needsCompat);
2304
+ const load = !!programExtra.hasClientStatement;
2305
+ const isRoot = !state.bundled && (init || load || !!programExtra.hasResumes);
2306
+ if (init) state.init = true;
2307
+ if (load) state.load = true;
2308
+ if (isRoot) state.roots.push((0, _marko_compiler_babel_utils.resolveRelativePath)(entryFile, file.opts.filename));
2309
+ if (assetImports) {
2310
+ const assets = isRoot || state.bundled ? state.bundledAssets : state.assets;
2311
+ for (const request of assetImports) assets.add(resolveRelativeToEntry(entryFile, file, request));
2312
+ }
2313
+ if (isRoot) state.bundled++;
2314
+ for (const tag of analyzedTags ? [...analyzedTags] : []) {
2315
+ const lazy = loadImports?.has(tag);
2316
+ if (lazy) state.bundled++;
2317
+ visitChild(tag, !!state.bundled);
2318
+ if (lazy) state.bundled--;
2319
+ }
2320
+ if (isRoot) state.bundled--;
2321
+ }
2322
+ };
2323
+ //#endregion
2324
+ //#region src/translator/util/get-style-file.ts
2325
+ function getStyleFile(file) {
2326
+ const { filename } = file.opts;
2327
+ const fs = file.markoOpts.fileSystem;
2328
+ const base = getBase(filename);
2329
+ const styleMatch = new RegExp(`^(${escapeRegExp(base)}\\.${"index" === base ? "|" : ""})style\\.\\w+$`);
2330
+ let dirFiles;
2331
+ try {
2332
+ dirFiles = fs.readdirSync(path.default.dirname(filename)).sort();
2333
+ } catch {
2334
+ return;
2335
+ }
2336
+ for (const file of dirFiles) if (styleMatch.test(file)) return `./${file}`;
2197
2337
  }
2198
- function filterArguments(args) {
2199
- const filteredArgs = [];
2200
- for (let i = args.length; i--;) {
2201
- const arg = args[i];
2202
- if (arg || filteredArgs.length) filteredArgs[i] = arg || _marko_compiler.types.unaryExpression("void", _marko_compiler.types.numericLiteral(0));
2338
+ /**
2339
+ * Given a filename, gets the base name, strips off the file extension
2340
+ * and removes any arc flags (https://github.com/eBay/arc).
2341
+ *
2342
+ * @example
2343
+ * getBase("/dir/foo.marko") // => "foo"
2344
+ * getBase("/dir/foo.bar.marko") // => "foo.bar"
2345
+ * getBase("/dir/foo[bar].marko") // => "foo"
2346
+ * getBase("/dir/foo[bar].baz.marko") // => "foo.baz"
2347
+ */
2348
+ function getBase(filename) {
2349
+ const start = filename.lastIndexOf(path.default.sep) + 1;
2350
+ const leftDot = filename.indexOf(".", start);
2351
+ if (leftDot === -1) return filename.slice(start);
2352
+ const rightDot = filename.lastIndexOf(".");
2353
+ const closeBracket = leftDot - 1;
2354
+ if (filename[closeBracket] === "]") {
2355
+ const openBracket = filename.lastIndexOf("[", closeBracket);
2356
+ if (openBracket > start) return filename.slice(start, openBracket) + filename.slice(leftDot, rightDot);
2203
2357
  }
2204
- return filteredArgs;
2358
+ return filename.slice(start, rightDot);
2205
2359
  }
2206
- function getCompatRuntimeFile() {
2207
- const markoOpts = getMarkoOpts();
2208
- return `marko/${markoOpts.optimize ? "dist" : "src"}/runtime/helpers/tags-compat/${isOutputHTML() ? "html" : "dom"}${markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`;
2360
+ const regexpCharsReg = /[\\^$.*+?()[\]{}|]/g;
2361
+ function escapeRegExp(str) {
2362
+ return str.replace(regexpCharsReg, "\\$&");
2209
2363
  }
2210
2364
  //#endregion
2211
2365
  //#region src/translator/util/setup-statements.ts
@@ -2275,13 +2429,13 @@ function addExportRegistrations(node, seen, statements) {
2275
2429
  }
2276
2430
  }
2277
2431
  function buildRegistration(local, registerId) {
2278
- return _marko_compiler.types.expressionStatement(isOutputHTML() ? callRuntime("_resume", _marko_compiler.types.identifier(local), _marko_compiler.types.stringLiteral(registerId)) : callRuntime("_resume", _marko_compiler.types.stringLiteral(registerId), _marko_compiler.types.identifier(local)));
2432
+ return _marko_compiler.types.expressionStatement(isOutputHTML() ? callRuntime("_resume", _marko_compiler.types.identifier(local), _marko_compiler.types.stringLiteral(registerId)) : registerRuntimeValue(registerId, _marko_compiler.types.identifier(local)));
2279
2433
  }
2280
2434
  function resolveRegisterModule(file, { filename, exportName, registerId }) {
2281
2435
  const importer = file.opts.filename;
2282
2436
  return getMarkoOpts().resolveVirtualDependency(importer, {
2283
2437
  virtualPath: `${relativePath(importer, filename)}.register-${exportName}.js`,
2284
- code: `import { ${exportName} } from "./${path.default.basename(filename)}";\nimport { _resume } from "${getRuntimePath("dom")}";\n_resume(${JSON.stringify(registerId)}, ${exportName});\n`
2438
+ code: `import { ${exportName} } from "./${path.default.basename(filename)}";\nimport { _resumed } from "${getRuntimePath("dom")}";\n_resumed${isValidPropertyIdentifier(registerId) ? `.${registerId}` : `[${JSON.stringify(registerId)}]`} = ${exportName};\n`
2285
2439
  });
2286
2440
  }
2287
2441
  function relativePath(from, to) {
@@ -2361,148 +2515,50 @@ function translateByTarget({ html, dom }) {
2361
2515
  //#endregion
2362
2516
  //#region src/translator/util/normalize-string-expression.ts
2363
2517
  function normalizeStringExpression(parts, useIife) {
2364
- const strs = [];
2365
- const exprs = [];
2366
- let curStr = "";
2367
- for (let i = 0; i < parts.length; i++) {
2368
- let content = parts[i];
2369
- if (typeof content === "object") if (_marko_compiler.types.isStringLiteral(content)) content = content.value;
2370
- else if (_marko_compiler.types.isTemplateLiteral(content)) {
2371
- let nextIndex = i + 1;
2372
- const exprLen = content.expressions.length;
2373
- shiftItems(parts, nextIndex, content.quasis.length + exprLen);
2374
- for (let j = 0; j < exprLen; j++) {
2375
- parts[nextIndex++] = content.quasis[j].value.cooked ?? "";
2376
- parts[nextIndex++] = content.expressions[j];
2377
- }
2378
- parts[nextIndex] = content.quasis[exprLen].value.cooked ?? "";
2379
- continue;
2380
- } else {
2381
- exprs.push(content);
2382
- strs.push(curStr);
2383
- curStr = "";
2384
- continue;
2385
- }
2386
- curStr += content;
2387
- }
2388
- if (exprs.length) {
2389
- if (exprs.length === 1 && !curStr && !strs[0]) return exprs[0];
2390
- strs.push(curStr);
2391
- if (useIife) {
2392
- const params = exprs.map((_, i) => _marko_compiler.types.identifier(`_w${i}`));
2393
- const iife = _marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression(params, _marko_compiler.types.templateLiteral(strs.map((raw) => _marko_compiler.types.templateElement({ raw: escapeTemplateRaw(raw) })), params)), exprs);
2394
- _marko_compiler.types.addComment(iife, "leading", "@__PURE__");
2395
- return iife;
2396
- }
2397
- return _marko_compiler.types.templateLiteral(strs.map((raw) => _marko_compiler.types.templateElement({ raw: escapeTemplateRaw(raw) })), exprs);
2398
- } else if (curStr) return _marko_compiler.types.stringLiteral(curStr);
2399
- }
2400
- function appendLiteral(arr, str) {
2401
- arr[arr.length - 1] += str;
2402
- }
2403
- function escapeTemplateRaw(raw) {
2404
- return raw.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$(?=\{)/g, "\\$");
2405
- }
2406
- function shiftItems(list, start, offset) {
2407
- for (let i = list.length - 1; i >= start; i--) list[i + offset] = list[i];
2408
- }
2409
- //#endregion
2410
- //#region src/translator/util/with-comment.ts
2411
- function withLeadingComment(node, value) {
2412
- if (value) {
2413
- const comment = {
2414
- type: "CommentBlock",
2415
- value: ` ${value} `
2416
- };
2417
- node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
2418
- }
2419
- return node;
2420
- }
2421
- //#endregion
2422
- //#region src/translator/util/serialize-guard.ts
2423
- const [getSectionReasonState] = createSectionState("serializeReasonState", (section) => ({
2424
- if: createTypeState(),
2425
- guard: createTypeState(),
2426
- declarators: [_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(getSharedUid(`scope${section.id}_reason`, section)), callRuntime("_scope_reason"))]
2427
- }));
2428
- function getScopeReasonDeclaration(section) {
2429
- return _marko_compiler.types.variableDeclaration("const", getSectionReasonState(section).declarators);
2430
- }
2431
- function getSerializeGuard(section, reason, optional) {
2432
- if (!isReasonDynamic(reason) || isCrossSection(section, reason)) {
2433
- if (!reason) return _marko_compiler.types.numericLiteral(0);
2434
- return optional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason === true ? void 0 : reason.state));
2435
- }
2436
- return getOrHoist(reason, true);
2437
- }
2438
- function getSerializeGuardForAny(section, reasons, optional) {
2439
- if (!Array.isArray(reasons)) return getSerializeGuard(section, reasons, optional);
2440
- let expr;
2441
- for (const reason of reasons) {
2442
- if (!isReasonDynamic(reason)) return optional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.state));
2443
- const guard = getSerializeGuard(section, reason, false);
2444
- expr = expr ? _marko_compiler.types.logicalExpression("||", expr, guard) : guard;
2445
- }
2446
- return expr;
2447
- }
2448
- function getExprIfSerialized(section, reason, expr) {
2449
- if (!isReasonDynamic(reason) || isCrossSection(section, reason)) return reason && expr;
2450
- const guard = getOrHoist(reason, false);
2451
- return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
2452
- }
2453
- function getOrHoist(reason, isGuard) {
2454
- const onlySection = getOnlySection(reason.param);
2455
- if (onlySection) {
2456
- const state = getSectionReasonState(onlySection);
2457
- const tracking = isGuard ? state.guard : state.if;
2458
- const existingFound = sourcesUtil.find(tracking.hoistedReasons, reason);
2459
- if (existingFound) return _marko_compiler.types.identifier(tracking.names.get(existingFound));
2460
- const guard = buildGuardExpr(onlySection, reason.param, isGuard);
2461
- const seenFound = sourcesUtil.find(tracking.seenReasons, reason);
2462
- if (!seenFound) {
2463
- const expr = _marko_compiler.types.parenthesizedExpression(guard);
2464
- tracking.pending.set(reason, expr);
2465
- tracking.seenReasons = sourcesUtil.add(tracking.seenReasons, reason);
2466
- return expr;
2467
- }
2468
- const name = generateUid(`${isGuard ? "sg" : "si"}__${getDebugNamesAsIdentifier(reason.param)}`);
2469
- tracking.hoistedReasons = sourcesUtil.add(tracking.hoistedReasons, reason);
2470
- tracking.names.set(reason, name);
2471
- state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(name), guard));
2472
- const pendingParen = tracking.pending.get(seenFound);
2473
- if (pendingParen) {
2474
- pendingParen.expression = _marko_compiler.types.identifier(name);
2475
- tracking.pending.delete(seenFound);
2518
+ const strs = [];
2519
+ const exprs = [];
2520
+ let curStr = "";
2521
+ for (let i = 0; i < parts.length; i++) {
2522
+ let content = parts[i];
2523
+ if (typeof content === "object") if (_marko_compiler.types.isStringLiteral(content)) content = content.value;
2524
+ else if (_marko_compiler.types.isTemplateLiteral(content)) {
2525
+ let nextIndex = i + 1;
2526
+ const exprLen = content.expressions.length;
2527
+ shiftItems(parts, nextIndex, content.quasis.length + exprLen);
2528
+ for (let j = 0; j < exprLen; j++) {
2529
+ parts[nextIndex++] = content.quasis[j].value.cooked ?? "";
2530
+ parts[nextIndex++] = content.expressions[j];
2531
+ }
2532
+ parts[nextIndex] = content.quasis[exprLen].value.cooked ?? "";
2533
+ continue;
2534
+ } else {
2535
+ exprs.push(content);
2536
+ strs.push(curStr);
2537
+ curStr = "";
2538
+ continue;
2476
2539
  }
2477
- return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(name));
2478
- }
2479
- let orExpr;
2480
- for (const [paramsSection, params] of groupParamsBySection(reason.param)) {
2481
- const expr = buildGuardExpr(paramsSection, params, isGuard);
2482
- orExpr = orExpr ? _marko_compiler.types.logicalExpression("||", orExpr, expr) : expr;
2540
+ curStr += content;
2483
2541
  }
2484
- return orExpr;
2485
- }
2486
- function buildGuardExpr(paramsSection, params, isGuard) {
2487
- const serializeIdentifier = _marko_compiler.types.identifier(getSharedUid(`scope${paramsSection.id}_reason`, paramsSection));
2488
- return paramsSection.paramReasonGroups ? callRuntime(isGuard ? "_serialize_guard" : "_serialize_if", serializeIdentifier, withLeadingComment(_marko_compiler.types.numericLiteral(getParamReasonGroupIndex(paramsSection, params)), getDebugNames(params))) : serializeIdentifier;
2542
+ if (exprs.length) {
2543
+ if (exprs.length === 1 && !curStr && !strs[0]) return exprs[0];
2544
+ strs.push(curStr);
2545
+ if (useIife) {
2546
+ const params = exprs.map((_, i) => _marko_compiler.types.identifier(`_w${i}`));
2547
+ const iife = _marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression(params, _marko_compiler.types.templateLiteral(strs.map((raw) => _marko_compiler.types.templateElement({ raw: escapeTemplateRaw(raw) })), params)), exprs);
2548
+ _marko_compiler.types.addComment(iife, "leading", "@__PURE__");
2549
+ return iife;
2550
+ }
2551
+ return _marko_compiler.types.templateLiteral(strs.map((raw) => _marko_compiler.types.templateElement({ raw: escapeTemplateRaw(raw) })), exprs);
2552
+ } else if (curStr) return _marko_compiler.types.stringLiteral(curStr);
2489
2553
  }
2490
- function getOnlySection(params) {
2491
- if (params === void 0) return void 0;
2492
- if (!Array.isArray(params)) return params.section;
2493
- const { section } = params[0];
2494
- return section === params[params.length - 1].section ? section : void 0;
2554
+ function appendLiteral(arr, str) {
2555
+ arr[arr.length - 1] += str;
2495
2556
  }
2496
- function isCrossSection(section, reason) {
2497
- return some(reason.param, (param) => !isSameOrChildSection(param.section, section));
2557
+ function escapeTemplateRaw(raw) {
2558
+ return raw.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$(?=\{)/g, "\\$");
2498
2559
  }
2499
- function createTypeState() {
2500
- return {
2501
- names: /* @__PURE__ */ new Map(),
2502
- pending: /* @__PURE__ */ new Map(),
2503
- seenReasons: void 0,
2504
- hoistedReasons: void 0
2505
- };
2560
+ function shiftItems(list, start, offset) {
2561
+ for (let i = list.length - 1; i >= start; i--) list[i + offset] = list[i];
2506
2562
  }
2507
2563
  //#endregion
2508
2564
  //#region src/translator/util/writer.ts
@@ -2586,7 +2642,7 @@ var return_default = {
2586
2642
  if (attrs.valueChange) {
2587
2643
  (attrs.valueChange.extra ??= {}).isEffect = true;
2588
2644
  addSetupExpr(section, attrs.valueChange);
2589
- addSerializeReason(section, true, getAccessorProp().TagVariableChange);
2645
+ addSerializeReason(section, FORCED, getAccessorProp().TagVariableChange);
2590
2646
  }
2591
2647
  addSetupExpr(section, attrs.value);
2592
2648
  section.returnValueExpr = attrs.value.extra ??= {};
@@ -2734,40 +2790,10 @@ function resolvesTo(read, canonical) {
2734
2790
  }
2735
2791
  function readsKey(read, keyBinding) {
2736
2792
  if (!read || read.getter) return false;
2737
- let binding = read.binding;
2738
- forEach(read.props, (prop) => {
2739
- binding = binding?.propertyAliases.get(prop);
2740
- });
2793
+ const binding = getPropertyAlias(read.binding, read.props);
2741
2794
  return !!binding && getCanonicalBinding(binding) === getCanonicalBinding(keyBinding);
2742
2795
  }
2743
2796
  //#endregion
2744
- //#region src/translator/util/to-property-name.ts
2745
- function getMemberExpressionPropString(expr) {
2746
- switch (expr.property.type) {
2747
- case "StringLiteral": return expr.property.value;
2748
- case "NumericLiteral": return "" + expr.property.value;
2749
- case "Identifier":
2750
- if (expr.computed) return;
2751
- return expr.property.name;
2752
- }
2753
- }
2754
- function isValidPropertyIdentifier(name) {
2755
- return /^[a-z_$][a-z0-9_$]*$/i.test(name);
2756
- }
2757
- function toPropertyName(name) {
2758
- if (isValidPropertyIdentifier(name)) return _marko_compiler.types.identifier(name);
2759
- else if (/^(?:0|[1-9][0-9]*)$/.test(name)) return _marko_compiler.types.numericLiteral(parseInt(name, 10));
2760
- return _marko_compiler.types.stringLiteral(name);
2761
- }
2762
- function toObjectProperty(name, value) {
2763
- return _marko_compiler.types.objectProperty(toPropertyName(name), value);
2764
- }
2765
- function toMemberExpression(object, key, optional) {
2766
- const prop = toPropertyName(key);
2767
- const computed = prop.type !== "Identifier";
2768
- return optional ? _marko_compiler.types.optionalMemberExpression(object, prop, computed, true) : _marko_compiler.types.memberExpression(object, prop, computed);
2769
- }
2770
- //#endregion
2771
2797
  //#region src/translator/util/get-declared-binding-expression.ts
2772
2798
  function getDeclaredBindingExpression(binding) {
2773
2799
  const canonicalBinding = getCanonicalBinding(binding);
@@ -2860,7 +2886,7 @@ function setSerializedValue(section, key, expression) {
2860
2886
  nonAnalyzedForceSerializedSection.add(section);
2861
2887
  getSerializedAccessors(section).set(key, {
2862
2888
  expression,
2863
- reason: true
2889
+ reason: FORCED
2864
2890
  });
2865
2891
  }
2866
2892
  const [getSectionWriteScopeBuilder, setSectionWriteScopeBuilder] = createSectionState("sectionWriteScopeBuilder");
@@ -2914,10 +2940,10 @@ function getSignal(section, referencedBindings, name) {
2914
2940
  if (isOutputHTML()) return signal;
2915
2941
  else if (!referencedBindings) signal.build = () => getSignalFn(signal);
2916
2942
  else if (Array.isArray(referencedBindings)) {
2917
- const collapseSource = collapsedIntersectionSource.get(referencedBindings);
2918
- subscribe(collapseSource || referencedBindings, signal);
2919
- if (collapseSource) {
2920
- const sourceSignal = getSignal(section, collapseSource);
2943
+ const meta = intersectionMeta.get(referencedBindings);
2944
+ subscribe(meta.source || referencedBindings, signal);
2945
+ if (meta.source) {
2946
+ const sourceSignal = getSignal(section, meta.source);
2921
2947
  forEach(referencedBindings, (member) => {
2922
2948
  const memberSignal = getSignal(section, member);
2923
2949
  const inline = member.type === 5 && !member.upstreamAlias && member.reads.size === 1 && sourceSignal.values.find((v) => v.signal === memberSignal);
@@ -2926,7 +2952,7 @@ function getSignal(section, referencedBindings, name) {
2926
2952
  });
2927
2953
  signal.build = () => getSignalFn(signal);
2928
2954
  } else signal.build = () => {
2929
- const { id, scopeOffset } = intersectionMeta.get(referencedBindings);
2955
+ const { id, scopeOffset } = meta;
2930
2956
  return callRuntime("_or", _marko_compiler.types.numericLiteral(id), getSignalFn(signal), scopeOffset || referencedBindings.length > 2 ? _marko_compiler.types.numericLiteral(referencedBindings.length - 1) : void 0, scopeOffset && getScopeAccessorLiteral(scopeOffset, true));
2931
2957
  };
2932
2958
  } else if (referencedBindings.section !== section && sectionUtil.has(referencedBindings.closureSections, section)) signal.build = () => {
@@ -2934,11 +2960,15 @@ function getSignal(section, referencedBindings, name) {
2934
2960
  const render = getSignalFn(signal);
2935
2961
  const closureSignalBuilder = getClosureSignalBuilder(section);
2936
2962
  if (closureSignalBuilder && !isDynamicClosure(section, closure)) return closureSignalBuilder(closure, render);
2937
- return callRuntime("_closure_get", isOptimize() ? _marko_compiler.types.numericLiteral(getClosureAccessorId(closure)) : getScopeAccessorLiteral(closure, true), render, isImmediateOwner(section, closure) ? void 0 : _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], getScopeExpression(section, closure.section)), underTryPlaceholder(section) ? _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")) : void 0);
2963
+ return callRuntime("_closure_get", isOptimize() ? _marko_compiler.types.numericLiteral(getClosureAccessorId(closure)) : getScopeAccessorLiteral(closure, true), render, isImmediateOwner(section, closure) ? void 0 : _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], getScopeExpression(section, closure.section)), underTryPlaceholder(section) && closureResumes(closure) ? _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")) : void 0);
2938
2964
  };
2939
2965
  }
2940
2966
  return signal;
2941
2967
  }
2968
+ function closureResumes(closure) {
2969
+ const state = closure.sources?.state;
2970
+ return !state || some(state, hasResumableWriter);
2971
+ }
2942
2972
  function underTryPlaceholder(section) {
2943
2973
  let curSection = section.parent;
2944
2974
  while (curSection) {
@@ -2954,8 +2984,7 @@ function initValue(binding, isLet = false) {
2954
2984
  signal.build = () => {
2955
2985
  if (isPureMemberForwarder(binding)) return;
2956
2986
  const fn = getSignalFn(signal);
2957
- const isDirectAlias = binding.upstreamAlias && binding.property === void 0 && binding.excludeProperties === void 0;
2958
- if (!signal.forcePersist && (isDirectAlias || !signal.hasSideEffect || !signalHasStatements(signal))) return fn;
2987
+ if (!signal.forcePersist && (isDirectAlias(binding) || !signal.hasSideEffect || !signalHasStatements(signal))) return fn;
2959
2988
  return callRuntime(isLet ? signal.extraArgs ? "_let_change" : "_let" : "_const", getScopeAccessorLiteral(binding, true, isLet), fn);
2960
2989
  };
2961
2990
  for (const alias of binding.aliases) if (alias.type !== 6) initValue(alias);
@@ -2971,7 +3000,7 @@ function signalHasStatements(signal) {
2971
3000
  return false;
2972
3001
  }
2973
3002
  function isPureMemberForwarder(binding) {
2974
- if (binding.property === void 0 || binding.reads.size || binding.exposed || binding.aliases.size || binding.assignmentSections || isForSelectorValue(binding) || getSerializeReason(binding.section, binding) || getSignal(binding.section, binding).hasSideEffect) return false;
3003
+ if (binding.property === void 0 || binding.reads.size || binding.exposed || binding.aliases.size || binding.assignments || isForSelectorValue(binding) || getSerializeReason(binding.section, binding) || getSignal(binding.section, binding).hasSideEffect) return false;
2975
3004
  for (const alias of binding.propertyAliases.values()) if (alias.type !== 6) return true;
2976
3005
  return false;
2977
3006
  }
@@ -3111,7 +3140,7 @@ function isOwnValueRead(node, binding) {
3111
3140
  function subscribe(references, subscriber) {
3112
3141
  if (references) forEach(references, (binding) => {
3113
3142
  if (binding.type !== 6) {
3114
- const source = binding.property === void 0 && binding.excludeProperties === void 0 && binding.upstreamAlias || binding;
3143
+ const source = isDirectAlias(binding) && binding.upstreamAlias || binding;
3115
3144
  const providerSignal = getSignal(subscriber.section, source);
3116
3145
  providerSignal.hasSideEffect = true;
3117
3146
  providerSignal.intersection = push(providerSignal.intersection, subscriber);
@@ -3162,8 +3191,7 @@ function addValue(targetSection, referencedBindings, signal, value) {
3162
3191
  function buildResumeRegisterKey(section, referencedBindings, type) {
3163
3192
  let name = "";
3164
3193
  if (referencedBindings) if (typeof referencedBindings === "string") name += `*${referencedBindings}`;
3165
- else if (Array.isArray(referencedBindings)) for (const ref of referencedBindings) name += `_${ref.name}#${ref.id}`;
3166
- else name += `_${referencedBindings.name}#${referencedBindings.id}`;
3194
+ else name = reduce(referencedBindings, appendBindingKey, name);
3167
3195
  return `${section.id}${name}${type ? "/" + type : ""}`;
3168
3196
  }
3169
3197
  function getResumeRegisterId(section, referencedBindings, type) {
@@ -3247,7 +3275,7 @@ function writeRegisteredFns() {
3247
3275
  else fn = _marko_compiler.types.functionDeclaration(_marko_compiler.types.identifier(registeredFn.id), registeredFn.node.params, registeredFn.node.body.type === "BlockStatement" ? registeredFn.node.body : _marko_compiler.types.blockStatement([_marko_compiler.types.returnStatement(registeredFn.node.body)]), registeredFn.node.generator, registeredFn.node.async);
3248
3276
  statements.push(fn);
3249
3277
  }
3250
- for (const registeredFn of registeredFns) statements.push(_marko_compiler.types.expressionStatement(callRuntime("_resume", _marko_compiler.types.stringLiteral(registeredFn.registerId), _marko_compiler.types.identifier(registeredFn.id))));
3278
+ for (const registeredFn of registeredFns) statements.push(_marko_compiler.types.expressionStatement(registerRuntimeValue(registeredFn.registerId, _marko_compiler.types.identifier(registeredFn.id))));
3251
3279
  (0, _marko_compiler_babel_utils.getProgram)().node.body.push(...statements);
3252
3280
  }
3253
3281
  }
@@ -3270,7 +3298,7 @@ function writeHTMLResumeStatements(path) {
3270
3298
  const allSignals = Array.from(getSignals(section).values());
3271
3299
  const scopeIdIdentifier = getScopeIdIdentifier(section);
3272
3300
  const markerSerializeArg = getSerializeGuardForAny(section, section.domSerializeReasons, true);
3273
- const sectionSerializeReason = nonAnalyzedForceSerializedSection.has(section) ? true : section.serializeReason;
3301
+ const sectionSerializeReason = nonAnalyzedForceSerializedSection.has(section) ? FORCED : section.serializeReason;
3274
3302
  forEach(section.referencedClosures, (closure) => {
3275
3303
  if (closure.sources) {
3276
3304
  if (isDynamicClosure(section, closure)) {
@@ -3284,7 +3312,7 @@ function writeHTMLResumeStatements(path) {
3284
3312
  const closureIndex = getDynamicClosureIndex(closure, section);
3285
3313
  if (closureIndex) setBindingSerializedValue(section, closure, _marko_compiler.types.numericLiteral(closureIndex), getAccessorPrefix().ClosureSignalIndex);
3286
3314
  const closureScopesReason = getSerializeReason(closure.section, closure, getAccessorPrefix().ClosureScopes);
3287
- if (underTryPlaceholder(section)) {
3315
+ if (underTryPlaceholder(section) && closureResumes(closure)) {
3288
3316
  const reason = getSerializeReason(section);
3289
3317
  if (reason) {
3290
3318
  const script = getExprIfSerialized(section, reason, callRuntime("_script", getScopeIdIdentifier(section), _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")), markerSerializeArg));
@@ -3357,7 +3385,7 @@ function writeHTMLResumeStatements(path) {
3357
3385
  }
3358
3386
  body.push(_marko_compiler.types.expressionStatement(getExprIfSerialized(section, sectionSerializeReason, writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs))));
3359
3387
  }
3360
- if (!section.isBranch && (section.hasAbortSignal || !!section.referencedClosures || sectionSerializeReason && !!find(section.bindings, (binding) => binding.type === 1)) && markerSerializeArg) {
3388
+ if (!section.isBranch && (section.hasAbortSignal || !!section.referencedClosures || sectionSerializeReason && some(section.bindings, isLetBinding)) && markerSerializeArg) {
3361
3389
  const call = callRuntime("_resume_branch", scopeIdIdentifier);
3362
3390
  const link = section.hasAbortSignal ? call : getExprIfSerialized(section, sectionSerializeReason, call);
3363
3391
  if (link) body.push(_marko_compiler.types.expressionStatement(markerSerializeArg.type === "NumericLiteral" ? link : _marko_compiler.types.logicalExpression("||", markerSerializeArg, link)));
@@ -3384,7 +3412,8 @@ function replaceBindingReadNode$1(node, signal) {
3384
3412
  case "Identifier":
3385
3413
  case "MemberExpression":
3386
3414
  case "OptionalMemberExpression": return getReadReplacement(node, signal);
3387
- case "CallExpression": {
3415
+ case "CallExpression":
3416
+ case "OptionalCallExpression": {
3388
3417
  const { extra } = node.callee;
3389
3418
  if (extra?.read) {
3390
3419
  const { binding, getter } = extra.read;
@@ -3542,6 +3571,12 @@ function getRegisteredFnExpression$1(node) {
3542
3571
  else return _marko_compiler.types.identifier(id);
3543
3572
  }
3544
3573
  }
3574
+ function appendBindingKey(name, binding) {
3575
+ return `${name}_${binding.name}#${binding.id}`;
3576
+ }
3577
+ function isLetBinding(binding) {
3578
+ return binding.type === 1;
3579
+ }
3545
3580
  //#endregion
3546
3581
  //#region src/translator/util/import-reference.ts
3547
3582
  function importOrSelfReferenceName(file, request, name, nameHint) {
@@ -3822,13 +3857,15 @@ var dom_default = { translate: {
3822
3857
  tagParamsIdentifier
3823
3858
  ]);
3824
3859
  else {
3825
- let renderer = callRuntime(getSectionRegisterReasons(childSection) ? "_content_resume" : "_content", _marko_compiler.types.stringLiteral(getResumeRegisterId(childSection, "content")), ...replaceNullishAndEmptyFunctionsWith0([
3860
+ const registerReason = getSectionRegisterReasons(childSection);
3861
+ let renderer = callRuntime(registerReason ? "_content_resume" : "_content", _marko_compiler.types.stringLiteral(getResumeRegisterId(childSection, "content")), ...replaceNullishAndEmptyFunctionsWith0([
3826
3862
  writes,
3827
3863
  walks,
3828
3864
  setupIdentifier,
3829
3865
  tagParamsIdentifier,
3830
3866
  childSection.hoisted || childSection.isHoistThrough ? getSectionInstancesAccessorLiteral(childSection) : void 0
3831
3867
  ]));
3868
+ if (registerReason && isSectionRegisterDynamic(childSection, registerReason)) renderer = _marko_compiler.types.addComment(renderer, "leading", "@__PURE__");
3832
3869
  if (childSection.referencedLocalClosures) {
3833
3870
  const objProps = [];
3834
3871
  forEach(childSection.referencedLocalClosures, (closure) => {
@@ -3941,7 +3978,8 @@ function replaceBindingReadNode(node) {
3941
3978
  if (extra && !(extra.read && !extra.read.binding.declared || extra.binding && !extra.binding.declared)) return getReadReplacement(node);
3942
3979
  break;
3943
3980
  }
3944
- case "CallExpression": {
3981
+ case "CallExpression":
3982
+ case "OptionalCallExpression": {
3945
3983
  const read = node.callee.extra?.read;
3946
3984
  if (read && (read.getter !== void 0 || read.binding.type === 0)) return _marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression([_marko_compiler.types.cloneNode(node.callee)], node), [importRuntime(read.binding.type === 0 ? "_el_read_error" : "_hoist_read_error")]);
3947
3985
  break;
@@ -4125,6 +4163,8 @@ var for_default = {
4125
4163
  const keyAttr = tag.node.attributes.find((attr) => attr.type === "MarkoAttribute" && attr.name === "key");
4126
4164
  if (keyAttr) throw tag.hub.buildError(keyAttr, `The [\`<for>\` tag](https://markojs.com/docs/reference/core-tag#for) keys items with the \`by=\` attribute, not \`key=\`. ${forType === "of" ? "Use `by=\"propName\"` or `by=(item, index) => key`" : forType === "in" ? "Use `by=(key, value) => key`" : "Use `by=(num) => key`"}.`);
4127
4165
  (0, _marko_compiler_babel_utils.assertAllowedAttributes)(tag, allowAttrs);
4166
+ const extraParam = tag.node.body.params[forType === "of" || forType === "in" ? 2 : 1];
4167
+ if (extraParam && extraParam.type !== "RestElement") throw tag.hub.buildError(extraParam, `The [\`<for>\` tag](https://markojs.com/docs/reference/core-tag#for) only provides \`|${forType === "of" ? "item, index" : forType === "in" ? "key, value" : "num"}|\` with \`${forType}=\`, so this parameter is never supplied.`);
4128
4168
  if (isAttrTag) return;
4129
4169
  const byAttr = getKnownAttrValues(tag.node).by;
4130
4170
  if (forType !== "of" && byAttr?.type === "StringLiteral") throw tag.hub.buildError(byAttr, `The [\`<for>\` tag](https://markojs.com/docs/reference/core-tag#for) only supports a string \`by\` key with \`of\`; use a \`by=(${forType === "in" ? "key, value" : "index"}) => ...\` function for \`<for ${forType}>\`.`);
@@ -4535,8 +4575,9 @@ function translateAttrs(tag, propTree = true, skip, statements = [], contentKey
4535
4575
  for (let i = attributes.length; i--;) {
4536
4576
  const attr = attributes[i];
4537
4577
  const { value } = attr;
4538
- if (_marko_compiler.types.isMarkoSpreadAttribute(attr)) attrProperties.push(_marko_compiler.types.spreadElement(value));
4539
- else if (!seen.has(attr.name) && getKnownFromPropTree(propTree, attr.name)) {
4578
+ if (_marko_compiler.types.isMarkoSpreadAttribute(attr)) {
4579
+ if (!value.extra?.pruned) attrProperties.push(_marko_compiler.types.spreadElement(value));
4580
+ } else if (!seen.has(attr.name) && getKnownFromPropTree(propTree, attr.name)) {
4540
4581
  seen.add(attr.name);
4541
4582
  attrProperties.push(toObjectProperty(attr.name, value));
4542
4583
  }
@@ -4761,9 +4802,7 @@ var native_tag_default = {
4761
4802
  const spreadBinding = node.extra?.spreadFrom;
4762
4803
  if (spreadBinding) {
4763
4804
  spreadBinding.noSerialize = true;
4764
- if (carveProperties) {
4765
- for (const property of carveProperties) if (!includes(spreadBinding.noSerializeProperties, property)) spreadBinding.noSerializeProperties = push(spreadBinding.noSerializeProperties, property);
4766
- }
4805
+ if (carveProperties) for (const property of carveProperties) spreadBinding.noSerializeProperties = propsUtil.add(spreadBinding.noSerializeProperties, property);
4767
4806
  }
4768
4807
  }
4769
4808
  }
@@ -4778,7 +4817,7 @@ var native_tag_default = {
4778
4817
  const attr = seen[name];
4779
4818
  if (isEventHandler(name) || name === "content" || !evaluate(attr.value).confident) addSetupExpr(tagSection, attr.value);
4780
4819
  }
4781
- addSerializeExpr(tagSection, !!(node.var || hasEventHandlers), nodeBinding);
4820
+ if (node.var || hasEventHandlers) addSerializeReason(tagSection, FORCED, nodeBinding);
4782
4821
  trackDomVarReferences(tag, nodeBinding);
4783
4822
  addSerializeExpr(tagSection, push(exprExtras, tagExtra), nodeBinding);
4784
4823
  }
@@ -5580,7 +5619,7 @@ const IfTag = {
5580
5619
  if (branchBodySection) {
5581
5620
  const branchSerializeReason = getSerializeReason(branchBodySection, kBranchSerializeReason);
5582
5621
  if (branchSerializeReason) {
5583
- if (branchSerializeReasons !== true) branchSerializeReasons = branchSerializeReason === true || branchSerializeReason.state ? true : sourcesUtil.add(branchSerializeReasons, branchSerializeReason);
5622
+ branchSerializeReasons = sourcesUtil.add(branchSerializeReasons, branchSerializeReason);
5584
5623
  bodyStatements.push(_marko_compiler.types.returnStatement(_marko_compiler.types.numericLiteral(i)));
5585
5624
  }
5586
5625
  }
@@ -6071,7 +6110,7 @@ var program_default = {
6071
6110
  if (paramsBinding && !paramsBinding.pruned) programExtra.domExports.params = getBindingPropTree(paramsBinding);
6072
6111
  const section = programExtra.section;
6073
6112
  forEachSection((childSection) => {
6074
- programExtra.hasResumes ||= !!(childSection.serializeReason || childSection.serializeReasons.size || childSection !== section && !isSectionRendererElided(childSection) && getSectionRegisterReasons(childSection));
6113
+ programExtra.hasResumes ||= !!(childSection.serializeReason || childSection.serializeReasons.size || childSection !== section && !isSectionRendererElided(childSection) && isSectionRegisterEager(childSection));
6075
6114
  });
6076
6115
  if (!section.hoistedTo && !sectionHasSetupStatements(section)) programExtra.domExports.setupEmpty = true;
6077
6116
  }
@@ -6145,6 +6184,48 @@ var program_default = {
6145
6184
  }
6146
6185
  };
6147
6186
  //#endregion
6187
+ //#region src/translator/util/cyclic-memo.ts
6188
+ function createCyclicMemo(compute, cycleAnswer) {
6189
+ const cache = /* @__PURE__ */ new WeakMap();
6190
+ const computing = /* @__PURE__ */ new Map();
6191
+ let provisionalAt = Infinity;
6192
+ return (key) => {
6193
+ if (cache.has(key)) return cache.get(key);
6194
+ const at = computing.get(key);
6195
+ if (at !== void 0) {
6196
+ if (at < provisionalAt) provisionalAt = at;
6197
+ return cycleAnswer;
6198
+ }
6199
+ const frame = computing.size;
6200
+ computing.set(key, frame);
6201
+ const outerProvisionalAt = provisionalAt;
6202
+ provisionalAt = Infinity;
6203
+ try {
6204
+ const result = compute(key);
6205
+ if (provisionalAt >= frame) cache.set(key, result);
6206
+ return result;
6207
+ } finally {
6208
+ computing.delete(key);
6209
+ if (provisionalAt >= frame || outerProvisionalAt < provisionalAt) provisionalAt = outerProvisionalAt;
6210
+ }
6211
+ };
6212
+ }
6213
+ function createCyclicPathMemo(compute, cycleAnswer) {
6214
+ const keys = /* @__PURE__ */ new WeakMap();
6215
+ const memo = createCyclicMemo(([key, path]) => compute(key, path), cycleAnswer);
6216
+ return (key, path) => {
6217
+ let node = keys.get(key);
6218
+ if (!node) keys.set(key, node = {});
6219
+ if (path === true) return memo(node.all ??= [key, path]);
6220
+ forEach(path, (property) => {
6221
+ let next = node.props?.get(property);
6222
+ if (!next) (node.props ??= /* @__PURE__ */ new Map()).set(property, next = {});
6223
+ node = next;
6224
+ });
6225
+ return memo(node.value ??= [key, path]);
6226
+ };
6227
+ }
6228
+ //#endregion
6148
6229
  //#region src/translator/util/set-tag-sections-downstream.ts
6149
6230
  const [getTagDownstreams] = createSectionState("tag-downstreams", () => /* @__PURE__ */ new Map());
6150
6231
  function setTagDownstream(tag, binding, exprs) {
@@ -6160,14 +6241,13 @@ function crawlSectionsAndSetBinding(tag, downstreamTag, binding, exprs, properti
6160
6241
  if (!skip) {
6161
6242
  const contentSection = getSectionForBody(tag.get("body"));
6162
6243
  if (contentSection) {
6163
- let target = binding;
6164
- forEach(properties, (property) => {
6165
- target = target?.propertyAliases.get(property);
6244
+ const serialized = filter(binding, (binding) => {
6245
+ const target = getPropertyAlias(binding, properties);
6246
+ return !(target && (target.noSerialize || propsUtil.has(target.noSerializeProperties, "content")));
6166
6247
  });
6167
- const serialized = !(target && (target.noSerialize || includes(target.noSerializeProperties, "content")));
6168
6248
  contentSection.downstream = {
6169
6249
  tag: downstreamTag,
6170
- binding: serialized ? binding : void 0,
6250
+ binding: serialized,
6171
6251
  properties: serialized ? concat(properties, "content") : void 0,
6172
6252
  exprs: serialized ? exprs : void 0
6173
6253
  };
@@ -6193,7 +6273,7 @@ function translateVar(tag, initialValue, kind = "const", statements) {
6193
6273
  if (!idExtra) return;
6194
6274
  const binding = idExtra.binding;
6195
6275
  if (!binding?.upstreamAlias) return;
6196
- if (binding.assignmentSections && binding.property !== void 0) {
6276
+ if (binding.assignments && binding.property !== void 0) {
6197
6277
  const changeName = binding.property + "Change";
6198
6278
  const changeBinding = binding.upstreamAlias.propertyAliases.get(changeName);
6199
6279
  if (changeBinding && changeName !== changeBinding.name) {
@@ -6253,14 +6333,24 @@ function knownTagAnalyze(tag, contentSection, propTree) {
6253
6333
  if (varBinding) {
6254
6334
  addSetupStatement(section);
6255
6335
  const mutatesTagVar = !!(tag.node.var.type === "Identifier" && tag.scope.getBinding(tag.node.var.name)?.constantViolations.length);
6256
- const varExpr = tagExtra.defineBodySection ? contentSection.returnValueExpr : mapParamReasonToExpr(exprs, contentSection.returnSerializeReason && (contentSection.returnSerializeReason === true || !!contentSection.returnSerializeReason.state || contentSection.returnSerializeReason.param));
6336
+ const varExpr = tagExtra.defineBodySection ? contentSection.returnValueExpr : mapParamReasonToExpr(exprs, contentSection.returnSerializeReason && (contentSection.returnSerializeReason.forced || !!contentSection.returnSerializeReason.state || contentSection.returnSerializeReason.param));
6257
6337
  varBinding.scopeOffset = tagExtra[kChildOffsetScopeBinding$1] = createBinding("#scopeOffset", 0, section);
6258
6338
  setBindingDownstream(varBinding, varExpr);
6259
- if (mutatesTagVar) addSerializeExpr(section, true, childScopeBinding);
6260
- addSerializeExpr(section, varExpr, childScopeBinding);
6339
+ if (mutatesTagVar || varExpr === true) addSerializeReason(section, FORCED, childScopeBinding);
6340
+ if (varExpr !== true) addSerializeExpr(section, varExpr, childScopeBinding);
6261
6341
  }
6262
6342
  addSerializeExpr(section, fromIter(attrExprs), childScopeBinding);
6263
6343
  }
6344
+ function getRenderArgs(tag) {
6345
+ const args = tag.node.arguments;
6346
+ return args?.length && !args.every(isPrunedNode) ? args.map(toRenderArg) : null;
6347
+ }
6348
+ function isPrunedNode(node) {
6349
+ return !!node.extra?.pruned;
6350
+ }
6351
+ function toRenderArg(arg) {
6352
+ return isPrunedNode(arg) ? _marko_compiler.types.unaryExpression("void", _marko_compiler.types.numericLiteral(0)) : arg;
6353
+ }
6264
6354
  function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6265
6355
  const tagBody = tag.get("body");
6266
6356
  const { node } = tag;
@@ -6284,39 +6374,20 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6284
6374
  if (tagVar) varStatement = _marko_compiler.types.expressionStatement(callRuntime("_var", getScopeIdIdentifier(section), getScopeAccessorLiteral(tag.node.extra[kChildOffsetScopeBinding$1]), peekScopeId, _marko_compiler.types.stringLiteral(getResumeRegisterId(section, tagVar.extra?.binding, "var"))));
6285
6375
  }
6286
6376
  if (contentSection.paramReasonGroups) {
6287
- let childSerializeReasonExpr;
6288
- if (contentSection.paramReasonGroups.length === 1) {
6289
- const [group] = contentSection.paramReasonGroups;
6377
+ const childSerializeReasonExpr = buildGroupMask(contentSection.paramReasonGroups.map((group) => {
6290
6378
  const reason = getSerializeReason(section, childScopeBinding, group.id);
6291
- childSerializeReasonExpr = reason && getSerializeGuard(section, reason, false);
6292
- } else {
6293
- const props = [];
6294
- let bitmask = 0;
6295
- let bitmaskNames = "";
6296
- let hasDynamicReasons = false;
6297
- let hasSkippedReasons = false;
6298
- for (let i = 0; i < contentSection.paramReasonGroups.length; i++) {
6299
- const group = contentSection.paramReasonGroups[i];
6300
- const reason = getSerializeReason(section, childScopeBinding, group.id);
6301
- if (reason) {
6302
- hasDynamicReasons ||= reason !== true && !reason.state;
6303
- const guard = getSerializeGuard(section, reason, false);
6304
- if (bitmask >= 0) if (guard.type === "NumericLiteral" && guard.value === 1 && i < 30) {
6305
- bitmask |= 1 << i + 1;
6306
- const names = getDebugNames(group.reason);
6307
- if (names) bitmaskNames += bitmaskNames ? ` | ${names}` : names;
6308
- } else bitmask = -1;
6309
- props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), getDebugNames(group.reason)), guard));
6310
- } else hasSkippedReasons = true;
6311
- }
6312
- if (props.length) childSerializeReasonExpr = !(hasDynamicReasons || hasSkippedReasons) ? _marko_compiler.types.numericLiteral(1) : bitmask > 0 ? withLeadingComment(_marko_compiler.types.numericLiteral(bitmask), bitmaskNames) : _marko_compiler.types.objectExpression(props);
6313
- }
6379
+ const guard = reason && getSerializeGuard(section, reason, false);
6380
+ return {
6381
+ value: !guard ? void 0 : guard.type === "NumericLiteral" ? guard.value : guard,
6382
+ names: getDebugNames(group.reason)
6383
+ };
6384
+ }));
6314
6385
  if (childSerializeReasonExpr) tag.insertBefore(_marko_compiler.types.expressionStatement(callRuntime("_set_serialize_reason", childSerializeReasonExpr)));
6315
6386
  }
6316
6387
  const getArgs = () => {
6317
- let renderArgs = [];
6318
- if (tag.node.arguments) renderArgs = [...renderArgs, ...tag.node.arguments];
6319
- if (!tag.node.arguments?.length || properties.length) renderArgs.push(propsToExpression(properties));
6388
+ const args = getRenderArgs(tag);
6389
+ const renderArgs = args ? [...args] : [];
6390
+ if (!args || properties.length) renderArgs.push(propsToExpression(properties));
6320
6391
  return renderArgs;
6321
6392
  };
6322
6393
  if (tagVar) {
@@ -6506,12 +6577,12 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs, rootE
6506
6577
  addSetupExpr(section, attr.value);
6507
6578
  setBindingDownstream(templateExportAttr.binding, attrExtra, rootExprs);
6508
6579
  if (getRootSection(templateExportAttr.binding.section) !== (0, _marko_compiler_babel_utils.getProgram)().node.extra.section && isInvokeOnlyBinding(templateExportAttr.binding)) attrExtra.invokeOnly = true;
6509
- if (knownSpread && !includes(knownSpread.binding.excludeProperties, attr.name)) addRead(attrExtra, {}, getOrCreatePropertyAlias(knownSpread.binding, attr.name), section, void 0);
6580
+ if (knownSpread && !propsUtil.has(knownSpread.binding.excludeProperties, attr.name)) addRead(attrExtra, {}, getOrCreatePropertyAlias(knownSpread.binding, attr.name), section, void 0);
6510
6581
  }
6511
6582
  } else if (spreadReferenceNodes) spreadReferenceNodes.push(attr.value);
6512
6583
  else {
6513
6584
  knownSpread = hasAllKnownProps(propTree) ? getSingleKnownSpread(attributes) : void 0;
6514
- if (knownSpread) dropNodes(attr.value);
6585
+ if (knownSpread) untrackNode(attr.value);
6515
6586
  else (spreadReferenceNodes = restReferenceNodes || []).push(attr.value);
6516
6587
  }
6517
6588
  }
@@ -6544,7 +6615,7 @@ function getSingleKnownSpread(attributes) {
6544
6615
  let extra;
6545
6616
  for (let i = attributes.length; i--;) {
6546
6617
  const attr = attributes[i];
6547
- if (attr.type === "MarkoSpreadAttribute" ? binding || !(binding = (extra = attr.value.extra)?.spreadFrom) : binding && !includes(binding.excludeProperties, attr.name)) return;
6618
+ if (attr.type === "MarkoSpreadAttribute" ? binding || !(binding = (extra = attr.value.extra)?.spreadFrom) : binding && !propsUtil.has(binding.excludeProperties, attr.name)) return;
6548
6619
  }
6549
6620
  if (binding) return {
6550
6621
  extra,
@@ -6557,8 +6628,9 @@ function writeParamsToSignals(tag, propTree, importAlias, info) {
6557
6628
  const tagInputIdentifier = info.getBindingIdentifier(propTree.binding, `${importAlias}_params`);
6558
6629
  const translatedAttrs = translateAttrs(tag);
6559
6630
  if (translatedAttrs.statements.length) addStatement("render", info.tagSection, referencedBindings, translatedAttrs.statements);
6560
- const renderParams = tag.node.arguments ? [...tag.node.arguments] : [];
6561
- if (!tag.node.arguments?.length || translatedAttrs.properties.length) renderParams.push(propsToExpression(translatedAttrs.properties));
6631
+ const args = getRenderArgs(tag);
6632
+ const renderParams = args ? [...args] : [];
6633
+ if (!args || translatedAttrs.properties.length) renderParams.push(propsToExpression(translatedAttrs.properties));
6562
6634
  addStatement("render", info.tagSection, referencedBindings, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(tagInputIdentifier, [createScopeReadExpression(info.childScopeBinding, info.tagSection), _marko_compiler.types.arrayExpression(renderParams)])));
6563
6635
  return;
6564
6636
  }
@@ -6786,10 +6858,17 @@ function getRootSection(section) {
6786
6858
  //#endregion
6787
6859
  //#region src/translator/util/references.ts
6788
6860
  const kBranchSerializeReason = Symbol("branch serialize reason");
6861
+ const FORCED = {
6862
+ state: void 0,
6863
+ param: void 0,
6864
+ global: void 0,
6865
+ forced: true
6866
+ };
6789
6867
  const globalSources = {
6790
6868
  state: void 0,
6791
6869
  param: void 0,
6792
- global: true
6870
+ global: true,
6871
+ forced: void 0
6793
6872
  };
6794
6873
  const [getBindings] = createProgramState(() => /* @__PURE__ */ new Set());
6795
6874
  const [getNextBindingId, setNextBindingId] = createProgramState(() => 0);
@@ -6809,11 +6888,12 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6809
6888
  property,
6810
6889
  declared,
6811
6890
  closureSections: void 0,
6812
- assignmentSections: void 0,
6891
+ assignments: void 0,
6813
6892
  excludeProperties,
6814
6893
  noSerialize: false,
6815
6894
  noSerializeProperties: void 0,
6816
6895
  sources: void 0,
6896
+ upstreamIntersection: void 0,
6817
6897
  reads: /* @__PURE__ */ new Set(),
6818
6898
  aliases: /* @__PURE__ */ new Set(),
6819
6899
  hoists: void 0,
@@ -6846,8 +6926,18 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6846
6926
  return binding;
6847
6927
  }
6848
6928
  function getOrCreatePropertyAlias(binding, property) {
6929
+ while (isDirectAlias(binding)) binding = binding.upstreamAlias;
6849
6930
  return binding.propertyAliases.get(property) || createBinding(`${binding.name}_${property.replace(/[^a-zA-Z0-9_$]/g, "_")}`, binding.type, binding.section, binding, property);
6850
6931
  }
6932
+ function getPropertyAlias(binding, properties) {
6933
+ return reduce(properties, getExistingPropertyAlias, binding);
6934
+ }
6935
+ function getExistingPropertyAlias(binding, property) {
6936
+ while (binding) {
6937
+ if (!isDirectAlias(binding)) return binding.propertyAliases.get(property);
6938
+ binding = binding.upstreamAlias;
6939
+ }
6940
+ }
6851
6941
  function trackDomVarReferences(tag, binding) {
6852
6942
  const tagVar = tag.node.var;
6853
6943
  if (!tagVar) return;
@@ -6866,7 +6956,7 @@ function trackDomVarReferences(tag, binding) {
6866
6956
  } : void 0);
6867
6957
  if (refSection !== binding.section) {
6868
6958
  setReadsOwner(refSection, section);
6869
- addOwnerSerializeReason(refSection, section, true);
6959
+ addOwnerSerializeReason(refSection, section, FORCED);
6870
6960
  }
6871
6961
  }
6872
6962
  return binding;
@@ -6985,10 +7075,12 @@ function trackAssignment(assignment, binding) {
6985
7075
  const idExtra = id.node.extra ??= {};
6986
7076
  idExtra.assignment = binding;
6987
7077
  idExtra.section = section;
6988
- binding.assignmentSections = sectionUtil.add(binding.assignmentSections, section);
7078
+ idExtra.exprRoot = getExprRoot(fnRoot || assignment).node.extra ??= {};
7079
+ idExtra.fnRoot = fnExtra;
7080
+ getAssignments().push(idExtra);
6989
7081
  if (fnExtra) {
6990
- idExtra.assignmentFunction = fnExtra;
6991
- fnExtra.section = idExtra.section = section;
7082
+ fnExtra.section = section;
7083
+ fnExtra.exprRoot = idExtra.exprRoot;
6992
7084
  }
6993
7085
  if (binding.upstreamAlias && binding.property !== void 0) {
6994
7086
  if (binding.upstreamAlias === binding.section.params) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag parameter and cannot be assigned to.`);
@@ -7027,10 +7119,7 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, upstreamAl
7027
7119
  else if (prop.key.type === "StringLiteral") key = prop.key.value;
7028
7120
  else throw scope.path.hub.buildError(prop.key, "Only identifier and string literal keys are supported when destructuring.");
7029
7121
  if (hasRest) excludeProperties = propsUtil.add(excludeProperties, key);
7030
- if (_marko_compiler.types.isLVal(prop.value)) {
7031
- createBindingsAndTrackReferences(prop.value, type, scope, section, patternBinding, key, void 0);
7032
- if (hasRest && prop.value.extra?.binding?.assignmentSections) excludeProperties = propsUtil.add(excludeProperties, `${key}Change`);
7033
- }
7122
+ if (_marko_compiler.types.isLVal(prop.value)) createBindingsAndTrackReferences(prop.value, type, scope, section, patternBinding, key, void 0);
7034
7123
  }
7035
7124
  break;
7036
7125
  }
@@ -7131,6 +7220,33 @@ function finalizeReferences() {
7131
7220
  const readsByExpression = getReadsByExpression();
7132
7221
  const fnReadsByExpression = getFunctionReadsByExpression();
7133
7222
  const intersectionsBySection = /* @__PURE__ */ new Map();
7223
+ const assignments = getAssignments();
7224
+ for (const idExtra of assignments) if (inEmittedExpr(idExtra)) {
7225
+ const binding = idExtra.assignment;
7226
+ binding.assignments = push(binding.assignments, idExtra);
7227
+ }
7228
+ for (const binding of bindings) {
7229
+ if (binding.type !== 0) {
7230
+ if (pruneBinding(binding, true)) bindings.delete(binding);
7231
+ }
7232
+ if (binding.noSerialize) if (isPureSpreadResolved(binding)) if (hasAnyMemberAccess(binding)) {
7233
+ binding.noSerialize = false;
7234
+ binding.noSerializeProperties = propsUtil.filter(binding.noSerializeProperties, (property) => !isPropertyMemberAccessed(binding, property));
7235
+ } else binding.noSerializeProperties = void 0;
7236
+ else {
7237
+ binding.noSerialize = false;
7238
+ binding.noSerializeProperties = void 0;
7239
+ }
7240
+ }
7241
+ const excluded = /* @__PURE__ */ new Set();
7242
+ for (const idExtra of assignments) {
7243
+ const binding = idExtra.assignment;
7244
+ if (!inEmittedExpr(idExtra)) binding.assignments = filter(binding.assignments, inEmittedExpr);
7245
+ else if (!excluded.has(binding) && binding.upstreamAlias && binding.property !== void 0) {
7246
+ excluded.add(binding);
7247
+ for (const alias of binding.upstreamAlias.aliases) if (propsUtil.has(alias.excludeProperties, binding.property)) alias.excludeProperties = propsUtil.add(alias.excludeProperties, binding.property + "Change");
7248
+ }
7249
+ }
7134
7250
  for (const [expr, reads] of readsByExpression) if (isReferencedExtra(expr)) {
7135
7251
  const exprBindings = resolveReferencedBindings(expr, reads, intersectionsBySection);
7136
7252
  expr.referencedBindings = exprBindings.referencedBindings;
@@ -7143,13 +7259,13 @@ function finalizeReferences() {
7143
7259
  if (exprBindings.hoistedBindings) expr.section.referencedHoists = bindingUtil.union(expr.section.referencedHoists, exprBindings.hoistedBindings);
7144
7260
  if (expr.isEffect) {
7145
7261
  forEach(exprBindings.referencedBindings, (binding) => {
7146
- addSerializeReason(binding.section, true, binding);
7262
+ addSerializeReason(binding.section, FORCED, binding);
7147
7263
  });
7148
7264
  forEach(exprBindings.constantBindings, (binding) => {
7149
- addSerializeReason(binding.section, true, binding);
7265
+ addSerializeReason(binding.section, FORCED, binding);
7150
7266
  });
7151
7267
  forEach(exprBindings.lazyBindings, (binding) => {
7152
- addSerializeReason(binding.section, true, binding);
7268
+ addSerializeReason(binding.section, FORCED, binding);
7153
7269
  });
7154
7270
  } else forEach(reads, (read) => {
7155
7271
  if (read.serializedValue) addSerializeExpr(read.binding.section, expr, read.binding);
@@ -7164,23 +7280,6 @@ function finalizeReferences() {
7164
7280
  }
7165
7281
  }
7166
7282
  const bindingNamesBySection = /* @__PURE__ */ new Map();
7167
- for (const binding of bindings) {
7168
- if (binding.type !== 0) {
7169
- if (pruneBinding(binding)) bindings.delete(binding);
7170
- }
7171
- if (binding.noSerialize) if (isPureSpreadResolved(binding)) if (hasAnyMemberAccess(binding)) {
7172
- let kept = void 0;
7173
- binding.noSerialize = false;
7174
- forEach(binding.noSerializeProperties, (property) => {
7175
- if (!isPropertyMemberAccessed(binding, property)) kept = push(kept, property);
7176
- });
7177
- binding.noSerializeProperties = kept;
7178
- } else binding.noSerializeProperties = void 0;
7179
- else {
7180
- binding.noSerialize = false;
7181
- binding.noSerializeProperties = void 0;
7182
- }
7183
- }
7184
7283
  forEachSection(finalizeTagDownstreams);
7185
7284
  for (const binding of bindings) {
7186
7285
  const { name, section } = binding;
@@ -7190,9 +7289,9 @@ function finalizeReferences() {
7190
7289
  }
7191
7290
  if (binding.type !== 0) {
7192
7291
  resolveBindingSources(binding);
7193
- forEach(binding.assignmentSections, (assignedSection) => {
7292
+ forEach(binding.assignments, ({ section: assignedSection }) => {
7194
7293
  setReadsOwner(assignedSection, section);
7195
- addOwnerSerializeReason(assignedSection, section, true);
7294
+ addOwnerSerializeReason(assignedSection, section, FORCED);
7196
7295
  });
7197
7296
  let bindingNames = bindingNamesBySection.get(section);
7198
7297
  if (!bindingNames) {
@@ -7206,7 +7305,7 @@ function finalizeReferences() {
7206
7305
  forEach(binding.hoists, (hoistSection) => {
7207
7306
  if (!highestHoistSection || hoistSection.depth < highestHoistSection.depth) highestHoistSection = hoistSection;
7208
7307
  hoistSection.hoistedTo = bindingUtil.add(hoistSection.hoistedTo, binding);
7209
- addSerializeReason(binding.section, true, binding);
7308
+ addSerializeReason(binding.section, FORCED, binding);
7210
7309
  });
7211
7310
  binding.section.hoisted = bindingUtil.add(binding.section.hoisted, binding);
7212
7311
  let currentSection = binding.section.parent;
@@ -7229,21 +7328,20 @@ function finalizeReferences() {
7229
7328
  section.referencedClosures = bindingUtil.add(section.referencedClosures, canonicalUpstreamAlias);
7230
7329
  }
7231
7330
  setReadsOwner(section, canonicalUpstreamAlias.section);
7232
- if (isEffect) addOwnerSerializeReason(section, canonicalUpstreamAlias.section, true);
7233
- addOwnerSerializeReason(section, canonicalUpstreamAlias.section, canonicalUpstreamAlias.sources);
7331
+ addOwnerSerializeReason(section, canonicalUpstreamAlias.section, isEffect ? mergeSources(FORCED, canonicalUpstreamAlias.sources) : canonicalUpstreamAlias.sources);
7234
7332
  }
7235
7333
  }
7236
7334
  }
7237
7335
  }
7238
7336
  forEachSection((section) => {
7239
- if (section.isHoistThrough) addSerializeReason(section, true);
7337
+ if (section.isHoistThrough) addSerializeReason(section, FORCED);
7240
7338
  forEach(section.referencedHoists, (hoistedBinding) => {
7241
7339
  setReadsOwner(section, hoistedBinding.section);
7242
- addOwnerSerializeReason(section, hoistedBinding.section, true);
7340
+ addOwnerSerializeReason(section, hoistedBinding.section, FORCED);
7243
7341
  });
7244
7342
  if (section.parent && section.isBranch && section.sectionAccessor && section.upstreamExpression) {
7245
- if (section.isHoistThrough || section.hoisted) addSerializeReason(section, true, kBranchSerializeReason);
7246
- addSerializeReason(section, getSerializeSourcesForRef(getDirectClosures(section)), kBranchSerializeReason);
7343
+ const closureSources = getSerializeSourcesForRef(getDirectClosures(section));
7344
+ addSerializeReason(section, section.isHoistThrough || section.hoisted ? mergeSources(FORCED, closureSources) : closureSources, kBranchSerializeReason);
7247
7345
  addSerializeExpr(section, section.upstreamExpression, kBranchSerializeReason);
7248
7346
  addSerializeExpr(section.parent, section.upstreamExpression, section.sectionAccessor.binding);
7249
7347
  }
@@ -7282,8 +7380,7 @@ function finalizeReferences() {
7282
7380
  else if (upstreamReason) branchesSources = mergeSources(branchesSources, upstreamReason);
7283
7381
  currentSection = currentSection.parent;
7284
7382
  }
7285
- const branchesReason = branchesForced || branchesSources;
7286
- if (branchesForced) addSerializeReason(sourceSection, branchesSources, closure);
7383
+ const branchesReason = branchesForced ? mergeSources(FORCED, branchesSources) : branchesSources;
7287
7384
  addSerializeReason(sourceSection, branchesReason, closure);
7288
7385
  addSerializeReason(sourceSection, getSerializeReason(sourceSection, closure));
7289
7386
  if (isDynamicClosure(section, closure)) {
@@ -7296,22 +7393,15 @@ function finalizeReferences() {
7296
7393
  });
7297
7394
  });
7298
7395
  finalizeFunctionRegistry();
7299
- const referencedExprs = /* @__PURE__ */ new Set();
7300
- for (const binding of bindings) for (const expr of binding.reads) referencedExprs.add(expr);
7301
- for (const expr of referencedExprs) {
7302
- const exprFnReads = fnReadsByExpression.get(expr);
7303
- if (exprFnReads) {
7304
- for (const fn of exprFnReads.keys()) if (fn.registerReason) {
7305
- forEach(fn.referencedBindingsInFunction, (binding) => {
7306
- addSerializeReason(binding.section, fn.registerReason, binding);
7307
- if (binding.section !== fn.section) addOwnerSerializeReason(fn.section, binding.section, fn.registerReason);
7308
- });
7309
- forEach(fn.constantBindingsInFunction, (binding) => {
7310
- addSerializeReason(binding.section, fn.registerReason, binding);
7311
- if (binding.section !== fn.section) addOwnerSerializeReason(fn.section, binding.section, fn.registerReason);
7312
- });
7313
- }
7314
- }
7396
+ for (const exprFnReads of fnReadsByExpression.values()) for (const fn of exprFnReads.keys()) if (fn.registerReason) {
7397
+ forEach(fn.referencedBindingsInFunction, (binding) => {
7398
+ addSerializeReason(binding.section, fn.registerReason, binding);
7399
+ if (binding.section !== fn.section) addOwnerSerializeReason(fn.section, binding.section, fn.registerReason);
7400
+ });
7401
+ forEach(fn.constantBindingsInFunction, (binding) => {
7402
+ addSerializeReason(binding.section, fn.registerReason, binding);
7403
+ if (binding.section !== fn.section) addOwnerSerializeReason(fn.section, binding.section, fn.registerReason);
7404
+ });
7315
7405
  }
7316
7406
  forEachSection(finalizeParamSerializeReasonGroups);
7317
7407
  forEachSectionReverse((section) => {
@@ -7323,10 +7413,11 @@ function finalizeReferences() {
7323
7413
  const { id, bindings } = section;
7324
7414
  const isOwnedBinding = ({ section }) => section.id === id;
7325
7415
  const ownedBindings = filter(bindings, isOwnedBinding);
7416
+ const intersectionSources = /* @__PURE__ */ new Map();
7326
7417
  const intersections = (intersectionsBySection.get(section) || []).filter((intersection) => {
7327
- const collapseSource = getCollapsibleIntersectionSource(intersection, section);
7328
- if (collapseSource) collapsedIntersectionSource.set(intersection, collapseSource);
7329
- return !collapseSource;
7418
+ const source = getIntersectionSource(intersection, section, intersectionSources);
7419
+ if (source) intersectionMeta.set(intersection, { source });
7420
+ return !source;
7330
7421
  });
7331
7422
  let anchors;
7332
7423
  if (intersections.length) {
@@ -7344,31 +7435,29 @@ function finalizeReferences() {
7344
7435
  let intersectionIndex = 0;
7345
7436
  let nextId = 0;
7346
7437
  let intersection;
7438
+ const assignIntersectionId = (intersection) => {
7439
+ intersectionMeta.set(intersection, {
7440
+ source: void 0,
7441
+ id: nextId++,
7442
+ scopeOffset: getMaxOwnSourceOffset(intersection, section)
7443
+ });
7444
+ };
7347
7445
  forEach(ownedBindings, (binding) => {
7348
7446
  if (binding.type !== 0) while (intersectionIndex < intersections.length && !anchors.get(intersection = intersections[intersectionIndex])) {
7349
7447
  intersectionIndex++;
7350
- intersectionMeta.set(intersection, {
7351
- id: nextId++,
7352
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
7353
- });
7448
+ assignIntersectionId(intersection);
7354
7449
  }
7355
7450
  binding.id = nextId++;
7356
7451
  nextId += binding.reserveSize;
7357
7452
  while (intersectionIndex < intersections.length && anchors.get(intersection = intersections[intersectionIndex]) === binding) {
7358
7453
  intersectionIndex++;
7359
- intersectionMeta.set(intersection, {
7360
- id: nextId++,
7361
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
7362
- });
7454
+ assignIntersectionId(intersection);
7363
7455
  }
7364
7456
  });
7365
7457
  while (intersectionIndex < intersections.length) {
7366
7458
  intersection = intersections[intersectionIndex];
7367
7459
  intersectionIndex++;
7368
- intersectionMeta.set(intersection, {
7369
- id: nextId++,
7370
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
7371
- });
7460
+ assignIntersectionId(intersection);
7372
7461
  }
7373
7462
  forEach(ownedBindings, (binding) => {
7374
7463
  if (binding.closureSections) closureAccessorIds.set(binding, nextId++);
@@ -7402,13 +7491,20 @@ function getMaxOwnSourceOffset(intersection, section) {
7402
7491
  }
7403
7492
  const intersectionMeta = /* @__PURE__ */ new WeakMap();
7404
7493
  const closureAccessorIds = /* @__PURE__ */ new WeakMap();
7405
- const collapsedIntersectionSource = /* @__PURE__ */ new WeakMap();
7406
- function getCollapsibleIntersectionSource(intersection, section) {
7494
+ function getIntersectionSource(intersection, section, resolved) {
7495
+ if (!resolved.has(intersection)) {
7496
+ resolved.set(intersection, void 0);
7497
+ resolved.set(intersection, resolveIntersectionSource(intersection, section, resolved));
7498
+ }
7499
+ return resolved.get(intersection);
7500
+ }
7501
+ function resolveIntersectionSource(intersection, section, resolved) {
7407
7502
  let sources;
7408
7503
  for (const member of intersection) {
7409
7504
  if (!member.sources) return void 0;
7410
- const isDirectAlias = member.upstreamAlias && member.property === void 0 && member.excludeProperties === void 0;
7411
- if (member.section !== section || isDirectAlias) return void 0;
7505
+ if (member.section !== section || isDirectAlias(member)) return void 0;
7506
+ const upstream = getUpstreamIntersection(member);
7507
+ if (upstream && upstream !== intersection && !getIntersectionSource(upstream, section, resolved)) return;
7412
7508
  sources = mergeSources(sources, member.sources);
7413
7509
  }
7414
7510
  if (!sources || sources.state && sources.param) return;
@@ -7416,12 +7512,15 @@ function getCollapsibleIntersectionSource(intersection, section) {
7416
7512
  return source && !Array.isArray(source) && source.section === section && !source.scopeOffset ? source : void 0;
7417
7513
  }
7418
7514
  function setBindingDownstream(binding, expr, exprs) {
7419
- getBindingValueExprs().set(binding, expr || false);
7515
+ setBindingValueExprs(binding, expr);
7420
7516
  if (expr && expr !== true) forEach(expr, (expr) => {
7421
7517
  expr.downstream = bindingUtil.add(expr.downstream, binding);
7422
7518
  if (exprs) expr.downstreamExprs = exprs;
7423
7519
  });
7424
7520
  }
7521
+ function setBindingValueExprs(binding, expr) {
7522
+ getBindingValueExprs().set(binding, expr || false);
7523
+ }
7425
7524
  const [getResolvedSources] = createProgramState(() => /* @__PURE__ */ new Set());
7426
7525
  const [getBindingValueExprs] = createProgramState(() => /* @__PURE__ */ new Map());
7427
7526
  function resolveBindingSources(binding) {
@@ -7434,7 +7533,7 @@ function resolveBindingSources(binding) {
7434
7533
  if (aliasRoot) {
7435
7534
  resolveBindingSources(aliasRoot);
7436
7535
  binding.sources = aliasRoot.sources;
7437
- } else if (binding.assignmentSections) binding.sources = createSources(binding, void 0);
7536
+ } else if (binding.assignments) binding.sources = createSources(binding, void 0);
7438
7537
  else resolveDerivedSources(binding);
7439
7538
  return;
7440
7539
  }
@@ -7466,34 +7565,36 @@ function getAliasRoot(binding) {
7466
7565
  return alias;
7467
7566
  }
7468
7567
  function resolveDerivedSources(binding) {
7469
- const bindingValueExprs = getBindingValueExprs();
7470
- const exprs = bindingValueExprs.get(binding);
7471
- bindingValueExprs.delete(binding);
7568
+ const exprs = getBindingValueExprs().get(binding);
7472
7569
  if (exprs === void 0 || exprs === true) binding.sources = createSources(binding, void 0);
7473
7570
  else if (exprs) {
7474
- const seen = /* @__PURE__ */ new Set();
7571
+ let refs;
7475
7572
  forEach(exprs, (expr) => {
7476
- if (isReferencedExtra(expr)) forEach(expr.referencedBindings, (ref) => {
7477
- if (!seen.has(ref)) {
7478
- seen.add(ref);
7479
- resolveBindingSources(ref);
7480
- binding.sources = mergeSources(binding.sources, ref.sources);
7481
- }
7482
- });
7573
+ if (isReferencedExtra(expr) && bindingUtil.has(expr.downstream, binding)) refs = bindingUtil.union(refs, expr.referencedBindings);
7574
+ });
7575
+ forEach(refs, (ref) => {
7576
+ resolveBindingSources(ref);
7577
+ binding.sources = mergeSources(binding.sources, ref.sources);
7483
7578
  });
7579
+ binding.upstreamIntersection = Array.isArray(refs) ? refs : refs && getUpstreamIntersection(refs);
7484
7580
  }
7485
7581
  }
7486
- function createSources(state, param, global) {
7582
+ function getUpstreamIntersection(binding) {
7583
+ return (getAliasRoot(binding) || binding).upstreamIntersection;
7584
+ }
7585
+ function createSources(state, param, global, forced) {
7487
7586
  /* v8 ignore next 6 -- every caller passes at least one source */
7488
- if (!(state || param || global)) throw new Error("Cannot create a serialize reason that does not reference state, a param, or $global.");
7587
+ if (!(state || param || global || forced)) throw new Error("Cannot create a serialize reason that does not reference state, a param, or $global.");
7489
7588
  return {
7490
7589
  state,
7491
7590
  param,
7492
- global
7591
+ global,
7592
+ forced
7493
7593
  };
7494
7594
  }
7495
7595
  function compareSources(a, b) {
7496
7596
  let delta;
7597
+ if (a.forced !== b.forced) return a.forced ? 1 : -1;
7497
7598
  if (a.global !== b.global) return a.global ? 1 : -1;
7498
7599
  if (a.param) {
7499
7600
  if (!b.param) return 1;
@@ -7508,12 +7609,12 @@ function compareSources(a, b) {
7508
7609
  function mergeSources(a, b) {
7509
7610
  if (!a) return b;
7510
7611
  if (!b) return a;
7511
- if (a.state === b.state && a.param === b.param && a.global === b.global) return a;
7512
- return createSources(bindingUtil.union(a.state, b.state), unionParamSources(a.param, b.param), a.global || b.global);
7612
+ if (a.state === b.state && a.param === b.param && a.global === b.global && a.forced === b.forced) return a;
7613
+ return createSources(bindingUtil.union(a.state, b.state), unionParamSources(a.param, b.param), a.global || b.global, a.forced || b.forced);
7513
7614
  }
7514
7615
  function unionParamSources(a, b) {
7515
7616
  const merged = bindingUtil.union(a, b);
7516
- if (merged && Array.isArray(merged)) return filter(merged, (binding) => {
7617
+ if (merged && Array.isArray(merged)) return bindingUtil.filter(merged, (binding) => {
7517
7618
  let alias = binding.upstreamAlias;
7518
7619
  while (alias) {
7519
7620
  if (bindingUtil.has(merged, alias)) return false;
@@ -7529,6 +7630,7 @@ const bindingUtil = new Sorted(function compareBindings(a, b) {
7529
7630
  const propsUtil = new Sorted(function compareProps(a, b) {
7530
7631
  return a < b ? -1 : a > b ? 1 : 0;
7531
7632
  });
7633
+ const [getAssignments] = createProgramState(() => []);
7532
7634
  const [getReadsByExpression] = createProgramState(() => /* @__PURE__ */ new Map());
7533
7635
  const [getFunctionReadsByExpression] = createProgramState(() => /* @__PURE__ */ new Map());
7534
7636
  const [getReferenceFinalizers] = createProgramState(() => []);
@@ -7553,20 +7655,43 @@ function addRead(exprExtra, extra, binding, section, getter) {
7553
7655
  readsByExpression.set(exprExtra, push(readsByExpression.get(exprExtra), read));
7554
7656
  return read;
7555
7657
  }
7658
+ function isEmitted(exprExtra) {
7659
+ return !getCanonicalExtra(exprExtra).pruned;
7660
+ }
7661
+ function inEmittedExpr({ exprRoot }) {
7662
+ return isEmitted(exprRoot);
7663
+ }
7664
+ function isDroppableValue(expr) {
7665
+ return !!expr.pure && !expr.merged && !expr.pruned;
7666
+ }
7667
+ function dropPureExtra(expr) {
7668
+ if (isDroppableValue(expr) && every(expr.downstream, isPrunedBinding)) dropExtra(expr);
7669
+ }
7670
+ function isPrunedBinding(binding) {
7671
+ return !!binding.pruned;
7672
+ }
7556
7673
  function dropNodes(node) {
7557
7674
  if (Array.isArray(node)) for (const item of node) dropExtra(item.extra ??= {});
7558
7675
  else dropExtra(node.extra ??= {});
7559
7676
  }
7677
+ function untrackNode(node) {
7678
+ untrackExtra(node.extra ??= {});
7679
+ }
7560
7680
  function dropExtra(exprExtra) {
7681
+ exprExtra.pruned = true;
7682
+ untrackExtra(exprExtra);
7683
+ }
7684
+ function untrackExtra(exprExtra) {
7561
7685
  /* v8 ignore next 3 -- a merged reference is never dropped */
7562
7686
  if (exprExtra.merged) throw new Error("Cannot drop a merged reference");
7563
7687
  const readsByExpr = getReadsByExpression();
7564
7688
  const reads = readsByExpr.get(exprExtra);
7565
- exprExtra.pruned = true;
7566
7689
  if (reads) {
7567
7690
  readsByExpr.delete(exprExtra);
7691
+ getFunctionReadsByExpression().delete(exprExtra);
7568
7692
  forEach(reads, (read) => {
7569
7693
  read.binding.reads.delete(exprExtra);
7694
+ if (!exprExtra.pruned) read.binding.untracked = true;
7570
7695
  });
7571
7696
  }
7572
7697
  }
@@ -7583,8 +7708,11 @@ function addReadToExpression(root, binding, getter) {
7583
7708
  const fnRoot = getFnRoot(root);
7584
7709
  const exprRoot = getExprRoot(fnRoot || root);
7585
7710
  const section = getOrCreateSection(exprRoot);
7586
- const exprExtra = getCanonicalExtra(exprRoot.node.extra ??= { section });
7587
- const read = addRead(exprExtra, node.extra ??= {}, binding, section, getter);
7711
+ const rootExtra = exprRoot.node.extra ??= { section };
7712
+ const exprExtra = getCanonicalExtra(rootExtra);
7713
+ const extra = node.extra ??= {};
7714
+ extra.exprRoot = rootExtra;
7715
+ const read = addRead(exprExtra, extra, binding, section, getter);
7588
7716
  if (!fnRoot && isSerializedChangeHandlerRead(exprRoot)) read.serializedValue = true;
7589
7717
  const { parent } = root;
7590
7718
  if (parent.type === "BinaryExpression" && (parent.operator === "===" || parent.operator === "!==")) read.comparedTo = parent.left === node ? parent.right : parent.left;
@@ -7600,14 +7728,23 @@ function addReadToExpression(root, binding, getter) {
7600
7728
  if (!exprFnReads) fnReadsByExpr.set(exprExtra, exprFnReads = /* @__PURE__ */ new Map());
7601
7729
  const fnExtra = fnRoot.node.extra ??= {};
7602
7730
  fnExtra.section = section;
7731
+ fnExtra.exprRoot = rootExtra;
7603
7732
  exprFnReads.set(fnExtra, push(exprFnReads.get(fnExtra), read));
7604
7733
  }
7605
7734
  }
7606
7735
  function getCanonicalBinding(binding) {
7607
7736
  const alias = binding.upstreamAlias;
7608
- if (alias && binding.property === void 0 && binding.excludeProperties === void 0) return alias;
7737
+ if (alias && isDirectAlias(binding)) return alias;
7609
7738
  return binding;
7610
7739
  }
7740
+ function someAlias(binding, test, arg, directOnly) {
7741
+ if (test(binding, arg)) return true;
7742
+ for (const alias of binding.aliases) if ((!directOnly || isDirectAlias(alias)) && someAlias(alias, test, arg, directOnly)) return true;
7743
+ return false;
7744
+ }
7745
+ function isDirectAlias(binding) {
7746
+ return binding.upstreamAlias !== void 0 && binding.property === void 0 && binding.excludeProperties === void 0;
7747
+ }
7611
7748
  function getAllTagReferenceNodes(tag, referenceNodes = []) {
7612
7749
  if (tag.arguments) for (const arg of tag.arguments) referenceNodes.push(arg);
7613
7750
  for (const attr of tag.attributes) referenceNodes.push(attr.value);
@@ -7732,20 +7869,22 @@ function getReadReplacement(node, signal) {
7732
7869
  if (readBinding.getters.has(readBinding.section)) replacement = getBindingGetterIdentifier(readBinding, readBinding.section);
7733
7870
  } else if (readBinding.name !== node.name) node.name = readBinding.name;
7734
7871
  } else {
7735
- const props = read.props ? Array.isArray(read.props) ? read.props.slice() : [read.props] : [];
7872
+ const { props } = read;
7873
+ let remaining = size(props);
7736
7874
  let curNode = node;
7737
7875
  let curBinding = readBinding;
7738
7876
  let replaceMember;
7739
7877
  if (isOutputDOM()) if (signal?.referencedBindings === readBinding && !signal.hasSideEffect) replacement = getSignalValueIdentifier(signal);
7740
7878
  else replacement = createScopeReadExpression(readBinding, extra.section);
7741
7879
  else replacement = _marko_compiler.types.identifier(readBinding.name);
7742
- while (props.length && (curNode.type === "MemberExpression" || curNode.type === "OptionalMemberExpression")) {
7743
- const prop = props.pop();
7880
+ while (remaining && (curNode.type === "MemberExpression" || curNode.type === "OptionalMemberExpression")) {
7881
+ const prop = at(props, --remaining);
7744
7882
  if (getMemberExpressionPropString(curNode) !== prop) break;
7745
7883
  replaceMember = curNode;
7746
7884
  curNode = curNode.object;
7747
7885
  }
7748
- for (const prop of props) {
7886
+ for (let i = 0; i < remaining; i++) {
7887
+ const prop = at(props, i);
7749
7888
  if (curBinding) curBinding = curBinding.propertyAliases.get(prop);
7750
7889
  replacement = toMemberExpression(replacement, prop, !!curBinding?.nullable);
7751
7890
  }
@@ -7762,45 +7901,62 @@ function getReadReplacement(node, signal) {
7762
7901
  } else if (binding && node.type == "Identifier" && node.name !== binding.name) node.name = binding.name;
7763
7902
  }
7764
7903
  function isInvokeOnlyBinding(binding) {
7765
- if (binding.assignmentSections || binding.hoists || binding.getters.size || binding.propertyAliases.size || binding.excludeProperties) return false;
7766
- for (const expr of binding.reads) if (!expr.invokeOnly) return false;
7767
- for (const alias of binding.aliases) if (!isInvokeOnlyBinding(alias)) return false;
7768
- return true;
7904
+ return !someAlias(binding, isReadBeyondInvoking, void 0);
7905
+ }
7906
+ function isReadBeyondInvoking(binding) {
7907
+ if (binding.assignments || binding.hoists || binding.getters.size || binding.propertyAliases.size || binding.excludeProperties) return true;
7908
+ for (const expr of binding.reads) if (!expr.invokeOnly) return true;
7909
+ return false;
7769
7910
  }
7770
7911
  function hasNonConstantPropertyAlias(ref) {
7771
7912
  for (const alias of ref.propertyAliases.values()) if (alias.type !== 6) return true;
7772
7913
  return false;
7773
7914
  }
7774
- function pruneBinding(binding) {
7915
+ function pruneBinding(binding, settled) {
7775
7916
  if (binding.pruned !== void 0) return binding.pruned;
7917
+ if (settled) {
7918
+ binding.pruned = false;
7919
+ for (const read of binding.reads) if (isDroppableValue(read)) forEach(read.downstream, pruneSettledBinding);
7920
+ forEach(binding.assignments, pruneSettledWriter);
7921
+ }
7776
7922
  for (const read of binding.reads) {
7777
7923
  let upstream = binding.upstreamAlias;
7778
7924
  while (upstream && !upstream.reads.has(read)) upstream = upstream.upstreamAlias;
7779
7925
  if (upstream) binding.reads.delete(read);
7780
7926
  }
7781
7927
  let shouldPrune = !binding.reads.size && !binding.reserveSize;
7782
- for (const alias of binding.aliases) if (pruneBinding(alias)) binding.aliases.delete(alias);
7928
+ for (const alias of binding.aliases) if (pruneBinding(alias, settled)) binding.aliases.delete(alias);
7783
7929
  else if (alias.type !== 6) shouldPrune = false;
7784
- for (const [key, alias] of binding.propertyAliases) if (pruneBinding(alias)) binding.propertyAliases.delete(key);
7930
+ for (const [key, alias] of binding.propertyAliases) if (pruneBinding(alias, settled)) binding.propertyAliases.delete(key);
7785
7931
  else if (alias.type !== 6) shouldPrune = false;
7786
- binding.pruned = shouldPrune;
7932
+ if (settled) {
7933
+ binding.pruned = shouldPrune;
7934
+ if (shouldPrune && !binding.untracked && !some(binding.assignments, inEmittedExpr)) {
7935
+ const exprs = getBindingValueExprs().get(binding);
7936
+ if (exprs && exprs !== true) forEach(exprs, dropPureExtra);
7937
+ }
7938
+ }
7787
7939
  return shouldPrune;
7788
7940
  }
7941
+ function pruneSettledBinding(binding) {
7942
+ pruneBinding(binding, true);
7943
+ }
7944
+ function pruneSettledWriter({ exprRoot }) {
7945
+ if (isDroppableValue(exprRoot)) forEach(exprRoot.downstream, pruneSettledBinding);
7946
+ }
7789
7947
  function resolveReferencedBindingsInFunction(refs, reads) {
7790
7948
  let referencedBindings;
7791
7949
  let constantBindings;
7792
- if (reads) if (Array.isArray(reads)) for (const read of reads) {
7793
- const { getter, binding } = read;
7950
+ const closest = /* @__PURE__ */ new Set();
7951
+ forEach(reads, ({ getter, binding }) => {
7794
7952
  if (getter) {} else if (binding.type === 6) {
7795
7953
  if (bindingUtil.find(refs, binding)) constantBindings = bindingUtil.add(constantBindings, binding);
7796
- } else if (binding.type !== 0 && binding.type !== 7) referencedBindings = bindingUtil.add(referencedBindings, findClosestReference(read.binding, refs));
7797
- }
7798
- else {
7799
- const { getter, binding } = reads;
7800
- if (getter) {} else if (binding.type === 6) {
7801
- if (bindingUtil.find(refs, binding)) constantBindings = binding;
7802
- } else if (binding.type !== 0 && binding.type !== 7) referencedBindings = findClosestReference(binding, refs);
7803
- }
7954
+ } else if (binding.type !== 0 && binding.type !== 7) {
7955
+ const ref = findClosestReference(binding, refs);
7956
+ if (ref) closest.add(ref);
7957
+ }
7958
+ });
7959
+ if (closest.size) referencedBindings = bindingUtil.filter(refs, (ref) => closest.has(ref));
7804
7960
  return {
7805
7961
  referencedBindings,
7806
7962
  constantBindings
@@ -7970,6 +8126,12 @@ function createGetterRead(binding, props, getter) {
7970
8126
  function isReferencedExtra(extra) {
7971
8127
  return !!(extra && !extra.pruned && extra.section);
7972
8128
  }
8129
+ function hasResumableWriter(binding) {
8130
+ return some(binding.assignments, isResumableWriter);
8131
+ }
8132
+ function isResumableWriter({ exprRoot, fnRoot }) {
8133
+ return !!getCanonicalExtra(exprRoot).isEffect || isRegisteredFnExtra(fnRoot);
8134
+ }
7973
8135
  function isAssignedBindingExtra(extra) {
7974
8136
  return isReferencedExtra(extra) && extra.assignment !== void 0;
7975
8137
  }
@@ -7980,93 +8142,129 @@ function getCanonicalExtra(extra) {
7980
8142
  while (extra.merged) extra = extra.merged;
7981
8143
  return extra;
7982
8144
  }
7983
- const serializeReasonCache = /* @__PURE__ */ new WeakMap();
7984
- const registerReasonCache = /* @__PURE__ */ new WeakMap();
7985
- function getAllSerializeReasonsForExtra(extra, register) {
7986
- if (extra.isEffect || register && extra.dynamicTagInput) return true;
7987
- const cache = register ? registerReasonCache : serializeReasonCache;
7988
- let reason = cache.get(extra);
7989
- if (reason === false) return;
7990
- if (reason === void 0) {
7991
- if (extra === (0, _marko_compiler_babel_utils.getProgram)().node.extra?.section.returnValueExpr) reason = true;
7992
- else {
7993
- cache.set(extra, false);
7994
- forEach(extra.downstream, (binding) => {
7995
- let linked = getAllSerializeReasonsForBinding(binding, true, register);
7996
- if (linked && linked !== true) {
7997
- const exprs = extra.downstreamExprs;
7998
- if (exprs) linked = mapDownstreamReason(binding.section.program, linked, exprs);
7999
- }
8000
- reason = mergeSerializeReasons(reason, linked);
8001
- });
8002
- }
8003
- if (reason) cache.set(extra, reason);
8004
- }
8005
- return reason;
8145
+ const UNSERIALIZED = {
8146
+ reason: void 0,
8147
+ reads: void 0
8148
+ };
8149
+ const FORCED_SERIALIZATION = {
8150
+ reason: FORCED,
8151
+ reads: void 0
8152
+ };
8153
+ const extraSerialization = createCyclicMemo(computeExtraSerialization, UNSERIALIZED);
8154
+ const bindingSerialization = createCyclicPathMemo(computeBindingSerialization, UNSERIALIZED);
8155
+ function getAllSerializeReasonsForBinding(binding, properties) {
8156
+ return serializationForBinding(binding, properties).reason;
8157
+ }
8158
+ function getRegisterReasonForExtra(extra) {
8159
+ const { reason, reads } = serializationForExtra(extra);
8160
+ return some(reads, isDynamicTagInput) ? FORCED : reason;
8161
+ }
8162
+ function isDynamicTagInput(read) {
8163
+ return !!read.dynamicTagInput;
8164
+ }
8165
+ function serializationForExtra(extra) {
8166
+ if (extra.isEffect) return FORCED_SERIALIZATION;
8167
+ const serialization = extraSerialization(extra);
8168
+ const reads = isReferencedExtra(extra) ? addUnique(serialization.reads, extra) : serialization.reads;
8169
+ return reads === serialization.reads ? serialization : {
8170
+ reason: serialization.reason,
8171
+ reads
8172
+ };
8006
8173
  }
8007
- function getAllSerializeReasonsForBinding(binding, properties, register) {
8008
- const cache = register ? registerReasonCache : serializeReasonCache;
8009
- let reason = cache.get(binding);
8010
- if (reason === void 0) {
8011
- reason = getSerializeReason(binding.section, binding);
8012
- if (reason !== true) {
8013
- cache.set(binding, reason || false);
8014
- if (properties !== true && binding.upstreamAlias) reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(binding.upstreamAlias, binding.property, register));
8015
- if (reason !== true) {
8016
- for (const expr of binding.reads) {
8017
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForExtra(expr, register));
8018
- if (reason === true) break;
8019
- }
8020
- if (reason !== true) for (const alias of binding.aliases) {
8021
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(alias, properties, register));
8022
- if (reason === true) break;
8023
- }
8024
- }
8174
+ function serializationForBinding(binding, properties) {
8175
+ return bindingSerialization(binding, properties);
8176
+ }
8177
+ function computeExtraSerialization(extra) {
8178
+ return readSerialization(extra, void 0);
8179
+ }
8180
+ function readSerialization(extra, part) {
8181
+ if (extra === (0, _marko_compiler_babel_utils.getProgram)().node.extra?.section.returnValueExpr) return FORCED_SERIALIZATION;
8182
+ let serialization = UNSERIALIZED;
8183
+ forEach(extra.downstream, (binding) => {
8184
+ if (!isPartOf(binding, part)) serialization = mergeSerialization(serialization, downstreamSerialization(extra, binding));
8185
+ });
8186
+ return serialization;
8187
+ }
8188
+ function downstreamSerialization(extra, binding) {
8189
+ const linked = serializationForBinding(binding, true);
8190
+ const exprs = extra.downstreamExprs;
8191
+ return linked.reason && exprs ? {
8192
+ reason: mapParamReason(binding.section.program, linked.reason, exprs, true),
8193
+ reads: linked.reads
8194
+ } : linked;
8195
+ }
8196
+ function isPartOf(binding, value) {
8197
+ return !!value && binding.upstreamAlias === value && !isDirectAlias(binding);
8198
+ }
8199
+ function computeBindingSerialization(binding, properties) {
8200
+ let reason = getSerializeReason(binding.section, binding);
8201
+ let serialization = reason ? {
8202
+ reason,
8203
+ reads: void 0
8204
+ } : UNSERIALIZED;
8205
+ const upstream = binding.upstreamAlias;
8206
+ if (properties !== true && upstream && !upstream.noSerialize && !propsUtil.has(upstream.noSerializeProperties, binding.property)) serialization = mergeSerialization(serialization, serializationForBinding(upstream, properties === void 0 ? binding.property : concat(binding.property, properties)));
8207
+ for (const expr of binding.reads) {
8208
+ if (expr.isEffect) {
8209
+ serialization = mergeSerialization(serialization, FORCED_SERIALIZATION);
8210
+ continue;
8025
8211
  }
8026
- if (reason) cache.set(binding, reason);
8212
+ const reads = addUnique(serialization.reads, expr);
8213
+ if (reads !== serialization.reads) serialization = {
8214
+ reason: serialization.reason,
8215
+ reads
8216
+ };
8217
+ serialization = mergeSerialization(serialization, readSerialization(expr, binding));
8027
8218
  }
8028
- if (reason === false) reason = void 0;
8029
- if (properties !== void 0) if (properties === true) {
8030
- if (reason !== true) for (const propBinding of binding.propertyAliases.values()) {
8031
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(propBinding, true, register));
8032
- if (reason === true) break;
8033
- }
8034
- } else {
8035
- let property;
8036
- let rest;
8037
- if (Array.isArray(properties)) {
8038
- property = properties[0];
8039
- rest = properties.length === 2 ? properties[1] : properties.slice(1);
8040
- } else property = properties;
8041
- if (includes(binding.excludeProperties, property)) reason = void 0;
8042
- else {
8043
- const propBinding = binding.propertyAliases.get(property);
8044
- if (propBinding) reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(propBinding, rest, register));
8045
- if (reason !== true) for (const alias of binding.aliases) {
8046
- const propBinding = alias.propertyAliases.get(property);
8047
- if (propBinding) {
8048
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(propBinding, rest, register));
8049
- if (reason === true) break;
8050
- }
8051
- }
8052
- }
8219
+ for (const alias of binding.aliases) serialization = mergeSerialization(serialization, serializationForBinding(alias, properties));
8220
+ if (properties === void 0) return serialization;
8221
+ if (properties === true) {
8222
+ for (const propBinding of binding.propertyAliases.values()) serialization = mergeSerialization(serialization, serializationForBinding(propBinding, true));
8223
+ return serialization;
8053
8224
  }
8054
- return reason;
8225
+ const property = first(properties);
8226
+ if (propsUtil.has(binding.excludeProperties, property)) return UNSERIALIZED;
8227
+ const propBinding = binding.propertyAliases.get(property);
8228
+ if (propBinding) serialization = mergeSerialization(serialization, serializationForBinding(propBinding, rest(properties)));
8229
+ for (const alias of binding.aliases) {
8230
+ const propBinding = alias.propertyAliases.get(property);
8231
+ if (propBinding) serialization = mergeSerialization(serialization, serializationForBinding(propBinding, rest(properties)));
8232
+ }
8233
+ return serialization;
8234
+ }
8235
+ function mergeSerialization(a, b) {
8236
+ if (a === UNSERIALIZED) return b;
8237
+ if (b === UNSERIALIZED) return a;
8238
+ const reason = mergeSources(a.reason, b.reason);
8239
+ let reads = a.reads;
8240
+ forEach(b.reads, (read) => {
8241
+ reads = addUnique(reads, read);
8242
+ });
8243
+ if (reason === a.reason && reads === a.reads) return a;
8244
+ if (reason === b.reason && reads === b.reads) return b;
8245
+ return {
8246
+ reason,
8247
+ reads
8248
+ };
8055
8249
  }
8056
8250
  function isPureSpreadResolved(binding) {
8057
- for (const read of binding.reads) if (!read.nativeTagSpread || read.nativeTagSpreadMerged) return false;
8058
- for (const alias of binding.aliases) if (!isPureSpreadResolved(alias)) return false;
8059
- return true;
8251
+ return !someAlias(binding, hasReadBeyondSpreading, void 0);
8060
8252
  }
8061
- function hasAnyMemberAccess(binding) {
8062
- if (binding.propertyAliases.size) return true;
8063
- for (const alias of binding.aliases) if (hasAnyMemberAccess(alias)) return true;
8253
+ function hasReadBeyondSpreading(binding) {
8254
+ for (const read of binding.reads) if (!read.nativeTagSpread || read.nativeTagSpreadMerged) return true;
8064
8255
  return false;
8065
8256
  }
8257
+ function hasAnyMemberAccess(binding) {
8258
+ return someAlias(binding, hasPropertyAliases, void 0);
8259
+ }
8260
+ function hasPropertyAliases(binding) {
8261
+ return binding.propertyAliases.size > 0;
8262
+ }
8066
8263
  function isPropertyMemberAccessed(binding, property) {
8067
- if (binding.propertyAliases.has(property)) return true;
8068
- for (const alias of binding.aliases) if (isPropertyMemberAccessed(alias, property)) return true;
8069
- return false;
8264
+ return someAlias(binding, hasPropertyAlias, property);
8265
+ }
8266
+ function hasPropertyAlias(binding, property) {
8267
+ return binding.propertyAliases.has(property);
8070
8268
  }
8071
8269
  function addNumericPropertiesUntil(props, len) {
8072
8270
  let result = props;
@@ -8074,11 +8272,7 @@ function addNumericPropertiesUntil(props, len) {
8074
8272
  return result;
8075
8273
  }
8076
8274
  function setReadsOwner(from, to) {
8077
- let cur = from;
8078
- while (cur !== to && cur.parent) {
8079
- cur.readsOwner = true;
8080
- cur = cur.parent;
8081
- }
8275
+ for (const section of ancestorSections(from, to)) section.readsOwner = true;
8082
8276
  }
8083
8277
  function mapParamReasonToExpr(exprs, reason) {
8084
8278
  if (reason) {
@@ -8109,7 +8303,7 @@ function mapParamBindingToExpr(exprs, binding) {
8109
8303
  if (isWholeAlias) {
8110
8304
  let result = curExpr.value;
8111
8305
  if (curExpr.known) {
8112
- for (const key in curExpr.known) if (!includes(binding.excludeProperties, key)) result = concat(result, curExpr.known[key].value);
8306
+ for (const key in curExpr.known) if (!propsUtil.has(binding.excludeProperties, key)) result = concat(result, curExpr.known[key].value);
8113
8307
  }
8114
8308
  return result;
8115
8309
  }
@@ -8117,7 +8311,6 @@ function mapParamBindingToExpr(exprs, binding) {
8117
8311
  }
8118
8312
  //#endregion
8119
8313
  //#region src/translator/core/await.ts
8120
- const kDOMBinding$2 = Symbol("await tag dom binding");
8121
8314
  var await_default = {
8122
8315
  analyze(tag) {
8123
8316
  (0, _marko_compiler_babel_utils.assertNoVar)(tag);
@@ -8129,7 +8322,7 @@ var await_default = {
8129
8322
  const section = getOrCreateSection(tag);
8130
8323
  const [valueAttr] = node.attributes;
8131
8324
  const tagExtra = tag.node.extra ??= {};
8132
- tagExtra[kDOMBinding$2] = createBinding("#text", 0, section);
8325
+ tagExtra.nodeBinding = createBinding("#text", 0, section);
8133
8326
  if (!valueAttr) throw tag.get("name").buildCodeFrameError("The [`<await>` tag](https://markojs.com/docs/reference/core-tag#await) requires a [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
8134
8327
  if (node.attributes.length > 1 || !_marko_compiler.types.isMarkoAttribute(valueAttr) || valueAttr.name !== "value") throw tag.get("name").buildCodeFrameError("The [`<await>` tag](https://markojs.com/docs/reference/core-tag#await) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
8135
8328
  if (!node.body.body.length) throw tag.get("name").buildCodeFrameError("The [`<await>` tag](https://markojs.com/docs/reference/core-tag#await) requires [content](https://markojs.com/docs/reference/language#tag-content).");
@@ -8157,7 +8350,7 @@ var await_default = {
8157
8350
  exit(tag) {
8158
8351
  const { node } = tag;
8159
8352
  const [valueAttr] = node.attributes;
8160
- const nodeRef = node.extra[kDOMBinding$2];
8353
+ const nodeRef = node.extra.nodeBinding;
8161
8354
  const tagBody = tag.get("body");
8162
8355
  const section = getSection(tag);
8163
8356
  const bodySection = getSectionForBody(tagBody);
@@ -8177,7 +8370,7 @@ var await_default = {
8177
8370
  },
8178
8371
  exit(tag) {
8179
8372
  const { node } = tag;
8180
- const nodeRef = node.extra[kDOMBinding$2];
8373
+ const nodeRef = node.extra.nodeBinding;
8181
8374
  const section = getSection(tag);
8182
8375
  const bodySection = getSectionForBody(tag.get("body"));
8183
8376
  const signal = getSignal(section, nodeRef, "await_promise");
@@ -8260,7 +8453,7 @@ var const_default = {
8260
8453
  if (node.attributes.length > 1 || !_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value") throw tag.get("name").buildCodeFrameError("The [`<const>` tag](https://markojs.com/docs/reference/core-tag#const) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
8261
8454
  const valueExtra = evaluate(valueAttr.value);
8262
8455
  const upstreamAlias = _marko_compiler.types.isIdentifier(valueAttr.value) ? tag.scope.getBinding(valueAttr.value.name)?.identifier.extra?.binding : void 0;
8263
- if (upstreamAlias) dropNodes(valueAttr.value);
8456
+ if (upstreamAlias) untrackNode(valueAttr.value);
8264
8457
  const binding = trackVarReferences(tag, 5, upstreamAlias);
8265
8458
  if (binding) {
8266
8459
  assertNoTagVarMutation(tag);
@@ -8275,14 +8468,14 @@ var const_default = {
8275
8468
  const { node } = tag;
8276
8469
  const [valueAttr] = node.attributes;
8277
8470
  const { value } = valueAttr;
8471
+ const varBinding = node.var.extra?.binding;
8278
8472
  if (isOutputDOM()) {
8279
8473
  const section = getSection(tag);
8280
- const varBinding = node.var.extra?.binding;
8281
- if (varBinding && !varBinding.upstreamAlias) {
8474
+ if (varBinding && !varBinding.upstreamAlias && !value.extra?.pruned) {
8282
8475
  const derivation = initValue(varBinding);
8283
8476
  addValue(section, value.extra?.referencedBindings, derivation, value);
8284
8477
  }
8285
- } else translateVar(tag, value);
8478
+ } else if (!varBinding?.pruned || !value.extra?.pruned) translateVar(tag, value);
8286
8479
  tag.remove();
8287
8480
  } },
8288
8481
  parseOptions: { openTagOnly: true },
@@ -8489,7 +8682,7 @@ var html_comment_default = {
8489
8682
  const tagExtra = mergeReferences(tagSection, tag.node, referenceNodes);
8490
8683
  nodeBinding = tagExtra[kNodeBinding$1] = createBinding("#comment", 0, tagSection, void 0, void 0, void 0, void 0, !!tagVar);
8491
8684
  trackDomVarReferences(tag, nodeBinding);
8492
- if (tagVar) addSerializeExpr(tagSection, true, nodeBinding);
8685
+ if (tagVar) addSerializeReason(tagSection, FORCED, nodeBinding);
8493
8686
  addSerializeExpr(tagSection, tagExtra, nodeBinding);
8494
8687
  }
8495
8688
  const write = writeTo(tag);
@@ -8675,11 +8868,20 @@ var let_default = {
8675
8868
  if (valueChangeAttr) {
8676
8869
  binding.reserveSize = 1;
8677
8870
  setBindingDownstream(binding, tagExtra);
8678
- if (binding.assignmentSections) addSerializeReason(tagSection, true, binding, getAccessorPrefix().TagVariableChange);
8679
- } else setBindingDownstream(binding, false);
8871
+ onFinalizeReferences(() => {
8872
+ if (binding.assignments) addSerializeReason(tagSection, FORCED, binding, getAccessorPrefix().TagVariableChange);
8873
+ });
8874
+ } else {
8875
+ tagExtra.pure = !valueAttr || evaluate(valueAttr.value).pure;
8876
+ setBindingValueExprs(binding, tagExtra);
8877
+ }
8680
8878
  },
8681
8879
  translate: { exit(tag) {
8682
8880
  const { node } = tag;
8881
+ if (node.extra?.pruned) {
8882
+ tag.remove();
8883
+ return;
8884
+ }
8683
8885
  const tagVar = node.var;
8684
8886
  const valueAttr = node.attributes.find((attr) => _marko_compiler.types.isMarkoAttribute(attr) && (attr.default || attr.name === "value")) ?? _marko_compiler.types.markoAttribute("value", _marko_compiler.types.identifier("undefined"));
8685
8887
  const valueChangeAttr = node.attributes.find((attr) => _marko_compiler.types.isMarkoAttribute(attr) && attr.name === "valueChange");
@@ -9170,6 +9372,7 @@ var style_default = {
9170
9372
  analyzeDynamicStyle(tag, names);
9171
9373
  addSetupStatement(getOrCreateSection(tag));
9172
9374
  visit(tag, 32);
9375
+ enterShallow(tag);
9173
9376
  writeTo(tag)`<style></style>`;
9174
9377
  }
9175
9378
  },
@@ -9339,7 +9542,6 @@ function getStyleImportPath(file, node, names) {
9339
9542
  }
9340
9543
  //#endregion
9341
9544
  //#region src/translator/core/try.ts
9342
- const kDOMBinding$1 = Symbol("try tag dom binding");
9343
9545
  var try_default = {
9344
9546
  analyze(tag) {
9345
9547
  (0, _marko_compiler_babel_utils.assertNoVar)(tag);
@@ -9355,7 +9557,7 @@ var try_default = {
9355
9557
  }
9356
9558
  const section = getOrCreateSection(tag);
9357
9559
  const tagExtra = mergeReferences(section, tag.node, getAllTagReferenceNodes(tag.node));
9358
- tagExtra[kDOMBinding$1] = createBinding("#text", 0, section);
9560
+ tagExtra.nodeBinding = createBinding("#text", 0, section);
9359
9561
  if (!tag.node.body.body.length) throw tag.get("name").buildCodeFrameError("The [`<try>` tag](https://markojs.com/docs/reference/core-tag#try) requires [body content](https://markojs.com/docs/reference/language#tag-content).");
9360
9562
  const bodySection = startSection(tag.get("body"));
9361
9563
  if (bodySection) {
@@ -9382,7 +9584,7 @@ var try_default = {
9382
9584
  const tagExtra = node.extra;
9383
9585
  const tagBody = tag.get("body");
9384
9586
  const translatedAttrs = translateAttrs(tag);
9385
- const nodeRef = tagExtra[kDOMBinding$1];
9587
+ const nodeRef = tagExtra.nodeBinding;
9386
9588
  const contentProp = getTranslatedBodyContentProperty(translatedAttrs.properties);
9387
9589
  if (contentProp) translatedAttrs.properties.splice(translatedAttrs.properties.indexOf(contentProp), 1);
9388
9590
  flushInto(tag);
@@ -9400,7 +9602,7 @@ var try_default = {
9400
9602
  exit(tag) {
9401
9603
  const { node } = tag;
9402
9604
  const tagExtra = node.extra;
9403
- const nodeRef = tagExtra[kDOMBinding$1];
9605
+ const nodeRef = tagExtra.nodeBinding;
9404
9606
  const referencedBindings = tagExtra.referencedBindings;
9405
9607
  const translatedAttrs = translateAttrs(tag);
9406
9608
  const contentProp = getTranslatedBodyContentProperty(translatedAttrs.properties);
@@ -9849,8 +10051,8 @@ var referenced_identifier_default = {
9849
10051
  const section = getOrCreateSection(identifier);
9850
10052
  section.hasAbortSignal = true;
9851
10053
  setReferencesScope(identifier);
9852
- const exprRoot = getExprRoot(identifier);
9853
- const rootExtra = exprRoot.node.extra ??= { section };
10054
+ const rootExtra = getExprRoot(identifier).node.extra ??= { section };
10055
+ (identifier.node.extra ??= {}).exprRoot = rootExtra;
9854
10056
  if (rootExtra.abortId === void 0) rootExtra.abortId = section.abortSignalExprs++;
9855
10057
  }
9856
10058
  },
@@ -9869,12 +10071,12 @@ var referenced_identifier_default = {
9869
10071
  case "$signal": if (isOutputHTML()) identifier.replaceWith(_marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([_marko_compiler.types.throwStatement(_marko_compiler.types.newExpression(_marko_compiler.types.identifier("Error"), [_marko_compiler.types.stringLiteral("Cannot use $signal in a server render.")]))])), []));
9870
10072
  else {
9871
10073
  const section = getSection(identifier);
9872
- const exprRoot = getExprRoot(identifier);
9873
- const exprId = exprRoot.node.extra.abortId;
10074
+ const exprRoot = identifier.node.extra.exprRoot;
10075
+ const exprId = exprRoot.abortId;
9874
10076
  const resetEmitted = getAbortResetEmitted(section);
9875
10077
  if (!resetEmitted.has(exprRoot)) {
9876
10078
  resetEmitted.add(exprRoot);
9877
- addStatement("render", section, exprRoot.node.extra?.referencedBindings, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(importRuntime("$signalReset"), [scopeIdentifier, _marko_compiler.types.numericLiteral(exprId)])));
10079
+ addStatement("render", section, exprRoot.referencedBindings, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(importRuntime("$signalReset"), [scopeIdentifier, _marko_compiler.types.numericLiteral(exprId)])));
9878
10080
  }
9879
10081
  identifier.replaceWith(_marko_compiler.types.callExpression(importRuntime("$signal"), [scopeIdentifier, _marko_compiler.types.numericLiteral(exprId)]));
9880
10082
  }
@@ -10082,10 +10284,7 @@ function tagNotFoundError(tag) {
10082
10284
  const proseText = tagName && getProseText(tag);
10083
10285
  if (knownWrongTagHint) didYouMean = ` ${knownWrongTagHint}`;
10084
10286
  else if (proseText) didYouMean = ` If this line is meant to be text, prefix it with \`--\` (e.g. \`-- ${proseText}\`) or wrap it in an element such as \`<p>${proseText}</p>\`.`;
10085
- else if (tagName) {
10086
- const closestTag = (0, fastest_levenshtein.closest)(tagName, Object.keys((0, _marko_compiler_babel_utils.getTaglibLookup)((0, _marko_compiler_babel_utils.getFile)()).merged.tags));
10087
- if ((0, fastest_levenshtein.distance)(tagName, closestTag) < 4) didYouMean = ` Did you mean \`<${closestTag}>\`?`;
10088
- }
10287
+ else if (tagName) didYouMean = getSimilarTagHint(tagName);
10089
10288
  return tag.get("name").buildCodeFrameError(`Unable to find entry point for [custom tag](https://markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName ?? getStaticTagName(tag.node)}>\`.${didYouMean}`);
10090
10289
  }
10091
10290
  const wordReg = /^[A-Za-z]+$/;
@@ -10109,6 +10308,25 @@ function collectProseWords(node, tagName) {
10109
10308
  }
10110
10309
  return text;
10111
10310
  }
10311
+ function getSimilarTagHint(tagName) {
10312
+ const lookup = (0, _marko_compiler_babel_utils.getTaglibLookup)((0, _marko_compiler_babel_utils.getFile)());
10313
+ if (lookup.getTag(tagName)) return "";
10314
+ const lowerTagName = tagName.toLowerCase();
10315
+ let closestTag;
10316
+ let closestDistance = 4;
10317
+ for (const name in lookup.merged.tags) {
10318
+ const lengthDelta = Math.abs(name.length - tagName.length);
10319
+ if (lengthDelta < closestDistance) {
10320
+ if (!lengthDelta && name.toLowerCase() === lowerTagName) return ` Tag names are case-sensitive: did you mean \`<${name}>\`?`;
10321
+ const nameDistance = (0, fastest_levenshtein.distance)(tagName, name);
10322
+ if (nameDistance < closestDistance) {
10323
+ closestTag = name;
10324
+ closestDistance = nameDistance;
10325
+ }
10326
+ }
10327
+ }
10328
+ return closestTag ? ` Did you mean \`<${closestTag}>\`?` : "";
10329
+ }
10112
10330
  function buildLoadSetupVirtualModule(file, childFileName, childExports) {
10113
10331
  const parts = `${childExports.template}, ${childExports.walks}, ${childExports.setup}`;
10114
10332
  return getMarkoOpts().resolveVirtualDependency(file.opts.filename, {
@@ -10140,7 +10358,6 @@ function optionalValueToNode(value) {
10140
10358
  }
10141
10359
  //#endregion
10142
10360
  //#region src/translator/visitors/tag/dynamic-tag.ts
10143
- const kDOMBinding = Symbol("dynamic tag dom binding");
10144
10361
  const kChildOffsetScopeBinding = Symbol("custom tag scope offset");
10145
10362
  const importedDynamicTagResume = /* @__PURE__ */ new WeakSet();
10146
10363
  const importedDynamicTagVarResume = /* @__PURE__ */ new WeakSet();
@@ -10175,15 +10392,19 @@ var dynamic_tag_default = {
10175
10392
  if (inputNodes.length) tagExtra.dynamicTagInput = true;
10176
10393
  const tagBody = tag.get("body");
10177
10394
  const hasVar = !!tag.node.var;
10178
- const nodeBinding = tagExtra[kDOMBinding] = createBinding("#text", 0, tagSection);
10395
+ const nodeBinding = tagExtra.nodeBinding = createBinding("#text", 0, tagSection);
10179
10396
  if (hasVar || tag.node.attributes.some((attr) => _marko_compiler.types.isMarkoSpreadAttribute(attr) || isEventOrChangeHandler(attr.name))) (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
10180
10397
  if (hasVar) {
10181
10398
  trackVarReferences(tag, 5);
10182
10399
  tag.node.var.extra.binding.scopeOffset = tagExtra[kChildOffsetScopeBinding] = createBinding("#scopeOffset", 0, tagSection);
10183
10400
  }
10184
10401
  const bodySection = startSection(tagBody);
10402
+ if (bodySection) {
10403
+ bodySection.upstreamExpression = tagExtra;
10404
+ if (analyzeTagNameType(tag, true) === 1 && !node.arguments) setTagDownstream(tag, getDynamicTagInputBindings(tagExtra), { value: tagExtra });
10405
+ }
10185
10406
  trackParamsReferences(tagBody, 3);
10186
- if (hasVar) addSerializeExpr(tagSection, true, nodeBinding);
10407
+ if (hasVar) addSerializeReason(tagSection, FORCED, nodeBinding);
10187
10408
  addSerializeExpr(tagSection, tagExtra, nodeBinding);
10188
10409
  if (!hasVar && !node.arguments && !node.attributes.length && !node.body.body.length) tagExtra[kDirectContent] = true;
10189
10410
  if (tagExtra.featureType !== "class" || (0, _marko_compiler_babel_utils.getTagTemplate)(tag)) {
@@ -10218,7 +10439,7 @@ var dynamic_tag_default = {
10218
10439
  return;
10219
10440
  }
10220
10441
  const tagExtra = node.extra;
10221
- const nodeBinding = tagExtra[kDOMBinding];
10442
+ const nodeBinding = tagExtra.nodeBinding;
10222
10443
  const isClassAPI = tagExtra.featureType === "class";
10223
10444
  const tagsSerializeReason = getSerializeReason(tagSection, nodeBinding);
10224
10445
  const serializeReason = tagsSerializeReason;
@@ -10242,7 +10463,7 @@ var dynamic_tag_default = {
10242
10463
  ...preserveBoundary ? [_marko_compiler.types.stringLiteral("preserve")] : []
10243
10464
  ]) : void 0;
10244
10465
  if (isOutputHTML() ? serializeReason || classHydration : serializeReason) {
10245
- if (pushCompatRegistration(classId, registration ? _marko_compiler.types.markoScriptlet([_marko_compiler.types.expressionStatement(registration)], true) : _marko_compiler.types.expressionStatement(callRuntime("_resume", _marko_compiler.types.stringLiteral(classId), _marko_compiler.types.identifier(tagExpression.name)))) && registration) getCompatBoundaryCalls().set(classId, registration);
10466
+ if (pushCompatRegistration(classId, registration ? _marko_compiler.types.markoScriptlet([_marko_compiler.types.expressionStatement(registration)], true) : _marko_compiler.types.expressionStatement(registerRuntimeValue(classId, _marko_compiler.types.identifier(tagExpression.name)))) && registration) getCompatBoundaryCalls().set(classId, registration);
10246
10467
  }
10247
10468
  if (!preserveBoundary) {
10248
10469
  const emitted = getCompatBoundaryCalls().get(classId);
@@ -10338,6 +10559,15 @@ function enableDynamicTagResume(tag) {
10338
10559
  }
10339
10560
  }
10340
10561
  }
10562
+ function getDynamicTagInputBindings(tagExtra) {
10563
+ let inputBindings;
10564
+ for (const childExtra of tagExtra.tagNameTemplates || []) {
10565
+ if (childExtra.featureType === "class") return;
10566
+ const inputBinding = childExtra.domExports?.params?.props?.[0]?.binding;
10567
+ if (inputBinding) inputBindings = bindingUtil.add(inputBindings, inputBinding);
10568
+ }
10569
+ return inputBindings;
10570
+ }
10341
10571
  //#endregion
10342
10572
  //#region src/translator/visitors/tag/index.ts
10343
10573
  var tag_default = {
@@ -10818,7 +11048,9 @@ const taglibs = [[core_default.taglibId, {
10818
11048
  migrate: visitors.migrate
10819
11049
  }]];
10820
11050
  function getRuntimeEntryFiles(output, optimize) {
10821
- return [`${runtime_info_default.name}${optimize ? "" : "/debug"}/${output === "html" ? "html" : "dom"}`];
11051
+ const runtime = `${runtime_info_default.name}${optimize ? "" : "/debug"}`;
11052
+ if (output === "html") return [`${runtime}/html`];
11053
+ return [`${runtime}/dom`, ...domRuntimeFeatures.map((feature) => `${runtime}/dom/${feature}.feat`)];
10822
11054
  }
10823
11055
  //#endregion
10824
11056
  exports.analyze = analyze;