@solidjs/web 2.0.0-beta.5 → 2.0.0-beta.7

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.
package/dist/server.cjs CHANGED
@@ -12,7 +12,10 @@ const SVGElements = /*#__PURE__*/new Set([
12
12
  "set", "stop",
13
13
  "svg", "switch", "symbol", "text", "textPath",
14
14
  "tref", "tspan", "use", "view", "vkern"]);
15
- const SVGNamespace = {
15
+ const MathMLElements = /*#__PURE__*/new Set(["annotation", "annotation-xml", "maction", "math", "menclose", "merror", "mfenced", "mfrac", "mi", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mprescripts", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msubsup", "msup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "semantics"]);
16
+ const Namespaces = {
17
+ svg: "http://www.w3.org/2000/svg",
18
+ mathml: "http://www.w3.org/1998/Math/MathML",
16
19
  xlink: "http://www.w3.org/1999/xlink",
17
20
  xml: "http://www.w3.org/XML/1998/namespace"
18
21
  };
@@ -20,10 +23,10 @@ const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta"
20
23
  "webview",
21
24
  "isindex", "listing", "multicol", "nextid", "noindex", "search"]);
22
25
 
23
- const effect = (fn, effectFn, initial) => solidJs.createRenderEffect(fn, effectFn, initial, {
26
+ const effect = (fn, effectFn) => solidJs.createRenderEffect(fn, effectFn, {
24
27
  transparent: true
25
28
  });
26
- const memo = (fn, transparent) => transparent ? fn.$r ? fn : signals.createMemo(() => fn(), undefined, {
29
+ const memo = (fn, transparent) => transparent ? fn.$r ? fn : signals.createMemo(() => fn(), {
27
30
  transparent: true
28
31
  }) : solidJs.createMemo(() => fn());
29
32
 
@@ -108,11 +111,11 @@ function createAssetTracking() {
108
111
  currentBoundaryId = v;
109
112
  },
110
113
  registerModule(moduleUrl, entryUrl) {
111
- if (!currentBoundaryId) return;
112
- let map = boundaryModules.get(currentBoundaryId);
114
+ const id = currentBoundaryId || "";
115
+ let map = boundaryModules.get(id);
113
116
  if (!map) {
114
117
  map = {};
115
- boundaryModules.set(currentBoundaryId, map);
118
+ boundaryModules.set(id, map);
116
119
  }
117
120
  map[moduleUrl] = entryUrl;
118
121
  },
@@ -140,7 +143,7 @@ function applyAssetTracking(context, tracking, manifest) {
140
143
  if (manifest) context.resolveAssets = moduleUrl => resolveAssets(moduleUrl, manifest);
141
144
  }
142
145
  const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
143
- const REPLACE_SCRIPT = `function $df(e,n,o,t){if(n=document.getElementById(e),o=document.getElementById("pl-"+e)){for(;o&&8!==o.nodeType&&o.nodeValue!=="pl-"+e;)t=o.nextSibling,o.remove(),o=t;_$HY.done?o.remove():o.replaceWith(n.content)}n.remove(),_$HY.fe(e)}function $dfs(e,c){(_$HY.sc=_$HY.sc||{})[e]=c}function $dfc(e){if(--_$HY.sc[e]<=0)delete _$HY.sc[e],$df(e)}`;
146
+ const REPLACE_SCRIPT = `function $df(e,n,o,t){if(!(n=document.getElementById(e))||!(o=document.getElementById("pl-"+e)))return 0;for(;o&&8!==o.nodeType&&o.nodeValue!=="pl-"+e;)t=o.nextSibling,o.remove(),o=t;_$HY.done?o.remove():o.replaceWith(n.content),n.remove(),_$HY.fe(e);return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return 0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1;return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)if($dfl(e[i]))return e[i];return null}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
144
147
  function renderToString(code, options = {}) {
145
148
  const {
146
149
  renderId = "",
@@ -195,6 +198,7 @@ function renderToString(code, options = {}) {
195
198
  }, {
196
199
  id: renderId
197
200
  });
201
+ serializeFragmentAssets("", tracking.boundaryModules, solidJs.sharedConfig.context);
198
202
  solidJs.sharedConfig.context.noHydrate = true;
199
203
  serializer.close();
200
204
  html = injectAssets(solidJs.sharedConfig.context.assets, html);
@@ -213,10 +217,12 @@ function renderToStream(code, options = {}) {
213
217
  } = options;
214
218
  let dispose;
215
219
  const blockingPromises = new Set();
220
+ let headerEmitted = false;
216
221
  const pushTask = task => {
217
222
  if (noScripts) return;
218
- if (!tasks && !firstFlushed) {
219
- tasks = getLocalHeaderScript(renderId);
223
+ if (!headerEmitted) {
224
+ headerEmitted = true;
225
+ tasks += getLocalHeaderScript(renderId);
220
226
  }
221
227
  tasks += task + ";";
222
228
  if (!timer && firstFlushed) {
@@ -265,7 +271,29 @@ function renderToStream(code, options = {}) {
265
271
  let shellCompleted = false;
266
272
  let scriptFlushed = false;
267
273
  let headStyles;
274
+ const revealGroups = new Map();
268
275
  let timer = null;
276
+ const emitTask = task => {
277
+ pushTask(`${task}${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
278
+ scriptFlushed = true;
279
+ };
280
+ function resolveRevealKeys(groupOrKeys, release, consume) {
281
+ if (Array.isArray(groupOrKeys)) return groupOrKeys.slice();
282
+ let group = revealGroups.get(groupOrKeys);
283
+ if (!group) {
284
+ if (!release) return;
285
+ group = {
286
+ order: [],
287
+ keys: new Set(),
288
+ released: true
289
+ };
290
+ revealGroups.set(groupOrKeys, group);
291
+ } else if (release) group.released = true;
292
+ if (!group.order.length) return;
293
+ const keys = group.order.slice();
294
+ if (consume) revealGroups.delete(groupOrKeys);
295
+ return keys;
296
+ }
269
297
  let rootHoles = null;
270
298
  let nextHoleId = 0;
271
299
  let buffer = {
@@ -315,7 +343,26 @@ function renderToStream(code, options = {}) {
315
343
  escape: escape,
316
344
  resolve: resolveSSRNode,
317
345
  ssr: ssr,
318
- registerFragment(key) {
346
+ registerFragment(key, options) {
347
+ const revealGroup = options && options.revealGroup;
348
+ if (revealGroup) {
349
+ let group = revealGroups.get(revealGroup);
350
+ if (!group) {
351
+ group = {
352
+ order: [],
353
+ keys: new Set(),
354
+ released: false
355
+ };
356
+ revealGroups.set(revealGroup, group);
357
+ }
358
+ if (!group.keys.has(key)) {
359
+ group.keys.add(key);
360
+ group.order.push(key);
361
+ }
362
+ if (group.released) {
363
+ throw new Error("registerFragment() for reveal group '" + revealGroup + "' was called after revealFragments(). Ensure template payload is emitted before grouped reveal.");
364
+ }
365
+ }
319
366
  if (!registry.has(key)) {
320
367
  let resolve, reject;
321
368
  const p = new Promise((r, rej) => (resolve = r, reject = rej));
@@ -325,7 +372,7 @@ function renderToStream(code, options = {}) {
325
372
  queue(flushEnd);
326
373
  }))
327
374
  });
328
- serializer.write(key, p);
375
+ serializer.write(key + "_fr", p);
329
376
  }
330
377
  return (value, error) => {
331
378
  if (registry.has(key)) {
@@ -354,9 +401,9 @@ function renderToStream(code, options = {}) {
354
401
  } else {
355
402
  serializeFragmentAssets(key, tracking.boundaryModules, context);
356
403
  const styles = collectStreamStyles(key, tracking, headStyles);
404
+ const deferActivation = !!revealGroup;
357
405
  if (styles.length) {
358
- pushTask(`$dfs("${key}",${styles.length})${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
359
- scriptFlushed = true;
406
+ emitTask(`$dfs("${key}",${styles.length},${deferActivation ? 1 : 0})`);
360
407
  writeTasks();
361
408
  for (const url of styles) {
362
409
  buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
@@ -364,8 +411,9 @@ function renderToStream(code, options = {}) {
364
411
  buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
365
412
  } else {
366
413
  buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
367
- pushTask(`$df("${key}")${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
368
- scriptFlushed = true;
414
+ if (!deferActivation) {
415
+ emitTask(`$df("${key}")`);
416
+ }
369
417
  }
370
418
  item.resolve(error);
371
419
  }
@@ -373,6 +421,16 @@ function renderToStream(code, options = {}) {
373
421
  }
374
422
  return firstFlushed;
375
423
  };
424
+ },
425
+ revealFragments(groupOrKeys) {
426
+ const keys = resolveRevealKeys(groupOrKeys, true, true);
427
+ if (!keys) return;
428
+ emitTask(`$dfj(${JSON.stringify(keys)})`);
429
+ },
430
+ revealFallbacks(groupOrKeys) {
431
+ const keys = resolveRevealKeys(groupOrKeys, false, false);
432
+ if (!keys) return;
433
+ emitTask(`$dflj(${JSON.stringify(keys)})`);
376
434
  }
377
435
  };
378
436
  applyAssetTracking(context, tracking, manifest);
@@ -399,13 +457,32 @@ function renderToStream(code, options = {}) {
399
457
  function doShell() {
400
458
  if (shellCompleted) return;
401
459
  if (rootHoles) {
460
+ const pending = [];
402
461
  for (const {
403
462
  id,
404
463
  fn
405
464
  } of rootHoles) {
406
465
  const marker = `<!--rh${id}-->`;
407
466
  const res = resolveSSRNode(fn);
408
- html = html.replace(marker, !res.h.length ? res.t[0] : "");
467
+ if (!res.h.length) {
468
+ html = html.replace(marker, res.t[0]);
469
+ } else {
470
+ let out = res.t[0];
471
+ for (let j = 0; j < res.h.length; j++) {
472
+ const newId = nextHoleId++;
473
+ pending.push({
474
+ id: newId,
475
+ fn: res.h[j]
476
+ });
477
+ out += `<!--rh${newId}-->` + res.t[j + 1];
478
+ }
479
+ html = html.replace(marker, out);
480
+ for (const p of res.p) blockingPromises.add(p);
481
+ }
482
+ }
483
+ if (pending.length) {
484
+ rootHoles = pending;
485
+ return;
409
486
  }
410
487
  rootHoles = null;
411
488
  }
@@ -416,6 +493,7 @@ function renderToStream(code, options = {}) {
416
493
  if (url.endsWith(".css")) headStyles.add(url);
417
494
  }
418
495
  html = injectPreloadLinks(tracking.emittedAssets, html);
496
+ serializeFragmentAssets("", tracking.boundaryModules, context);
419
497
  if (tasks.length) html = injectScripts(html, tasks, nonce);
420
498
  buffer.write(html);
421
499
  tasks = "";
@@ -442,48 +520,56 @@ function renderToStream(code, options = {}) {
442
520
  queue(flushEnd);
443
521
  },
444
522
  pipe(w) {
445
- allSettled(blockingPromises).then(() => {
446
- setTimeout(() => {
447
- doShell();
448
- buffer = writable = w;
449
- buffer.write(tmp);
450
- firstFlushed = true;
451
- if (completed) {
452
- dispose();
453
- writable.end();
454
- } else flushEnd();
523
+ function flush() {
524
+ allSettled(blockingPromises).then(() => {
525
+ setTimeout(() => {
526
+ doShell();
527
+ if (!shellCompleted) return flush();
528
+ buffer = writable = w;
529
+ buffer.write(tmp);
530
+ firstFlushed = true;
531
+ if (completed) {
532
+ dispose();
533
+ writable.end();
534
+ } else flushEnd();
535
+ });
455
536
  });
456
- });
537
+ }
538
+ flush();
457
539
  },
458
540
  pipeTo(w) {
459
- return allSettled(blockingPromises).then(() => {
460
- let resolve;
461
- const p = new Promise(r => resolve = r);
462
- setTimeout(() => {
463
- doShell();
464
- const encoder = new TextEncoder();
465
- const writer = w.getWriter();
466
- writable = {
467
- end() {
468
- writer.releaseLock();
469
- w.close().catch(() => {});
470
- resolve();
471
- }
472
- };
473
- buffer = {
474
- write(payload) {
475
- writer.write(encoder.encode(payload)).catch(() => {});
476
- }
477
- };
478
- buffer.write(tmp);
479
- firstFlushed = true;
480
- if (completed) {
481
- dispose();
482
- writable.end();
483
- } else flushEnd();
541
+ let resolve;
542
+ const p = new Promise(r => resolve = r);
543
+ function flush() {
544
+ allSettled(blockingPromises).then(() => {
545
+ setTimeout(() => {
546
+ doShell();
547
+ if (!shellCompleted) return flush();
548
+ const encoder = new TextEncoder();
549
+ const writer = w.getWriter();
550
+ writable = {
551
+ end() {
552
+ writer.releaseLock();
553
+ w.close().catch(() => {});
554
+ resolve();
555
+ }
556
+ };
557
+ buffer = {
558
+ write(payload) {
559
+ writer.write(encoder.encode(payload)).catch(() => {});
560
+ }
561
+ };
562
+ buffer.write(tmp);
563
+ firstFlushed = true;
564
+ if (completed) {
565
+ dispose();
566
+ writable.end();
567
+ } else flushEnd();
568
+ });
484
569
  });
485
- return p;
486
- });
570
+ }
571
+ flush();
572
+ return p;
487
573
  }
488
574
  };
489
575
  }
@@ -883,6 +969,10 @@ Object.defineProperty(exports, "Repeat", {
883
969
  enumerable: true,
884
970
  get: function () { return solidJs.Repeat; }
885
971
  });
972
+ Object.defineProperty(exports, "Reveal", {
973
+ enumerable: true,
974
+ get: function () { return solidJs.Reveal; }
975
+ });
886
976
  Object.defineProperty(exports, "Show", {
887
977
  enumerable: true,
888
978
  get: function () { return solidJs.Show; }
@@ -912,10 +1002,11 @@ exports.DOMElements = DOMElements;
912
1002
  exports.DelegatedEvents = DelegatedEvents;
913
1003
  exports.Dynamic = Dynamic;
914
1004
  exports.HydrationScript = HydrationScript;
1005
+ exports.MathMLElements = MathMLElements;
1006
+ exports.Namespaces = Namespaces;
915
1007
  exports.Portal = Portal;
916
1008
  exports.RequestContext = RequestContext;
917
1009
  exports.SVGElements = SVGElements;
918
- exports.SVGNamespace = SVGNamespace;
919
1010
  exports.addEventListener = notSup;
920
1011
  exports.applyRef = applyRef;
921
1012
  exports.assign = notSup;
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRenderEffect, createMemo as createMemo$1, sharedConfig, createRoot, ssrHandleError, omit, getOwner, getNextChildId, createOwner, runWithOwner } from 'solid-js';
2
- export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Show, Switch, createComponent, getOwner, ssrRunInScope, untrack } from 'solid-js';
2
+ export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, ssrRunInScope, untrack } from 'solid-js';
3
3
  import { Serializer, Feature, getCrossReferenceHeader } from 'seroval';
4
4
  import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
5
5
  import { createMemo } from '@solidjs/signals';
@@ -11,7 +11,10 @@ const SVGElements = /*#__PURE__*/new Set([
11
11
  "set", "stop",
12
12
  "svg", "switch", "symbol", "text", "textPath",
13
13
  "tref", "tspan", "use", "view", "vkern"]);
14
- const SVGNamespace = {
14
+ const MathMLElements = /*#__PURE__*/new Set(["annotation", "annotation-xml", "maction", "math", "menclose", "merror", "mfenced", "mfrac", "mi", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mprescripts", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msubsup", "msup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "semantics"]);
15
+ const Namespaces = {
16
+ svg: "http://www.w3.org/2000/svg",
17
+ mathml: "http://www.w3.org/1998/Math/MathML",
15
18
  xlink: "http://www.w3.org/1999/xlink",
16
19
  xml: "http://www.w3.org/XML/1998/namespace"
17
20
  };
@@ -19,10 +22,10 @@ const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta"
19
22
  "webview",
20
23
  "isindex", "listing", "multicol", "nextid", "noindex", "search"]);
21
24
 
22
- const effect = (fn, effectFn, initial) => createRenderEffect(fn, effectFn, initial, {
25
+ const effect = (fn, effectFn) => createRenderEffect(fn, effectFn, {
23
26
  transparent: true
24
27
  });
25
- const memo = (fn, transparent) => transparent ? fn.$r ? fn : createMemo(() => fn(), undefined, {
28
+ const memo = (fn, transparent) => transparent ? fn.$r ? fn : createMemo(() => fn(), {
26
29
  transparent: true
27
30
  }) : createMemo$1(() => fn());
28
31
 
@@ -107,11 +110,11 @@ function createAssetTracking() {
107
110
  currentBoundaryId = v;
108
111
  },
109
112
  registerModule(moduleUrl, entryUrl) {
110
- if (!currentBoundaryId) return;
111
- let map = boundaryModules.get(currentBoundaryId);
113
+ const id = currentBoundaryId || "";
114
+ let map = boundaryModules.get(id);
112
115
  if (!map) {
113
116
  map = {};
114
- boundaryModules.set(currentBoundaryId, map);
117
+ boundaryModules.set(id, map);
115
118
  }
116
119
  map[moduleUrl] = entryUrl;
117
120
  },
@@ -139,7 +142,7 @@ function applyAssetTracking(context, tracking, manifest) {
139
142
  if (manifest) context.resolveAssets = moduleUrl => resolveAssets(moduleUrl, manifest);
140
143
  }
141
144
  const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
142
- const REPLACE_SCRIPT = `function $df(e,n,o,t){if(n=document.getElementById(e),o=document.getElementById("pl-"+e)){for(;o&&8!==o.nodeType&&o.nodeValue!=="pl-"+e;)t=o.nextSibling,o.remove(),o=t;_$HY.done?o.remove():o.replaceWith(n.content)}n.remove(),_$HY.fe(e)}function $dfs(e,c){(_$HY.sc=_$HY.sc||{})[e]=c}function $dfc(e){if(--_$HY.sc[e]<=0)delete _$HY.sc[e],$df(e)}`;
145
+ const REPLACE_SCRIPT = `function $df(e,n,o,t){if(!(n=document.getElementById(e))||!(o=document.getElementById("pl-"+e)))return 0;for(;o&&8!==o.nodeType&&o.nodeValue!=="pl-"+e;)t=o.nextSibling,o.remove(),o=t;_$HY.done?o.remove():o.replaceWith(n.content),n.remove(),_$HY.fe(e);return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return 0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1;return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)if($dfl(e[i]))return e[i];return null}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
143
146
  function renderToString(code, options = {}) {
144
147
  const {
145
148
  renderId = "",
@@ -194,6 +197,7 @@ function renderToString(code, options = {}) {
194
197
  }, {
195
198
  id: renderId
196
199
  });
200
+ serializeFragmentAssets("", tracking.boundaryModules, sharedConfig.context);
197
201
  sharedConfig.context.noHydrate = true;
198
202
  serializer.close();
199
203
  html = injectAssets(sharedConfig.context.assets, html);
@@ -212,10 +216,12 @@ function renderToStream(code, options = {}) {
212
216
  } = options;
213
217
  let dispose;
214
218
  const blockingPromises = new Set();
219
+ let headerEmitted = false;
215
220
  const pushTask = task => {
216
221
  if (noScripts) return;
217
- if (!tasks && !firstFlushed) {
218
- tasks = getLocalHeaderScript(renderId);
222
+ if (!headerEmitted) {
223
+ headerEmitted = true;
224
+ tasks += getLocalHeaderScript(renderId);
219
225
  }
220
226
  tasks += task + ";";
221
227
  if (!timer && firstFlushed) {
@@ -264,7 +270,29 @@ function renderToStream(code, options = {}) {
264
270
  let shellCompleted = false;
265
271
  let scriptFlushed = false;
266
272
  let headStyles;
273
+ const revealGroups = new Map();
267
274
  let timer = null;
275
+ const emitTask = task => {
276
+ pushTask(`${task}${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
277
+ scriptFlushed = true;
278
+ };
279
+ function resolveRevealKeys(groupOrKeys, release, consume) {
280
+ if (Array.isArray(groupOrKeys)) return groupOrKeys.slice();
281
+ let group = revealGroups.get(groupOrKeys);
282
+ if (!group) {
283
+ if (!release) return;
284
+ group = {
285
+ order: [],
286
+ keys: new Set(),
287
+ released: true
288
+ };
289
+ revealGroups.set(groupOrKeys, group);
290
+ } else if (release) group.released = true;
291
+ if (!group.order.length) return;
292
+ const keys = group.order.slice();
293
+ if (consume) revealGroups.delete(groupOrKeys);
294
+ return keys;
295
+ }
268
296
  let rootHoles = null;
269
297
  let nextHoleId = 0;
270
298
  let buffer = {
@@ -314,7 +342,26 @@ function renderToStream(code, options = {}) {
314
342
  escape: escape,
315
343
  resolve: resolveSSRNode,
316
344
  ssr: ssr,
317
- registerFragment(key) {
345
+ registerFragment(key, options) {
346
+ const revealGroup = options && options.revealGroup;
347
+ if (revealGroup) {
348
+ let group = revealGroups.get(revealGroup);
349
+ if (!group) {
350
+ group = {
351
+ order: [],
352
+ keys: new Set(),
353
+ released: false
354
+ };
355
+ revealGroups.set(revealGroup, group);
356
+ }
357
+ if (!group.keys.has(key)) {
358
+ group.keys.add(key);
359
+ group.order.push(key);
360
+ }
361
+ if (group.released) {
362
+ throw new Error("registerFragment() for reveal group '" + revealGroup + "' was called after revealFragments(). Ensure template payload is emitted before grouped reveal.");
363
+ }
364
+ }
318
365
  if (!registry.has(key)) {
319
366
  let resolve, reject;
320
367
  const p = new Promise((r, rej) => (resolve = r, reject = rej));
@@ -324,7 +371,7 @@ function renderToStream(code, options = {}) {
324
371
  queue(flushEnd);
325
372
  }))
326
373
  });
327
- serializer.write(key, p);
374
+ serializer.write(key + "_fr", p);
328
375
  }
329
376
  return (value, error) => {
330
377
  if (registry.has(key)) {
@@ -353,9 +400,9 @@ function renderToStream(code, options = {}) {
353
400
  } else {
354
401
  serializeFragmentAssets(key, tracking.boundaryModules, context);
355
402
  const styles = collectStreamStyles(key, tracking, headStyles);
403
+ const deferActivation = !!revealGroup;
356
404
  if (styles.length) {
357
- pushTask(`$dfs("${key}",${styles.length})${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
358
- scriptFlushed = true;
405
+ emitTask(`$dfs("${key}",${styles.length},${deferActivation ? 1 : 0})`);
359
406
  writeTasks();
360
407
  for (const url of styles) {
361
408
  buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
@@ -363,8 +410,9 @@ function renderToStream(code, options = {}) {
363
410
  buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
364
411
  } else {
365
412
  buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
366
- pushTask(`$df("${key}")${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
367
- scriptFlushed = true;
413
+ if (!deferActivation) {
414
+ emitTask(`$df("${key}")`);
415
+ }
368
416
  }
369
417
  item.resolve(error);
370
418
  }
@@ -372,6 +420,16 @@ function renderToStream(code, options = {}) {
372
420
  }
373
421
  return firstFlushed;
374
422
  };
423
+ },
424
+ revealFragments(groupOrKeys) {
425
+ const keys = resolveRevealKeys(groupOrKeys, true, true);
426
+ if (!keys) return;
427
+ emitTask(`$dfj(${JSON.stringify(keys)})`);
428
+ },
429
+ revealFallbacks(groupOrKeys) {
430
+ const keys = resolveRevealKeys(groupOrKeys, false, false);
431
+ if (!keys) return;
432
+ emitTask(`$dflj(${JSON.stringify(keys)})`);
375
433
  }
376
434
  };
377
435
  applyAssetTracking(context, tracking, manifest);
@@ -398,13 +456,32 @@ function renderToStream(code, options = {}) {
398
456
  function doShell() {
399
457
  if (shellCompleted) return;
400
458
  if (rootHoles) {
459
+ const pending = [];
401
460
  for (const {
402
461
  id,
403
462
  fn
404
463
  } of rootHoles) {
405
464
  const marker = `<!--rh${id}-->`;
406
465
  const res = resolveSSRNode(fn);
407
- html = html.replace(marker, !res.h.length ? res.t[0] : "");
466
+ if (!res.h.length) {
467
+ html = html.replace(marker, res.t[0]);
468
+ } else {
469
+ let out = res.t[0];
470
+ for (let j = 0; j < res.h.length; j++) {
471
+ const newId = nextHoleId++;
472
+ pending.push({
473
+ id: newId,
474
+ fn: res.h[j]
475
+ });
476
+ out += `<!--rh${newId}-->` + res.t[j + 1];
477
+ }
478
+ html = html.replace(marker, out);
479
+ for (const p of res.p) blockingPromises.add(p);
480
+ }
481
+ }
482
+ if (pending.length) {
483
+ rootHoles = pending;
484
+ return;
408
485
  }
409
486
  rootHoles = null;
410
487
  }
@@ -415,6 +492,7 @@ function renderToStream(code, options = {}) {
415
492
  if (url.endsWith(".css")) headStyles.add(url);
416
493
  }
417
494
  html = injectPreloadLinks(tracking.emittedAssets, html);
495
+ serializeFragmentAssets("", tracking.boundaryModules, context);
418
496
  if (tasks.length) html = injectScripts(html, tasks, nonce);
419
497
  buffer.write(html);
420
498
  tasks = "";
@@ -441,48 +519,56 @@ function renderToStream(code, options = {}) {
441
519
  queue(flushEnd);
442
520
  },
443
521
  pipe(w) {
444
- allSettled(blockingPromises).then(() => {
445
- setTimeout(() => {
446
- doShell();
447
- buffer = writable = w;
448
- buffer.write(tmp);
449
- firstFlushed = true;
450
- if (completed) {
451
- dispose();
452
- writable.end();
453
- } else flushEnd();
522
+ function flush() {
523
+ allSettled(blockingPromises).then(() => {
524
+ setTimeout(() => {
525
+ doShell();
526
+ if (!shellCompleted) return flush();
527
+ buffer = writable = w;
528
+ buffer.write(tmp);
529
+ firstFlushed = true;
530
+ if (completed) {
531
+ dispose();
532
+ writable.end();
533
+ } else flushEnd();
534
+ });
454
535
  });
455
- });
536
+ }
537
+ flush();
456
538
  },
457
539
  pipeTo(w) {
458
- return allSettled(blockingPromises).then(() => {
459
- let resolve;
460
- const p = new Promise(r => resolve = r);
461
- setTimeout(() => {
462
- doShell();
463
- const encoder = new TextEncoder();
464
- const writer = w.getWriter();
465
- writable = {
466
- end() {
467
- writer.releaseLock();
468
- w.close().catch(() => {});
469
- resolve();
470
- }
471
- };
472
- buffer = {
473
- write(payload) {
474
- writer.write(encoder.encode(payload)).catch(() => {});
475
- }
476
- };
477
- buffer.write(tmp);
478
- firstFlushed = true;
479
- if (completed) {
480
- dispose();
481
- writable.end();
482
- } else flushEnd();
540
+ let resolve;
541
+ const p = new Promise(r => resolve = r);
542
+ function flush() {
543
+ allSettled(blockingPromises).then(() => {
544
+ setTimeout(() => {
545
+ doShell();
546
+ if (!shellCompleted) return flush();
547
+ const encoder = new TextEncoder();
548
+ const writer = w.getWriter();
549
+ writable = {
550
+ end() {
551
+ writer.releaseLock();
552
+ w.close().catch(() => {});
553
+ resolve();
554
+ }
555
+ };
556
+ buffer = {
557
+ write(payload) {
558
+ writer.write(encoder.encode(payload)).catch(() => {});
559
+ }
560
+ };
561
+ buffer.write(tmp);
562
+ firstFlushed = true;
563
+ if (completed) {
564
+ dispose();
565
+ writable.end();
566
+ } else flushEnd();
567
+ });
483
568
  });
484
- return p;
485
- });
569
+ }
570
+ flush();
571
+ return p;
486
572
  }
487
573
  };
488
574
  }
@@ -854,4 +940,4 @@ function Portal(props) {
854
940
  throw new Error("Portal is not supported on the server");
855
941
  }
856
942
 
857
- export { ChildProperties, DOMElements, DelegatedEvents, Dynamic, HydrationScript, Portal, RequestContext, SVGElements, SVGNamespace, notSup as addEventListener, applyRef, notSup as assign, notSup as className, createDynamic, notSup as delegateEvents, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, notSup as hydrate, notSup as insert, isDev, isServer, memo, mergeProps, notSup as render, renderToStream, renderToString, renderToStringAsync, notSup as runHydrationEvents, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, useAssets };
943
+ export { ChildProperties, DOMElements, DelegatedEvents, Dynamic, HydrationScript, MathMLElements, Namespaces, Portal, RequestContext, SVGElements, notSup as addEventListener, applyRef, notSup as assign, notSup as className, createDynamic, notSup as delegateEvents, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, notSup as hydrate, notSup as insert, isDev, isServer, memo, mergeProps, notSup as render, renderToStream, renderToString, renderToStringAsync, notSup as runHydrationEvents, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, useAssets };