marko 6.0.84 → 6.0.86

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.
@@ -52,7 +52,6 @@ __export(html_exports, {
52
52
  _for_of: () => _for_of,
53
53
  _for_to: () => _for_to,
54
54
  _for_until: () => _for_until,
55
- _get_serialize_reason: () => _get_serialize_reason,
56
55
  _hoist: () => _hoist,
57
56
  _html: () => _html,
58
57
  _id: () => _id,
@@ -62,6 +61,7 @@ __export(html_exports, {
62
61
  _resume_branch: () => _resume_branch,
63
62
  _scope: () => writeScope,
64
63
  _scope_id: () => _scope_id,
64
+ _scope_reason: () => _scope_reason,
65
65
  _scope_with_id: () => _scope_with_id,
66
66
  _script: () => _script,
67
67
  _sep: () => _sep,
@@ -1804,7 +1804,7 @@ function getScopeById(scopeId) {
1804
1804
  function _set_serialize_reason(reason) {
1805
1805
  $chunk.boundary.state.serializeReason = reason;
1806
1806
  }
1807
- function _get_serialize_reason() {
1807
+ function _scope_reason() {
1808
1808
  const reason = $chunk.boundary.state.serializeReason;
1809
1809
  $chunk.boundary.state.serializeReason = void 0;
1810
1810
  return reason;
@@ -3480,7 +3480,6 @@ function NOOP3() {
3480
3480
  _for_of,
3481
3481
  _for_to,
3482
3482
  _for_until,
3483
- _get_serialize_reason,
3484
3483
  _hoist,
3485
3484
  _html,
3486
3485
  _id,
@@ -3490,6 +3489,7 @@ function NOOP3() {
3490
3489
  _resume_branch,
3491
3490
  _scope,
3492
3491
  _scope_id,
3492
+ _scope_reason,
3493
3493
  _scope_with_id,
3494
3494
  _script,
3495
3495
  _sep,
@@ -1715,7 +1715,7 @@ function getScopeById(scopeId) {
1715
1715
  function _set_serialize_reason(reason) {
1716
1716
  $chunk.boundary.state.serializeReason = reason;
1717
1717
  }
1718
- function _get_serialize_reason() {
1718
+ function _scope_reason() {
1719
1719
  const reason = $chunk.boundary.state.serializeReason;
1720
1720
  $chunk.boundary.state.serializeReason = void 0;
1721
1721
  return reason;
@@ -3390,7 +3390,6 @@ export {
3390
3390
  _for_of,
3391
3391
  _for_to,
3392
3392
  _for_until,
3393
- _get_serialize_reason,
3394
3393
  _hoist,
3395
3394
  _html,
3396
3395
  _id,
@@ -3400,6 +3399,7 @@ export {
3400
3399
  _resume_branch,
3401
3400
  writeScope as _scope,
3402
3401
  _scope_id,
3402
+ _scope_reason,
3403
3403
  _scope_with_id,
3404
3404
  _script,
3405
3405
  _sep,
@@ -28,7 +28,7 @@ export declare function _scope_id(): number;
28
28
  export declare function _peek_scope_id(): number;
29
29
  export declare function getScopeById(scopeId: number | undefined): PartialScope | undefined;
30
30
  export declare function _set_serialize_reason(reason: undefined | 0 | 1): void;
31
- export declare function _get_serialize_reason(): 0 | 1 | undefined;
31
+ export declare function _scope_reason(): 0 | 1 | undefined;
32
32
  export declare function _serialize_if(condition: undefined | 1 | Record<string, 1>, key: string): 1 | undefined;
33
33
  export declare function _serialize_guard(condition: undefined | 1 | Record<string, 1>, key: string): 0 | 1;
34
34
  export declare function _el_resume(scopeId: number, accessor: Accessor, shouldResume?: 0 | 1): string;
package/dist/html.d.ts CHANGED
@@ -5,4 +5,4 @@ export { _escape, _escape_script, _escape_style, _escape_textarea_value, _unesca
5
5
  export { _content, _content_resume, _dynamic_tag } from "./html/dynamic-tag";
6
6
  export { forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, } from "./html/for";
7
7
  export { _template } from "./html/template";
8
- export { _attr_content, _await, _el, _el_resume, _existing_scope, _for_in, _for_of, _for_to, _for_until, _get_serialize_reason, _hoist, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, _scope, _scope_id, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _subscribe, _trailers, _try, _var, $global, } from "./html/writer";
8
+ export { _attr_content, _await, _el, _el_resume, _existing_scope, _for_in, _for_of, _for_to, _for_until, _hoist, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _subscribe, _trailers, _try, _var, $global, } from "./html/writer";
package/dist/html.js CHANGED
@@ -49,7 +49,6 @@ __export(html_exports, {
49
49
  _for_of: () => _for_of,
50
50
  _for_to: () => _for_to,
51
51
  _for_until: () => _for_until,
52
- _get_serialize_reason: () => _get_serialize_reason,
53
52
  _hoist: () => _hoist,
54
53
  _html: () => _html,
55
54
  _id: () => _id,
@@ -59,6 +58,7 @@ __export(html_exports, {
59
58
  _resume_branch: () => _resume_branch,
60
59
  _scope: () => writeScope,
61
60
  _scope_id: () => _scope_id,
61
+ _scope_reason: () => _scope_reason,
62
62
  _scope_with_id: () => _scope_with_id,
63
63
  _script: () => _script,
64
64
  _sep: () => _sep,
@@ -1173,7 +1173,7 @@ function getScopeById(scopeId) {
1173
1173
  function _set_serialize_reason(reason) {
1174
1174
  $chunk.boundary.state.serializeReason = reason;
1175
1175
  }
1176
- function _get_serialize_reason() {
1176
+ function _scope_reason() {
1177
1177
  let reason = $chunk.boundary.state.serializeReason;
1178
1178
  return $chunk.boundary.state.serializeReason = void 0, reason;
1179
1179
  }
@@ -2275,7 +2275,6 @@ function NOOP3() {
2275
2275
  _for_of,
2276
2276
  _for_to,
2277
2277
  _for_until,
2278
- _get_serialize_reason,
2279
2278
  _hoist,
2280
2279
  _html,
2281
2280
  _id,
@@ -2285,6 +2284,7 @@ function NOOP3() {
2285
2284
  _resume_branch,
2286
2285
  _scope,
2287
2286
  _scope_id,
2287
+ _scope_reason,
2288
2288
  _scope_with_id,
2289
2289
  _script,
2290
2290
  _sep,
package/dist/html.mjs CHANGED
@@ -1087,7 +1087,7 @@ function getScopeById(scopeId) {
1087
1087
  function _set_serialize_reason(reason) {
1088
1088
  $chunk.boundary.state.serializeReason = reason;
1089
1089
  }
1090
- function _get_serialize_reason() {
1090
+ function _scope_reason() {
1091
1091
  let reason = $chunk.boundary.state.serializeReason;
1092
1092
  return $chunk.boundary.state.serializeReason = void 0, reason;
1093
1093
  }
@@ -2188,7 +2188,6 @@ export {
2188
2188
  _for_of,
2189
2189
  _for_to,
2190
2190
  _for_until,
2191
- _get_serialize_reason,
2192
2191
  _hoist,
2193
2192
  _html,
2194
2193
  _id,
@@ -2198,6 +2197,7 @@ export {
2198
2197
  _resume_branch,
2199
2198
  writeScope as _scope,
2200
2199
  _scope_id,
2200
+ _scope_reason,
2201
2201
  _scope_with_id,
2202
2202
  _script,
2203
2203
  _sep,
@@ -2650,80 +2650,85 @@ var import_compiler14 = require("@marko/compiler");
2650
2650
 
2651
2651
  // src/translator/util/with-comment.ts
2652
2652
  function withLeadingComment(node, value) {
2653
- const comment = {
2654
- type: "CommentBlock",
2655
- value: ` ${value} `
2656
- };
2657
- node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
2653
+ if (value) {
2654
+ const comment = {
2655
+ type: "CommentBlock",
2656
+ value: ` ${value} `
2657
+ };
2658
+ node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
2659
+ }
2658
2660
  return node;
2659
2661
  }
2660
2662
 
2661
2663
  // src/translator/util/serialize-guard.ts
2662
- function getSerializeGuard(reason, optional) {
2663
- return !reason ? import_compiler14.types.numericLiteral(0) : reason === true || reason.state ? optional ? void 0 : reason === true ? import_compiler14.types.numericLiteral(1) : withLeadingComment(
2664
- import_compiler14.types.numericLiteral(1),
2665
- mapToString(reason.state, ", ", getDebugName)
2666
- ) : getInputSerializeReasonGuard(reason);
2664
+ function getSerializeGuard(section, reason, optional) {
2665
+ if (!isReasonDynamic(reason)) {
2666
+ return reason ? optional ? void 0 : withLeadingComment(
2667
+ import_compiler14.types.numericLiteral(1),
2668
+ getDebugNames(reason === true ? void 0 : reason.state)
2669
+ ) : import_compiler14.types.numericLiteral(0);
2670
+ }
2671
+ let expr;
2672
+ for (const [paramsSection, params] of groupParamsBySection(reason.param)) {
2673
+ if (!isSameOrChildSection(paramsSection, section)) {
2674
+ return optional ? void 0 : withLeadingComment(import_compiler14.types.numericLiteral(1), getDebugNames(params));
2675
+ }
2676
+ const serializeIdentifier = import_compiler14.types.identifier(
2677
+ getSharedUid(`scope${paramsSection.id}_reason`, paramsSection)
2678
+ );
2679
+ const guard = paramsSection.paramReasonGroups ? callRuntime(
2680
+ "_serialize_guard",
2681
+ serializeIdentifier,
2682
+ withLeadingComment(
2683
+ import_compiler14.types.numericLiteral(getParamReasonGroupIndex(paramsSection, params)),
2684
+ getDebugNames(params)
2685
+ )
2686
+ ) : serializeIdentifier;
2687
+ expr = expr ? import_compiler14.types.logicalExpression("||", expr, guard) : guard;
2688
+ }
2689
+ return expr;
2667
2690
  }
2668
- function getSerializeGuardForAny(reasons, optional) {
2691
+ function getSerializeGuardForAny(section, reasons, optional) {
2669
2692
  if (!reasons || reasons === true) {
2670
- return getSerializeGuard(reasons, optional);
2693
+ return getSerializeGuard(section, reasons, optional);
2671
2694
  }
2672
2695
  if (reasons.length === 1) {
2673
- return getSerializeGuard(reasons[0], optional);
2696
+ return getSerializeGuard(section, reasons[0], optional);
2674
2697
  }
2675
2698
  let expr;
2676
2699
  for (const reason of reasons) {
2677
- if (reason.state) {
2678
- return optional ? void 0 : withLeadingComment(
2679
- import_compiler14.types.numericLiteral(1),
2680
- mapToString(reason.state, ", ", getDebugName)
2681
- );
2700
+ if (!isReasonDynamic(reason)) {
2701
+ return optional ? void 0 : withLeadingComment(import_compiler14.types.numericLiteral(1), getDebugNames(reason.state));
2682
2702
  }
2683
- const guard = getSerializeGuard(reason, false);
2703
+ const guard = getSerializeGuard(section, reason, false);
2684
2704
  expr = expr ? import_compiler14.types.logicalExpression("||", expr, guard) : guard;
2685
2705
  }
2686
2706
  return expr;
2687
2707
  }
2688
- function getExprIfSerialized(reason, expr) {
2708
+ function getExprIfSerialized(section, reason, expr) {
2689
2709
  if (!isReasonDynamic(reason)) {
2690
2710
  return reason && expr;
2691
2711
  }
2692
2712
  let orExpr;
2693
- for (const [section, reasons] of groupParamsBySection(reason.param)) {
2713
+ for (const [paramsSection, params] of groupParamsBySection(reason.param)) {
2714
+ if (!isSameOrChildSection(paramsSection, section)) {
2715
+ return expr;
2716
+ }
2694
2717
  const serializeIdentifier = import_compiler14.types.identifier(
2695
- getSharedUid("serialize", section)
2718
+ getSharedUid(`scope${paramsSection.id}_reason`, paramsSection)
2696
2719
  );
2697
- const guard = section.paramReasonGroups ? callRuntime(
2720
+ const guard = paramsSection.paramReasonGroups ? callRuntime(
2698
2721
  "_serialize_if",
2699
2722
  serializeIdentifier,
2700
2723
  withLeadingComment(
2701
- import_compiler14.types.numericLiteral(getParamReasonGroupIndex(section, reasons)),
2702
- mapToString(reasons, ", ", getDebugName)
2724
+ import_compiler14.types.numericLiteral(getParamReasonGroupIndex(paramsSection, params)),
2725
+ getDebugNames(params)
2703
2726
  )
2704
2727
  ) : serializeIdentifier;
2705
2728
  orExpr = orExpr ? import_compiler14.types.logicalExpression("||", orExpr, guard) : guard;
2706
2729
  }
2707
2730
  return import_compiler14.types.logicalExpression("&&", orExpr, expr);
2708
2731
  }
2709
- function getInputSerializeReasonGuard(reason) {
2710
- let expr;
2711
- for (const [section, reasons] of groupParamsBySection(reason.param)) {
2712
- const serializeIdentifier = import_compiler14.types.identifier(
2713
- getSharedUid("serialize", section)
2714
- );
2715
- const guard = section.paramReasonGroups ? callRuntime(
2716
- "_serialize_guard",
2717
- serializeIdentifier,
2718
- withLeadingComment(
2719
- import_compiler14.types.numericLiteral(getParamReasonGroupIndex(section, reasons)),
2720
- mapToString(reasons, ", ", getDebugName)
2721
- )
2722
- ) : serializeIdentifier;
2723
- expr = expr ? import_compiler14.types.logicalExpression("||", expr, guard) : guard;
2724
- }
2725
- return expr;
2726
- }
2727
2732
 
2728
2733
  // src/translator/util/walks.ts
2729
2734
  var import_compiler15 = require("@marko/compiler");
@@ -2992,7 +2997,7 @@ function markNode(path5, nodeBinding, reason) {
2992
2997
  "_el_resume",
2993
2998
  getScopeIdIdentifier(section),
2994
2999
  getScopeAccessorLiteral(nodeBinding),
2995
- getSerializeGuard(reason, true)
3000
+ getSerializeGuard(section, reason, true)
2996
3001
  )}`;
2997
3002
  }
2998
3003
  }
@@ -3354,20 +3359,15 @@ function initValue(binding, isLet = false) {
3354
3359
  const signal = getSignal(section, binding);
3355
3360
  signal.build = () => {
3356
3361
  const fn = getSignalFn(signal);
3357
- const isParamBinding = !binding.upstreamAlias && (binding.type === 3 /* param */ || binding.type === 4 /* local */ || binding.type === 2 /* input */);
3358
- const isNakedAlias = binding.upstreamAlias && binding.property === void 0 && binding.excludeProperties === void 0;
3359
- const needsGuard = !isNakedAlias && (binding.closureSections || binding.downstreamExpressions.size || fn.type === "ArrowFunctionExpression" && fn.body.body.length > 0);
3360
- const needsCache = needsGuard || signal.intersection;
3361
- const needsMarks = isParamBinding || signal.intersection;
3362
- if (needsCache || needsMarks || binding.hoists.size) {
3363
- return callRuntime(
3364
- isLet ? "_let" : "_const",
3365
- getScopeAccessorLiteral(binding, isLet),
3366
- fn
3367
- );
3368
- } else {
3362
+ const isDirectAlias = binding.upstreamAlias && binding.property === void 0 && binding.excludeProperties === void 0;
3363
+ if (isDirectAlias || !signalHasStatements(signal)) {
3369
3364
  return fn;
3370
3365
  }
3366
+ return callRuntime(
3367
+ isLet ? "_let" : "_const",
3368
+ getScopeAccessorLiteral(binding, isLet),
3369
+ fn
3370
+ );
3371
3371
  };
3372
3372
  signal.valueAccessor = getScopeAccessorLiteral(binding);
3373
3373
  for (const alias of binding.aliases) {
@@ -3379,12 +3379,12 @@ function initValue(binding, isLet = false) {
3379
3379
  return signal;
3380
3380
  }
3381
3381
  function signalHasStatements(signal) {
3382
- if (signal.render.length || signal.effect.length || signal.values.length || signal.intersection) {
3382
+ if (signal.extraArgs || signal.render.length || signal.effect.length || signal.values.length || signal.intersection) {
3383
3383
  return true;
3384
3384
  }
3385
3385
  const binding = signal.referencedBindings;
3386
3386
  if (binding) {
3387
- if (!Array.isArray(binding) && binding.section === signal.section && (binding.aliases.size || binding.propertyAliases.size)) {
3387
+ if (!Array.isArray(binding) && (binding.closureSections || binding.type === 0 /* dom */ || binding.section === signal.section && (binding.hoists.size || binding.aliases.size || binding.propertyAliases.size))) {
3388
3388
  return true;
3389
3389
  }
3390
3390
  } else if (signal.section.referencedClosures) {
@@ -3411,7 +3411,7 @@ function getSignalFn(signal) {
3411
3411
  if (isValue) {
3412
3412
  for (const alias of binding.aliases) {
3413
3413
  const aliasSignal = getSignal(alias.section, alias);
3414
- if (aliasSignal.render.length || aliasSignal.values.length || aliasSignal.effect.length) {
3414
+ if (signalHasStatements(aliasSignal)) {
3415
3415
  if (alias.excludeProperties !== void 0) {
3416
3416
  const props = [];
3417
3417
  const aliasId = import_compiler22.types.identifier(alias.name);
@@ -3474,8 +3474,7 @@ function getSignalFn(signal) {
3474
3474
  }
3475
3475
  }
3476
3476
  for (const value of signal.values) {
3477
- const valSignal = value.signal;
3478
- if (!valSignal.referencedBindings || Array.isArray(valSignal.referencedBindings) || !valSignal.referencedBindings.upstreamAlias || valSignal.referencedBindings.property !== void 0 || valSignal.referencedBindings.excludeProperties !== void 0 || valSignal.effect.length || valSignal.render.length || valSignal.values.length) {
3477
+ if (signalHasStatements(value.signal)) {
3479
3478
  signal.render.push(
3480
3479
  import_compiler22.types.expressionStatement(
3481
3480
  import_compiler22.types.callExpression(value.signal.identifier, [
@@ -3486,7 +3485,14 @@ function getSignalFn(signal) {
3486
3485
  )
3487
3486
  );
3488
3487
  } else {
3489
- signal.render.push(import_compiler22.types.expressionStatement(value.value));
3488
+ signal.render.push(
3489
+ import_compiler22.types.expressionStatement(
3490
+ withLeadingComment(
3491
+ value.value,
3492
+ getDebugNames(value.signal.referencedBindings)
3493
+ )
3494
+ )
3495
+ );
3490
3496
  }
3491
3497
  }
3492
3498
  forEach(signal.intersection, (intersection) => {
@@ -3782,15 +3788,7 @@ function writeSignals(section) {
3782
3788
  );
3783
3789
  }
3784
3790
  let value = signal.build();
3785
- if (!value) {
3786
- return;
3787
- }
3788
- if (
3789
- // It's possible for aliases to render nothing
3790
- // if they're only consumed in effects/closures.
3791
- // This ignores writing out those signals in that case.
3792
- signal.referencedBindings && !Array.isArray(signal.referencedBindings) && signal.referencedBindings.upstreamAlias && signal.referencedBindings.property === void 0 && signal.referencedBindings.excludeProperties === void 0 && import_compiler22.types.isFunction(value) && import_compiler22.types.isBlockStatement(value.body) && !value.body.body.length
3793
- ) {
3791
+ if (!value || !signal.register && import_compiler22.types.isFunction(value) && import_compiler22.types.isBlockStatement(value.body) && !value.body.body.length) {
3794
3792
  return;
3795
3793
  }
3796
3794
  if (import_compiler22.types.isCallExpression(value)) {
@@ -4064,7 +4062,11 @@ function writeHTMLResumeStatements(path5) {
4064
4062
  serializedProperties.push(
4065
4063
  toObjectProperty(
4066
4064
  accessor,
4067
- sectionSerializeReason && (sectionSerializeReason === reason || sectionSerializeReason !== true && reason !== true && compareSources(sectionSerializeReason, reason) === 0) ? getDeclaredBindingExpression(binding) : getExprIfSerialized(reason, getDeclaredBindingExpression(binding))
4065
+ sectionSerializeReason && (sectionSerializeReason === reason || sectionSerializeReason !== true && reason !== true && compareSources(sectionSerializeReason, reason) === 0) ? getDeclaredBindingExpression(binding) : getExprIfSerialized(
4066
+ section,
4067
+ reason,
4068
+ getDeclaredBindingExpression(binding)
4069
+ )
4068
4070
  )
4069
4071
  );
4070
4072
  if (debug) {
@@ -4098,14 +4100,14 @@ function writeHTMLResumeStatements(path5) {
4098
4100
  serializedProperties.push(
4099
4101
  toObjectProperty(
4100
4102
  ownerAccessor,
4101
- sectionSerializeReason && (sectionSerializeReason === ownerReason || sectionSerializeReason !== true && ownerReason !== true && compareSources(sectionSerializeReason, ownerReason) === 0) ? getOwnerExpr : getExprIfSerialized(ownerReason, getOwnerExpr)
4103
+ sectionSerializeReason && (sectionSerializeReason === ownerReason || sectionSerializeReason !== true && ownerReason !== true && compareSources(sectionSerializeReason, ownerReason) === 0) ? getOwnerExpr : getExprIfSerialized(section, ownerReason, getOwnerExpr)
4102
4104
  )
4103
4105
  );
4104
4106
  }
4105
4107
  }
4106
4108
  for (const [key, { expression, reason }] of serializedLookup) {
4107
4109
  serializedProperties.push(
4108
- toObjectProperty(key, getExprIfSerialized(reason, expression))
4110
+ toObjectProperty(key, getExprIfSerialized(section, reason, expression))
4109
4111
  );
4110
4112
  }
4111
4113
  if (sectionSerializeReason) {
@@ -4129,15 +4131,15 @@ function writeHTMLResumeStatements(path5) {
4129
4131
  writeScopeArgs.push(import_compiler22.types.objectExpression(debugVars));
4130
4132
  }
4131
4133
  }
4132
- let writeScopeCall = writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs);
4133
- if (sectionSerializeReason !== true && !sectionSerializeReason.state) {
4134
- writeScopeCall = import_compiler22.types.logicalExpression(
4135
- "&&",
4136
- getSerializeGuard(sectionSerializeReason, false),
4137
- writeScopeCall
4138
- );
4139
- }
4140
- body.push(import_compiler22.types.expressionStatement(writeScopeCall));
4134
+ body.push(
4135
+ import_compiler22.types.expressionStatement(
4136
+ getExprIfSerialized(
4137
+ section,
4138
+ sectionSerializeReason,
4139
+ writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs)
4140
+ )
4141
+ )
4142
+ );
4141
4143
  }
4142
4144
  const resumeClosestBranch = !section.isBranch && (section.hasAbortSignal || !!section.referencedClosures || !!find(section.bindings, (binding) => binding.type === 1 /* let */));
4143
4145
  if (resumeClosestBranch) {
@@ -4189,12 +4191,15 @@ function replaceAssignedNode(node) {
4189
4191
  case "UpdateExpression": {
4190
4192
  const { extra } = node.argument;
4191
4193
  if (isAssignedBindingExtra(extra)) {
4192
- const buildAssignment = getBuildAssignment(extra);
4193
- if (buildAssignment) {
4194
+ const builtAssignment = getBuildAssignment(extra)?.(
4195
+ extra.section,
4196
+ node
4197
+ );
4198
+ if (builtAssignment) {
4194
4199
  if (!node.prefix) {
4195
4200
  node.prefix = true;
4196
4201
  const replacement = import_compiler22.types.sequenceExpression([
4197
- buildAssignment(extra.section, node),
4202
+ builtAssignment,
4198
4203
  import_compiler22.types.binaryExpression(
4199
4204
  node.operator === "++" ? "-" : "+",
4200
4205
  node.argument,
@@ -4204,7 +4209,7 @@ function replaceAssignedNode(node) {
4204
4209
  updateExpressions.add(replacement);
4205
4210
  return replacement;
4206
4211
  }
4207
- return buildAssignment(extra.section, node);
4212
+ return builtAssignment;
4208
4213
  }
4209
4214
  }
4210
4215
  break;
@@ -4214,27 +4219,20 @@ function replaceAssignedNode(node) {
4214
4219
  case "Identifier": {
4215
4220
  const { extra } = node.left;
4216
4221
  if (isAssignedBindingExtra(extra)) {
4217
- const buildAssignment = getBuildAssignment(extra);
4218
- if (buildAssignment) {
4219
- if (bindingUtil.has(
4222
+ return getBuildAssignment(extra)?.(
4223
+ extra.section,
4224
+ bindingUtil.has(
4220
4225
  extra.fnExtra?.referencedBindingsInFunction,
4221
4226
  extra.assignment
4222
- )) {
4223
- return buildAssignment(extra.section, node);
4224
- } else {
4225
- return buildAssignment(
4226
- extra.section,
4227
- node.operator === "=" ? node.right : import_compiler22.types.binaryExpression(
4228
- node.operator.slice(
4229
- 0,
4230
- -1
4231
- ),
4232
- node.left,
4233
- node.right
4234
- )
4235
- );
4236
- }
4237
- }
4227
+ ) ? node : node.operator === "=" ? node.right : import_compiler22.types.binaryExpression(
4228
+ node.operator.slice(
4229
+ 0,
4230
+ -1
4231
+ ),
4232
+ node.left,
4233
+ node.right
4234
+ )
4235
+ ) || extra?.assignment && withLeadingComment(node.right, getDebugName(extra.assignment));
4238
4236
  }
4239
4237
  break;
4240
4238
  }
@@ -4247,18 +4245,27 @@ function replaceAssignedNode(node) {
4247
4245
  if (isAssignedBindingExtra(extra)) {
4248
4246
  const buildAssignment = getBuildAssignment(extra);
4249
4247
  if (buildAssignment) {
4250
- if (!bindingUtil.has(
4251
- extra.fnExtra?.referencedBindingsInFunction,
4252
- extra.assignment
4253
- )) {
4254
- id.name = generateUid(id.name);
4255
- (params ||= []).push(import_compiler22.types.identifier(id.name));
4256
- }
4257
- (assignments ||= []).push(
4258
- buildAssignment(extra.section, import_compiler22.types.identifier(id.name))
4248
+ const uid = generateUid(id.name);
4249
+ const builtAssignment = buildAssignment(
4250
+ extra.section,
4251
+ import_compiler22.types.identifier(uid)
4259
4252
  );
4253
+ if (builtAssignment) {
4254
+ if (!bindingUtil.has(
4255
+ extra.fnExtra?.referencedBindingsInFunction,
4256
+ extra.assignment
4257
+ )) {
4258
+ id.name = uid;
4259
+ }
4260
+ (params ||= []).push(import_compiler22.types.identifier(uid));
4261
+ (assignments ||= []).push(builtAssignment);
4262
+ return;
4263
+ }
4260
4264
  }
4261
4265
  }
4266
+ if (extra?.assignment) {
4267
+ (params ||= []).push(import_compiler22.types.identifier(id.name));
4268
+ }
4262
4269
  });
4263
4270
  if (assignments) {
4264
4271
  const resultId = generateUid("result");
@@ -4370,22 +4377,25 @@ var dom_default = {
4370
4377
  if (childSection !== section) {
4371
4378
  forEach(childSection.referencedClosures, (closure) => {
4372
4379
  const closureSignal = getSignal(childSection, closure);
4373
- addStatement(
4374
- "render",
4375
- childSection,
4376
- void 0,
4377
- import_compiler23.types.expressionStatement(
4378
- import_compiler23.types.callExpression(
4379
- isDynamicClosure(childSection, closure) ? closureSignal.identifier : import_compiler23.types.memberExpression(
4380
- closureSignal.identifier,
4381
- import_compiler23.types.identifier("_")
4382
- ),
4383
- [scopeIdentifier]
4380
+ if (signalHasStatements(closureSignal)) {
4381
+ addStatement(
4382
+ "render",
4383
+ childSection,
4384
+ void 0,
4385
+ import_compiler23.types.expressionStatement(
4386
+ import_compiler23.types.callExpression(
4387
+ isDynamicClosure(childSection, closure) ? closureSignal.identifier : import_compiler23.types.memberExpression(
4388
+ closureSignal.identifier,
4389
+ import_compiler23.types.identifier("_")
4390
+ ),
4391
+ [scopeIdentifier]
4392
+ )
4384
4393
  )
4385
- )
4386
- );
4394
+ );
4395
+ }
4387
4396
  });
4388
4397
  const tagParamsSignal = childSection.params && initValue(childSection.params);
4398
+ const tagParamsIdentifier = tagParamsSignal && signalHasStatements(tagParamsSignal) ? tagParamsSignal.identifier : void 0;
4389
4399
  const { walks: walks2, writes: writes2, setup: setup2, decls: decls2 } = getSectionMeta(childSection);
4390
4400
  writeSignals(childSection);
4391
4401
  if (!childSection.downstreamBinding || bindingHasDownstreamExpressions(childSection.downstreamBinding)) {
@@ -4395,7 +4405,7 @@ var dom_default = {
4395
4405
  writes2,
4396
4406
  walks2,
4397
4407
  setup2,
4398
- tagParamsSignal?.identifier
4408
+ tagParamsIdentifier
4399
4409
  ])
4400
4410
  ) : callRuntime(
4401
4411
  getSectionRegisterReasons(childSection) ? "_content_resume" : "_content",
@@ -4404,30 +4414,33 @@ var dom_default = {
4404
4414
  writes2,
4405
4415
  walks2,
4406
4416
  setup2,
4407
- tagParamsSignal?.identifier,
4417
+ tagParamsIdentifier,
4408
4418
  childSection.hoisted || childSection.isHoistThrough ? getSectionInstancesAccessorLiteral(childSection) : void 0
4409
4419
  ])
4410
4420
  );
4411
4421
  if (childSection.referencedLocalClosures) {
4412
- renderer = callRuntime(
4413
- "_content_closures",
4414
- renderer,
4415
- import_compiler23.types.objectExpression(
4416
- toArray(childSection.referencedLocalClosures, (closure) => {
4417
- const expr = getSignalFn(getSignal(childSection, closure));
4418
- const key = toPropertyName(getScopeAccessor(closure));
4419
- if (import_compiler23.types.isFunction(expr) && import_compiler23.types.isBlockStatement(expr.body)) {
4420
- return import_compiler23.types.objectMethod(
4421
- "method",
4422
- key,
4423
- expr.params,
4424
- expr.body
4425
- );
4426
- }
4427
- return import_compiler23.types.objectProperty(key, expr);
4428
- })
4429
- )
4430
- );
4422
+ const objProps = [];
4423
+ forEach(childSection.referencedLocalClosures, (closure) => {
4424
+ const closureSignal = getSignal(childSection, closure);
4425
+ const key = toPropertyName(getScopeAccessor(closure));
4426
+ if (signalHasStatements(closureSignal)) {
4427
+ const expr = getSignalFn(closureSignal);
4428
+ if (import_compiler23.types.isFunction(expr) && import_compiler23.types.isBlockStatement(expr.body)) {
4429
+ objProps.push(
4430
+ import_compiler23.types.objectMethod("method", key, expr.params, expr.body)
4431
+ );
4432
+ } else {
4433
+ objProps.push(import_compiler23.types.objectProperty(key, expr));
4434
+ }
4435
+ }
4436
+ });
4437
+ if (objProps.length) {
4438
+ renderer = callRuntime(
4439
+ "_content_closures",
4440
+ renderer,
4441
+ import_compiler23.types.objectExpression(objProps)
4442
+ );
4443
+ }
4431
4444
  }
4432
4445
  program.node.body.push(
4433
4446
  import_compiler23.types.variableDeclaration("const", [
@@ -4521,8 +4534,8 @@ var html_default = {
4521
4534
  renderContent.push(
4522
4535
  import_compiler24.types.variableDeclaration("const", [
4523
4536
  import_compiler24.types.variableDeclarator(
4524
- import_compiler24.types.identifier(getSharedUid("serialize", section)),
4525
- callRuntime("_get_serialize_reason")
4537
+ import_compiler24.types.identifier(getSharedUid(`scope${section.id}_reason`, section)),
4538
+ callRuntime("_scope_reason")
4526
4539
  )
4527
4540
  ])
4528
4541
  );
@@ -5285,6 +5298,7 @@ var native_tag_default = {
5285
5298
  getScopeIdIdentifier(tagSection),
5286
5299
  usedAttrs.staticContentAttr.value,
5287
5300
  getSerializeGuard(
5301
+ tagSection,
5288
5302
  nodeBinding && getSerializeReason(tagSection, nodeBinding),
5289
5303
  true
5290
5304
  )
@@ -5293,6 +5307,7 @@ var native_tag_default = {
5293
5307
  ];
5294
5308
  } else if (spreadExpression && !hasChildren) {
5295
5309
  const serializeReason = getSerializeGuard(
5310
+ tagSection,
5296
5311
  nodeBinding && getSerializeReason(tagSection, nodeBinding),
5297
5312
  true
5298
5313
  );
@@ -6042,10 +6057,12 @@ var for_default = {
6042
6057
  if (branchSerializeReason) {
6043
6058
  const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
6044
6059
  const statefulSerializeArg = getSerializeGuard(
6060
+ tagSection,
6045
6061
  getSerializeReason(tagSection, kStatefulReason),
6046
6062
  !(skipParentEnd || singleNodeOptimization)
6047
6063
  );
6048
6064
  const markerSerializeArg = getSerializeGuard(
6065
+ tagSection,
6049
6066
  markerSerializeReason,
6050
6067
  !statefulSerializeArg
6051
6068
  );
@@ -6053,7 +6070,11 @@ var for_default = {
6053
6070
  forAttrs.by || import_compiler31.types.numericLiteral(0),
6054
6071
  getScopeIdIdentifier(tagSection),
6055
6072
  getScopeAccessorLiteral(nodeBinding),
6056
- getSerializeGuard(branchSerializeReason, !markerSerializeArg),
6073
+ getSerializeGuard(
6074
+ tagSection,
6075
+ branchSerializeReason,
6076
+ !markerSerializeArg
6077
+ ),
6057
6078
  markerSerializeArg,
6058
6079
  statefulSerializeArg
6059
6080
  );
@@ -6604,8 +6625,10 @@ function buildContent(body) {
6604
6625
  body.node.body.unshift(
6605
6626
  import_compiler32.types.variableDeclaration("const", [
6606
6627
  import_compiler32.types.variableDeclarator(
6607
- import_compiler32.types.identifier(getSharedUid("serialize", bodySection)),
6608
- callRuntime("_get_serialize_reason")
6628
+ import_compiler32.types.identifier(
6629
+ getSharedUid(`scope${bodySection.id}_reason`, bodySection)
6630
+ ),
6631
+ callRuntime("_scope_reason")
6609
6632
  )
6610
6633
  ])
6611
6634
  );
@@ -6756,7 +6779,7 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6756
6779
  if (contentSection.paramReasonGroups.length === 1) {
6757
6780
  const [group] = contentSection.paramReasonGroups;
6758
6781
  const reason = getSerializeReason(section, childScopeBinding, group.id);
6759
- childSerializeReasonExpr = reason && getSerializeGuard(reason, false);
6782
+ childSerializeReasonExpr = reason && getSerializeGuard(section, reason, false);
6760
6783
  } else {
6761
6784
  const props = [];
6762
6785
  let hasDynamicReasons = false;
@@ -6770,9 +6793,9 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
6770
6793
  import_compiler33.types.objectProperty(
6771
6794
  withLeadingComment(
6772
6795
  import_compiler33.types.numericLiteral(i),
6773
- mapToString(group.reason, ", ", getDebugName)
6796
+ getDebugNames(group.reason)
6774
6797
  ),
6775
- getSerializeGuard(reason, false)
6798
+ getSerializeGuard(section, reason, false)
6776
6799
  )
6777
6800
  );
6778
6801
  } else {
@@ -8040,6 +8063,8 @@ function finalizeReferences() {
8040
8063
  }
8041
8064
  }
8042
8065
  }
8066
+ });
8067
+ forEachSection((section) => {
8043
8068
  forEach(section.referencedLocalClosures, (closure) => {
8044
8069
  addSerializeReason(
8045
8070
  section,
@@ -8048,41 +8073,39 @@ function finalizeReferences() {
8048
8073
  );
8049
8074
  });
8050
8075
  forEach(section.referencedClosures, (closure) => {
8051
- if (!isForceSerialized(closure.section, closure)) {
8052
- const sourceSection = closure.section;
8053
- let serializeReason;
8054
- let currentSection = section;
8055
- while (currentSection !== sourceSection) {
8056
- const upstreamReason = currentSection.downstreamBinding ? getSectionRegisterReasons(currentSection) || void 0 : !currentSection.upstreamExpression || getSerializeSourcesForExpr(currentSection.upstreamExpression);
8057
- if (upstreamReason === true) {
8058
- serializeReason = true;
8059
- break;
8060
- }
8061
- serializeReason = mergeSerializeReasons(
8062
- serializeReason,
8063
- upstreamReason
8064
- );
8065
- currentSection = currentSection.parent;
8076
+ const sourceSection = closure.section;
8077
+ let currentSection = section;
8078
+ let branchesReason;
8079
+ while (currentSection !== sourceSection) {
8080
+ const upstreamReason = currentSection.downstreamBinding ? getSectionRegisterReasons(currentSection) || void 0 : !currentSection.upstreamExpression || getSerializeSourcesForExpr(currentSection.upstreamExpression);
8081
+ if (upstreamReason === true) {
8082
+ branchesReason = true;
8083
+ break;
8066
8084
  }
8067
- addSerializeReason(closure.section, serializeReason, closure);
8085
+ branchesReason = mergeSerializeReasons(branchesReason, upstreamReason);
8086
+ currentSection = currentSection.parent;
8068
8087
  }
8088
+ addSerializeReason(sourceSection, branchesReason, closure);
8069
8089
  addSerializeReason(
8070
- closure.section,
8071
- getSerializeReason(closure.section, closure)
8090
+ sourceSection,
8091
+ getSerializeReason(sourceSection, closure)
8072
8092
  );
8073
- if (closure.sources && isDynamicClosure(section, closure)) {
8074
- addSerializeReason(
8075
- closure.section,
8076
- closure.sources,
8077
- closure,
8078
- getAccessorPrefix().ClosureScopes
8079
- );
8080
- addSerializeReason(
8081
- section,
8082
- closure.sources,
8083
- closure,
8084
- getAccessorPrefix().ClosureSignalIndex
8085
- );
8093
+ if (isDynamicClosure(section, closure)) {
8094
+ addOwnerSerializeReason(section, sourceSection, branchesReason);
8095
+ if (closure.sources) {
8096
+ addSerializeReason(
8097
+ sourceSection,
8098
+ closure.sources,
8099
+ closure,
8100
+ getAccessorPrefix().ClosureScopes
8101
+ );
8102
+ addSerializeReason(
8103
+ section,
8104
+ closure.sources,
8105
+ closure,
8106
+ getAccessorPrefix().ClosureSignalIndex
8107
+ );
8108
+ }
8086
8109
  }
8087
8110
  });
8088
8111
  });
@@ -8400,6 +8423,9 @@ function getDebugName(binding) {
8400
8423
  const { root, access } = getDebugScopeAccess(binding);
8401
8424
  return root.name + access;
8402
8425
  }
8426
+ function getDebugNames(refs) {
8427
+ return mapToString(refs, ", ", getDebugName);
8428
+ }
8403
8429
  function getSectionInstancesAccessor(section) {
8404
8430
  return section.sectionAccessor ? section.sectionAccessor.prefix + getScopeAccessor(section.sectionAccessor.binding) : getAccessorPrefix().ClosureScopes + section.id;
8405
8431
  }
@@ -8704,7 +8730,7 @@ var await_default = {
8704
8730
  node.body.params,
8705
8731
  toFirstExpressionOrBlock(node.body.body)
8706
8732
  ),
8707
- getSerializeGuard(bodySection?.serializeReason, true)
8733
+ getSerializeGuard(section, bodySection?.serializeReason, true)
8708
8734
  )
8709
8735
  )
8710
8736
  )[0].skip();
@@ -10313,10 +10339,12 @@ var IfTag = {
10313
10339
  getParentTag(ifTag).node.extra[kSkipEndTag] = true;
10314
10340
  }
10315
10341
  const statefulSerializeArg = getSerializeGuard(
10342
+ ifTagSection,
10316
10343
  getSerializeReason(ifTagSection, kStatefulReason2),
10317
10344
  !(skipParentEnd || singleNodeOptimization)
10318
10345
  );
10319
10346
  const markerSerializeArg = getSerializeGuard(
10347
+ ifTagSection,
10320
10348
  markerSerializeReason,
10321
10349
  !statefulSerializeArg
10322
10350
  );
@@ -10331,6 +10359,7 @@ var IfTag = {
10331
10359
  getScopeIdIdentifier(ifTagSection),
10332
10360
  getScopeAccessorLiteral(nodeBinding),
10333
10361
  getSerializeGuardForAny(
10362
+ ifTagSection,
10334
10363
  branchSerializeReasons,
10335
10364
  !markerSerializeArg
10336
10365
  ),
@@ -10637,8 +10666,12 @@ var let_default = {
10637
10666
  signal.extraArgs = [valueChangeAttr.value];
10638
10667
  }
10639
10668
  signal.buildAssignment = (valueSection, value) => {
10640
- const scope = getScopeExpression(valueSection, signal.section);
10641
- return import_compiler48.types.callExpression(signal.identifier, [scope, value]);
10669
+ if (valueChangeAttr || signalHasStatements(signal)) {
10670
+ return import_compiler48.types.callExpression(signal.identifier, [
10671
+ getScopeExpression(valueSection, signal.section),
10672
+ value
10673
+ ]);
10674
+ }
10642
10675
  };
10643
10676
  } else {
10644
10677
  translateVar(tag, valueAttr.value, "let");
@@ -11430,7 +11463,7 @@ var placeholder_default = {
11430
11463
  if (markerSerializeReason === true || markerSerializeReason.state) {
11431
11464
  write`<!>`;
11432
11465
  } else {
11433
- write`${callRuntime("_sep", getSerializeGuard(markerSerializeReason, true))}`;
11466
+ write`${callRuntime("_sep", getSerializeGuard(section, markerSerializeReason, true))}`;
11434
11467
  }
11435
11468
  }
11436
11469
  visit(placeholder, 37 /* Replace */);
@@ -12074,6 +12107,7 @@ var dynamic_tag_default = {
12074
12107
  flushInto(tag);
12075
12108
  writeHTMLResumeStatements(tag.get("body"));
12076
12109
  const serializeArg = getSerializeGuard(
12110
+ tagSection,
12077
12111
  getSerializeReason(tagSection, nodeBinding),
12078
12112
  true
12079
12113
  );
@@ -105,6 +105,7 @@ export declare function getDebugScopeAccess(binding: Binding): {
105
105
  access: string;
106
106
  };
107
107
  export declare function getDebugName(binding: Binding): string;
108
+ export declare function getDebugNames(refs: ReferencedBindings): string;
108
109
  export declare function getSectionInstancesAccessor(section: Section): string;
109
110
  export declare function getSectionInstancesAccessorLiteral(section: Section): t.StringLiteral | t.NumericLiteral | undefined;
110
111
  export declare function getReadReplacement(node: t.Identifier | t.MemberExpression): t.Node | undefined;
@@ -1,5 +1,6 @@
1
1
  import { types as t } from "@marko/compiler";
2
+ import { type Section } from "./sections";
2
3
  import { type SerializeReason, type SerializeReasons } from "./serialize-reasons";
3
- export declare function getSerializeGuard(reason: undefined | SerializeReason, optional: boolean): t.Expression | undefined;
4
- export declare function getSerializeGuardForAny(reasons: undefined | SerializeReasons, optional: boolean): t.Expression | undefined;
5
- export declare function getExprIfSerialized<T extends undefined | SerializeReason, U extends t.Expression>(reason: T, expr: U): T extends {} ? U : undefined;
4
+ export declare function getSerializeGuard(section: Section, reason: undefined | SerializeReason, optional: boolean): t.Expression | undefined;
5
+ export declare function getSerializeGuardForAny(section: Section, reasons: undefined | SerializeReasons, optional: boolean): t.Expression | undefined;
6
+ export declare function getExprIfSerialized<T extends undefined | SerializeReason, U extends t.Expression>(section: Section, reason: T, expr: U): T extends {} ? U : undefined;
@@ -23,7 +23,7 @@ export type Signal = {
23
23
  export: boolean;
24
24
  extraArgs?: t.Expression[];
25
25
  prependStatements?: t.Statement[];
26
- buildAssignment?: (valueSection: Section, value: t.Expression) => t.Expression;
26
+ buildAssignment?: (valueSection: Section, value: t.Expression) => t.Expression | undefined;
27
27
  };
28
28
  type closureSignalBuilder = (closure: Binding, render: t.Expression) => t.Expression;
29
29
  export declare function setClosureSignalBuilder(tag: t.NodePath<t.MarkoTag>, builder: closureSignalBuilder): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.0.84",
3
+ "version": "6.0.86",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",