@dom-expressions/runtime 0.50.0-next.19 → 0.50.0-next.20

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # dom-expressions
2
2
 
3
+ ## 0.50.0-next.20
4
+
5
+ ### Patch Changes
6
+
7
+ - 9d5a90b: Queue streamed fragment activations whose `pl-*` marker is not yet in the live DOM instead of silently dropping them.
8
+
9
+ A fragment's marker can sit inside a flushed-but-unactivated ancestor `<template>` (a slot held by a reveal group). Template content is inert, so `document.getElementById` cannot see the marker and `$df`/`$dfl` previously returned `0` and lost the swap permanently — the fallback stayed stuck even though the content template had streamed. Today this window is masked because the server enrolls nested boundaries into the ancestor reveal group, but fixing that enrollment (solidjs/solid#2871, solidjs/solid#2872) makes nested boundaries activate independently, exposing the drop.
10
+
11
+ `$df` and `$dfl` now queue marker misses (`_$HY.dq` / `_$HY.dlq`) and a new `$dfd` drains both queues after every successful swap or fallback materialization — the only events that can bring queued markers into the live document. Content swaps drain before fallbacks so a settled fragment wins over its own pending fallback, and drains cascade through arbitrarily nested held levels. An activation whose content template is already consumed remains a plain no-op and is never queued.
12
+
3
13
  ## 0.50.0-next.19
4
14
 
5
15
  ### Patch Changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dom-expressions/runtime",
3
3
  "description": "A Fine-Grained Runtime for Performant DOM Rendering",
4
- "version": "0.50.0-next.19",
4
+ "version": "0.50.0-next.20",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -26,7 +26,7 @@
26
26
  "csstype": "^3.1",
27
27
  "seroval": "~1.5.0",
28
28
  "seroval-plugins": "~1.5.0",
29
- "@dom-expressions/babel-plugin-jsx": "0.50.0-next.19"
29
+ "@dom-expressions/babel-plugin-jsx": "0.50.0-next.20"
30
30
  },
31
31
  "scripts": {
32
32
  "test": "jest --no-cache",
package/src/server.js CHANGED
@@ -178,14 +178,24 @@ function applyAssetTracking(context, tracking, manifest) {
178
178
  const VOID_ELEMENTS =
179
179
  /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
180
180
  // Fragment replacement helpers emitted into stream task scripts:
181
- // - $df(id): swap template payload into the `pl-*` marker range.
181
+ // - $df(id): swap template payload into the `pl-*` marker range. A marker that
182
+ // isn't in the live DOM yet (it sits inside a flushed-but-unactivated ancestor
183
+ // template held by a reveal group) queues the id in `_$HY.dq` for retry instead
184
+ // of dropping the swap. A missing content template means the swap already ran —
185
+ // that stays a plain no-op and is never queued.
182
186
  // - $dfl(id): materialize fallback from `pl-*` template content without resolving.
187
+ // Marker misses queue in `_$HY.dlq`, same reasoning as $df.
183
188
  // - $dflj(ids): materialize fallback content for every id in the list.
189
+ // - $dfd(): drain both retry queues. Runs after every successful swap or fallback
190
+ // materialization — the only events that can bring queued markers into the live
191
+ // document. Content swaps ($df) drain before fallbacks ($dfl) so a settled
192
+ // fragment wins over its own pending fallback. Each pass snapshots the queue,
193
+ // so still-inert entries simply re-queue and wait for the next swap.
184
194
  // - $dfs(id, count, defer): register pending stylesheet count for fragment `id`.
185
195
  // - $dfc(id): style completion callback; reveals when the fragment/group is unblocked.
186
196
  // - $dfg(id): group-style gate check; reveals a waiting group once all style counts hit zero.
187
197
  // - $dfj(ids): reveal a group in registration order, waiting if any member still has pending styles.
188
- 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++)$dfl(e[i])}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])}`;
198
+ const REPLACE_SCRIPT = `function $df(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,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),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,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,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}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])}`;
189
199
 
190
200
  export function renderToString(code, options = {}) {
191
201
  const { renderId = "", nonce, noScripts, manifest } = options;