@solidjs/web 2.0.0-beta.30 → 2.0.0-beta.32

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 (66) hide show
  1. package/README.md +1 -6
  2. package/dist/dev.cjs +284 -82
  3. package/dist/dev.js +271 -79
  4. package/dist/server.cjs +555 -135
  5. package/dist/server.js +544 -132
  6. package/dist/web.cjs +281 -79
  7. package/dist/web.js +268 -76
  8. package/frames/dist/client.cjs +413 -360
  9. package/frames/dist/client.dev.cjs +413 -360
  10. package/frames/dist/client.dev.js +414 -361
  11. package/frames/dist/client.js +414 -361
  12. package/frames/dist/server.cjs +604 -199
  13. package/frames/dist/server.js +605 -201
  14. package/package.json +56 -6
  15. package/serialization/dist/serialization.cjs +8 -0
  16. package/serialization/dist/serialization.js +1 -0
  17. package/serialization/types/index.d.ts +173 -6
  18. package/serialization/types-cjs/index.d.cts +173 -6
  19. package/server-functions/dist/client.cjs +46 -9
  20. package/server-functions/dist/client.js +47 -11
  21. package/server-functions/dist/rich-args.cjs +11 -0
  22. package/server-functions/dist/rich-args.js +9 -0
  23. package/server-functions/dist/server.cjs +275 -126
  24. package/server-functions/dist/server.dev.cjs +1053 -0
  25. package/server-functions/dist/server.dev.js +1021 -0
  26. package/server-functions/dist/server.js +273 -127
  27. package/server-functions/package.json +10 -0
  28. package/server-functions/rich-args/package.json +20 -0
  29. package/storage/types/index.d.ts +1 -1
  30. package/storage/types-cjs/index.d.cts +1 -1
  31. package/types/client.d.ts +134 -11
  32. package/types/core.d.ts +3 -1
  33. package/types/frames/client.d.ts +24 -8
  34. package/types/frames/frame-client.d.ts +49 -7
  35. package/types/frames/frame-sink.d.ts +32 -6
  36. package/types/frames/frame-transport.d.ts +88 -62
  37. package/types/frames/serializer.d.ts +173 -6
  38. package/types/frames/server.d.ts +22 -0
  39. package/types/index.d.ts +2 -3
  40. package/types/jsx.d.ts +3 -3
  41. package/types/response.d.ts +45 -0
  42. package/types/serializer.d.ts +173 -6
  43. package/types/server-functions/client.d.ts +1 -0
  44. package/types/server-functions/rich-args.d.ts +10 -0
  45. package/types/server-functions/server.d.ts +98 -0
  46. package/types/server-functions/shared.d.ts +22 -0
  47. package/types/server-mock.d.ts +171 -59
  48. package/types/server.d.ts +196 -42
  49. package/types-cjs/client.d.cts +134 -11
  50. package/types-cjs/core.d.cts +3 -1
  51. package/types-cjs/frames/client.d.cts +24 -8
  52. package/types-cjs/frames/frame-client.d.cts +49 -7
  53. package/types-cjs/frames/frame-sink.d.cts +32 -6
  54. package/types-cjs/frames/frame-transport.d.cts +88 -62
  55. package/types-cjs/frames/serializer.d.cts +173 -6
  56. package/types-cjs/frames/server.d.cts +22 -0
  57. package/types-cjs/index.d.cts +2 -3
  58. package/types-cjs/jsx.d.cts +3 -3
  59. package/types-cjs/response.d.cts +45 -0
  60. package/types-cjs/serializer.d.cts +173 -6
  61. package/types-cjs/server-functions/client.d.cts +1 -0
  62. package/types-cjs/server-functions/rich-args.d.cts +10 -0
  63. package/types-cjs/server-functions/server.d.cts +98 -0
  64. package/types-cjs/server-functions/shared.d.cts +22 -0
  65. package/types-cjs/server-mock.d.cts +171 -59
  66. package/types-cjs/server.d.cts +196 -42
package/dist/dev.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createRenderEffect, createMemo, sharedConfig, untrack, runWithOwner, flatten, createRoot, merge, createComponent, omit, createOwner, createSignal, onSettled, $DEVCOMP, enableHydration, enforceLoadingBoundary, flush, getOwner, createEffect } from 'solid-js';
1
+ import { createRenderEffect, createMemo, runWithOwner, sharedConfig, untrack, flatten, createRoot, merge, createComponent, omit, createOwner, createSignal, $DEVCOMP, onCleanup, enableHydration, enforceLoadingBoundary, flush, getOwner, createEffect } from 'solid-js';
2
2
  export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, untrack } from 'solid-js';
3
3
 
4
4
  const DOMWithState = {
@@ -62,6 +62,17 @@ const effect = (fn, effectFn, options) => createRenderEffect(fn, effectFn, optio
62
62
  transparent: !options.scope
63
63
  } : transparentOptions);
64
64
  const memo = fn => createMemo(() => fn(), syncOptions);
65
+ const assetGates = new WeakMap();
66
+ const waitAsset = promise => {
67
+ let gate = assetGates.get(promise);
68
+ if (!gate) {
69
+ runWithOwner(null, () => {
70
+ gate = createMemo(() => promise);
71
+ });
72
+ assetGates.set(promise, gate);
73
+ }
74
+ gate();
75
+ };
65
76
 
66
77
  function reconcileArrays(parentNode, a, b, marker) {
67
78
  let bLength = b.length,
@@ -171,8 +182,9 @@ function reconcileArrays(parentNode, a, b, marker) {
171
182
 
172
183
  const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
173
184
  const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
174
- const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "icon", "stylesheet"]);
185
+ const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "stylesheet"]);
175
186
  const RESOURCE_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
187
+ const STYLESHEET_FETCH_META = new Set(["crossorigin", "integrity", "referrerpolicy", "fetchpriority"]);
176
188
  function evalHeadValue(v) {
177
189
  return typeof v === "function" ? v() : v;
178
190
  }
@@ -214,12 +226,14 @@ function replaceableIdentity(tag, props, key, unique) {
214
226
  if (tag === "meta" && props.charset != null) return "charset";
215
227
  if (key != null) return tag + ":key:" + key;
216
228
  if (tag === "meta") {
217
- if (props.name != null) return "meta:name:" + props.name;
218
- if (props.property != null) return "meta:property:" + props.property;
219
- if (props["http-equiv"] != null) return "meta:http-equiv:" + props["http-equiv"];
229
+ for (const ns of ["name", "property", "http-equiv"]) if (props[ns] != null) return "meta:" + ns + ":" + props[ns] + (props.media != null ? ":media=" + props.media : "");
220
230
  return unique;
221
231
  }
222
- if (tag === "link") return "link:" + (props.rel || "") + ":" + (props.href || "");
232
+ if (tag === "link") {
233
+ const rel = props.rel || "";
234
+ if (rel === "icon" || rel === "apple-touch-icon") return "link:" + rel + (props.sizes != null ? ":sizes=" + props.sizes : "") + (props.type != null ? ":type=" + props.type : "");
235
+ return "link:" + rel + ":" + (props.href || "");
236
+ }
223
237
  return unique;
224
238
  }
225
239
  function resolveHead(groups) {
@@ -252,6 +266,43 @@ function resolveHead(groups) {
252
266
  return winners;
253
267
  }
254
268
 
269
+ function parseCookieHeader(header) {
270
+ const cookies = {};
271
+ if (!header) return cookies;
272
+ for (const part of header.split(";")) {
273
+ const eq = part.indexOf("=");
274
+ if (eq < 0) continue;
275
+ const name = decodeSafe(part.slice(0, eq).trim());
276
+ let value = part.slice(eq + 1).trim();
277
+ if (value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
278
+ value = value.slice(1, -1);
279
+ }
280
+ cookies[name] = decodeSafe(value);
281
+ }
282
+ return cookies;
283
+ }
284
+ function decodeSafe(text) {
285
+ try {
286
+ return decodeURIComponent(text);
287
+ } catch {
288
+ return text;
289
+ }
290
+ }
291
+ function serializeCookie(name, value, options = {}) {
292
+ let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
293
+ cookie += `; Path=${options.path === undefined ? "/" : options.path}`;
294
+ if (options.domain) cookie += `; Domain=${options.domain}`;
295
+ if (options.maxAge !== undefined) cookie += `; Max-Age=${Math.trunc(options.maxAge)}`;
296
+ if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
297
+ if (options.httpOnly) cookie += "; HttpOnly";
298
+ if (options.secure) cookie += "; Secure";
299
+ if (options.sameSite) {
300
+ const sameSite = options.sameSite.toLowerCase();
301
+ cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
302
+ }
303
+ return cookie;
304
+ }
305
+
255
306
  const $$EVENT_OWNER = "_$DX_EVENT_OWNER";
256
307
  const INNER_OWNED = {};
257
308
  const delegatedEvents = new Set();
@@ -655,6 +706,9 @@ function findAssetElement(selector, attr, value) {
655
706
  }
656
707
  return null;
657
708
  }
709
+ function setAssetAttrs(el, attrs) {
710
+ for (const name in attrs) el.setAttribute(name, attrs[name]);
711
+ }
658
712
  function mountAssetElement(descriptor) {
659
713
  let el;
660
714
  if (descriptor.type === "inline-style") {
@@ -673,12 +727,77 @@ function mountAssetElement(descriptor) {
673
727
  el.href = descriptor.href;
674
728
  }
675
729
  }
676
- if (descriptor.attrs) {
677
- for (const name in descriptor.attrs) el.setAttribute(name, descriptor.attrs[name]);
678
- }
730
+ if (descriptor.attrs) setAssetAttrs(el, descriptor.attrs);
679
731
  if (!el.isConnected) document.head.appendChild(el);
680
732
  return el;
681
733
  }
734
+ const assetLoadSettled = /*#__PURE__*/Promise.resolve();
735
+ function trackAssetLoad(entry, adopted) {
736
+ if (entry.loadPromise) return;
737
+ const el = entry.element;
738
+ let settled = el.sheet != null;
739
+ if (!settled && adopted && typeof performance !== "undefined" && performance.getEntriesByName) {
740
+ settled = performance.getEntriesByName(el.href).length > 0;
741
+ }
742
+ if (settled) {
743
+ entry.loadState = "loaded";
744
+ entry.loadPromise = assetLoadSettled;
745
+ return;
746
+ }
747
+ entry.loadState = "pending";
748
+ entry.loadPromise = new Promise(resolve => {
749
+ const settle = state => {
750
+ entry.loadState = state;
751
+ resolve();
752
+ };
753
+ el.addEventListener("load", () => settle("loaded"), {
754
+ once: true
755
+ });
756
+ el.addEventListener("error", () => settle("errored"), {
757
+ once: true
758
+ });
759
+ });
760
+ }
761
+ function warmAsset(descriptor) {
762
+ if (descriptor.policy === "exclusive" || descriptor.type === "inline-style") return;
763
+ const key = assetEntryKey(descriptor);
764
+ let entry = assetRegistry.get(key);
765
+ if (!entry) {
766
+ entry = {
767
+ count: 0,
768
+ element: null,
769
+ timer: null
770
+ };
771
+ assetRegistry.set(key, entry);
772
+ }
773
+ let adopted = true;
774
+ if (!entry.element || !entry.element.isConnected) {
775
+ const rel = descriptor.type === "module" ? "modulepreload" : "stylesheet";
776
+ let el = findAssetElement(`link[rel="${rel}"]`, "href", descriptor.href);
777
+ if (!el && descriptor.type === "style") {
778
+ el = findAssetElement('link[rel="preload"][as="style"]', "href", descriptor.href);
779
+ }
780
+ if (!el) {
781
+ adopted = false;
782
+ el = document.createElement("link");
783
+ if (descriptor.type === "style") {
784
+ el.setAttribute("rel", "preload");
785
+ el.setAttribute("as", "style");
786
+ } else {
787
+ el.setAttribute("rel", "modulepreload");
788
+ }
789
+ el.setAttribute("href", descriptor.href);
790
+ if (!document.body) el.setAttribute("blocking", "render");
791
+ }
792
+ if (descriptor.attrs) setAssetAttrs(el, descriptor.attrs);
793
+ if (!el.isConnected) document.head.appendChild(el);
794
+ entry.element = el;
795
+ entry.loadState = undefined;
796
+ entry.loadPromise = undefined;
797
+ }
798
+ if (descriptor.type === "style") trackAssetLoad(entry, adopted);
799
+ return entry;
800
+ }
682
801
  function acquireAsset(descriptor) {
683
802
  const key = assetEntryKey(descriptor);
684
803
  let entry = assetRegistry.get(key);
@@ -725,7 +844,12 @@ function acquireAsset(descriptor) {
725
844
  entry.timer = null;
726
845
  }
727
846
  entry.count++;
728
- if (!entry.element || !entry.element.isConnected) entry.element = mountAssetElement(descriptor);
847
+ if (!entry.element || !entry.element.isConnected) {
848
+ entry.element = mountAssetElement(descriptor);
849
+ } else if (descriptor.type === "style" && entry.element.getAttribute("rel") === "preload") {
850
+ entry.element.removeAttribute("as");
851
+ entry.element.setAttribute("rel", "stylesheet");
852
+ }
729
853
  let released = false;
730
854
  return () => {
731
855
  if (released) return;
@@ -837,22 +961,26 @@ function flushHeadRegistry() {
837
961
  headOwned.set(identity, els);
838
962
  }
839
963
  }
840
- function renderHeadElement(t, identity, existing) {
841
- for (let i = 0; i < existing.length; i++) {
842
- if (headElementMatches(existing[i], t)) return existing.splice(i, 1)[0];
843
- }
844
- const el = document.createElement(t.tag);
845
- for (const name in t.props) {
964
+ function createHeadElement(tag, props) {
965
+ const el = document.createElement(tag);
966
+ for (const name in props) {
846
967
  if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
847
968
  if (!HEAD_ATTR_NAME.test(name)) {
848
969
  console.warn(`useHead: ignoring invalid attribute name "${name}"`);
849
970
  continue;
850
971
  }
851
- const v = t.props[name];
972
+ const v = props[name];
852
973
  if (v == null || v === false) continue;
853
974
  el.setAttribute(name, v === true ? "" : String(v));
854
975
  }
855
- if (t.props.children != null) el.textContent = String(t.props.children);
976
+ if (props.children != null) el.textContent = String(props.children);
977
+ return el;
978
+ }
979
+ function renderHeadElement(t, identity, existing) {
980
+ for (let i = 0; i < existing.length; i++) {
981
+ if (headElementMatches(existing[i], t)) return existing.splice(i, 1)[0];
982
+ }
983
+ const el = createHeadElement(t.tag, t.props);
856
984
  el.setAttribute("data-dh", identity);
857
985
  document.head.appendChild(el);
858
986
  return el;
@@ -870,48 +998,39 @@ function headElementMatches(el, t) {
870
998
  const children = t.props.children;
871
999
  return (children == null ? "" : String(children)) === el.textContent;
872
1000
  }
873
- function acquireHeadResource(tag, props) {
874
- if (tag === "link" && (props.rel === "stylesheet" || props.rel === "modulepreload")) {
875
- const descriptor = {
876
- type: props.rel === "stylesheet" ? "style" : "module",
877
- href: props.href
878
- };
879
- let attrs = null;
880
- for (const name in props) {
881
- if (name === "rel" || name === "href") continue;
882
- if (!HEAD_ATTR_NAME.test(name)) continue;
883
- const v = props[name];
884
- if (v == null || v === false) continue;
885
- (attrs || (attrs = {}))[name] = v === true ? "" : String(v);
886
- }
887
- if (attrs) descriptor.attrs = attrs;
888
- return acquireAsset(descriptor);
889
- }
1001
+ function mountHeadResource(tag, props) {
890
1002
  const identity = resourceIdentity(tag, props);
891
- if (headMountedResources.has(identity)) return noopFn;
1003
+ if (headMountedResources.has(identity)) return;
892
1004
  headMountedResources.add(identity);
893
1005
  const url = props.href || props.src;
894
1006
  let el = null;
895
1007
  if (url != null) {
896
1008
  if (tag === "link") el = findAssetElement(`link[rel="${props.rel}"]`, "href", url);else if (tag === "script") el = findAssetElement("script[src]", "src", url);else el = findAssetElement("style[href]", "href", url);
897
1009
  }
898
- if (!el) {
899
- el = document.createElement(tag);
900
- for (const name in props) {
901
- if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
902
- if (!HEAD_ATTR_NAME.test(name)) continue;
903
- const v = props[name];
904
- if (v == null || v === false) continue;
905
- el.setAttribute(name, v === true ? "" : String(v));
906
- }
907
- if (props.children != null) el.textContent = String(props.children);
908
- document.head.appendChild(el);
1010
+ if (!el) document.head.appendChild(createHeadElement(tag, props));
1011
+ }
1012
+ function gateHeadResource(props) {
1013
+ const descriptor = {
1014
+ type: props.rel === "stylesheet" ? "style" : "module",
1015
+ href: props.href
1016
+ };
1017
+ let gateable = props.rel === "stylesheet" && props.href != null;
1018
+ let attrs = null;
1019
+ for (const name in props) {
1020
+ if (name === "rel" || name === "href") continue;
1021
+ if (!STYLESHEET_FETCH_META.has(name)) gateable = false;
1022
+ if (!HEAD_ATTR_NAME.test(name)) continue;
1023
+ const v = props[name];
1024
+ if (v == null || v === false) continue;
1025
+ (attrs || (attrs = {}))[name] = v === true ? "" : String(v);
909
1026
  }
910
- return noopFn;
1027
+ if (attrs) descriptor.attrs = attrs;
1028
+ effect(() => {
1029
+ const entry = warmAsset(descriptor);
1030
+ if (gateable && entry.loadState === "pending" && typeof waitAsset === "function") waitAsset(entry.loadPromise);
1031
+ }, () => acquireAsset(descriptor));
911
1032
  }
912
- function noopFn() {}
913
1033
  function useHead(tags) {
914
- const list = Array.isArray(tags) ? tags : [tags];
915
1034
  initHeadRegistry();
916
1035
  const reg = {
917
1036
  seq: -1,
@@ -919,6 +1038,8 @@ function useHead(tags) {
919
1038
  };
920
1039
  const uid = ++headUid;
921
1040
  effect(() => {
1041
+ let list = typeof tags === "function" ? tags() : tags;
1042
+ if (!Array.isArray(list)) list = [list];
922
1043
  const replaceable = [];
923
1044
  const resources = [];
924
1045
  for (let i = 0; i < list.length; i++) {
@@ -932,10 +1053,16 @@ function useHead(tags) {
932
1053
  rel: cls.rel
933
1054
  } : undefined);
934
1055
  if (cls.resource) {
935
- resources.push({
936
- tag: desc.tag,
937
- props
938
- });
1056
+ if (desc.tag === "link" && (props.rel === "stylesheet" || props.rel === "modulepreload")) {
1057
+ gateHeadResource(props);
1058
+ } else if (desc.tag === "link") {
1059
+ mountHeadResource(desc.tag, props);
1060
+ } else {
1061
+ resources.push({
1062
+ tag: desc.tag,
1063
+ props
1064
+ });
1065
+ }
939
1066
  } else {
940
1067
  const key = evalHeadValue(desc.key);
941
1068
  replaceable.push({
@@ -950,9 +1077,8 @@ function useHead(tags) {
950
1077
  resources
951
1078
  };
952
1079
  }, evaluated => {
953
- const releases = [];
954
1080
  for (let i = 0; i < evaluated.resources.length; i++) {
955
- releases.push(acquireHeadResource(evaluated.resources[i].tag, evaluated.resources[i].props));
1081
+ mountHeadResource(evaluated.resources[i].tag, evaluated.resources[i].props);
956
1082
  }
957
1083
  reg.tags = evaluated.replaceable;
958
1084
  if (reg.seq < 0) reg.seq = ++headSeq;
@@ -961,7 +1087,6 @@ function useHead(tags) {
961
1087
  return () => {
962
1088
  const idx = headRegistrations.indexOf(reg);
963
1089
  if (idx > -1) headRegistrations.splice(idx, 1);
964
- for (let i = 0; i < releases.length; i++) releases[i]();
965
1090
  scheduleHeadApply();
966
1091
  };
967
1092
  });
@@ -1449,7 +1574,13 @@ function gatherHydratable(element, root) {
1449
1574
  for (let i = 0; i < templates.length; i++) {
1450
1575
  const node = templates[i];
1451
1576
  const key = node.getAttribute("_hk");
1452
- if ((!root || key.startsWith(root)) && !sharedConfig.registry.has(key)) sharedConfig.registry.set(key, node);
1577
+ if (root) {
1578
+ if (!key.startsWith(root)) continue;
1579
+ } else {
1580
+ const frame = node.closest("[data-fid]");
1581
+ if (frame && frame !== element && element.contains(frame)) continue;
1582
+ }
1583
+ if (!sharedConfig.registry.has(key)) sharedConfig.registry.set(key, node);
1453
1584
  }
1454
1585
  }
1455
1586
  function getHydrationKey() {
@@ -1465,20 +1596,37 @@ function throwInBrowser(func) {
1465
1596
  function renderToString(fn, options) {
1466
1597
  throwInBrowser(renderToString);
1467
1598
  }
1468
- function renderToStringAsync(fn, options) {
1469
- throwInBrowser(renderToStringAsync);
1470
- }
1471
1599
  function renderToStream(fn, options) {
1472
1600
  throwInBrowser(renderToStream);
1473
1601
  }
1602
+ function createResponseStub() {
1603
+ throwInBrowser(createResponseStub);
1604
+ }
1605
+ function createRequestEvent(request, init) {
1606
+ throwInBrowser(createRequestEvent);
1607
+ }
1608
+ function getExpectedRedirectStatus(response) {
1609
+ throwInBrowser(getExpectedRedirectStatus);
1610
+ }
1611
+ function createSSRResponse() {
1612
+ throwInBrowser(createSSRResponse);
1613
+ }
1614
+ function commitEventResponse(response, event) {
1615
+ throwInBrowser(commitEventResponse);
1616
+ }
1617
+ function composeMiddleware(middlewares) {
1618
+ throwInBrowser(composeMiddleware);
1619
+ }
1474
1620
  function ssr(template, ...nodes) {}
1475
1621
  function ssrElement(name, props, children, needsId) {}
1476
- function ssrClassList(value) {}
1622
+ function ssrClassName(value) {}
1477
1623
  function ssrStyle(value) {}
1624
+ function ssrStyleProperty(name, value) {}
1478
1625
  function ssrAttribute(key, value) {}
1626
+ function ssrGroup(fn, n) {}
1479
1627
  function ssrHydrationKey() {}
1480
- function resolveSSRNode(node) {}
1481
- function escape(html) {}
1628
+ function resolveSSRNode(node, result, top) {}
1629
+ function escape(s, attr) {}
1482
1630
 
1483
1631
  const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
1484
1632
  class ResponseEnvelope {
@@ -1495,13 +1643,38 @@ const HREF = Symbol.for("solid.Href");
1495
1643
  function isHref(value) {
1496
1644
  return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
1497
1645
  }
1646
+ const SAFE_ERROR = Symbol.for("solid.SafeError");
1647
+ function markSafeError(error) {
1648
+ if (error && (typeof error === "object" || typeof error === "function")) {
1649
+ Object.defineProperty(error, SAFE_ERROR, {
1650
+ value: true,
1651
+ enumerable: false,
1652
+ configurable: true
1653
+ });
1654
+ }
1655
+ return error;
1656
+ }
1657
+ function isSafeError(value) {
1658
+ return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
1659
+ }
1498
1660
  const REVALIDATE_HEADER = "X-Revalidate";
1499
1661
  function initWithRevalidate(init) {
1500
1662
  const {
1501
1663
  revalidate,
1502
1664
  ...responseInit
1503
1665
  } = init;
1504
- const headers = new Headers(responseInit.headers);
1666
+ let headers;
1667
+ if (responseInit.headers && responseInit.headers.getSetCookie) {
1668
+ headers = new Headers();
1669
+ responseInit.headers.forEach((value, key) => {
1670
+ if (key !== "set-cookie") headers.append(key, value);
1671
+ });
1672
+ for (const cookie of responseInit.headers.getSetCookie()) {
1673
+ headers.append("Set-Cookie", cookie);
1674
+ }
1675
+ } else {
1676
+ headers = new Headers(responseInit.headers);
1677
+ }
1505
1678
  revalidate !== undefined && headers.set(REVALIDATE_HEADER, revalidate.toString());
1506
1679
  return {
1507
1680
  responseInit,
@@ -1621,19 +1794,31 @@ function portalImpl(props) {
1621
1794
  });
1622
1795
  return treeMarker;
1623
1796
  }
1624
- const COMPONENT_HANDOFF = Symbol.for("dom-expressions.component-handoff");
1625
- function resolveHandoff(next, prev) {
1626
- const handoff = typeof next === "function" && next !== null && next[COMPONENT_HANDOFF];
1627
- return handoff && handoff.take(prev) ? prev : next;
1797
+ const COMPONENT_BINDING = Symbol.for("dom-expressions.component-binding");
1798
+ function bindingOf(value) {
1799
+ return value !== null && (typeof value === "function" || typeof value === "object") && value[COMPONENT_BINDING] || undefined;
1628
1800
  }
1629
1801
  function dynamic(source) {
1630
1802
  let latest = 0;
1803
+ const sites = new Set();
1804
+ let deliveredAddress;
1805
+ const resolveBinding = (next, prev) => {
1806
+ const binding = bindingOf(next);
1807
+ if (!binding) return next;
1808
+ deliveredAddress = binding.address;
1809
+ const prevBinding = bindingOf(prev);
1810
+ if (prevBinding && prevBinding.component === binding.component) {
1811
+ for (const deliver of sites) deliver(binding.address);
1812
+ return prev;
1813
+ }
1814
+ return next;
1815
+ };
1631
1816
  const cached = createMemo(prev => {
1632
1817
  const next = source();
1633
- if (!next || typeof next.then !== "function") return resolveHandoff(next, prev);
1818
+ if (!next || typeof next.then !== "function") return resolveBinding(next, prev);
1634
1819
  const token = ++latest;
1635
1820
  return {
1636
- then: (onFulfilled, onRejected) => next.then(resolved => onFulfilled(token === latest ? resolveHandoff(resolved, prev) : resolved), onRejected)
1821
+ then: (onFulfilled, onRejected) => next.then(resolved => onFulfilled(token === latest ? resolveBinding(resolved, prev) : resolved), onRejected)
1637
1822
  };
1638
1823
  }, {
1639
1824
  lazy: true
@@ -1643,10 +1828,19 @@ function dynamic(source) {
1643
1828
  const component = cached();
1644
1829
  switch (typeof component) {
1645
1830
  case "function":
1646
- Object.assign(component, {
1647
- [$DEVCOMP]: true
1648
- });
1649
- return untrack(() => component(props));
1831
+ {
1832
+ Object.assign(component, {
1833
+ [$DEVCOMP]: true
1834
+ });
1835
+ const binding = bindingOf(component);
1836
+ if (binding) {
1837
+ const [address, setAddress] = createSignal(deliveredAddress ?? binding.address);
1838
+ sites.add(setAddress);
1839
+ onCleanup(() => sites.delete(setAddress));
1840
+ return untrack(() => binding.component(props, address));
1841
+ }
1842
+ return untrack(() => component(props));
1843
+ }
1650
1844
  case "string":
1651
1845
  const el = sharedConfig.hydrating ? getNextElement() : createElement(component, untrack(() => props.is));
1652
1846
  spread(el, props);
@@ -1683,13 +1877,11 @@ _moduleUrl) {
1683
1877
  if ((Comp = untrack(comp)) && !sharedConfig.hydrating) return Comp(rest);
1684
1878
  const [mounted, setMounted] = createSignal(!sharedConfig.hydrating);
1685
1879
  const gate = createMemo(() => (Comp = comp(), m = mounted(), untrack(() => Comp && m ? Comp(rest) : props.fallback)));
1686
- onSettled(() => {
1687
- setMounted(true);
1688
- });
1880
+ sharedConfig.onHydrationEnd(() => setMounted(true));
1689
1881
  return gate;
1690
1882
  };
1691
1883
  }
1692
1884
  function httpStatus(_code, _text) {}
1693
1885
  function httpHeader(_name, _value, _options) {}
1694
1886
 
1695
- export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, clientOnly, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets, useHead };
1887
+ 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, 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, httpHeader, httpStatus, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isSafeError, isServer, 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 };