@marko/runtime-tags 6.4.7 → 6.4.8

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.
@@ -2015,7 +2015,7 @@ function finalizeRegistrations() {
2015
2015
  const programExtra = (0, _marko_compiler_babel_utils.getProgram)().node.extra;
2016
2016
  for (const fnExtra of getReferencesByFn().keys()) if (fnExtra.reason) {
2017
2017
  registerFunction(fnExtra);
2018
- programExtra.isInteractive ||= isUnconditionalReason(fnExtra.reason);
2018
+ programExtra.isInteractive ||= !isGuardedReason(fnExtra.reason);
2019
2019
  }
2020
2020
  for (const [{ node, local, registered, fnRoots }, exprExtras] of getReferencesByImport()) {
2021
2021
  const reason = fnRoots ? resolveTemplateReason(exprExtras) : resolveReason(exprExtras);
@@ -2025,7 +2025,7 @@ function finalizeRegistrations() {
2025
2025
  extra.registeredImports ??= /* @__PURE__ */ new Map();
2026
2026
  extra.registeredImports.set(local, registered);
2027
2027
  }
2028
- programExtra.isInteractive ||= isUnconditionalReason(reason);
2028
+ programExtra.isInteractive ||= !isGuardedReason(reason);
2029
2029
  }
2030
2030
  }
2031
2031
  }
@@ -2276,7 +2276,8 @@ function getBranchExprReason(section) {
2276
2276
  const { derives, branchExpr } = section;
2277
2277
  if (derives) {
2278
2278
  let reason = mergeSources(getRendererReason(section) || void 0, getSourcesForDerived(derives));
2279
- forEach(section.callSections, (callSection) => {
2279
+ forEach(section.calls, (call) => {
2280
+ const callSection = call.childScopeBinding.section;
2280
2281
  reason = mergeSources(reason, getBranchExprReasonUntil(callSection, isSameOrAncestorSection(section, callSection) ? section : section.parent));
2281
2282
  });
2282
2283
  return reason;
@@ -2304,7 +2305,8 @@ function addClosureReasons(section) {
2304
2305
  });
2305
2306
  }
2306
2307
  function addCallOwnerReasons(body) {
2307
- if (body.readsOwner) forEach(body.callSections, (callSection) => {
2308
+ if (body.readsOwner) forEach(body.calls, (call) => {
2309
+ const callSection = call.childScopeBinding.section;
2308
2310
  addOwnerReason(callSection, body.parent, getBranchExprReasonUntil(callSection, body.parent));
2309
2311
  });
2310
2312
  }
@@ -2338,13 +2340,17 @@ function getReasonForBinding(binding, properties) {
2338
2340
  function getReasonForExpr(extra) {
2339
2341
  return extra.isEffect ? ALWAYS : extraReaders(extra).reason;
2340
2342
  }
2343
+ function bindingLandsRetained(binding, properties) {
2344
+ return someRead(bindingReaders(binding, properties), isRetainedInput);
2345
+ }
2341
2346
  function landsRetained(extra) {
2342
2347
  if (extra.retained) return true;
2343
- if (!extra.isEffect) {
2344
- const { reads } = extraReaders(extra);
2345
- if (reads) {
2346
- for (const read of reads) if (read.retained) return true;
2347
- }
2348
+ if (!extra.isEffect) return someRead(extraReaders(extra), isRetained);
2349
+ return false;
2350
+ }
2351
+ function someRead({ reads }, leaf) {
2352
+ if (reads) {
2353
+ for (const [read, tagNameOnly] of reads) if (leaf(read, tagNameOnly)) return true;
2348
2354
  }
2349
2355
  return false;
2350
2356
  }
@@ -2398,7 +2404,7 @@ function computeBindingReaders(binding, properties) {
2398
2404
  if (!(head === "content" && expr.rendersContent && bindingUtil.has(expr.spreadFrom, binding))) readers = mergeReaders(readers, ALWAYS_READ);
2399
2405
  continue;
2400
2406
  }
2401
- readers = mergeReaders(withLandingRead(readers, expr), readersOfDerives(expr, binding, properties));
2407
+ readers = mergeReaders(withLandingRead(readers, expr, binding), readersOfDerives(expr, binding, properties));
2402
2408
  }
2403
2409
  for (const alias of binding.aliases) readers = mergeReaders(readers, bindingReaders(alias, properties));
2404
2410
  if (properties === void 0) return readers;
@@ -2428,16 +2434,31 @@ function mergeReaders(a, b) {
2428
2434
  reads
2429
2435
  };
2430
2436
  }
2431
- function withLandingRead(readers, read) {
2432
- return readers.reads?.has(read) ? readers : {
2437
+ function withLandingRead(readers, read, binding) {
2438
+ const had = readers.reads?.get(read);
2439
+ const tagNameOnly = (had ?? true) && every(binding.reads.get(read), isTagNameRead);
2440
+ return had === tagNameOnly ? readers : {
2433
2441
  reason: readers.reason,
2434
- reads: new Set(readers.reads).add(read)
2442
+ reads: new Map(readers.reads).set(read, tagNameOnly)
2435
2443
  };
2436
2444
  }
2445
+ function isRetainedInput(read, tagNameOnly) {
2446
+ return !tagNameOnly && isRetained(read);
2447
+ }
2448
+ function isRetained(read) {
2449
+ return !!read.retained;
2450
+ }
2451
+ function isTagNameRead({ extra }) {
2452
+ return !!extra.exprRoot?.tagName;
2453
+ }
2437
2454
  function unionReads(a, b) {
2438
2455
  if (!a || !b || a === b) return a || b;
2439
2456
  let result;
2440
- for (const read of b) if (!a.has(read)) (result ??= new Set(a)).add(read);
2457
+ for (const [read, tagNameOnly] of b) {
2458
+ const had = a.get(read);
2459
+ const merged = (had ?? true) && tagNameOnly;
2460
+ if (had !== merged) (result ??= new Map(a)).set(read, merged);
2461
+ }
2441
2462
  return result || a;
2442
2463
  }
2443
2464
  //#endregion
@@ -3001,6 +3022,191 @@ function isMarkoPlaceholder(node) {
3001
3022
  return _marko_compiler.types.isMarkoPlaceholder(node);
3002
3023
  }
3003
3024
  //#endregion
3025
+ //#region src/translator/util/with-comment.ts
3026
+ function withLeadingComment(node, value) {
3027
+ if (value) {
3028
+ const comment = {
3029
+ type: "CommentBlock",
3030
+ value: ` ${value} `
3031
+ };
3032
+ node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
3033
+ }
3034
+ return node;
3035
+ }
3036
+ //#endregion
3037
+ //#region src/translator/util/write-guard.ts
3038
+ function isSameReason(a, b) {
3039
+ return a === b || (a && b ? a.always && b.always || compareSources(a, b) === 0 : false);
3040
+ }
3041
+ const groupCheckPrefixes = {
3042
+ _write_guard: "wg",
3043
+ _write_if: "wi"
3044
+ };
3045
+ const [getSectionGuards] = createOutputSectionState((section) => ({
3046
+ hoists: /* @__PURE__ */ new Map(),
3047
+ declarators: [_marko_compiler.types.variableDeclarator(scopeReasonIdentifier(section), callRuntime("_scope_reason"))]
3048
+ }));
3049
+ function buildGroupMask(groups) {
3050
+ let mask = 0;
3051
+ let maskNames = "";
3052
+ let dynamic;
3053
+ const props = [];
3054
+ let needsObject = false;
3055
+ let any = false;
3056
+ for (let i = 0; i < groups.length; i++) {
3057
+ const { value, names } = groups[i];
3058
+ if (value === void 0) continue;
3059
+ any = true;
3060
+ if (value === 0) continue;
3061
+ if (i >= 15) needsObject = true;
3062
+ else if (typeof value === "number") {
3063
+ mask |= value << 1 + 2 * i;
3064
+ if (names) maskNames += maskNames ? ` | ${names}` : names;
3065
+ } else {
3066
+ const shifted = _marko_compiler.types.binaryExpression("<<", value, withLeadingComment(_marko_compiler.types.numericLiteral(1 + 2 * i), names));
3067
+ dynamic = dynamic ? _marko_compiler.types.binaryExpression("|", dynamic, shifted) : shifted;
3068
+ }
3069
+ props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), names), typeof value === "number" ? _marko_compiler.types.numericLiteral(value) : value));
3070
+ }
3071
+ if (needsObject) return _marko_compiler.types.objectExpression(props);
3072
+ if (!any) return;
3073
+ const literal = mask ? withLeadingComment(_marko_compiler.types.numericLiteral(mask), maskNames) : void 0;
3074
+ return literal && dynamic ? _marko_compiler.types.binaryExpression("|", literal, dynamic) : literal || dynamic || _marko_compiler.types.numericLiteral(0);
3075
+ }
3076
+ function getScopeReasonStatement(section) {
3077
+ return hasGuardedReason(section) ? _marko_compiler.types.variableDeclaration("const", getSectionGuards(section).declarators) : _marko_compiler.types.expressionStatement(callRuntime("_scope_reason"));
3078
+ }
3079
+ function getWriteReason(binding) {
3080
+ return findSlot(binding)?.reason;
3081
+ }
3082
+ function getBranchWriteReason(section) {
3083
+ return findSectionSlot(section, 9)?.reason;
3084
+ }
3085
+ function getWriteGuard(section, reason, omitUnconditional) {
3086
+ if (!isDynamicWriteGuard(section, reason)) {
3087
+ if (!reason) return _marko_compiler.types.numericLiteral(0);
3088
+ return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.always ? void 0 : reason.state));
3089
+ }
3090
+ const bit = getGroupsBit(reason.param);
3091
+ if (bit !== void 0) return bit && omitUnconditional ? void 0 : _marko_compiler.types.numericLiteral(bit);
3092
+ return orEachParamGroup(reason.param, "_write_guard");
3093
+ }
3094
+ function getWriteGuardForAny(section, reasons, omitUnconditional) {
3095
+ if (!Array.isArray(reasons)) return getWriteGuard(section, reasons, omitUnconditional);
3096
+ for (const reason of reasons) if (getWriteBit(section, reason) === 1) return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.state));
3097
+ let expr;
3098
+ for (const reason of reasons) if (getWriteBit(section, reason) !== 0) expr = orGuard(expr, getWriteGuard(section, reason, false));
3099
+ return expr || _marko_compiler.types.numericLiteral(0);
3100
+ }
3101
+ function getExprIfWritten(section, reason, expr) {
3102
+ const ownReason = mapBodyParams(section, reason);
3103
+ if (!isGuardedReason(ownReason)) return ownReason && expr;
3104
+ const bit = getGroupsBit(ownReason.param);
3105
+ if (bit !== void 0) return bit ? expr : void 0;
3106
+ return andGuard(orEachParamGroup(ownReason.param, "_write_if"), expr);
3107
+ }
3108
+ function isEverWritten(section, reason) {
3109
+ const ownReason = mapBodyParams(section, reason);
3110
+ return isGuardedReason(ownReason) ? getGroupsBit(ownReason.param) !== 0 : !!ownReason;
3111
+ }
3112
+ function getWriteBit(section, reason) {
3113
+ return isDynamicWriteGuard(section, reason) ? getGroupsBit(reason.param) : reason ? 1 : 0;
3114
+ }
3115
+ function getGroupsBit(params) {
3116
+ return reduceParamGroups(params, addGroupBit, 0);
3117
+ }
3118
+ function addGroupBit(bit, section, group) {
3119
+ const groupBit = getStaticGroupBit(section, group);
3120
+ return bit === 1 || groupBit === 1 ? 1 : bit === 0 && groupBit === 0 ? 0 : void 0;
3121
+ }
3122
+ function orEachParamGroup(params, check) {
3123
+ return reduceParamGroups(params, orGroupChecks[check], void 0);
3124
+ }
3125
+ const orGroupChecks = {
3126
+ _write_guard: orGroupCheck("_write_guard"),
3127
+ _write_if: orGroupCheck("_write_if")
3128
+ };
3129
+ function orGroupCheck(check) {
3130
+ return (expr, section, group) => getStaticGroupBit(section, group) === 0 ? expr : orGuard(expr, getOrHoistSectionGuard(section, group, check));
3131
+ }
3132
+ function orGuard(guard, other) {
3133
+ return guard ? _marko_compiler.types.logicalExpression("||", guard, other) : other;
3134
+ }
3135
+ function andGuard(guard, expr) {
3136
+ return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
3137
+ }
3138
+ function getOrHoistSectionGuard(section, params, check) {
3139
+ if (!section.paramReasonGroups) return scopeReasonIdentifier(section);
3140
+ const state = getSectionGuards(section);
3141
+ let tracking = state.hoists.get(check);
3142
+ if (!tracking) state.hoists.set(check, tracking = createGuardHoists());
3143
+ const index = getParamReasonGroupIndex(section, params);
3144
+ const name = tracking.names.get(index);
3145
+ if (name) return _marko_compiler.types.identifier(name);
3146
+ const guard = callRuntime(check, scopeReasonIdentifier(section), withLeadingComment(_marko_compiler.types.numericLiteral(index), getDebugNames(params)));
3147
+ const pending = tracking.pending.get(index);
3148
+ if (!pending) {
3149
+ const expr = _marko_compiler.types.parenthesizedExpression(guard);
3150
+ tracking.pending.set(index, expr);
3151
+ return expr;
3152
+ }
3153
+ const hoisted = generateUid(`${groupCheckPrefixes[check]}__${getDebugNamesAsIdentifier(params)}`);
3154
+ tracking.names.set(index, hoisted);
3155
+ tracking.pending.delete(index);
3156
+ state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(hoisted), guard));
3157
+ pending.expression = _marko_compiler.types.identifier(hoisted);
3158
+ return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(hoisted));
3159
+ }
3160
+ function isDynamicWriteGuard(section, reason) {
3161
+ return isGuardedReason(reason) && !isCrossSection(section, reason);
3162
+ }
3163
+ function isCrossSection(section, reason) {
3164
+ return some(reason.param, (param) => !isSameOrAncestorSection(param.section, section));
3165
+ }
3166
+ const [getStaticGroupBits] = createAnalysisSectionState(() => /* @__PURE__ */ new Map());
3167
+ function getStaticGroupBit(body, group) {
3168
+ const bits = getStaticGroupBits(body);
3169
+ const index = getParamReasonGroupIndex(body, group);
3170
+ if (!bits.has(index)) {
3171
+ bits.set(index, void 0);
3172
+ bits.set(index, isOnlyCalled(body) ? getCallsBit(body, group) : void 0);
3173
+ }
3174
+ return bits.get(index);
3175
+ }
3176
+ function getCallsBit(body, group) {
3177
+ const calls = body.calls;
3178
+ let bit;
3179
+ for (const call of Array.isArray(calls) ? calls : [calls]) {
3180
+ const callSection = call.childScopeBinding.section;
3181
+ const callBit = getWriteBit(callSection, findSlot(call.childScopeBinding, 5, callSection, group)?.reason);
3182
+ if (callBit === void 0 || bit !== void 0 && bit !== callBit) return;
3183
+ bit = callBit;
3184
+ }
3185
+ return bit;
3186
+ }
3187
+ function isOnlyCalled(body) {
3188
+ return !!body.calls && !!body.derives && !some(body.derives.binding, isUsed);
3189
+ }
3190
+ function isUsed(binding) {
3191
+ return !!binding.reads.size || !!binding.aliases.size || !!binding.propertyAliases.size;
3192
+ }
3193
+ function createGuardHoists() {
3194
+ return {
3195
+ names: /* @__PURE__ */ new Map(),
3196
+ pending: /* @__PURE__ */ new Map()
3197
+ };
3198
+ }
3199
+ function hasGuardedReason(section) {
3200
+ if (section.paramReasonGroups || isGuardedReason(mapBodyParams(section, section.reason))) return true;
3201
+ return some(section.slots, isConditionalSlot);
3202
+ }
3203
+ function isConditionalSlot(slot) {
3204
+ return isGuardedReason(mapBodyParams(slot.section, slot.reason));
3205
+ }
3206
+ function scopeReasonIdentifier(section) {
3207
+ return _marko_compiler.types.identifier(ensureSharedUid(`scope${section.id}_reason`, section));
3208
+ }
3209
+ //#endregion
3004
3210
  //#region src/translator/util/sections.ts
3005
3211
  const sectionUtil = new Sorted(function compareSections(a, b) {
3006
3212
  return a.id - b.id;
@@ -3036,7 +3242,7 @@ function ensureBodySection(path) {
3036
3242
  returnValueExpr: void 0,
3037
3243
  content: getContentInfo(path),
3038
3244
  branchExpr: void 0,
3039
- callSections: void 0,
3245
+ calls: void 0,
3040
3246
  knownTags: void 0,
3041
3247
  derives: void 0,
3042
3248
  dropped: !!extra.dropped,
@@ -3081,11 +3287,23 @@ function forEachSection(fn) {
3081
3287
  sections?.forEach(fn);
3082
3288
  }
3083
3289
  function getDynamicTagContentClosures(section) {
3084
- if (section.branchExpr?.tagNameType === 2) return getClosuresFromAbove(section, section);
3290
+ const { derives } = section;
3291
+ if (section.branchExpr?.tagNameType === 2 || derives && some(derives.binding, (binding) => bindingLandsRetained(binding, derives.properties))) return bindingUtil.filter(getClosuresFromAbove(section, section, /* @__PURE__ */ new Set()), mayBeUnwritten);
3292
+ }
3293
+ function mayBeUnwritten(closure) {
3294
+ const reason = getWriteReason(closure);
3295
+ return !reason || isGuardedReason(reason);
3085
3296
  }
3086
- function getClosuresFromAbove(section, top) {
3297
+ function getClosuresFromAbove(section, top, seen) {
3087
3298
  let closures = bindingUtil.leadingRun(section.referencedClosures, bindingToSection, sectionUtil.compare, top);
3088
- for (const child of section.children) closures = bindingUtil.union(closures, getClosuresFromAbove(child, top));
3299
+ for (const child of section.children) closures = bindingUtil.union(closures, getClosuresFromAbove(child, top, seen));
3300
+ for (const tagExtra of section.knownTags || []) {
3301
+ const body = tagExtra.childSection;
3302
+ if (!seen.has(body)) {
3303
+ seen.add(body);
3304
+ closures = bindingUtil.union(closures, getClosuresFromAbove(body, isSameOrAncestorSection(top, body) ? top : body, seen));
3305
+ }
3306
+ }
3089
3307
  return closures;
3090
3308
  }
3091
3309
  function forEachAncestorSection(from, to, fn, arg) {
@@ -3197,7 +3415,7 @@ function ensureSlotReasonGroups(slot) {
3197
3415
  }
3198
3416
  function ensureReasonGroups(section, reason) {
3199
3417
  const ownReason = mapBodyParams(section, reason);
3200
- if (isConditionalReason(ownReason)) forEachParamGroup(ownReason.param, ensureParamReasonGroup);
3418
+ if (isGuardedReason(ownReason)) forEachParamGroup(ownReason.param, ensureParamReasonGroup);
3201
3419
  }
3202
3420
  function ensureParamReasonGroup(section, group) {
3203
3421
  const { paramReasonGroups } = section;
@@ -3527,7 +3745,8 @@ function finalizeSetupWork() {
3527
3745
  });
3528
3746
  }
3529
3747
  function setCallSectionsSetup(body) {
3530
- forEach(body.callSections, (callSection) => {
3748
+ forEach(body.calls, (call) => {
3749
+ const callSection = call.childScopeBinding.section;
3531
3750
  if (!callSection.hasSetupWork) {
3532
3751
  callSection.hasSetupWork = true;
3533
3752
  setCallSectionsSetup(callSection);
@@ -3840,139 +4059,6 @@ function getDestructurePattern(id) {
3840
4059
  }
3841
4060
  }
3842
4061
  //#endregion
3843
- //#region src/translator/util/with-comment.ts
3844
- function withLeadingComment(node, value) {
3845
- if (value) {
3846
- const comment = {
3847
- type: "CommentBlock",
3848
- value: ` ${value} `
3849
- };
3850
- node.leadingComments = node.leadingComments ? [...node.leadingComments, comment] : [comment];
3851
- }
3852
- return node;
3853
- }
3854
- //#endregion
3855
- //#region src/translator/util/write-guard.ts
3856
- function isSameReason(a, b) {
3857
- return a === b || (a && b ? a.always && b.always || compareSources(a, b) === 0 : false);
3858
- }
3859
- const groupCheckPrefixes = {
3860
- _write_guard: "wg",
3861
- _write_if: "wi"
3862
- };
3863
- const [getSectionGuards] = createOutputSectionState((section) => ({
3864
- hoists: /* @__PURE__ */ new Map(),
3865
- declarators: [_marko_compiler.types.variableDeclarator(scopeReasonIdentifier(section), callRuntime("_scope_reason"))]
3866
- }));
3867
- function buildGroupMask(groups) {
3868
- let mask = 0;
3869
- let maskNames = "";
3870
- let dynamic;
3871
- const props = [];
3872
- let needsObject = false;
3873
- let any = false;
3874
- for (let i = 0; i < groups.length; i++) {
3875
- const { value, names } = groups[i];
3876
- if (value === void 0) continue;
3877
- any = true;
3878
- if (value === 0) continue;
3879
- if (i >= 15) needsObject = true;
3880
- else if (typeof value === "number") {
3881
- mask |= value << 1 + 2 * i;
3882
- if (names) maskNames += maskNames ? ` | ${names}` : names;
3883
- } else {
3884
- const shifted = _marko_compiler.types.binaryExpression("<<", value, withLeadingComment(_marko_compiler.types.numericLiteral(1 + 2 * i), names));
3885
- dynamic = dynamic ? _marko_compiler.types.binaryExpression("|", dynamic, shifted) : shifted;
3886
- }
3887
- props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), names), typeof value === "number" ? _marko_compiler.types.numericLiteral(value) : value));
3888
- }
3889
- if (needsObject) return _marko_compiler.types.objectExpression(props);
3890
- if (!any) return;
3891
- const literal = mask ? withLeadingComment(_marko_compiler.types.numericLiteral(mask), maskNames) : void 0;
3892
- return literal && dynamic ? _marko_compiler.types.binaryExpression("|", literal, dynamic) : literal || dynamic || _marko_compiler.types.numericLiteral(0);
3893
- }
3894
- function getScopeReasonStatement(section) {
3895
- return hasConditionalReason(section) ? _marko_compiler.types.variableDeclaration("const", getSectionGuards(section).declarators) : _marko_compiler.types.expressionStatement(callRuntime("_scope_reason"));
3896
- }
3897
- function getWriteReason(binding) {
3898
- return findSlot(binding)?.reason;
3899
- }
3900
- function getBranchWriteReason(section) {
3901
- return findSectionSlot(section, 9)?.reason;
3902
- }
3903
- function getWriteGuard(section, reason, omitUnconditional) {
3904
- if (!isDynamicWriteGuard(section, reason)) {
3905
- if (!reason) return _marko_compiler.types.numericLiteral(0);
3906
- return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.always ? void 0 : reason.state));
3907
- }
3908
- return orEachParamGroup(reason.param, "_write_guard");
3909
- }
3910
- function getWriteGuardForAny(section, reasons, omitUnconditional) {
3911
- if (!Array.isArray(reasons)) return getWriteGuard(section, reasons, omitUnconditional);
3912
- for (const reason of reasons) if (!isConditionalReason(reason)) return omitUnconditional ? void 0 : withLeadingComment(_marko_compiler.types.numericLiteral(1), getDebugNames(reason.state));
3913
- let expr;
3914
- for (const reason of reasons) expr = orGuard(expr, getWriteGuard(section, reason, false));
3915
- return expr;
3916
- }
3917
- function getExprIfWritten(section, reason, expr) {
3918
- const ownReason = mapBodyParams(section, reason);
3919
- if (!isConditionalReason(ownReason)) return ownReason && expr;
3920
- return andGuard(orEachParamGroup(ownReason.param, "_write_if"), expr);
3921
- }
3922
- function orEachParamGroup(params, check) {
3923
- return reduceParamGroups(params, (expr, section, group) => orGuard(expr, getOrHoistSectionGuard(section, group, check)), void 0);
3924
- }
3925
- function orGuard(guard, other) {
3926
- return guard ? _marko_compiler.types.logicalExpression("||", guard, other) : other;
3927
- }
3928
- function andGuard(guard, expr) {
3929
- return guard ? _marko_compiler.types.logicalExpression("&&", guard, expr) : expr;
3930
- }
3931
- function getOrHoistSectionGuard(section, params, check) {
3932
- if (!section.paramReasonGroups) return scopeReasonIdentifier(section);
3933
- const state = getSectionGuards(section);
3934
- let tracking = state.hoists.get(check);
3935
- if (!tracking) state.hoists.set(check, tracking = createGuardHoists());
3936
- const index = getParamReasonGroupIndex(section, params);
3937
- const name = tracking.names.get(index);
3938
- if (name) return _marko_compiler.types.identifier(name);
3939
- const guard = callRuntime(check, scopeReasonIdentifier(section), withLeadingComment(_marko_compiler.types.numericLiteral(index), getDebugNames(params)));
3940
- const pending = tracking.pending.get(index);
3941
- if (!pending) {
3942
- const expr = _marko_compiler.types.parenthesizedExpression(guard);
3943
- tracking.pending.set(index, expr);
3944
- return expr;
3945
- }
3946
- const hoisted = generateUid(`${groupCheckPrefixes[check]}__${getDebugNamesAsIdentifier(params)}`);
3947
- tracking.names.set(index, hoisted);
3948
- tracking.pending.delete(index);
3949
- state.declarators.push(_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(hoisted), guard));
3950
- pending.expression = _marko_compiler.types.identifier(hoisted);
3951
- return _marko_compiler.types.parenthesizedExpression(_marko_compiler.types.identifier(hoisted));
3952
- }
3953
- function isDynamicWriteGuard(section, reason) {
3954
- return isConditionalReason(reason) && !isCrossSection(section, reason);
3955
- }
3956
- function isCrossSection(section, reason) {
3957
- return some(reason.param, (param) => !isSameOrAncestorSection(param.section, section));
3958
- }
3959
- function createGuardHoists() {
3960
- return {
3961
- names: /* @__PURE__ */ new Map(),
3962
- pending: /* @__PURE__ */ new Map()
3963
- };
3964
- }
3965
- function hasConditionalReason(section) {
3966
- if (section.paramReasonGroups || isConditionalReason(mapBodyParams(section, section.reason))) return true;
3967
- return some(section.slots, isConditionalSlot);
3968
- }
3969
- function isConditionalSlot(slot) {
3970
- return isConditionalReason(mapBodyParams(slot.section, slot.reason));
3971
- }
3972
- function scopeReasonIdentifier(section) {
3973
- return _marko_compiler.types.identifier(ensureSharedUid(`scope${section.id}_reason`, section));
3974
- }
3975
- //#endregion
3976
4062
  //#region src/translator/util/build-string-expression.ts
3977
4063
  function buildStringExpression(parts, useIife) {
3978
4064
  const strs = [""];
@@ -4090,7 +4176,7 @@ function setSectionOwnerResumedByMarker(section) {
4090
4176
  setOwnerResumedByMarker(section, true);
4091
4177
  }
4092
4178
  function getContentClosureValues(bodySection) {
4093
- const contentClosures = bindingUtil.filter(getDynamicTagContentClosures(bodySection), mayBeUnwritten);
4179
+ const contentClosures = getDynamicTagContentClosures(bodySection);
4094
4180
  if (!contentClosures) return;
4095
4181
  const scope = generateUidIdentifier("scope");
4096
4182
  const closures = Array.isArray(contentClosures) ? contentClosures : [contentClosures];
@@ -4111,9 +4197,6 @@ function getContentClosureValues(bodySection) {
4111
4197
  levels: levels.reverse()
4112
4198
  };
4113
4199
  }
4114
- function mayBeUnwritten(closure) {
4115
- return !isUnconditionalReason(getWriteReason(closure));
4116
- }
4117
4200
  const [getScopeProperties] = createOutputSectionState(() => /* @__PURE__ */ new Map());
4118
4201
  function writeSlot(slot, expression) {
4119
4202
  const reason = slot?.reason;
@@ -4537,9 +4620,9 @@ function writeHTMLResumeStatements(path) {
4537
4620
  const closureIndex = getDynamicClosureIndex(closure, section);
4538
4621
  if (closureIndex) writeSlot(findSlot(closure, 3, section), _marko_compiler.types.numericLiteral(closureIndex));
4539
4622
  const closureScopesReason = findSlot(closure, 2)?.reason;
4540
- const subscribeArg = isConditionalReason(closureScopesReason) && !isSameReason(closureScopesReason, sectionReason) ? getExprIfWritten(closure.section, closureScopesReason, identifier) : identifier;
4623
+ const subscribeArg = isGuardedReason(closureScopesReason) && !isSameReason(closureScopesReason, sectionReason) ? getExprIfWritten(closure.section, closureScopesReason, identifier) : identifier;
4541
4624
  const changeable = isChangeableDynamicClosure(section, closure);
4542
- addWriteScopeBuilder(section, (expr) => {
4625
+ if (subscribeArg) addWriteScopeBuilder(section, (expr) => {
4543
4626
  const resumeId = changeable && _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "subscribe"));
4544
4627
  return callRuntime("_subscribe", subscribeArg, expr, resumeId, resumeId && markerGuard);
4545
4628
  });
@@ -4564,7 +4647,8 @@ function writeHTMLResumeStatements(path) {
4564
4647
  if (!reason) return;
4565
4648
  const accessor = getScopeAccessor(binding);
4566
4649
  pendingProperties.delete(accessor);
4567
- scopeProperties.push(toObjectProperty(accessor, ifWritten(reason, getDeclaredBindingExpression(binding))));
4650
+ const value = ifWritten(reason, getDeclaredBindingExpression(binding));
4651
+ if (value) scopeProperties.push(toObjectProperty(accessor, value));
4568
4652
  if (debug) {
4569
4653
  const { root, access } = getDebugAccess(binding, false, toAccess);
4570
4654
  const locExpr = root.loc && _marko_compiler.types.stringLiteral(getDebugLoc(root.loc));
@@ -4579,10 +4663,14 @@ function writeHTMLResumeStatements(path) {
4579
4663
  const ownerReason = findSectionSlot(section, 7)?.reason;
4580
4664
  if (ownerReason) {
4581
4665
  pendingProperties.delete(ownerAccessor);
4582
- if (!getOwnerResumedByMarker(section)) scopeProperties.push(toObjectProperty(ownerAccessor, ifWritten(ownerReason, callRuntime("_scope_with_id", getScopeIdIdentifier(section.parent)))));
4666
+ const owner = !getOwnerResumedByMarker(section) && ifWritten(ownerReason, callRuntime("_scope_with_id", getScopeIdIdentifier(section.parent)));
4667
+ if (owner) scopeProperties.push(toObjectProperty(ownerAccessor, owner));
4583
4668
  }
4584
4669
  }
4585
- for (const [key, { expression, reason }] of pendingProperties) scopeProperties.push(toObjectProperty(key, ifWritten(reason, expression)));
4670
+ for (const [key, { expression, reason }] of pendingProperties) {
4671
+ const value = ifWritten(reason, expression);
4672
+ if (value) scopeProperties.push(toObjectProperty(key, value));
4673
+ }
4586
4674
  if (sectionReason) {
4587
4675
  for (const prop of scopeProperties) if (prop.key.type === "Identifier" && prop.value.type === "Identifier" && prop.key.name === prop.value.name) prop.shorthand = true;
4588
4676
  const writeScopeArgs = [scopeIdIdentifier, _marko_compiler.types.objectExpression(scopeProperties)];
@@ -4591,8 +4679,8 @@ function writeHTMLResumeStatements(path) {
4591
4679
  for (const [accessor, varLoc] of getSectionDebugVars(section)) (debugVars ||= []).push(toObjectProperty(accessor, _marko_compiler.types.valueToNode(varLoc)));
4592
4680
  if (debugVars) writeScopeArgs.push(_marko_compiler.types.objectExpression(debugVars));
4593
4681
  }
4594
- const writeCall = writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs);
4595
- body.push(_marko_compiler.types.expressionStatement(getExprIfWritten(section, sectionReason, writeCall)));
4682
+ const write = getExprIfWritten(section, sectionReason, writeScopeBuilder ? writeScopeBuilder(callRuntime("_scope", ...writeScopeArgs)) : callRuntime("_scope", ...writeScopeArgs));
4683
+ if (write) body.push(_marko_compiler.types.expressionStatement(write));
4596
4684
  }
4597
4685
  if (!isOptionalBranch(section) && (section.hasAbortSignal || !!section.referencedClosures || sectionReason && some(section.bindings, isLetBinding)) && markerGuard) {
4598
4686
  const call = callRuntime("_resume_branch", scopeIdIdentifier);
@@ -4967,7 +5055,6 @@ function getSingleKnownSpread(paramsTree, attributes) {
4967
5055
  //#region src/translator/util/known-tag.ts
4968
5056
  const [getTagVarBindings] = createOutputSectionState(() => []);
4969
5057
  const [getCallSiteSourcesByParam] = createAnalysisState(() => /* @__PURE__ */ new Map());
4970
- const kChildSection = Symbol("known tag child section");
4971
5058
  const kParamsTree = Symbol("known tag params tree");
4972
5059
  const kKnownExprs = Symbol("known tag exprs");
4973
5060
  const [getRecursiveTags] = createAnalysisState(() => []);
@@ -4977,15 +5064,15 @@ function knownTagAnalyze(tag, childSection, childParamsTree) {
4977
5064
  const tagBody = tag.get("body");
4978
5065
  const tagExtra = tag.node.extra ??= {};
4979
5066
  tagExtra.childScopeBinding = createBinding("#childScope", 0, section);
5067
+ tagExtra.childSection = childSection;
4980
5068
  ensureBodySection(tagBody);
4981
5069
  trackParamsReferences(tagBody, 2);
4982
5070
  (section.knownTags ||= []).push(tagExtra);
4983
- tagExtra[kChildSection] = childSection;
4984
5071
  const varBinding = trackVarReferences(tag, 4);
4985
5072
  const recursive = isSameOrAncestorSection(childSection, section);
4986
5073
  let exprs;
4987
5074
  if (childSection.program === section.program) {
4988
- childSection.callSections = sectionUtil.add(childSection.callSections, section);
5075
+ childSection.calls = push(childSection.calls, tagExtra);
4989
5076
  if (recursive) getRecursiveTags().push(tag);
4990
5077
  else exprs = analyzeKnownTagParams(tag, exposeChildParamsTree(childSection));
4991
5078
  } else exprs = analyzeKnownTagParams(tag, childParamsTree);
@@ -5009,7 +5096,7 @@ function knownTagAnalyze(tag, childSection, childParamsTree) {
5009
5096
  }
5010
5097
  function analyzeRecursiveTags() {
5011
5098
  for (const tag of getRecursiveTags()) {
5012
- const childSection = tag.node.extra[kChildSection];
5099
+ const childSection = tag.node.extra.childSection;
5013
5100
  assertTerminates(tag, childSection);
5014
5101
  const exprs = analyzeKnownTagParams(tag, exposeChildParamsTree(childSection));
5015
5102
  if (tag.node.var) {
@@ -5024,8 +5111,8 @@ function assertTerminates(tag, childSection) {
5024
5111
  const callers = /* @__PURE__ */ new Set([getSection(tag)]);
5025
5112
  for (const caller of callers) {
5026
5113
  if (caller === childSection) throw tag.get("name").buildCodeFrameError(`A ${childSection === (0, _marko_compiler_babel_utils.getProgram)().node.extra.section ? "template" : "`<define>`"} that renders itself outside a branch never terminates. Render \`<${getTagNameHint(tag.node)}>\` inside a branch that eventually stops, such as \`<if>\`.`);
5027
- forEach(caller.callSections, (callSection) => {
5028
- callers.add(callSection);
5114
+ forEach(caller.calls, (call) => {
5115
+ callers.add(call.childScopeBinding.section);
5029
5116
  });
5030
5117
  }
5031
5118
  }
@@ -5048,8 +5135,8 @@ function getReturnParams(section) {
5048
5135
  function assertReturns(tag, childSection) {
5049
5136
  if (!childSection.returnValueExpr) throw tag.get("var").buildCodeFrameError(`The \`${getTagNameHint(tag.node)}\` tag does not [\`<return>\`](https://markojs.com/docs/reference/core-tag#return) a value, so it does not support a [tag variable](https://markojs.com/docs/reference/language#tag-variables). Remove the variable, or add a \`<return>\` to the tag.`);
5050
5137
  }
5051
- function isChildScopeResumed(tagExtra) {
5052
- return !!findSlot(tagExtra.childScopeBinding)?.reason;
5138
+ function isChildScopeResumed(section, tagExtra) {
5139
+ return isEverWritten(section, findSlot(tagExtra.childScopeBinding)?.reason);
5053
5140
  }
5054
5141
  function getRenderArgs(tag, properties) {
5055
5142
  const args = tag.node.arguments;
@@ -5066,7 +5153,7 @@ function toRenderArg(arg) {
5066
5153
  function knownTagTranslateHTML(tag, tagIdentifier) {
5067
5154
  const { node } = tag;
5068
5155
  const tagExtra = node.extra;
5069
- const childSection = tagExtra[kChildSection];
5156
+ const childSection = tagExtra.childSection;
5070
5157
  const paramsTree = getSettledParamsTree(tagExtra[kParamsTree]);
5071
5158
  writeHTMLResumeStatements(tag);
5072
5159
  const tagVar = node.var;
@@ -5078,8 +5165,8 @@ function knownTagTranslateHTML(tag, tagIdentifier) {
5078
5165
  };
5079
5166
  const childScopeBinding = tagExtra.childScopeBinding;
5080
5167
  let varStatement;
5081
- if (isChildScopeResumed(tagExtra)) {
5082
- const peekScopeId = generateUidIdentifier(childScopeBinding?.name);
5168
+ if (isChildScopeResumed(section, tagExtra)) {
5169
+ const peekScopeId = generateUidIdentifier(childScopeBinding.name);
5083
5170
  statements.push(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(peekScopeId, callRuntime("_peek_scope_id"))]));
5084
5171
  const childScopeSlot = findSlot(childScopeBinding);
5085
5172
  writeSlot(childScopeSlot, callRuntime("_existing_scope", peekScopeId));
@@ -5104,7 +5191,7 @@ function knownTagTranslateDOM(tag, getBindingIdentifier, callSetup) {
5104
5191
  if (node.var) {
5105
5192
  const varBinding = node.var.extra.binding;
5106
5193
  const signal = initValue(varBinding);
5107
- signal.register = isChildScopeResumed(extra);
5194
+ signal.register = isChildScopeResumed(getSection(tag), extra);
5108
5195
  signal.referenced = true;
5109
5196
  signal.buildAssignment = (valueSection, value) => buildVarChange(createScopeReadExpression(childScopeBinding, valueSection), value, varBinding);
5110
5197
  getTagVarBindings(tagSection).push(_marko_compiler.types.expressionStatement(callRuntime("_var", scopeIdentifier, getScopeAccessorLiteral(childScopeBinding, true), signal.identifier)));
@@ -5122,8 +5209,8 @@ function getCallSiteSources(param) {
5122
5209
  if (sourcesByParam.has(param)) return sourcesByParam.get(param);
5123
5210
  const body = param.section;
5124
5211
  let sources;
5125
- forEach(body.callSections, (callSection) => {
5126
- for (const tagExtra of callSection.knownTags) if (tagExtra[kChildSection] === body) sources = mergeSources(sources, getSourcesForExprs(mapParamBindingToExpr(tagExtra[kKnownExprs], param)));
5212
+ forEach(body.calls, (call) => {
5213
+ sources = mergeSources(sources, getSourcesForExprs(mapParamBindingToExpr(call[kKnownExprs], param)));
5127
5214
  });
5128
5215
  sourcesByParam.set(param, sources);
5129
5216
  return sources;
@@ -5136,8 +5223,8 @@ function addKnownTagReasons(section) {
5136
5223
  for (const tagExtra of section.knownTags || []) {
5137
5224
  const { childScopeBinding } = tagExtra;
5138
5225
  const knownExprs = tagExtra[kKnownExprs];
5139
- const childSection = tagExtra[kChildSection];
5140
- if (knownExprs && childScopeBinding && childSection.paramReasonGroups) {
5226
+ const { childSection } = tagExtra;
5227
+ if (knownExprs && childSection.paramReasonGroups) {
5141
5228
  for (const group of childSection.paramReasonGroups) if (!findSlot(childScopeBinding, 5, section, group)) {
5142
5229
  const slot = ensureSlot(childScopeBinding, 5, section, group);
5143
5230
  slot.reasonExprs = mapParamReasonToExpr(knownExprs, group);
@@ -5148,7 +5235,7 @@ function addKnownTagReasons(section) {
5148
5235
  }
5149
5236
  function callsOtherTemplateSetup(section) {
5150
5237
  for (const tagExtra of section.knownTags || []) {
5151
- const childSection = tagExtra[kChildSection];
5238
+ const { childSection } = tagExtra;
5152
5239
  if (tagExtra.tagNameLoad || childSection.program !== section.program && childSection.hasSetupWork) return true;
5153
5240
  }
5154
5241
  return false;
@@ -5609,12 +5696,9 @@ function mapBodyParams(section, reason, seen) {
5609
5696
  if (params === reason.param) return reason;
5610
5697
  return mergeSources(mapBodyParams(section, mapped, seen), withSources(reason, reason.state, params)) || ALWAYS;
5611
5698
  }
5612
- function isConditionalReason(reason) {
5699
+ function isGuardedReason(reason) {
5613
5700
  return !!reason && !reason.always && !reason.state;
5614
5701
  }
5615
- function isUnconditionalReason(reason) {
5616
- return !!reason && !isConditionalReason(reason);
5617
- }
5618
5702
  function isStateReason(reason) {
5619
5703
  return !!reason && !reason.always && !!reason.state;
5620
5704
  }
@@ -5942,7 +6026,9 @@ function initBranchSection(bodySection, branchExpr, branch) {
5942
6026
  }
5943
6027
  function resumeOwnerByMarkerWhenUnconditional(bodySection, nodeBinding) {
5944
6028
  const branchExprReason = findSlot(nodeBinding, 4)?.reason;
5945
- if (isStateReason(branchExprReason) && some(branchExprReason.state, hasResumableAssignment) && isUnconditionalReason(getBranchWriteReason(bodySection)) && isUnconditionalReason(getWriteReason(nodeBinding))) setSectionOwnerResumedByMarker(bodySection);
6029
+ const branchReason = getBranchWriteReason(bodySection);
6030
+ const nodeReason = getWriteReason(nodeBinding);
6031
+ if (isStateReason(branchExprReason) && some(branchExprReason.state, hasResumableAssignment) && branchReason && !isGuardedReason(branchReason) && nodeReason && !isGuardedReason(nodeReason)) setSectionOwnerResumedByMarker(bodySection);
5946
6032
  }
5947
6033
  function getBranchResumeArgs(tag, branchReasons, singleNode) {
5948
6034
  const tagSection = getSection(tag);
@@ -8085,8 +8171,8 @@ function resolveBindings() {
8085
8171
  }
8086
8172
  }
8087
8173
  function addSectionReasons(section) {
8088
- if (section.readsOwner) forEach(section.callSections, (callSection) => {
8089
- setReadsOwner(callSection, section.parent);
8174
+ if (section.readsOwner) forEach(section.calls, (call) => {
8175
+ setReadsOwner(call.childScopeBinding.section, section.parent);
8090
8176
  });
8091
8177
  if (section.isHoistThrough) addReason(ensureSectionSlot(section, 6), ALWAYS);
8092
8178
  forEach(section.referencedClosures, (closure) => {
@@ -9816,6 +9902,7 @@ var dynamic_tag_default = {
9816
9902
  analyzeAttributeTags(tag);
9817
9903
  const tagSection = ensureSection(tag);
9818
9904
  const inputNodes = getAllTagReferenceNodes(node);
9905
+ (node.name.extra ??= {}).tagName = true;
9819
9906
  const tagExtra = mergeReferences(tagSection, node, [node.name, ...inputNodes]);
9820
9907
  if (inputNodes.length) tagExtra.retained = true;
9821
9908
  const tagBody = tag.get("body");
@@ -9841,7 +9928,7 @@ var dynamic_tag_default = {
9841
9928
  trackParamsReferences(tagBody, 2);
9842
9929
  if (usesVar) addAlwaysReason(nodeBinding);
9843
9930
  addReasonExprs(ensureSlot(nodeBinding), tagExtra);
9844
- if (!hasVar && !node.arguments && !node.attributes.length && !node.body.body.length) tagExtra.nameOnly = true;
9931
+ if (!hasVar && !node.arguments && !node.attributes.length && !node.body.body.length && !tagExtra.attrTagLookup) tagExtra.nameOnly = true;
9845
9932
  marker(tag, nodeBinding);
9846
9933
  enterShallow(tag);
9847
9934
  if (bodySection && tagExtra.featureType === "class" && !(0, _marko_compiler_babel_utils.getTagTemplate)(tag)) bodySection.structure = null;
@@ -10234,7 +10321,8 @@ var program_default = {
10234
10321
  if (paramsBinding && !paramsBinding.pruned) programExtra.paramsTree = exposeParamsTree(paramsBinding);
10235
10322
  const section = programExtra.section;
10236
10323
  forEachSection((childSection) => {
10237
- programExtra.hasResumes ||= !!(isUnconditionalReason(mapBodyParams(childSection, childSection.reason)) || childSection !== section && !isSectionRendererElided(childSection) && getRendererReason(childSection));
10324
+ const reason = mapBodyParams(childSection, childSection.reason);
10325
+ programExtra.hasResumes ||= !!(reason && !isGuardedReason(reason) || childSection !== section && !isSectionRendererElided(childSection) && getRendererReason(childSection));
10238
10326
  });
10239
10327
  finalizeSetupWork();
10240
10328
  }
@@ -4,19 +4,23 @@ import { type ParamsTree } from "./params-tree";
4
4
  import { type KnownExprs } from "./reasons";
5
5
  import { type Section } from "./sections";
6
6
  import { type Sources } from "./sources";
7
- declare const kChildSection: unique symbol;
8
7
  declare const kParamsTree: unique symbol;
9
8
  declare const kKnownExprs: unique symbol;
10
9
  declare module "@marko/compiler/dist/types" {
11
10
  interface MarkoTagExtra {
12
11
  /** The dom binding a known tag holds its child's scope in. */
13
12
  childScopeBinding?: Binding;
14
- [kChildSection]?: Section;
13
+ /** The section a known tag renders: another template's, a `<define>` body. */
14
+ childSection?: Section;
15
15
  /** The child's params tree the call site was analyzed against. */
16
16
  [kParamsTree]?: ParamsTree;
17
17
  [kKnownExprs]?: KnownExprs;
18
18
  }
19
19
  }
20
+ export interface KnownTagExtra extends t.MarkoTagExtra {
21
+ childScopeBinding: Binding;
22
+ childSection: Section;
23
+ }
20
24
  export declare function knownTagAnalyze(tag: t.NodePath<t.MarkoTag>, childSection: Section, childParamsTree?: ParamsTree): void;
21
25
  export declare function analyzeRecursiveTags(): void;
22
26
  export declare function knownTagTranslateHTML(tag: t.NodePath<t.MarkoTag>, tagIdentifier: t.Expression): void;
@@ -11,11 +11,10 @@ export declare function addAlwaysReason(binding: Binding): void;
11
11
  export declare function addReasonExprs(slot: Slot, expr: Opt<t.NodeExtra>): void;
12
12
  export declare function addOwnerReason(from: Section, to: Section, reason: undefined | false | Reason): void;
13
13
  export declare function mapBodyParams(section: Section, reason: undefined | Reason, seen?: Set<ParamBinding>): Reason | undefined;
14
- export declare function isConditionalReason(reason: undefined | Reason): reason is Sources & {
14
+ export declare function isGuardedReason(reason: undefined | Reason): reason is Sources & {
15
15
  state: undefined;
16
16
  always: undefined;
17
17
  };
18
- export declare function isUnconditionalReason(reason: undefined | Reason): reason is Reason;
19
18
  export declare function isStateReason(reason: undefined | Reason): reason is Sources;
20
19
  export declare function getSourcesForExpr(expr: t.NodeExtra): Sources | undefined;
21
20
  export declare function getSourcesForExprs(exprs: Opt<t.NodeExtra> | boolean): Sources | undefined;
@@ -63,6 +63,8 @@ declare module "@marko/compiler/dist/types" {
63
63
  assignment?: Binding;
64
64
  assignmentTo?: Binding;
65
65
  read?: ResolvedRead;
66
+ /** An expression root that is a dynamic tag's name, not one of its inputs. */
67
+ tagName?: true;
66
68
  dropped?: true;
67
69
  /** The expression this node sits in: dropped or merged as one. */
68
70
  exprRoot?: NodeExtra;
@@ -3,6 +3,7 @@ import { type Binding, type Intersection, type IntersectionMeta, type ParamBindi
3
3
  import * as ContentType from "./constants/content-type";
4
4
  import type * as Step from "./constants/step";
5
5
  import * as StructureKind from "./constants/structure-kind";
6
+ import type { KnownTagExtra } from "./known-tag";
6
7
  import { type OneMany, type Opt, Sorted, type SortedOpt } from "./optional";
7
8
  import { type KnownExprs, type Reason } from "./reasons";
8
9
  import { type Slot } from "./slots";
@@ -70,11 +71,11 @@ export interface Section {
70
71
  returnValueExpr: t.NodeExtra | undefined;
71
72
  isHoistThrough: true | undefined;
72
73
  branchExpr: t.NodeExtra | undefined;
73
- /** For a `<define>` body or a template rendering itself, the sections whose
74
- * direct calls render it. */
75
- callSections: SortedOpt<Section>;
74
+ /** For a `<define>` body or a template rendering itself, the known tags whose
75
+ * direct calls render it (each in its child scope binding's section). */
76
+ calls: Opt<KnownTagExtra>;
76
77
  /** The known tags rendering in it, in analyze order. */
77
- knownTags: t.MarkoTagExtra[] | undefined;
78
+ knownTags: KnownTagExtra[] | undefined;
78
79
  /** The content's rendering tag (its extra), and each child binding that
79
80
  * derives from the content, at `properties`. */
80
81
  derives: {
@@ -128,7 +129,7 @@ export declare function getSection(path: t.NodePath): Section;
128
129
  export declare const getScopeIdIdentifier: (section: Section) => t.Identifier;
129
130
  export declare const getBranchRendererArgs: (section: Section) => [template?: t.Expression | undefined, walks?: t.Expression | undefined, setup?: t.Expression | undefined, params?: t.Expression | undefined], setBranchRendererArgs: (section: Section, value: [template?: t.Expression | undefined, walks?: t.Expression | undefined, setup?: t.Expression | undefined, params?: t.Expression | undefined]) => void;
130
131
  export declare function forEachSection(fn: (section: Section) => void): void;
131
- export declare function getDynamicTagContentClosures(section: Section): ReferencedBindings;
132
+ export declare function getDynamicTagContentClosures(section: Section): SortedOpt<Binding>;
132
133
  export declare function forEachAncestorSection<A>(from: Section, to: Section, fn: (section: Section, arg: A) => void, arg: A): void;
133
134
  export declare function forEachSectionReverse(fn: (section: Section) => void): void;
134
135
  export declare function getNodeContentType(path: t.NodePath<t.Statement>, edge: "startType" | "endType"): ContentType.Value | null;
@@ -6,4 +6,5 @@ import { type Section } from "./sections";
6
6
  export declare function solveReasons(intersectionsBySection: Map<Section, Intersection[]>): void;
7
7
  export declare function getReasonForBinding(binding: Binding, properties?: Opt<string> | true): undefined | Reason;
8
8
  export declare function getReasonForExpr(extra: t.NodeExtra): undefined | Reason;
9
+ export declare function bindingLandsRetained(binding: Binding, properties: Opt<string>): boolean;
9
10
  export declare function landsRetained(extra: t.NodeExtra): boolean;
@@ -13,4 +13,5 @@ export declare function getWriteReason(binding: Binding): Sources | undefined;
13
13
  export declare function getBranchWriteReason(section: Section): Sources | undefined;
14
14
  export declare function getWriteGuard(section: Section, reason: undefined | Reason, omitUnconditional: boolean): t.Expression | undefined;
15
15
  export declare function getWriteGuardForAny(section: Section, reasons: undefined | Reasons, omitUnconditional: boolean): t.Expression | undefined;
16
- export declare function getExprIfWritten<T extends undefined | Reason, R extends (T extends {} ? t.Expression : undefined)>(section: Section, reason: T, expr: t.Expression): R;
16
+ export declare function getExprIfWritten(section: Section, reason: undefined | Reason, expr: t.Expression): t.Expression | undefined;
17
+ export declare function isEverWritten(section: Section, reason: undefined | Reason): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marko/runtime-tags",
3
- "version": "6.4.7",
3
+ "version": "6.4.8",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",
@@ -51,14 +51,14 @@
51
51
  }
52
52
  },
53
53
  "dependencies": {
54
- "@marko/compiler": "^5.42.13",
54
+ "@marko/compiler": "^5.42.14",
55
55
  "csstype": "^3.2.3",
56
56
  "fastest-levenshtein": "^1.0.16",
57
57
  "magic-string": "^0.30.21"
58
58
  },
59
59
  "devDependencies": {
60
- "@marko/runtime-tags": "6.4.7",
61
- "marko": "5.39.47"
60
+ "@marko/runtime-tags": "6.4.8",
61
+ "marko": "5.39.48"
62
62
  },
63
63
  "engines": {
64
64
  "node": ">=22"
package/tags-html.d.ts CHANGED
@@ -97,6 +97,7 @@ declare global {
97
97
  search: NativeTag<Marko.HTML.Search, HTMLElement>;
98
98
  section: NativeTag<Marko.HTML.Section, HTMLElement>;
99
99
  select: NativeTag<Marko.HTML.Select, HTMLSelectElement>;
100
+ selectedcontent: NativeTag<Marko.HTML.SelectedContent, HTMLElement>;
100
101
  slot: NativeTag<Marko.HTML.Slot, HTMLSlotElement>;
101
102
  small: NativeTag<Marko.HTML.Small, HTMLElement>;
102
103
  source: NativeTag<Marko.HTML.Source, HTMLSourceElement>;
@@ -2056,6 +2057,8 @@ declare global {
2056
2057
  ) => void);
2057
2058
  }
2058
2059
 
2060
+ interface SelectedContent extends HTMLAttributes<HTMLElement> {}
2061
+
2059
2062
  interface Slot extends HTMLAttributes<HTMLSlotElement> {
2060
2063
  /**
2061
2064
  * Used to assign slots to other elements