marko 6.4.1 → 6.4.2

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 (73) hide show
  1. package/cheatsheet.md +1 -1
  2. package/dist/common/errors.d.ts +1 -0
  3. package/dist/common/opt.d.ts +1 -0
  4. package/dist/debug/dom/catch.feat.js +1 -1
  5. package/dist/debug/dom/catch.feat.mjs +1 -1
  6. package/dist/debug/dom/controllable-input.feat.js +1 -1
  7. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  8. package/dist/debug/dom/controllable-open.feat.js +1 -1
  9. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  10. package/dist/debug/dom/controllable-select.feat.js +1 -1
  11. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  12. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  13. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  14. package/dist/debug/dom/controllable.feat.js +1 -1
  15. package/dist/debug/dom/controllable.feat.mjs +1 -1
  16. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  17. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  18. package/dist/debug/dom/dynamic-tag-var.feat.js +1 -1
  19. package/dist/debug/dom/dynamic-tag-var.feat.mjs +1 -1
  20. package/dist/debug/dom/lazy.feat.js +1 -1
  21. package/dist/debug/dom/lazy.feat.mjs +1 -1
  22. package/dist/debug/dom/placeholder.feat.js +1 -1
  23. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  24. package/dist/debug/{dom-ClV4kVOO.js → dom-BLbR0hEx.js} +30 -0
  25. package/dist/debug/{dom-LFrKxOk5.mjs → dom-Cii0IA92.mjs} +19 -1
  26. package/dist/debug/dom.js +7 -4
  27. package/dist/debug/dom.mjs +6 -5
  28. package/dist/debug/html.js +280 -76
  29. package/dist/debug/html.mjs +280 -77
  30. package/dist/dom/catch.feat.js +3 -3
  31. package/dist/dom/catch.feat.mjs +1 -1
  32. package/dist/dom/controllable-input.feat.js +1 -1
  33. package/dist/dom/controllable-input.feat.mjs +1 -1
  34. package/dist/dom/controllable-open.feat.js +1 -1
  35. package/dist/dom/controllable-open.feat.mjs +1 -1
  36. package/dist/dom/controllable-select.feat.js +1 -1
  37. package/dist/dom/controllable-select.feat.mjs +1 -1
  38. package/dist/dom/controllable-textarea.feat.js +1 -1
  39. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  40. package/dist/dom/controllable.feat.js +1 -1
  41. package/dist/dom/controllable.feat.mjs +1 -1
  42. package/dist/dom/dom.d.ts +1 -0
  43. package/dist/dom/dynamic-tag-script.feat.js +2 -2
  44. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  45. package/dist/dom/dynamic-tag-var.feat.js +1 -1
  46. package/dist/dom/dynamic-tag-var.feat.mjs +1 -1
  47. package/dist/dom/lazy.feat.js +1 -1
  48. package/dist/dom/lazy.feat.mjs +1 -1
  49. package/dist/dom/placeholder.feat.js +3 -3
  50. package/dist/dom/placeholder.feat.mjs +1 -1
  51. package/dist/{dom-CNglVi8P.js → dom-B8UEYzOz.js} +99 -80
  52. package/dist/{dom-DfP3MCo0.mjs → dom-BPjLe6YU.mjs} +10 -1
  53. package/dist/dom.d.ts +2 -2
  54. package/dist/dom.js +34 -33
  55. package/dist/dom.mjs +6 -5
  56. package/dist/html/assets.d.ts +12 -6
  57. package/dist/html/attrs.d.ts +1 -0
  58. package/dist/html/compat.d.ts +10 -2
  59. package/dist/html/serializer.d.ts +1 -0
  60. package/dist/html/writer.d.ts +8 -0
  61. package/dist/html.d.ts +1 -1
  62. package/dist/html.js +194 -59
  63. package/dist/html.mjs +194 -59
  64. package/dist/translator/index.js +404 -190
  65. package/dist/translator/util/bindings.d.ts +9 -1
  66. package/dist/translator/util/constants/structure-kind.d.ts +1 -0
  67. package/dist/translator/util/known-tag.d.ts +2 -1
  68. package/dist/translator/util/module-read.d.ts +21 -0
  69. package/dist/translator/util/references.d.ts +1 -0
  70. package/dist/translator/util/runtime.d.ts +2 -0
  71. package/dist/translator/util/sections.d.ts +5 -1
  72. package/dist/translator/util/structure.d.ts +1 -0
  73. package/package.json +3 -3
@@ -164,6 +164,16 @@ function assertValidAttrValue(name, value) {
164
164
  const unrenderable = describeUnrenderable(value);
165
165
  if (unrenderable) throw new Error(`The \`${name}\` attribute cannot be ${unrenderable}.`);
166
166
  }
167
+ function _assert_class_toggles(classes, toggles) {
168
+ {
169
+ const written = new Set(classes.split(" "));
170
+ for (const toggle of toggles) {
171
+ const names = new Set(toggle.split(" "));
172
+ for (const name of names) if (written.has(name)) throw new Error(`The toggled class \`${name}\` is also written by another part of the \`class\` value; a toggled class may appear only once.`);
173
+ for (const name of names) written.add(name);
174
+ }
175
+ }
176
+ }
167
177
  function assertValidTextValue(value) {
168
178
  const unrenderable = describeUnrenderable(value);
169
179
  if (unrenderable) throw new Error(`Text content cannot be ${unrenderable}.`);
@@ -296,6 +306,13 @@ function forUntil(until, from, step, cb) {
296
306
  }
297
307
  //#endregion
298
308
  //#region src/common/opt.ts
309
+ function reduce(opt, cb, acc) {
310
+ if (opt) {
311
+ if (Array.isArray(opt)) for (const item of opt) acc = cb(acc, item);
312
+ else acc = cb(acc, opt);
313
+ }
314
+ return acc;
315
+ }
299
316
  function push(opt, item) {
300
317
  return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
301
318
  }
@@ -644,6 +661,17 @@ var Serializer = class {
644
661
  channel
645
662
  });
646
663
  }
664
+ dropCall(value, object, property) {
665
+ const { mutated } = this.#state;
666
+ for (let i = 0; i < mutated.length; i++) {
667
+ const mutation = mutated[i];
668
+ if (mutation.value === value && mutation.object === object && mutation.property === property) {
669
+ mutated.splice(i, 1);
670
+ return true;
671
+ }
672
+ }
673
+ return false;
674
+ }
647
675
  };
648
676
  function register(id, val, scope, locals) {
649
677
  REGISTRY.set(val, {
@@ -2235,6 +2263,15 @@ function _html(html) {
2235
2263
  function writeScript(script) {
2236
2264
  $chunk.writeScript(script);
2237
2265
  }
2266
+ function catchableBoundary() {
2267
+ const { boundary } = $chunk;
2268
+ return boundary.withinCatch ? boundary : null;
2269
+ }
2270
+ function mayDrop(written) {
2271
+ const { boundary } = $chunk;
2272
+ for (let cur = written; cur && !isWithin(boundary, cur); cur = cur.parent) if (cur.aborted || cur.count) return true;
2273
+ return false;
2274
+ }
2238
2275
  function _script(scopeId, registryId, markerGuard) {
2239
2276
  if (markerGuard === 0 && ($chunk.serializeState.readyId || $chunk.context?.[kIsAsync])) _resume_branch(scopeId);
2240
2277
  $chunk.boundary.state.needsMainRuntime = true;
@@ -2464,10 +2501,12 @@ function scopeWithId(state, scopeId) {
2464
2501
  }
2465
2502
  function _subscribe(subscribers, scope, resumeId, markerGuard) {
2466
2503
  if (subscribers) {
2467
- const { serializer } = $chunk.boundary.state;
2468
- if (!$chunk.serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2504
+ const { boundary, serializeState } = $chunk;
2505
+ const { serializer } = boundary.state;
2506
+ if (!serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2469
2507
  else if (resumeId) _script(scope[K_SCOPE_ID], resumeId, markerGuard);
2470
- else serializer.writeCall(scope, subscribers, "add", $chunk.serializeState);
2508
+ else serializer.writeCall(scope, subscribers, "add", serializeState);
2509
+ if (boundary.withinCatch) (boundary.subscribed ||= []).push(subscribers, scope, serializeState);
2471
2510
  }
2472
2511
  return scope;
2473
2512
  }
@@ -2596,6 +2635,7 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2596
2635
  const { boundary } = chunk;
2597
2636
  const { state } = boundary;
2598
2637
  const catchBoundary = new Boundary(state, void 0, boundary);
2638
+ if (catchContent) catchBoundary.withinCatch = true;
2599
2639
  const body = chunk.fork(catchBoundary, null);
2600
2640
  const bodyEnd = body.render(() => withBranchId(branchId, content));
2601
2641
  if (catchBoundary.aborted) {
@@ -2629,8 +2669,10 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2629
2669
  const streamed = !chunk.catchRange;
2630
2670
  const catchChunk = chunk.fork(boundary, null);
2631
2671
  chunk.catchRange = null;
2672
+ if (!renderersAtSettle) catchChunk.render(clearTryRenderers, branchId);
2632
2673
  const inOrder = catchChunk === catchChunk.render(catchContent, catchBoundary.reason);
2633
2674
  if (boundary.aborted) return;
2675
+ if (bodyEnd.consumed || !inOrder) catchChunk.reorderStart = state.mark("*", branchId + "");
2634
2676
  if (bodyEnd.consumed) {
2635
2677
  catchChunk.reorderId = reorderId;
2636
2678
  state.reorder(catchChunk);
@@ -2659,6 +2701,20 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2659
2701
  };
2660
2702
  return renderersAtSettle;
2661
2703
  }
2704
+ function unsubscribe(subscribed, serializer) {
2705
+ for (let i = 0; i < subscribed.length; i += 3) {
2706
+ const subscribers = subscribed[i];
2707
+ const scope = subscribed[i + 1];
2708
+ if (!serializer.written(subscribers)) subscribers.delete(scope);
2709
+ else if (!serializer.dropCall(scope, subscribers, "add")) serializer.writeCall(scope, subscribers, "delete", subscribed[i + 2]);
2710
+ }
2711
+ }
2712
+ function clearTryRenderers(branchId) {
2713
+ writeScope(branchId, {
2714
+ [CatchContent]: 0,
2715
+ [PlaceholderContent]: _scope_with_id(branchId)["#PlaceholderContent"] && 0
2716
+ });
2717
+ }
2662
2718
  function writeTryRenderers(branchId, catchContent, placeholderContent) {
2663
2719
  writeScope(branchId, {
2664
2720
  [CatchContent]: catchContent,
@@ -2767,12 +2823,15 @@ var Boundary = class {
2767
2823
  parent;
2768
2824
  aborted = false;
2769
2825
  reason;
2826
+ subscribed;
2770
2827
  pendingReorders;
2771
2828
  children;
2829
+ withinCatch = false;
2772
2830
  constructor(state, signal, parent) {
2773
2831
  this.state = state;
2774
2832
  this.parent = parent;
2775
2833
  if (parent) {
2834
+ this.withinCatch = parent.withinCatch;
2776
2835
  if (parent.aborted) this.abort(parent.reason);
2777
2836
  else (parent.children ||= []).push(this);
2778
2837
  } else if (signal) {
@@ -2785,6 +2844,7 @@ var Boundary = class {
2785
2844
  const { state } = this;
2786
2845
  this.aborted = true;
2787
2846
  this.reason = reason;
2847
+ if (this.subscribed) unsubscribe(this.subscribed, state.serializer);
2788
2848
  if (this.pendingReorders) {
2789
2849
  for (const reorder of this.pendingReorders) state.reorder(reorder);
2790
2850
  this.pendingReorders = void 0;
@@ -2820,7 +2880,9 @@ var Chunk = class Chunk {
2820
2880
  async = false;
2821
2881
  consumed = false;
2822
2882
  reorderId = null;
2883
+ reorderStart = "";
2823
2884
  deferredReady = null;
2885
+ heldEffects = null;
2824
2886
  deferredReorder = null;
2825
2887
  catchRange = null;
2826
2888
  placeholder = null;
@@ -2842,7 +2904,7 @@ var Chunk = class Chunk {
2842
2904
  }
2843
2905
  writeEffect(scopeId, registryId) {
2844
2906
  countResumeWrite(this);
2845
- if (this.lastEffect === registryId) this.effects += " " + scopeId;
2907
+ if (this.lastEffect === registryId) this.effects = concatEffects(this.effects, scopeId + "");
2846
2908
  else {
2847
2909
  this.lastEffect = registryId;
2848
2910
  this.effects = concatEffects(this.effects, registryId + " " + scopeId);
@@ -2858,6 +2920,11 @@ var Chunk = class Chunk {
2858
2920
  this.lastEffect = chunk.lastEffect || this.lastEffect;
2859
2921
  this.deferredReady = concat(this.deferredReady, chunk.takeDeferredReady());
2860
2922
  }
2923
+ takeHeldEffects() {
2924
+ const { heldEffects } = this;
2925
+ this.heldEffects = null;
2926
+ return heldEffects;
2927
+ }
2861
2928
  takeDeferredReady() {
2862
2929
  const { deferredReady } = this;
2863
2930
  this.deferredReady = null;
@@ -2910,7 +2977,7 @@ var Chunk = class Chunk {
2910
2977
  return false;
2911
2978
  }
2912
2979
  const { branchId, scopeId, placeholderBranchId } = placeholder;
2913
- const reorderId = body.reorderId = branchId ? branchId + "" : state.nextReorderId();
2980
+ const reorderId = body.reorderId = branchId + "";
2914
2981
  this.writeHTML(state.mark("!^", reorderId));
2915
2982
  const { effects } = this;
2916
2983
  const beforeBranch = deferBranchStart(this);
@@ -2921,7 +2988,7 @@ var Chunk = class Chunk {
2921
2988
  if (stateful) {
2922
2989
  this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2923
2990
  this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2924
- end.writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2991
+ dismissChunk(end, body).writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2925
2992
  }
2926
2993
  this.writeHTML(state.mark("!", reorderId));
2927
2994
  this.deferredReorder = body;
@@ -2949,28 +3016,46 @@ var Chunk = class Chunk {
2949
3016
  let html = "";
2950
3017
  let effects = "";
2951
3018
  let scripts = "";
2952
- let lastEffect = "";
3019
+ let effectsEnd;
3020
+ let heldEffects = this.heldEffects;
2953
3021
  let deferredReady;
3022
+ this.heldEffects = null;
3023
+ if (this.serializeState.readyId && this.effects) followHeldEffects(this);
2954
3024
  while (cur.next && !cur.async) {
2955
3025
  cur.markCatchRange();
2956
3026
  cur.queueDeferredReorder();
2957
3027
  html += cur.html;
2958
3028
  if (cur.serializeState.readyId) deferredReady = push(deferredReady, cur);
2959
3029
  else {
2960
- effects = concatEffects(effects, cur.effects);
3030
+ if (cur.effects) {
3031
+ if (effectsEnd && effectsEnd.boundary !== cur.boundary) {
3032
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3033
+ effects = "";
3034
+ }
3035
+ effectsEnd = cur;
3036
+ effects = concatEffects(effects, cur.effects);
3037
+ }
2961
3038
  scripts = concatScripts(scripts, cur.scripts);
2962
- lastEffect = cur.lastEffect || lastEffect;
2963
3039
  }
2964
3040
  deferredReady = concat(deferredReady, cur.takeDeferredReady());
2965
3041
  cur.consumed = true;
2966
3042
  cur = cur.next;
2967
3043
  }
2968
3044
  cur.deferOwnReady();
3045
+ if (effects) {
3046
+ if (cur.serializeState.readyId) heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3047
+ else if (effectsEnd.boundary !== cur.boundary) {
3048
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3049
+ if (isWithin(cur.boundary, effectsEnd.boundary)) cur.lastEffect ||= effectsEnd.lastEffect;
3050
+ } else {
3051
+ cur.effects = concatEffects(effects, cur.effects);
3052
+ cur.lastEffect ||= effectsEnd.lastEffect;
3053
+ }
3054
+ }
3055
+ cur.heldEffects = heldEffects;
2969
3056
  cur.deferredReady = concat(deferredReady, cur.deferredReady);
2970
3057
  cur.html = html + cur.html;
2971
- cur.effects = concatEffects(effects, cur.effects);
2972
3058
  cur.scripts = concatScripts(scripts, cur.scripts);
2973
- cur.lastEffect ||= lastEffect;
2974
3059
  return cur;
2975
3060
  }
2976
3061
  render(content, val) {
@@ -3023,6 +3108,7 @@ var Chunk = class Chunk {
3023
3108
  const { $global, runtimePrefix } = state;
3024
3109
  let needsWalk = state.walkOnNextFlush;
3025
3110
  if (needsWalk) state.walkOnNextFlush = false;
3111
+ flushSerializer(boundary, state);
3026
3112
  let readyResumeScripts = this.flushReadyScripts(boundary, void 0, this.async);
3027
3113
  for (let channel; !boundary.aborted && (channel = state.serializer.pendingReadyChannel());) {
3028
3114
  const resumes = state.serializer.stringifyScopes([], boundary, channel);
@@ -3031,8 +3117,9 @@ var Chunk = class Chunk {
3031
3117
  readyResumeScripts = concatScripts(readyResumeScripts, state.writeReady(channel.readyId, concatSequence(depsMarker(deps), resumes)));
3032
3118
  }
3033
3119
  if (readyResumeScripts) needsWalk = true;
3034
- const effects = this.async ? "" : this.effects;
3120
+ const effects = this.async ? "" : joinHeldEffects(this.takeHeldEffects(), this.effects);
3035
3121
  let { html, scripts } = this;
3122
+ if (html && state.hasReorderRuntime) html = state.mark("*", "") + html;
3036
3123
  if (state.needsMainRuntime && !state.hasMainRuntime) {
3037
3124
  state.hasMainRuntime = true;
3038
3125
  scripts = concatScripts(scripts, WALKER_RUNTIME_CODE + "(\"" + $global.runtimeId + "\")(\"" + $global.renderId + "\")");
@@ -3051,10 +3138,11 @@ var Chunk = class Chunk {
3051
3138
  state.hasReorderRuntime = true;
3052
3139
  scripts = concatScripts(scripts, REORDER_RUNTIME_CODE + "(" + runtimePrefix + ")");
3053
3140
  }
3054
- const { reorderId } = reorderedChunk;
3141
+ const { reorderId, reorderStart } = reorderedChunk;
3055
3142
  const readyReservations = [];
3056
3143
  let reorderHTML = "";
3057
3144
  let reorderEffects = "";
3145
+ let effectsBoundary = reorderedChunk.boundary;
3058
3146
  let reorderScripts = "";
3059
3147
  let cur = reorderedChunk.boundary.aborted ? null : reorderedChunk;
3060
3148
  reorderedChunk.reorderId = null;
@@ -3067,10 +3155,18 @@ var Chunk = class Chunk {
3067
3155
  this.deferredReady = concat(this.deferredReady, cur.takeDeferredReady());
3068
3156
  cur.consumed = true;
3069
3157
  reorderHTML += cur.html;
3158
+ if (this.async && cur.effects && cur.boundary !== effectsBoundary) {
3159
+ if (reorderEffects) {
3160
+ holdReorderEffects(this, effectsBoundary, reorderEffects);
3161
+ reorderEffects = "";
3162
+ }
3163
+ effectsBoundary = cur.boundary;
3164
+ }
3070
3165
  reorderEffects = concatEffects(reorderEffects, cur.effects);
3071
3166
  reorderScripts = concatScripts(reorderScripts, concatScripts(readyResumeScripts, cur.scripts));
3072
3167
  if (cur.async) {
3073
3168
  reorderHTML += state.mark("#", cur.reorderId = state.nextReorderId());
3169
+ cur.reorderStart = reorderStart;
3074
3170
  (cur.boundary.pendingReorders ||= /* @__PURE__ */ new Set()).add(cur);
3075
3171
  cur.html = cur.effects = cur.scripts = cur.lastEffect = "";
3076
3172
  cur.next = null;
@@ -3078,21 +3174,18 @@ var Chunk = class Chunk {
3078
3174
  cur = next;
3079
3175
  }
3080
3176
  if (reorderEffects) {
3081
- if (this.async) {
3082
- this.effects = concatEffects(this.effects, reorderEffects);
3083
- this.lastEffect = "";
3084
- } else {
3177
+ if (this.async) holdReorderEffects(this, effectsBoundary, reorderEffects);
3178
+ else {
3085
3179
  needsResumeArray = true;
3086
3180
  reorderScripts = concatScripts(reorderScripts, "_.push(\"" + reorderEffects + "\")");
3087
3181
  }
3088
3182
  }
3089
3183
  for (const reservation of readyReservations) reordered = concatScripts(reordered, reservation);
3090
3184
  reordered = concatScripts(reordered, reorderScripts && runtimePrefix + ".j" + toAccess(reorderId) + "=_=>{" + reorderScripts + "}");
3091
- html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + reorderHTML + "</t>";
3185
+ html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + reorderStart + reorderHTML + "</t>";
3092
3186
  }
3093
3187
  state.writeReorders = null;
3094
3188
  }
3095
- flushSerializer(boundary, state);
3096
3189
  if (state.resumes || needsResumeArray && !state.hasWrittenResume) scripts = concatScripts(scripts, state.resumeScript(state.resumes));
3097
3190
  scripts = concatScripts(scripts, reordered);
3098
3191
  if (needsWalk) scripts = concatScripts(scripts, state.walkScript());
@@ -3117,6 +3210,41 @@ function renderReorderPlaceholders(reorder, reorders) {
3117
3210
  }
3118
3211
  return reorders;
3119
3212
  }
3213
+ function dismissChunk(end, body) {
3214
+ if (end.boundary !== body.boundary) while (end.next) end = end.next;
3215
+ return end;
3216
+ }
3217
+ function followHeldEffects(chunk) {
3218
+ const held = reduce(chunk.deferredReady, lastHeldOf, chunk);
3219
+ if (held !== chunk) {
3220
+ held.effects = concatEffects(held.effects, chunk.effects);
3221
+ chunk.effects = "";
3222
+ }
3223
+ }
3224
+ function lastHeldOf(held, cur) {
3225
+ return cur.serializeState === held.serializeState && cur.boundary === held.boundary ? cur : held;
3226
+ }
3227
+ function holdEffectsOn(heldEffects, chunk, effects) {
3228
+ chunk.effects = effects;
3229
+ return push(heldEffects, chunk);
3230
+ }
3231
+ function isWithin(boundary, outer) {
3232
+ while (boundary && boundary !== outer) boundary = boundary.parent;
3233
+ return !!boundary;
3234
+ }
3235
+ function holdReorderEffects(head, boundary, effects) {
3236
+ if (!head.serializeState.readyId) {
3237
+ if (head.effects) head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(head.boundary, null), head.effects);
3238
+ head.effects = head.lastEffect = "";
3239
+ }
3240
+ head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(boundary, null), effects);
3241
+ }
3242
+ function joinHeldEffects(heldEffects, effects) {
3243
+ return concatEffects(reduce(heldEffects, joinUncaught, ""), effects);
3244
+ }
3245
+ function joinUncaught(joined, held) {
3246
+ return held.boundary.aborted ? joined : concatEffects(joined, held.effects);
3247
+ }
3120
3248
  function flushSerializer(boundary, serializeState) {
3121
3249
  const { state } = boundary;
3122
3250
  const { serializer } = state;
@@ -3624,19 +3752,18 @@ function NOOP$1() {}
3624
3752
  //#endregion
3625
3753
  //#region src/html/assets.ts
3626
3754
  const kAssets = Symbol();
3627
- const kBlockIndex = Symbol();
3628
- const kDeferIndex = Symbol();
3629
- let assetFlush;
3630
- function withLoadAssets(renderer, assetId, triggers) {
3755
+ const kHead = Symbol();
3756
+ function withLoadAssets(renderer, flush, assetId, triggers) {
3631
3757
  return Object.assign((input) => {
3632
- const g = $global();
3633
- addAsset(g, assetId, triggers);
3634
- _html(flush(g, ""));
3758
+ writeLoadAsset(assetId, flush, triggers);
3635
3759
  return writeWaitReady(assetId, renderer, input);
3636
3760
  }, renderer);
3637
3761
  }
3762
+ function writeLoadAsset(assetId, flush, triggers) {
3763
+ const g = $global();
3764
+ writeAsset(g, addAsset(g, assetId, flush, triggers));
3765
+ }
3638
3766
  function withPageAssets(template, runtime, assetId, runtimeId) {
3639
- assetFlush = runtime;
3640
3767
  return Object.assign((input) => {
3641
3768
  const g = $global();
3642
3769
  if (runtimeId) {
@@ -3645,57 +3772,78 @@ function withPageAssets(template, runtime, assetId, runtimeId) {
3645
3772
  g.runtimeId = runtimeId;
3646
3773
  } else if (g.runtimeId !== runtimeId) console.error(`A page entry compiled with runtimeId "${runtimeId}" is nested in a render using runtimeId "${g.runtimeId}", so its content cannot resume.`);
3647
3774
  }
3648
- addAsset(g, assetId);
3775
+ const asset = addAsset(g, assetId, runtime);
3649
3776
  if (g.__flush__) {
3650
- _html(flush(g, ""));
3777
+ writeAsset(g, asset);
3651
3778
  return writeWaitReady(assetId, template, input);
3652
3779
  }
3653
- g.__flush__ = flush;
3780
+ g.__flush__ = flushPage;
3654
3781
  return template(input);
3655
3782
  }, template);
3656
3783
  }
3657
3784
  function _flush_head() {
3658
3785
  const g = $global();
3659
- return g[kAssets] ? flush(g, "") : "";
3786
+ if (!g[kAssets]) return "";
3787
+ g[kHead] = true;
3788
+ return takeAssets(g, catchableBoundary());
3789
+ }
3790
+ function flushPage(g, html) {
3791
+ return takeAssets(g, null) + html;
3792
+ }
3793
+ function takeAssets(g, at) {
3794
+ let block = "";
3795
+ let defer = "";
3796
+ for (const asset of g[kAssets]) if (asset.htmlAt === void 0) {
3797
+ asset.htmlAt = at;
3798
+ block += blockHTML(g, asset);
3799
+ if (!asset.triggers) defer += deferHTML(g, asset);
3800
+ }
3801
+ return block + defer;
3802
+ }
3803
+ function writeAsset(g, asset) {
3804
+ if (needsWrite(asset.htmlAt)) {
3805
+ asset.htmlAt = void 0;
3806
+ if (g[kHead] || g.__flush__ !== flushPage) {
3807
+ const block = blockHTML(g, asset);
3808
+ _html(block + (asset.triggers ? "" : deferHTML(g, asset)));
3809
+ if (block && isInResumedBranch()) writeScript(`document.head.insertAdjacentHTML("beforeend",${_escape_script(JSON.stringify(block))})`);
3810
+ asset.htmlAt = catchableBoundary();
3811
+ }
3812
+ }
3813
+ if (asset.triggers && needsWrite(asset.scriptAt)) {
3814
+ const defer = deferHTML(g, asset);
3815
+ if (defer) writeScript(asset.script ||= triggerScript(asset.id, defer, asset.triggers));
3816
+ asset.scriptAt = catchableBoundary();
3817
+ }
3660
3818
  }
3661
- function flush(g, html) {
3662
- let result = "";
3663
- const assets = g[kAssets];
3664
- const { length } = assets;
3665
- let bi = g[kBlockIndex];
3666
- let di = g[kDeferIndex];
3667
- for (; bi < length; bi++) result += assetFlush(g, "block", assets[bi].id);
3668
- for (; di < length; di++) {
3669
- const { id, triggers } = assets[di];
3670
- const deferHTML = assetFlush(g, "defer", id);
3671
- if (triggers) {
3672
- if (deferHTML) writeTriggerScript(id, deferHTML, triggers);
3673
- } else result += deferHTML;
3674
- }
3675
- g[kBlockIndex] = bi;
3676
- g[kDeferIndex] = di;
3677
- return result + html;
3678
- }
3679
- function addAsset(g, id, triggers) {
3680
- const assets = g[kAssets];
3681
- if (!assets) {
3682
- g[kAssets] = [{
3683
- id,
3684
- triggers
3685
- }];
3686
- g[kBlockIndex] = g[kDeferIndex] = 0;
3687
- } else if (!assets.find((a) => a.id === id)) assets.push({
3819
+ function needsWrite(at) {
3820
+ return at === void 0 || at !== null && mayDrop(at);
3821
+ }
3822
+ function blockHTML(g, asset) {
3823
+ return asset.block ??= asset.flush(g, "block", asset.id);
3824
+ }
3825
+ function deferHTML(g, asset) {
3826
+ return asset.defer ??= asset.flush(g, "defer", asset.id);
3827
+ }
3828
+ function addAsset(g, id, flush, triggers) {
3829
+ const assets = g[kAssets] ||= [];
3830
+ let asset = assets.find((a) => a.id === id);
3831
+ if (!asset) assets.push(asset = {
3688
3832
  id,
3689
- triggers
3833
+ flush,
3834
+ triggers,
3835
+ block: void 0,
3836
+ defer: void 0,
3837
+ script: void 0,
3838
+ htmlAt: void 0,
3839
+ scriptAt: void 0
3690
3840
  });
3691
- else {
3692
- const existing = assets.find((a) => a.id === id);
3693
- if (JSON.stringify(existing.triggers) !== JSON.stringify(triggers)) console.error(`The lazy asset "${id}" is imported with different \`load\` triggers; an asset must use one consistent trigger.`);
3694
- }
3841
+ else if (JSON.stringify(asset.triggers) !== JSON.stringify(triggers)) console.error(`The lazy asset "${id}" is imported with different \`load\` triggers; an asset must use one consistent trigger.`);
3842
+ return asset;
3695
3843
  }
3696
- function writeTriggerScript(id, html, triggers) {
3844
+ function triggerScript(id, html, triggers) {
3697
3845
  const htmlStr = _escape_script(JSON.stringify(html));
3698
- const insert = `(d=new Range().createContextualFragment(h),d.querySelectorAll("script").forEach(s=>s.onerror=()=>console.error(${_escape_script(JSON.stringify(`The lazy module for "${id}" failed to load; its server-rendered content cannot become interactive.`))})),p.after(d))`;
3846
+ const insert = `(d=new Range().createContextualFragment(h),d.querySelectorAll("script").forEach(s=>s.onerror=()=>console.error(${_escape_script(JSON.stringify(`The lazy module for "${id}" failed to load; its server-rendered content cannot become interactive.`))})),document.head.append(d))`;
3699
3847
  const exprs = triggers.map((trigger) => {
3700
3848
  const options = trigger.options && toObjectExpression(trigger.options);
3701
3849
  switch (trigger.type) {
@@ -3705,7 +3853,7 @@ function writeTriggerScript(id, html, triggers) {
3705
3853
  default: return `(e=>e?.addEventListener("${trigger.type.slice(3)}",l,{once:1}))(${querySelectorOrLoad(trigger.selector)})`;
3706
3854
  }
3707
3855
  });
3708
- writeScript(`((p,h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3856
+ return `((h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(${htmlStr})`;
3709
3857
  }
3710
3858
  function querySelectorOrLoad(selector) {
3711
3859
  return `document.querySelector(${JSON.stringify(selector)})||${`(console.warn(${JSON.stringify(`A lazy load trigger could not find an element matching "${selector}". The module was loaded immediately.`)}),l())`}`;
@@ -3729,6 +3877,7 @@ const K_TAGS_API_STATE = Symbol();
3729
3877
  const COMPAT_REGISTRY = /* @__PURE__ */ new WeakMap();
3730
3878
  const compat = {
3731
3879
  $global,
3880
+ writeLoadAsset,
3732
3881
  fork: _await,
3733
3882
  write: _html,
3734
3883
  writeScript,
@@ -3752,7 +3901,10 @@ const compat = {
3752
3901
  onFlush(fn) {
3753
3902
  const { flushHTML } = Chunk.prototype;
3754
3903
  Chunk.prototype.flushHTML = function(boundary) {
3904
+ const { state } = boundary;
3905
+ const reorders = swapReorders(state, null);
3755
3906
  fn(this);
3907
+ swapReorders(state, reorders);
3756
3908
  return flushHTML.call(this, boundary);
3757
3909
  };
3758
3910
  },
@@ -3778,21 +3930,52 @@ const compat = {
3778
3930
  return compatRegistered;
3779
3931
  };
3780
3932
  },
3933
+ joinChunks(chunks) {
3934
+ let joined;
3935
+ for (const chunk of chunks) {
3936
+ if (chunk.boundary.aborted) continue;
3937
+ if (joined) joined.append(chunk);
3938
+ else joined = chunk;
3939
+ }
3940
+ return joined;
3941
+ },
3942
+ appendChunks(chunks) {
3943
+ const chunk = getChunk();
3944
+ for (const part of chunks) {
3945
+ chunk.append(part);
3946
+ if (part.effects) chunk.lastEffect = part.lastEffect;
3947
+ }
3948
+ },
3949
+ deferReorders(reorders) {
3950
+ const chunk = getChunk();
3951
+ for (let i = reorders.length; i--;) {
3952
+ const carrier = chunk.fork(chunk.boundary, chunk.next);
3953
+ carrier.deferredReorder = reorders[i];
3954
+ chunk.next = carrier;
3955
+ }
3956
+ },
3781
3957
  createChunk($global) {
3782
3958
  const state = this.ensureState($global);
3783
3959
  return new Chunk(new Boundary(state), null, null, state);
3784
3960
  },
3785
- flushScript($global, chunk) {
3786
- chunk ||= this.createChunk($global);
3961
+ flushScript(chunk, reorders) {
3787
3962
  const { boundary } = chunk;
3788
- const scripts = boundary.flush() === 0 ? chunk.flushScript(boundary).scripts : "";
3963
+ const { state } = boundary;
3964
+ let html = "";
3965
+ let scripts = "";
3966
+ if (reorders) for (const reorder of reorders) state.reorder(reorder);
3967
+ if (boundary.flush() === 0) ({html, scripts} = chunk.flushScript(boundary));
3789
3968
  if (boundary.aborted) throw boundary.reason;
3790
3969
  if (boundary.count) throw new Error("Cannot serialize promise across tags/class compat layer.");
3791
- return scripts;
3970
+ return {
3971
+ html,
3972
+ scripts
3973
+ };
3792
3974
  },
3793
- render(renderer, willRerender, classAPIOut, component, input, completeChunks, registerChildScope) {
3975
+ render(renderer, willRerender, classAPIOut, component, input, componentScopes, registerChildScope, parentChunk) {
3976
+ if (parentChunk?.boundary.aborted) return;
3794
3977
  const state = this.ensureState(classAPIOut.global);
3795
- const boundary = new Boundary(state);
3978
+ const boundary = new Boundary(state, void 0, parentChunk?.boundary);
3796
3979
  const context = getChunk()?.context ?? null;
3797
3980
  let head = new Chunk(boundary, new Chunk(boundary, null, context, state), context, state);
3798
3981
  let normalizedInput = input;
@@ -3800,7 +3983,8 @@ const compat = {
3800
3983
  normalizedInput = {};
3801
3984
  for (const key in input) normalizedInput[key === "renderBody" ? "content" : key] = input[key];
3802
3985
  }
3803
- head.render(() => {
3986
+ const componentScope = new Chunk(boundary, null, context, state);
3987
+ componentScope.render(() => {
3804
3988
  if (this.hasPendingClassFunctions(classAPIOut.global)) drainClassFunctions(classAPIOut.global, (hostId) => {
3805
3989
  const fnScopeId = _scope_id();
3806
3990
  const scope = writeScope(fnScopeId, {
@@ -3815,6 +3999,8 @@ const compat = {
3815
3999
  writeScope(scopeId, { m5c: component.id });
3816
4000
  _script(scopeId, SET_SCOPE_REGISTER_ID);
3817
4001
  }
4002
+ });
4003
+ head.render(() => {
3818
4004
  _set_scope_reason(willRerender ? CLIENT_ALL : 0);
3819
4005
  try {
3820
4006
  renderer(normalizedInput);
@@ -3828,16 +4014,28 @@ const compat = {
3828
4014
  classAPIOut.onLast((next) => {
3829
4015
  (boundary.onNext = () => {
3830
4016
  if (boundary.aborted) {
3831
- asyncOut.error(boundary.reason);
3832
4017
  boundary.onNext = NOOP;
4018
+ if (parentChunk?.boundary.aborted) {
4019
+ asyncOut.end();
4020
+ next();
4021
+ } else asyncOut.error(boundary.reason);
3833
4022
  } else if (!boundary.count) {
3834
4023
  boundary.onNext = NOOP;
4024
+ const queued = swapReorders(state, null);
3835
4025
  head = head.consume(boundary);
4026
+ const reorders = swapReorders(state, queued);
4027
+ if (reorders) asyncOut.writer.get("reorders").push(...reorders);
4028
+ const heldEffects = head.takeHeldEffects();
4029
+ if (heldEffects) {
4030
+ head.effects = joinHeldEffects(heldEffects, head.effects);
4031
+ head.lastEffect = "";
4032
+ }
3836
4033
  asyncOut.write(head.html);
3837
4034
  asyncOut.script(head.scripts);
3838
- asyncOut.end();
3839
4035
  head.html = head.scripts = "";
3840
- completeChunks.push(head);
4036
+ asyncOut.writer.get("chunks").push(head);
4037
+ asyncOut.end();
4038
+ componentScopes.push(componentScope);
3841
4039
  next();
3842
4040
  }
3843
4041
  })();
@@ -3875,9 +4073,15 @@ function drainClassFunctions($global, writeScope) {
3875
4073
  for (const [id, fn, hostId] of pending) register(id, fn, scopeByHost[hostId] ||= writeScope(hostId));
3876
4074
  pending.length = 0;
3877
4075
  }
4076
+ function swapReorders(state, reorders) {
4077
+ const { writeReorders } = state;
4078
+ state.writeReorders = reorders;
4079
+ return writeReorders;
4080
+ }
3878
4081
  function NOOP() {}
3879
4082
  //#endregion
3880
4083
  exports.$global = $global;
4084
+ exports._assert_class_toggles = _assert_class_toggles;
3881
4085
  exports._assert_hoist = _assert_hoist;
3882
4086
  exports._attr = _attr;
3883
4087
  exports._attr_and = _attr_and;