@solidjs/web 2.0.0-rc.0 → 2.0.0-rc.2

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 (40) hide show
  1. package/README.md +1 -1
  2. package/dist/dev.cjs +40 -11
  3. package/dist/dev.js +39 -12
  4. package/dist/server.cjs +419 -69
  5. package/dist/server.js +411 -73
  6. package/dist/web.cjs +37 -11
  7. package/dist/web.js +36 -12
  8. package/frames/dist/client.cjs +94 -8
  9. package/frames/dist/client.dev.cjs +97 -8
  10. package/frames/dist/client.dev.js +98 -9
  11. package/frames/dist/client.js +95 -9
  12. package/frames/dist/server.cjs +266 -56
  13. package/frames/dist/server.js +267 -57
  14. package/package.json +4 -3
  15. package/serialization/dist/decode.cjs +32 -3
  16. package/serialization/dist/decode.js +33 -4
  17. package/serialization/dist/serialization.cjs +32 -3
  18. package/serialization/dist/serialization.js +33 -4
  19. package/server-functions/dist/client.cjs +196 -8
  20. package/server-functions/dist/client.js +195 -9
  21. package/server-functions/dist/server.cjs +201 -36
  22. package/server-functions/dist/server.dev.cjs +201 -36
  23. package/server-functions/dist/server.dev.js +199 -37
  24. package/server-functions/dist/server.js +199 -37
  25. package/types/core.d.ts +3 -0
  26. package/types/frames/frame-client.d.ts +18 -0
  27. package/types/index.d.ts +16 -2
  28. package/types/jsx.d.ts +9 -0
  29. package/types/server-functions/client.d.ts +61 -0
  30. package/types/server-functions/server.d.ts +94 -1
  31. package/types/server-mock.d.ts +11 -2
  32. package/types/server.d.ts +23 -2
  33. package/types-cjs/core.d.cts +3 -0
  34. package/types-cjs/frames/frame-client.d.cts +18 -0
  35. package/types-cjs/index.d.cts +16 -2
  36. package/types-cjs/jsx.d.cts +9 -0
  37. package/types-cjs/server-functions/client.d.cts +61 -0
  38. package/types-cjs/server-functions/server.d.cts +94 -1
  39. package/types-cjs/server-mock.d.cts +11 -2
  40. package/types-cjs/server.d.cts +23 -2
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Solid 2.0's web platform runtime — DOM rendering, hydration, server-side rendering, and the web-only control-flow components (`Portal`, `Dynamic`).
4
4
 
5
- > **Solid 2.0 (experimental beta).** In 1.x this package was the `solid-js/web` subpath; in 2.0 it's a separate `@solidjs/web` package.
5
+ > **Solid 2.0 (Release Candidate).** In 1.x this package was the `solid-js/web` subpath; in 2.0 it's a separate `@solidjs/web` package.
6
6
  >
7
7
  > See [`solid-js`'s CHEATSHEET](https://github.com/solidjs/solid/blob/next/packages/solid/CHEATSHEET.md) and [MIGRATION guide](https://github.com/solidjs/solid/blob/next/documentation/solid-2.0/MIGRATION.md) for the 2.0 surface.
8
8
 
package/dist/dev.cjs CHANGED
@@ -87,13 +87,18 @@ function reconcileArrays(parentNode, a, b, marker) {
87
87
  map = null,
88
88
  anchor,
89
89
  anchorTag;
90
+ const isLive = n => {
91
+ if (!n) return false;
92
+ const tag = n[$$SLOT];
93
+ return n.parentNode === parentNode && (!tag || tag === marker);
94
+ };
90
95
  while (aStart < aEnd || bStart < bEnd) {
91
- if (a[aStart] === b[bStart]) {
96
+ if (a[aStart] === b[bStart] && isLive(a[aStart])) {
92
97
  aStart++;
93
98
  bStart++;
94
99
  continue;
95
100
  }
96
- while (a[aEnd - 1] === b[bEnd - 1]) {
101
+ while (a[aEnd - 1] === b[bEnd - 1] && isLive(a[aEnd - 1])) {
97
102
  aEnd--;
98
103
  bEnd--;
99
104
  }
@@ -592,6 +597,11 @@ function ref(fn, element) {
592
597
  const resolved = solidJs.untrack(fn);
593
598
  solidJs.runWithOwner(null, () => applyRef(resolved, element));
594
599
  }
600
+ const PURE_ROW = Symbol.for("solid.pure-row");
601
+ function rowProof(fn) {
602
+ fn[PURE_ROW] = true;
603
+ return fn;
604
+ }
595
605
  function scope(fn) {
596
606
  fn.$s = true;
597
607
  return fn;
@@ -655,6 +665,11 @@ function stripTextSeparators(nodes) {
655
665
  nodes.length = j;
656
666
  return nodes;
657
667
  }
668
+ function patchDriver(subject, body) {
669
+ {
670
+ effect(() => body(subject, subject, false), () => body(subject, undefined, true));
671
+ }
672
+ }
658
673
  function insert(parent, accessor, marker, initial, options) {
659
674
  const multi = marker !== undefined;
660
675
  const host = options && options.host;
@@ -895,7 +910,7 @@ function initHeadRegistry() {
895
910
  headOwned = new Map();
896
911
  headApplied = new Map();
897
912
  const t = document.querySelector("title");
898
- headFallbackTitle = t && !t.hasAttribute("data-dh") ? t.textContent : null;
913
+ headFallbackTitle = t ? t.hasAttribute("data-dh") ? t.getAttribute("data-dhf") : t.textContent : null;
899
914
  if (globalThis._$HY) globalThis._$HY.h = applyServerHeadOps;
900
915
  }
901
916
  function applyServerHeadOps(ops) {
@@ -950,7 +965,11 @@ function flushHeadRegistry() {
950
965
  headOwned.delete(identity);
951
966
  headApplied.delete(identity);
952
967
  if (identity === "title") {
953
- if (headFallbackTitle != null) setHeadTitle(headFallbackTitle).removeAttribute("data-dh");
968
+ if (headFallbackTitle != null) {
969
+ const el = setHeadTitle(headFallbackTitle);
970
+ el.removeAttribute("data-dh");
971
+ el.removeAttribute("data-dhf");
972
+ }
954
973
  } else {
955
974
  for (let i = 0; i < els.length; i++) els[i].remove();
956
975
  }
@@ -1117,7 +1136,7 @@ function loadModuleAssets(mapping) {
1117
1136
  const pending = [];
1118
1137
  for (const key in mapping) {
1119
1138
  if (hy.modules[key]) continue;
1120
- const entryUrl = mapping[key];
1139
+ const entryUrl = new URL(mapping[key], document.baseURI).href;
1121
1140
  if (!hy.loading[key]) {
1122
1141
  hy.loading[key] = import(entryUrl).then(mod => {
1123
1142
  hy.modules[key] = mod;
@@ -1219,6 +1238,9 @@ function getNextElement(template) {
1219
1238
  if (!template) {
1220
1239
  throw new Error(`Hydration Mismatch. Unable to find DOM nodes for hydration key: ${key}`);
1221
1240
  }
1241
+ if (hydrating) {
1242
+ console.warn(`Hydration key miss for "${key}": no server-rendered element carries this key` + (template._html ? ` (template: ${template._html.slice(0, 60)})` : "") + `. A detached element was created instead; its subtree will not appear in the ` + `document or become interactive. This usually means the server and client ` + `hydration id namespaces are misaligned — when hydrating a subtree of a larger ` + `server render, wrap the document shell in <NoHydration> and re-enter with ` + `<Hydration> around the hydrated subtree (or pass hydrate() a renderId matching ` + `the server's <Hydration id>).`);
1243
+ }
1222
1244
  return template(true);
1223
1245
  }
1224
1246
  if (template && template._html) {
@@ -1422,6 +1444,7 @@ function eventHandler(e, container, state) {
1422
1444
  }
1423
1445
  const owner = state && (state.owners.size === 1 && state.owners.has(container) ? container : findOwner(e.target, state)?.owner);
1424
1446
  if (state && !owner) return;
1447
+ if (owner && owner === resumeNode) return;
1425
1448
  e[$$EVENT_OWNER] = owner || true;
1426
1449
  let node = resumeNode || e.target;
1427
1450
  const key = `$$${e.type}`;
@@ -1432,7 +1455,11 @@ function eventHandler(e, container, state) {
1432
1455
  value
1433
1456
  });
1434
1457
  const handleNode = () => {
1435
- const handler = node[key];
1458
+ let handler = node[key];
1459
+ if (handler === undefined && node.hasAttribute && node.hasAttribute("_bnd")) {
1460
+ const seam = globalThis[Symbol.for("dx.bnd")];
1461
+ if (seam) handler = seam.resolve(node, e.type);
1462
+ }
1436
1463
  if (handler && !node.disabled) {
1437
1464
  const data = node[`${key}Data`];
1438
1465
  data !== undefined ? handler.call(node, data, e) : handler.call(node, e);
@@ -1442,7 +1469,7 @@ function eventHandler(e, container, state) {
1442
1469
  return true;
1443
1470
  };
1444
1471
  const walkUpTree = () => {
1445
- while (handleNode()) {
1472
+ while (node && handleNode()) {
1446
1473
  if (node === boundary || node.parentNode === boundary) break;
1447
1474
  node = node._$host || node.parentNode || node.host;
1448
1475
  }
@@ -1894,21 +1921,21 @@ function createElement(tagName, is = undefined) {
1894
1921
  is
1895
1922
  });
1896
1923
  }
1897
- function loadClientOnly(fn, setComp) {
1898
- fn().then(m => setComp(() => m.default));
1924
+ function loadClientOnly(fn, setComp, exportName) {
1925
+ fn().then(m => setComp(() => exportName ? m[exportName] : m.default));
1899
1926
  }
1900
1927
  function clientOnly(fn, options = {},
1901
1928
  _moduleUrl) {
1902
1929
  const [comp, setComp] = solidJs.createSignal();
1903
1930
  let started = !options.lazy;
1904
- started && loadClientOnly(fn, setComp);
1931
+ started && loadClientOnly(fn, setComp, options.export);
1905
1932
  return props => {
1906
1933
  let Comp;
1907
1934
  let m;
1908
1935
  const rest = solidJs.omit(props, "fallback");
1909
1936
  if (!started) {
1910
1937
  started = true;
1911
- loadClientOnly(fn, setComp);
1938
+ loadClientOnly(fn, setComp, options.export);
1912
1939
  }
1913
1940
  if ((Comp = solidJs.untrack(comp)) && !solidJs.sharedConfig.hydrating) return Comp(rest);
1914
1941
  const [mounted, setMounted] = solidJs.createSignal(!solidJs.sharedConfig.hydrating);
@@ -2038,6 +2065,7 @@ exports.markSafeError = markSafeError;
2038
2065
  exports.memo = memo;
2039
2066
  exports.mergeProps = mergeProps;
2040
2067
  exports.parseCookieHeader = parseCookieHeader;
2068
+ exports.patchDriver = patchDriver;
2041
2069
  exports.redirect = redirect;
2042
2070
  exports.ref = ref;
2043
2071
  exports.registerDelegatedContainer = registerDelegatedContainer;
@@ -2049,6 +2077,7 @@ exports.renderToStream = renderToStream;
2049
2077
  exports.renderToString = renderToString;
2050
2078
  exports.resolveSSRNode = resolveSSRNode;
2051
2079
  exports.respond = respond;
2080
+ exports.rowProof = rowProof;
2052
2081
  exports.runHydrationEvents = runHydrationEvents;
2053
2082
  exports.scope = scope;
2054
2083
  exports.serializeCookie = serializeCookie;
package/dist/dev.js CHANGED
@@ -86,13 +86,18 @@ function reconcileArrays(parentNode, a, b, marker) {
86
86
  map = null,
87
87
  anchor,
88
88
  anchorTag;
89
+ const isLive = n => {
90
+ if (!n) return false;
91
+ const tag = n[$$SLOT];
92
+ return n.parentNode === parentNode && (!tag || tag === marker);
93
+ };
89
94
  while (aStart < aEnd || bStart < bEnd) {
90
- if (a[aStart] === b[bStart]) {
95
+ if (a[aStart] === b[bStart] && isLive(a[aStart])) {
91
96
  aStart++;
92
97
  bStart++;
93
98
  continue;
94
99
  }
95
- while (a[aEnd - 1] === b[bEnd - 1]) {
100
+ while (a[aEnd - 1] === b[bEnd - 1] && isLive(a[aEnd - 1])) {
96
101
  aEnd--;
97
102
  bEnd--;
98
103
  }
@@ -591,6 +596,11 @@ function ref(fn, element) {
591
596
  const resolved = untrack(fn);
592
597
  runWithOwner(null, () => applyRef(resolved, element));
593
598
  }
599
+ const PURE_ROW = Symbol.for("solid.pure-row");
600
+ function rowProof(fn) {
601
+ fn[PURE_ROW] = true;
602
+ return fn;
603
+ }
594
604
  function scope(fn) {
595
605
  fn.$s = true;
596
606
  return fn;
@@ -654,6 +664,11 @@ function stripTextSeparators(nodes) {
654
664
  nodes.length = j;
655
665
  return nodes;
656
666
  }
667
+ function patchDriver(subject, body) {
668
+ {
669
+ effect(() => body(subject, subject, false), () => body(subject, undefined, true));
670
+ }
671
+ }
657
672
  function insert(parent, accessor, marker, initial, options) {
658
673
  const multi = marker !== undefined;
659
674
  const host = options && options.host;
@@ -894,7 +909,7 @@ function initHeadRegistry() {
894
909
  headOwned = new Map();
895
910
  headApplied = new Map();
896
911
  const t = document.querySelector("title");
897
- headFallbackTitle = t && !t.hasAttribute("data-dh") ? t.textContent : null;
912
+ headFallbackTitle = t ? t.hasAttribute("data-dh") ? t.getAttribute("data-dhf") : t.textContent : null;
898
913
  if (globalThis._$HY) globalThis._$HY.h = applyServerHeadOps;
899
914
  }
900
915
  function applyServerHeadOps(ops) {
@@ -949,7 +964,11 @@ function flushHeadRegistry() {
949
964
  headOwned.delete(identity);
950
965
  headApplied.delete(identity);
951
966
  if (identity === "title") {
952
- if (headFallbackTitle != null) setHeadTitle(headFallbackTitle).removeAttribute("data-dh");
967
+ if (headFallbackTitle != null) {
968
+ const el = setHeadTitle(headFallbackTitle);
969
+ el.removeAttribute("data-dh");
970
+ el.removeAttribute("data-dhf");
971
+ }
953
972
  } else {
954
973
  for (let i = 0; i < els.length; i++) els[i].remove();
955
974
  }
@@ -1116,7 +1135,7 @@ function loadModuleAssets(mapping) {
1116
1135
  const pending = [];
1117
1136
  for (const key in mapping) {
1118
1137
  if (hy.modules[key]) continue;
1119
- const entryUrl = mapping[key];
1138
+ const entryUrl = new URL(mapping[key], document.baseURI).href;
1120
1139
  if (!hy.loading[key]) {
1121
1140
  hy.loading[key] = import(entryUrl).then(mod => {
1122
1141
  hy.modules[key] = mod;
@@ -1218,6 +1237,9 @@ function getNextElement(template) {
1218
1237
  if (!template) {
1219
1238
  throw new Error(`Hydration Mismatch. Unable to find DOM nodes for hydration key: ${key}`);
1220
1239
  }
1240
+ if (hydrating) {
1241
+ console.warn(`Hydration key miss for "${key}": no server-rendered element carries this key` + (template._html ? ` (template: ${template._html.slice(0, 60)})` : "") + `. A detached element was created instead; its subtree will not appear in the ` + `document or become interactive. This usually means the server and client ` + `hydration id namespaces are misaligned — when hydrating a subtree of a larger ` + `server render, wrap the document shell in <NoHydration> and re-enter with ` + `<Hydration> around the hydrated subtree (or pass hydrate() a renderId matching ` + `the server's <Hydration id>).`);
1242
+ }
1221
1243
  return template(true);
1222
1244
  }
1223
1245
  if (template && template._html) {
@@ -1421,6 +1443,7 @@ function eventHandler(e, container, state) {
1421
1443
  }
1422
1444
  const owner = state && (state.owners.size === 1 && state.owners.has(container) ? container : findOwner(e.target, state)?.owner);
1423
1445
  if (state && !owner) return;
1446
+ if (owner && owner === resumeNode) return;
1424
1447
  e[$$EVENT_OWNER] = owner || true;
1425
1448
  let node = resumeNode || e.target;
1426
1449
  const key = `$$${e.type}`;
@@ -1431,7 +1454,11 @@ function eventHandler(e, container, state) {
1431
1454
  value
1432
1455
  });
1433
1456
  const handleNode = () => {
1434
- const handler = node[key];
1457
+ let handler = node[key];
1458
+ if (handler === undefined && node.hasAttribute && node.hasAttribute("_bnd")) {
1459
+ const seam = globalThis[Symbol.for("dx.bnd")];
1460
+ if (seam) handler = seam.resolve(node, e.type);
1461
+ }
1435
1462
  if (handler && !node.disabled) {
1436
1463
  const data = node[`${key}Data`];
1437
1464
  data !== undefined ? handler.call(node, data, e) : handler.call(node, e);
@@ -1441,7 +1468,7 @@ function eventHandler(e, container, state) {
1441
1468
  return true;
1442
1469
  };
1443
1470
  const walkUpTree = () => {
1444
- while (handleNode()) {
1471
+ while (node && handleNode()) {
1445
1472
  if (node === boundary || node.parentNode === boundary) break;
1446
1473
  node = node._$host || node.parentNode || node.host;
1447
1474
  }
@@ -1893,21 +1920,21 @@ function createElement(tagName, is = undefined) {
1893
1920
  is
1894
1921
  });
1895
1922
  }
1896
- function loadClientOnly(fn, setComp) {
1897
- fn().then(m => setComp(() => m.default));
1923
+ function loadClientOnly(fn, setComp, exportName) {
1924
+ fn().then(m => setComp(() => exportName ? m[exportName] : m.default));
1898
1925
  }
1899
1926
  function clientOnly(fn, options = {},
1900
1927
  _moduleUrl) {
1901
1928
  const [comp, setComp] = createSignal();
1902
1929
  let started = !options.lazy;
1903
- started && loadClientOnly(fn, setComp);
1930
+ started && loadClientOnly(fn, setComp, options.export);
1904
1931
  return props => {
1905
1932
  let Comp;
1906
1933
  let m;
1907
1934
  const rest = omit(props, "fallback");
1908
1935
  if (!started) {
1909
1936
  started = true;
1910
- loadClientOnly(fn, setComp);
1937
+ loadClientOnly(fn, setComp, options.export);
1911
1938
  }
1912
1939
  if ((Comp = untrack(comp)) && !sharedConfig.hydrating) return Comp(rest);
1913
1940
  const [mounted, setMounted] = createSignal(!sharedConfig.hydrating);
@@ -1921,4 +1948,4 @@ _moduleUrl) {
1921
1948
  function httpStatus(_code, _text) {}
1922
1949
  function httpHeader(_name, _value, _options) {}
1923
1950
 
1924
- export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as 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, voidFn as generateHydrationScript, getDelegatedRoot, getExpectedRedirectStatus, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, mergeProps, parseCookieHeader, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, resolveSSRNode, respond, runHydrationEvents, scope, serializeCookie, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, useHead, warmAsset };
1951
+ export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as 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, voidFn as generateHydrationScript, getDelegatedRoot, getExpectedRedirectStatus, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, mergeProps, 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, warmAsset };