@rsc-kit/core 0.16.1 → 0.16.3

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.
@@ -1 +1,7 @@
1
+ /**
2
+ * The digest a stored page carries where the query was read under the
3
+ * boundary that caught it. The client recognises it on hydration and does
4
+ * not report the fallback as an error, because it is the designed path.
5
+ */
6
+ export declare const SEARCH_PARAMS_FALLBACK = "rsc-kit:search-params-fallback";
1
7
  export declare function useSearchParams(): URLSearchParams;
@@ -14,6 +14,11 @@
14
14
  * root, nothing paints, and the build refuses the route and says why — which
15
15
  * is the same answer it gives for reading the request too early on the server.
16
16
  *
17
+ * The dev server renders per request and could answer with that request's
18
+ * query string; it does not, on purpose. A page has one shape — a stored
19
+ * shell with the query read in the browser — and dev shows that shape, so a
20
+ * boundary missing in dev is the boundary the build will refuse.
21
+ *
17
22
  * Returning an empty URLSearchParams instead would be worse than either: the
18
23
  * page would be stored showing results for no query at all, and nothing would
19
24
  * say so.
@@ -56,10 +61,18 @@ function getSnapshot() {
56
61
  }
57
62
  return cached.params;
58
63
  }
64
+ /**
65
+ * The digest a stored page carries where the query was read under the
66
+ * boundary that caught it. The client recognises it on hydration and does
67
+ * not report the fallback as an error, because it is the designed path.
68
+ */
69
+ export const SEARCH_PARAMS_FALLBACK = "rsc-kit:search-params-fallback";
59
70
  function getServerSnapshot() {
60
- throw new Error("useSearchParams() was read while rendering on the server, where there is no query string. " +
61
- "Wrap the component in <Suspense> — or add a loading.tsx beside the page — so the fallback " +
62
- "is stored and the real value arrives in the browser.");
71
+ const error = new Error("useSearchParams() was read while rendering on the server, where there is no query string to give: " +
72
+ "a stored page would serve one visitor's query to everyone. Wrap the component in <Suspense> — or add a " +
73
+ "loading.tsx beside the page — so the fallback is stored and the real value arrives in the browser.");
74
+ error.digest = SEARCH_PARAMS_FALLBACK;
75
+ throw error;
63
76
  }
64
77
  export function useSearchParams() {
65
78
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
@@ -1 +1 @@
1
- {"version":3,"file":"useSearchParams.js","sourceRoot":"","sources":["../../src/js/useSearchParams.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AAExC;;;;;;GAMG;AACH,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,EAAE,CAAC;AAE3D,SAAS,aAAa;IACpB,OAAO,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;AACrE,CAAC;AAED,SAAS,MAAM;IACb,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,SAAS,SAAS,CAAC,QAAoB;IACrC,0EAA0E;IAC1E,0EAA0E;IAC1E,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,IAAI,CAAC,SAAS,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5C,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAExB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,SAAS,iBAAiB;IACxB,MAAM,IAAI,KAAK,CACb,4FAA4F;QAC1F,4FAA4F;QAC5F,sDAAsD,CACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;AACzE,CAAC","sourcesContent":["\"use client\";\n\n/**\n * The query string, live across navigations.\n *\n * Deliberately unlike usePathname, which answers with the url being rendered.\n * A pathname is fixed for a given stored page; a query string is not — the\n * same route is asked for with `?q=shoes` and `?q=hats`, and a page stored\n * holding one of them would serve it to everyone.\n *\n * So there is no server snapshot to give, and this throws rather than\n * inventing one. React treats an error thrown during SSR as recoverable at the\n * nearest Suspense boundary: the fallback is what gets stored, and the client\n * renders the real thing on hydration. Without a boundary the error reaches the\n * root, nothing paints, and the build refuses the route and says why — which\n * is the same answer it gives for reading the request too early on the server.\n *\n * Returning an empty URLSearchParams instead would be worse than either: the\n * page would be stored showing results for no query at all, and nothing would\n * say so.\n */\n\nimport { useSyncExternalStore } from \"react\";\n\nconst listeners = new Set<() => void>();\n\n/**\n * Cached by the string it was parsed from.\n *\n * useSyncExternalStore compares snapshots by identity, so handing back a fresh\n * URLSearchParams on every read reads as \"changed every time\" and loops until\n * React gives up.\n */\nlet cached = { search: \"\", params: new URLSearchParams() };\n\nfunction currentSearch(): string {\n return typeof window === \"undefined\" ? \"\" : window.location.search;\n}\n\nfunction notify(): void {\n listeners.forEach((fn) => fn());\n}\n\nlet listening = false;\n\nfunction subscribe(callback: () => void): () => void {\n // On the first subscriber rather than at module load. A listener attached\n // when the module is evaluated is attached to whatever `window` exists at\n // that moment — which in a test that installs a DOM after its imports is\n // none, and the hook silently never updates. Attaching here is the shape\n // useSyncExternalStore expects and is correct wherever the module loads.\n if (!listening && typeof window !== \"undefined\") {\n window.addEventListener(\"rsc-navigate\", notify);\n window.addEventListener(\"popstate\", notify);\n listening = true;\n }\n\n listeners.add(callback);\n\n return () => listeners.delete(callback);\n}\n\nfunction getSnapshot(): URLSearchParams {\n const search = currentSearch();\n\n if (search !== cached.search) {\n cached = { search, params: new URLSearchParams(search) };\n }\n\n return cached.params;\n}\n\nfunction getServerSnapshot(): URLSearchParams {\n throw new Error(\n \"useSearchParams() was read while rendering on the server, where there is no query string. \" +\n \"Wrap the component in <Suspense> — or add a loading.tsx beside the page — so the fallback \" +\n \"is stored and the real value arrives in the browser.\",\n );\n}\n\nexport function useSearchParams(): URLSearchParams {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n"]}
1
+ {"version":3,"file":"useSearchParams.js","sourceRoot":"","sources":["../../src/js/useSearchParams.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AAExC;;;;;;GAMG;AACH,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,EAAE,CAAC;AAE3D,SAAS,aAAa;IACpB,OAAO,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;AACrE,CAAC;AAED,SAAS,MAAM;IACb,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,SAAS,SAAS,CAAC,QAAoB;IACrC,0EAA0E;IAC1E,0EAA0E;IAC1E,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,IAAI,CAAC,SAAS,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5C,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAExB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAEvE,SAAS,iBAAiB;IACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,oGAAoG;QAClG,yGAAyG;QACzG,oGAAoG,CACxE,CAAC;IAEjC,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC;IAEtC,MAAM,KAAK,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;AACzE,CAAC","sourcesContent":["\"use client\";\n\n/**\n * The query string, live across navigations.\n *\n * Deliberately unlike usePathname, which answers with the url being rendered.\n * A pathname is fixed for a given stored page; a query string is not — the\n * same route is asked for with `?q=shoes` and `?q=hats`, and a page stored\n * holding one of them would serve it to everyone.\n *\n * So there is no server snapshot to give, and this throws rather than\n * inventing one. React treats an error thrown during SSR as recoverable at the\n * nearest Suspense boundary: the fallback is what gets stored, and the client\n * renders the real thing on hydration. Without a boundary the error reaches the\n * root, nothing paints, and the build refuses the route and says why — which\n * is the same answer it gives for reading the request too early on the server.\n *\n * The dev server renders per request and could answer with that request's\n * query string; it does not, on purpose. A page has one shape — a stored\n * shell with the query read in the browser — and dev shows that shape, so a\n * boundary missing in dev is the boundary the build will refuse.\n *\n * Returning an empty URLSearchParams instead would be worse than either: the\n * page would be stored showing results for no query at all, and nothing would\n * say so.\n */\n\nimport { useSyncExternalStore } from \"react\";\n\nconst listeners = new Set<() => void>();\n\n/**\n * Cached by the string it was parsed from.\n *\n * useSyncExternalStore compares snapshots by identity, so handing back a fresh\n * URLSearchParams on every read reads as \"changed every time\" and loops until\n * React gives up.\n */\nlet cached = { search: \"\", params: new URLSearchParams() };\n\nfunction currentSearch(): string {\n return typeof window === \"undefined\" ? \"\" : window.location.search;\n}\n\nfunction notify(): void {\n listeners.forEach((fn) => fn());\n}\n\nlet listening = false;\n\nfunction subscribe(callback: () => void): () => void {\n // On the first subscriber rather than at module load. A listener attached\n // when the module is evaluated is attached to whatever `window` exists at\n // that moment — which in a test that installs a DOM after its imports is\n // none, and the hook silently never updates. Attaching here is the shape\n // useSyncExternalStore expects and is correct wherever the module loads.\n if (!listening && typeof window !== \"undefined\") {\n window.addEventListener(\"rsc-navigate\", notify);\n window.addEventListener(\"popstate\", notify);\n listening = true;\n }\n\n listeners.add(callback);\n\n return () => listeners.delete(callback);\n}\n\nfunction getSnapshot(): URLSearchParams {\n const search = currentSearch();\n\n if (search !== cached.search) {\n cached = { search, params: new URLSearchParams(search) };\n }\n\n return cached.params;\n}\n\n/**\n * The digest a stored page carries where the query was read under the\n * boundary that caught it. The client recognises it on hydration and does\n * not report the fallback as an error, because it is the designed path.\n */\nexport const SEARCH_PARAMS_FALLBACK = \"rsc-kit:search-params-fallback\";\n\nfunction getServerSnapshot(): URLSearchParams {\n const error = new Error(\n \"useSearchParams() was read while rendering on the server, where there is no query string to give: \" +\n \"a stored page would serve one visitor's query to everyone. Wrap the component in <Suspense> — or add a \" +\n \"loading.tsx beside the page — so the fallback is stored and the real value arrives in the browser.\",\n ) as Error & { digest?: string };\n\n error.digest = SEARCH_PARAMS_FALLBACK;\n\n throw error;\n}\n\nexport function useSearchParams(): URLSearchParams {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { ManifestRoute, RouteManifest } from './manifest.js';
1
+ import type { ManifestRoute, RouteManifest } from "./manifest.js";
2
2
  /**
3
3
  * Every `<link rel="stylesheet">` whose source the reader answers for,
4
4
  * replaced by a `<style>` holding it. A link the reader declines - too big,
@@ -156,7 +156,7 @@ export interface PrerenderResult {
156
156
  * has no boundary to move: it either depends on the request or it does not,
157
157
  * and depending on it is the ordinary case rather than a mistake.
158
158
  */
159
- type: 'frozen' | 'shell' | 'blocked' | 'error' | 'dynamic';
159
+ type: "frozen" | "shell" | "blocked" | "error" | "dynamic";
160
160
  reason: string | null;
161
161
  /**
162
162
  * Something worth knowing that is not a failure.