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

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/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 = {
@@ -332,6 +332,10 @@ const waitAsset = promise => {
332
332
  }
333
333
  gate();
334
334
  };
335
+ let listDriver;
336
+ function installListDriver(driver) {
337
+ listDriver = driver;
338
+ }
335
339
  const $$EVENT_OWNER = "_$SOLID_EVENT_OWNER";
336
340
  const INNER_OWNED = {};
337
341
  const delegatedEvents = new Set();
@@ -607,11 +611,6 @@ function ref(fn, element) {
607
611
  const resolved = untrack(fn);
608
612
  runWithOwner(null, () => applyRef(resolved, element));
609
613
  }
610
- const PURE_ROW = Symbol.for("solid.pure-row");
611
- function rowProof(fn) {
612
- fn[PURE_ROW] = true;
613
- return fn;
614
- }
615
614
  function scope(fn) {
616
615
  fn.$s = true;
617
616
  return fn;
@@ -675,16 +674,16 @@ function stripTextSeparators(nodes) {
675
674
  nodes.length = j;
676
675
  return nodes;
677
676
  }
678
- function patchDriver(subject, body) {
679
- {
680
- effect(() => body(subject, subject, false), () => body(subject, undefined, true));
681
- }
682
- }
683
677
  function insert(parent, accessor, marker, initial, options) {
684
678
  const multi = marker !== undefined;
685
679
  const host = options && options.host;
686
680
  if (multi && !initial) initial = [];
687
681
  if (hydrationRt !== null) initial = hydrationRt.claimInitial(parent, multi, initial);
682
+ if (listDriver !== undefined && typeof accessor === "function" && accessor.$ll !== undefined) {
683
+ const listAccessor = accessor;
684
+ const owner = getOwner();
685
+ if (listDriver(parent, accessor, marker, () => runWithOwner(owner, () => insert(parent, () => listAccessor(), marker, marker !== undefined ? [] : undefined, options)))) return;
686
+ }
688
687
  if (typeof accessor !== "function") {
689
688
  accessor = normalize(accessor, initial, multi, true);
690
689
  if (typeof accessor !== "function") {
@@ -1160,6 +1159,15 @@ function hydrate(code, element, options = {}) {
1160
1159
  enableHydration();
1161
1160
  installHydrationRuntime();
1162
1161
  if (globalThis._$HY.done) return render(code, element, [...element.childNodes], options);
1162
+ const head = (element.nodeType === 9 ? element : element.ownerDocument).head;
1163
+ if (head && element.contains(head)) {
1164
+ let n = head.firstChild;
1165
+ while (n && n.nodeType === 1 && n.hasAttribute("data-dh") && !n.hasAttribute("data-dhf")) {
1166
+ const next = n.nextSibling;
1167
+ head.appendChild(n);
1168
+ n = next;
1169
+ }
1170
+ }
1163
1171
  options.renderId ||= "";
1164
1172
  if (!globalThis._$HY.modules) globalThis._$HY.modules = {};
1165
1173
  if (!globalThis._$HY.loading) globalThis._$HY.loading = {};
@@ -1618,6 +1626,322 @@ function getHydrationKey() {
1618
1626
  }
1619
1627
  const RequestContext = Symbol();
1620
1628
 
1629
+ const PURE_ROW = Symbol.for("solid.pure-row");
1630
+ const arm = () => {
1631
+ installListDriver(driveList);
1632
+ };
1633
+ function rowProof(fn) {
1634
+ arm();
1635
+ fn[PURE_ROW] = true;
1636
+ return fn;
1637
+ }
1638
+ let rowCollector = null;
1639
+ const lisPositions = sources => {
1640
+ const n = sources.length;
1641
+ const tails = [];
1642
+ const tailsIdx = [];
1643
+ const prev = new Array(n).fill(-1);
1644
+ for (let j = 0; j < n; j++) {
1645
+ const v = sources[j];
1646
+ if (v === -1) continue;
1647
+ let lo = 0,
1648
+ hi = tails.length;
1649
+ while (lo < hi) {
1650
+ const mid = lo + hi >> 1;
1651
+ if (tails[mid] < v) lo = mid + 1;else hi = mid;
1652
+ }
1653
+ if (lo > 0) prev[j] = tailsIdx[lo - 1];
1654
+ tails[lo] = v;
1655
+ tailsIdx[lo] = j;
1656
+ }
1657
+ const stable = new Set();
1658
+ let k = tailsIdx.length ? tailsIdx[tails.length - 1] : -1;
1659
+ while (k >= 0) {
1660
+ stable.add(k);
1661
+ k = prev[k];
1662
+ }
1663
+ return stable;
1664
+ };
1665
+ const driveList = (parent, listFn, marker, lateClassic) => {
1666
+ const meta = listFn.$ll;
1667
+ if (meta.row?.[PURE_ROW] !== true) return false;
1668
+ if (typeof meta.keyed === "function") return false;
1669
+ const evalOwner = createOwner({
1670
+ id: "&each"
1671
+ });
1672
+ let subject = runWithOwner(evalOwner, () => untrack(meta.each));
1673
+ evalOwner.dispose();
1674
+ let raw = subject != null ? patchableRaw(subject) : undefined;
1675
+ if (raw === undefined || !Array.isArray(raw)) return false;
1676
+ const optimistic = storeHasOptimisticFamily(subject);
1677
+ if (optimistic) raw = untrack(() => Array.from(subject));
1678
+ const hydrating = !!sharedConfig.hydrating;
1679
+ if (hydrating && raw.length === 0) return false;
1680
+ let domRows;
1681
+ let rowIds;
1682
+ if (hydrating) {
1683
+ if (marker !== undefined) return false;
1684
+ domRows = Array.from(parent.children);
1685
+ if (domRows.length !== raw.length) return false;
1686
+ rowIds = new Array(raw.length);
1687
+ for (let i = 0; i < domRows.length; i++) {
1688
+ const key = domRows[i].getAttribute("_hk");
1689
+ if (key === null || !key.endsWith("0") || key.length < 2) return false;
1690
+ rowIds[i] = key.slice(0, -1);
1691
+ }
1692
+ }
1693
+ const rowFn = meta.row;
1694
+ const endAnchor = marker ?? null;
1695
+ const shallow = storeIsShallow(subject);
1696
+ let lastBodies = null;
1697
+ let lastUnbinds = null;
1698
+ const collectBind = (abs, build) => {
1699
+ const prevC = rowCollector;
1700
+ rowCollector = {
1701
+ row: shallow ? subject[abs] : undefined,
1702
+ bodies: [],
1703
+ unbinds: []
1704
+ };
1705
+ try {
1706
+ return build();
1707
+ } finally {
1708
+ lastBodies = rowCollector.bodies;
1709
+ lastUnbinds = rowCollector.unbinds;
1710
+ rowCollector = prevC;
1711
+ }
1712
+ };
1713
+ const listOwner = createOwner();
1714
+ let declined = false;
1715
+ const bindRow = (abs, claimId) => {
1716
+ return collectBind(abs, () => runWithOwner(listOwner, () => claimId !== undefined ? runWithOwner(createOwner({
1717
+ id: claimId
1718
+ }), () => untrack(() => rowFn(subject[abs]))) : untrack(() => rowFn(subject[abs]))));
1719
+ };
1720
+ let entries = new Array(raw.length);
1721
+ let rowBodies = shallow ? new Array(raw.length) : null;
1722
+ let rowUnbinds = new Array(raw.length);
1723
+ const runUnbinds = list => {
1724
+ if (list !== undefined) for (let u = 0; u < list.length; u++) list[u]();
1725
+ };
1726
+ const unbindAllRows = () => {
1727
+ for (let j = 0; j < rowUnbinds.length; j++) runUnbinds(rowUnbinds[j]);
1728
+ rowUnbinds = [];
1729
+ };
1730
+ let prevRaws = raw.slice();
1731
+ try {
1732
+ if (hydrating) {
1733
+ for (let i = 0; i < raw.length; i++) {
1734
+ entries[i] = bindRow(i, rowIds[i]);
1735
+ if (rowBodies !== null) rowBodies[i] = lastBodies;
1736
+ rowUnbinds[i] = lastUnbinds;
1737
+ }
1738
+ } else {
1739
+ for (let i = 0; i < raw.length; i++) {
1740
+ const node = bindRow(i);
1741
+ entries[i] = node;
1742
+ if (rowBodies !== null) rowBodies[i] = lastBodies;
1743
+ rowUnbinds[i] = lastUnbinds;
1744
+ parent.insertBefore(node, endAnchor);
1745
+ }
1746
+ }
1747
+ } catch (err) {
1748
+ unbindAllRows();
1749
+ runUnbinds(lastUnbinds ?? undefined);
1750
+ for (let j = 0; j < entries.length; j++) {
1751
+ const n = entries[j];
1752
+ if (n !== undefined && n.parentNode === parent) n.remove();
1753
+ }
1754
+ listOwner.dispose();
1755
+ throw err;
1756
+ }
1757
+ const identityOps = nextArr => {
1758
+ const keyOf = r => {
1759
+ const w = r != null ? patchableRaw(r) : undefined;
1760
+ return w !== undefined ? w : r;
1761
+ };
1762
+ const oldIndex = new Map();
1763
+ for (let j = 0; j < prevRaws.length; j++) {
1764
+ const k = keyOf(prevRaws[j]);
1765
+ const existing = oldIndex.get(k);
1766
+ if (existing === undefined) oldIndex.set(k, j);else if (Array.isArray(existing)) existing.push(j);else oldIndex.set(k, [existing, j]);
1767
+ }
1768
+ const sources = new Array(nextArr.length);
1769
+ for (let k = 0; k < nextArr.length; k++) {
1770
+ const m = oldIndex.get(keyOf(nextArr[k]));
1771
+ if (m === undefined) sources[k] = -1;else if (Array.isArray(m)) {
1772
+ sources[k] = m.shift();
1773
+ if (m.length === 1) oldIndex.set(keyOf(nextArr[k]), m[0]);
1774
+ } else {
1775
+ sources[k] = m;
1776
+ oldIndex.delete(keyOf(nextArr[k]));
1777
+ }
1778
+ }
1779
+ return {
1780
+ prefix: 0,
1781
+ sources
1782
+ };
1783
+ };
1784
+ let resyncNeeded = false;
1785
+ const applyOps = (next, ops) => {
1786
+ if (declined) return;
1787
+ if (resyncNeeded) ops = null;
1788
+ if (ops === null) ops = identityOps(next);
1789
+ const {
1790
+ prefix,
1791
+ sources
1792
+ } = ops;
1793
+ const built = new Array(sources.length);
1794
+ const builtBodies = rowBodies !== null ? new Array(sources.length) : null;
1795
+ const builtUnbinds = new Array(sources.length);
1796
+ let j = 0;
1797
+ try {
1798
+ for (; j < sources.length; j++) {
1799
+ const abs = prefix + j;
1800
+ const src = sources[j];
1801
+ if (src === -1 || refRebuild && src >= 0 && next[abs] !== prevRaws[src]) {
1802
+ built[j] = bindRow(abs);
1803
+ if (builtBodies !== null) builtBodies[j] = lastBodies;
1804
+ builtUnbinds[j] = lastUnbinds;
1805
+ }
1806
+ }
1807
+ } catch (err) {
1808
+ for (let k = 0; k < j; k++) runUnbinds(builtUnbinds[k]);
1809
+ runUnbinds(lastUnbinds ?? undefined);
1810
+ resyncNeeded = true;
1811
+ throw err;
1812
+ }
1813
+ const retained = new Set();
1814
+ for (let k = 0; k < sources.length; k++) {
1815
+ if (sources[k] >= 0 && built[k] === undefined) retained.add(sources[k]);
1816
+ }
1817
+ for (let k = prefix; k < entries.length; k++) {
1818
+ if (!retained.has(k)) {
1819
+ entries[k].remove();
1820
+ runUnbinds(rowUnbinds[k]);
1821
+ }
1822
+ }
1823
+ const newEntries = new Array(prefix + sources.length);
1824
+ const newBodies = rowBodies !== null ? new Array(prefix + sources.length) : null;
1825
+ const newUnbinds = new Array(prefix + sources.length);
1826
+ for (let i = 0; i < prefix; i++) {
1827
+ newEntries[i] = entries[i];
1828
+ if (newBodies !== null) newBodies[i] = rowBodies[i];
1829
+ newUnbinds[i] = rowUnbinds[i];
1830
+ }
1831
+ const stable = lisPositions(sources);
1832
+ let anchor = endAnchor;
1833
+ for (let k = sources.length - 1; k >= 0; k--) {
1834
+ const abs = prefix + k;
1835
+ const src = sources[k];
1836
+ let node;
1837
+ if (built[k] !== undefined) {
1838
+ node = built[k];
1839
+ if (newBodies !== null) newBodies[abs] = builtBodies[k];
1840
+ newUnbinds[abs] = builtUnbinds[k];
1841
+ parent.insertBefore(node, anchor);
1842
+ } else {
1843
+ node = entries[src];
1844
+ if (newBodies !== null) newBodies[abs] = rowBodies[src];
1845
+ newUnbinds[abs] = rowUnbinds[src];
1846
+ if (!stable.has(k)) parent.insertBefore(node, anchor);
1847
+ }
1848
+ newEntries[abs] = node;
1849
+ anchor = node;
1850
+ }
1851
+ entries = newEntries;
1852
+ if (newBodies !== null) rowBodies = newBodies;
1853
+ rowUnbinds = newUnbinds;
1854
+ prevRaws = next.slice();
1855
+ resyncNeeded = false;
1856
+ };
1857
+ let unbindOps = runWithOwner(listOwner, () => registerRowOps(subject, applyOps));
1858
+ const refRebuild = shallow && typeof meta.keyed !== "function";
1859
+ const rebuildSlot = i => {
1860
+ runUnbinds(rowUnbinds[i]);
1861
+ const old = entries[i];
1862
+ const node = bindRow(i);
1863
+ rowBodies[i] = lastBodies;
1864
+ rowUnbinds[i] = lastUnbinds;
1865
+ parent.insertBefore(node, old);
1866
+ old.remove();
1867
+ entries[i] = node;
1868
+ };
1869
+ const applySlot = (i, next, prev) => {
1870
+ if (declined) return;
1871
+ if (resyncNeeded) {
1872
+ const live = subject != null ? patchableRaw(subject) : undefined;
1873
+ if (live !== undefined && Array.isArray(live)) applyOps(live, null);
1874
+ return;
1875
+ }
1876
+ if (refRebuild) {
1877
+ rebuildSlot(i);
1878
+ prevRaws[i] = next;
1879
+ return;
1880
+ }
1881
+ const bodies = rowBodies[i];
1882
+ if (bodies !== undefined) {
1883
+ for (let b = 0; b < bodies.length; b++) bodies[b](next, prev, false);
1884
+ }
1885
+ prevRaws[i] = next;
1886
+ };
1887
+ let unbindSlots = shallow ? runWithOwner(listOwner, () => registerSlotPatch(subject, applySlot)) : null;
1888
+ runWithOwner(listOwner, () => effect(() => meta.each(), value => {
1889
+ if (declined || value === subject) return;
1890
+ const nextRaw = value != null ? patchableRaw(value) : undefined;
1891
+ unbindOps();
1892
+ unbindSlots?.();
1893
+ if (nextRaw !== undefined && Array.isArray(nextRaw) && storeIsShallow(value) !== shallow) {
1894
+ for (let j = 0; j < entries.length; j++) entries[j].remove();
1895
+ entries = [];
1896
+ prevRaws = [];
1897
+ unbindAllRows();
1898
+ subject = value;
1899
+ declined = true;
1900
+ listOwner.dispose();
1901
+ lateClassic?.();
1902
+ return;
1903
+ }
1904
+ if (nextRaw === undefined || !Array.isArray(nextRaw)) {
1905
+ for (let j = 0; j < entries.length; j++) entries[j].remove();
1906
+ entries = [];
1907
+ prevRaws = [];
1908
+ unbindAllRows();
1909
+ subject = value;
1910
+ declined = true;
1911
+ listOwner.dispose();
1912
+ lateClassic?.();
1913
+ return;
1914
+ }
1915
+ const swapOps = identityOps(nextRaw);
1916
+ subject = value;
1917
+ unbindOps = runWithOwner(listOwner, () => registerRowOps(subject, applyOps));
1918
+ if (shallow) unbindSlots = runWithOwner(listOwner, () => registerSlotPatch(subject, applySlot));
1919
+ applyOps(nextRaw, swapOps);
1920
+ }));
1921
+ onCleanup(() => {
1922
+ unbindOps();
1923
+ unbindSlots?.();
1924
+ unbindAllRows();
1925
+ listOwner.dispose();
1926
+ });
1927
+ return true;
1928
+ };
1929
+ const patchDriver = (subject, body) => {
1930
+ const raw = patchableRaw(subject);
1931
+ if (raw !== undefined) {
1932
+ if (!sharedConfig.hydrating) body(raw, undefined, true);
1933
+ const unbind = registerPatch(subject, body);
1934
+ if (rowCollector !== null) rowCollector.unbinds.push(unbind);
1935
+ else onCleanup(unbind);
1936
+ } else if (rowCollector !== null && subject === rowCollector.row) {
1937
+ rowCollector.bodies.push(body);
1938
+ if (!sharedConfig.hydrating) body(subject, undefined, true);
1939
+ } else {
1940
+ effect(() => body(subject, subject, false),
1941
+ () => untrack(() => body(subject, undefined, true)));
1942
+ }
1943
+ };
1944
+
1621
1945
  function throwInBrowser(func) {
1622
1946
  const err = new Error(`${func.name} is not supported in the browser, returning undefined`);
1623
1947
  console.error(err);
@@ -1728,7 +2052,8 @@ function redirect(url, init = 302) {
1728
2052
  if (responseInit.status === undefined) {
1729
2053
  responseInit.status = 302;
1730
2054
  }
1731
- headers.set("Location", String(url));
2055
+ const target = typeof url === "string" ? url : url[HREF];
2056
+ headers.set("Location", typeof target === "string" ? target : String(url));
1732
2057
  return new Response(null, {
1733
2058
  ...responseInit,
1734
2059
  headers
@@ -1899,4 +2224,4 @@ _moduleUrl) {
1899
2224
  function httpStatus(_code, _text) {}
1900
2225
  function httpHeader(_name, _value, _options) {}
1901
2226
 
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 };
2227
+ 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, 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 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@solidjs/web",
3
3
  "description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
4
- "version": "2.0.0-rc.3",
4
+ "version": "2.0.0-rc.4",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -398,7 +398,7 @@
398
398
  "seroval-plugins": "~1.5.4"
399
399
  },
400
400
  "peerDependencies": {
401
- "solid-js": "^2.0.0-rc.3"
401
+ "solid-js": "^2.0.0-rc.4"
402
402
  },
403
403
  "devDependencies": {
404
404
  "@codspeed/vitest-plugin": "^5.4.0",