@nifrajs/web-react 2.11.0 → 2.12.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.
- package/dist/client.d.ts +9 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +23 -4
- package/dist/client.js.map +1 -1
- package/package.json +11 -9
- package/src/client.ts +37 -3
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { MountRouterOptions, RenderProps } from "@nifrajs/web";
|
|
2
2
|
export { errorBoundary } from "./error.js";
|
|
3
3
|
/** Hydrate a server-rendered React layout `chain` (with the loader `props`) inside `container`. */
|
|
4
|
-
export
|
|
4
|
+
export interface HydrationAssuranceOptions {
|
|
5
|
+
readonly onRecoverableError?: (error: unknown, info?: unknown) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function hydrate(chain: readonly unknown[], props: RenderProps, container: unknown, options?: HydrationAssuranceOptions): void;
|
|
8
|
+
/** Testing hook used by verification runners to observe React's recoverable errors and identity. */
|
|
9
|
+
export declare const hydrationAssuranceHook: Readonly<{
|
|
10
|
+
framework: "react";
|
|
11
|
+
runtimeIdentity: () => object;
|
|
12
|
+
}>;
|
|
5
13
|
/**
|
|
6
14
|
* Hydrate a stateful React Router. `useSyncExternalStore` subscribes to the agnostic store and
|
|
7
15
|
* re-renders the matched layout chain on each store change - so client navigations swap routes
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAkBnE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,mGAAmG;AACnG,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACvE;AAaD,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,yBAAyB,GAClC,IAAI,CAIN;AAED,oGAAoG;AACpG,eAAO,MAAM,sBAAsB;;2BAEZ,MAAM;EAC3B,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CA8B7D"}
|
package/dist/client.js
CHANGED
|
@@ -7,6 +7,7 @@ import { searchOfChain } from "@nifrajs/web/client";
|
|
|
7
7
|
* `useSyncExternalStore`) and re-renders the matched chain on every client navigation (no full
|
|
8
8
|
* reload). Kept in its own entry so server code stays out of the client bundle.
|
|
9
9
|
*/
|
|
10
|
+
import * as React from "react";
|
|
10
11
|
import { createElement, useSyncExternalStore } from "react";
|
|
11
12
|
import { hydrateRoot } from "react-dom/client";
|
|
12
13
|
import { compose } from "./compose.js";
|
|
@@ -14,10 +15,27 @@ import { setMountedRouter } from "./fetcher.js";
|
|
|
14
15
|
// The `_error` boundary chain element - defined in its own (react-dom-free) module, re-exported here so
|
|
15
16
|
// nifra's client codegen resolves it from `@nifrajs/web-react/client` alongside `mountRouter`.
|
|
16
17
|
export { errorBoundary } from "./error.js";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
function assuranceError() {
|
|
19
|
+
const value = globalThis[Symbol.for("nifra.hydration.assurance")];
|
|
20
|
+
if (typeof value !== "object" || value === null)
|
|
21
|
+
return undefined;
|
|
22
|
+
const callback = value.onRecoverableError;
|
|
23
|
+
return typeof callback === "function"
|
|
24
|
+
? callback
|
|
25
|
+
: undefined;
|
|
20
26
|
}
|
|
27
|
+
export function hydrate(chain, props, container, options) {
|
|
28
|
+
const onRecoverableError = options?.onRecoverableError ?? assuranceError();
|
|
29
|
+
if (onRecoverableError === undefined)
|
|
30
|
+
hydrateRoot(container, compose(chain, props));
|
|
31
|
+
else
|
|
32
|
+
hydrateRoot(container, compose(chain, props), { onRecoverableError });
|
|
33
|
+
}
|
|
34
|
+
/** Testing hook used by verification runners to observe React's recoverable errors and identity. */
|
|
35
|
+
export const hydrationAssuranceHook = Object.freeze({
|
|
36
|
+
framework: "react",
|
|
37
|
+
runtimeIdentity: () => React,
|
|
38
|
+
});
|
|
21
39
|
/**
|
|
22
40
|
* Hydrate a stateful React Router. `useSyncExternalStore` subscribes to the agnostic store and
|
|
23
41
|
* re-renders the matched layout chain on each store change - so client navigations swap routes
|
|
@@ -48,6 +66,7 @@ export function mountRouter(options) {
|
|
|
48
66
|
...(state.submission ? { submission: state.submission } : {}),
|
|
49
67
|
});
|
|
50
68
|
};
|
|
51
|
-
|
|
69
|
+
const onRecoverableError = assuranceError();
|
|
70
|
+
hydrateRoot(container, createElement(Router), ...(onRecoverableError === undefined ? [] : [{ onRecoverableError }]));
|
|
52
71
|
}
|
|
53
72
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,mGAAmG;AACnG,gGAAgG;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAA0B,oBAAoB,EAAE,MAAM,OAAO,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,wGAAwG;AACxG,+FAA+F;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/web-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "React render adapter for @nifrajs/web - SSR + hydration (Bun-native JSX, no Babel).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
7
7
|
"typescript",
|
|
8
8
|
"nifra",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"ssr"
|
|
9
|
+
"react",
|
|
10
|
+
"ssr",
|
|
11
|
+
"hydration",
|
|
12
|
+
"streaming-ssr",
|
|
13
|
+
"render-adapter",
|
|
14
|
+
"full-stack"
|
|
13
15
|
],
|
|
14
16
|
"type": "module",
|
|
15
17
|
"main": "./dist/index.js",
|
|
@@ -85,10 +87,10 @@
|
|
|
85
87
|
"access": "public"
|
|
86
88
|
},
|
|
87
89
|
"dependencies": {
|
|
88
|
-
"@nifrajs/core": "2.
|
|
89
|
-
"@nifrajs/i18n": "2.
|
|
90
|
-
"@nifrajs/image": "2.
|
|
91
|
-
"@nifrajs/web": "2.
|
|
90
|
+
"@nifrajs/core": "2.12.0",
|
|
91
|
+
"@nifrajs/i18n": "2.12.0",
|
|
92
|
+
"@nifrajs/image": "2.12.0",
|
|
93
|
+
"@nifrajs/web": "2.12.0"
|
|
92
94
|
},
|
|
93
95
|
"peerDependencies": {
|
|
94
96
|
"react": "^19.0.0",
|
package/src/client.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { searchOfChain } from "@nifrajs/web/client"
|
|
|
8
8
|
* `useSyncExternalStore`) and re-renders the matched chain on every client navigation (no full
|
|
9
9
|
* reload). Kept in its own entry so server code stays out of the client bundle.
|
|
10
10
|
*/
|
|
11
|
+
import * as React from "react"
|
|
11
12
|
import { createElement, type FunctionComponent, useSyncExternalStore } from "react"
|
|
12
13
|
import { hydrateRoot } from "react-dom/client"
|
|
13
14
|
import { compose } from "./compose.ts"
|
|
@@ -18,10 +19,38 @@ import { setMountedRouter } from "./fetcher.ts"
|
|
|
18
19
|
export { errorBoundary } from "./error.ts"
|
|
19
20
|
|
|
20
21
|
/** Hydrate a server-rendered React layout `chain` (with the loader `props`) inside `container`. */
|
|
21
|
-
export
|
|
22
|
-
|
|
22
|
+
export interface HydrationAssuranceOptions {
|
|
23
|
+
readonly onRecoverableError?: (error: unknown, info?: unknown) => void
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
function assuranceError(): HydrationAssuranceOptions["onRecoverableError"] {
|
|
27
|
+
const value = (globalThis as unknown as Record<PropertyKey, unknown>)[
|
|
28
|
+
Symbol.for("nifra.hydration.assurance")
|
|
29
|
+
]
|
|
30
|
+
if (typeof value !== "object" || value === null) return undefined
|
|
31
|
+
const callback = (value as { onRecoverableError?: unknown }).onRecoverableError
|
|
32
|
+
return typeof callback === "function"
|
|
33
|
+
? (callback as HydrationAssuranceOptions["onRecoverableError"])
|
|
34
|
+
: undefined
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function hydrate(
|
|
38
|
+
chain: readonly unknown[],
|
|
39
|
+
props: RenderProps,
|
|
40
|
+
container: unknown,
|
|
41
|
+
options?: HydrationAssuranceOptions,
|
|
42
|
+
): void {
|
|
43
|
+
const onRecoverableError = options?.onRecoverableError ?? assuranceError()
|
|
44
|
+
if (onRecoverableError === undefined) hydrateRoot(container as Element, compose(chain, props))
|
|
45
|
+
else hydrateRoot(container as Element, compose(chain, props), { onRecoverableError })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Testing hook used by verification runners to observe React's recoverable errors and identity. */
|
|
49
|
+
export const hydrationAssuranceHook = Object.freeze({
|
|
50
|
+
framework: "react" as const,
|
|
51
|
+
runtimeIdentity: (): object => React,
|
|
52
|
+
})
|
|
53
|
+
|
|
25
54
|
/**
|
|
26
55
|
* Hydrate a stateful React Router. `useSyncExternalStore` subscribes to the agnostic store and
|
|
27
56
|
* re-renders the matched layout chain on each store change - so client navigations swap routes
|
|
@@ -52,5 +81,10 @@ export function mountRouter(options: MountRouterOptions): void {
|
|
|
52
81
|
...(state.submission ? { submission: state.submission } : {}),
|
|
53
82
|
})
|
|
54
83
|
}
|
|
55
|
-
|
|
84
|
+
const onRecoverableError = assuranceError()
|
|
85
|
+
hydrateRoot(
|
|
86
|
+
container as Element,
|
|
87
|
+
createElement(Router),
|
|
88
|
+
...(onRecoverableError === undefined ? [] : [{ onRecoverableError }]),
|
|
89
|
+
)
|
|
56
90
|
}
|