marko 6.4.1 → 6.4.3

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 (80) hide show
  1. package/cheatsheet.md +1 -1
  2. package/dist/common/constants/accessor-prop.d.ts +1 -0
  3. package/dist/common/constants/accessor-prop.debug.d.ts +1 -0
  4. package/dist/common/errors.d.ts +1 -0
  5. package/dist/common/opt.d.ts +1 -0
  6. package/dist/common/types.d.ts +1 -0
  7. package/dist/debug/dom/catch.feat.js +1 -1
  8. package/dist/debug/dom/catch.feat.mjs +1 -1
  9. package/dist/debug/dom/controllable-input.feat.js +1 -1
  10. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  11. package/dist/debug/dom/controllable-open.feat.js +1 -1
  12. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  13. package/dist/debug/dom/controllable-select.feat.js +1 -1
  14. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  15. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  16. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  17. package/dist/debug/dom/controllable.feat.js +1 -1
  18. package/dist/debug/dom/controllable.feat.mjs +1 -1
  19. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  20. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  21. package/dist/debug/dom/dynamic-tag-var.feat.js +6 -2
  22. package/dist/debug/dom/dynamic-tag-var.feat.mjs +6 -2
  23. package/dist/debug/dom/lazy.feat.js +1 -1
  24. package/dist/debug/dom/lazy.feat.mjs +1 -1
  25. package/dist/debug/dom/placeholder.feat.js +1 -1
  26. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  27. package/dist/debug/{dom-ClV4kVOO.js → dom-C7F3yZTh.js} +119 -24
  28. package/dist/debug/{dom-LFrKxOk5.mjs → dom-uEY0J_H9.mjs} +78 -25
  29. package/dist/debug/dom.js +16 -4
  30. package/dist/debug/dom.mjs +14 -5
  31. package/dist/debug/html.js +288 -78
  32. package/dist/debug/html.mjs +288 -79
  33. package/dist/dom/catch.feat.js +4 -4
  34. package/dist/dom/catch.feat.mjs +1 -1
  35. package/dist/dom/control-flow.d.ts +2 -2
  36. package/dist/dom/controllable-input.feat.js +2 -2
  37. package/dist/dom/controllable-input.feat.mjs +1 -1
  38. package/dist/dom/controllable-open.feat.js +2 -2
  39. package/dist/dom/controllable-open.feat.mjs +1 -1
  40. package/dist/dom/controllable-select.feat.js +2 -2
  41. package/dist/dom/controllable-select.feat.mjs +1 -1
  42. package/dist/dom/controllable-textarea.feat.js +2 -2
  43. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  44. package/dist/dom/controllable.feat.js +2 -2
  45. package/dist/dom/controllable.feat.mjs +1 -1
  46. package/dist/dom/dom.d.ts +1 -0
  47. package/dist/dom/dynamic-tag-script.feat.js +2 -2
  48. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  49. package/dist/dom/dynamic-tag-var.feat.js +4 -2
  50. package/dist/dom/dynamic-tag-var.feat.mjs +4 -3
  51. package/dist/dom/lazy.feat.js +1 -1
  52. package/dist/dom/lazy.feat.mjs +1 -1
  53. package/dist/dom/load.d.ts +1 -0
  54. package/dist/dom/placeholder.feat.js +3 -3
  55. package/dist/dom/placeholder.feat.mjs +1 -1
  56. package/dist/dom/queue.d.ts +4 -1
  57. package/dist/{dom-CNglVi8P.js → dom-CtIT8Mpr.js} +201 -138
  58. package/dist/{dom-DfP3MCo0.mjs → dom-DHg9YChM.mjs} +60 -27
  59. package/dist/dom.d.ts +3 -3
  60. package/dist/dom.js +41 -34
  61. package/dist/dom.mjs +12 -5
  62. package/dist/html/assets.d.ts +12 -6
  63. package/dist/html/attrs.d.ts +1 -0
  64. package/dist/html/compat.d.ts +10 -2
  65. package/dist/html/serializer.d.ts +1 -0
  66. package/dist/html/writer.d.ts +8 -0
  67. package/dist/html.d.ts +1 -1
  68. package/dist/html.js +207 -62
  69. package/dist/html.mjs +207 -62
  70. package/dist/translator/index.js +432 -213
  71. package/dist/translator/util/bindings.d.ts +9 -1
  72. package/dist/translator/util/constants/structure-kind.d.ts +1 -0
  73. package/dist/translator/util/known-tag.d.ts +2 -1
  74. package/dist/translator/util/module-read.d.ts +21 -0
  75. package/dist/translator/util/references.d.ts +1 -0
  76. package/dist/translator/util/runtime.d.ts +2 -0
  77. package/dist/translator/util/sections.d.ts +5 -1
  78. package/dist/translator/util/structure.d.ts +1 -0
  79. package/package.json +3 -3
  80. package/tags-html.d.ts +6 -5
@@ -162,6 +162,16 @@ function assertValidAttrValue(name, value) {
162
162
  const unrenderable = describeUnrenderable(value);
163
163
  if (unrenderable) throw new Error(`The \`${name}\` attribute cannot be ${unrenderable}.`);
164
164
  }
165
+ function _assert_class_toggles(classes, toggles) {
166
+ {
167
+ const written = new Set(classes.split(" "));
168
+ for (const toggle of toggles) {
169
+ const names = new Set(toggle.split(" "));
170
+ 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.`);
171
+ for (const name of names) written.add(name);
172
+ }
173
+ }
174
+ }
165
175
  function assertValidTextValue(value) {
166
176
  const unrenderable = describeUnrenderable(value);
167
177
  if (unrenderable) throw new Error(`Text content cannot be ${unrenderable}.`);
@@ -294,6 +304,13 @@ function forUntil(until, from, step, cb) {
294
304
  }
295
305
  //#endregion
296
306
  //#region src/common/opt.ts
307
+ function reduce(opt, cb, acc) {
308
+ if (opt) {
309
+ if (Array.isArray(opt)) for (const item of opt) acc = cb(acc, item);
310
+ else acc = cb(acc, opt);
311
+ }
312
+ return acc;
313
+ }
297
314
  function push(opt, item) {
298
315
  return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
299
316
  }
@@ -642,6 +659,17 @@ var Serializer = class {
642
659
  channel
643
660
  });
644
661
  }
662
+ dropCall(value, object, property) {
663
+ const { mutated } = this.#state;
664
+ for (let i = 0; i < mutated.length; i++) {
665
+ const mutation = mutated[i];
666
+ if (mutation.value === value && mutation.object === object && mutation.property === property) {
667
+ mutated.splice(i, 1);
668
+ return true;
669
+ }
670
+ }
671
+ return false;
672
+ }
645
673
  };
646
674
  function register(id, val, scope, locals) {
647
675
  REGISTRY.set(val, {
@@ -2233,6 +2261,15 @@ function _html(html) {
2233
2261
  function writeScript(script) {
2234
2262
  $chunk.writeScript(script);
2235
2263
  }
2264
+ function catchableBoundary() {
2265
+ const { boundary } = $chunk;
2266
+ return boundary.withinCatch ? boundary : null;
2267
+ }
2268
+ function mayDrop(written) {
2269
+ const { boundary } = $chunk;
2270
+ for (let cur = written; cur && !isWithin(boundary, cur); cur = cur.parent) if (cur.aborted || cur.count) return true;
2271
+ return false;
2272
+ }
2236
2273
  function _script(scopeId, registryId, markerGuard) {
2237
2274
  if (markerGuard === 0 && ($chunk.serializeState.readyId || $chunk.context?.[kIsAsync])) _resume_branch(scopeId);
2238
2275
  $chunk.boundary.state.needsMainRuntime = true;
@@ -2286,9 +2323,12 @@ function _attr_content(nodeAccessor, scopeId, content, markerGuard) {
2286
2323
  const shouldResume = markerGuard !== 0;
2287
2324
  const render = normalizeServerRender(content);
2288
2325
  const branchId = _peek_scope_id();
2289
- if (render) {
2326
+ if (render) try {
2327
+ _set_scope_reason(shouldResume ? CLIENT_ALL : 0);
2290
2328
  if (shouldResume) withBranchId(branchId, render);
2291
2329
  else render();
2330
+ } finally {
2331
+ _set_scope_reason(void 0);
2292
2332
  }
2293
2333
  if (_peek_scope_id() !== branchId) {
2294
2334
  if (shouldResume) writeScope(scopeId, {
@@ -2462,10 +2502,12 @@ function scopeWithId(state, scopeId) {
2462
2502
  }
2463
2503
  function _subscribe(subscribers, scope, resumeId, markerGuard) {
2464
2504
  if (subscribers) {
2465
- const { serializer } = $chunk.boundary.state;
2466
- if (!$chunk.serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2505
+ const { boundary, serializeState } = $chunk;
2506
+ const { serializer } = boundary.state;
2507
+ if (!serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2467
2508
  else if (resumeId) _script(scope[K_SCOPE_ID], resumeId, markerGuard);
2468
- else serializer.writeCall(scope, subscribers, "add", $chunk.serializeState);
2509
+ else serializer.writeCall(scope, subscribers, "add", serializeState);
2510
+ if (boundary.withinCatch) (boundary.subscribed ||= []).push(subscribers, scope, serializeState);
2469
2511
  }
2470
2512
  return scope;
2471
2513
  }
@@ -2594,6 +2636,7 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2594
2636
  const { boundary } = chunk;
2595
2637
  const { state } = boundary;
2596
2638
  const catchBoundary = new Boundary(state, void 0, boundary);
2639
+ if (catchContent) catchBoundary.withinCatch = true;
2597
2640
  const body = chunk.fork(catchBoundary, null);
2598
2641
  const bodyEnd = body.render(() => withBranchId(branchId, content));
2599
2642
  if (catchBoundary.aborted) {
@@ -2627,8 +2670,10 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2627
2670
  const streamed = !chunk.catchRange;
2628
2671
  const catchChunk = chunk.fork(boundary, null);
2629
2672
  chunk.catchRange = null;
2673
+ if (!renderersAtSettle) catchChunk.render(clearTryRenderers, branchId);
2630
2674
  const inOrder = catchChunk === catchChunk.render(catchContent, catchBoundary.reason);
2631
2675
  if (boundary.aborted) return;
2676
+ if (bodyEnd.consumed || !inOrder) catchChunk.reorderBranch = branchId;
2632
2677
  if (bodyEnd.consumed) {
2633
2678
  catchChunk.reorderId = reorderId;
2634
2679
  state.reorder(catchChunk);
@@ -2657,6 +2702,20 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2657
2702
  };
2658
2703
  return renderersAtSettle;
2659
2704
  }
2705
+ function unsubscribe(subscribed, serializer) {
2706
+ for (let i = 0; i < subscribed.length; i += 3) {
2707
+ const subscribers = subscribed[i];
2708
+ const scope = subscribed[i + 1];
2709
+ if (!serializer.written(subscribers)) subscribers.delete(scope);
2710
+ else if (!serializer.dropCall(scope, subscribers, "add")) serializer.writeCall(scope, subscribers, "delete", subscribed[i + 2]);
2711
+ }
2712
+ }
2713
+ function clearTryRenderers(branchId) {
2714
+ writeScope(branchId, {
2715
+ [CatchContent]: 0,
2716
+ [PlaceholderContent]: _scope_with_id(branchId)["#PlaceholderContent"] && 0
2717
+ });
2718
+ }
2660
2719
  function writeTryRenderers(branchId, catchContent, placeholderContent) {
2661
2720
  writeScope(branchId, {
2662
2721
  [CatchContent]: catchContent,
@@ -2765,12 +2824,15 @@ var Boundary = class {
2765
2824
  parent;
2766
2825
  aborted = false;
2767
2826
  reason;
2827
+ subscribed;
2768
2828
  pendingReorders;
2769
2829
  children;
2830
+ withinCatch = false;
2770
2831
  constructor(state, signal, parent) {
2771
2832
  this.state = state;
2772
2833
  this.parent = parent;
2773
2834
  if (parent) {
2835
+ this.withinCatch = parent.withinCatch;
2774
2836
  if (parent.aborted) this.abort(parent.reason);
2775
2837
  else (parent.children ||= []).push(this);
2776
2838
  } else if (signal) {
@@ -2783,6 +2845,7 @@ var Boundary = class {
2783
2845
  const { state } = this;
2784
2846
  this.aborted = true;
2785
2847
  this.reason = reason;
2848
+ if (this.subscribed) unsubscribe(this.subscribed, state.serializer);
2786
2849
  if (this.pendingReorders) {
2787
2850
  for (const reorder of this.pendingReorders) state.reorder(reorder);
2788
2851
  this.pendingReorders = void 0;
@@ -2818,7 +2881,9 @@ var Chunk = class Chunk {
2818
2881
  async = false;
2819
2882
  consumed = false;
2820
2883
  reorderId = null;
2884
+ reorderBranch = 0;
2821
2885
  deferredReady = null;
2886
+ heldEffects = null;
2822
2887
  deferredReorder = null;
2823
2888
  catchRange = null;
2824
2889
  placeholder = null;
@@ -2840,7 +2905,7 @@ var Chunk = class Chunk {
2840
2905
  }
2841
2906
  writeEffect(scopeId, registryId) {
2842
2907
  countResumeWrite(this);
2843
- if (this.lastEffect === registryId) this.effects += " " + scopeId;
2908
+ if (this.lastEffect === registryId) this.effects = concatEffects(this.effects, scopeId + "");
2844
2909
  else {
2845
2910
  this.lastEffect = registryId;
2846
2911
  this.effects = concatEffects(this.effects, registryId + " " + scopeId);
@@ -2856,6 +2921,11 @@ var Chunk = class Chunk {
2856
2921
  this.lastEffect = chunk.lastEffect || this.lastEffect;
2857
2922
  this.deferredReady = concat(this.deferredReady, chunk.takeDeferredReady());
2858
2923
  }
2924
+ takeHeldEffects() {
2925
+ const { heldEffects } = this;
2926
+ this.heldEffects = null;
2927
+ return heldEffects;
2928
+ }
2859
2929
  takeDeferredReady() {
2860
2930
  const { deferredReady } = this;
2861
2931
  this.deferredReady = null;
@@ -2908,7 +2978,7 @@ var Chunk = class Chunk {
2908
2978
  return false;
2909
2979
  }
2910
2980
  const { branchId, scopeId, placeholderBranchId } = placeholder;
2911
- const reorderId = body.reorderId = branchId ? branchId + "" : state.nextReorderId();
2981
+ const reorderId = body.reorderId = branchId + "";
2912
2982
  this.writeHTML(state.mark("!^", reorderId));
2913
2983
  const { effects } = this;
2914
2984
  const beforeBranch = deferBranchStart(this);
@@ -2919,7 +2989,7 @@ var Chunk = class Chunk {
2919
2989
  if (stateful) {
2920
2990
  this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2921
2991
  this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2922
- end.writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2992
+ dismissChunk(end, body).writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2923
2993
  }
2924
2994
  this.writeHTML(state.mark("!", reorderId));
2925
2995
  this.deferredReorder = body;
@@ -2947,28 +3017,46 @@ var Chunk = class Chunk {
2947
3017
  let html = "";
2948
3018
  let effects = "";
2949
3019
  let scripts = "";
2950
- let lastEffect = "";
3020
+ let effectsEnd;
3021
+ let heldEffects = this.heldEffects;
2951
3022
  let deferredReady;
3023
+ this.heldEffects = null;
3024
+ if (this.serializeState.readyId && this.effects) followHeldEffects(this);
2952
3025
  while (cur.next && !cur.async) {
2953
3026
  cur.markCatchRange();
2954
3027
  cur.queueDeferredReorder();
2955
3028
  html += cur.html;
2956
3029
  if (cur.serializeState.readyId) deferredReady = push(deferredReady, cur);
2957
3030
  else {
2958
- effects = concatEffects(effects, cur.effects);
3031
+ if (cur.effects) {
3032
+ if (effectsEnd && effectsEnd.boundary !== cur.boundary) {
3033
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3034
+ effects = "";
3035
+ }
3036
+ effectsEnd = cur;
3037
+ effects = concatEffects(effects, cur.effects);
3038
+ }
2959
3039
  scripts = concatScripts(scripts, cur.scripts);
2960
- lastEffect = cur.lastEffect || lastEffect;
2961
3040
  }
2962
3041
  deferredReady = concat(deferredReady, cur.takeDeferredReady());
2963
3042
  cur.consumed = true;
2964
3043
  cur = cur.next;
2965
3044
  }
2966
3045
  cur.deferOwnReady();
3046
+ if (effects) {
3047
+ if (cur.serializeState.readyId) heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3048
+ else if (effectsEnd.boundary !== cur.boundary) {
3049
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3050
+ if (isWithin(cur.boundary, effectsEnd.boundary)) cur.lastEffect ||= effectsEnd.lastEffect;
3051
+ } else {
3052
+ cur.effects = concatEffects(effects, cur.effects);
3053
+ cur.lastEffect ||= effectsEnd.lastEffect;
3054
+ }
3055
+ }
3056
+ cur.heldEffects = heldEffects;
2967
3057
  cur.deferredReady = concat(deferredReady, cur.deferredReady);
2968
3058
  cur.html = html + cur.html;
2969
- cur.effects = concatEffects(effects, cur.effects);
2970
3059
  cur.scripts = concatScripts(scripts, cur.scripts);
2971
- cur.lastEffect ||= lastEffect;
2972
3060
  return cur;
2973
3061
  }
2974
3062
  render(content, val) {
@@ -3021,6 +3109,7 @@ var Chunk = class Chunk {
3021
3109
  const { $global, runtimePrefix } = state;
3022
3110
  let needsWalk = state.walkOnNextFlush;
3023
3111
  if (needsWalk) state.walkOnNextFlush = false;
3112
+ flushSerializer(boundary, state);
3024
3113
  let readyResumeScripts = this.flushReadyScripts(boundary, void 0, this.async);
3025
3114
  for (let channel; !boundary.aborted && (channel = state.serializer.pendingReadyChannel());) {
3026
3115
  const resumes = state.serializer.stringifyScopes([], boundary, channel);
@@ -3029,8 +3118,9 @@ var Chunk = class Chunk {
3029
3118
  readyResumeScripts = concatScripts(readyResumeScripts, state.writeReady(channel.readyId, concatSequence(depsMarker(deps), resumes)));
3030
3119
  }
3031
3120
  if (readyResumeScripts) needsWalk = true;
3032
- const effects = this.async ? "" : this.effects;
3121
+ const effects = this.async ? "" : joinHeldEffects(this.takeHeldEffects(), this.effects);
3033
3122
  let { html, scripts } = this;
3123
+ if (html && state.hasReorderRuntime) html = state.mark("*", "") + html;
3034
3124
  if (state.needsMainRuntime && !state.hasMainRuntime) {
3035
3125
  state.hasMainRuntime = true;
3036
3126
  scripts = concatScripts(scripts, WALKER_RUNTIME_CODE + "(\"" + $global.runtimeId + "\")(\"" + $global.renderId + "\")");
@@ -3049,10 +3139,12 @@ var Chunk = class Chunk {
3049
3139
  state.hasReorderRuntime = true;
3050
3140
  scripts = concatScripts(scripts, REORDER_RUNTIME_CODE + "(" + runtimePrefix + ")");
3051
3141
  }
3052
- const { reorderId } = reorderedChunk;
3142
+ const { reorderId, reorderBranch } = reorderedChunk;
3143
+ const rootBranch = reorderBranch || +reorderId;
3053
3144
  const readyReservations = [];
3054
3145
  let reorderHTML = "";
3055
3146
  let reorderEffects = "";
3147
+ let effectsBoundary = reorderedChunk.boundary;
3056
3148
  let reorderScripts = "";
3057
3149
  let cur = reorderedChunk.boundary.aborted ? null : reorderedChunk;
3058
3150
  reorderedChunk.reorderId = null;
@@ -3065,10 +3157,19 @@ var Chunk = class Chunk {
3065
3157
  this.deferredReady = concat(this.deferredReady, cur.takeDeferredReady());
3066
3158
  cur.consumed = true;
3067
3159
  reorderHTML += cur.html;
3160
+ if (this.async && cur.effects && cur.boundary !== effectsBoundary) {
3161
+ if (reorderEffects) {
3162
+ holdReorderEffects(this, effectsBoundary, reorderEffects);
3163
+ reorderEffects = "";
3164
+ }
3165
+ effectsBoundary = cur.boundary;
3166
+ }
3068
3167
  reorderEffects = concatEffects(reorderEffects, cur.effects);
3069
3168
  reorderScripts = concatScripts(reorderScripts, concatScripts(readyResumeScripts, cur.scripts));
3070
3169
  if (cur.async) {
3071
3170
  reorderHTML += state.mark("#", cur.reorderId = state.nextReorderId());
3171
+ const holeBranch = cur.context?.[kBranchId];
3172
+ cur.reorderBranch = holeBranch > rootBranch ? holeBranch : reorderBranch;
3072
3173
  (cur.boundary.pendingReorders ||= /* @__PURE__ */ new Set()).add(cur);
3073
3174
  cur.html = cur.effects = cur.scripts = cur.lastEffect = "";
3074
3175
  cur.next = null;
@@ -3076,21 +3177,18 @@ var Chunk = class Chunk {
3076
3177
  cur = next;
3077
3178
  }
3078
3179
  if (reorderEffects) {
3079
- if (this.async) {
3080
- this.effects = concatEffects(this.effects, reorderEffects);
3081
- this.lastEffect = "";
3082
- } else {
3180
+ if (this.async) holdReorderEffects(this, effectsBoundary, reorderEffects);
3181
+ else {
3083
3182
  needsResumeArray = true;
3084
3183
  reorderScripts = concatScripts(reorderScripts, "_.push(\"" + reorderEffects + "\")");
3085
3184
  }
3086
3185
  }
3087
3186
  for (const reservation of readyReservations) reordered = concatScripts(reordered, reservation);
3088
3187
  reordered = concatScripts(reordered, reorderScripts && runtimePrefix + ".j" + toAccess(reorderId) + "=_=>{" + reorderScripts + "}");
3089
- html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + reorderHTML + "</t>";
3188
+ html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + (reorderBranch ? state.mark("*", reorderBranch + "") : "") + reorderHTML + "</t>";
3090
3189
  }
3091
3190
  state.writeReorders = null;
3092
3191
  }
3093
- flushSerializer(boundary, state);
3094
3192
  if (state.resumes || needsResumeArray && !state.hasWrittenResume) scripts = concatScripts(scripts, state.resumeScript(state.resumes));
3095
3193
  scripts = concatScripts(scripts, reordered);
3096
3194
  if (needsWalk) scripts = concatScripts(scripts, state.walkScript());
@@ -3115,6 +3213,41 @@ function renderReorderPlaceholders(reorder, reorders) {
3115
3213
  }
3116
3214
  return reorders;
3117
3215
  }
3216
+ function dismissChunk(end, body) {
3217
+ if (end.boundary !== body.boundary) while (end.next) end = end.next;
3218
+ return end;
3219
+ }
3220
+ function followHeldEffects(chunk) {
3221
+ const held = reduce(chunk.deferredReady, lastHeldOf, chunk);
3222
+ if (held !== chunk) {
3223
+ held.effects = concatEffects(held.effects, chunk.effects);
3224
+ chunk.effects = "";
3225
+ }
3226
+ }
3227
+ function lastHeldOf(held, cur) {
3228
+ return cur.serializeState === held.serializeState && cur.boundary === held.boundary ? cur : held;
3229
+ }
3230
+ function holdEffectsOn(heldEffects, chunk, effects) {
3231
+ chunk.effects = effects;
3232
+ return push(heldEffects, chunk);
3233
+ }
3234
+ function isWithin(boundary, outer) {
3235
+ while (boundary && boundary !== outer) boundary = boundary.parent;
3236
+ return !!boundary;
3237
+ }
3238
+ function holdReorderEffects(head, boundary, effects) {
3239
+ if (!head.serializeState.readyId) {
3240
+ if (head.effects) head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(head.boundary, null), head.effects);
3241
+ head.effects = head.lastEffect = "";
3242
+ }
3243
+ head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(boundary, null), effects);
3244
+ }
3245
+ function joinHeldEffects(heldEffects, effects) {
3246
+ return concatEffects(reduce(heldEffects, joinUncaught, ""), effects);
3247
+ }
3248
+ function joinUncaught(joined, held) {
3249
+ return held.boundary.aborted ? joined : concatEffects(joined, held.effects);
3250
+ }
3118
3251
  function flushSerializer(boundary, serializeState) {
3119
3252
  const { state } = boundary;
3120
3253
  const { serializer } = state;
@@ -3317,7 +3450,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, m
3317
3450
  const beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0;
3318
3451
  const render = () => {
3319
3452
  if (renderer) try {
3320
- _set_scope_reason(shouldResume && inputOrArgs !== void 0 ? CLIENT_ALL : 0);
3453
+ _set_scope_reason(shouldResume ? CLIENT_ALL : 0);
3321
3454
  return inputIsArgs ? renderer(...inputOrArgs) : renderer(content ? {
3322
3455
  ...inputOrArgs,
3323
3456
  content
@@ -3332,6 +3465,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, m
3332
3465
  if (beforeBranch !== void 0) {
3333
3466
  applyBranchStart(chunk, beforeBranch, rendered);
3334
3467
  _html(state.mark("]", scopeId + " " + accessor + (rendered ? " " + branchId : "")));
3468
+ if (renderer) _existing_scope(branchId);
3335
3469
  }
3336
3470
  }
3337
3471
  if (rendered) {
@@ -3622,19 +3756,18 @@ function NOOP$1() {}
3622
3756
  //#endregion
3623
3757
  //#region src/html/assets.ts
3624
3758
  const kAssets = Symbol();
3625
- const kBlockIndex = Symbol();
3626
- const kDeferIndex = Symbol();
3627
- let assetFlush;
3628
- function withLoadAssets(renderer, assetId, triggers) {
3759
+ const kHead = Symbol();
3760
+ function withLoadAssets(renderer, flush, assetId, triggers) {
3629
3761
  return Object.assign((input) => {
3630
- const g = $global();
3631
- addAsset(g, assetId, triggers);
3632
- _html(flush(g, ""));
3762
+ writeLoadAsset(assetId, flush, triggers);
3633
3763
  return writeWaitReady(assetId, renderer, input);
3634
3764
  }, renderer);
3635
3765
  }
3766
+ function writeLoadAsset(assetId, flush, triggers) {
3767
+ const g = $global();
3768
+ writeAsset(g, addAsset(g, assetId, flush, triggers));
3769
+ }
3636
3770
  function withPageAssets(template, runtime, assetId, runtimeId) {
3637
- assetFlush = runtime;
3638
3771
  return Object.assign((input) => {
3639
3772
  const g = $global();
3640
3773
  if (runtimeId) {
@@ -3643,57 +3776,78 @@ function withPageAssets(template, runtime, assetId, runtimeId) {
3643
3776
  g.runtimeId = runtimeId;
3644
3777
  } 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.`);
3645
3778
  }
3646
- addAsset(g, assetId);
3779
+ const asset = addAsset(g, assetId, runtime);
3647
3780
  if (g.__flush__) {
3648
- _html(flush(g, ""));
3781
+ writeAsset(g, asset);
3649
3782
  return writeWaitReady(assetId, template, input);
3650
3783
  }
3651
- g.__flush__ = flush;
3784
+ g.__flush__ = flushPage;
3652
3785
  return template(input);
3653
3786
  }, template);
3654
3787
  }
3655
3788
  function _flush_head() {
3656
3789
  const g = $global();
3657
- return g[kAssets] ? flush(g, "") : "";
3790
+ if (!g[kAssets]) return "";
3791
+ g[kHead] = true;
3792
+ return takeAssets(g, catchableBoundary());
3658
3793
  }
3659
- function flush(g, html) {
3660
- let result = "";
3661
- const assets = g[kAssets];
3662
- const { length } = assets;
3663
- let bi = g[kBlockIndex];
3664
- let di = g[kDeferIndex];
3665
- for (; bi < length; bi++) result += assetFlush(g, "block", assets[bi].id);
3666
- for (; di < length; di++) {
3667
- const { id, triggers } = assets[di];
3668
- const deferHTML = assetFlush(g, "defer", id);
3669
- if (triggers) {
3670
- if (deferHTML) writeTriggerScript(id, deferHTML, triggers);
3671
- } else result += deferHTML;
3672
- }
3673
- g[kBlockIndex] = bi;
3674
- g[kDeferIndex] = di;
3675
- return result + html;
3676
- }
3677
- function addAsset(g, id, triggers) {
3678
- const assets = g[kAssets];
3679
- if (!assets) {
3680
- g[kAssets] = [{
3681
- id,
3682
- triggers
3683
- }];
3684
- g[kBlockIndex] = g[kDeferIndex] = 0;
3685
- } else if (!assets.find((a) => a.id === id)) assets.push({
3794
+ function flushPage(g, html) {
3795
+ return takeAssets(g, null) + html;
3796
+ }
3797
+ function takeAssets(g, at) {
3798
+ let block = "";
3799
+ let defer = "";
3800
+ for (const asset of g[kAssets]) if (asset.htmlAt === void 0) {
3801
+ asset.htmlAt = at;
3802
+ block += blockHTML(g, asset);
3803
+ if (!asset.triggers) defer += deferHTML(g, asset);
3804
+ }
3805
+ return block + defer;
3806
+ }
3807
+ function writeAsset(g, asset) {
3808
+ if (needsWrite(asset.htmlAt)) {
3809
+ asset.htmlAt = void 0;
3810
+ if (g[kHead] || g.__flush__ !== flushPage) {
3811
+ const block = blockHTML(g, asset);
3812
+ _html(block + (asset.triggers ? "" : deferHTML(g, asset)));
3813
+ if (block && isInResumedBranch()) writeScript(`document.head.insertAdjacentHTML("beforeend",${_escape_script(JSON.stringify(block))})`);
3814
+ asset.htmlAt = catchableBoundary();
3815
+ }
3816
+ }
3817
+ if (asset.triggers && needsWrite(asset.scriptAt)) {
3818
+ const defer = deferHTML(g, asset);
3819
+ if (defer) writeScript(asset.script ||= triggerScript(asset.id, defer, asset.triggers));
3820
+ asset.scriptAt = catchableBoundary();
3821
+ }
3822
+ }
3823
+ function needsWrite(at) {
3824
+ return at === void 0 || at !== null && mayDrop(at);
3825
+ }
3826
+ function blockHTML(g, asset) {
3827
+ return asset.block ??= asset.flush(g, "block", asset.id);
3828
+ }
3829
+ function deferHTML(g, asset) {
3830
+ return asset.defer ??= asset.flush(g, "defer", asset.id);
3831
+ }
3832
+ function addAsset(g, id, flush, triggers) {
3833
+ const assets = g[kAssets] ||= [];
3834
+ let asset = assets.find((a) => a.id === id);
3835
+ if (!asset) assets.push(asset = {
3686
3836
  id,
3687
- triggers
3837
+ flush,
3838
+ triggers,
3839
+ block: void 0,
3840
+ defer: void 0,
3841
+ script: void 0,
3842
+ htmlAt: void 0,
3843
+ scriptAt: void 0
3688
3844
  });
3689
- else {
3690
- const existing = assets.find((a) => a.id === id);
3691
- 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.`);
3692
- }
3845
+ 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.`);
3846
+ return asset;
3693
3847
  }
3694
- function writeTriggerScript(id, html, triggers) {
3848
+ function triggerScript(id, html, triggers) {
3695
3849
  const htmlStr = _escape_script(JSON.stringify(html));
3696
- 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))`;
3850
+ 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))`;
3697
3851
  const exprs = triggers.map((trigger) => {
3698
3852
  const options = trigger.options && toObjectExpression(trigger.options);
3699
3853
  switch (trigger.type) {
@@ -3703,7 +3857,7 @@ function writeTriggerScript(id, html, triggers) {
3703
3857
  default: return `(e=>e?.addEventListener("${trigger.type.slice(3)}",l,{once:1}))(${querySelectorOrLoad(trigger.selector)})`;
3704
3858
  }
3705
3859
  });
3706
- writeScript(`((p,h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3860
+ return `((h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(${htmlStr})`;
3707
3861
  }
3708
3862
  function querySelectorOrLoad(selector) {
3709
3863
  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())`}`;
@@ -3727,6 +3881,7 @@ const K_TAGS_API_STATE = Symbol();
3727
3881
  const COMPAT_REGISTRY = /* @__PURE__ */ new WeakMap();
3728
3882
  const compat = {
3729
3883
  $global,
3884
+ writeLoadAsset,
3730
3885
  fork: _await,
3731
3886
  write: _html,
3732
3887
  writeScript,
@@ -3750,7 +3905,10 @@ const compat = {
3750
3905
  onFlush(fn) {
3751
3906
  const { flushHTML } = Chunk.prototype;
3752
3907
  Chunk.prototype.flushHTML = function(boundary) {
3908
+ const { state } = boundary;
3909
+ const reorders = swapReorders(state, null);
3753
3910
  fn(this);
3911
+ swapReorders(state, reorders);
3754
3912
  return flushHTML.call(this, boundary);
3755
3913
  };
3756
3914
  },
@@ -3776,21 +3934,52 @@ const compat = {
3776
3934
  return compatRegistered;
3777
3935
  };
3778
3936
  },
3937
+ joinChunks(chunks) {
3938
+ let joined;
3939
+ for (const chunk of chunks) {
3940
+ if (chunk.boundary.aborted) continue;
3941
+ if (joined) joined.append(chunk);
3942
+ else joined = chunk;
3943
+ }
3944
+ return joined;
3945
+ },
3946
+ appendChunks(chunks) {
3947
+ const chunk = getChunk();
3948
+ for (const part of chunks) {
3949
+ chunk.append(part);
3950
+ if (part.effects) chunk.lastEffect = part.lastEffect;
3951
+ }
3952
+ },
3953
+ deferReorders(reorders) {
3954
+ const chunk = getChunk();
3955
+ for (let i = reorders.length; i--;) {
3956
+ const carrier = chunk.fork(chunk.boundary, chunk.next);
3957
+ carrier.deferredReorder = reorders[i];
3958
+ chunk.next = carrier;
3959
+ }
3960
+ },
3779
3961
  createChunk($global) {
3780
3962
  const state = this.ensureState($global);
3781
3963
  return new Chunk(new Boundary(state), null, null, state);
3782
3964
  },
3783
- flushScript($global, chunk) {
3784
- chunk ||= this.createChunk($global);
3965
+ flushScript(chunk, reorders) {
3785
3966
  const { boundary } = chunk;
3786
- const scripts = boundary.flush() === 0 ? chunk.flushScript(boundary).scripts : "";
3967
+ const { state } = boundary;
3968
+ let html = "";
3969
+ let scripts = "";
3970
+ if (reorders) for (const reorder of reorders) state.reorder(reorder);
3971
+ if (boundary.flush() === 0) ({html, scripts} = chunk.flushScript(boundary));
3787
3972
  if (boundary.aborted) throw boundary.reason;
3788
3973
  if (boundary.count) throw new Error("Cannot serialize promise across tags/class compat layer.");
3789
- return scripts;
3974
+ return {
3975
+ html,
3976
+ scripts
3977
+ };
3790
3978
  },
3791
- render(renderer, willRerender, classAPIOut, component, input, completeChunks, registerChildScope) {
3979
+ render(renderer, willRerender, classAPIOut, component, input, componentScopes, registerChildScope, parentChunk) {
3980
+ if (parentChunk?.boundary.aborted) return;
3792
3981
  const state = this.ensureState(classAPIOut.global);
3793
- const boundary = new Boundary(state);
3982
+ const boundary = new Boundary(state, void 0, parentChunk?.boundary);
3794
3983
  const context = getChunk()?.context ?? null;
3795
3984
  let head = new Chunk(boundary, new Chunk(boundary, null, context, state), context, state);
3796
3985
  let normalizedInput = input;
@@ -3798,7 +3987,8 @@ const compat = {
3798
3987
  normalizedInput = {};
3799
3988
  for (const key in input) normalizedInput[key === "renderBody" ? "content" : key] = input[key];
3800
3989
  }
3801
- head.render(() => {
3990
+ const componentScope = new Chunk(boundary, null, context, state);
3991
+ componentScope.render(() => {
3802
3992
  if (this.hasPendingClassFunctions(classAPIOut.global)) drainClassFunctions(classAPIOut.global, (hostId) => {
3803
3993
  const fnScopeId = _scope_id();
3804
3994
  const scope = writeScope(fnScopeId, {
@@ -3813,6 +4003,8 @@ const compat = {
3813
4003
  writeScope(scopeId, { m5c: component.id });
3814
4004
  _script(scopeId, SET_SCOPE_REGISTER_ID);
3815
4005
  }
4006
+ });
4007
+ head.render(() => {
3816
4008
  _set_scope_reason(willRerender ? CLIENT_ALL : 0);
3817
4009
  try {
3818
4010
  renderer(normalizedInput);
@@ -3826,16 +4018,28 @@ const compat = {
3826
4018
  classAPIOut.onLast((next) => {
3827
4019
  (boundary.onNext = () => {
3828
4020
  if (boundary.aborted) {
3829
- asyncOut.error(boundary.reason);
3830
4021
  boundary.onNext = NOOP;
4022
+ if (parentChunk?.boundary.aborted) {
4023
+ asyncOut.end();
4024
+ next();
4025
+ } else asyncOut.error(boundary.reason);
3831
4026
  } else if (!boundary.count) {
3832
4027
  boundary.onNext = NOOP;
4028
+ const queued = swapReorders(state, null);
3833
4029
  head = head.consume(boundary);
4030
+ const reorders = swapReorders(state, queued);
4031
+ if (reorders) asyncOut.writer.get("reorders").push(...reorders);
4032
+ const heldEffects = head.takeHeldEffects();
4033
+ if (heldEffects) {
4034
+ head.effects = joinHeldEffects(heldEffects, head.effects);
4035
+ head.lastEffect = "";
4036
+ }
3834
4037
  asyncOut.write(head.html);
3835
4038
  asyncOut.script(head.scripts);
3836
- asyncOut.end();
3837
4039
  head.html = head.scripts = "";
3838
- completeChunks.push(head);
4040
+ asyncOut.writer.get("chunks").push(head);
4041
+ asyncOut.end();
4042
+ componentScopes.push(componentScope);
3839
4043
  next();
3840
4044
  }
3841
4045
  })();
@@ -3873,6 +4077,11 @@ function drainClassFunctions($global, writeScope) {
3873
4077
  for (const [id, fn, hostId] of pending) register(id, fn, scopeByHost[hostId] ||= writeScope(hostId));
3874
4078
  pending.length = 0;
3875
4079
  }
4080
+ function swapReorders(state, reorders) {
4081
+ const { writeReorders } = state;
4082
+ state.writeReorders = reorders;
4083
+ return writeReorders;
4084
+ }
3876
4085
  function NOOP() {}
3877
4086
  //#endregion
3878
- export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _attrs_select_value, _attrs_textarea_value, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _escape_style_value, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _html_resume, _id, _if, _peek_scope_id, _resume, _resume_branch, _resume_locals, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _set_scope_reason, _show_end, _show_start, _style_html, _subscribe, _template, _text_resume, _textarea_value, _to_text, _trailers, _try, _unescaped, _var, _write_guard, _write_if, attrTag, attrTags, compat, forIn, forOf, forTo, forUntil, withLoadAssets, withPageAssets };
4087
+ export { $global, _assert_class_toggles, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _attrs_select_value, _attrs_textarea_value, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _escape_style_value, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _html_resume, _id, _if, _peek_scope_id, _resume, _resume_branch, _resume_locals, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _set_scope_reason, _show_end, _show_start, _style_html, _subscribe, _template, _text_resume, _textarea_value, _to_text, _trailers, _try, _unescaped, _var, _write_guard, _write_if, attrTag, attrTags, compat, forIn, forOf, forTo, forUntil, withLoadAssets, withPageAssets };