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
@@ -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;
@@ -2288,9 +2325,12 @@ function _attr_content(nodeAccessor, scopeId, content, markerGuard) {
2288
2325
  const shouldResume = markerGuard !== 0;
2289
2326
  const render = normalizeServerRender(content);
2290
2327
  const branchId = _peek_scope_id();
2291
- if (render) {
2328
+ if (render) try {
2329
+ _set_scope_reason(shouldResume ? CLIENT_ALL : 0);
2292
2330
  if (shouldResume) withBranchId(branchId, render);
2293
2331
  else render();
2332
+ } finally {
2333
+ _set_scope_reason(void 0);
2294
2334
  }
2295
2335
  if (_peek_scope_id() !== branchId) {
2296
2336
  if (shouldResume) writeScope(scopeId, {
@@ -2464,10 +2504,12 @@ function scopeWithId(state, scopeId) {
2464
2504
  }
2465
2505
  function _subscribe(subscribers, scope, resumeId, markerGuard) {
2466
2506
  if (subscribers) {
2467
- const { serializer } = $chunk.boundary.state;
2468
- if (!$chunk.serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2507
+ const { boundary, serializeState } = $chunk;
2508
+ const { serializer } = boundary.state;
2509
+ if (!serializeState.readyId && !serializer.written(subscribers)) subscribers.add(scope);
2469
2510
  else if (resumeId) _script(scope[K_SCOPE_ID], resumeId, markerGuard);
2470
- else serializer.writeCall(scope, subscribers, "add", $chunk.serializeState);
2511
+ else serializer.writeCall(scope, subscribers, "add", serializeState);
2512
+ if (boundary.withinCatch) (boundary.subscribed ||= []).push(subscribers, scope, serializeState);
2471
2513
  }
2472
2514
  return scope;
2473
2515
  }
@@ -2596,6 +2638,7 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2596
2638
  const { boundary } = chunk;
2597
2639
  const { state } = boundary;
2598
2640
  const catchBoundary = new Boundary(state, void 0, boundary);
2641
+ if (catchContent) catchBoundary.withinCatch = true;
2599
2642
  const body = chunk.fork(catchBoundary, null);
2600
2643
  const bodyEnd = body.render(() => withBranchId(branchId, content));
2601
2644
  if (catchBoundary.aborted) {
@@ -2629,8 +2672,10 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2629
2672
  const streamed = !chunk.catchRange;
2630
2673
  const catchChunk = chunk.fork(boundary, null);
2631
2674
  chunk.catchRange = null;
2675
+ if (!renderersAtSettle) catchChunk.render(clearTryRenderers, branchId);
2632
2676
  const inOrder = catchChunk === catchChunk.render(catchContent, catchBoundary.reason);
2633
2677
  if (boundary.aborted) return;
2678
+ if (bodyEnd.consumed || !inOrder) catchChunk.reorderBranch = branchId;
2634
2679
  if (bodyEnd.consumed) {
2635
2680
  catchChunk.reorderId = reorderId;
2636
2681
  state.reorder(catchChunk);
@@ -2659,6 +2704,20 @@ function tryBoundary(content, catchContent, branchId, renderers) {
2659
2704
  };
2660
2705
  return renderersAtSettle;
2661
2706
  }
2707
+ function unsubscribe(subscribed, serializer) {
2708
+ for (let i = 0; i < subscribed.length; i += 3) {
2709
+ const subscribers = subscribed[i];
2710
+ const scope = subscribed[i + 1];
2711
+ if (!serializer.written(subscribers)) subscribers.delete(scope);
2712
+ else if (!serializer.dropCall(scope, subscribers, "add")) serializer.writeCall(scope, subscribers, "delete", subscribed[i + 2]);
2713
+ }
2714
+ }
2715
+ function clearTryRenderers(branchId) {
2716
+ writeScope(branchId, {
2717
+ [CatchContent]: 0,
2718
+ [PlaceholderContent]: _scope_with_id(branchId)["#PlaceholderContent"] && 0
2719
+ });
2720
+ }
2662
2721
  function writeTryRenderers(branchId, catchContent, placeholderContent) {
2663
2722
  writeScope(branchId, {
2664
2723
  [CatchContent]: catchContent,
@@ -2767,12 +2826,15 @@ var Boundary = class {
2767
2826
  parent;
2768
2827
  aborted = false;
2769
2828
  reason;
2829
+ subscribed;
2770
2830
  pendingReorders;
2771
2831
  children;
2832
+ withinCatch = false;
2772
2833
  constructor(state, signal, parent) {
2773
2834
  this.state = state;
2774
2835
  this.parent = parent;
2775
2836
  if (parent) {
2837
+ this.withinCatch = parent.withinCatch;
2776
2838
  if (parent.aborted) this.abort(parent.reason);
2777
2839
  else (parent.children ||= []).push(this);
2778
2840
  } else if (signal) {
@@ -2785,6 +2847,7 @@ var Boundary = class {
2785
2847
  const { state } = this;
2786
2848
  this.aborted = true;
2787
2849
  this.reason = reason;
2850
+ if (this.subscribed) unsubscribe(this.subscribed, state.serializer);
2788
2851
  if (this.pendingReorders) {
2789
2852
  for (const reorder of this.pendingReorders) state.reorder(reorder);
2790
2853
  this.pendingReorders = void 0;
@@ -2820,7 +2883,9 @@ var Chunk = class Chunk {
2820
2883
  async = false;
2821
2884
  consumed = false;
2822
2885
  reorderId = null;
2886
+ reorderBranch = 0;
2823
2887
  deferredReady = null;
2888
+ heldEffects = null;
2824
2889
  deferredReorder = null;
2825
2890
  catchRange = null;
2826
2891
  placeholder = null;
@@ -2842,7 +2907,7 @@ var Chunk = class Chunk {
2842
2907
  }
2843
2908
  writeEffect(scopeId, registryId) {
2844
2909
  countResumeWrite(this);
2845
- if (this.lastEffect === registryId) this.effects += " " + scopeId;
2910
+ if (this.lastEffect === registryId) this.effects = concatEffects(this.effects, scopeId + "");
2846
2911
  else {
2847
2912
  this.lastEffect = registryId;
2848
2913
  this.effects = concatEffects(this.effects, registryId + " " + scopeId);
@@ -2858,6 +2923,11 @@ var Chunk = class Chunk {
2858
2923
  this.lastEffect = chunk.lastEffect || this.lastEffect;
2859
2924
  this.deferredReady = concat(this.deferredReady, chunk.takeDeferredReady());
2860
2925
  }
2926
+ takeHeldEffects() {
2927
+ const { heldEffects } = this;
2928
+ this.heldEffects = null;
2929
+ return heldEffects;
2930
+ }
2861
2931
  takeDeferredReady() {
2862
2932
  const { deferredReady } = this;
2863
2933
  this.deferredReady = null;
@@ -2910,7 +2980,7 @@ var Chunk = class Chunk {
2910
2980
  return false;
2911
2981
  }
2912
2982
  const { branchId, scopeId, placeholderBranchId } = placeholder;
2913
- const reorderId = body.reorderId = branchId ? branchId + "" : state.nextReorderId();
2983
+ const reorderId = body.reorderId = branchId + "";
2914
2984
  this.writeHTML(state.mark("!^", reorderId));
2915
2985
  const { effects } = this;
2916
2986
  const beforeBranch = deferBranchStart(this);
@@ -2921,7 +2991,7 @@ var Chunk = class Chunk {
2921
2991
  if (stateful) {
2922
2992
  this.render(() => writeScope(branchId, { [PlaceholderBranch]: scopeWithId(state, placeholderBranchId) }));
2923
2993
  this.writeHTML(state.mark("]", scopeId + " " + (PlaceholderBranch + branchId) + " " + placeholderBranchId));
2924
- end.writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2994
+ dismissChunk(end, body).writeEffect(branchId, PLACEHOLDER_DISMISS_REGISTER_ID);
2925
2995
  }
2926
2996
  this.writeHTML(state.mark("!", reorderId));
2927
2997
  this.deferredReorder = body;
@@ -2949,28 +3019,46 @@ var Chunk = class Chunk {
2949
3019
  let html = "";
2950
3020
  let effects = "";
2951
3021
  let scripts = "";
2952
- let lastEffect = "";
3022
+ let effectsEnd;
3023
+ let heldEffects = this.heldEffects;
2953
3024
  let deferredReady;
3025
+ this.heldEffects = null;
3026
+ if (this.serializeState.readyId && this.effects) followHeldEffects(this);
2954
3027
  while (cur.next && !cur.async) {
2955
3028
  cur.markCatchRange();
2956
3029
  cur.queueDeferredReorder();
2957
3030
  html += cur.html;
2958
3031
  if (cur.serializeState.readyId) deferredReady = push(deferredReady, cur);
2959
3032
  else {
2960
- effects = concatEffects(effects, cur.effects);
3033
+ if (cur.effects) {
3034
+ if (effectsEnd && effectsEnd.boundary !== cur.boundary) {
3035
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3036
+ effects = "";
3037
+ }
3038
+ effectsEnd = cur;
3039
+ effects = concatEffects(effects, cur.effects);
3040
+ }
2961
3041
  scripts = concatScripts(scripts, cur.scripts);
2962
- lastEffect = cur.lastEffect || lastEffect;
2963
3042
  }
2964
3043
  deferredReady = concat(deferredReady, cur.takeDeferredReady());
2965
3044
  cur.consumed = true;
2966
3045
  cur = cur.next;
2967
3046
  }
2968
3047
  cur.deferOwnReady();
3048
+ if (effects) {
3049
+ if (cur.serializeState.readyId) heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3050
+ else if (effectsEnd.boundary !== cur.boundary) {
3051
+ heldEffects = holdEffectsOn(heldEffects, effectsEnd, effects);
3052
+ if (isWithin(cur.boundary, effectsEnd.boundary)) cur.lastEffect ||= effectsEnd.lastEffect;
3053
+ } else {
3054
+ cur.effects = concatEffects(effects, cur.effects);
3055
+ cur.lastEffect ||= effectsEnd.lastEffect;
3056
+ }
3057
+ }
3058
+ cur.heldEffects = heldEffects;
2969
3059
  cur.deferredReady = concat(deferredReady, cur.deferredReady);
2970
3060
  cur.html = html + cur.html;
2971
- cur.effects = concatEffects(effects, cur.effects);
2972
3061
  cur.scripts = concatScripts(scripts, cur.scripts);
2973
- cur.lastEffect ||= lastEffect;
2974
3062
  return cur;
2975
3063
  }
2976
3064
  render(content, val) {
@@ -3023,6 +3111,7 @@ var Chunk = class Chunk {
3023
3111
  const { $global, runtimePrefix } = state;
3024
3112
  let needsWalk = state.walkOnNextFlush;
3025
3113
  if (needsWalk) state.walkOnNextFlush = false;
3114
+ flushSerializer(boundary, state);
3026
3115
  let readyResumeScripts = this.flushReadyScripts(boundary, void 0, this.async);
3027
3116
  for (let channel; !boundary.aborted && (channel = state.serializer.pendingReadyChannel());) {
3028
3117
  const resumes = state.serializer.stringifyScopes([], boundary, channel);
@@ -3031,8 +3120,9 @@ var Chunk = class Chunk {
3031
3120
  readyResumeScripts = concatScripts(readyResumeScripts, state.writeReady(channel.readyId, concatSequence(depsMarker(deps), resumes)));
3032
3121
  }
3033
3122
  if (readyResumeScripts) needsWalk = true;
3034
- const effects = this.async ? "" : this.effects;
3123
+ const effects = this.async ? "" : joinHeldEffects(this.takeHeldEffects(), this.effects);
3035
3124
  let { html, scripts } = this;
3125
+ if (html && state.hasReorderRuntime) html = state.mark("*", "") + html;
3036
3126
  if (state.needsMainRuntime && !state.hasMainRuntime) {
3037
3127
  state.hasMainRuntime = true;
3038
3128
  scripts = concatScripts(scripts, WALKER_RUNTIME_CODE + "(\"" + $global.runtimeId + "\")(\"" + $global.renderId + "\")");
@@ -3051,10 +3141,12 @@ var Chunk = class Chunk {
3051
3141
  state.hasReorderRuntime = true;
3052
3142
  scripts = concatScripts(scripts, REORDER_RUNTIME_CODE + "(" + runtimePrefix + ")");
3053
3143
  }
3054
- const { reorderId } = reorderedChunk;
3144
+ const { reorderId, reorderBranch } = reorderedChunk;
3145
+ const rootBranch = reorderBranch || +reorderId;
3055
3146
  const readyReservations = [];
3056
3147
  let reorderHTML = "";
3057
3148
  let reorderEffects = "";
3149
+ let effectsBoundary = reorderedChunk.boundary;
3058
3150
  let reorderScripts = "";
3059
3151
  let cur = reorderedChunk.boundary.aborted ? null : reorderedChunk;
3060
3152
  reorderedChunk.reorderId = null;
@@ -3067,10 +3159,19 @@ var Chunk = class Chunk {
3067
3159
  this.deferredReady = concat(this.deferredReady, cur.takeDeferredReady());
3068
3160
  cur.consumed = true;
3069
3161
  reorderHTML += cur.html;
3162
+ if (this.async && cur.effects && cur.boundary !== effectsBoundary) {
3163
+ if (reorderEffects) {
3164
+ holdReorderEffects(this, effectsBoundary, reorderEffects);
3165
+ reorderEffects = "";
3166
+ }
3167
+ effectsBoundary = cur.boundary;
3168
+ }
3070
3169
  reorderEffects = concatEffects(reorderEffects, cur.effects);
3071
3170
  reorderScripts = concatScripts(reorderScripts, concatScripts(readyResumeScripts, cur.scripts));
3072
3171
  if (cur.async) {
3073
3172
  reorderHTML += state.mark("#", cur.reorderId = state.nextReorderId());
3173
+ const holeBranch = cur.context?.[kBranchId];
3174
+ cur.reorderBranch = holeBranch > rootBranch ? holeBranch : reorderBranch;
3074
3175
  (cur.boundary.pendingReorders ||= /* @__PURE__ */ new Set()).add(cur);
3075
3176
  cur.html = cur.effects = cur.scripts = cur.lastEffect = "";
3076
3177
  cur.next = null;
@@ -3078,21 +3179,18 @@ var Chunk = class Chunk {
3078
3179
  cur = next;
3079
3180
  }
3080
3181
  if (reorderEffects) {
3081
- if (this.async) {
3082
- this.effects = concatEffects(this.effects, reorderEffects);
3083
- this.lastEffect = "";
3084
- } else {
3182
+ if (this.async) holdReorderEffects(this, effectsBoundary, reorderEffects);
3183
+ else {
3085
3184
  needsResumeArray = true;
3086
3185
  reorderScripts = concatScripts(reorderScripts, "_.push(\"" + reorderEffects + "\")");
3087
3186
  }
3088
3187
  }
3089
3188
  for (const reservation of readyReservations) reordered = concatScripts(reordered, reservation);
3090
3189
  reordered = concatScripts(reordered, reorderScripts && runtimePrefix + ".j" + toAccess(reorderId) + "=_=>{" + reorderScripts + "}");
3091
- html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + reorderHTML + "</t>";
3190
+ html += "<t hidden " + state.commentPrefix + "=" + reorderId + ">" + (reorderBranch ? state.mark("*", reorderBranch + "") : "") + reorderHTML + "</t>";
3092
3191
  }
3093
3192
  state.writeReorders = null;
3094
3193
  }
3095
- flushSerializer(boundary, state);
3096
3194
  if (state.resumes || needsResumeArray && !state.hasWrittenResume) scripts = concatScripts(scripts, state.resumeScript(state.resumes));
3097
3195
  scripts = concatScripts(scripts, reordered);
3098
3196
  if (needsWalk) scripts = concatScripts(scripts, state.walkScript());
@@ -3117,6 +3215,41 @@ function renderReorderPlaceholders(reorder, reorders) {
3117
3215
  }
3118
3216
  return reorders;
3119
3217
  }
3218
+ function dismissChunk(end, body) {
3219
+ if (end.boundary !== body.boundary) while (end.next) end = end.next;
3220
+ return end;
3221
+ }
3222
+ function followHeldEffects(chunk) {
3223
+ const held = reduce(chunk.deferredReady, lastHeldOf, chunk);
3224
+ if (held !== chunk) {
3225
+ held.effects = concatEffects(held.effects, chunk.effects);
3226
+ chunk.effects = "";
3227
+ }
3228
+ }
3229
+ function lastHeldOf(held, cur) {
3230
+ return cur.serializeState === held.serializeState && cur.boundary === held.boundary ? cur : held;
3231
+ }
3232
+ function holdEffectsOn(heldEffects, chunk, effects) {
3233
+ chunk.effects = effects;
3234
+ return push(heldEffects, chunk);
3235
+ }
3236
+ function isWithin(boundary, outer) {
3237
+ while (boundary && boundary !== outer) boundary = boundary.parent;
3238
+ return !!boundary;
3239
+ }
3240
+ function holdReorderEffects(head, boundary, effects) {
3241
+ if (!head.serializeState.readyId) {
3242
+ if (head.effects) head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(head.boundary, null), head.effects);
3243
+ head.effects = head.lastEffect = "";
3244
+ }
3245
+ head.heldEffects = holdEffectsOn(head.heldEffects, head.fork(boundary, null), effects);
3246
+ }
3247
+ function joinHeldEffects(heldEffects, effects) {
3248
+ return concatEffects(reduce(heldEffects, joinUncaught, ""), effects);
3249
+ }
3250
+ function joinUncaught(joined, held) {
3251
+ return held.boundary.aborted ? joined : concatEffects(joined, held.effects);
3252
+ }
3120
3253
  function flushSerializer(boundary, serializeState) {
3121
3254
  const { state } = boundary;
3122
3255
  const { serializer } = state;
@@ -3319,7 +3452,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, m
3319
3452
  const beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0;
3320
3453
  const render = () => {
3321
3454
  if (renderer) try {
3322
- _set_scope_reason(shouldResume && inputOrArgs !== void 0 ? CLIENT_ALL : 0);
3455
+ _set_scope_reason(shouldResume ? CLIENT_ALL : 0);
3323
3456
  return inputIsArgs ? renderer(...inputOrArgs) : renderer(content ? {
3324
3457
  ...inputOrArgs,
3325
3458
  content
@@ -3334,6 +3467,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, m
3334
3467
  if (beforeBranch !== void 0) {
3335
3468
  applyBranchStart(chunk, beforeBranch, rendered);
3336
3469
  _html(state.mark("]", scopeId + " " + accessor + (rendered ? " " + branchId : "")));
3470
+ if (renderer) _existing_scope(branchId);
3337
3471
  }
3338
3472
  }
3339
3473
  if (rendered) {
@@ -3624,19 +3758,18 @@ function NOOP$1() {}
3624
3758
  //#endregion
3625
3759
  //#region src/html/assets.ts
3626
3760
  const kAssets = Symbol();
3627
- const kBlockIndex = Symbol();
3628
- const kDeferIndex = Symbol();
3629
- let assetFlush;
3630
- function withLoadAssets(renderer, assetId, triggers) {
3761
+ const kHead = Symbol();
3762
+ function withLoadAssets(renderer, flush, assetId, triggers) {
3631
3763
  return Object.assign((input) => {
3632
- const g = $global();
3633
- addAsset(g, assetId, triggers);
3634
- _html(flush(g, ""));
3764
+ writeLoadAsset(assetId, flush, triggers);
3635
3765
  return writeWaitReady(assetId, renderer, input);
3636
3766
  }, renderer);
3637
3767
  }
3768
+ function writeLoadAsset(assetId, flush, triggers) {
3769
+ const g = $global();
3770
+ writeAsset(g, addAsset(g, assetId, flush, triggers));
3771
+ }
3638
3772
  function withPageAssets(template, runtime, assetId, runtimeId) {
3639
- assetFlush = runtime;
3640
3773
  return Object.assign((input) => {
3641
3774
  const g = $global();
3642
3775
  if (runtimeId) {
@@ -3645,57 +3778,78 @@ function withPageAssets(template, runtime, assetId, runtimeId) {
3645
3778
  g.runtimeId = runtimeId;
3646
3779
  } 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
3780
  }
3648
- addAsset(g, assetId);
3781
+ const asset = addAsset(g, assetId, runtime);
3649
3782
  if (g.__flush__) {
3650
- _html(flush(g, ""));
3783
+ writeAsset(g, asset);
3651
3784
  return writeWaitReady(assetId, template, input);
3652
3785
  }
3653
- g.__flush__ = flush;
3786
+ g.__flush__ = flushPage;
3654
3787
  return template(input);
3655
3788
  }, template);
3656
3789
  }
3657
3790
  function _flush_head() {
3658
3791
  const g = $global();
3659
- return g[kAssets] ? flush(g, "") : "";
3792
+ if (!g[kAssets]) return "";
3793
+ g[kHead] = true;
3794
+ return takeAssets(g, catchableBoundary());
3795
+ }
3796
+ function flushPage(g, html) {
3797
+ return takeAssets(g, null) + html;
3798
+ }
3799
+ function takeAssets(g, at) {
3800
+ let block = "";
3801
+ let defer = "";
3802
+ for (const asset of g[kAssets]) if (asset.htmlAt === void 0) {
3803
+ asset.htmlAt = at;
3804
+ block += blockHTML(g, asset);
3805
+ if (!asset.triggers) defer += deferHTML(g, asset);
3806
+ }
3807
+ return block + defer;
3808
+ }
3809
+ function writeAsset(g, asset) {
3810
+ if (needsWrite(asset.htmlAt)) {
3811
+ asset.htmlAt = void 0;
3812
+ if (g[kHead] || g.__flush__ !== flushPage) {
3813
+ const block = blockHTML(g, asset);
3814
+ _html(block + (asset.triggers ? "" : deferHTML(g, asset)));
3815
+ if (block && isInResumedBranch()) writeScript(`document.head.insertAdjacentHTML("beforeend",${_escape_script(JSON.stringify(block))})`);
3816
+ asset.htmlAt = catchableBoundary();
3817
+ }
3818
+ }
3819
+ if (asset.triggers && needsWrite(asset.scriptAt)) {
3820
+ const defer = deferHTML(g, asset);
3821
+ if (defer) writeScript(asset.script ||= triggerScript(asset.id, defer, asset.triggers));
3822
+ asset.scriptAt = catchableBoundary();
3823
+ }
3660
3824
  }
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({
3825
+ function needsWrite(at) {
3826
+ return at === void 0 || at !== null && mayDrop(at);
3827
+ }
3828
+ function blockHTML(g, asset) {
3829
+ return asset.block ??= asset.flush(g, "block", asset.id);
3830
+ }
3831
+ function deferHTML(g, asset) {
3832
+ return asset.defer ??= asset.flush(g, "defer", asset.id);
3833
+ }
3834
+ function addAsset(g, id, flush, triggers) {
3835
+ const assets = g[kAssets] ||= [];
3836
+ let asset = assets.find((a) => a.id === id);
3837
+ if (!asset) assets.push(asset = {
3688
3838
  id,
3689
- triggers
3839
+ flush,
3840
+ triggers,
3841
+ block: void 0,
3842
+ defer: void 0,
3843
+ script: void 0,
3844
+ htmlAt: void 0,
3845
+ scriptAt: void 0
3690
3846
  });
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
- }
3847
+ 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.`);
3848
+ return asset;
3695
3849
  }
3696
- function writeTriggerScript(id, html, triggers) {
3850
+ function triggerScript(id, html, triggers) {
3697
3851
  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))`;
3852
+ 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
3853
  const exprs = triggers.map((trigger) => {
3700
3854
  const options = trigger.options && toObjectExpression(trigger.options);
3701
3855
  switch (trigger.type) {
@@ -3705,7 +3859,7 @@ function writeTriggerScript(id, html, triggers) {
3705
3859
  default: return `(e=>e?.addEventListener("${trigger.type.slice(3)}",l,{once:1}))(${querySelectorOrLoad(trigger.selector)})`;
3706
3860
  }
3707
3861
  });
3708
- writeScript(`((p,h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3862
+ return `((h,d,l=$=>{d||${insert}})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(${htmlStr})`;
3709
3863
  }
3710
3864
  function querySelectorOrLoad(selector) {
3711
3865
  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 +3883,7 @@ const K_TAGS_API_STATE = Symbol();
3729
3883
  const COMPAT_REGISTRY = /* @__PURE__ */ new WeakMap();
3730
3884
  const compat = {
3731
3885
  $global,
3886
+ writeLoadAsset,
3732
3887
  fork: _await,
3733
3888
  write: _html,
3734
3889
  writeScript,
@@ -3752,7 +3907,10 @@ const compat = {
3752
3907
  onFlush(fn) {
3753
3908
  const { flushHTML } = Chunk.prototype;
3754
3909
  Chunk.prototype.flushHTML = function(boundary) {
3910
+ const { state } = boundary;
3911
+ const reorders = swapReorders(state, null);
3755
3912
  fn(this);
3913
+ swapReorders(state, reorders);
3756
3914
  return flushHTML.call(this, boundary);
3757
3915
  };
3758
3916
  },
@@ -3778,21 +3936,52 @@ const compat = {
3778
3936
  return compatRegistered;
3779
3937
  };
3780
3938
  },
3939
+ joinChunks(chunks) {
3940
+ let joined;
3941
+ for (const chunk of chunks) {
3942
+ if (chunk.boundary.aborted) continue;
3943
+ if (joined) joined.append(chunk);
3944
+ else joined = chunk;
3945
+ }
3946
+ return joined;
3947
+ },
3948
+ appendChunks(chunks) {
3949
+ const chunk = getChunk();
3950
+ for (const part of chunks) {
3951
+ chunk.append(part);
3952
+ if (part.effects) chunk.lastEffect = part.lastEffect;
3953
+ }
3954
+ },
3955
+ deferReorders(reorders) {
3956
+ const chunk = getChunk();
3957
+ for (let i = reorders.length; i--;) {
3958
+ const carrier = chunk.fork(chunk.boundary, chunk.next);
3959
+ carrier.deferredReorder = reorders[i];
3960
+ chunk.next = carrier;
3961
+ }
3962
+ },
3781
3963
  createChunk($global) {
3782
3964
  const state = this.ensureState($global);
3783
3965
  return new Chunk(new Boundary(state), null, null, state);
3784
3966
  },
3785
- flushScript($global, chunk) {
3786
- chunk ||= this.createChunk($global);
3967
+ flushScript(chunk, reorders) {
3787
3968
  const { boundary } = chunk;
3788
- const scripts = boundary.flush() === 0 ? chunk.flushScript(boundary).scripts : "";
3969
+ const { state } = boundary;
3970
+ let html = "";
3971
+ let scripts = "";
3972
+ if (reorders) for (const reorder of reorders) state.reorder(reorder);
3973
+ if (boundary.flush() === 0) ({html, scripts} = chunk.flushScript(boundary));
3789
3974
  if (boundary.aborted) throw boundary.reason;
3790
3975
  if (boundary.count) throw new Error("Cannot serialize promise across tags/class compat layer.");
3791
- return scripts;
3976
+ return {
3977
+ html,
3978
+ scripts
3979
+ };
3792
3980
  },
3793
- render(renderer, willRerender, classAPIOut, component, input, completeChunks, registerChildScope) {
3981
+ render(renderer, willRerender, classAPIOut, component, input, componentScopes, registerChildScope, parentChunk) {
3982
+ if (parentChunk?.boundary.aborted) return;
3794
3983
  const state = this.ensureState(classAPIOut.global);
3795
- const boundary = new Boundary(state);
3984
+ const boundary = new Boundary(state, void 0, parentChunk?.boundary);
3796
3985
  const context = getChunk()?.context ?? null;
3797
3986
  let head = new Chunk(boundary, new Chunk(boundary, null, context, state), context, state);
3798
3987
  let normalizedInput = input;
@@ -3800,7 +3989,8 @@ const compat = {
3800
3989
  normalizedInput = {};
3801
3990
  for (const key in input) normalizedInput[key === "renderBody" ? "content" : key] = input[key];
3802
3991
  }
3803
- head.render(() => {
3992
+ const componentScope = new Chunk(boundary, null, context, state);
3993
+ componentScope.render(() => {
3804
3994
  if (this.hasPendingClassFunctions(classAPIOut.global)) drainClassFunctions(classAPIOut.global, (hostId) => {
3805
3995
  const fnScopeId = _scope_id();
3806
3996
  const scope = writeScope(fnScopeId, {
@@ -3815,6 +4005,8 @@ const compat = {
3815
4005
  writeScope(scopeId, { m5c: component.id });
3816
4006
  _script(scopeId, SET_SCOPE_REGISTER_ID);
3817
4007
  }
4008
+ });
4009
+ head.render(() => {
3818
4010
  _set_scope_reason(willRerender ? CLIENT_ALL : 0);
3819
4011
  try {
3820
4012
  renderer(normalizedInput);
@@ -3828,16 +4020,28 @@ const compat = {
3828
4020
  classAPIOut.onLast((next) => {
3829
4021
  (boundary.onNext = () => {
3830
4022
  if (boundary.aborted) {
3831
- asyncOut.error(boundary.reason);
3832
4023
  boundary.onNext = NOOP;
4024
+ if (parentChunk?.boundary.aborted) {
4025
+ asyncOut.end();
4026
+ next();
4027
+ } else asyncOut.error(boundary.reason);
3833
4028
  } else if (!boundary.count) {
3834
4029
  boundary.onNext = NOOP;
4030
+ const queued = swapReorders(state, null);
3835
4031
  head = head.consume(boundary);
4032
+ const reorders = swapReorders(state, queued);
4033
+ if (reorders) asyncOut.writer.get("reorders").push(...reorders);
4034
+ const heldEffects = head.takeHeldEffects();
4035
+ if (heldEffects) {
4036
+ head.effects = joinHeldEffects(heldEffects, head.effects);
4037
+ head.lastEffect = "";
4038
+ }
3836
4039
  asyncOut.write(head.html);
3837
4040
  asyncOut.script(head.scripts);
3838
- asyncOut.end();
3839
4041
  head.html = head.scripts = "";
3840
- completeChunks.push(head);
4042
+ asyncOut.writer.get("chunks").push(head);
4043
+ asyncOut.end();
4044
+ componentScopes.push(componentScope);
3841
4045
  next();
3842
4046
  }
3843
4047
  })();
@@ -3875,9 +4079,15 @@ function drainClassFunctions($global, writeScope) {
3875
4079
  for (const [id, fn, hostId] of pending) register(id, fn, scopeByHost[hostId] ||= writeScope(hostId));
3876
4080
  pending.length = 0;
3877
4081
  }
4082
+ function swapReorders(state, reorders) {
4083
+ const { writeReorders } = state;
4084
+ state.writeReorders = reorders;
4085
+ return writeReorders;
4086
+ }
3878
4087
  function NOOP() {}
3879
4088
  //#endregion
3880
4089
  exports.$global = $global;
4090
+ exports._assert_class_toggles = _assert_class_toggles;
3881
4091
  exports._assert_hoist = _assert_hoist;
3882
4092
  exports._attr = _attr;
3883
4093
  exports._attr_and = _attr_and;