@solidjs/web 2.0.0-rc.3 → 2.0.0-rc.5

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 (65) hide show
  1. package/dist/dev.cjs +398 -17
  2. package/dist/dev.js +396 -19
  3. package/dist/server.cjs +166 -38
  4. package/dist/server.js +165 -39
  5. package/dist/web.cjs +369 -17
  6. package/dist/web.js +367 -19
  7. package/frames/dist/client.cjs +41 -8
  8. package/frames/dist/client.dev.cjs +41 -8
  9. package/frames/dist/client.dev.js +41 -8
  10. package/frames/dist/client.js +41 -8
  11. package/frames/dist/server.cjs +432 -44
  12. package/frames/dist/server.js +432 -44
  13. package/package.json +2 -2
  14. package/serialization/dist/decode.cjs +4 -2
  15. package/serialization/dist/decode.js +4 -2
  16. package/serialization/dist/serialization.cjs +12 -8
  17. package/serialization/dist/serialization.js +12 -8
  18. package/serialization/types/index.d.ts +7 -0
  19. package/serialization/types/serializer-decode.d.ts +14 -1
  20. package/serialization/types/serializer.d.ts +7 -0
  21. package/serialization/types-cjs/index.d.cts +7 -0
  22. package/serialization/types-cjs/serializer-decode.d.cts +14 -1
  23. package/serialization/types-cjs/serializer.d.cts +7 -0
  24. package/server-functions/dist/client.cjs +271 -47
  25. package/server-functions/dist/client.js +264 -47
  26. package/server-functions/dist/server.cjs +872 -131
  27. package/server-functions/dist/server.dev.cjs +892 -131
  28. package/server-functions/dist/server.dev.js +884 -131
  29. package/server-functions/dist/server.js +864 -131
  30. package/types/client.d.ts +4 -2
  31. package/types/cookies.d.ts +6 -14
  32. package/types/frames/frame-client.d.ts +4 -0
  33. package/types/frames/serializer-decode.d.ts +14 -1
  34. package/types/frames/serializer.d.ts +7 -0
  35. package/types/index.d.ts +1 -0
  36. package/types/jsx.d.ts +11 -16
  37. package/types/patch-driver.d.ts +3 -0
  38. package/types/response.d.ts +20 -1
  39. package/types/serializer-decode.d.ts +14 -1
  40. package/types/serializer.d.ts +7 -0
  41. package/types/server-functions/client.d.ts +58 -7
  42. package/types/server-functions/flash.d.ts +9 -0
  43. package/types/server-functions/registry.d.ts +38 -1
  44. package/types/server-functions/server.d.ts +66 -14
  45. package/types/server-functions/shared.d.ts +122 -16
  46. package/types/server-mock.d.ts +17 -2
  47. package/types/server.d.ts +16 -2
  48. package/types-cjs/client.d.cts +4 -2
  49. package/types-cjs/cookies.d.cts +6 -14
  50. package/types-cjs/frames/frame-client.d.cts +4 -0
  51. package/types-cjs/frames/serializer-decode.d.cts +14 -1
  52. package/types-cjs/frames/serializer.d.cts +7 -0
  53. package/types-cjs/index.d.cts +1 -0
  54. package/types-cjs/jsx.d.cts +11 -16
  55. package/types-cjs/patch-driver.d.cts +3 -0
  56. package/types-cjs/response.d.cts +20 -1
  57. package/types-cjs/serializer-decode.d.cts +14 -1
  58. package/types-cjs/serializer.d.cts +7 -0
  59. package/types-cjs/server-functions/client.d.cts +58 -7
  60. package/types-cjs/server-functions/flash.d.cts +9 -0
  61. package/types-cjs/server-functions/registry.d.cts +38 -1
  62. package/types-cjs/server-functions/server.d.cts +66 -14
  63. package/types-cjs/server-functions/shared.d.cts +122 -16
  64. package/types-cjs/server-mock.d.cts +17 -2
  65. package/types-cjs/server.d.cts +16 -2
package/dist/web.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createRenderEffect, createMemo, sharedConfig, enableHydration, untrack, runWithOwner, createRoot, flatten, flush, createComponent, omit, createOwner, createSignal, onCleanup, getOwner, createEffect } from 'solid-js';
1
+ import { createRenderEffect, createMemo, sharedConfig, enableHydration, untrack, runWithOwner, createRoot, flatten, flush, getOwner, createOwner, patchableRaw, storeHasOptimisticFamily, storeIsShallow, registerRowOps, registerSlotPatch, onCleanup, registerPatch, createComponent, omit, createSignal, createEffect } from 'solid-js';
2
2
  export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, merge as mergeProps, untrack } from 'solid-js';
3
3
 
4
4
  const DOMWithState = {
@@ -214,7 +214,8 @@ function resourceIdentity(tag, props) {
214
214
  let id = "res:" + tag + ":" + (props.rel || "") + ":" + (props.href || props.src || "");
215
215
  for (let i = 0; i < RESOURCE_QUALIFIERS.length; i++) {
216
216
  const q = RESOURCE_QUALIFIERS[i];
217
- if (props[q] != null) id += ":" + q + "=" + props[q];
217
+ const value = props[q];
218
+ if (value != null) id += ":" + q + "=" + (value === true ? "" : value);
218
219
  }
219
220
  return id;
220
221
  }
@@ -293,6 +294,7 @@ function serializeCookie(name, value, options = {}) {
293
294
  if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
294
295
  if (options.httpOnly) cookie += "; HttpOnly";
295
296
  if (options.secure) cookie += "; Secure";
297
+ if (options.partitioned) cookie += "; Partitioned";
296
298
  if (options.sameSite) {
297
299
  const sameSite = options.sameSite.toLowerCase();
298
300
  cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
@@ -332,6 +334,10 @@ const waitAsset = promise => {
332
334
  }
333
335
  gate();
334
336
  };
337
+ let listDriver;
338
+ function installListDriver(driver) {
339
+ listDriver = driver;
340
+ }
335
341
  const $$EVENT_OWNER = "_$SOLID_EVENT_OWNER";
336
342
  const INNER_OWNED = {};
337
343
  const delegatedEvents = new Set();
@@ -575,16 +581,18 @@ function setStyleProperty(node, name, value) {
575
581
  }
576
582
  function spread(node, props = {}, skipChildren) {
577
583
  const prevProps = {};
578
- if (!skipChildren) insert(node, () => props.children);
584
+ const get = typeof props === "function" ? props : () => props;
585
+ if (!skipChildren) insert(node, () => get().children);
579
586
  effect(() => {
580
- const r = props.ref;
587
+ const r = get().ref;
581
588
  (typeof r === "function" || Array.isArray(r)) && ref(() => r, node);
582
589
  }, () => {});
583
590
  effect(() => {
591
+ const source = get();
584
592
  const newProps = {};
585
- for (const prop in props) {
593
+ for (const prop in source) {
586
594
  if (prop === "children" || prop === "ref") continue;
587
- newProps[prop] = props[prop];
595
+ newProps[prop] = source[prop];
588
596
  }
589
597
  return newProps;
590
598
  }, props => assign(node, props, true, prevProps, true));
@@ -607,11 +615,6 @@ function ref(fn, element) {
607
615
  const resolved = untrack(fn);
608
616
  runWithOwner(null, () => applyRef(resolved, element));
609
617
  }
610
- const PURE_ROW = Symbol.for("solid.pure-row");
611
- function rowProof(fn) {
612
- fn[PURE_ROW] = true;
613
- return fn;
614
- }
615
618
  function scope(fn) {
616
619
  fn.$s = true;
617
620
  return fn;
@@ -675,16 +678,16 @@ function stripTextSeparators(nodes) {
675
678
  nodes.length = j;
676
679
  return nodes;
677
680
  }
678
- function patchDriver(subject, body) {
679
- {
680
- effect(() => body(subject, subject, false), () => body(subject, undefined, true));
681
- }
682
- }
683
681
  function insert(parent, accessor, marker, initial, options) {
684
682
  const multi = marker !== undefined;
685
683
  const host = options && options.host;
686
684
  if (multi && !initial) initial = [];
687
685
  if (hydrationRt !== null) initial = hydrationRt.claimInitial(parent, multi, initial);
686
+ if (listDriver !== undefined && typeof accessor === "function" && accessor.$ll !== undefined) {
687
+ const listAccessor = accessor;
688
+ const owner = getOwner();
689
+ if (listDriver(parent, accessor, marker, () => runWithOwner(owner, () => insert(parent, () => listAccessor(), marker, marker !== undefined ? [] : undefined, options)))) return;
690
+ }
688
691
  if (typeof accessor !== "function") {
689
692
  accessor = normalize(accessor, initial, multi, true);
690
693
  if (typeof accessor !== "function") {
@@ -1160,6 +1163,15 @@ function hydrate(code, element, options = {}) {
1160
1163
  enableHydration();
1161
1164
  installHydrationRuntime();
1162
1165
  if (globalThis._$HY.done) return render(code, element, [...element.childNodes], options);
1166
+ const head = (element.nodeType === 9 ? element : element.ownerDocument).head;
1167
+ if (head && element.contains(head)) {
1168
+ let n = head.firstChild;
1169
+ while (n && n.nodeType === 1 && n.hasAttribute("data-dh") && !n.hasAttribute("data-dhf")) {
1170
+ const next = n.nextSibling;
1171
+ head.appendChild(n);
1172
+ n = next;
1173
+ }
1174
+ }
1163
1175
  options.renderId ||= "";
1164
1176
  if (!globalThis._$HY.modules) globalThis._$HY.modules = {};
1165
1177
  if (!globalThis._$HY.loading) globalThis._$HY.loading = {};
@@ -1618,6 +1630,322 @@ function getHydrationKey() {
1618
1630
  }
1619
1631
  const RequestContext = Symbol();
1620
1632
 
1633
+ const PURE_ROW = Symbol.for("solid.pure-row");
1634
+ const arm = () => {
1635
+ installListDriver(driveList);
1636
+ };
1637
+ function rowProof(fn) {
1638
+ arm();
1639
+ fn[PURE_ROW] = true;
1640
+ return fn;
1641
+ }
1642
+ let rowCollector = null;
1643
+ const lisPositions = sources => {
1644
+ const n = sources.length;
1645
+ const tails = [];
1646
+ const tailsIdx = [];
1647
+ const prev = new Array(n).fill(-1);
1648
+ for (let j = 0; j < n; j++) {
1649
+ const v = sources[j];
1650
+ if (v === -1) continue;
1651
+ let lo = 0,
1652
+ hi = tails.length;
1653
+ while (lo < hi) {
1654
+ const mid = lo + hi >> 1;
1655
+ if (tails[mid] < v) lo = mid + 1;else hi = mid;
1656
+ }
1657
+ if (lo > 0) prev[j] = tailsIdx[lo - 1];
1658
+ tails[lo] = v;
1659
+ tailsIdx[lo] = j;
1660
+ }
1661
+ const stable = new Set();
1662
+ let k = tailsIdx.length ? tailsIdx[tails.length - 1] : -1;
1663
+ while (k >= 0) {
1664
+ stable.add(k);
1665
+ k = prev[k];
1666
+ }
1667
+ return stable;
1668
+ };
1669
+ const driveList = (parent, listFn, marker, lateClassic) => {
1670
+ const meta = listFn.$ll;
1671
+ if (meta.row?.[PURE_ROW] !== true) return false;
1672
+ if (typeof meta.keyed === "function") return false;
1673
+ const evalOwner = createOwner({
1674
+ id: "&each"
1675
+ });
1676
+ let subject = runWithOwner(evalOwner, () => untrack(meta.each));
1677
+ evalOwner.dispose();
1678
+ let raw = subject != null ? patchableRaw(subject) : undefined;
1679
+ if (raw === undefined || !Array.isArray(raw)) return false;
1680
+ const optimistic = storeHasOptimisticFamily(subject);
1681
+ if (optimistic) raw = untrack(() => Array.from(subject));
1682
+ const hydrating = !!sharedConfig.hydrating;
1683
+ if (hydrating && raw.length === 0) return false;
1684
+ let domRows;
1685
+ let rowIds;
1686
+ if (hydrating) {
1687
+ if (marker !== undefined) return false;
1688
+ domRows = Array.from(parent.children);
1689
+ if (domRows.length !== raw.length) return false;
1690
+ rowIds = new Array(raw.length);
1691
+ for (let i = 0; i < domRows.length; i++) {
1692
+ const key = domRows[i].getAttribute("_hk");
1693
+ if (key === null || !key.endsWith("0") || key.length < 2) return false;
1694
+ rowIds[i] = key.slice(0, -1);
1695
+ }
1696
+ }
1697
+ const rowFn = meta.row;
1698
+ const endAnchor = marker ?? null;
1699
+ const shallow = storeIsShallow(subject);
1700
+ let lastBodies = null;
1701
+ let lastUnbinds = null;
1702
+ const collectBind = (abs, build) => {
1703
+ const prevC = rowCollector;
1704
+ rowCollector = {
1705
+ row: shallow ? subject[abs] : undefined,
1706
+ bodies: [],
1707
+ unbinds: []
1708
+ };
1709
+ try {
1710
+ return build();
1711
+ } finally {
1712
+ lastBodies = rowCollector.bodies;
1713
+ lastUnbinds = rowCollector.unbinds;
1714
+ rowCollector = prevC;
1715
+ }
1716
+ };
1717
+ const listOwner = createOwner();
1718
+ let declined = false;
1719
+ const bindRow = (abs, claimId) => {
1720
+ return collectBind(abs, () => runWithOwner(listOwner, () => claimId !== undefined ? runWithOwner(createOwner({
1721
+ id: claimId
1722
+ }), () => untrack(() => rowFn(subject[abs]))) : untrack(() => rowFn(subject[abs]))));
1723
+ };
1724
+ let entries = new Array(raw.length);
1725
+ let rowBodies = shallow ? new Array(raw.length) : null;
1726
+ let rowUnbinds = new Array(raw.length);
1727
+ const runUnbinds = list => {
1728
+ if (list !== undefined) for (let u = 0; u < list.length; u++) list[u]();
1729
+ };
1730
+ const unbindAllRows = () => {
1731
+ for (let j = 0; j < rowUnbinds.length; j++) runUnbinds(rowUnbinds[j]);
1732
+ rowUnbinds = [];
1733
+ };
1734
+ let prevRaws = raw.slice();
1735
+ try {
1736
+ if (hydrating) {
1737
+ for (let i = 0; i < raw.length; i++) {
1738
+ entries[i] = bindRow(i, rowIds[i]);
1739
+ if (rowBodies !== null) rowBodies[i] = lastBodies;
1740
+ rowUnbinds[i] = lastUnbinds;
1741
+ }
1742
+ } else {
1743
+ for (let i = 0; i < raw.length; i++) {
1744
+ const node = bindRow(i);
1745
+ entries[i] = node;
1746
+ if (rowBodies !== null) rowBodies[i] = lastBodies;
1747
+ rowUnbinds[i] = lastUnbinds;
1748
+ parent.insertBefore(node, endAnchor);
1749
+ }
1750
+ }
1751
+ } catch (err) {
1752
+ unbindAllRows();
1753
+ runUnbinds(lastUnbinds ?? undefined);
1754
+ for (let j = 0; j < entries.length; j++) {
1755
+ const n = entries[j];
1756
+ if (n !== undefined && n.parentNode === parent) n.remove();
1757
+ }
1758
+ listOwner.dispose();
1759
+ throw err;
1760
+ }
1761
+ const identityOps = nextArr => {
1762
+ const keyOf = r => {
1763
+ const w = r != null ? patchableRaw(r) : undefined;
1764
+ return w !== undefined ? w : r;
1765
+ };
1766
+ const oldIndex = new Map();
1767
+ for (let j = 0; j < prevRaws.length; j++) {
1768
+ const k = keyOf(prevRaws[j]);
1769
+ const existing = oldIndex.get(k);
1770
+ if (existing === undefined) oldIndex.set(k, j);else if (Array.isArray(existing)) existing.push(j);else oldIndex.set(k, [existing, j]);
1771
+ }
1772
+ const sources = new Array(nextArr.length);
1773
+ for (let k = 0; k < nextArr.length; k++) {
1774
+ const m = oldIndex.get(keyOf(nextArr[k]));
1775
+ if (m === undefined) sources[k] = -1;else if (Array.isArray(m)) {
1776
+ sources[k] = m.shift();
1777
+ if (m.length === 1) oldIndex.set(keyOf(nextArr[k]), m[0]);
1778
+ } else {
1779
+ sources[k] = m;
1780
+ oldIndex.delete(keyOf(nextArr[k]));
1781
+ }
1782
+ }
1783
+ return {
1784
+ prefix: 0,
1785
+ sources
1786
+ };
1787
+ };
1788
+ let resyncNeeded = false;
1789
+ const applyOps = (next, ops) => {
1790
+ if (declined) return;
1791
+ if (resyncNeeded) ops = null;
1792
+ if (ops === null) ops = identityOps(next);
1793
+ const {
1794
+ prefix,
1795
+ sources
1796
+ } = ops;
1797
+ const built = new Array(sources.length);
1798
+ const builtBodies = rowBodies !== null ? new Array(sources.length) : null;
1799
+ const builtUnbinds = new Array(sources.length);
1800
+ let j = 0;
1801
+ try {
1802
+ for (; j < sources.length; j++) {
1803
+ const abs = prefix + j;
1804
+ const src = sources[j];
1805
+ if (src === -1 || refRebuild && src >= 0 && next[abs] !== prevRaws[src]) {
1806
+ built[j] = bindRow(abs);
1807
+ if (builtBodies !== null) builtBodies[j] = lastBodies;
1808
+ builtUnbinds[j] = lastUnbinds;
1809
+ }
1810
+ }
1811
+ } catch (err) {
1812
+ for (let k = 0; k < j; k++) runUnbinds(builtUnbinds[k]);
1813
+ runUnbinds(lastUnbinds ?? undefined);
1814
+ resyncNeeded = true;
1815
+ throw err;
1816
+ }
1817
+ const retained = new Set();
1818
+ for (let k = 0; k < sources.length; k++) {
1819
+ if (sources[k] >= 0 && built[k] === undefined) retained.add(sources[k]);
1820
+ }
1821
+ for (let k = prefix; k < entries.length; k++) {
1822
+ if (!retained.has(k)) {
1823
+ entries[k].remove();
1824
+ runUnbinds(rowUnbinds[k]);
1825
+ }
1826
+ }
1827
+ const newEntries = new Array(prefix + sources.length);
1828
+ const newBodies = rowBodies !== null ? new Array(prefix + sources.length) : null;
1829
+ const newUnbinds = new Array(prefix + sources.length);
1830
+ for (let i = 0; i < prefix; i++) {
1831
+ newEntries[i] = entries[i];
1832
+ if (newBodies !== null) newBodies[i] = rowBodies[i];
1833
+ newUnbinds[i] = rowUnbinds[i];
1834
+ }
1835
+ const stable = lisPositions(sources);
1836
+ let anchor = endAnchor;
1837
+ for (let k = sources.length - 1; k >= 0; k--) {
1838
+ const abs = prefix + k;
1839
+ const src = sources[k];
1840
+ let node;
1841
+ if (built[k] !== undefined) {
1842
+ node = built[k];
1843
+ if (newBodies !== null) newBodies[abs] = builtBodies[k];
1844
+ newUnbinds[abs] = builtUnbinds[k];
1845
+ parent.insertBefore(node, anchor);
1846
+ } else {
1847
+ node = entries[src];
1848
+ if (newBodies !== null) newBodies[abs] = rowBodies[src];
1849
+ newUnbinds[abs] = rowUnbinds[src];
1850
+ if (!stable.has(k)) parent.insertBefore(node, anchor);
1851
+ }
1852
+ newEntries[abs] = node;
1853
+ anchor = node;
1854
+ }
1855
+ entries = newEntries;
1856
+ if (newBodies !== null) rowBodies = newBodies;
1857
+ rowUnbinds = newUnbinds;
1858
+ prevRaws = next.slice();
1859
+ resyncNeeded = false;
1860
+ };
1861
+ let unbindOps = runWithOwner(listOwner, () => registerRowOps(subject, applyOps));
1862
+ const refRebuild = shallow && typeof meta.keyed !== "function";
1863
+ const rebuildSlot = i => {
1864
+ runUnbinds(rowUnbinds[i]);
1865
+ const old = entries[i];
1866
+ const node = bindRow(i);
1867
+ rowBodies[i] = lastBodies;
1868
+ rowUnbinds[i] = lastUnbinds;
1869
+ parent.insertBefore(node, old);
1870
+ old.remove();
1871
+ entries[i] = node;
1872
+ };
1873
+ const applySlot = (i, next, prev) => {
1874
+ if (declined) return;
1875
+ if (resyncNeeded) {
1876
+ const live = subject != null ? patchableRaw(subject) : undefined;
1877
+ if (live !== undefined && Array.isArray(live)) applyOps(live, null);
1878
+ return;
1879
+ }
1880
+ if (refRebuild) {
1881
+ rebuildSlot(i);
1882
+ prevRaws[i] = next;
1883
+ return;
1884
+ }
1885
+ const bodies = rowBodies[i];
1886
+ if (bodies !== undefined) {
1887
+ for (let b = 0; b < bodies.length; b++) bodies[b](next, prev, false);
1888
+ }
1889
+ prevRaws[i] = next;
1890
+ };
1891
+ let unbindSlots = shallow ? runWithOwner(listOwner, () => registerSlotPatch(subject, applySlot)) : null;
1892
+ runWithOwner(listOwner, () => effect(() => meta.each(), value => {
1893
+ if (declined || value === subject) return;
1894
+ const nextRaw = value != null ? patchableRaw(value) : undefined;
1895
+ unbindOps();
1896
+ unbindSlots?.();
1897
+ if (nextRaw !== undefined && Array.isArray(nextRaw) && storeIsShallow(value) !== shallow) {
1898
+ for (let j = 0; j < entries.length; j++) entries[j].remove();
1899
+ entries = [];
1900
+ prevRaws = [];
1901
+ unbindAllRows();
1902
+ subject = value;
1903
+ declined = true;
1904
+ listOwner.dispose();
1905
+ lateClassic?.();
1906
+ return;
1907
+ }
1908
+ if (nextRaw === undefined || !Array.isArray(nextRaw)) {
1909
+ for (let j = 0; j < entries.length; j++) entries[j].remove();
1910
+ entries = [];
1911
+ prevRaws = [];
1912
+ unbindAllRows();
1913
+ subject = value;
1914
+ declined = true;
1915
+ listOwner.dispose();
1916
+ lateClassic?.();
1917
+ return;
1918
+ }
1919
+ const swapOps = identityOps(nextRaw);
1920
+ subject = value;
1921
+ unbindOps = runWithOwner(listOwner, () => registerRowOps(subject, applyOps));
1922
+ if (shallow) unbindSlots = runWithOwner(listOwner, () => registerSlotPatch(subject, applySlot));
1923
+ applyOps(nextRaw, swapOps);
1924
+ }));
1925
+ onCleanup(() => {
1926
+ unbindOps();
1927
+ unbindSlots?.();
1928
+ unbindAllRows();
1929
+ listOwner.dispose();
1930
+ });
1931
+ return true;
1932
+ };
1933
+ const patchDriver = (subject, body) => {
1934
+ const raw = patchableRaw(subject);
1935
+ if (raw !== undefined) {
1936
+ if (!sharedConfig.hydrating) body(raw, undefined, true);
1937
+ const unbind = registerPatch(subject, body);
1938
+ if (rowCollector !== null) rowCollector.unbinds.push(unbind);
1939
+ else onCleanup(unbind);
1940
+ } else if (rowCollector !== null && subject === rowCollector.row) {
1941
+ rowCollector.bodies.push(body);
1942
+ if (!sharedConfig.hydrating) body(subject, undefined, true);
1943
+ } else {
1944
+ effect(() => body(subject, subject, false),
1945
+ () => untrack(() => body(subject, undefined, true)));
1946
+ }
1947
+ };
1948
+
1621
1949
  function throwInBrowser(func) {
1622
1950
  const err = new Error(`${func.name} is not supported in the browser, returning undefined`);
1623
1951
  console.error(err);
@@ -1691,6 +2019,7 @@ function isSafeError(value) {
1691
2019
  return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
1692
2020
  }
1693
2021
  const REVALIDATE_HEADER = "X-Revalidate";
2022
+ const RESPONSE_HEADER_VALUE_LIMIT = 4096;
1694
2023
  function initWithRevalidate(init = {}) {
1695
2024
  const resolved = typeof init === "number" ? {
1696
2025
  status: init
@@ -1711,7 +2040,13 @@ function initWithRevalidate(init = {}) {
1711
2040
  } else {
1712
2041
  headers = new Headers(responseInit.headers);
1713
2042
  }
1714
- revalidate !== undefined && headers.set(REVALIDATE_HEADER, revalidate.toString());
2043
+ if (revalidate !== undefined) {
2044
+ const keys = revalidate.toString();
2045
+ if (keys.length > RESPONSE_HEADER_VALUE_LIMIT) {
2046
+ throw new TypeError(`revalidate names ${keys.length} characters of cache keys; past ` + `${RESPONSE_HEADER_VALUE_LIMIT} the ${REVALIDATE_HEADER} header would overflow ` + `receivers (an 8 KiB proxy buffer holds the whole header block) and the response ` + `dies at the socket after the mutation committed. Split the invalidation across ` + `calls or use coarser keys — a dropped key would be a silently stale cache, so ` + `the runtime refuses rather than trims.`);
2047
+ }
2048
+ headers.set(REVALIDATE_HEADER, keys);
2049
+ }
1715
2050
  return {
1716
2051
  responseInit,
1717
2052
  headers
@@ -1728,7 +2063,13 @@ function redirect(url, init = 302) {
1728
2063
  if (responseInit.status === undefined) {
1729
2064
  responseInit.status = 302;
1730
2065
  }
1731
- headers.set("Location", String(url));
2066
+ const target = typeof url === "string" ? url : url[HREF];
2067
+ const location = typeof target === "string" ? target : String(url);
2068
+ const encoded = location.replace(/[^\x00-\x7f]/gu, encodeURIComponent);
2069
+ if (encoded.length > RESPONSE_HEADER_VALUE_LIMIT) {
2070
+ throw new TypeError(`redirect() target is ${encoded.length} characters; past ` + `${RESPONSE_HEADER_VALUE_LIMIT} the Location header (and the scripted transport's ` + `redirect header) would overflow receivers and the response dies at the socket. ` + `A target this size is usually unbounded input echoed into the url — carry the ` + `state server-side instead. Refused rather than trimmed: a cut target is a ` + `different address.`);
2071
+ }
2072
+ headers.set("Location", encoded);
1732
2073
  return new Response(null, {
1733
2074
  ...responseInit,
1734
2075
  headers
@@ -1744,11 +2085,18 @@ function reload(init = {}) {
1744
2085
  headers
1745
2086
  });
1746
2087
  }
2088
+ const NULL_BODY_STATUSES = new Set([204, 205, 304]);
1747
2089
  function respond(value, init = {}) {
1748
2090
  const {
1749
2091
  responseInit,
1750
2092
  headers
1751
2093
  } = initWithRevalidate(init);
2094
+ if (NULL_BODY_STATUSES.has(responseInit.status)) {
2095
+ return new ResponseEnvelope(new Response(null, {
2096
+ ...responseInit,
2097
+ headers
2098
+ }), value);
2099
+ }
1752
2100
  headers.set("Content-Type", "application/json");
1753
2101
  return new ResponseEnvelope(new Response(JSON.stringify(value), {
1754
2102
  ...responseInit,
@@ -1899,4 +2247,4 @@ _moduleUrl) {
1899
2247
  function httpStatus(_code, _text) {}
1900
2248
  function httpHeader(_name, _value, _options) {}
1901
2249
 
1902
- export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clearFlashCookie, clientOnly, commitEventResponse, composeMiddleware, createRequestEvent, createResponseStub, createSSRResponse, delegateEvents, dynamic, dynamicProperty, effect, escape, generateHydrationScript, getDelegatedRoot, getExpectedRedirectStatus, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, parseCookieHeader, patchDriver, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, resolveSSRNode, respond, rowProof, runHydrationEvents, scope, serializeCookie, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, useHead, waitAsset, warmAsset };
2250
+ export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, NULL_BODY_STATUSES, Namespaces, Portal, RESPONSE_HEADER_VALUE_LIMIT, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clearFlashCookie, clientOnly, commitEventResponse, composeMiddleware, createRequestEvent, createResponseStub, createSSRResponse, delegateEvents, driveList, dynamic, dynamicProperty, effect, escape, generateHydrationScript, getDelegatedRoot, getExpectedRedirectStatus, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, installListDriver, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, listDriver, markSafeError, memo, parseCookieHeader, patchDriver, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, resolveSSRNode, respond, rowProof, runHydrationEvents, scope, serializeCookie, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, useHead, waitAsset, warmAsset };
@@ -177,7 +177,18 @@ function createFrameHost(options = {}) {
177
177
  store.version = version;
178
178
  clearStreamRecords(store.records);
179
179
  }
180
- Object.assign(store.records, records);
180
+ const assets = records["seg::assets"];
181
+ const previous = assets && store.records["seg::assets"];
182
+ if (!previous || previous === assets) {
183
+ Object.assign(store.records, records);
184
+ } else {
185
+ for (const name in assets) {
186
+ const values = assets[name];
187
+ if (Array.isArray(values)) {
188
+ previous[name] ? previous[name].push(...values) : previous[name] = values;
189
+ }
190
+ }
191
+ }
181
192
  return true;
182
193
  };
183
194
  return {
@@ -269,7 +280,7 @@ class FrameImpl {
269
280
  #slotRegions = new Map();
270
281
  #slotResolvedRefs = new Map();
271
282
  #slotNodes = new Map();
272
- #processedAssets = new Set();
283
+ #processedAssets = new WeakSet();
273
284
  #recordRefresh = null;
274
285
  #disposed = false;
275
286
  #styleFlush = () => {
@@ -370,6 +381,7 @@ class FrameImpl {
370
381
  this.#revealed.clear();
371
382
  this.#fallbackShown.clear();
372
383
  this.#appliedHoles.clear();
384
+ this.#processedAssets = new WeakSet();
373
385
  this.#errorNotified = false;
374
386
  clearStreamRecords(this.#store, root);
375
387
  }
@@ -429,12 +441,17 @@ class FrameImpl {
429
441
  }
430
442
  }
431
443
  for (const key in this.#store) {
432
- if (this.#processedAssets.has(key) || !key.endsWith(":assets")) continue;
433
- this.#processedAssets.add(key);
434
444
  const record = this.#store[key];
435
- if (record && record.modules) {
445
+ if (!key.endsWith(":assets") || !record || this.#processedAssets.has(record)) {
446
+ continue;
447
+ }
448
+ this.#processedAssets.add(record);
449
+ if (record.modules) {
436
450
  for (const href of record.modules) ensureModulePreload(href);
437
451
  }
452
+ if (record.preloads) {
453
+ for (const entry of record.preloads) ensurePreload(entry);
454
+ }
438
455
  }
439
456
  this.#syncSlots();
440
457
  }
@@ -902,12 +919,28 @@ function parseFragment(html) {
902
919
  template.innerHTML = html;
903
920
  return template.content;
904
921
  }
905
- function findHeadElement(selector, attr, value) {
906
- for (const node of document.head.querySelectorAll(selector)) {
907
- if (node.getAttribute(attr) === value) return node;
922
+ const PRELOAD_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
923
+ function findHeadElement(selector, attr, value, qualifiers) {
924
+ candidate: for (const node of document.head.querySelectorAll(selector)) {
925
+ if (node.getAttribute(attr) !== value) continue;
926
+ if (!qualifiers) return node;
927
+ for (let i = 0; i < PRELOAD_QUALIFIERS.length; i++) {
928
+ const name = PRELOAD_QUALIFIERS[i];
929
+ if (node.getAttribute(name) !== (qualifiers[name] ?? null)) continue candidate;
930
+ }
931
+ return node;
908
932
  }
909
933
  return null;
910
934
  }
935
+ function ensurePreload(entry) {
936
+ const attrs = entry.attrs;
937
+ if (findHeadElement('link[rel="preload"]', "href", entry.href, attrs)) return;
938
+ const link = document.createElement("link");
939
+ link.rel = "preload";
940
+ for (const name in attrs) link.setAttribute(name, attrs[name]);
941
+ link.setAttribute("href", entry.href);
942
+ document.head.appendChild(link);
943
+ }
911
944
  function ensureStylesheet(entry, onSettle) {
912
945
  const href = typeof entry === "string" ? entry : entry.href;
913
946
  let link = findHeadElement('link[rel="stylesheet"]', "href", href);
@@ -180,7 +180,18 @@ function createFrameHost(options = {}) {
180
180
  store.version = version;
181
181
  clearStreamRecords(store.records);
182
182
  }
183
- Object.assign(store.records, records);
183
+ const assets = records["seg::assets"];
184
+ const previous = assets && store.records["seg::assets"];
185
+ if (!previous || previous === assets) {
186
+ Object.assign(store.records, records);
187
+ } else {
188
+ for (const name in assets) {
189
+ const values = assets[name];
190
+ if (Array.isArray(values)) {
191
+ previous[name] ? previous[name].push(...values) : previous[name] = values;
192
+ }
193
+ }
194
+ }
184
195
  return true;
185
196
  };
186
197
  return {
@@ -272,7 +283,7 @@ class FrameImpl {
272
283
  #slotRegions = new Map();
273
284
  #slotResolvedRefs = new Map();
274
285
  #slotNodes = new Map();
275
- #processedAssets = new Set();
286
+ #processedAssets = new WeakSet();
276
287
  #recordRefresh = null;
277
288
  #disposed = false;
278
289
  #styleFlush = () => {
@@ -373,6 +384,7 @@ class FrameImpl {
373
384
  this.#revealed.clear();
374
385
  this.#fallbackShown.clear();
375
386
  this.#appliedHoles.clear();
387
+ this.#processedAssets = new WeakSet();
376
388
  this.#errorNotified = false;
377
389
  clearStreamRecords(this.#store, root);
378
390
  }
@@ -433,12 +445,17 @@ class FrameImpl {
433
445
  }
434
446
  }
435
447
  for (const key in this.#store) {
436
- if (this.#processedAssets.has(key) || !key.endsWith(":assets")) continue;
437
- this.#processedAssets.add(key);
438
448
  const record = this.#store[key];
439
- if (record && record.modules) {
449
+ if (!key.endsWith(":assets") || !record || this.#processedAssets.has(record)) {
450
+ continue;
451
+ }
452
+ this.#processedAssets.add(record);
453
+ if (record.modules) {
440
454
  for (const href of record.modules) ensureModulePreload(href);
441
455
  }
456
+ if (record.preloads) {
457
+ for (const entry of record.preloads) ensurePreload(entry);
458
+ }
442
459
  }
443
460
  this.#syncSlots();
444
461
  }
@@ -912,12 +929,28 @@ function parseFragment(html) {
912
929
  template.innerHTML = html;
913
930
  return template.content;
914
931
  }
915
- function findHeadElement(selector, attr, value) {
916
- for (const node of document.head.querySelectorAll(selector)) {
917
- if (node.getAttribute(attr) === value) return node;
932
+ const PRELOAD_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
933
+ function findHeadElement(selector, attr, value, qualifiers) {
934
+ candidate: for (const node of document.head.querySelectorAll(selector)) {
935
+ if (node.getAttribute(attr) !== value) continue;
936
+ if (!qualifiers) return node;
937
+ for (let i = 0; i < PRELOAD_QUALIFIERS.length; i++) {
938
+ const name = PRELOAD_QUALIFIERS[i];
939
+ if (node.getAttribute(name) !== (qualifiers[name] ?? null)) continue candidate;
940
+ }
941
+ return node;
918
942
  }
919
943
  return null;
920
944
  }
945
+ function ensurePreload(entry) {
946
+ const attrs = entry.attrs;
947
+ if (findHeadElement('link[rel="preload"]', "href", entry.href, attrs)) return;
948
+ const link = document.createElement("link");
949
+ link.rel = "preload";
950
+ for (const name in attrs) link.setAttribute(name, attrs[name]);
951
+ link.setAttribute("href", entry.href);
952
+ document.head.appendChild(link);
953
+ }
921
954
  function ensureStylesheet(entry, onSettle) {
922
955
  const href = typeof entry === "string" ? entry : entry.href;
923
956
  let link = findHeadElement('link[rel="stylesheet"]', "href", href);