marko 6.3.50 → 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 +1893 -1658
  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;
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;
1732
1690
  }
1733
1691
  }
1734
- return exportNames.length ? exportNames : void 0;
1735
1692
  }
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;
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);
1743
+ }
1744
+ return section;
1745
+ }
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
+ }
1752
+ }
1753
+ function getSectionForBody(body) {
1754
+ return body.node.extra?.section;
1740
1755
  }
1741
- function getExportedName(specifier) {
1742
- const { exported } = specifier;
1743
- return exported.type === "Identifier" ? exported.name : exported.value;
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;
1744
1761
  }
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"));
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);
1747
1768
  }
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;
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;
1782
- }
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;
1787
- }
1788
- function getTagFromMarkoRoot(markoRoot) {
1789
- let cur = markoRoot;
1790
- do {
1791
- if (cur.isMarkoTag()) return cur;
1792
- cur = cur.parentPath;
1793
- } while (cur);
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;
1794
1859
  }
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)}`);
1860
+ function isSectionRegisterDynamic(section, registerReason) {
1861
+ const dynamicTagBinding = getDynamicTagNodeBinding(section);
1862
+ return !!dynamicTagBinding && registerReason !== true && isDynamicSerializeGuard(dynamicTagBinding.section, registerReason);
1801
1863
  }
1802
- function isMarkoAttribute(path) {
1803
- return path ? path.isMarkoAttribute() : false;
1864
+ function isSectionRegisterEager(section) {
1865
+ const registerReason = getSectionRegisterReasons(section);
1866
+ return !!registerReason && !isSectionRegisterDynamic(section, registerReason);
1804
1867
  }
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
- }
1868
+ function getDynamicTagNodeBinding(section) {
1869
+ const { upstreamExpression } = section;
1870
+ return upstreamExpression?.tagNameType === 0 ? upstreamExpression.nodeBinding : void 0;
1812
1871
  }
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
1823
- });
1872
+ function isImmediateOwner(section, binding) {
1873
+ return section.parent?.id === binding.section.id;
1824
1874
  }
1825
- function hasAnalyzeErrors() {
1826
- return getHasAnalyzeErrors();
1875
+ function isDirectClosure(section, closure) {
1876
+ return section.isBranch && isImmediateOwner(section, closure);
1827
1877
  }
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);
1878
+ function isDynamicClosure(section, closure) {
1879
+ return !isDirectClosure(section, closure);
1832
1880
  }
1833
- function isClientAssetImport(file, request) {
1834
- const { hydrateIncludeImports } = file.markoOpts;
1835
- return typeof hydrateIncludeImports === "function" ? hydrateIncludeImports(request) : !!hydrateIncludeImports?.test(request);
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;
1887
+ });
1888
+ return index;
1836
1889
  }
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);
1890
+ function getDirectClosures(section) {
1891
+ if (section.isBranch) return bindingUtil.filter(section.referencedClosures, (closure) => isImmediateOwner(section, closure));
1841
1892
  }
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;
1893
+ function isSameOrChildSection(section, other) {
1894
+ do
1895
+ if (other === section) return true;
1896
+ while (other = other.parent);
1855
1897
  return false;
1856
1898
  }
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
- }
1899
+ function getCommonSection(section, other) {
1900
+ let ancestor = section;
1901
+ if (other.depth < section.depth) {
1902
+ ancestor = other;
1903
+ other = section;
1884
1904
  }
1885
- if (binding.type === 2) binding.export ??= generateUid(binding.name);
1886
- if (isDirectContentBinding(binding)) binding.directContentExport ??= generateUid(`${binding.name}_direct`);
1887
- return props;
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");
1911
+ }
1912
+ function finalizeParamSerializeReasonGroups(section) {
1913
+ ensureReasonGroups(section.serializeReason);
1914
+ for (const reason of section.serializeReasons.values()) ensureReasonGroups(reason);
1915
+ }
1916
+ function ensureReasonGroups(reason) {
1917
+ if (isReasonDynamic(reason)) for (const [paramSection, params] of groupParamsBySection(reason.param)) ensureParamReasonGroup(paramSection, params);
1888
1918
  }
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;
1919
+ function ensureParamReasonGroup(section, reason) {
1920
+ const { paramReasonGroups } = section;
1921
+ if (paramReasonGroups) {
1922
+ const found = findSorted(compareParamGroups, paramReasonGroups, { reason });
1923
+ if (found) return found;
1924
+ }
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) {
@@ -2362,147 +2516,49 @@ function translateByTarget({ html, dom }) {
2362
2516
  //#region src/translator/util/normalize-string-expression.ts
2363
2517
  function normalizeStringExpression(parts, useIife) {
2364
2518
  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);
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)) {
@@ -3283,11 +3311,14 @@ function writeHTMLResumeStatements(path) {
3283
3311
  }
3284
3312
  const closureIndex = getDynamicClosureIndex(closure, section);
3285
3313
  if (closureIndex) setBindingSerializedValue(section, closure, _marko_compiler.types.numericLiteral(closureIndex), getAccessorPrefix().ClosureSignalIndex);
3286
- if (underTryPlaceholder(section)) {
3314
+ const closureScopesReason = getSerializeReason(closure.section, closure, getAccessorPrefix().ClosureScopes);
3315
+ if (underTryPlaceholder(section) && closureResumes(closure)) {
3287
3316
  const reason = getSerializeReason(section);
3288
- if (reason) getHTMLSectionStatements(section).push(_marko_compiler.types.expressionStatement(getExprIfSerialized(section, reason, callRuntime("_script", getScopeIdIdentifier(section), _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")), markerSerializeArg))));
3317
+ if (reason) {
3318
+ const script = getExprIfSerialized(section, reason, callRuntime("_script", getScopeIdIdentifier(section), _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")), markerSerializeArg));
3319
+ getHTMLSectionStatements(section).push(_marko_compiler.types.expressionStatement(isReasonDynamic(closureScopesReason) && !isSameReason(closureScopesReason, reason) ? getExprIfSerialized(closure.section, closureScopesReason, script) : script));
3320
+ }
3289
3321
  } else {
3290
- const closureScopesReason = getSerializeReason(closure.section, closure, getAccessorPrefix().ClosureScopes);
3291
3322
  const subscribeArg = isReasonDynamic(closureScopesReason) && !isSameReason(closureScopesReason, sectionSerializeReason) ? getExprIfSerialized(closure.section, closureScopesReason, identifier) : identifier;
3292
3323
  addWriteScopeBuilder(section, (expr) => callRuntime("_subscribe", subscribeArg, expr));
3293
3324
  }
@@ -3354,7 +3385,7 @@ function writeHTMLResumeStatements(path) {
3354
3385
  }
3355
3386
  body.push(_marko_compiler.types.expressionStatement(getExprIfSerialized(section, sectionSerializeReason, writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs))));
3356
3387
  }
3357
- 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) {
3358
3389
  const call = callRuntime("_resume_branch", scopeIdIdentifier);
3359
3390
  const link = section.hasAbortSignal ? call : getExprIfSerialized(section, sectionSerializeReason, call);
3360
3391
  if (link) body.push(_marko_compiler.types.expressionStatement(markerSerializeArg.type === "NumericLiteral" ? link : _marko_compiler.types.logicalExpression("||", markerSerializeArg, link)));
@@ -3381,7 +3412,8 @@ function replaceBindingReadNode$1(node, signal) {
3381
3412
  case "Identifier":
3382
3413
  case "MemberExpression":
3383
3414
  case "OptionalMemberExpression": return getReadReplacement(node, signal);
3384
- case "CallExpression": {
3415
+ case "CallExpression":
3416
+ case "OptionalCallExpression": {
3385
3417
  const { extra } = node.callee;
3386
3418
  if (extra?.read) {
3387
3419
  const { binding, getter } = extra.read;
@@ -3539,6 +3571,12 @@ function getRegisteredFnExpression$1(node) {
3539
3571
  else return _marko_compiler.types.identifier(id);
3540
3572
  }
3541
3573
  }
3574
+ function appendBindingKey(name, binding) {
3575
+ return `${name}_${binding.name}#${binding.id}`;
3576
+ }
3577
+ function isLetBinding(binding) {
3578
+ return binding.type === 1;
3579
+ }
3542
3580
  //#endregion
3543
3581
  //#region src/translator/util/import-reference.ts
3544
3582
  function importOrSelfReferenceName(file, request, name, nameHint) {
@@ -3819,13 +3857,15 @@ var dom_default = { translate: {
3819
3857
  tagParamsIdentifier
3820
3858
  ]);
3821
3859
  else {
3822
- 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([
3823
3862
  writes,
3824
3863
  walks,
3825
3864
  setupIdentifier,
3826
3865
  tagParamsIdentifier,
3827
3866
  childSection.hoisted || childSection.isHoistThrough ? getSectionInstancesAccessorLiteral(childSection) : void 0
3828
3867
  ]));
3868
+ if (registerReason && isSectionRegisterDynamic(childSection, registerReason)) renderer = _marko_compiler.types.addComment(renderer, "leading", "@__PURE__");
3829
3869
  if (childSection.referencedLocalClosures) {
3830
3870
  const objProps = [];
3831
3871
  forEach(childSection.referencedLocalClosures, (closure) => {
@@ -3938,7 +3978,8 @@ function replaceBindingReadNode(node) {
3938
3978
  if (extra && !(extra.read && !extra.read.binding.declared || extra.binding && !extra.binding.declared)) return getReadReplacement(node);
3939
3979
  break;
3940
3980
  }
3941
- case "CallExpression": {
3981
+ case "CallExpression":
3982
+ case "OptionalCallExpression": {
3942
3983
  const read = node.callee.extra?.read;
3943
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")]);
3944
3985
  break;
@@ -4122,6 +4163,8 @@ var for_default = {
4122
4163
  const keyAttr = tag.node.attributes.find((attr) => attr.type === "MarkoAttribute" && attr.name === "key");
4123
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`"}.`);
4124
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.`);
4125
4168
  if (isAttrTag) return;
4126
4169
  const byAttr = getKnownAttrValues(tag.node).by;
4127
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}>\`.`);
@@ -4532,8 +4575,9 @@ function translateAttrs(tag, propTree = true, skip, statements = [], contentKey
4532
4575
  for (let i = attributes.length; i--;) {
4533
4576
  const attr = attributes[i];
4534
4577
  const { value } = attr;
4535
- if (_marko_compiler.types.isMarkoSpreadAttribute(attr)) attrProperties.push(_marko_compiler.types.spreadElement(value));
4536
- 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)) {
4537
4581
  seen.add(attr.name);
4538
4582
  attrProperties.push(toObjectProperty(attr.name, value));
4539
4583
  }
@@ -4758,9 +4802,7 @@ var native_tag_default = {
4758
4802
  const spreadBinding = node.extra?.spreadFrom;
4759
4803
  if (spreadBinding) {
4760
4804
  spreadBinding.noSerialize = true;
4761
- if (carveProperties) {
4762
- for (const property of carveProperties) if (!includes(spreadBinding.noSerializeProperties, property)) spreadBinding.noSerializeProperties = push(spreadBinding.noSerializeProperties, property);
4763
- }
4805
+ if (carveProperties) for (const property of carveProperties) spreadBinding.noSerializeProperties = propsUtil.add(spreadBinding.noSerializeProperties, property);
4764
4806
  }
4765
4807
  }
4766
4808
  }
@@ -4775,7 +4817,7 @@ var native_tag_default = {
4775
4817
  const attr = seen[name];
4776
4818
  if (isEventHandler(name) || name === "content" || !evaluate(attr.value).confident) addSetupExpr(tagSection, attr.value);
4777
4819
  }
4778
- addSerializeExpr(tagSection, !!(node.var || hasEventHandlers), nodeBinding);
4820
+ if (node.var || hasEventHandlers) addSerializeReason(tagSection, FORCED, nodeBinding);
4779
4821
  trackDomVarReferences(tag, nodeBinding);
4780
4822
  addSerializeExpr(tagSection, push(exprExtras, tagExtra), nodeBinding);
4781
4823
  }
@@ -5577,7 +5619,7 @@ const IfTag = {
5577
5619
  if (branchBodySection) {
5578
5620
  const branchSerializeReason = getSerializeReason(branchBodySection, kBranchSerializeReason);
5579
5621
  if (branchSerializeReason) {
5580
- if (branchSerializeReasons !== true) branchSerializeReasons = branchSerializeReason === true || branchSerializeReason.state ? true : sourcesUtil.add(branchSerializeReasons, branchSerializeReason);
5622
+ branchSerializeReasons = sourcesUtil.add(branchSerializeReasons, branchSerializeReason);
5581
5623
  bodyStatements.push(_marko_compiler.types.returnStatement(_marko_compiler.types.numericLiteral(i)));
5582
5624
  }
5583
5625
  }
@@ -6068,7 +6110,7 @@ var program_default = {
6068
6110
  if (paramsBinding && !paramsBinding.pruned) programExtra.domExports.params = getBindingPropTree(paramsBinding);
6069
6111
  const section = programExtra.section;
6070
6112
  forEachSection((childSection) => {
6071
- 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));
6072
6114
  });
6073
6115
  if (!section.hoistedTo && !sectionHasSetupStatements(section)) programExtra.domExports.setupEmpty = true;
6074
6116
  }
@@ -6142,6 +6184,48 @@ var program_default = {
6142
6184
  }
6143
6185
  };
6144
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
6145
6229
  //#region src/translator/util/set-tag-sections-downstream.ts
6146
6230
  const [getTagDownstreams] = createSectionState("tag-downstreams", () => /* @__PURE__ */ new Map());
6147
6231
  function setTagDownstream(tag, binding, exprs) {
@@ -6157,14 +6241,13 @@ function crawlSectionsAndSetBinding(tag, downstreamTag, binding, exprs, properti
6157
6241
  if (!skip) {
6158
6242
  const contentSection = getSectionForBody(tag.get("body"));
6159
6243
  if (contentSection) {
6160
- let target = binding;
6161
- forEach(properties, (property) => {
6162
- 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")));
6163
6247
  });
6164
- const serialized = !(target && (target.noSerialize || includes(target.noSerializeProperties, "content")));
6165
6248
  contentSection.downstream = {
6166
6249
  tag: downstreamTag,
6167
- binding: serialized ? binding : void 0,
6250
+ binding: serialized,
6168
6251
  properties: serialized ? concat(properties, "content") : void 0,
6169
6252
  exprs: serialized ? exprs : void 0
6170
6253
  };
@@ -6190,7 +6273,7 @@ function translateVar(tag, initialValue, kind = "const", statements) {
6190
6273
  if (!idExtra) return;
6191
6274
  const binding = idExtra.binding;
6192
6275
  if (!binding?.upstreamAlias) return;
6193
- if (binding.assignmentSections && binding.property !== void 0) {
6276
+ if (binding.assignments && binding.property !== void 0) {
6194
6277
  const changeName = binding.property + "Change";
6195
6278
  const changeBinding = binding.upstreamAlias.propertyAliases.get(changeName);
6196
6279
  if (changeBinding && changeName !== changeBinding.name) {
@@ -6250,14 +6333,24 @@ function knownTagAnalyze(tag, contentSection, propTree) {
6250
6333
  if (varBinding) {
6251
6334
  addSetupStatement(section);
6252
6335
  const mutatesTagVar = !!(tag.node.var.type === "Identifier" && tag.scope.getBinding(tag.node.var.name)?.constantViolations.length);
6253
- 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));
6254
6337
  varBinding.scopeOffset = tagExtra[kChildOffsetScopeBinding$1] = createBinding("#scopeOffset", 0, section);
6255
6338
  setBindingDownstream(varBinding, varExpr);
6256
- if (mutatesTagVar) addSerializeExpr(section, true, childScopeBinding);
6257
- addSerializeExpr(section, varExpr, childScopeBinding);
6339
+ if (mutatesTagVar || varExpr === true) addSerializeReason(section, FORCED, childScopeBinding);
6340
+ if (varExpr !== true) addSerializeExpr(section, varExpr, childScopeBinding);
6258
6341
  }
6259
6342
  addSerializeExpr(section, fromIter(attrExprs), childScopeBinding);
6260
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
+ }
6261
6354
  function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6262
6355
  const tagBody = tag.get("body");
6263
6356
  const { node } = tag;
@@ -6281,39 +6374,20 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6281
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"))));
6282
6375
  }
6283
6376
  if (contentSection.paramReasonGroups) {
6284
- let childSerializeReasonExpr;
6285
- if (contentSection.paramReasonGroups.length === 1) {
6286
- const [group] = contentSection.paramReasonGroups;
6377
+ const childSerializeReasonExpr = buildGroupMask(contentSection.paramReasonGroups.map((group) => {
6287
6378
  const reason = getSerializeReason(section, childScopeBinding, group.id);
6288
- childSerializeReasonExpr = reason && getSerializeGuard(section, reason, false);
6289
- } else {
6290
- const props = [];
6291
- let bitmask = 0;
6292
- let bitmaskNames = "";
6293
- let hasDynamicReasons = false;
6294
- let hasSkippedReasons = false;
6295
- for (let i = 0; i < contentSection.paramReasonGroups.length; i++) {
6296
- const group = contentSection.paramReasonGroups[i];
6297
- const reason = getSerializeReason(section, childScopeBinding, group.id);
6298
- if (reason) {
6299
- hasDynamicReasons ||= reason !== true && !reason.state;
6300
- const guard = getSerializeGuard(section, reason, false);
6301
- if (bitmask >= 0) if (guard.type === "NumericLiteral" && guard.value === 1 && i < 30) {
6302
- bitmask |= 1 << i + 1;
6303
- const names = getDebugNames(group.reason);
6304
- if (names) bitmaskNames += bitmaskNames ? ` | ${names}` : names;
6305
- } else bitmask = -1;
6306
- props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), getDebugNames(group.reason)), guard));
6307
- } else hasSkippedReasons = true;
6308
- }
6309
- 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);
6310
- }
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
+ }));
6311
6385
  if (childSerializeReasonExpr) tag.insertBefore(_marko_compiler.types.expressionStatement(callRuntime("_set_serialize_reason", childSerializeReasonExpr)));
6312
6386
  }
6313
6387
  const getArgs = () => {
6314
- let renderArgs = [];
6315
- if (tag.node.arguments) renderArgs = [...renderArgs, ...tag.node.arguments];
6316
- 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));
6317
6391
  return renderArgs;
6318
6392
  };
6319
6393
  if (tagVar) {
@@ -6503,12 +6577,12 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs, rootE
6503
6577
  addSetupExpr(section, attr.value);
6504
6578
  setBindingDownstream(templateExportAttr.binding, attrExtra, rootExprs);
6505
6579
  if (getRootSection(templateExportAttr.binding.section) !== (0, _marko_compiler_babel_utils.getProgram)().node.extra.section && isInvokeOnlyBinding(templateExportAttr.binding)) attrExtra.invokeOnly = true;
6506
- 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);
6507
6581
  }
6508
6582
  } else if (spreadReferenceNodes) spreadReferenceNodes.push(attr.value);
6509
6583
  else {
6510
6584
  knownSpread = hasAllKnownProps(propTree) ? getSingleKnownSpread(attributes) : void 0;
6511
- if (knownSpread) dropNodes(attr.value);
6585
+ if (knownSpread) untrackNode(attr.value);
6512
6586
  else (spreadReferenceNodes = restReferenceNodes || []).push(attr.value);
6513
6587
  }
6514
6588
  }
@@ -6541,7 +6615,7 @@ function getSingleKnownSpread(attributes) {
6541
6615
  let extra;
6542
6616
  for (let i = attributes.length; i--;) {
6543
6617
  const attr = attributes[i];
6544
- 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;
6545
6619
  }
6546
6620
  if (binding) return {
6547
6621
  extra,
@@ -6554,8 +6628,9 @@ function writeParamsToSignals(tag, propTree, importAlias, info) {
6554
6628
  const tagInputIdentifier = info.getBindingIdentifier(propTree.binding, `${importAlias}_params`);
6555
6629
  const translatedAttrs = translateAttrs(tag);
6556
6630
  if (translatedAttrs.statements.length) addStatement("render", info.tagSection, referencedBindings, translatedAttrs.statements);
6557
- const renderParams = tag.node.arguments ? [...tag.node.arguments] : [];
6558
- 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));
6559
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)])));
6560
6635
  return;
6561
6636
  }
@@ -6783,10 +6858,17 @@ function getRootSection(section) {
6783
6858
  //#endregion
6784
6859
  //#region src/translator/util/references.ts
6785
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
+ };
6786
6867
  const globalSources = {
6787
6868
  state: void 0,
6788
6869
  param: void 0,
6789
- global: true
6870
+ global: true,
6871
+ forced: void 0
6790
6872
  };
6791
6873
  const [getBindings] = createProgramState(() => /* @__PURE__ */ new Set());
6792
6874
  const [getNextBindingId, setNextBindingId] = createProgramState(() => 0);
@@ -6806,11 +6888,12 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6806
6888
  property,
6807
6889
  declared,
6808
6890
  closureSections: void 0,
6809
- assignmentSections: void 0,
6891
+ assignments: void 0,
6810
6892
  excludeProperties,
6811
6893
  noSerialize: false,
6812
6894
  noSerializeProperties: void 0,
6813
6895
  sources: void 0,
6896
+ upstreamIntersection: void 0,
6814
6897
  reads: /* @__PURE__ */ new Set(),
6815
6898
  aliases: /* @__PURE__ */ new Set(),
6816
6899
  hoists: void 0,
@@ -6843,8 +6926,18 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6843
6926
  return binding;
6844
6927
  }
6845
6928
  function getOrCreatePropertyAlias(binding, property) {
6929
+ while (isDirectAlias(binding)) binding = binding.upstreamAlias;
6846
6930
  return binding.propertyAliases.get(property) || createBinding(`${binding.name}_${property.replace(/[^a-zA-Z0-9_$]/g, "_")}`, binding.type, binding.section, binding, property);
6847
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
+ }
6848
6941
  function trackDomVarReferences(tag, binding) {
6849
6942
  const tagVar = tag.node.var;
6850
6943
  if (!tagVar) return;
@@ -6863,7 +6956,7 @@ function trackDomVarReferences(tag, binding) {
6863
6956
  } : void 0);
6864
6957
  if (refSection !== binding.section) {
6865
6958
  setReadsOwner(refSection, section);
6866
- addOwnerSerializeReason(refSection, section, true);
6959
+ addOwnerSerializeReason(refSection, section, FORCED);
6867
6960
  }
6868
6961
  }
6869
6962
  return binding;
@@ -6982,10 +7075,12 @@ function trackAssignment(assignment, binding) {
6982
7075
  const idExtra = id.node.extra ??= {};
6983
7076
  idExtra.assignment = binding;
6984
7077
  idExtra.section = section;
6985
- binding.assignmentSections = sectionUtil.add(binding.assignmentSections, section);
7078
+ idExtra.exprRoot = getExprRoot(fnRoot || assignment).node.extra ??= {};
7079
+ idExtra.fnRoot = fnExtra;
7080
+ getAssignments().push(idExtra);
6986
7081
  if (fnExtra) {
6987
- idExtra.assignmentFunction = fnExtra;
6988
- fnExtra.section = idExtra.section = section;
7082
+ fnExtra.section = section;
7083
+ fnExtra.exprRoot = idExtra.exprRoot;
6989
7084
  }
6990
7085
  if (binding.upstreamAlias && binding.property !== void 0) {
6991
7086
  if (binding.upstreamAlias === binding.section.params) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag parameter and cannot be assigned to.`);
@@ -7024,10 +7119,7 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, upstreamAl
7024
7119
  else if (prop.key.type === "StringLiteral") key = prop.key.value;
7025
7120
  else throw scope.path.hub.buildError(prop.key, "Only identifier and string literal keys are supported when destructuring.");
7026
7121
  if (hasRest) excludeProperties = propsUtil.add(excludeProperties, key);
7027
- if (_marko_compiler.types.isLVal(prop.value)) {
7028
- createBindingsAndTrackReferences(prop.value, type, scope, section, patternBinding, key, void 0);
7029
- if (hasRest && prop.value.extra?.binding?.assignmentSections) excludeProperties = propsUtil.add(excludeProperties, `${key}Change`);
7030
- }
7122
+ if (_marko_compiler.types.isLVal(prop.value)) createBindingsAndTrackReferences(prop.value, type, scope, section, patternBinding, key, void 0);
7031
7123
  }
7032
7124
  break;
7033
7125
  }
@@ -7128,6 +7220,33 @@ function finalizeReferences() {
7128
7220
  const readsByExpression = getReadsByExpression();
7129
7221
  const fnReadsByExpression = getFunctionReadsByExpression();
7130
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
+ }
7131
7250
  for (const [expr, reads] of readsByExpression) if (isReferencedExtra(expr)) {
7132
7251
  const exprBindings = resolveReferencedBindings(expr, reads, intersectionsBySection);
7133
7252
  expr.referencedBindings = exprBindings.referencedBindings;
@@ -7140,13 +7259,13 @@ function finalizeReferences() {
7140
7259
  if (exprBindings.hoistedBindings) expr.section.referencedHoists = bindingUtil.union(expr.section.referencedHoists, exprBindings.hoistedBindings);
7141
7260
  if (expr.isEffect) {
7142
7261
  forEach(exprBindings.referencedBindings, (binding) => {
7143
- addSerializeReason(binding.section, true, binding);
7262
+ addSerializeReason(binding.section, FORCED, binding);
7144
7263
  });
7145
7264
  forEach(exprBindings.constantBindings, (binding) => {
7146
- addSerializeReason(binding.section, true, binding);
7265
+ addSerializeReason(binding.section, FORCED, binding);
7147
7266
  });
7148
7267
  forEach(exprBindings.lazyBindings, (binding) => {
7149
- addSerializeReason(binding.section, true, binding);
7268
+ addSerializeReason(binding.section, FORCED, binding);
7150
7269
  });
7151
7270
  } else forEach(reads, (read) => {
7152
7271
  if (read.serializedValue) addSerializeExpr(read.binding.section, expr, read.binding);
@@ -7161,23 +7280,6 @@ function finalizeReferences() {
7161
7280
  }
7162
7281
  }
7163
7282
  const bindingNamesBySection = /* @__PURE__ */ new Map();
7164
- for (const binding of bindings) {
7165
- if (binding.type !== 0) {
7166
- if (pruneBinding(binding)) bindings.delete(binding);
7167
- }
7168
- if (binding.noSerialize) if (isPureSpreadResolved(binding)) if (hasAnyMemberAccess(binding)) {
7169
- let kept = void 0;
7170
- binding.noSerialize = false;
7171
- forEach(binding.noSerializeProperties, (property) => {
7172
- if (!isPropertyMemberAccessed(binding, property)) kept = push(kept, property);
7173
- });
7174
- binding.noSerializeProperties = kept;
7175
- } else binding.noSerializeProperties = void 0;
7176
- else {
7177
- binding.noSerialize = false;
7178
- binding.noSerializeProperties = void 0;
7179
- }
7180
- }
7181
7283
  forEachSection(finalizeTagDownstreams);
7182
7284
  for (const binding of bindings) {
7183
7285
  const { name, section } = binding;
@@ -7187,9 +7289,9 @@ function finalizeReferences() {
7187
7289
  }
7188
7290
  if (binding.type !== 0) {
7189
7291
  resolveBindingSources(binding);
7190
- forEach(binding.assignmentSections, (assignedSection) => {
7292
+ forEach(binding.assignments, ({ section: assignedSection }) => {
7191
7293
  setReadsOwner(assignedSection, section);
7192
- addOwnerSerializeReason(assignedSection, section, true);
7294
+ addOwnerSerializeReason(assignedSection, section, FORCED);
7193
7295
  });
7194
7296
  let bindingNames = bindingNamesBySection.get(section);
7195
7297
  if (!bindingNames) {
@@ -7203,7 +7305,7 @@ function finalizeReferences() {
7203
7305
  forEach(binding.hoists, (hoistSection) => {
7204
7306
  if (!highestHoistSection || hoistSection.depth < highestHoistSection.depth) highestHoistSection = hoistSection;
7205
7307
  hoistSection.hoistedTo = bindingUtil.add(hoistSection.hoistedTo, binding);
7206
- addSerializeReason(binding.section, true, binding);
7308
+ addSerializeReason(binding.section, FORCED, binding);
7207
7309
  });
7208
7310
  binding.section.hoisted = bindingUtil.add(binding.section.hoisted, binding);
7209
7311
  let currentSection = binding.section.parent;
@@ -7226,21 +7328,20 @@ function finalizeReferences() {
7226
7328
  section.referencedClosures = bindingUtil.add(section.referencedClosures, canonicalUpstreamAlias);
7227
7329
  }
7228
7330
  setReadsOwner(section, canonicalUpstreamAlias.section);
7229
- if (isEffect) addOwnerSerializeReason(section, canonicalUpstreamAlias.section, true);
7230
- addOwnerSerializeReason(section, canonicalUpstreamAlias.section, canonicalUpstreamAlias.sources);
7331
+ addOwnerSerializeReason(section, canonicalUpstreamAlias.section, isEffect ? mergeSources(FORCED, canonicalUpstreamAlias.sources) : canonicalUpstreamAlias.sources);
7231
7332
  }
7232
7333
  }
7233
7334
  }
7234
7335
  }
7235
7336
  forEachSection((section) => {
7236
- if (section.isHoistThrough) addSerializeReason(section, true);
7337
+ if (section.isHoistThrough) addSerializeReason(section, FORCED);
7237
7338
  forEach(section.referencedHoists, (hoistedBinding) => {
7238
7339
  setReadsOwner(section, hoistedBinding.section);
7239
- addOwnerSerializeReason(section, hoistedBinding.section, true);
7340
+ addOwnerSerializeReason(section, hoistedBinding.section, FORCED);
7240
7341
  });
7241
7342
  if (section.parent && section.isBranch && section.sectionAccessor && section.upstreamExpression) {
7242
- if (section.isHoistThrough || section.hoisted) addSerializeReason(section, true, kBranchSerializeReason);
7243
- addSerializeReason(section, getSerializeSourcesForRef(getDirectClosures(section)), kBranchSerializeReason);
7343
+ const closureSources = getSerializeSourcesForRef(getDirectClosures(section));
7344
+ addSerializeReason(section, section.isHoistThrough || section.hoisted ? mergeSources(FORCED, closureSources) : closureSources, kBranchSerializeReason);
7244
7345
  addSerializeExpr(section, section.upstreamExpression, kBranchSerializeReason);
7245
7346
  addSerializeExpr(section.parent, section.upstreamExpression, section.sectionAccessor.binding);
7246
7347
  }
@@ -7279,8 +7380,7 @@ function finalizeReferences() {
7279
7380
  else if (upstreamReason) branchesSources = mergeSources(branchesSources, upstreamReason);
7280
7381
  currentSection = currentSection.parent;
7281
7382
  }
7282
- const branchesReason = branchesForced || branchesSources;
7283
- if (branchesForced) addSerializeReason(sourceSection, branchesSources, closure);
7383
+ const branchesReason = branchesForced ? mergeSources(FORCED, branchesSources) : branchesSources;
7284
7384
  addSerializeReason(sourceSection, branchesReason, closure);
7285
7385
  addSerializeReason(sourceSection, getSerializeReason(sourceSection, closure));
7286
7386
  if (isDynamicClosure(section, closure)) {
@@ -7293,22 +7393,15 @@ function finalizeReferences() {
7293
7393
  });
7294
7394
  });
7295
7395
  finalizeFunctionRegistry();
7296
- const referencedExprs = /* @__PURE__ */ new Set();
7297
- for (const binding of bindings) for (const expr of binding.reads) referencedExprs.add(expr);
7298
- for (const expr of referencedExprs) {
7299
- const exprFnReads = fnReadsByExpression.get(expr);
7300
- if (exprFnReads) {
7301
- for (const fn of exprFnReads.keys()) if (fn.registerReason) {
7302
- forEach(fn.referencedBindingsInFunction, (binding) => {
7303
- addSerializeReason(binding.section, fn.registerReason, binding);
7304
- if (binding.section !== fn.section) addOwnerSerializeReason(fn.section, binding.section, fn.registerReason);
7305
- });
7306
- forEach(fn.constantBindingsInFunction, (binding) => {
7307
- addSerializeReason(binding.section, fn.registerReason, binding);
7308
- if (binding.section !== fn.section) addOwnerSerializeReason(fn.section, binding.section, fn.registerReason);
7309
- });
7310
- }
7311
- }
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
+ });
7312
7405
  }
7313
7406
  forEachSection(finalizeParamSerializeReasonGroups);
7314
7407
  forEachSectionReverse((section) => {
@@ -7320,10 +7413,11 @@ function finalizeReferences() {
7320
7413
  const { id, bindings } = section;
7321
7414
  const isOwnedBinding = ({ section }) => section.id === id;
7322
7415
  const ownedBindings = filter(bindings, isOwnedBinding);
7416
+ const intersectionSources = /* @__PURE__ */ new Map();
7323
7417
  const intersections = (intersectionsBySection.get(section) || []).filter((intersection) => {
7324
- const collapseSource = getCollapsibleIntersectionSource(intersection, section);
7325
- if (collapseSource) collapsedIntersectionSource.set(intersection, collapseSource);
7326
- return !collapseSource;
7418
+ const source = getIntersectionSource(intersection, section, intersectionSources);
7419
+ if (source) intersectionMeta.set(intersection, { source });
7420
+ return !source;
7327
7421
  });
7328
7422
  let anchors;
7329
7423
  if (intersections.length) {
@@ -7341,31 +7435,29 @@ function finalizeReferences() {
7341
7435
  let intersectionIndex = 0;
7342
7436
  let nextId = 0;
7343
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
+ };
7344
7445
  forEach(ownedBindings, (binding) => {
7345
7446
  if (binding.type !== 0) while (intersectionIndex < intersections.length && !anchors.get(intersection = intersections[intersectionIndex])) {
7346
7447
  intersectionIndex++;
7347
- intersectionMeta.set(intersection, {
7348
- id: nextId++,
7349
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
7350
- });
7448
+ assignIntersectionId(intersection);
7351
7449
  }
7352
7450
  binding.id = nextId++;
7353
7451
  nextId += binding.reserveSize;
7354
7452
  while (intersectionIndex < intersections.length && anchors.get(intersection = intersections[intersectionIndex]) === binding) {
7355
7453
  intersectionIndex++;
7356
- intersectionMeta.set(intersection, {
7357
- id: nextId++,
7358
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
7359
- });
7454
+ assignIntersectionId(intersection);
7360
7455
  }
7361
7456
  });
7362
7457
  while (intersectionIndex < intersections.length) {
7363
7458
  intersection = intersections[intersectionIndex];
7364
7459
  intersectionIndex++;
7365
- intersectionMeta.set(intersection, {
7366
- id: nextId++,
7367
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
7368
- });
7460
+ assignIntersectionId(intersection);
7369
7461
  }
7370
7462
  forEach(ownedBindings, (binding) => {
7371
7463
  if (binding.closureSections) closureAccessorIds.set(binding, nextId++);
@@ -7399,13 +7491,20 @@ function getMaxOwnSourceOffset(intersection, section) {
7399
7491
  }
7400
7492
  const intersectionMeta = /* @__PURE__ */ new WeakMap();
7401
7493
  const closureAccessorIds = /* @__PURE__ */ new WeakMap();
7402
- const collapsedIntersectionSource = /* @__PURE__ */ new WeakMap();
7403
- 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) {
7404
7502
  let sources;
7405
7503
  for (const member of intersection) {
7406
7504
  if (!member.sources) return void 0;
7407
- const isDirectAlias = member.upstreamAlias && member.property === void 0 && member.excludeProperties === void 0;
7408
- 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;
7409
7508
  sources = mergeSources(sources, member.sources);
7410
7509
  }
7411
7510
  if (!sources || sources.state && sources.param) return;
@@ -7413,12 +7512,15 @@ function getCollapsibleIntersectionSource(intersection, section) {
7413
7512
  return source && !Array.isArray(source) && source.section === section && !source.scopeOffset ? source : void 0;
7414
7513
  }
7415
7514
  function setBindingDownstream(binding, expr, exprs) {
7416
- getBindingValueExprs().set(binding, expr || false);
7515
+ setBindingValueExprs(binding, expr);
7417
7516
  if (expr && expr !== true) forEach(expr, (expr) => {
7418
7517
  expr.downstream = bindingUtil.add(expr.downstream, binding);
7419
7518
  if (exprs) expr.downstreamExprs = exprs;
7420
7519
  });
7421
7520
  }
7521
+ function setBindingValueExprs(binding, expr) {
7522
+ getBindingValueExprs().set(binding, expr || false);
7523
+ }
7422
7524
  const [getResolvedSources] = createProgramState(() => /* @__PURE__ */ new Set());
7423
7525
  const [getBindingValueExprs] = createProgramState(() => /* @__PURE__ */ new Map());
7424
7526
  function resolveBindingSources(binding) {
@@ -7431,7 +7533,7 @@ function resolveBindingSources(binding) {
7431
7533
  if (aliasRoot) {
7432
7534
  resolveBindingSources(aliasRoot);
7433
7535
  binding.sources = aliasRoot.sources;
7434
- } else if (binding.assignmentSections) binding.sources = createSources(binding, void 0);
7536
+ } else if (binding.assignments) binding.sources = createSources(binding, void 0);
7435
7537
  else resolveDerivedSources(binding);
7436
7538
  return;
7437
7539
  }
@@ -7463,34 +7565,36 @@ function getAliasRoot(binding) {
7463
7565
  return alias;
7464
7566
  }
7465
7567
  function resolveDerivedSources(binding) {
7466
- const bindingValueExprs = getBindingValueExprs();
7467
- const exprs = bindingValueExprs.get(binding);
7468
- bindingValueExprs.delete(binding);
7568
+ const exprs = getBindingValueExprs().get(binding);
7469
7569
  if (exprs === void 0 || exprs === true) binding.sources = createSources(binding, void 0);
7470
7570
  else if (exprs) {
7471
- const seen = /* @__PURE__ */ new Set();
7571
+ let refs;
7472
7572
  forEach(exprs, (expr) => {
7473
- if (isReferencedExtra(expr)) forEach(expr.referencedBindings, (ref) => {
7474
- if (!seen.has(ref)) {
7475
- seen.add(ref);
7476
- resolveBindingSources(ref);
7477
- binding.sources = mergeSources(binding.sources, ref.sources);
7478
- }
7479
- });
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);
7480
7578
  });
7579
+ binding.upstreamIntersection = Array.isArray(refs) ? refs : refs && getUpstreamIntersection(refs);
7481
7580
  }
7482
7581
  }
7483
- function createSources(state, param, global) {
7582
+ function getUpstreamIntersection(binding) {
7583
+ return (getAliasRoot(binding) || binding).upstreamIntersection;
7584
+ }
7585
+ function createSources(state, param, global, forced) {
7484
7586
  /* v8 ignore next 6 -- every caller passes at least one source */
7485
- 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.");
7486
7588
  return {
7487
7589
  state,
7488
7590
  param,
7489
- global
7591
+ global,
7592
+ forced
7490
7593
  };
7491
7594
  }
7492
7595
  function compareSources(a, b) {
7493
7596
  let delta;
7597
+ if (a.forced !== b.forced) return a.forced ? 1 : -1;
7494
7598
  if (a.global !== b.global) return a.global ? 1 : -1;
7495
7599
  if (a.param) {
7496
7600
  if (!b.param) return 1;
@@ -7505,12 +7609,12 @@ function compareSources(a, b) {
7505
7609
  function mergeSources(a, b) {
7506
7610
  if (!a) return b;
7507
7611
  if (!b) return a;
7508
- if (a.state === b.state && a.param === b.param && a.global === b.global) return a;
7509
- 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);
7510
7614
  }
7511
7615
  function unionParamSources(a, b) {
7512
7616
  const merged = bindingUtil.union(a, b);
7513
- if (merged && Array.isArray(merged)) return filter(merged, (binding) => {
7617
+ if (merged && Array.isArray(merged)) return bindingUtil.filter(merged, (binding) => {
7514
7618
  let alias = binding.upstreamAlias;
7515
7619
  while (alias) {
7516
7620
  if (bindingUtil.has(merged, alias)) return false;
@@ -7526,6 +7630,7 @@ const bindingUtil = new Sorted(function compareBindings(a, b) {
7526
7630
  const propsUtil = new Sorted(function compareProps(a, b) {
7527
7631
  return a < b ? -1 : a > b ? 1 : 0;
7528
7632
  });
7633
+ const [getAssignments] = createProgramState(() => []);
7529
7634
  const [getReadsByExpression] = createProgramState(() => /* @__PURE__ */ new Map());
7530
7635
  const [getFunctionReadsByExpression] = createProgramState(() => /* @__PURE__ */ new Map());
7531
7636
  const [getReferenceFinalizers] = createProgramState(() => []);
@@ -7550,20 +7655,43 @@ function addRead(exprExtra, extra, binding, section, getter) {
7550
7655
  readsByExpression.set(exprExtra, push(readsByExpression.get(exprExtra), read));
7551
7656
  return read;
7552
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
+ }
7553
7673
  function dropNodes(node) {
7554
7674
  if (Array.isArray(node)) for (const item of node) dropExtra(item.extra ??= {});
7555
7675
  else dropExtra(node.extra ??= {});
7556
7676
  }
7677
+ function untrackNode(node) {
7678
+ untrackExtra(node.extra ??= {});
7679
+ }
7557
7680
  function dropExtra(exprExtra) {
7681
+ exprExtra.pruned = true;
7682
+ untrackExtra(exprExtra);
7683
+ }
7684
+ function untrackExtra(exprExtra) {
7558
7685
  /* v8 ignore next 3 -- a merged reference is never dropped */
7559
7686
  if (exprExtra.merged) throw new Error("Cannot drop a merged reference");
7560
7687
  const readsByExpr = getReadsByExpression();
7561
7688
  const reads = readsByExpr.get(exprExtra);
7562
- exprExtra.pruned = true;
7563
7689
  if (reads) {
7564
7690
  readsByExpr.delete(exprExtra);
7691
+ getFunctionReadsByExpression().delete(exprExtra);
7565
7692
  forEach(reads, (read) => {
7566
7693
  read.binding.reads.delete(exprExtra);
7694
+ if (!exprExtra.pruned) read.binding.untracked = true;
7567
7695
  });
7568
7696
  }
7569
7697
  }
@@ -7580,8 +7708,11 @@ function addReadToExpression(root, binding, getter) {
7580
7708
  const fnRoot = getFnRoot(root);
7581
7709
  const exprRoot = getExprRoot(fnRoot || root);
7582
7710
  const section = getOrCreateSection(exprRoot);
7583
- const exprExtra = getCanonicalExtra(exprRoot.node.extra ??= { section });
7584
- 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);
7585
7716
  if (!fnRoot && isSerializedChangeHandlerRead(exprRoot)) read.serializedValue = true;
7586
7717
  const { parent } = root;
7587
7718
  if (parent.type === "BinaryExpression" && (parent.operator === "===" || parent.operator === "!==")) read.comparedTo = parent.left === node ? parent.right : parent.left;
@@ -7597,14 +7728,23 @@ function addReadToExpression(root, binding, getter) {
7597
7728
  if (!exprFnReads) fnReadsByExpr.set(exprExtra, exprFnReads = /* @__PURE__ */ new Map());
7598
7729
  const fnExtra = fnRoot.node.extra ??= {};
7599
7730
  fnExtra.section = section;
7731
+ fnExtra.exprRoot = rootExtra;
7600
7732
  exprFnReads.set(fnExtra, push(exprFnReads.get(fnExtra), read));
7601
7733
  }
7602
7734
  }
7603
7735
  function getCanonicalBinding(binding) {
7604
7736
  const alias = binding.upstreamAlias;
7605
- if (alias && binding.property === void 0 && binding.excludeProperties === void 0) return alias;
7737
+ if (alias && isDirectAlias(binding)) return alias;
7606
7738
  return binding;
7607
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
+ }
7608
7748
  function getAllTagReferenceNodes(tag, referenceNodes = []) {
7609
7749
  if (tag.arguments) for (const arg of tag.arguments) referenceNodes.push(arg);
7610
7750
  for (const attr of tag.attributes) referenceNodes.push(attr.value);
@@ -7729,20 +7869,22 @@ function getReadReplacement(node, signal) {
7729
7869
  if (readBinding.getters.has(readBinding.section)) replacement = getBindingGetterIdentifier(readBinding, readBinding.section);
7730
7870
  } else if (readBinding.name !== node.name) node.name = readBinding.name;
7731
7871
  } else {
7732
- const props = read.props ? Array.isArray(read.props) ? read.props.slice() : [read.props] : [];
7872
+ const { props } = read;
7873
+ let remaining = size(props);
7733
7874
  let curNode = node;
7734
7875
  let curBinding = readBinding;
7735
7876
  let replaceMember;
7736
7877
  if (isOutputDOM()) if (signal?.referencedBindings === readBinding && !signal.hasSideEffect) replacement = getSignalValueIdentifier(signal);
7737
7878
  else replacement = createScopeReadExpression(readBinding, extra.section);
7738
7879
  else replacement = _marko_compiler.types.identifier(readBinding.name);
7739
- while (props.length && (curNode.type === "MemberExpression" || curNode.type === "OptionalMemberExpression")) {
7740
- const prop = props.pop();
7880
+ while (remaining && (curNode.type === "MemberExpression" || curNode.type === "OptionalMemberExpression")) {
7881
+ const prop = at(props, --remaining);
7741
7882
  if (getMemberExpressionPropString(curNode) !== prop) break;
7742
7883
  replaceMember = curNode;
7743
7884
  curNode = curNode.object;
7744
7885
  }
7745
- for (const prop of props) {
7886
+ for (let i = 0; i < remaining; i++) {
7887
+ const prop = at(props, i);
7746
7888
  if (curBinding) curBinding = curBinding.propertyAliases.get(prop);
7747
7889
  replacement = toMemberExpression(replacement, prop, !!curBinding?.nullable);
7748
7890
  }
@@ -7759,45 +7901,62 @@ function getReadReplacement(node, signal) {
7759
7901
  } else if (binding && node.type == "Identifier" && node.name !== binding.name) node.name = binding.name;
7760
7902
  }
7761
7903
  function isInvokeOnlyBinding(binding) {
7762
- if (binding.assignmentSections || binding.hoists || binding.getters.size || binding.propertyAliases.size || binding.excludeProperties) return false;
7763
- for (const expr of binding.reads) if (!expr.invokeOnly) return false;
7764
- for (const alias of binding.aliases) if (!isInvokeOnlyBinding(alias)) return false;
7765
- 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;
7766
7910
  }
7767
7911
  function hasNonConstantPropertyAlias(ref) {
7768
7912
  for (const alias of ref.propertyAliases.values()) if (alias.type !== 6) return true;
7769
7913
  return false;
7770
7914
  }
7771
- function pruneBinding(binding) {
7915
+ function pruneBinding(binding, settled) {
7772
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
+ }
7773
7922
  for (const read of binding.reads) {
7774
7923
  let upstream = binding.upstreamAlias;
7775
7924
  while (upstream && !upstream.reads.has(read)) upstream = upstream.upstreamAlias;
7776
7925
  if (upstream) binding.reads.delete(read);
7777
7926
  }
7778
7927
  let shouldPrune = !binding.reads.size && !binding.reserveSize;
7779
- 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);
7780
7929
  else if (alias.type !== 6) shouldPrune = false;
7781
- 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);
7782
7931
  else if (alias.type !== 6) shouldPrune = false;
7783
- 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
+ }
7784
7939
  return shouldPrune;
7785
7940
  }
7941
+ function pruneSettledBinding(binding) {
7942
+ pruneBinding(binding, true);
7943
+ }
7944
+ function pruneSettledWriter({ exprRoot }) {
7945
+ if (isDroppableValue(exprRoot)) forEach(exprRoot.downstream, pruneSettledBinding);
7946
+ }
7786
7947
  function resolveReferencedBindingsInFunction(refs, reads) {
7787
7948
  let referencedBindings;
7788
7949
  let constantBindings;
7789
- if (reads) if (Array.isArray(reads)) for (const read of reads) {
7790
- const { getter, binding } = read;
7950
+ const closest = /* @__PURE__ */ new Set();
7951
+ forEach(reads, ({ getter, binding }) => {
7791
7952
  if (getter) {} else if (binding.type === 6) {
7792
7953
  if (bindingUtil.find(refs, binding)) constantBindings = bindingUtil.add(constantBindings, binding);
7793
- } else if (binding.type !== 0 && binding.type !== 7) referencedBindings = bindingUtil.add(referencedBindings, findClosestReference(read.binding, refs));
7794
- }
7795
- else {
7796
- const { getter, binding } = reads;
7797
- if (getter) {} else if (binding.type === 6) {
7798
- if (bindingUtil.find(refs, binding)) constantBindings = binding;
7799
- } else if (binding.type !== 0 && binding.type !== 7) referencedBindings = findClosestReference(binding, refs);
7800
- }
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));
7801
7960
  return {
7802
7961
  referencedBindings,
7803
7962
  constantBindings
@@ -7967,6 +8126,12 @@ function createGetterRead(binding, props, getter) {
7967
8126
  function isReferencedExtra(extra) {
7968
8127
  return !!(extra && !extra.pruned && extra.section);
7969
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
+ }
7970
8135
  function isAssignedBindingExtra(extra) {
7971
8136
  return isReferencedExtra(extra) && extra.assignment !== void 0;
7972
8137
  }
@@ -7977,93 +8142,129 @@ function getCanonicalExtra(extra) {
7977
8142
  while (extra.merged) extra = extra.merged;
7978
8143
  return extra;
7979
8144
  }
7980
- const serializeReasonCache = /* @__PURE__ */ new WeakMap();
7981
- const registerReasonCache = /* @__PURE__ */ new WeakMap();
7982
- function getAllSerializeReasonsForExtra(extra, register) {
7983
- if (extra.isEffect || register && extra.dynamicTagInput) return true;
7984
- const cache = register ? registerReasonCache : serializeReasonCache;
7985
- let reason = cache.get(extra);
7986
- if (reason === false) return;
7987
- if (reason === void 0) {
7988
- if (extra === (0, _marko_compiler_babel_utils.getProgram)().node.extra?.section.returnValueExpr) reason = true;
7989
- else {
7990
- cache.set(extra, false);
7991
- forEach(extra.downstream, (binding) => {
7992
- let linked = getAllSerializeReasonsForBinding(binding, true, register);
7993
- if (linked && linked !== true) {
7994
- const exprs = extra.downstreamExprs;
7995
- if (exprs) linked = mapDownstreamReason(binding.section.program, linked, exprs);
7996
- }
7997
- reason = mergeSerializeReasons(reason, linked);
7998
- });
7999
- }
8000
- if (reason) cache.set(extra, reason);
8001
- }
8002
- 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
+ };
8003
8173
  }
8004
- function getAllSerializeReasonsForBinding(binding, properties, register) {
8005
- const cache = register ? registerReasonCache : serializeReasonCache;
8006
- let reason = cache.get(binding);
8007
- if (reason === void 0) {
8008
- reason = getSerializeReason(binding.section, binding);
8009
- if (reason !== true) {
8010
- cache.set(binding, reason || false);
8011
- if (properties !== true && binding.upstreamAlias) reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(binding.upstreamAlias, binding.property, register));
8012
- if (reason !== true) {
8013
- for (const expr of binding.reads) {
8014
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForExtra(expr, register));
8015
- if (reason === true) break;
8016
- }
8017
- if (reason !== true) for (const alias of binding.aliases) {
8018
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(alias, properties, register));
8019
- if (reason === true) break;
8020
- }
8021
- }
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;
8022
8211
  }
8023
- 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));
8024
8218
  }
8025
- if (reason === false) reason = void 0;
8026
- if (properties !== void 0) if (properties === true) {
8027
- if (reason !== true) for (const propBinding of binding.propertyAliases.values()) {
8028
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(propBinding, true, register));
8029
- if (reason === true) break;
8030
- }
8031
- } else {
8032
- let property;
8033
- let rest;
8034
- if (Array.isArray(properties)) {
8035
- property = properties[0];
8036
- rest = properties.length === 2 ? properties[1] : properties.slice(1);
8037
- } else property = properties;
8038
- if (includes(binding.excludeProperties, property)) reason = void 0;
8039
- else {
8040
- const propBinding = binding.propertyAliases.get(property);
8041
- if (propBinding) reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(propBinding, rest, register));
8042
- if (reason !== true) for (const alias of binding.aliases) {
8043
- const propBinding = alias.propertyAliases.get(property);
8044
- if (propBinding) {
8045
- reason = mergeSerializeReasons(reason, getAllSerializeReasonsForBinding(propBinding, rest, register));
8046
- if (reason === true) break;
8047
- }
8048
- }
8049
- }
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;
8050
8224
  }
8051
- 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
+ };
8052
8249
  }
8053
8250
  function isPureSpreadResolved(binding) {
8054
- for (const read of binding.reads) if (!read.nativeTagSpread || read.nativeTagSpreadMerged) return false;
8055
- for (const alias of binding.aliases) if (!isPureSpreadResolved(alias)) return false;
8056
- return true;
8251
+ return !someAlias(binding, hasReadBeyondSpreading, void 0);
8057
8252
  }
8058
- function hasAnyMemberAccess(binding) {
8059
- if (binding.propertyAliases.size) return true;
8060
- 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;
8061
8255
  return false;
8062
8256
  }
8257
+ function hasAnyMemberAccess(binding) {
8258
+ return someAlias(binding, hasPropertyAliases, void 0);
8259
+ }
8260
+ function hasPropertyAliases(binding) {
8261
+ return binding.propertyAliases.size > 0;
8262
+ }
8063
8263
  function isPropertyMemberAccessed(binding, property) {
8064
- if (binding.propertyAliases.has(property)) return true;
8065
- for (const alias of binding.aliases) if (isPropertyMemberAccessed(alias, property)) return true;
8066
- return false;
8264
+ return someAlias(binding, hasPropertyAlias, property);
8265
+ }
8266
+ function hasPropertyAlias(binding, property) {
8267
+ return binding.propertyAliases.has(property);
8067
8268
  }
8068
8269
  function addNumericPropertiesUntil(props, len) {
8069
8270
  let result = props;
@@ -8071,11 +8272,7 @@ function addNumericPropertiesUntil(props, len) {
8071
8272
  return result;
8072
8273
  }
8073
8274
  function setReadsOwner(from, to) {
8074
- let cur = from;
8075
- while (cur !== to && cur.parent) {
8076
- cur.readsOwner = true;
8077
- cur = cur.parent;
8078
- }
8275
+ for (const section of ancestorSections(from, to)) section.readsOwner = true;
8079
8276
  }
8080
8277
  function mapParamReasonToExpr(exprs, reason) {
8081
8278
  if (reason) {
@@ -8106,7 +8303,7 @@ function mapParamBindingToExpr(exprs, binding) {
8106
8303
  if (isWholeAlias) {
8107
8304
  let result = curExpr.value;
8108
8305
  if (curExpr.known) {
8109
- 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);
8110
8307
  }
8111
8308
  return result;
8112
8309
  }
@@ -8114,7 +8311,6 @@ function mapParamBindingToExpr(exprs, binding) {
8114
8311
  }
8115
8312
  //#endregion
8116
8313
  //#region src/translator/core/await.ts
8117
- const kDOMBinding$2 = Symbol("await tag dom binding");
8118
8314
  var await_default = {
8119
8315
  analyze(tag) {
8120
8316
  (0, _marko_compiler_babel_utils.assertNoVar)(tag);
@@ -8126,7 +8322,7 @@ var await_default = {
8126
8322
  const section = getOrCreateSection(tag);
8127
8323
  const [valueAttr] = node.attributes;
8128
8324
  const tagExtra = tag.node.extra ??= {};
8129
- tagExtra[kDOMBinding$2] = createBinding("#text", 0, section);
8325
+ tagExtra.nodeBinding = createBinding("#text", 0, section);
8130
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).");
8131
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).");
8132
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).");
@@ -8154,7 +8350,7 @@ var await_default = {
8154
8350
  exit(tag) {
8155
8351
  const { node } = tag;
8156
8352
  const [valueAttr] = node.attributes;
8157
- const nodeRef = node.extra[kDOMBinding$2];
8353
+ const nodeRef = node.extra.nodeBinding;
8158
8354
  const tagBody = tag.get("body");
8159
8355
  const section = getSection(tag);
8160
8356
  const bodySection = getSectionForBody(tagBody);
@@ -8174,7 +8370,7 @@ var await_default = {
8174
8370
  },
8175
8371
  exit(tag) {
8176
8372
  const { node } = tag;
8177
- const nodeRef = node.extra[kDOMBinding$2];
8373
+ const nodeRef = node.extra.nodeBinding;
8178
8374
  const section = getSection(tag);
8179
8375
  const bodySection = getSectionForBody(tag.get("body"));
8180
8376
  const signal = getSignal(section, nodeRef, "await_promise");
@@ -8257,7 +8453,7 @@ var const_default = {
8257
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).");
8258
8454
  const valueExtra = evaluate(valueAttr.value);
8259
8455
  const upstreamAlias = _marko_compiler.types.isIdentifier(valueAttr.value) ? tag.scope.getBinding(valueAttr.value.name)?.identifier.extra?.binding : void 0;
8260
- if (upstreamAlias) dropNodes(valueAttr.value);
8456
+ if (upstreamAlias) untrackNode(valueAttr.value);
8261
8457
  const binding = trackVarReferences(tag, 5, upstreamAlias);
8262
8458
  if (binding) {
8263
8459
  assertNoTagVarMutation(tag);
@@ -8272,14 +8468,14 @@ var const_default = {
8272
8468
  const { node } = tag;
8273
8469
  const [valueAttr] = node.attributes;
8274
8470
  const { value } = valueAttr;
8471
+ const varBinding = node.var.extra?.binding;
8275
8472
  if (isOutputDOM()) {
8276
8473
  const section = getSection(tag);
8277
- const varBinding = node.var.extra?.binding;
8278
- if (varBinding && !varBinding.upstreamAlias) {
8474
+ if (varBinding && !varBinding.upstreamAlias && !value.extra?.pruned) {
8279
8475
  const derivation = initValue(varBinding);
8280
8476
  addValue(section, value.extra?.referencedBindings, derivation, value);
8281
8477
  }
8282
- } else translateVar(tag, value);
8478
+ } else if (!varBinding?.pruned || !value.extra?.pruned) translateVar(tag, value);
8283
8479
  tag.remove();
8284
8480
  } },
8285
8481
  parseOptions: { openTagOnly: true },
@@ -8486,7 +8682,7 @@ var html_comment_default = {
8486
8682
  const tagExtra = mergeReferences(tagSection, tag.node, referenceNodes);
8487
8683
  nodeBinding = tagExtra[kNodeBinding$1] = createBinding("#comment", 0, tagSection, void 0, void 0, void 0, void 0, !!tagVar);
8488
8684
  trackDomVarReferences(tag, nodeBinding);
8489
- if (tagVar) addSerializeExpr(tagSection, true, nodeBinding);
8685
+ if (tagVar) addSerializeReason(tagSection, FORCED, nodeBinding);
8490
8686
  addSerializeExpr(tagSection, tagExtra, nodeBinding);
8491
8687
  }
8492
8688
  const write = writeTo(tag);
@@ -8672,11 +8868,20 @@ var let_default = {
8672
8868
  if (valueChangeAttr) {
8673
8869
  binding.reserveSize = 1;
8674
8870
  setBindingDownstream(binding, tagExtra);
8675
- if (binding.assignmentSections) addSerializeReason(tagSection, true, binding, getAccessorPrefix().TagVariableChange);
8676
- } 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
+ }
8677
8878
  },
8678
8879
  translate: { exit(tag) {
8679
8880
  const { node } = tag;
8881
+ if (node.extra?.pruned) {
8882
+ tag.remove();
8883
+ return;
8884
+ }
8680
8885
  const tagVar = node.var;
8681
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"));
8682
8887
  const valueChangeAttr = node.attributes.find((attr) => _marko_compiler.types.isMarkoAttribute(attr) && attr.name === "valueChange");
@@ -9167,6 +9372,7 @@ var style_default = {
9167
9372
  analyzeDynamicStyle(tag, names);
9168
9373
  addSetupStatement(getOrCreateSection(tag));
9169
9374
  visit(tag, 32);
9375
+ enterShallow(tag);
9170
9376
  writeTo(tag)`<style></style>`;
9171
9377
  }
9172
9378
  },
@@ -9336,7 +9542,6 @@ function getStyleImportPath(file, node, names) {
9336
9542
  }
9337
9543
  //#endregion
9338
9544
  //#region src/translator/core/try.ts
9339
- const kDOMBinding$1 = Symbol("try tag dom binding");
9340
9545
  var try_default = {
9341
9546
  analyze(tag) {
9342
9547
  (0, _marko_compiler_babel_utils.assertNoVar)(tag);
@@ -9352,7 +9557,7 @@ var try_default = {
9352
9557
  }
9353
9558
  const section = getOrCreateSection(tag);
9354
9559
  const tagExtra = mergeReferences(section, tag.node, getAllTagReferenceNodes(tag.node));
9355
- tagExtra[kDOMBinding$1] = createBinding("#text", 0, section);
9560
+ tagExtra.nodeBinding = createBinding("#text", 0, section);
9356
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).");
9357
9562
  const bodySection = startSection(tag.get("body"));
9358
9563
  if (bodySection) {
@@ -9379,7 +9584,7 @@ var try_default = {
9379
9584
  const tagExtra = node.extra;
9380
9585
  const tagBody = tag.get("body");
9381
9586
  const translatedAttrs = translateAttrs(tag);
9382
- const nodeRef = tagExtra[kDOMBinding$1];
9587
+ const nodeRef = tagExtra.nodeBinding;
9383
9588
  const contentProp = getTranslatedBodyContentProperty(translatedAttrs.properties);
9384
9589
  if (contentProp) translatedAttrs.properties.splice(translatedAttrs.properties.indexOf(contentProp), 1);
9385
9590
  flushInto(tag);
@@ -9397,7 +9602,7 @@ var try_default = {
9397
9602
  exit(tag) {
9398
9603
  const { node } = tag;
9399
9604
  const tagExtra = node.extra;
9400
- const nodeRef = tagExtra[kDOMBinding$1];
9605
+ const nodeRef = tagExtra.nodeBinding;
9401
9606
  const referencedBindings = tagExtra.referencedBindings;
9402
9607
  const translatedAttrs = translateAttrs(tag);
9403
9608
  const contentProp = getTranslatedBodyContentProperty(translatedAttrs.properties);
@@ -9846,8 +10051,8 @@ var referenced_identifier_default = {
9846
10051
  const section = getOrCreateSection(identifier);
9847
10052
  section.hasAbortSignal = true;
9848
10053
  setReferencesScope(identifier);
9849
- const exprRoot = getExprRoot(identifier);
9850
- const rootExtra = exprRoot.node.extra ??= { section };
10054
+ const rootExtra = getExprRoot(identifier).node.extra ??= { section };
10055
+ (identifier.node.extra ??= {}).exprRoot = rootExtra;
9851
10056
  if (rootExtra.abortId === void 0) rootExtra.abortId = section.abortSignalExprs++;
9852
10057
  }
9853
10058
  },
@@ -9866,12 +10071,12 @@ var referenced_identifier_default = {
9866
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.")]))])), []));
9867
10072
  else {
9868
10073
  const section = getSection(identifier);
9869
- const exprRoot = getExprRoot(identifier);
9870
- const exprId = exprRoot.node.extra.abortId;
10074
+ const exprRoot = identifier.node.extra.exprRoot;
10075
+ const exprId = exprRoot.abortId;
9871
10076
  const resetEmitted = getAbortResetEmitted(section);
9872
10077
  if (!resetEmitted.has(exprRoot)) {
9873
10078
  resetEmitted.add(exprRoot);
9874
- 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)])));
9875
10080
  }
9876
10081
  identifier.replaceWith(_marko_compiler.types.callExpression(importRuntime("$signal"), [scopeIdentifier, _marko_compiler.types.numericLiteral(exprId)]));
9877
10082
  }
@@ -10079,10 +10284,7 @@ function tagNotFoundError(tag) {
10079
10284
  const proseText = tagName && getProseText(tag);
10080
10285
  if (knownWrongTagHint) didYouMean = ` ${knownWrongTagHint}`;
10081
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>\`.`;
10082
- else if (tagName) {
10083
- const closestTag = (0, fastest_levenshtein.closest)(tagName, Object.keys((0, _marko_compiler_babel_utils.getTaglibLookup)((0, _marko_compiler_babel_utils.getFile)()).merged.tags));
10084
- if ((0, fastest_levenshtein.distance)(tagName, closestTag) < 4) didYouMean = ` Did you mean \`<${closestTag}>\`?`;
10085
- }
10287
+ else if (tagName) didYouMean = getSimilarTagHint(tagName);
10086
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}`);
10087
10289
  }
10088
10290
  const wordReg = /^[A-Za-z]+$/;
@@ -10106,6 +10308,25 @@ function collectProseWords(node, tagName) {
10106
10308
  }
10107
10309
  return text;
10108
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
+ }
10109
10330
  function buildLoadSetupVirtualModule(file, childFileName, childExports) {
10110
10331
  const parts = `${childExports.template}, ${childExports.walks}, ${childExports.setup}`;
10111
10332
  return getMarkoOpts().resolveVirtualDependency(file.opts.filename, {
@@ -10137,7 +10358,6 @@ function optionalValueToNode(value) {
10137
10358
  }
10138
10359
  //#endregion
10139
10360
  //#region src/translator/visitors/tag/dynamic-tag.ts
10140
- const kDOMBinding = Symbol("dynamic tag dom binding");
10141
10361
  const kChildOffsetScopeBinding = Symbol("custom tag scope offset");
10142
10362
  const importedDynamicTagResume = /* @__PURE__ */ new WeakSet();
10143
10363
  const importedDynamicTagVarResume = /* @__PURE__ */ new WeakSet();
@@ -10172,15 +10392,19 @@ var dynamic_tag_default = {
10172
10392
  if (inputNodes.length) tagExtra.dynamicTagInput = true;
10173
10393
  const tagBody = tag.get("body");
10174
10394
  const hasVar = !!tag.node.var;
10175
- const nodeBinding = tagExtra[kDOMBinding] = createBinding("#text", 0, tagSection);
10395
+ const nodeBinding = tagExtra.nodeBinding = createBinding("#text", 0, tagSection);
10176
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;
10177
10397
  if (hasVar) {
10178
10398
  trackVarReferences(tag, 5);
10179
10399
  tag.node.var.extra.binding.scopeOffset = tagExtra[kChildOffsetScopeBinding] = createBinding("#scopeOffset", 0, tagSection);
10180
10400
  }
10181
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
+ }
10182
10406
  trackParamsReferences(tagBody, 3);
10183
- if (hasVar) addSerializeExpr(tagSection, true, nodeBinding);
10407
+ if (hasVar) addSerializeReason(tagSection, FORCED, nodeBinding);
10184
10408
  addSerializeExpr(tagSection, tagExtra, nodeBinding);
10185
10409
  if (!hasVar && !node.arguments && !node.attributes.length && !node.body.body.length) tagExtra[kDirectContent] = true;
10186
10410
  if (tagExtra.featureType !== "class" || (0, _marko_compiler_babel_utils.getTagTemplate)(tag)) {
@@ -10215,7 +10439,7 @@ var dynamic_tag_default = {
10215
10439
  return;
10216
10440
  }
10217
10441
  const tagExtra = node.extra;
10218
- const nodeBinding = tagExtra[kDOMBinding];
10442
+ const nodeBinding = tagExtra.nodeBinding;
10219
10443
  const isClassAPI = tagExtra.featureType === "class";
10220
10444
  const tagsSerializeReason = getSerializeReason(tagSection, nodeBinding);
10221
10445
  const serializeReason = tagsSerializeReason;
@@ -10239,7 +10463,7 @@ var dynamic_tag_default = {
10239
10463
  ...preserveBoundary ? [_marko_compiler.types.stringLiteral("preserve")] : []
10240
10464
  ]) : void 0;
10241
10465
  if (isOutputHTML() ? serializeReason || classHydration : serializeReason) {
10242
- 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);
10243
10467
  }
10244
10468
  if (!preserveBoundary) {
10245
10469
  const emitted = getCompatBoundaryCalls().get(classId);
@@ -10335,6 +10559,15 @@ function enableDynamicTagResume(tag) {
10335
10559
  }
10336
10560
  }
10337
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
+ }
10338
10571
  //#endregion
10339
10572
  //#region src/translator/visitors/tag/index.ts
10340
10573
  var tag_default = {
@@ -10815,7 +11048,9 @@ const taglibs = [[core_default.taglibId, {
10815
11048
  migrate: visitors.migrate
10816
11049
  }]];
10817
11050
  function getRuntimeEntryFiles(output, optimize) {
10818
- 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`)];
10819
11054
  }
10820
11055
  //#endregion
10821
11056
  exports.analyze = analyze;