@rshono/core 1.0.0-rc.4 → 1.0.0-rc.6
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/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/boundaries.d.ts +29 -25
- package/dist/runtime/boundaries.d.ts.map +1 -1
- package/dist/runtime/boundaries.js +16 -17
- package/dist/runtime/boundaries.js.map +1 -1
- package/dist/runtime/client.d.ts +3 -3
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +3 -3
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/entry.client.js +49 -9
- package/dist/runtime/entry.client.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -284,6 +284,6 @@ Notes worth knowing before choosing one:
|
|
|
284
284
|
|
|
285
285
|
- Node ≥ 22.18 (worker threads, `process.loadEnvFile`, `Promise.withResolvers`, `URL.parse`, and native TypeScript stripping so a `.ts` config needs no loader), React ≥ 19.1 (the floor `react-server-dom-rspack` itself requires).
|
|
286
286
|
- Responses are not compressed. A proxy, a load balancer or a CDN is where that belongs, and every hosted target already does it.
|
|
287
|
-
- Scroll restoration is the browser's (`history.scrollRestoration = 'auto'`). A soft navigation to a new page starts at the top
|
|
287
|
+
- Scroll restoration is the browser's (`history.scrollRestoration = 'auto'`). A soft navigation to a new page starts at the top — or at the `#hash` the link named, once that page's payload is on screen — and a traversal is restored by the browser. Same-page anchors are untouched and jump natively.
|
|
288
288
|
- Dev-mode proxy doesn't forward WebSocket upgrades to a custom sub-app (prod is unaffected — the bundle owns the socket there).
|
|
289
289
|
- Dev source maps embed the original source of `'use server'` action modules (dev binds to 127.0.0.1 only; production ships no client source maps).
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* server components and actions (`getRequestContext`, `redirect`, `notFound`), plus
|
|
9
9
|
* `onServerError` for reporting the errors the framework catches.
|
|
10
10
|
* - `@rshono/core/client` — hooks and components for `'use client'` modules
|
|
11
|
-
* (`useNavigation`, `
|
|
11
|
+
* (`useNavigation`, `AsyncBoundary`, `CatchBoundary`).
|
|
12
12
|
*
|
|
13
13
|
* @packageDocumentation
|
|
14
14
|
*/
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* server components and actions (`getRequestContext`, `redirect`, `notFound`), plus
|
|
9
9
|
* `onServerError` for reporting the errors the framework catches.
|
|
10
10
|
* - `@rshono/core/client` — hooks and components for `'use client'` modules
|
|
11
|
-
* (`useNavigation`, `
|
|
11
|
+
* (`useNavigation`, `AsyncBoundary`, `CatchBoundary`).
|
|
12
12
|
*
|
|
13
13
|
* @packageDocumentation
|
|
14
14
|
*/
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,GAab,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAA6C,MAAM,aAAa,CAAC;AAItF,kGAAkG;AAClG,sGAAsG;AACtG,mGAAmG","sourcesContent":["/**\n * `@rshono/core` — the build-time surface: route and config declaration plus the types\n * your pages and endpoints are written against. Everything here is safe to\n * import from server code; none of it pulls in runtime machinery.\n *\n * The two companion entry points are runtime-only:\n * - `@rshono/core/server` — {@link https://hono.dev | Hono} request context inside\n * server components and actions (`getRequestContext`, `redirect`, `notFound`), plus\n * `onServerError` for reporting the errors the framework catches.\n * - `@rshono/core/client` — hooks and components for `'use client'` modules\n * (`useNavigation`, `
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,GAab,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAA6C,MAAM,aAAa,CAAC;AAItF,kGAAkG;AAClG,sGAAsG;AACtG,mGAAmG","sourcesContent":["/**\n * `@rshono/core` — the build-time surface: route and config declaration plus the types\n * your pages and endpoints are written against. Everything here is safe to\n * import from server code; none of it pulls in runtime machinery.\n *\n * The two companion entry points are runtime-only:\n * - `@rshono/core/server` — {@link https://hono.dev | Hono} request context inside\n * server components and actions (`getRequestContext`, `redirect`, `notFound`), plus\n * `onServerError` for reporting the errors the framework catches.\n * - `@rshono/core/client` — hooks and components for `'use client'` modules\n * (`useNavigation`, `AsyncBoundary`, `CatchBoundary`).\n *\n * @packageDocumentation\n */\n\nexport {\n defineRoutes,\n type EndpointRoute,\n type EndpointServerModule,\n type ErrorPageInfo,\n type ErrorPageProps,\n type FallbackPage,\n type HTTPMethod,\n type PageComponent,\n type PageProps,\n type PageRoute,\n type PathParams,\n type Route,\n type RouteConfig,\n} from './router.js';\n\nexport { defineConfig, type RshonoConfig, type RspackHookContext } from './config.js';\n\nexport type { DeployTarget } from './deploy/contract.js';\n\n// Hono's own `Context` and `Handler` used to be re-exported from here \"for convenience\". They are\n// Hono's types, `hono` is a peer dependency every app already has, and importing them from two places\n// only raised the question of which one is right — so an endpoint module imports them from `hono`.\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Component, type ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* What
|
|
3
|
+
* What a {@link CatchBoundary} / {@link AsyncBoundary} renders once a child throws.
|
|
4
4
|
* Either a static node, or a render function that also gets a `reset` callback
|
|
5
5
|
* to clear the error and re-render the children (e.g. a "Try again" button).
|
|
6
6
|
*
|
|
@@ -9,7 +9,7 @@ import { Component, type ReactNode } from 'react';
|
|
|
9
9
|
* server component, pass a `ReactNode`.
|
|
10
10
|
*/
|
|
11
11
|
export type ErrorFallback = ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
12
|
-
export interface
|
|
12
|
+
export interface CatchBoundaryProps {
|
|
13
13
|
/**
|
|
14
14
|
* Rendered in place of the children after one of them throws. Omit it to
|
|
15
15
|
* report the error via `onError` and re-throw to the next boundary out (or
|
|
@@ -26,7 +26,7 @@ export interface ErrorBoundaryProps {
|
|
|
26
26
|
resetKeys?: readonly unknown[];
|
|
27
27
|
children: ReactNode;
|
|
28
28
|
}
|
|
29
|
-
interface
|
|
29
|
+
interface CatchBoundaryState {
|
|
30
30
|
error: Error | null;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
@@ -36,39 +36,44 @@ interface ErrorBoundaryState {
|
|
|
36
36
|
* tearing down the whole page.
|
|
37
37
|
*
|
|
38
38
|
* It's a `'use client'` component (React error boundaries must be), so drop it
|
|
39
|
-
* anywhere in the tree from a server or client component. Use {@link
|
|
39
|
+
* anywhere in the tree from a server or client component. Use {@link AsyncBoundary}
|
|
40
40
|
* when you also want a Suspense loading fallback in the same wrapper.
|
|
41
41
|
*
|
|
42
42
|
* @example
|
|
43
43
|
* ```tsx
|
|
44
|
-
* import {
|
|
44
|
+
* import { CatchBoundary } from '@rshono/core/client';
|
|
45
45
|
*
|
|
46
|
-
* <
|
|
46
|
+
* <CatchBoundary fallback={(error, reset) => (
|
|
47
47
|
* <div role="alert">
|
|
48
48
|
* <p>{error.message}</p>
|
|
49
49
|
* <button onClick={reset}>Try again</button>
|
|
50
50
|
* </div>
|
|
51
51
|
* )}>
|
|
52
52
|
* <RiskyWidget />
|
|
53
|
-
* </
|
|
53
|
+
* </CatchBoundary>
|
|
54
54
|
* ```
|
|
55
55
|
*/
|
|
56
|
-
export declare class
|
|
57
|
-
state:
|
|
58
|
-
static getDerivedStateFromError(error: Error):
|
|
56
|
+
export declare class CatchBoundary extends Component<CatchBoundaryProps, CatchBoundaryState> {
|
|
57
|
+
state: CatchBoundaryState;
|
|
58
|
+
static getDerivedStateFromError(error: Error): CatchBoundaryState;
|
|
59
59
|
componentDidCatch(error: Error): void;
|
|
60
|
-
componentDidUpdate(prev:
|
|
60
|
+
componentDidUpdate(prev: CatchBoundaryProps): void;
|
|
61
61
|
reset: () => void;
|
|
62
62
|
render(): ReactNode;
|
|
63
63
|
}
|
|
64
|
-
export interface
|
|
65
|
-
/**
|
|
66
|
-
|
|
64
|
+
export interface AsyncBoundaryProps {
|
|
65
|
+
/**
|
|
66
|
+
* Suspense fallback, shown while the children (or their data) are still
|
|
67
|
+
* loading. Required — a loading state is the reason to reach for this over
|
|
68
|
+
* {@link CatchBoundary}, so showing nothing is an explicit `loading={null}`
|
|
69
|
+
* rather than something you get by leaving the prop off.
|
|
70
|
+
*/
|
|
71
|
+
loading: ReactNode;
|
|
67
72
|
/** Error fallback, shown if a child throws. See {@link ErrorFallback}. */
|
|
68
73
|
error?: ErrorFallback;
|
|
69
74
|
/** Called with the caught error. */
|
|
70
75
|
onError?: (error: Error) => void;
|
|
71
|
-
/** Clears the error fallback when any value changes — see {@link
|
|
76
|
+
/** Clears the error fallback when any value changes — see {@link CatchBoundaryProps.resetKeys}. */
|
|
72
77
|
resetKeys?: readonly unknown[];
|
|
73
78
|
children: ReactNode;
|
|
74
79
|
}
|
|
@@ -77,26 +82,25 @@ export interface BoundaryProps {
|
|
|
77
82
|
* section of a page. It always renders the same shape:
|
|
78
83
|
*
|
|
79
84
|
* ```tsx
|
|
80
|
-
* <
|
|
85
|
+
* <CatchBoundary fallback={error}>
|
|
81
86
|
* <Suspense fallback={loading}>{children}</Suspense>
|
|
82
|
-
* </
|
|
87
|
+
* </CatchBoundary>
|
|
83
88
|
* ```
|
|
84
89
|
*
|
|
85
90
|
* so `error` catches anything the children throw (including while suspended) and
|
|
86
|
-
* `loading` shows until they resolve.
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* being caught here.
|
|
91
|
+
* `loading` shows until they resolve. `error` is optional: omit it and thrown
|
|
92
|
+
* errors propagate to the next boundary out (or the global error page) rather
|
|
93
|
+
* than being caught here.
|
|
90
94
|
*
|
|
91
95
|
* @example
|
|
92
96
|
* ```tsx
|
|
93
|
-
* import {
|
|
97
|
+
* import { AsyncBoundary } from '@rshono/core/client';
|
|
94
98
|
*
|
|
95
|
-
* <
|
|
99
|
+
* <AsyncBoundary loading={<Spinner />} error={(e, reset) => <Retry onClick={reset} />}>
|
|
96
100
|
* <SlowServerComponent />
|
|
97
|
-
* </
|
|
101
|
+
* </AsyncBoundary>
|
|
98
102
|
* ```
|
|
99
103
|
*/
|
|
100
|
-
export declare function
|
|
104
|
+
export declare function AsyncBoundary({ loading, error, onError, resetKeys, children }: AsyncBoundaryProps): ReactNode;
|
|
101
105
|
export {};
|
|
102
106
|
//# sourceMappingURL=boundaries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundaries.d.ts","sourceRoot":"","sources":["../../src/runtime/boundaries.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAa5D;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC,CAAC;AAEzF,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAClF,KAAK,EAAE,kBAAkB,CAAmB;IAE5C,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB,CAEhE;IAED,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAGpC;IAED,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAKjD;IAED,KAAK,QAAO,IAAI,CAEd;IAEF,MAAM,IAAI,SAAS,CASlB;CACF;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"boundaries.d.ts","sourceRoot":"","sources":["../../src/runtime/boundaries.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAa5D;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC,CAAC;AAEzF,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAClF,KAAK,EAAE,kBAAkB,CAAmB;IAE5C,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB,CAEhE;IAED,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAGpC;IAED,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAKjD;IAED,KAAK,QAAO,IAAI,CAEd;IAEF,MAAM,IAAI,SAAS,CASlB;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,mGAAmG;IACnG,SAAS,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,kBAAkB,GAAG,SAAS,CAM7G"}
|
|
@@ -5,7 +5,7 @@ import { isControlDigest } from './control.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* `redirect()` and `notFound()` reach the browser as a thrown error carrying a control digest.
|
|
7
7
|
* They are navigation, not failure, so no boundary may absorb one — otherwise a `redirect()` from
|
|
8
|
-
* a component inside a `<
|
|
8
|
+
* a component inside a `<CatchBoundary>` would render "something went wrong" instead of navigating.
|
|
9
9
|
* They're re-thrown to the root, where the runtime turns the digest into a real navigation.
|
|
10
10
|
*/
|
|
11
11
|
function isControlError(error) {
|
|
@@ -21,24 +21,24 @@ function keysChanged(a, b) {
|
|
|
21
21
|
* tearing down the whole page.
|
|
22
22
|
*
|
|
23
23
|
* It's a `'use client'` component (React error boundaries must be), so drop it
|
|
24
|
-
* anywhere in the tree from a server or client component. Use {@link
|
|
24
|
+
* anywhere in the tree from a server or client component. Use {@link AsyncBoundary}
|
|
25
25
|
* when you also want a Suspense loading fallback in the same wrapper.
|
|
26
26
|
*
|
|
27
27
|
* @example
|
|
28
28
|
* ```tsx
|
|
29
|
-
* import {
|
|
29
|
+
* import { CatchBoundary } from '@rshono/core/client';
|
|
30
30
|
*
|
|
31
|
-
* <
|
|
31
|
+
* <CatchBoundary fallback={(error, reset) => (
|
|
32
32
|
* <div role="alert">
|
|
33
33
|
* <p>{error.message}</p>
|
|
34
34
|
* <button onClick={reset}>Try again</button>
|
|
35
35
|
* </div>
|
|
36
36
|
* )}>
|
|
37
37
|
* <RiskyWidget />
|
|
38
|
-
* </
|
|
38
|
+
* </CatchBoundary>
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
|
-
export class
|
|
41
|
+
export class CatchBoundary extends Component {
|
|
42
42
|
state = { error: null };
|
|
43
43
|
static getDerivedStateFromError(error) {
|
|
44
44
|
return { error };
|
|
@@ -75,27 +75,26 @@ export class ErrorBoundary extends Component {
|
|
|
75
75
|
* section of a page. It always renders the same shape:
|
|
76
76
|
*
|
|
77
77
|
* ```tsx
|
|
78
|
-
* <
|
|
78
|
+
* <CatchBoundary fallback={error}>
|
|
79
79
|
* <Suspense fallback={loading}>{children}</Suspense>
|
|
80
|
-
* </
|
|
80
|
+
* </CatchBoundary>
|
|
81
81
|
* ```
|
|
82
82
|
*
|
|
83
83
|
* so `error` catches anything the children throw (including while suspended) and
|
|
84
|
-
* `loading` shows until they resolve.
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* being caught here.
|
|
84
|
+
* `loading` shows until they resolve. `error` is optional: omit it and thrown
|
|
85
|
+
* errors propagate to the next boundary out (or the global error page) rather
|
|
86
|
+
* than being caught here.
|
|
88
87
|
*
|
|
89
88
|
* @example
|
|
90
89
|
* ```tsx
|
|
91
|
-
* import {
|
|
90
|
+
* import { AsyncBoundary } from '@rshono/core/client';
|
|
92
91
|
*
|
|
93
|
-
* <
|
|
92
|
+
* <AsyncBoundary loading={<Spinner />} error={(e, reset) => <Retry onClick={reset} />}>
|
|
94
93
|
* <SlowServerComponent />
|
|
95
|
-
* </
|
|
94
|
+
* </AsyncBoundary>
|
|
96
95
|
* ```
|
|
97
96
|
*/
|
|
98
|
-
export function
|
|
99
|
-
return (_jsx(
|
|
97
|
+
export function AsyncBoundary({ loading, error, onError, resetKeys, children }) {
|
|
98
|
+
return (_jsx(CatchBoundary, { fallback: error, onError: onError, resetKeys: resetKeys, children: _jsx(Suspense, { fallback: loading, children: children }) }));
|
|
100
99
|
}
|
|
101
100
|
//# sourceMappingURL=boundaries.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundaries.js","sourceRoot":"","sources":["../../src/runtime/boundaries.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;;GAKG;AACH,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,eAAe,CAAE,KAAqC,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AAmCD,SAAS,WAAW,CAAC,CAAqB,EAAE,CAAqB;IAC/D,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,aAAc,SAAQ,SAAiD;IAClF,KAAK,GAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAE5C,MAAM,CAAC,wBAAwB,CAAC,KAAY;QAC1C,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,iBAAiB,CAAC,KAAY;QAC5B,IAAI,cAAc,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,sCAAsC;QACzE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,kBAAkB,CAAC,IAAwB;QACzC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,IAAI,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;YAC9F,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,GAAG,GAAS,EAAE;QACjB,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,MAAM;QACJ,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,IAAI,cAAc,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC,CAAC,sDAAsD;YAC9F,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,KAAK,CAAC,CAAC,qDAAqD;YAC9F,OAAO,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACjF,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"boundaries.js","sourceRoot":"","sources":["../../src/runtime/boundaries.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;;GAKG;AACH,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,eAAe,CAAE,KAAqC,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AAmCD,SAAS,WAAW,CAAC,CAAqB,EAAE,CAAqB;IAC/D,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,aAAc,SAAQ,SAAiD;IAClF,KAAK,GAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAE5C,MAAM,CAAC,wBAAwB,CAAC,KAAY;QAC1C,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,iBAAiB,CAAC,KAAY;QAC5B,IAAI,cAAc,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,sCAAsC;QACzE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,kBAAkB,CAAC,IAAwB;QACzC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,IAAI,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;YAC9F,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,GAAG,GAAS,EAAE;QACjB,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,MAAM;QACJ,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,IAAI,cAAc,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC,CAAC,sDAAsD;YAC9F,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,KAAK,CAAC,CAAC,qDAAqD;YAC9F,OAAO,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACjF,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF;AAmBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAsB;IAChG,OAAO,CACL,KAAC,aAAa,IAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,YACpE,KAAC,QAAQ,IAAC,QAAQ,EAAE,OAAO,YAAG,QAAQ,GAAY,GACpC,CACjB,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport { Component, Suspense, type ReactNode } from 'react';\nimport { isControlDigest } from './control.js';\n\n/**\n * `redirect()` and `notFound()` reach the browser as a thrown error carrying a control digest.\n * They are navigation, not failure, so no boundary may absorb one — otherwise a `redirect()` from\n * a component inside a `<CatchBoundary>` would render \"something went wrong\" instead of navigating.\n * They're re-thrown to the root, where the runtime turns the digest into a real navigation.\n */\nfunction isControlError(error: unknown): boolean {\n return isControlDigest((error as { digest?: unknown } | null)?.digest);\n}\n\n/**\n * What a {@link CatchBoundary} / {@link AsyncBoundary} renders once a child throws.\n * Either a static node, or a render function that also gets a `reset` callback\n * to clear the error and re-render the children (e.g. a \"Try again\" button).\n *\n * The render-function form only works when the boundary is used from a `'use\n * client'` component — functions can't cross the server→client boundary. From a\n * server component, pass a `ReactNode`.\n */\nexport type ErrorFallback = ReactNode | ((error: Error, reset: () => void) => ReactNode);\n\nexport interface CatchBoundaryProps {\n /**\n * Rendered in place of the children after one of them throws. Omit it to\n * report the error via `onError` and re-throw to the next boundary out (or\n * the global error page) instead of handling it here.\n */\n fallback?: ErrorFallback;\n /** Called with the caught error (for logging / reporting). */\n onError?: (error: Error) => void;\n /**\n * When any value in this array changes while the boundary is showing its\n * fallback, the error is cleared automatically. Pass the current pathname to\n * recover when the user navigates away: `resetKeys={[useNavigation().url.pathname]}`.\n */\n resetKeys?: readonly unknown[];\n children: ReactNode;\n}\n\ninterface CatchBoundaryState {\n error: Error | null;\n}\n\nfunction keysChanged(a: readonly unknown[], b: readonly unknown[]): boolean {\n return a.length !== b.length || a.some((value, i) => !Object.is(value, b[i]));\n}\n\n/**\n * A general-purpose error boundary. Catches errors thrown while rendering its\n * children — a client island that blew up, or a server component that rejected\n * on a soft navigation — and renders `fallback` in their place instead of\n * tearing down the whole page.\n *\n * It's a `'use client'` component (React error boundaries must be), so drop it\n * anywhere in the tree from a server or client component. Use {@link AsyncBoundary}\n * when you also want a Suspense loading fallback in the same wrapper.\n *\n * @example\n * ```tsx\n * import { CatchBoundary } from '@rshono/core/client';\n *\n * <CatchBoundary fallback={(error, reset) => (\n * <div role=\"alert\">\n * <p>{error.message}</p>\n * <button onClick={reset}>Try again</button>\n * </div>\n * )}>\n * <RiskyWidget />\n * </CatchBoundary>\n * ```\n */\nexport class CatchBoundary extends Component<CatchBoundaryProps, CatchBoundaryState> {\n state: CatchBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): CatchBoundaryState {\n return { error };\n }\n\n componentDidCatch(error: Error): void {\n if (isControlError(error)) return; // a redirect isn't an error to report\n this.props.onError?.(error);\n }\n\n componentDidUpdate(prev: CatchBoundaryProps): void {\n const { resetKeys } = this.props;\n if (this.state.error && prev.resetKeys && resetKeys && keysChanged(prev.resetKeys, resetKeys)) {\n this.reset();\n }\n }\n\n reset = (): void => {\n this.setState({ error: null });\n };\n\n render(): ReactNode {\n const { error } = this.state;\n if (error !== null) {\n if (isControlError(error)) throw error; // navigation in flight — never show a fallback for it\n const { fallback } = this.props;\n if (fallback === undefined) throw error; // no local fallback → propagate to an outer boundary\n return typeof fallback === 'function' ? fallback(error, this.reset) : fallback;\n }\n return this.props.children;\n }\n}\n\nexport interface AsyncBoundaryProps {\n /**\n * Suspense fallback, shown while the children (or their data) are still\n * loading. Required — a loading state is the reason to reach for this over\n * {@link CatchBoundary}, so showing nothing is an explicit `loading={null}`\n * rather than something you get by leaving the prop off.\n */\n loading: ReactNode;\n /** Error fallback, shown if a child throws. See {@link ErrorFallback}. */\n error?: ErrorFallback;\n /** Called with the caught error. */\n onError?: (error: Error) => void;\n /** Clears the error fallback when any value changes — see {@link CatchBoundaryProps.resetKeys}. */\n resetKeys?: readonly unknown[];\n children: ReactNode;\n}\n\n/**\n * A loading + error boundary in one wrapper — the common case for an async\n * section of a page. It always renders the same shape:\n *\n * ```tsx\n * <CatchBoundary fallback={error}>\n * <Suspense fallback={loading}>{children}</Suspense>\n * </CatchBoundary>\n * ```\n *\n * so `error` catches anything the children throw (including while suspended) and\n * `loading` shows until they resolve. `error` is optional: omit it and thrown\n * errors propagate to the next boundary out (or the global error page) rather\n * than being caught here.\n *\n * @example\n * ```tsx\n * import { AsyncBoundary } from '@rshono/core/client';\n *\n * <AsyncBoundary loading={<Spinner />} error={(e, reset) => <Retry onClick={reset} />}>\n * <SlowServerComponent />\n * </AsyncBoundary>\n * ```\n */\nexport function AsyncBoundary({ loading, error, onError, resetKeys, children }: AsyncBoundaryProps): ReactNode {\n return (\n <CatchBoundary fallback={error} onError={onError} resetKeys={resetKeys}>\n <Suspense fallback={loading}>{children}</Suspense>\n </CatchBoundary>\n );\n}\n"]}
|
package/dist/runtime/client.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `@rshono/core/client` — the browser-side surface, for use from `'use client'`
|
|
3
3
|
* modules: {@link useNavigation} for the current URL and soft navigation, and
|
|
4
|
-
* {@link
|
|
4
|
+
* {@link AsyncBoundary} / {@link CatchBoundary} as components.
|
|
5
5
|
*
|
|
6
6
|
* Every export is itself a `'use client'` module, so a server component can
|
|
7
|
-
* render {@link
|
|
7
|
+
* render {@link AsyncBoundary} directly — but the hook needs a client component. In a
|
|
8
8
|
* server component, read the same request data from `getRequestContext()` in
|
|
9
9
|
* `@rshono/core/server`.
|
|
10
10
|
*
|
|
11
11
|
* @packageDocumentation
|
|
12
12
|
*/
|
|
13
13
|
export { useNavigation, type NavigationRouter, type NavigationState } from './navigation.js';
|
|
14
|
-
export {
|
|
14
|
+
export { AsyncBoundary, CatchBoundary, type AsyncBoundaryProps, type CatchBoundaryProps, type ErrorFallback } from './boundaries.js';
|
|
15
15
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/runtime/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/runtime/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/runtime/client.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `@rshono/core/client` — the browser-side surface, for use from `'use client'`
|
|
3
3
|
* modules: {@link useNavigation} for the current URL and soft navigation, and
|
|
4
|
-
* {@link
|
|
4
|
+
* {@link AsyncBoundary} / {@link CatchBoundary} as components.
|
|
5
5
|
*
|
|
6
6
|
* Every export is itself a `'use client'` module, so a server component can
|
|
7
|
-
* render {@link
|
|
7
|
+
* render {@link AsyncBoundary} directly — but the hook needs a client component. In a
|
|
8
8
|
* server component, read the same request data from `getRequestContext()` in
|
|
9
9
|
* `@rshono/core/server`.
|
|
10
10
|
*
|
|
11
11
|
* @packageDocumentation
|
|
12
12
|
*/
|
|
13
13
|
export { useNavigation } from './navigation.js';
|
|
14
|
-
export {
|
|
14
|
+
export { AsyncBoundary, CatchBoundary } from './boundaries.js';
|
|
15
15
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/runtime/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAA+C,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/runtime/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAA+C,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,aAAa,EAAwE,MAAM,iBAAiB,CAAC","sourcesContent":["/**\n * `@rshono/core/client` — the browser-side surface, for use from `'use client'`\n * modules: {@link useNavigation} for the current URL and soft navigation, and\n * {@link AsyncBoundary} / {@link CatchBoundary} as components.\n *\n * Every export is itself a `'use client'` module, so a server component can\n * render {@link AsyncBoundary} directly — but the hook needs a client component. In a\n * server component, read the same request data from `getRequestContext()` in\n * `@rshono/core/server`.\n *\n * @packageDocumentation\n */\n\nexport { useNavigation, type NavigationRouter, type NavigationState } from './navigation.js';\nexport { AsyncBoundary, CatchBoundary, type AsyncBoundaryProps, type CatchBoundaryProps, type ErrorFallback } from './boundaries.js';\n"]}
|
|
@@ -196,15 +196,29 @@ async function main() {
|
|
|
196
196
|
function BrowserRoot() {
|
|
197
197
|
const [payload, setPayloadState] = React.useState(initialPayload);
|
|
198
198
|
const [pending, startTransition] = React.useTransition();
|
|
199
|
+
// The scroll a fetched navigation still owes, held until its payload is on screen.
|
|
200
|
+
const pendingScroll = React.useRef(null);
|
|
199
201
|
React.useEffect(() => {
|
|
200
202
|
setPayload = (v) => setPayloadState(v);
|
|
201
203
|
startNav = (run) => startTransition(run);
|
|
202
204
|
}, [startTransition]);
|
|
205
|
+
/**
|
|
206
|
+
* Scrolls where the navigation asked, once React has put its payload in the DOM.
|
|
207
|
+
*
|
|
208
|
+
* This has to wait for the commit rather than the fetch: a `#hash` target does not exist until the
|
|
209
|
+
* new tree does, and until then the page a scroll would move is still the outgoing one. A layout
|
|
210
|
+
* effect runs before the browser paints, so the pre-scroll position is never on screen.
|
|
211
|
+
*/
|
|
212
|
+
React.useLayoutEffect(() => {
|
|
213
|
+
const scroll = pendingScroll.current;
|
|
214
|
+
pendingScroll.current = null;
|
|
215
|
+
scroll?.();
|
|
216
|
+
}, [payload]);
|
|
203
217
|
React.useEffect(() => {
|
|
204
218
|
const stopNavigating = listenNavigation((afterRender) => startNav(async () => {
|
|
205
219
|
try {
|
|
206
220
|
await fetchRscPayload();
|
|
207
|
-
afterRender
|
|
221
|
+
pendingScroll.current = afterRender;
|
|
208
222
|
}
|
|
209
223
|
catch {
|
|
210
224
|
window.location.reload();
|
|
@@ -326,12 +340,30 @@ function listenLinks() {
|
|
|
326
340
|
undo.push(() => document.removeEventListener('click', onClick));
|
|
327
341
|
return () => disposeAll(undo);
|
|
328
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* The element the current `#fragment` names, if it is on the page.
|
|
345
|
+
*
|
|
346
|
+
* A fragment in a URL is percent-encoded and an `id` attribute is not, so one has to be decoded into the
|
|
347
|
+
* other. A hand-written URL can carry a `%` that is not an escape, and `decodeURIComponent` throws on
|
|
348
|
+
* that rather than passing it through — in which case the fragment is taken literally, since that is the
|
|
349
|
+
* closest thing to an id it could have meant.
|
|
350
|
+
*/
|
|
351
|
+
function fragmentTarget() {
|
|
352
|
+
const fragment = location.hash.slice(1);
|
|
353
|
+
if (!fragment)
|
|
354
|
+
return null;
|
|
355
|
+
let id = fragment;
|
|
356
|
+
try {
|
|
357
|
+
id = decodeURIComponent(fragment);
|
|
358
|
+
}
|
|
359
|
+
catch { }
|
|
360
|
+
return document.getElementById(id);
|
|
361
|
+
}
|
|
329
362
|
function listenNavigation(onNavigation) {
|
|
330
363
|
const undo = [];
|
|
331
364
|
// Scroll restoration is the browser's. It used to be ours: each history entry was tagged with a key
|
|
332
365
|
// in `history.state`, `scrollY` was remembered per key, and `manual` handed restoration over — about
|
|
333
|
-
// 130 lines to restore a traversal exactly
|
|
334
|
-
// React had committed the new payload. `auto` is set explicitly rather than left at the default,
|
|
366
|
+
// 130 lines to restore a traversal exactly. `auto` is set explicitly rather than left at the default,
|
|
335
367
|
// because it is a statement: the browser remembers a traversal's offset for us.
|
|
336
368
|
const prevRestoration = window.history.scrollRestoration;
|
|
337
369
|
try {
|
|
@@ -347,18 +379,26 @@ function listenNavigation(onNavigation) {
|
|
|
347
379
|
/**
|
|
348
380
|
* A push is not a real navigation as far as the browser is concerned, so nothing resets the scroll
|
|
349
381
|
* offset — a click through to a new page would otherwise land wherever the last one was scrolled to.
|
|
350
|
-
* `
|
|
382
|
+
* A `#hash` on that link names where to land instead, and a fragment naming nothing on the page falls
|
|
383
|
+
* back to the top, which is what a browser does with one it cannot resolve. `replace` keeps its
|
|
384
|
+
* position deliberately, and a traversal is the browser's to restore.
|
|
351
385
|
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
386
|
+
* `scrollIntoView` rather than measuring the element and calling `scrollTo`: it is the same algorithm a
|
|
387
|
+
* browser's own fragment jump uses, so a `scroll-padding-top` — how an app clears a sticky header —
|
|
388
|
+
* still applies. Neither call passes a `behavior`, so `scroll-behavior: smooth` is likewise the app's
|
|
389
|
+
* to ask for.
|
|
354
390
|
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
391
|
+
* The caller decides *when* this runs, and for a navigation that fetched a payload that has to be
|
|
392
|
+
* after the commit — see the layout effect in `BrowserRoot`.
|
|
357
393
|
*/
|
|
358
394
|
const afterRenderFor = (type) => () => {
|
|
359
395
|
if (type !== 'push')
|
|
360
396
|
return;
|
|
361
|
-
|
|
397
|
+
const target = fragmentTarget();
|
|
398
|
+
if (target)
|
|
399
|
+
target.scrollIntoView();
|
|
400
|
+
else
|
|
401
|
+
window.scrollTo(0, 0);
|
|
362
402
|
};
|
|
363
403
|
const documentUrl = () => location.pathname + location.search;
|
|
364
404
|
// What the payload on screen was rendered for. Only the document part: the server never sees the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.client.js","sourceRoot":"","sources":["../../src/runtime/entry.client.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { hydrateRoot } from 'react-dom/client';\nimport {\n createFromFetch,\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n setServerCallback,\n} from 'react-server-dom-rspack/client.browser';\nimport { isControlDigest, parseRedirectDigest } from './control.js';\nimport type { DevMessage } from './dev-protocol.js';\nimport type { RscPayload } from './entry.rsc.js';\nimport { RouterContext, type NavigationRouter } from './navigation.js';\nimport { createRscRequest } from './request.js';\n\nconst isDev = process.env.NODE_ENV === 'development';\n\ndeclare global {\n /** The array the payload `<script>` tags `flight-inject.ts` emits push their chunks into. */\n var __FLIGHT_DATA: Array<string | Uint8Array> | undefined;\n}\n\n/**\n * The flight payload the document carried, read back out of `__FLIGHT_DATA`.\n *\n * The reader for the format `flight-inject.ts` writes — 14 lines, which is the whole reason neither\n * half of `rsc-html-stream` is a dependency: its server half mishandles a split document trailer\n * (see `flight-inject.ts`), and once that one is first-party, keeping the package for this one is a\n * dependency for a `for` loop.\n */\nfunction readFlightPayload(): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n // Assigned synchronously by `start`, which `new ReadableStream` runs before it returns.\n let controller!: ReadableStreamDefaultController<Uint8Array>;\n const stream = new ReadableStream<Uint8Array>({\n start: (c) => void (controller = c),\n });\n const enqueue = (chunk: string | Uint8Array) => controller.enqueue(typeof chunk === 'string' ? encoder.encode(chunk) : chunk);\n\n // Payload scripts interleave with the document, so some have already run by the time this module\n // is evaluated — those are in the array — and the rest run after it, arriving through `push`.\n const data = (self.__FLIGHT_DATA ??= []);\n for (const chunk of data) enqueue(chunk);\n data.push = enqueue as typeof data.push;\n\n // The last payload script lands before the document finishes parsing, so that is what says there\n // is no more of it to come.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => controller.close(), { once: true });\n } else {\n controller.close();\n }\n return stream;\n}\n\n/** Created at module evaluation, not inside `main()`, so no chunk can be pushed before it is watching. */\nconst flightStream = readFlightPayload();\n\n/**\n * Guarantees somewhere to attach the fatal overlay. React's root container is the whole `document`,\n * so by the time an uncaught error has torn the tree down, `<body>` — or even `<html>` — may be gone.\n */\nfunction overlayHost(): HTMLElement {\n if (!document.documentElement) document.appendChild(document.createElement('html'));\n if (!document.body) document.documentElement.appendChild(document.createElement('body'));\n return document.body;\n}\n\n/**\n * Replaces the white screen of death with something readable.\n *\n * Because the root container is `document`, an uncaught render error leaves a genuinely blank page\n * with the reason only in the console — so this paints the reason over it instead. In development\n * that's the full stack; in production it's a generic notice plus a reload button, since the tree is\n * unrecoverable and reloading is the only way forward.\n *\n * Written with DOM calls rather than React (the renderer is what just failed) and `textContent`\n * rather than `innerHTML` (an error message is untrusted input).\n */\nfunction showFatal(error: unknown, componentStack?: string | null): void {\n // Queued rather than run inline: React's teardown happens after this callback returns, and would\n // remove a node appended synchronously along with the rest of the tree.\n setTimeout(() => {\n const host = overlayHost();\n host.querySelector('[data-rshono-fatal]')?.remove();\n\n const box = document.createElement('div');\n box.setAttribute('data-rshono-fatal', '');\n box.setAttribute('role', 'alert'); // the page is gone; announce it rather than leaving silence\n box.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;overflow:auto;padding:1.5rem;background:#18181b;color:#f4f4f5;' +\n 'font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;text-align:left';\n\n const title = document.createElement('div');\n title.textContent = isDev ? 'Unhandled error' : 'Something went wrong';\n title.style.cssText = 'font-size:1.0625rem;font-weight:700;color:#f87171;margin:0 0 0.75rem';\n box.appendChild(title);\n\n if (isDev) {\n const detail = document.createElement('pre');\n detail.style.cssText = 'margin:0;white-space:pre-wrap;word-break:break-word';\n detail.textContent =\n (error instanceof Error ? (error.stack ?? `${error.name}: ${error.message}`) : String(error)) +\n (componentStack ? `\\n\\nComponent stack:${componentStack}` : '');\n box.appendChild(detail);\n } else {\n const message = document.createElement('p');\n message.textContent = 'This page hit an unexpected error and can’t continue.';\n message.style.cssText = 'margin:0 0 1rem;color:#d4d4d8';\n box.appendChild(message);\n }\n\n const reload = document.createElement('button');\n reload.textContent = 'Reload page';\n reload.style.cssText =\n 'margin-top:1.25rem;padding:0.5rem 1rem;font:inherit;color:#18181b;background:#f4f4f5;border:0;border-radius:4px;cursor:pointer';\n reload.addEventListener('click', () => window.location.reload());\n box.appendChild(reload);\n\n host.appendChild(box);\n }, 0);\n}\n\n/**\n * Asks a URL for its flight payload.\n *\n * There is no cache in front of this any more. A `data-prefetch` attribute used to warm one on\n * hover/focus, keyed by same-origin path+search and bounded to 8 entries — worth knowing about if you\n * are wondering where the speculative fetching went. Every navigation is now a fetch at the moment it\n * is asked for, so a payload can never be staler than the click that wanted it, and the browser's own\n * HTTP cache is what makes a repeat visit cheap.\n */\nfunction requestPayload(href: string): Promise<RscPayload> {\n return createFromFetch<RscPayload>(fetch(createRscRequest(new URL(href, location.href).href)));\n}\n\nasync function main() {\n const cspMeta = document.querySelector('meta[property=\"csp-nonce\"]') as HTMLMetaElement | null;\n if (cspMeta?.nonce) __webpack_nonce__ = cspMeta.nonce;\n\n // Both are replaced by BrowserRoot's own on mount. The defaults matter: `setServerCallback` is\n // registered before hydration, so an action or refresh firing in that window would otherwise call\n // an unassigned binding. Until there's a root to update, a full reload is the honest fallback.\n let setPayload: (v: RscPayload) => void = () => {\n window.location.reload();\n };\n // Runs work inside the nav transition so useNavigation().pending stays true across the round-trip.\n let startNav: (run: () => void | Promise<void>) => void = (run) => {\n void run();\n };\n\n const initialPayload = await createFromReadableStream<RscPayload>(flightStream);\n\n function push(href: string) {\n const target = new URL(href, window.location.href);\n if (target.origin !== window.location.origin) {\n window.location.assign(target.href);\n return;\n }\n window.history.pushState(null, '', target.href);\n }\n\n function replace(href: string) {\n const target = new URL(href, window.location.href);\n if (target.origin !== window.location.origin) {\n window.location.replace(target.href);\n return;\n }\n window.history.replaceState(null, '', target.href);\n }\n\n // A refresh keeps the URL, so it can't ride the history patch like push/replace — it drives the\n // flight re-fetch directly.\n const refresh = () =>\n startNav(async () => {\n try {\n await fetchRscPayload();\n } catch {\n window.location.reload();\n }\n });\n\n /**\n * Turns a control-signal digest — how `redirect()` / `notFound()` reach the browser — into a real\n * navigation. Returns false for anything else, so callers can fall through to their own handling.\n *\n * `hard` forces a full document load, for signals that surfaced *through React* (a nested\n * component's redirect, reported via the root error handlers). React unmounts the root on an\n * uncaught error, so there is no live tree left to soft-navigate with. A signal caught earlier —\n * a top-level payload rejection — still swaps the payload in place.\n */\n function handleControlDigest(error: unknown, { hard = false }: { hard?: boolean } = {}): boolean {\n const digest = (error as { digest?: unknown } | null)?.digest;\n if (!isControlDigest(digest)) return false;\n const redirect = parseRedirectDigest(digest);\n if (!redirect) {\n window.location.reload();\n } else if (hard) {\n window.location.assign(new URL(redirect.location, window.location.href).href);\n } else {\n push(redirect.location);\n }\n return true;\n }\n\n async function fetchRscPayload() {\n let payload: RscPayload;\n try {\n payload = await requestPayload(window.location.href);\n } catch (error) {\n if (handleControlDigest(error)) return;\n throw error;\n }\n if (payload.redirect) return push(payload.redirect);\n setPayload(payload);\n }\n\n function BrowserRoot() {\n const [payload, setPayloadState] = React.useState(initialPayload);\n const [pending, startTransition] = React.useTransition();\n\n React.useEffect(() => {\n setPayload = (v) => setPayloadState(v);\n startNav = (run) => startTransition(run);\n }, [startTransition]);\n\n React.useEffect(() => {\n const stopNavigating = listenNavigation((afterRender) =>\n startNav(async () => {\n try {\n await fetchRscPayload();\n afterRender();\n } catch {\n window.location.reload();\n }\n }),\n );\n const stopUpgradingLinks = listenLinks();\n return () => {\n stopUpgradingLinks();\n stopNavigating();\n };\n }, []);\n\n const router = React.useMemo<NavigationRouter>(() => ({ push, replace, refresh, pending }), [pending]);\n\n return <RouterContext.Provider value={router}>{payload.root}</RouterContext.Provider>;\n }\n\n setServerCallback(async (id, args) => {\n const temporaryReferences = createTemporaryReferenceSet();\n const request = createRscRequest(window.location.href, {\n id,\n body: await encodeReply(args, { temporaryReferences }),\n });\n let payload: RscPayload;\n try {\n payload = await createFromFetch<RscPayload>(fetch(request), { temporaryReferences });\n } catch (error) {\n if (handleControlDigest(error)) return undefined;\n throw error;\n }\n if (payload.redirect) {\n push(payload.redirect);\n return undefined;\n }\n React.startTransition(() => setPayload(payload));\n if (payload.notFound) return undefined;\n const result = payload.returnValue!;\n if (!result.ok) throw result.error;\n return result.value;\n });\n\n // A `redirect()` / `notFound()` from a component *below* the page root can only reach us through\n // React: it rides the flight payload as an error at that component's position, and boundaries\n // re-throw it (see boundaries.tsx) so it lands here rather than rendering an error fallback.\n //\n // Anything that isn't a control signal falls back to what React would have done on its own —\n // console for a caught error, `reportError` (i.e. window.onerror, so error-reporting tools still\n // see it) for an uncaught one. Overriding these hooks means opting out of that default, so it has\n // to be put back by hand.\n hydrateRoot(document, <BrowserRoot />, {\n formState: initialPayload.formState,\n onCaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // A boundary handled this and the tree is intact, so no overlay: whatever fallback the app\n // chose is the right thing to have on screen.\n console.error(error, errorInfo.componentStack ?? '');\n },\n onUncaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // Nothing caught it, so React tears the root down — and the root is `document`. This is the\n // white screen; paint the reason over it.\n globalThis.reportError(error);\n showFatal(error, errorInfo.componentStack);\n },\n });\n\n if (import.meta.webpackHot) {\n initDevRefresh(fetchRscPayload);\n }\n}\n\ntype NavigationType = 'push' | 'replace' | 'pop';\n\n/**\n * Runs teardown in reverse and empties the list, so a second call is a no-op.\n *\n * Collecting these as setup goes keeps each undo next to the thing it undoes: a listener added\n * without one is visible on the spot, rather than as a leak found later against a teardown block\n * that drifted out of sync.\n */\nfunction disposeAll(undo: Array<() => void>): void {\n for (const dispose of undo.splice(0).reverse()) dispose();\n}\n\n// An `<a>` we intercept for soft navigation: same-origin, same tab, not a download,\n// and not explicitly opted out with `data-native` (which forces a full browser navigation).\nfunction isRouterLink(link: HTMLAnchorElement): boolean {\n return (\n !!link.href &&\n (!link.target || link.target === '_self') &&\n link.origin === location.origin &&\n !link.hasAttribute('download') &&\n !link.hasAttribute('data-native')\n );\n}\n\n/**\n * Upgrades the app's anchors: a plain left-click becomes a soft navigation.\n *\n * Kept apart from `listenNavigation` because the two share no state. A click here only calls\n * `history.pushState` — which is where that function picks the navigation up — so the whole contract\n * between them is one global the browser already provides.\n */\nfunction listenLinks(): () => void {\n const undo: Array<() => void> = [];\n\n function onClick(e: MouseEvent) {\n const link = (e.target as Element).closest('a');\n if (\n link &&\n link instanceof HTMLAnchorElement &&\n isRouterLink(link) &&\n e.button === 0 &&\n !e.metaKey &&\n !e.ctrlKey &&\n !e.altKey &&\n !e.shiftKey &&\n !e.defaultPrevented\n ) {\n if (link.hash && link.pathname === location.pathname && link.search === location.search) return;\n e.preventDefault();\n history.pushState(null, '', link.href);\n }\n }\n document.addEventListener('click', onClick);\n undo.push(() => document.removeEventListener('click', onClick));\n\n return () => disposeAll(undo);\n}\n\nfunction listenNavigation(onNavigation: (afterRender: () => void) => void): () => void {\n const undo: Array<() => void> = [];\n\n // Scroll restoration is the browser's. It used to be ours: each history entry was tagged with a key\n // in `history.state`, `scrollY` was remembered per key, and `manual` handed restoration over — about\n // 130 lines to restore a traversal exactly and to chase a `#hash` target across the frames before\n // React had committed the new payload. `auto` is set explicitly rather than left at the default,\n // because it is a statement: the browser remembers a traversal's offset for us.\n const prevRestoration = window.history.scrollRestoration;\n try {\n window.history.scrollRestoration = 'auto';\n } catch {}\n undo.push(() => {\n try {\n window.history.scrollRestoration = prevRestoration;\n } catch {}\n });\n\n /**\n * A push is not a real navigation as far as the browser is concerned, so nothing resets the scroll\n * offset — a click through to a new page would otherwise land wherever the last one was scrolled to.\n * `replace` keeps its position deliberately, and a traversal is the browser's to restore.\n *\n * Deferred a frame because the payload is *set* before React commits it, so the layout being scrolled\n * is still the outgoing one until one has passed.\n *\n * A `#hash` on a cross-page link is no longer chased: the target does not exist until the new payload\n * commits, and following it was the other half of what came out with the scroll memory.\n */\n const afterRenderFor = (type: NavigationType) => () => {\n if (type !== 'push') return;\n requestAnimationFrame(() => window.scrollTo(0, 0));\n };\n\n const documentUrl = () => location.pathname + location.search;\n\n // What the payload on screen was rendered for. Only the document part: the server never sees the\n // fragment, so two URLs differing by one render identically.\n let renderedUrl = documentUrl();\n\n /**\n * A navigation that moves only the fragment — `#a` → `#b`, or back out of a same-page anchor —\n * leaves the document unchanged, so the payload already on screen is the right one. Fetching\n * another would be a wasted round-trip that re-renders the page out from under the jump.\n *\n * `router.refresh()` is unaffected: it drives the re-fetch directly rather than through here, and\n * remains the way to ask for fresh data at an unchanged URL.\n */\n const notify = (type: NavigationType) => {\n const afterRender = afterRenderFor(type);\n if (documentUrl() === renderedUrl) {\n afterRender();\n return;\n }\n renderedUrl = documentUrl();\n onNavigation(afterRender);\n };\n\n const onPopState = () => notify('pop');\n window.addEventListener('popstate', onPopState);\n undo.push(() => window.removeEventListener('popstate', onPopState));\n\n const oldPushState = window.history.pushState;\n window.history.pushState = function (state, unused, url) {\n const res = oldPushState.call(this, state, unused, url as string);\n notify('push');\n return res;\n };\n undo.push(() => {\n window.history.pushState = oldPushState;\n });\n\n const oldReplaceState = window.history.replaceState;\n window.history.replaceState = function (state, unused, url) {\n const res = oldReplaceState.call(this, state, unused, url as string);\n notify('replace');\n return res;\n };\n undo.push(() => {\n window.history.replaceState = oldReplaceState;\n });\n\n return () => disposeAll(undo);\n}\n\n/**\n * Dev-only refresh client (stripped from prod bundles: the whole call is\n * guarded by import.meta.webpackHot). Listens to the CLI's SSE endpoint:\n *\n * client-built → hot-apply the waiting updates (react-refresh keeps\n * component state); any failure falls back to reload.\n * rsc-update → server component code changed: re-fetch the flight\n * payload for the current URL, state preserved.\n * hello → sent on (re)connect with the latest build hash; a\n * mismatch means events were missed — resync.\n */\nfunction initDevRefresh(fetchRscPayload: () => Promise<void>) {\n let connectedOnce = false;\n\n async function applyClientUpdate(hash: string) {\n const hot = import.meta.webpackHot!;\n if (hash === __webpack_hash__) return;\n if (hot.status() !== 'idle') {\n window.location.reload();\n return;\n }\n try {\n await hot.check(true);\n if (hash !== __webpack_hash__) await applyClientUpdate(hash);\n } catch (error) {\n console.warn('[rshono] hot update failed, reloading:', error);\n window.location.reload();\n }\n }\n\n const source = new EventSource('/_rshono/hmr');\n source.onmessage = async (event) => {\n const message = JSON.parse(event.data) as DevMessage;\n switch (message.type) {\n case 'hello':\n if (connectedOnce) {\n if (message.hash && message.hash !== __webpack_hash__) await applyClientUpdate(message.hash);\n await fetchRscPayload().catch(() => window.location.reload());\n }\n connectedOnce = true;\n break;\n case 'client-built':\n if (message.hash) await applyClientUpdate(message.hash);\n break;\n case 'rsc-update':\n console.log('[rshono] server components updated');\n await fetchRscPayload().catch(() => window.location.reload());\n break;\n }\n };\n}\n\n// Bootstrap failures (a truncated or malformed initial flight payload, most likely) would otherwise\n// be an unhandled rejection: nothing hydrates, nothing is reported, and the page just sits there.\nmain().catch((error) => {\n console.error('[rshono] the client runtime failed to start:', error);\n showFatal(error);\n});\n"]}
|
|
1
|
+
{"version":3,"file":"entry.client.js","sourceRoot":"","sources":["../../src/runtime/entry.client.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,2BAA2B,EAC3B,WAAW,EACX,iBAAiB,GAClB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAyB,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;AAOrD;;;;;;;GAOG;AACH,SAAS,iBAAiB;IACxB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,wFAAwF;IACxF,IAAI,UAAwD,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,cAAc,CAAa;QAC5C,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;KACpC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,CAAC,KAA0B,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAE9H,iGAAiG;IACjG,8FAA8F;IAC9F,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,KAAK,EAAE,CAAC,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,IAAI;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,GAAG,OAA2B,CAAC;IAExC,iGAAiG;IACjG,4BAA4B;IAC5B,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACtC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1F,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0GAA0G;AAC1G,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAC;AAEzC;;;GAGG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC,QAAQ,CAAC,eAAe;QAAE,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ,CAAC,IAAI;QAAE,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,SAAS,CAAC,KAAc,EAAE,cAA8B;IAC/D,iGAAiG;IACjG,wEAAwE;IACxE,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;QAEpD,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1C,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAC1C,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,4DAA4D;QAC/F,GAAG,CAAC,KAAK,CAAC,OAAO;YACf,0GAA0G;gBAC1G,2EAA2E,CAAC;QAE9E,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5C,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,sBAAsB,CAAC;QACvE,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,sEAAsE,CAAC;QAC7F,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEvB,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,qDAAqD,CAAC;YAC7E,MAAM,CAAC,WAAW;gBAChB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC7F,CAAC,cAAc,CAAC,CAAC,CAAC,uBAAuB,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClE,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,CAAC,WAAW,GAAG,uDAAuD,CAAC;YAC9E,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,+BAA+B,CAAC;YACxD,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,WAAW,GAAG,aAAa,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,OAAO;YAClB,gIAAgI,CAAC;QACnI,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAExB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC,EAAE,CAAC,CAAC,CAAC;AACR,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,eAAe,CAAa,KAAK,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,4BAA4B,CAA2B,CAAC;IAC/F,IAAI,OAAO,EAAE,KAAK;QAAE,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC;IAEtD,+FAA+F;IAC/F,kGAAkG;IAClG,+FAA+F;IAC/F,IAAI,UAAU,GAA4B,GAAG,EAAE;QAC7C,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC3B,CAAC,CAAC;IACF,mGAAmG;IACnG,IAAI,QAAQ,GAA8C,CAAC,GAAG,EAAE,EAAE;QAChE,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,wBAAwB,CAAa,YAAY,CAAC,CAAC;IAEhF,SAAS,IAAI,CAAC,IAAY;QACxB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,SAAS,OAAO,CAAC,IAAY;QAC3B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,gGAAgG;IAChG,4BAA4B;IAC5B,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,QAAQ,CAAC,KAAK,IAAI,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,eAAe,EAAE,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC,CAAC;IAEL;;;;;;;;OAQG;IACH,SAAS,mBAAmB,CAAC,KAAc,EAAE,EAAE,IAAI,GAAG,KAAK,EAAE,GAAuB,EAAE;QACpF,MAAM,MAAM,GAAI,KAAqC,EAAE,MAAM,CAAC;QAC9D,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,UAAU,eAAe;QAC5B,IAAI,OAAmB,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,mBAAmB,CAAC,KAAK,CAAC;gBAAE,OAAO;YACvC,MAAM,KAAK,CAAC;QACd,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpD,UAAU,CAAC,OAAO,CAAC,CAAC;IACtB,CAAC;IAED,SAAS,WAAW;QAClB,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAClE,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QACzD,mFAAmF;QACnF,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAsB,IAAI,CAAC,CAAC;QAE9D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YACnB,UAAU,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACvC,QAAQ,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;QAEtB;;;;;;WAMG;QACH,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE;YACzB,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC;YACrC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;YAC7B,MAAM,EAAE,EAAE,CAAC;QACb,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAEd,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YACnB,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,WAAW,EAAE,EAAE,CACtD,QAAQ,CAAC,KAAK,IAAI,EAAE;gBAClB,IAAI,CAAC;oBACH,MAAM,eAAe,EAAE,CAAC;oBACxB,aAAa,CAAC,OAAO,GAAG,WAAW,CAAC;gBACtC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAC3B,CAAC;YACH,CAAC,CAAC,CACH,CAAC;YACF,MAAM,kBAAkB,GAAG,WAAW,EAAE,CAAC;YACzC,OAAO,GAAG,EAAE;gBACV,kBAAkB,EAAE,CAAC;gBACrB,cAAc,EAAE,CAAC;YACnB,CAAC,CAAC;QACJ,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAmB,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAEvG,OAAO,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAAG,OAAO,CAAC,IAAI,GAA0B,CAAC;IACxF,CAAC;IAED,iBAAiB,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;QACnC,MAAM,mBAAmB,GAAG,2BAA2B,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;YACrD,EAAE;YACF,IAAI,EAAE,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,mBAAmB,EAAE,CAAC;SACvD,CAAC,CAAC;QACH,IAAI,OAAmB,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,eAAe,CAAa,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACvF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,mBAAmB,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,WAAY,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,MAAM,CAAC,KAAK,CAAC;QACnC,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,iGAAiG;IACjG,8FAA8F;IAC9F,6FAA6F;IAC7F,EAAE;IACF,6FAA6F;IAC7F,iGAAiG;IACjG,kGAAkG;IAClG,0BAA0B;IAC1B,WAAW,CAAC,QAAQ,EAAE,KAAC,WAAW,KAAG,EAAE;QACrC,SAAS,EAAE,cAAc,CAAC,SAAS;QACnC,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;YAClC,IAAI,mBAAmB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAAE,OAAO;YACvD,2FAA2F;YAC3F,8CAA8C;YAC9C,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,eAAe,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;YACpC,IAAI,mBAAmB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAAE,OAAO;YACvD,4FAA4F;YAC5F,0CAA0C;YAC1C,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC9B,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,cAAc,CAAC,eAAe,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAID;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,IAAuB;IACzC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,CAAC;AAC5D,CAAC;AAED,oFAAoF;AACpF,4FAA4F;AAC5F,SAAS,YAAY,CAAC,IAAuB;IAC3C,OAAO,CACL,CAAC,CAAC,IAAI,CAAC,IAAI;QACX,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC;QACzC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;QAC/B,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;QAC9B,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAClC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW;IAClB,MAAM,IAAI,GAAsB,EAAE,CAAC;IAEnC,SAAS,OAAO,CAAC,CAAa;QAC5B,MAAM,IAAI,GAAI,CAAC,CAAC,MAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IACE,IAAI;YACJ,IAAI,YAAY,iBAAiB;YACjC,YAAY,CAAC,IAAI,CAAC;YAClB,CAAC,CAAC,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,CAAC,OAAO;YACV,CAAC,CAAC,CAAC,OAAO;YACV,CAAC,CAAC,CAAC,MAAM;YACT,CAAC,CAAC,CAAC,QAAQ;YACX,CAAC,CAAC,CAAC,gBAAgB,EACnB,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;gBAAE,OAAO;YAChG,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IACD,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAEhE,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc;IACrB,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,EAAE,GAAG,QAAQ,CAAC;IAClB,IAAI,CAAC;QACH,EAAE,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,gBAAgB,CAAC,YAA+C;IACvE,MAAM,IAAI,GAAsB,EAAE,CAAC;IAEnC,oGAAoG;IACpG,qGAAqG;IACrG,sGAAsG;IACtG,gFAAgF;IAChF,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,MAAM,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACb,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,eAAe,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH;;;;;;;;;;;;;;OAcG;IACH,MAAM,cAAc,GAAG,CAAC,IAAoB,EAAE,EAAE,CAAC,GAAG,EAAE;QACpD,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO;QAC5B,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;QAChC,IAAI,MAAM;YAAE,MAAM,CAAC,cAAc,EAAE,CAAC;;YAC/B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE9D,iGAAiG;IACjG,6DAA6D;IAC7D,IAAI,WAAW,GAAG,WAAW,EAAE,CAAC;IAEhC;;;;;;;OAOG;IACH,MAAM,MAAM,GAAG,CAAC,IAAoB,EAAE,EAAE;QACtC,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,WAAW,EAAE,KAAK,WAAW,EAAE,CAAC;YAClC,WAAW,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QACD,WAAW,GAAG,WAAW,EAAE,CAAC;QAC5B,YAAY,CAAC,WAAW,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAEpE,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;IAC9C,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,UAAU,KAAK,EAAE,MAAM,EAAE,GAAG;QACrD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAa,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC;QACf,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;IACpD,MAAM,CAAC,OAAO,CAAC,YAAY,GAAG,UAAU,KAAK,EAAE,MAAM,EAAE,GAAG;QACxD,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAa,CAAC,CAAC;QACrE,MAAM,CAAC,SAAS,CAAC,CAAC;QAClB,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,OAAO,CAAC,YAAY,GAAG,eAAe,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,cAAc,CAAC,eAAoC;IAC1D,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,KAAK,UAAU,iBAAiB,CAAC,IAAY;QAC3C,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,UAAW,CAAC;QACpC,IAAI,IAAI,KAAK,gBAAgB;YAAE,OAAO;QACtC,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,IAAI,KAAK,gBAAgB;gBAAE,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;YAC9D,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,CAAC,SAAS,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;QACrD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,OAAO;gBACV,IAAI,aAAa,EAAE,CAAC;oBAClB,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,gBAAgB;wBAAE,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAC7F,MAAM,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBAChE,CAAC;gBACD,aAAa,GAAG,IAAI,CAAC;gBACrB,MAAM;YACR,KAAK,cAAc;gBACjB,IAAI,OAAO,CAAC,IAAI;oBAAE,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACxD,MAAM;YACR,KAAK,YAAY;gBACf,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;gBAClD,MAAM,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC9D,MAAM;QACV,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,kGAAkG;AAClG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;IACrE,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { hydrateRoot } from 'react-dom/client';\nimport {\n createFromFetch,\n createFromReadableStream,\n createTemporaryReferenceSet,\n encodeReply,\n setServerCallback,\n} from 'react-server-dom-rspack/client.browser';\nimport { isControlDigest, parseRedirectDigest } from './control.js';\nimport type { DevMessage } from './dev-protocol.js';\nimport type { RscPayload } from './entry.rsc.js';\nimport { RouterContext, type NavigationRouter } from './navigation.js';\nimport { createRscRequest } from './request.js';\n\nconst isDev = process.env.NODE_ENV === 'development';\n\ndeclare global {\n /** The array the payload `<script>` tags `flight-inject.ts` emits push their chunks into. */\n var __FLIGHT_DATA: Array<string | Uint8Array> | undefined;\n}\n\n/**\n * The flight payload the document carried, read back out of `__FLIGHT_DATA`.\n *\n * The reader for the format `flight-inject.ts` writes — 14 lines, which is the whole reason neither\n * half of `rsc-html-stream` is a dependency: its server half mishandles a split document trailer\n * (see `flight-inject.ts`), and once that one is first-party, keeping the package for this one is a\n * dependency for a `for` loop.\n */\nfunction readFlightPayload(): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n // Assigned synchronously by `start`, which `new ReadableStream` runs before it returns.\n let controller!: ReadableStreamDefaultController<Uint8Array>;\n const stream = new ReadableStream<Uint8Array>({\n start: (c) => void (controller = c),\n });\n const enqueue = (chunk: string | Uint8Array) => controller.enqueue(typeof chunk === 'string' ? encoder.encode(chunk) : chunk);\n\n // Payload scripts interleave with the document, so some have already run by the time this module\n // is evaluated — those are in the array — and the rest run after it, arriving through `push`.\n const data = (self.__FLIGHT_DATA ??= []);\n for (const chunk of data) enqueue(chunk);\n data.push = enqueue as typeof data.push;\n\n // The last payload script lands before the document finishes parsing, so that is what says there\n // is no more of it to come.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => controller.close(), { once: true });\n } else {\n controller.close();\n }\n return stream;\n}\n\n/** Created at module evaluation, not inside `main()`, so no chunk can be pushed before it is watching. */\nconst flightStream = readFlightPayload();\n\n/**\n * Guarantees somewhere to attach the fatal overlay. React's root container is the whole `document`,\n * so by the time an uncaught error has torn the tree down, `<body>` — or even `<html>` — may be gone.\n */\nfunction overlayHost(): HTMLElement {\n if (!document.documentElement) document.appendChild(document.createElement('html'));\n if (!document.body) document.documentElement.appendChild(document.createElement('body'));\n return document.body;\n}\n\n/**\n * Replaces the white screen of death with something readable.\n *\n * Because the root container is `document`, an uncaught render error leaves a genuinely blank page\n * with the reason only in the console — so this paints the reason over it instead. In development\n * that's the full stack; in production it's a generic notice plus a reload button, since the tree is\n * unrecoverable and reloading is the only way forward.\n *\n * Written with DOM calls rather than React (the renderer is what just failed) and `textContent`\n * rather than `innerHTML` (an error message is untrusted input).\n */\nfunction showFatal(error: unknown, componentStack?: string | null): void {\n // Queued rather than run inline: React's teardown happens after this callback returns, and would\n // remove a node appended synchronously along with the rest of the tree.\n setTimeout(() => {\n const host = overlayHost();\n host.querySelector('[data-rshono-fatal]')?.remove();\n\n const box = document.createElement('div');\n box.setAttribute('data-rshono-fatal', '');\n box.setAttribute('role', 'alert'); // the page is gone; announce it rather than leaving silence\n box.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;overflow:auto;padding:1.5rem;background:#18181b;color:#f4f4f5;' +\n 'font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;text-align:left';\n\n const title = document.createElement('div');\n title.textContent = isDev ? 'Unhandled error' : 'Something went wrong';\n title.style.cssText = 'font-size:1.0625rem;font-weight:700;color:#f87171;margin:0 0 0.75rem';\n box.appendChild(title);\n\n if (isDev) {\n const detail = document.createElement('pre');\n detail.style.cssText = 'margin:0;white-space:pre-wrap;word-break:break-word';\n detail.textContent =\n (error instanceof Error ? (error.stack ?? `${error.name}: ${error.message}`) : String(error)) +\n (componentStack ? `\\n\\nComponent stack:${componentStack}` : '');\n box.appendChild(detail);\n } else {\n const message = document.createElement('p');\n message.textContent = 'This page hit an unexpected error and can’t continue.';\n message.style.cssText = 'margin:0 0 1rem;color:#d4d4d8';\n box.appendChild(message);\n }\n\n const reload = document.createElement('button');\n reload.textContent = 'Reload page';\n reload.style.cssText =\n 'margin-top:1.25rem;padding:0.5rem 1rem;font:inherit;color:#18181b;background:#f4f4f5;border:0;border-radius:4px;cursor:pointer';\n reload.addEventListener('click', () => window.location.reload());\n box.appendChild(reload);\n\n host.appendChild(box);\n }, 0);\n}\n\n/**\n * Asks a URL for its flight payload.\n *\n * There is no cache in front of this any more. A `data-prefetch` attribute used to warm one on\n * hover/focus, keyed by same-origin path+search and bounded to 8 entries — worth knowing about if you\n * are wondering where the speculative fetching went. Every navigation is now a fetch at the moment it\n * is asked for, so a payload can never be staler than the click that wanted it, and the browser's own\n * HTTP cache is what makes a repeat visit cheap.\n */\nfunction requestPayload(href: string): Promise<RscPayload> {\n return createFromFetch<RscPayload>(fetch(createRscRequest(new URL(href, location.href).href)));\n}\n\nasync function main() {\n const cspMeta = document.querySelector('meta[property=\"csp-nonce\"]') as HTMLMetaElement | null;\n if (cspMeta?.nonce) __webpack_nonce__ = cspMeta.nonce;\n\n // Both are replaced by BrowserRoot's own on mount. The defaults matter: `setServerCallback` is\n // registered before hydration, so an action or refresh firing in that window would otherwise call\n // an unassigned binding. Until there's a root to update, a full reload is the honest fallback.\n let setPayload: (v: RscPayload) => void = () => {\n window.location.reload();\n };\n // Runs work inside the nav transition so useNavigation().pending stays true across the round-trip.\n let startNav: (run: () => void | Promise<void>) => void = (run) => {\n void run();\n };\n\n const initialPayload = await createFromReadableStream<RscPayload>(flightStream);\n\n function push(href: string) {\n const target = new URL(href, window.location.href);\n if (target.origin !== window.location.origin) {\n window.location.assign(target.href);\n return;\n }\n window.history.pushState(null, '', target.href);\n }\n\n function replace(href: string) {\n const target = new URL(href, window.location.href);\n if (target.origin !== window.location.origin) {\n window.location.replace(target.href);\n return;\n }\n window.history.replaceState(null, '', target.href);\n }\n\n // A refresh keeps the URL, so it can't ride the history patch like push/replace — it drives the\n // flight re-fetch directly.\n const refresh = () =>\n startNav(async () => {\n try {\n await fetchRscPayload();\n } catch {\n window.location.reload();\n }\n });\n\n /**\n * Turns a control-signal digest — how `redirect()` / `notFound()` reach the browser — into a real\n * navigation. Returns false for anything else, so callers can fall through to their own handling.\n *\n * `hard` forces a full document load, for signals that surfaced *through React* (a nested\n * component's redirect, reported via the root error handlers). React unmounts the root on an\n * uncaught error, so there is no live tree left to soft-navigate with. A signal caught earlier —\n * a top-level payload rejection — still swaps the payload in place.\n */\n function handleControlDigest(error: unknown, { hard = false }: { hard?: boolean } = {}): boolean {\n const digest = (error as { digest?: unknown } | null)?.digest;\n if (!isControlDigest(digest)) return false;\n const redirect = parseRedirectDigest(digest);\n if (!redirect) {\n window.location.reload();\n } else if (hard) {\n window.location.assign(new URL(redirect.location, window.location.href).href);\n } else {\n push(redirect.location);\n }\n return true;\n }\n\n async function fetchRscPayload() {\n let payload: RscPayload;\n try {\n payload = await requestPayload(window.location.href);\n } catch (error) {\n if (handleControlDigest(error)) return;\n throw error;\n }\n if (payload.redirect) return push(payload.redirect);\n setPayload(payload);\n }\n\n function BrowserRoot() {\n const [payload, setPayloadState] = React.useState(initialPayload);\n const [pending, startTransition] = React.useTransition();\n // The scroll a fetched navigation still owes, held until its payload is on screen.\n const pendingScroll = React.useRef<(() => void) | null>(null);\n\n React.useEffect(() => {\n setPayload = (v) => setPayloadState(v);\n startNav = (run) => startTransition(run);\n }, [startTransition]);\n\n /**\n * Scrolls where the navigation asked, once React has put its payload in the DOM.\n *\n * This has to wait for the commit rather than the fetch: a `#hash` target does not exist until the\n * new tree does, and until then the page a scroll would move is still the outgoing one. A layout\n * effect runs before the browser paints, so the pre-scroll position is never on screen.\n */\n React.useLayoutEffect(() => {\n const scroll = pendingScroll.current;\n pendingScroll.current = null;\n scroll?.();\n }, [payload]);\n\n React.useEffect(() => {\n const stopNavigating = listenNavigation((afterRender) =>\n startNav(async () => {\n try {\n await fetchRscPayload();\n pendingScroll.current = afterRender;\n } catch {\n window.location.reload();\n }\n }),\n );\n const stopUpgradingLinks = listenLinks();\n return () => {\n stopUpgradingLinks();\n stopNavigating();\n };\n }, []);\n\n const router = React.useMemo<NavigationRouter>(() => ({ push, replace, refresh, pending }), [pending]);\n\n return <RouterContext.Provider value={router}>{payload.root}</RouterContext.Provider>;\n }\n\n setServerCallback(async (id, args) => {\n const temporaryReferences = createTemporaryReferenceSet();\n const request = createRscRequest(window.location.href, {\n id,\n body: await encodeReply(args, { temporaryReferences }),\n });\n let payload: RscPayload;\n try {\n payload = await createFromFetch<RscPayload>(fetch(request), { temporaryReferences });\n } catch (error) {\n if (handleControlDigest(error)) return undefined;\n throw error;\n }\n if (payload.redirect) {\n push(payload.redirect);\n return undefined;\n }\n React.startTransition(() => setPayload(payload));\n if (payload.notFound) return undefined;\n const result = payload.returnValue!;\n if (!result.ok) throw result.error;\n return result.value;\n });\n\n // A `redirect()` / `notFound()` from a component *below* the page root can only reach us through\n // React: it rides the flight payload as an error at that component's position, and boundaries\n // re-throw it (see boundaries.tsx) so it lands here rather than rendering an error fallback.\n //\n // Anything that isn't a control signal falls back to what React would have done on its own —\n // console for a caught error, `reportError` (i.e. window.onerror, so error-reporting tools still\n // see it) for an uncaught one. Overriding these hooks means opting out of that default, so it has\n // to be put back by hand.\n hydrateRoot(document, <BrowserRoot />, {\n formState: initialPayload.formState,\n onCaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // A boundary handled this and the tree is intact, so no overlay: whatever fallback the app\n // chose is the right thing to have on screen.\n console.error(error, errorInfo.componentStack ?? '');\n },\n onUncaughtError: (error, errorInfo) => {\n if (handleControlDigest(error, { hard: true })) return;\n // Nothing caught it, so React tears the root down — and the root is `document`. This is the\n // white screen; paint the reason over it.\n globalThis.reportError(error);\n showFatal(error, errorInfo.componentStack);\n },\n });\n\n if (import.meta.webpackHot) {\n initDevRefresh(fetchRscPayload);\n }\n}\n\ntype NavigationType = 'push' | 'replace' | 'pop';\n\n/**\n * Runs teardown in reverse and empties the list, so a second call is a no-op.\n *\n * Collecting these as setup goes keeps each undo next to the thing it undoes: a listener added\n * without one is visible on the spot, rather than as a leak found later against a teardown block\n * that drifted out of sync.\n */\nfunction disposeAll(undo: Array<() => void>): void {\n for (const dispose of undo.splice(0).reverse()) dispose();\n}\n\n// An `<a>` we intercept for soft navigation: same-origin, same tab, not a download,\n// and not explicitly opted out with `data-native` (which forces a full browser navigation).\nfunction isRouterLink(link: HTMLAnchorElement): boolean {\n return (\n !!link.href &&\n (!link.target || link.target === '_self') &&\n link.origin === location.origin &&\n !link.hasAttribute('download') &&\n !link.hasAttribute('data-native')\n );\n}\n\n/**\n * Upgrades the app's anchors: a plain left-click becomes a soft navigation.\n *\n * Kept apart from `listenNavigation` because the two share no state. A click here only calls\n * `history.pushState` — which is where that function picks the navigation up — so the whole contract\n * between them is one global the browser already provides.\n */\nfunction listenLinks(): () => void {\n const undo: Array<() => void> = [];\n\n function onClick(e: MouseEvent) {\n const link = (e.target as Element).closest('a');\n if (\n link &&\n link instanceof HTMLAnchorElement &&\n isRouterLink(link) &&\n e.button === 0 &&\n !e.metaKey &&\n !e.ctrlKey &&\n !e.altKey &&\n !e.shiftKey &&\n !e.defaultPrevented\n ) {\n if (link.hash && link.pathname === location.pathname && link.search === location.search) return;\n e.preventDefault();\n history.pushState(null, '', link.href);\n }\n }\n document.addEventListener('click', onClick);\n undo.push(() => document.removeEventListener('click', onClick));\n\n return () => disposeAll(undo);\n}\n\n/**\n * The element the current `#fragment` names, if it is on the page.\n *\n * A fragment in a URL is percent-encoded and an `id` attribute is not, so one has to be decoded into the\n * other. A hand-written URL can carry a `%` that is not an escape, and `decodeURIComponent` throws on\n * that rather than passing it through — in which case the fragment is taken literally, since that is the\n * closest thing to an id it could have meant.\n */\nfunction fragmentTarget(): HTMLElement | null {\n const fragment = location.hash.slice(1);\n if (!fragment) return null;\n let id = fragment;\n try {\n id = decodeURIComponent(fragment);\n } catch {}\n return document.getElementById(id);\n}\n\nfunction listenNavigation(onNavigation: (afterRender: () => void) => void): () => void {\n const undo: Array<() => void> = [];\n\n // Scroll restoration is the browser's. It used to be ours: each history entry was tagged with a key\n // in `history.state`, `scrollY` was remembered per key, and `manual` handed restoration over — about\n // 130 lines to restore a traversal exactly. `auto` is set explicitly rather than left at the default,\n // because it is a statement: the browser remembers a traversal's offset for us.\n const prevRestoration = window.history.scrollRestoration;\n try {\n window.history.scrollRestoration = 'auto';\n } catch {}\n undo.push(() => {\n try {\n window.history.scrollRestoration = prevRestoration;\n } catch {}\n });\n\n /**\n * A push is not a real navigation as far as the browser is concerned, so nothing resets the scroll\n * offset — a click through to a new page would otherwise land wherever the last one was scrolled to.\n * A `#hash` on that link names where to land instead, and a fragment naming nothing on the page falls\n * back to the top, which is what a browser does with one it cannot resolve. `replace` keeps its\n * position deliberately, and a traversal is the browser's to restore.\n *\n * `scrollIntoView` rather than measuring the element and calling `scrollTo`: it is the same algorithm a\n * browser's own fragment jump uses, so a `scroll-padding-top` — how an app clears a sticky header —\n * still applies. Neither call passes a `behavior`, so `scroll-behavior: smooth` is likewise the app's\n * to ask for.\n *\n * The caller decides *when* this runs, and for a navigation that fetched a payload that has to be\n * after the commit — see the layout effect in `BrowserRoot`.\n */\n const afterRenderFor = (type: NavigationType) => () => {\n if (type !== 'push') return;\n const target = fragmentTarget();\n if (target) target.scrollIntoView();\n else window.scrollTo(0, 0);\n };\n\n const documentUrl = () => location.pathname + location.search;\n\n // What the payload on screen was rendered for. Only the document part: the server never sees the\n // fragment, so two URLs differing by one render identically.\n let renderedUrl = documentUrl();\n\n /**\n * A navigation that moves only the fragment — `#a` → `#b`, or back out of a same-page anchor —\n * leaves the document unchanged, so the payload already on screen is the right one. Fetching\n * another would be a wasted round-trip that re-renders the page out from under the jump.\n *\n * `router.refresh()` is unaffected: it drives the re-fetch directly rather than through here, and\n * remains the way to ask for fresh data at an unchanged URL.\n */\n const notify = (type: NavigationType) => {\n const afterRender = afterRenderFor(type);\n if (documentUrl() === renderedUrl) {\n afterRender();\n return;\n }\n renderedUrl = documentUrl();\n onNavigation(afterRender);\n };\n\n const onPopState = () => notify('pop');\n window.addEventListener('popstate', onPopState);\n undo.push(() => window.removeEventListener('popstate', onPopState));\n\n const oldPushState = window.history.pushState;\n window.history.pushState = function (state, unused, url) {\n const res = oldPushState.call(this, state, unused, url as string);\n notify('push');\n return res;\n };\n undo.push(() => {\n window.history.pushState = oldPushState;\n });\n\n const oldReplaceState = window.history.replaceState;\n window.history.replaceState = function (state, unused, url) {\n const res = oldReplaceState.call(this, state, unused, url as string);\n notify('replace');\n return res;\n };\n undo.push(() => {\n window.history.replaceState = oldReplaceState;\n });\n\n return () => disposeAll(undo);\n}\n\n/**\n * Dev-only refresh client (stripped from prod bundles: the whole call is\n * guarded by import.meta.webpackHot). Listens to the CLI's SSE endpoint:\n *\n * client-built → hot-apply the waiting updates (react-refresh keeps\n * component state); any failure falls back to reload.\n * rsc-update → server component code changed: re-fetch the flight\n * payload for the current URL, state preserved.\n * hello → sent on (re)connect with the latest build hash; a\n * mismatch means events were missed — resync.\n */\nfunction initDevRefresh(fetchRscPayload: () => Promise<void>) {\n let connectedOnce = false;\n\n async function applyClientUpdate(hash: string) {\n const hot = import.meta.webpackHot!;\n if (hash === __webpack_hash__) return;\n if (hot.status() !== 'idle') {\n window.location.reload();\n return;\n }\n try {\n await hot.check(true);\n if (hash !== __webpack_hash__) await applyClientUpdate(hash);\n } catch (error) {\n console.warn('[rshono] hot update failed, reloading:', error);\n window.location.reload();\n }\n }\n\n const source = new EventSource('/_rshono/hmr');\n source.onmessage = async (event) => {\n const message = JSON.parse(event.data) as DevMessage;\n switch (message.type) {\n case 'hello':\n if (connectedOnce) {\n if (message.hash && message.hash !== __webpack_hash__) await applyClientUpdate(message.hash);\n await fetchRscPayload().catch(() => window.location.reload());\n }\n connectedOnce = true;\n break;\n case 'client-built':\n if (message.hash) await applyClientUpdate(message.hash);\n break;\n case 'rsc-update':\n console.log('[rshono] server components updated');\n await fetchRscPayload().catch(() => window.location.reload());\n break;\n }\n };\n}\n\n// Bootstrap failures (a truncated or malformed initial flight payload, most likely) would otherwise\n// be an unhandled rejection: nothing hydrates, nothing is reported, and the page just sits there.\nmain().catch((error) => {\n console.error('[rshono] the client runtime failed to start:', error);\n showFatal(error);\n});\n"]}
|
package/package.json
CHANGED