@nifrajs/web-react 2.1.0 → 2.3.0

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 (54) hide show
  1. package/README.md +3 -3
  2. package/dist/await.d.ts +2 -2
  3. package/dist/await.js +2 -2
  4. package/dist/client.d.ts +2 -2
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +13 -6
  7. package/dist/client.js.map +1 -1
  8. package/dist/compose.d.ts +4 -3
  9. package/dist/compose.d.ts.map +1 -1
  10. package/dist/compose.js +12 -5
  11. package/dist/compose.js.map +1 -1
  12. package/dist/content.d.ts +2 -2
  13. package/dist/content.js +2 -2
  14. package/dist/error.d.ts +1 -1
  15. package/dist/error.js +3 -3
  16. package/dist/fetcher.d.ts +2 -2
  17. package/dist/fetcher.js +4 -4
  18. package/dist/fn.d.ts +29 -0
  19. package/dist/fn.d.ts.map +1 -0
  20. package/dist/fn.js +31 -0
  21. package/dist/fn.js.map +1 -0
  22. package/dist/i18n.d.ts +1 -1
  23. package/dist/i18n.js +1 -1
  24. package/dist/image.d.ts +3 -3
  25. package/dist/image.js +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +7 -7
  28. package/dist/island.d.ts +3 -3
  29. package/dist/island.js +2 -2
  30. package/dist/query.d.ts +8 -8
  31. package/dist/query.js +5 -5
  32. package/dist/react-dom-server.d.ts +28 -7
  33. package/dist/react-dom-server.d.ts.map +1 -1
  34. package/dist/react-dom-server.js +69 -8
  35. package/dist/react-dom-server.js.map +1 -1
  36. package/dist/router.d.ts +66 -18
  37. package/dist/router.d.ts.map +1 -1
  38. package/dist/router.js +80 -15
  39. package/dist/router.js.map +1 -1
  40. package/package.json +11 -6
  41. package/src/await.ts +2 -2
  42. package/src/client.ts +13 -7
  43. package/src/compose.ts +17 -5
  44. package/src/content.ts +2 -2
  45. package/src/error.ts +3 -3
  46. package/src/fetcher.ts +4 -4
  47. package/src/fn.ts +43 -0
  48. package/src/i18n.ts +1 -1
  49. package/src/image.ts +3 -3
  50. package/src/index.ts +7 -7
  51. package/src/island.ts +3 -3
  52. package/src/query.ts +9 -9
  53. package/src/react-dom-server.ts +83 -10
  54. package/src/router.ts +114 -24
package/dist/query.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `@nifrajs/web-react/query` — React bindings for the keyed query-cache + mutations: `useQuery`,
2
+ * `@nifrajs/web-react/query` - React bindings for the keyed query-cache + mutations: `useQuery`,
3
3
  * `useInfiniteQuery`, `useMutation`, `useQueryClient`, `QueryClientProvider`, and the SSR
4
4
  * `HydrationBoundary` (+ `dehydrate` re-exported). A drop-in for the TanStack Query surface,
5
5
  * backed by `@nifrajs/web`'s agnostic engine. Imports only `react` + `@nifrajs/web` (never `react-dom/*`),
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Resolution order for the client a hook uses: a `QueryClientProvider` in the tree (required for SSR
9
9
  * dehydrate/hydrate and for tests), else a lazily-created **client-side** module singleton (the simple
10
- * client-only app — the `typeof window` guard means the server has none, so hooks render idle/pending
10
+ * client-only app - the `typeof window` guard means the server has none, so hooks render idle/pending
11
11
  * and the first client render matches for a clean hydration).
12
12
  */
13
13
  import { createMutation, createQueryClient, } from "@nifrajs/web";
@@ -35,7 +35,7 @@ const NOOP_CLIENT = {
35
35
  hydrate: () => { },
36
36
  };
37
37
  const QueryClientContext = createContext(undefined);
38
- /** Provide a {@link QueryClient} to the tree — required for SSR dehydrate/hydrate and for tests; a
38
+ /** Provide a {@link QueryClient} to the tree - required for SSR dehydrate/hydrate and for tests; a
39
39
  * client-only app can omit it and rely on the built-in client-side singleton. */
40
40
  export function QueryClientProvider(props) {
41
41
  return createElement(QueryClientContext.Provider, { value: props.client }, props.children);
@@ -91,7 +91,7 @@ export function useQuery(key, fn, options) {
91
91
  // A disabled query still binds a handle (so it re-renders when re-enabled), but never fetches.
92
92
  const handle = client.query(key, fn, queryOpts);
93
93
  // Server snapshot = the handle's own snapshot: without a provider the client is the NOOP one (idle),
94
- // but WITH a hydrated provider client it returns the server-seeded data — so a HydrationBoundary-fed
94
+ // but WITH a hydrated provider client it returns the server-seeded data - so a HydrationBoundary-fed
95
95
  // query renders its data during SSR and the first client render matches (no loading flash, no drift).
96
96
  const state = useSyncExternalStore(handle.subscribe, handle.snapshot, handle.snapshot);
97
97
  useEffect(() => {
@@ -159,7 +159,7 @@ export function useInfiniteQuery(key, fn, options) {
159
159
  };
160
160
  }
161
161
  /**
162
- * Seed the context's {@link QueryClient} from a server {@link dehydrate} snapshot — the SSR data bridge.
162
+ * Seed the context's {@link QueryClient} from a server {@link dehydrate} snapshot - the SSR data bridge.
163
163
  * Wrap the app (inside `QueryClientProvider`) so server-prefetched queries are in the cache before the
164
164
  * first client render, avoiding a loading flash. Hydration runs during render (idempotent, fresher-wins),
165
165
  * so the data is available synchronously to child `useQuery`s.
@@ -1,30 +1,30 @@
1
1
  /**
2
- * Resolve `react-dom/server` so it shares ONE React core with the route components — the fix for the
2
+ * Resolve `react-dom/server` so it shares ONE React core with the route components - the fix for the
3
3
  * dual-React SSR crash (`resolveDispatcher().useState` is null / "Invalid hook call: mismatching versions
4
4
  * of React and the renderer").
5
5
  *
6
6
  * WHY this exists: under Bun **runtime** SSR (`nifra dev`, `nifra start`, `nifra_render`, all in-process),
7
7
  * a static `import "react-dom/server"` in this adapter is resolved by Bun from THIS package's own
8
- * (symlinked) node_modules — which can be a DIFFERENT physical `react` than the one the consumer app's
8
+ * (symlinked) node_modules - which can be a DIFFERENT physical `react` than the one the consumer app's
9
9
  * route components import. Two React cores → two hook dispatchers → the renderer's dispatcher is the wrong
10
10
  * (or null) one → the crash. Resolving `react-dom/server` from the consumer **app root** instead makes
11
11
  * react-dom pull the app's `react` transitively, matching the components' `react`: a single core, a single
12
- * dispatcher, no crash. (Empirically verified against a two-copy install fixture — see
12
+ * dispatcher, no crash. (Empirically verified against a two-copy install fixture - see
13
13
  * test/dual-react.test.ts.)
14
14
  *
15
- * Guarding precisely so the BUILT path is untouched: a bundle is detected two ways — `Bun.resolveSync` is
15
+ * Guarding precisely so the BUILT path is untouched: a bundle is detected two ways - `Bun.resolveSync` is
16
16
  * unavailable (Node / Deno / Cloudflare / Vercel), OR `buildServer` tagged the output with
17
17
  * `process.env.NIFRA_SSR_BUNDLED` (a `target:"bun"` bundle DOES keep `Bun.resolveSync` under the Bun
18
18
  * runtime, so the resolver test alone can't see it). In either case the build already bundled+deduped a
19
19
  * single `react-dom` (buildServer's `reactDedupePlugin` pins `react`), so the static `import` is correct.
20
- * Re-rooting a bundle would instead re-import a SECOND react-dom from disk — a second React core whose hook
20
+ * Re-rooting a bundle would instead re-import a SECOND react-dom from disk - a second React core whose hook
21
21
  * dispatcher is null for the bundled components → the `…H.useRef of null` SSR crash. The app-root re-root
22
22
  * therefore runs ONLY under an UNBUNDLED Bun runtime (nifra dev/start, nifra_render), where the duplication
23
23
  * can occur, `Bun.resolveSync` exists, and no bundle marker is present.
24
24
  */
25
25
  import type { ReactNode } from "react";
26
26
  /** The slice of `react-dom/server` this adapter uses. Typed locally so the dynamic import (which Bun
27
- * resolves to an absolute path string) stays strict — no `any` crosses the boundary. */
27
+ * resolves to an absolute path string) stays strict - no `any` crosses the boundary. */
28
28
  export interface ReactDomServer {
29
29
  renderToString(node: ReactNode): string;
30
30
  renderToReadableStream(node: ReactNode): Promise<ReadableStream<Uint8Array>>;
@@ -37,6 +37,27 @@ export interface ReactDomServer {
37
37
  export declare function reactDomServer(): Promise<ReactDomServer>;
38
38
  /** A `Bun.resolveSync`-shaped function (specifier, from) → absolute path. */
39
39
  type ResolveSync = (specifier: string, from: string) => string;
40
+ /**
41
+ * The dual-React crash, caught on the RESOLVED graph instead of after it detonates.
42
+ *
43
+ * The re-root above makes `react-dom/server` load from the app root, which is right almost always. What it
44
+ * cannot guarantee is that react-dom then pulls in the SAME physical `react` the route components import -
45
+ * a nested `react` under react-dom, or a components tree resolving react elsewhere, still yields two cores.
46
+ * Two cores is two hook dispatchers, and the renderer sees a null (or foreign) one: the SSR throws
47
+ * `resolveDispatcher().useState is null` from deep inside react-dom-server, naming a React internal and
48
+ * nothing about the two directories that actually caused it. That is hours of inference from a message
49
+ * that points nowhere useful.
50
+ *
51
+ * `nifra doctor` checks what is INSTALLED; this checks what SSR actually RESOLVED, which is the only thing
52
+ * that can catch a duplicate the two dev pipelines introduce (Bun for SSR, Vite for the client) rather
53
+ * than the install. It compares the realpath of the `react` react-dom will render with against the
54
+ * `react` the components import, and if they differ throws with BOTH paths - turning a five-hour hunt into
55
+ * a five-second read. Silent when they agree, which is the single-copy common case.
56
+ *
57
+ * Never manufactures a failure: if either side cannot be resolved it returns, because a resolver that
58
+ * cannot answer is not evidence of a duplicate. Exported for direct unit testing.
59
+ */
60
+ export declare function assertSingleReactCore(reactDomServerPath: string, resolve: ResolveSync, realpath?: (path: string) => string): void;
40
61
  /**
41
62
  * Load `react-dom/server`, preferring the app-root-resolved copy under the Bun runtime. Exported for unit
42
63
  * tests: `resolve` defaults to the ambient `Bun.resolveSync` (undefined on non-Bun hosts), and a test can
@@ -45,7 +66,7 @@ type ResolveSync = (specifier: string, from: string) => string;
45
66
  */
46
67
  export declare function loadReactDomServer(resolve?: ResolveSync | undefined): Promise<ReactDomServer>;
47
68
  /**
48
- * The resolver `loadReactDomServer` uses by default, or `undefined` when re-rooting must NOT happen — a
69
+ * The resolver `loadReactDomServer` uses by default, or `undefined` when re-rooting must NOT happen - a
49
70
  * non-Bun host (no `Bun.resolveSync`; the static import is the only path) OR a BUNDLED SSR output.
50
71
  * `buildServer` defines `process.env.NIFRA_SSR_BUNDLED` to `"1"` in every bundle, where react-dom is
51
72
  * already inlined + deduped to the components' React (reactDedupePlugin); re-rooting there would re-import
@@ -1 +1 @@
1
- {"version":3,"file":"react-dom-server.d.ts","sourceRoot":"","sources":["../src/react-dom-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;wFACwF;AACxF,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;IACvC,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;CAC7E;AA4BD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAIxD;AAED,6EAA6E;AAC7E,KAAK,WAAW,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;AAE9D;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,WAAW,GAAG,SAA2B,GACjD,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAED;;;;;;;;kEAQkE;AAClE,wBAAgB,aAAa,IAAI,WAAW,GAAG,SAAS,CAKvD"}
1
+ {"version":3,"file":"react-dom-server.d.ts","sourceRoot":"","sources":["../src/react-dom-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;wFACwF;AACxF,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;IACvC,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;CAC7E;AA6CD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAIxD;AAED,6EAA6E;AAC7E,KAAK,WAAW,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,WAAW,EACpB,QAAQ,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAwB,GACnD,IAAI,CAsBN;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,WAAW,GAAG,SAA2B,GACjD,OAAO,CAAC,cAAc,CAAC,CAyBzB;AAED;;;;;;;;kEAQkE;AAClE,wBAAgB,aAAa,IAAI,WAAW,GAAG,SAAS,CAKvD"}
@@ -1,23 +1,23 @@
1
1
  /**
2
- * Resolve `react-dom/server` so it shares ONE React core with the route components — the fix for the
2
+ * Resolve `react-dom/server` so it shares ONE React core with the route components - the fix for the
3
3
  * dual-React SSR crash (`resolveDispatcher().useState` is null / "Invalid hook call: mismatching versions
4
4
  * of React and the renderer").
5
5
  *
6
6
  * WHY this exists: under Bun **runtime** SSR (`nifra dev`, `nifra start`, `nifra_render`, all in-process),
7
7
  * a static `import "react-dom/server"` in this adapter is resolved by Bun from THIS package's own
8
- * (symlinked) node_modules — which can be a DIFFERENT physical `react` than the one the consumer app's
8
+ * (symlinked) node_modules - which can be a DIFFERENT physical `react` than the one the consumer app's
9
9
  * route components import. Two React cores → two hook dispatchers → the renderer's dispatcher is the wrong
10
10
  * (or null) one → the crash. Resolving `react-dom/server` from the consumer **app root** instead makes
11
11
  * react-dom pull the app's `react` transitively, matching the components' `react`: a single core, a single
12
- * dispatcher, no crash. (Empirically verified against a two-copy install fixture — see
12
+ * dispatcher, no crash. (Empirically verified against a two-copy install fixture - see
13
13
  * test/dual-react.test.ts.)
14
14
  *
15
- * Guarding precisely so the BUILT path is untouched: a bundle is detected two ways — `Bun.resolveSync` is
15
+ * Guarding precisely so the BUILT path is untouched: a bundle is detected two ways - `Bun.resolveSync` is
16
16
  * unavailable (Node / Deno / Cloudflare / Vercel), OR `buildServer` tagged the output with
17
17
  * `process.env.NIFRA_SSR_BUNDLED` (a `target:"bun"` bundle DOES keep `Bun.resolveSync` under the Bun
18
18
  * runtime, so the resolver test alone can't see it). In either case the build already bundled+deduped a
19
19
  * single `react-dom` (buildServer's `reactDedupePlugin` pins `react`), so the static `import` is correct.
20
- * Re-rooting a bundle would instead re-import a SECOND react-dom from disk — a second React core whose hook
20
+ * Re-rooting a bundle would instead re-import a SECOND react-dom from disk - a second React core whose hook
21
21
  * dispatcher is null for the bundled components → the `…H.useRef of null` SSR crash. The app-root re-root
22
22
  * therefore runs ONLY under an UNBUNDLED Bun runtime (nifra dev/start, nifra_render), where the duplication
23
23
  * can occur, `Bun.resolveSync` exists, and no bundle marker is present.
@@ -30,6 +30,15 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
30
30
  }
31
31
  return path;
32
32
  };
33
+ function dirnamePortable(path) {
34
+ const slash = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
35
+ return slash <= 0 ? "." : path.slice(0, slash);
36
+ }
37
+ function runtimeRealpath(path) {
38
+ const runtimeProcess = globalThis.process;
39
+ const fs = runtimeProcess?.getBuiltinModule?.("node:fs");
40
+ return fs?.realpathSync?.(path) ?? path;
41
+ }
33
42
  const bunResolver = globalThis.Bun;
34
43
  const hasBunResolveSync = typeof bunResolver?.resolveSync === "function";
35
44
  // Resolve once and cache: the module identity is stable for the process lifetime, and re-resolving per
@@ -57,6 +66,49 @@ export function reactDomServer() {
57
66
  cached = loadReactDomServer();
58
67
  return cached;
59
68
  }
69
+ /**
70
+ * The dual-React crash, caught on the RESOLVED graph instead of after it detonates.
71
+ *
72
+ * The re-root above makes `react-dom/server` load from the app root, which is right almost always. What it
73
+ * cannot guarantee is that react-dom then pulls in the SAME physical `react` the route components import -
74
+ * a nested `react` under react-dom, or a components tree resolving react elsewhere, still yields two cores.
75
+ * Two cores is two hook dispatchers, and the renderer sees a null (or foreign) one: the SSR throws
76
+ * `resolveDispatcher().useState is null` from deep inside react-dom-server, naming a React internal and
77
+ * nothing about the two directories that actually caused it. That is hours of inference from a message
78
+ * that points nowhere useful.
79
+ *
80
+ * `nifra doctor` checks what is INSTALLED; this checks what SSR actually RESOLVED, which is the only thing
81
+ * that can catch a duplicate the two dev pipelines introduce (Bun for SSR, Vite for the client) rather
82
+ * than the install. It compares the realpath of the `react` react-dom will render with against the
83
+ * `react` the components import, and if they differ throws with BOTH paths - turning a five-hour hunt into
84
+ * a five-second read. Silent when they agree, which is the single-copy common case.
85
+ *
86
+ * Never manufactures a failure: if either side cannot be resolved it returns, because a resolver that
87
+ * cannot answer is not evidence of a duplicate. Exported for direct unit testing.
88
+ */
89
+ export function assertSingleReactCore(reactDomServerPath, resolve, realpath = runtimeRealpath) {
90
+ let rendererReact;
91
+ let componentsReact;
92
+ try {
93
+ // The `react` react-dom/server itself resolves - the core whose dispatcher the renderer sets.
94
+ rendererReact = realpath(resolve("react", dirnamePortable(reactDomServerPath)));
95
+ // The `react` the app's route components import - the core they call hooks on.
96
+ componentsReact = realpath(resolve("react", appRoot()));
97
+ }
98
+ catch {
99
+ return;
100
+ }
101
+ if (rendererReact === componentsReact)
102
+ return;
103
+ throw new Error("[nifra/web-react] two copies of React reached SSR, so hooks render against a null dispatcher " +
104
+ "(the `resolveDispatcher().useState is null` crash). react-dom renders with a DIFFERENT React " +
105
+ "than your components import:\n" +
106
+ ` react-dom's react: ${rendererReact}\n` +
107
+ ` components' react: ${componentsReact}\n` +
108
+ "Module identity is path-based, so two copies fail even at the same version. Dedupe react to one " +
109
+ "physical copy - usually a single hoisted install at the workspace root (`nifra doctor` locates " +
110
+ "the duplicate). A Vite `resolve.dedupe`/alias fixes only the client bundle, not this SSR path.");
111
+ }
60
112
  /**
61
113
  * Load `react-dom/server`, preferring the app-root-resolved copy under the Bun runtime. Exported for unit
62
114
  * tests: `resolve` defaults to the ambient `Bun.resolveSync` (undefined on non-Bun hosts), and a test can
@@ -68,12 +120,21 @@ export async function loadReactDomServer(resolve = bunResolverFn()) {
68
120
  // Bun runtime SSR: re-root to the app's copy so react-dom shares the components' React. `react-dom`
69
121
  // is a PEER dependency of this adapter, so a correct install puts it at the app root and this
70
122
  // resolves. If it somehow doesn't (an unusual nested layout), fall through to the bundled specifier
71
- // rather than crashing — degraded (possible duplicate) but never a hard failure.
123
+ // rather than crashing - degraded (possible duplicate) but never a hard failure.
72
124
  try {
73
125
  const resolved = resolve("react-dom/server", appRoot());
126
+ // Before returning the module, verify the react-dom we just re-rooted shares the components' React.
127
+ // The re-root fixes the common case; this catches the residual duplicate loudly, with both paths,
128
+ // instead of leaving it to throw a dispatcher-null error on the first hook render. Runs once (this
129
+ // whole function is cached), dev/unbundled Bun only (the branch `resolve` gates).
130
+ assertSingleReactCore(resolved, resolve);
74
131
  return (await import(__rewriteRelativeImportExtension(resolved)));
75
132
  }
76
- catch {
133
+ catch (err) {
134
+ // A genuine duplicate is surfaced (re-thrown with both paths); any other failure (react-dom not at
135
+ // the app root, an odd nested layout) falls through to the bundled specifier rather than crashing.
136
+ if (err instanceof Error && err.message.includes("two copies of React"))
137
+ throw err;
77
138
  // App-root resolution failed; use the specifier resolved from this module's own location below.
78
139
  }
79
140
  }
@@ -83,7 +144,7 @@ export async function loadReactDomServer(resolve = bunResolverFn()) {
83
144
  return (await import("react-dom/server"));
84
145
  }
85
146
  /**
86
- * The resolver `loadReactDomServer` uses by default, or `undefined` when re-rooting must NOT happen — a
147
+ * The resolver `loadReactDomServer` uses by default, or `undefined` when re-rooting must NOT happen - a
87
148
  * non-Bun host (no `Bun.resolveSync`; the static import is the only path) OR a BUNDLED SSR output.
88
149
  * `buildServer` defines `process.env.NIFRA_SSR_BUNDLED` to `"1"` in every bundle, where react-dom is
89
150
  * already inlined + deduped to the components' React (reactDedupePlugin); re-rooting there would re-import
@@ -1 +1 @@
1
- {"version":3,"file":"react-dom-server.js","sourceRoot":"","sources":["../src/react-dom-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;;;;;;;;;AAkBH,MAAM,WAAW,GAAI,UAA6C,CAAC,GAAG,CAAA;AACtE,MAAM,iBAAiB,GAAG,OAAO,WAAW,EAAE,WAAW,KAAK,UAAU,CAAA;AAExE,uGAAuG;AACvG,qGAAqG;AACrG,8EAA8E;AAC9E,IAAI,MAA2C,CAAA;AAE/C;;;;;;GAMG;AACH,SAAS,OAAO;IACd,OAAO,OAAO,CAAC,GAAG,EAAE,CAAA;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAA;IACvC,MAAM,GAAG,kBAAkB,EAAE,CAAA;IAC7B,OAAO,MAAM,CAAA;AACf,CAAC;AAKD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAmC,aAAa,EAAE;IAElD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,oGAAoG;QACpG,8FAA8F;QAC9F,oGAAoG;QACpG,iFAAiF;QACjF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAA;YACvD,OAAO,CAAC,MAAM,MAAM,kCAAC,QAAQ,EAAC,CAAmB,CAAA;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,gGAAgG;QAClG,CAAC;IACH,CAAC;IACD,8FAA8F;IAC9F,oGAAoG;IACpG,kGAAkG;IAClG,OAAO,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAmB,CAAA;AAC7D,CAAC;AAED;;;;;;;;kEAQkE;AAClE,MAAM,UAAU,aAAa;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG;QAAE,OAAO,SAAS,CAAA;IAC3D,OAAO,iBAAiB,IAAI,WAAW,EAAE,WAAW,KAAK,SAAS;QAChE,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC;QAC3C,CAAC,CAAC,SAAS,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"react-dom-server.js","sourceRoot":"","sources":["../src/react-dom-server.ts"],"names":[],"mappings":"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"}
package/dist/router.d.ts CHANGED
@@ -1,24 +1,30 @@
1
1
  /**
2
- * `@nifrajs/web-react/router` — React routing bindings over the agnostic `@nifrajs/web` router:
2
+ * `@nifrajs/web-react/router` - React routing bindings over the agnostic `@nifrajs/web` router:
3
3
  * `<Link>`/`<NavLink>`, `useNavigate`, `useParams`, `useLocation`, `useSearchParams`, and `<Navigate>`.
4
4
  *
5
5
  * These read the current route from a {@link RouterContext} that `compose` provides on BOTH the SSR
6
6
  * render and the client mount (seeded from the request match / router state respectively), so the read
7
7
  * hooks (`useParams`/`useLocation`/`useSearchParams`) are SSR-correct and hydrate with no mismatch.
8
8
  * Navigation goes through `@nifrajs/web`'s DOM-free navigate bridge (`getBrowserNavigate`, populated by
9
- * `installHistory`) — so this module imports only `react` (never `react-dom/*`), and a route component
9
+ * `installHistory`) - so this module imports only `react` (never `react-dom/*`), and a route component
10
10
  * can use these on the server and the client without dragging a DOM build into the wrong bundle. No JSX
11
11
  * (the package builds with plain `tsc`), so everything is `createElement`.
12
12
  */
13
- import { type NavigateOptions } from "@nifrajs/web";
13
+ import type { InferOutput, StandardSchemaV1 } from "@nifrajs/core/server";
14
+ import { type Blocker, type BlockerFunction, type NavigateFunction, type NavigateOptions } from "@nifrajs/web";
14
15
  import { type AnchorHTMLAttributes, type CSSProperties, type ReactNode } from "react";
16
+ export type { Blocker, BlockerFunction, BlockerState, NavigateFunction } from "@nifrajs/web";
15
17
  /** The current route the routing hooks read. Provided by `compose` on SSR + client mount alike. */
16
18
  export interface RouterContextValue {
17
19
  /** The matched route's decoded path params (`/users/:id` → `{ id: "7" }`). */
18
20
  readonly params: Readonly<Record<string, string>>;
19
- /** The current URL's `pathname + search` (no hash — the router never carries one). */
21
+ /** The current URL's `pathname + search` (no hash - the router never carries one). */
20
22
  readonly path: string;
21
- /** True while a client navigation (or revalidation) is in flight — the current route stays mounted
23
+ /** The route's typed, validated search params (the loader's `ctx.search`), derived from the URL via
24
+ * the shared `searchOf` on SSR + client alike, read by {@link useSearch}. `{}` when the route
25
+ * declares no `searchSchema` (then it is the raw parsed query) or outside a nifra route tree. */
26
+ readonly search: Record<string, unknown>;
27
+ /** True while a client navigation (or revalidation) is in flight - the current route stays mounted
22
28
  * until the new one is ready. Always `false` on SSR (loaders block before render). Drives loading UI
23
29
  * via {@link useNavigation}. */
24
30
  readonly pending: boolean;
@@ -26,16 +32,33 @@ export interface RouterContextValue {
26
32
  * during a same-route revalidation). Powers {@link NavLink}'s per-link `isPending`. */
27
33
  readonly pendingPath?: string | undefined;
28
34
  }
29
- /** Router context. The default ({} params, "" path) is what a component sees when rendered outside a
30
- * nifra route tree — the hooks stay defined (no throw) so a stray `useParams` degrades gracefully. */
35
+ /** Router context. The default ({} params, "" path, {} search) is what a component sees when rendered
36
+ * outside a nifra route tree (the hooks stay defined, no throw, so a stray `useParams` degrades
37
+ * gracefully). */
31
38
  export declare const RouterContext: import("react").Context<RouterContextValue>;
32
39
  /**
33
- * The matched route's decoded path params — `/users/:id` on `/users/7` → `{ id: "7" }`. SSR-correct:
40
+ * The matched route's decoded path params - `/users/:id` on `/users/7` → `{ id: "7" }`. SSR-correct:
34
41
  * `compose` provides the same value server-side (from the request match) and client-side (from router
35
42
  * state), so a param rendered into markup doesn't flash on hydration.
36
43
  */
37
44
  export declare function useParams<T extends Record<string, string | undefined> = Record<string, string>>(): Readonly<T>;
38
- /** The parsed current location. `hash` is always `""` — the fragment is client-only and never reaches
45
+ /**
46
+ * The route's typed, validated search params: the SAME value the loader received as `ctx.search`.
47
+ * SSR-correct: `compose` provides it from `searchOf(searchSchema, url.search)` server-side and from the
48
+ * identical derivation on the client mount, so a value rendered from it doesn't flash on hydration.
49
+ * Hostile input already failed closed to the schema's defaults at match time, so a component never
50
+ * parses `window.location.search` or guards against a bad query.
51
+ *
52
+ * Pass the route's `searchSchema` as the type argument to get its output type; bare, it's the raw parsed
53
+ * query (`Record<string, unknown>`), which is also what a route without a `searchSchema` yields.
54
+ *
55
+ * ```tsx
56
+ * export const searchSchema = v.object({ page: v.optional(v.fallback(v.number(), 1), 1) })
57
+ * const { page } = useSearch<typeof searchSchema>() // page: number
58
+ * ```
59
+ */
60
+ export declare function useSearch<Schema extends StandardSchemaV1 | undefined = undefined>(): Schema extends StandardSchemaV1 ? InferOutput<Schema> : Record<string, unknown>;
61
+ /** The parsed current location. `hash` is always `""` - the fragment is client-only and never reaches
39
62
  * the router state / server, so exposing a live hash would hydration-mismatch; read `window.location.hash`
40
63
  * directly (in an effect) if you truly need it. */
41
64
  export interface Location {
@@ -71,13 +94,38 @@ export interface Navigation {
71
94
  export declare function useNavigation(): Navigation;
72
95
  /** Convenience boolean form of {@link useNavigation}: `true` while a client navigation is in flight. */
73
96
  export declare function usePending(): boolean;
74
- /** A programmatic navigate: a string path (push, or replace via `{ replace: true }`) or a history delta
75
- * (`-1`/`1`). A no-op on the server / before hydration (a render-time navigate isn't valid — use
76
- * {@link Navigate}, which navigates in an effect). */
77
- export type NavigateFunction = (to: string | number, options?: NavigateOptions) => void;
78
- /** Get the {@link NavigateFunction}. Stable across renders; resolves the browser navigate at call time
79
- * (so it works as soon as `installHistory` has run, and no-ops before then / on the server). */
97
+ /** Get the {@link NavigateFunction} (a string path, a history delta, or a typed `{ to, search }` object;
98
+ * a render-time navigate isn't valid - use {@link Navigate}, which navigates in an effect). Stable across
99
+ * renders; resolves the browser navigate at call time (so it works as soon as `installHistory` has run,
100
+ * and no-ops before then / on the server). */
80
101
  export declare function useNavigate(): NavigateFunction;
102
+ /**
103
+ * Guard navigation away from a page with unsaved work, confirming with your OWN async UI. Mirrors
104
+ * react-router's `useBlocker`: pass a boolean (`useBlocker(isDirty)`) or a predicate
105
+ * `({ currentLocation, nextLocation }) => boolean`, and get back a {@link Blocker}. When a navigation
106
+ * (a `<Link>`/anchor click, `useNavigate`, or a browser back/forward) is intercepted, `blocker.state`
107
+ * becomes `"blocked"` and `proceed`/`reset` go live - render a dialog and call `proceed()` to continue
108
+ * or `reset()` to stay put. It also arms the browser's native "Leave site?" prompt on tab close / reload.
109
+ * Idle (never blocks, `proceed`/`reset` are `undefined`) on the server and before hydration, so it's
110
+ * SSR-safe and hydration-stable.
111
+ *
112
+ * ```tsx
113
+ * const blocker = useBlocker(form.isDirty)
114
+ * return (
115
+ * <>
116
+ * <MyForm />
117
+ * {blocker.state === "blocked" && (
118
+ * <ConfirmDialog
119
+ * onCancel={blocker.reset}
120
+ * onConfirm={blocker.proceed}
121
+ * message="Discard unsaved changes?"
122
+ * />
123
+ * )}
124
+ * </>
125
+ * )
126
+ * ```
127
+ */
128
+ export declare function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker;
81
129
  /** The value forms `setSearchParams` accepts. */
82
130
  export type SearchParamsInit = URLSearchParams | Record<string, string | readonly string[]> | string;
83
131
  /** Set the query string. Accepts a `URLSearchParams`, a record, a raw string, or an updater of the
@@ -99,7 +147,7 @@ export interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>,
99
147
  * A client-navigating anchor. Renders a real `<a href={to}>` (so it's a working link before hydration
100
148
  * and for right-click / open-in-new-tab), and on a plain left-click navigates through the router
101
149
  * instead of a full reload. Calling `navigate` + `preventDefault` here means `installHistory`'s
102
- * document-level click handler sees `defaultPrevented` and stands down — exactly one navigation.
150
+ * document-level click handler sees `defaultPrevented` and stands down - exactly one navigation.
103
151
  */
104
152
  export declare const Link: import("react").ForwardRefExoticComponent<LinkProps & import("react").RefAttributes<HTMLAnchorElement>>;
105
153
  /** The state a {@link NavLink}'s function-form `className`/`style`/`children` receive. */
@@ -110,7 +158,7 @@ export interface NavLinkRenderProps {
110
158
  * `false` on SSR and when idle. Use it to show a per-link spinner during the transition. */
111
159
  readonly isPending: boolean;
112
160
  }
113
- /** {@link NavLink} props — like {@link LinkProps}, but `className`/`style`/`children` may be functions
161
+ /** {@link NavLink} props - like {@link LinkProps}, but `className`/`style`/`children` may be functions
114
162
  * of the active state, and `end`/`caseSensitive` tune matching. */
115
163
  export interface NavLinkProps extends Omit<LinkProps, "className" | "style" | "children"> {
116
164
  /** Match the full path exactly instead of as a prefix (use for `to="/"` so it isn't always active). */
@@ -134,7 +182,7 @@ export interface NavigateProps {
134
182
  readonly replace?: boolean;
135
183
  }
136
184
  /**
137
- * Declaratively navigate on mount — the component analogue of `useNavigate` (e.g. a guard that renders
185
+ * Declaratively navigate on mount - the component analogue of `useNavigate` (e.g. a guard that renders
138
186
  * `<Navigate to="/login" replace />`). Navigates in an effect, so it's a safe no-op during SSR (renders
139
187
  * `null`); the redirect happens once on the client after hydration.
140
188
  */
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/dist/router.js CHANGED
@@ -1,24 +1,27 @@
1
1
  /**
2
- * `@nifrajs/web-react/router` — React routing bindings over the agnostic `@nifrajs/web` router:
2
+ * `@nifrajs/web-react/router` - React routing bindings over the agnostic `@nifrajs/web` router:
3
3
  * `<Link>`/`<NavLink>`, `useNavigate`, `useParams`, `useLocation`, `useSearchParams`, and `<Navigate>`.
4
4
  *
5
5
  * These read the current route from a {@link RouterContext} that `compose` provides on BOTH the SSR
6
6
  * render and the client mount (seeded from the request match / router state respectively), so the read
7
7
  * hooks (`useParams`/`useLocation`/`useSearchParams`) are SSR-correct and hydrate with no mismatch.
8
8
  * Navigation goes through `@nifrajs/web`'s DOM-free navigate bridge (`getBrowserNavigate`, populated by
9
- * `installHistory`) — so this module imports only `react` (never `react-dom/*`), and a route component
9
+ * `installHistory`) - so this module imports only `react` (never `react-dom/*`), and a route component
10
10
  * can use these on the server and the client without dragging a DOM build into the wrong bundle. No JSX
11
11
  * (the package builds with plain `tsc`), so everything is `createElement`.
12
12
  */
13
- import { getBrowserNavigate } from "@nifrajs/web";
14
- import { createContext, createElement, forwardRef, useCallback, useContext, useEffect, useMemo, } from "react";
15
- // Frozen empty params so the default context value has a stable reference (no needless re-renders).
13
+ import { getBrowserNavigate, IDLE_BLOCKER, registerBlocker, resolveNavigate, } from "@nifrajs/web";
14
+ import { createContext, createElement, forwardRef, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
15
+ // Frozen empty params/search so the default context value has a stable reference (no needless re-renders).
16
16
  const EMPTY_PARAMS = Object.freeze({});
17
- /** Router context. The default ({} params, "" path) is what a component sees when rendered outside a
18
- * nifra route tree — the hooks stay defined (no throw) so a stray `useParams` degrades gracefully. */
17
+ const EMPTY_SEARCH = Object.freeze({});
18
+ /** Router context. The default ({} params, "" path, {} search) is what a component sees when rendered
19
+ * outside a nifra route tree (the hooks stay defined, no throw, so a stray `useParams` degrades
20
+ * gracefully). */
19
21
  export const RouterContext = createContext({
20
22
  params: EMPTY_PARAMS,
21
23
  path: "",
24
+ search: EMPTY_SEARCH,
22
25
  pending: false,
23
26
  });
24
27
  /** Split a `pathname + search` into its parts. `search` keeps its leading `?` (like `location.search`);
@@ -30,13 +33,31 @@ function splitPath(path) {
30
33
  : { pathname: path.slice(0, q), search: path.slice(q) };
31
34
  }
32
35
  /**
33
- * The matched route's decoded path params — `/users/:id` on `/users/7` → `{ id: "7" }`. SSR-correct:
36
+ * The matched route's decoded path params - `/users/:id` on `/users/7` → `{ id: "7" }`. SSR-correct:
34
37
  * `compose` provides the same value server-side (from the request match) and client-side (from router
35
38
  * state), so a param rendered into markup doesn't flash on hydration.
36
39
  */
37
40
  export function useParams() {
38
41
  return useContext(RouterContext).params;
39
42
  }
43
+ /**
44
+ * The route's typed, validated search params: the SAME value the loader received as `ctx.search`.
45
+ * SSR-correct: `compose` provides it from `searchOf(searchSchema, url.search)` server-side and from the
46
+ * identical derivation on the client mount, so a value rendered from it doesn't flash on hydration.
47
+ * Hostile input already failed closed to the schema's defaults at match time, so a component never
48
+ * parses `window.location.search` or guards against a bad query.
49
+ *
50
+ * Pass the route's `searchSchema` as the type argument to get its output type; bare, it's the raw parsed
51
+ * query (`Record<string, unknown>`), which is also what a route without a `searchSchema` yields.
52
+ *
53
+ * ```tsx
54
+ * export const searchSchema = v.object({ page: v.optional(v.fallback(v.number(), 1), 1) })
55
+ * const { page } = useSearch<typeof searchSchema>() // page: number
56
+ * ```
57
+ */
58
+ export function useSearch() {
59
+ return useContext(RouterContext).search;
60
+ }
40
61
  /** The current {@link Location} (`pathname`/`search`/`hash`), derived from the router context. */
41
62
  export function useLocation() {
42
63
  const { path } = useContext(RouterContext);
@@ -69,15 +90,59 @@ export function useNavigation() {
69
90
  export function usePending() {
70
91
  return useContext(RouterContext).pending;
71
92
  }
72
- /** Get the {@link NavigateFunction}. Stable across renders; resolves the browser navigate at call time
73
- * (so it works as soon as `installHistory` has run, and no-ops before then / on the server). */
93
+ /** Get the {@link NavigateFunction} (a string path, a history delta, or a typed `{ to, search }` object;
94
+ * a render-time navigate isn't valid - use {@link Navigate}, which navigates in an effect). Stable across
95
+ * renders; resolves the browser navigate at call time (so it works as soon as `installHistory` has run,
96
+ * and no-ops before then / on the server). */
74
97
  export function useNavigate() {
75
98
  return useCallback((to, options) => {
76
99
  const navigate = getBrowserNavigate();
77
- if (navigate !== undefined)
78
- navigate(to, options);
100
+ if (navigate === undefined)
101
+ return;
102
+ const resolved = resolveNavigate(to, options);
103
+ navigate(resolved.to, resolved.options);
79
104
  }, []);
80
105
  }
106
+ /**
107
+ * Guard navigation away from a page with unsaved work, confirming with your OWN async UI. Mirrors
108
+ * react-router's `useBlocker`: pass a boolean (`useBlocker(isDirty)`) or a predicate
109
+ * `({ currentLocation, nextLocation }) => boolean`, and get back a {@link Blocker}. When a navigation
110
+ * (a `<Link>`/anchor click, `useNavigate`, or a browser back/forward) is intercepted, `blocker.state`
111
+ * becomes `"blocked"` and `proceed`/`reset` go live - render a dialog and call `proceed()` to continue
112
+ * or `reset()` to stay put. It also arms the browser's native "Leave site?" prompt on tab close / reload.
113
+ * Idle (never blocks, `proceed`/`reset` are `undefined`) on the server and before hydration, so it's
114
+ * SSR-safe and hydration-stable.
115
+ *
116
+ * ```tsx
117
+ * const blocker = useBlocker(form.isDirty)
118
+ * return (
119
+ * <>
120
+ * <MyForm />
121
+ * {blocker.state === "blocked" && (
122
+ * <ConfirmDialog
123
+ * onCancel={blocker.reset}
124
+ * onConfirm={blocker.proceed}
125
+ * message="Discard unsaved changes?"
126
+ * />
127
+ * )}
128
+ * </>
129
+ * )
130
+ * ```
131
+ */
132
+ export function useBlocker(shouldBlock) {
133
+ const [blocker, setBlocker] = useState(IDLE_BLOCKER);
134
+ // Track the latest predicate in a ref (updated every render) so the single registration always sees
135
+ // current component state (the dirty flag) WITHOUT re-registering - re-registering mid-prompt drops it.
136
+ const shouldBlockRef = useRef(shouldBlock);
137
+ shouldBlockRef.current = shouldBlock;
138
+ // Register once on mount; the returned unregister is the effect cleanup. A boolean reads as itself, a
139
+ // function is called. A no-op before `installHistory` has run (blocker stays idle → native navigation).
140
+ useEffect(() => registerBlocker((args) => {
141
+ const current = shouldBlockRef.current;
142
+ return typeof current === "function" ? current(args) : current;
143
+ }, setBlocker), []);
144
+ return blocker;
145
+ }
81
146
  function toSearchParams(init) {
82
147
  if (init instanceof URLSearchParams)
83
148
  return init;
@@ -109,7 +174,7 @@ export function useSearchParams() {
109
174
  }, [navigate, pathname, search]);
110
175
  return [searchParams, setSearchParams];
111
176
  }
112
- /** A left-click with no modifier and no new-tab target — the only click a client router should
177
+ /** A left-click with no modifier and no new-tab target - the only click a client router should
113
178
  * intercept (Cmd/Ctrl/Shift/Alt or a `_blank` target means the user wants native behavior). */
114
179
  function isPlainLeftClick(event, target) {
115
180
  if (event.button !== 0)
@@ -122,7 +187,7 @@ function isPlainLeftClick(event, target) {
122
187
  * A client-navigating anchor. Renders a real `<a href={to}>` (so it's a working link before hydration
123
188
  * and for right-click / open-in-new-tab), and on a plain left-click navigates through the router
124
189
  * instead of a full reload. Calling `navigate` + `preventDefault` here means `installHistory`'s
125
- * document-level click handler sees `defaultPrevented` and stands down — exactly one navigation.
190
+ * document-level click handler sees `defaultPrevented` and stands down - exactly one navigation.
126
191
  */
127
192
  export const Link = forwardRef(function Link({ to, replace, onClick, target, ...rest }, ref) {
128
193
  const handleClick = (event) => {
@@ -187,7 +252,7 @@ function matchesPrefix(current, target) {
187
252
  return current.startsWith(target === "/" ? "/" : `${target}/`);
188
253
  }
189
254
  /**
190
- * Declaratively navigate on mount — the component analogue of `useNavigate` (e.g. a guard that renders
255
+ * Declaratively navigate on mount - the component analogue of `useNavigate` (e.g. a guard that renders
191
256
  * `<Navigate to="/login" replace />`). Navigates in an effect, so it's a safe no-op during SSR (renders
192
257
  * `null`); the redirect happens once on the client after hydration.
193
258
  */
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}