@real-router/preact 0.11.1 → 0.13.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/README.md +140 -14
- package/dist/cjs/index.d.ts +21 -6
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/ssr.d.ts +169 -0
- package/dist/cjs/ssr.d.ts.map +1 -0
- package/dist/cjs/ssr.js +2 -0
- package/dist/cjs/ssr.js.map +1 -0
- package/dist/cjs/useRoute-B3rj5MXo.js +2 -0
- package/dist/cjs/useRoute-B3rj5MXo.js.map +1 -0
- package/dist/esm/index.d.mts +21 -6
- package/dist/esm/index.d.mts.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/ssr.d.mts +169 -0
- package/dist/esm/ssr.d.mts.map +1 -0
- package/dist/esm/ssr.mjs +2 -0
- package/dist/esm/ssr.mjs.map +1 -0
- package/dist/esm/useRoute-BSPVVbLz.mjs +2 -0
- package/dist/esm/useRoute-BSPVVbLz.mjs.map +1 -0
- package/package.json +23 -6
- package/src/RouterProvider.tsx +15 -2
- package/src/components/Await.tsx +99 -0
- package/src/components/ClientOnly.tsx +25 -0
- package/src/components/HttpStatusCode.tsx +82 -0
- package/src/components/HttpStatusProvider.tsx +22 -0
- package/src/components/Link.tsx +52 -39
- package/src/components/RouteView/RouteView.tsx +12 -8
- package/src/components/RouteView/helpers.tsx +20 -19
- package/src/components/RouterErrorBoundary.tsx +28 -3
- package/src/components/ServerOnly.tsx +26 -0
- package/src/components/Streamed.tsx +24 -0
- package/src/context.ts +17 -0
- package/src/hooks/useDeferred.tsx +26 -0
- package/src/hooks/useIsActiveRoute.tsx +21 -13
- package/src/hooks/useNavigator.tsx +5 -12
- package/src/hooks/useRoute.tsx +7 -8
- package/src/hooks/useRouteNode.tsx +11 -7
- package/src/hooks/useRouter.tsx +5 -12
- package/src/ssr.ts +39 -0
- package/src/types.ts +2 -2
- package/src/useSyncExternalStore.ts +20 -0
- package/src/utils/createHttpStatusSink.ts +27 -0
package/README.md
CHANGED
|
@@ -10,11 +10,14 @@
|
|
|
10
10
|
npm install @real-router/preact @real-router/core
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
`@real-router/core` is the
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
`@real-router/core` is the entry-point dependency the API revolves around;
|
|
14
|
+
`@real-router/route-utils` and `@real-router/sources` are pulled in automatically
|
|
15
|
+
as transitive deps (used internally by `useRouteUtils` / hook subscriptions).
|
|
16
|
+
Add `@real-router/browser-plugin` (or `hash-plugin` / `navigation-plugin` /
|
|
17
|
+
`memory-plugin`) when you need History API integration — the Quick Start below
|
|
18
|
+
uses it.
|
|
16
19
|
|
|
17
|
-
**Peer dependency:** `preact` >= 10.0.0
|
|
20
|
+
**Peer dependency:** `preact` >= 10.28.0 (Preact 10) or ^11.0.0-0 (Preact 11 beta and later). The adapter imports DOM types (`HTMLAttributes`, `TargetedMouseEvent`) from the top-level `preact` namespace introduced in 10.28; Preact 11's JSX-namespace restructure preserves the same imports.
|
|
18
21
|
|
|
19
22
|
## Quick Start
|
|
20
23
|
|
|
@@ -69,7 +72,7 @@ function App() {
|
|
|
69
72
|
| `useRouteUtils()` | `RouteUtils` | Never |
|
|
70
73
|
| `useRouterTransition()` | `{ isTransitioning, isLeaveApproved, toRoute, fromRoute }` | On transition start/end |
|
|
71
74
|
| `useRouteExit(handler, options?)` | `void` — wraps `router.subscribeLeave` with abort + same-route guards | Never (stable subscription) |
|
|
72
|
-
| `useRouteEnter(handler, options?)` | `void` — fires on nav-driven mount via `useRoute()` snapshot |
|
|
75
|
+
| `useRouteEnter(handler, options?)` | `void` — fires on nav-driven mount via `useRoute()` snapshot | Every navigation (host component reads `useRoute()`); handler ref + subscription are stable across renders |
|
|
73
76
|
|
|
74
77
|
```tsx
|
|
75
78
|
// useRouteNode — re-renders only when "users.*" changes
|
|
@@ -158,7 +161,7 @@ Tri-state: `undefined` preserves the current hash, `""` clears it, a value sets
|
|
|
158
161
|
|
|
159
162
|
### `<RouteView>`
|
|
160
163
|
|
|
161
|
-
Declarative route matching. Renders the first matching `<RouteView.Match>` child.
|
|
164
|
+
Declarative route matching. Renders the first matching `<RouteView.Match>` child; falls back to `<RouteView.Self>` when the active route name equals `nodeName`, or `<RouteView.NotFound>` for `UNKNOWN_ROUTE`.
|
|
162
165
|
|
|
163
166
|
```tsx
|
|
164
167
|
<RouteView nodeName="">
|
|
@@ -178,11 +181,44 @@ Declarative route matching. Renders the first matching `<RouteView.Match>` child
|
|
|
178
181
|
|
|
179
182
|
#### `RouteView.Match` props
|
|
180
183
|
|
|
181
|
-
| Prop | Type | Description |
|
|
182
|
-
| ---------- | ------------------- | ----------------------------------------------------------------------------- |
|
|
183
|
-
| `segment` | `string` | Route segment to match |
|
|
184
|
-
| `exact` | `boolean` | When `true`, matches only the exact route (not descendants). Default: `false` |
|
|
185
|
-
| `fallback` | `ComponentChildren` | Shown while children suspend. Wraps children in `<Suspense>` when provided. |
|
|
184
|
+
| Prop | Type | Required | Description |
|
|
185
|
+
| ---------- | ------------------- | -------- | ----------------------------------------------------------------------------- |
|
|
186
|
+
| `segment` | `string` | Yes | Route segment to match |
|
|
187
|
+
| `exact` | `boolean` | No | When `true`, matches only the exact route (not descendants). Default: `false` |
|
|
188
|
+
| `fallback` | `ComponentChildren` | No | Shown while children suspend. Wraps children in `<Suspense>` when provided. |
|
|
189
|
+
| `children` | `ComponentChildren` | Yes | Content to render when the active route matches `segment` |
|
|
190
|
+
|
|
191
|
+
#### `<RouteView.Self>` and `<RouteView.NotFound>`
|
|
192
|
+
|
|
193
|
+
Three fallback slots compose inside a `<RouteView nodeName="…">`:
|
|
194
|
+
|
|
195
|
+
| Element | Fires when | Props | Render position |
|
|
196
|
+
|--------------------------|---------------------------------------------------------|------------------------------------|---------------------------------|
|
|
197
|
+
| `<RouteView.Match>` | Active route segment matches `segment` (or descendant when `exact={false}`) | `segment` / `exact` / `fallback` / `children` | Inline at source position |
|
|
198
|
+
| `<RouteView.Self>` | Active route name **exactly equals** parent's `nodeName` | `fallback` / `children` | Appended after Match elements |
|
|
199
|
+
| `<RouteView.NotFound>` | Active route name is `UNKNOWN_ROUTE` AND no Match activated | `children` | Appended after Match elements |
|
|
200
|
+
|
|
201
|
+
Precedence:
|
|
202
|
+
|
|
203
|
+
1. `<Match>` first-wins — duplicate segments short-circuit; subsequent `<Match>` with the same segment are not rendered.
|
|
204
|
+
2. `<Self>` first-wins — only the first `<RouteView.Self>` contributes; subsequent ones are ignored.
|
|
205
|
+
3. `<NotFound>` **last-wins** — when multiple `<RouteView.NotFound>` siblings are declared (unusual but legal), only the *last* one renders. Asymmetric with the other two slots; prefer a single `<NotFound>` per RouteView.
|
|
206
|
+
4. An activating `<Match>` suppresses both `<Self>` and `<NotFound>`.
|
|
207
|
+
5. When no `<Match>` activates: `<Self>` wins over `<NotFound>` if both would fire (occurs only when `nodeName === UNKNOWN_ROUTE`, narrow edge case).
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
<RouteView nodeName="users">
|
|
211
|
+
<RouteView.Self>
|
|
212
|
+
<UsersIndex /> {/* route name === "users" → renders */}
|
|
213
|
+
</RouteView.Self>
|
|
214
|
+
<RouteView.Match segment="profile">
|
|
215
|
+
<UserProfile /> {/* "users.profile" and descendants → renders */}
|
|
216
|
+
</RouteView.Match>
|
|
217
|
+
<RouteView.NotFound>
|
|
218
|
+
<NotFoundPage /> {/* UNKNOWN_ROUTE → renders */}
|
|
219
|
+
</RouteView.NotFound>
|
|
220
|
+
</RouteView>
|
|
221
|
+
```
|
|
186
222
|
|
|
187
223
|
#### Lazy loading with `fallback` (experimental)
|
|
188
224
|
|
|
@@ -212,6 +248,7 @@ import {
|
|
|
212
248
|
RouteContext, // { navigator, route, previousRoute }
|
|
213
249
|
type RouteViewProps,
|
|
214
250
|
type RouteViewMatchProps,
|
|
251
|
+
type RouteViewSelfProps,
|
|
215
252
|
type RouteViewNotFoundProps,
|
|
216
253
|
} from "@real-router/preact";
|
|
217
254
|
```
|
|
@@ -245,6 +282,87 @@ import { RouterErrorBoundary } from "@real-router/preact";
|
|
|
245
282
|
|
|
246
283
|
Auto-resets on next successful navigation. Works with both `<Link>` and imperative `router.navigate()`.
|
|
247
284
|
|
|
285
|
+
## SSR-feature surface — `@real-router/preact/ssr`
|
|
286
|
+
|
|
287
|
+
All SSR-aware components, hooks, and utilities live at the `/ssr` subpath — mirror of `@real-router/react/ssr` (same exports, same API). Eight exports total: `<ClientOnly>`, `<ServerOnly>`, `<Streamed>`, `<Await>`, `<HttpStatusCode>`, `<HttpStatusProvider>`, `useDeferred`, `createHttpStatusSink`.
|
|
288
|
+
|
|
289
|
+
### `<ClientOnly>` / `<ServerOnly>`
|
|
290
|
+
|
|
291
|
+
Paired SSR-aware boundaries. `<ClientOnly>` renders `fallback` on the server (and on the client first paint, to match SSR HTML), then swaps in `children` after mount. `<ServerOnly>` is the symmetric inverse.
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
import { ClientOnly, ServerOnly } from "@real-router/preact/ssr";
|
|
295
|
+
|
|
296
|
+
<ClientOnly fallback={<Skeleton />}>
|
|
297
|
+
<BrowserApiWidget />
|
|
298
|
+
</ClientOnly>
|
|
299
|
+
|
|
300
|
+
<ServerOnly>
|
|
301
|
+
<SeoMetaStrip />
|
|
302
|
+
</ServerOnly>;
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Implementation: `useState(false)` + `useEffect(() => setMounted(true), [])` from `preact/hooks`. End-to-end dogfooding lives in [`examples/web/preact/ssr-examples/ssr/`](../../examples/web/preact/ssr-examples/ssr/) (see `e2e/ssr-boundaries.spec.ts`).
|
|
306
|
+
|
|
307
|
+
### `<Streamed>` / `<Await>` / `useDeferred`
|
|
308
|
+
|
|
309
|
+
Three pieces of the deferred-data pipeline (paired with [`@real-router/ssr-data-plugin`](https://www.npmjs.com/package/@real-router/ssr-data-plugin)'s `defer()` API). `<Streamed>` is a cross-adapter alias for Preact's `<Suspense>` (from `preact/compat`). `<Await<T> name="key">` reads the deferred promise the loader published under that key and hands the resolved value to a render-prop via Preact's Suspense-throwing convention. `useDeferred<T>(key)` returns the same promise for callers composing with a third-party Suspense-aware lib.
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
import { Streamed, Await, useDeferred } from "@real-router/preact/ssr";
|
|
313
|
+
|
|
314
|
+
<Streamed fallback={<Spinner />}>
|
|
315
|
+
<Await<Review[]> name="reviews">
|
|
316
|
+
{(reviews) => <ReviewList items={reviews} />}
|
|
317
|
+
</Await>
|
|
318
|
+
</Streamed>;
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
End-to-end example: [`examples/web/preact/ssr-examples/ssr-streaming/`](../../examples/web/preact/ssr-examples/ssr-streaming/).
|
|
322
|
+
|
|
323
|
+
### `<HttpStatusCode>` / `<HttpStatusProvider>` / `createHttpStatusSink`
|
|
324
|
+
|
|
325
|
+
Render-time HTTP status declaration for SSR responses. Mount `<HttpStatusCode code={N} />` inside a route component (typical use: a `<RouteView.NotFound>` glob page) — it writes `N` to the nearest `<HttpStatusProvider>`'s sink during render and returns `null`. After `renderToString`, read `sink.code` and pass it to your response.
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
// app.tsx
|
|
329
|
+
import { HttpStatusCode } from "@real-router/preact/ssr";
|
|
330
|
+
|
|
331
|
+
function NotFound() {
|
|
332
|
+
return (
|
|
333
|
+
<>
|
|
334
|
+
<HttpStatusCode code={404} />
|
|
335
|
+
<h1>Page not found</h1>
|
|
336
|
+
</>
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// entry-server.tsx
|
|
341
|
+
import { renderToString } from "preact-render-to-string";
|
|
342
|
+
import {
|
|
343
|
+
HttpStatusProvider,
|
|
344
|
+
createHttpStatusSink,
|
|
345
|
+
} from "@real-router/preact/ssr";
|
|
346
|
+
|
|
347
|
+
const sink = createHttpStatusSink();
|
|
348
|
+
const html = renderToString(
|
|
349
|
+
<HttpStatusProvider sink={sink}>
|
|
350
|
+
<RouterProvider router={router}>
|
|
351
|
+
<App />
|
|
352
|
+
</RouterProvider>
|
|
353
|
+
</HttpStatusProvider>,
|
|
354
|
+
);
|
|
355
|
+
response.status(sink.code ?? 200).send(html);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
| Export | Kind | Purpose |
|
|
359
|
+
| ------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
360
|
+
| `<HttpStatusCode code={N}/>` | component | Writes `code` to the optional context sink during render. Last write wins across multiple instances. No-op without a provider. |
|
|
361
|
+
| `<HttpStatusProvider sink={…}>` | component | Supplies an `HttpStatusSink` to descendant `<HttpStatusCode />` via Preact context. |
|
|
362
|
+
| `createHttpStatusSink()` | utility | Returns a fresh `{ code: number \| undefined }` sink — construct one per request on the server, read `sink.code` after rendering. |
|
|
363
|
+
|
|
364
|
+
Loader-driven errors (`LoaderNotFound` → 404, `LoaderRedirect` → 30x) keep working as before; this component covers render-time decisions only.
|
|
365
|
+
|
|
248
366
|
## Accessibility
|
|
249
367
|
|
|
250
368
|
Enable screen reader announcements for route changes:
|
|
@@ -267,7 +385,7 @@ Opt-in preservation of scroll position across navigations:
|
|
|
267
385
|
</RouterProvider>
|
|
268
386
|
```
|
|
269
387
|
|
|
270
|
-
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"native"`. Custom containers via `scrollContainer: () => HTMLElement | null`. Lifecycle tied to the provider — created on mount, destroyed on unmount. See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
388
|
+
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"native"`. Custom containers via `scrollContainer: () => HTMLElement | null`. Override the `sessionStorage` key via `storageKey` (default `"real-router:scroll"`) when isolating multiple routers on one origin. Lifecycle tied to the provider — created on mount, destroyed on unmount. See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
271
389
|
|
|
272
390
|
## View Transitions
|
|
273
391
|
|
|
@@ -290,9 +408,17 @@ Full documentation: [Wiki](https://github.com/greydragon888/real-router/wiki)
|
|
|
290
408
|
|
|
291
409
|
## Examples
|
|
292
410
|
|
|
293
|
-
|
|
411
|
+
20 runnable examples — each is a standalone Vite app. Run: `cd examples/web/preact/basic && pnpm dev`
|
|
412
|
+
|
|
413
|
+
**Routing fundamentals:** [basic](../../examples/web/preact/basic) · [nested-routes](../../examples/web/preact/nested-routes) · [dynamic-routes](../../examples/web/preact/dynamic-routes) · [combined](../../examples/web/preact/combined)
|
|
414
|
+
|
|
415
|
+
**Data & guards:** [auth-guards](../../examples/web/preact/auth-guards) · [async-guards](../../examples/web/preact/async-guards) · [data-loading](../../examples/web/preact/data-loading) · [lazy-loading](../../examples/web/preact/lazy-loading) · [error-handling](../../examples/web/preact/error-handling)
|
|
416
|
+
|
|
417
|
+
**URL features:** [hash-routing](../../examples/web/preact/hash-routing) · [persistent-params](../../examples/web/preact/persistent-params) · [search-schema](../../examples/web/preact/search-schema)
|
|
418
|
+
|
|
419
|
+
**Animations:** [motion-animations](../../examples/web/preact/animation-examples/motion-animations) · [page-animations](../../examples/web/preact/animation-examples/page-animations) · [route-animations](../../examples/web/preact/animation-examples/route-animations) · [view-transitions](../../examples/web/preact/animation-examples/view-transitions)
|
|
294
420
|
|
|
295
|
-
|
|
421
|
+
**SSR:** [ssg](../../examples/web/preact/ssr-examples/ssg) · [ssr](../../examples/web/preact/ssr-examples/ssr) · [ssr-mixed](../../examples/web/preact/ssr-examples/ssr-mixed) · [ssr-streaming](../../examples/web/preact/ssr-examples/ssr-streaming)
|
|
296
422
|
|
|
297
423
|
## Related Packages
|
|
298
424
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ComponentChildren, FunctionComponent, JSX, VNode } from "preact";
|
|
1
|
+
import { ComponentChildren, Context, FunctionComponent, HTMLAttributes, VNode } from "preact";
|
|
3
2
|
import { NavigationOptions, Navigator, Navigator as Navigator$1, Params, Router, RouterError, State } from "@real-router/core";
|
|
4
3
|
import { RouteUtils } from "@real-router/route-utils";
|
|
5
4
|
import { RouterTransitionSnapshot, RouterTransitionSnapshot as RouterTransitionSnapshot$1 } from "@real-router/sources";
|
|
@@ -61,7 +60,7 @@ interface RouteState<P extends Params = Params> {
|
|
|
61
60
|
type RouteContext$1<P extends Params = Params> = {
|
|
62
61
|
navigator: Navigator$1;
|
|
63
62
|
} & RouteState<P>;
|
|
64
|
-
interface LinkProps<P extends Params = Params> extends Omit<
|
|
63
|
+
interface LinkProps<P extends Params = Params> extends Omit<HTMLAttributes<HTMLAnchorElement>, "className"> {
|
|
65
64
|
routeName: string;
|
|
66
65
|
routeParams?: P;
|
|
67
66
|
routeOptions?: NavigationOptions;
|
|
@@ -91,6 +90,22 @@ interface RouterErrorBoundaryProps {
|
|
|
91
90
|
readonly fallback: (error: RouterError, resetError: () => void) => ComponentChildren;
|
|
92
91
|
readonly onError?: (error: RouterError, toRoute: State | null, fromRoute: State | null) => void;
|
|
93
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Declarative navigation-error boundary.
|
|
95
|
+
*
|
|
96
|
+
* **Not** a Preact `componentDidCatch`-style ErrorBoundary — this component
|
|
97
|
+
* does NOT catch render-time exceptions from `children`. It is a compositional
|
|
98
|
+
* component that subscribes to `createDismissableError` from
|
|
99
|
+
* `@real-router/sources` and renders `fallback(error, resetError)` ALONGSIDE
|
|
100
|
+
* `children` (wrapped in a `<Fragment>`) when the router emits a navigation
|
|
101
|
+
* error (guard rejection, ROUTE_NOT_FOUND, etc.). The boundary auto-resets on
|
|
102
|
+
* the next successful navigation; `resetError()` lets the consumer dismiss
|
|
103
|
+
* the fallback imperatively.
|
|
104
|
+
*
|
|
105
|
+
* For real exception boundaries, wrap children in a Preact ErrorBoundary
|
|
106
|
+
* (e.g. `preact-iso/ErrorBoundary` or a custom `componentDidCatch` class) —
|
|
107
|
+
* the two can coexist.
|
|
108
|
+
*/
|
|
94
109
|
declare function RouterErrorBoundary({
|
|
95
110
|
children,
|
|
96
111
|
fallback,
|
|
@@ -368,9 +383,9 @@ interface RouteProviderProps {
|
|
|
368
383
|
declare const RouterProvider: FunctionComponent<RouteProviderProps>;
|
|
369
384
|
//#endregion
|
|
370
385
|
//#region src/context.d.ts
|
|
371
|
-
declare const RouteContext:
|
|
372
|
-
declare const RouterContext:
|
|
373
|
-
declare const NavigatorContext:
|
|
386
|
+
declare const RouteContext: Context<RouteContext$1 | null>;
|
|
387
|
+
declare const RouterContext: Context<Router<object> | null>;
|
|
388
|
+
declare const NavigatorContext: Context<Navigator$1 | null>;
|
|
374
389
|
//#endregion
|
|
375
390
|
export { Link, type LinkProps, type Navigator, NavigatorContext, RouteContext, type RouteEnterContext, type RouteEnterHandler, type RouteExitContext, type RouteExitHandler, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, type SelfProps as RouteViewSelfProps, RouterContext, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, type RouterTransitionSnapshot, type UseRouteEnterOptions, type UseRouteExitOptions, useNavigator, useRoute, useRouteEnter, useRouteExit, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
|
|
376
391
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/components/RouteView/types.ts","../../src/components/RouteView/components.tsx","../../src/components/RouteView/RouteView.tsx","../../src/types.ts","../../src/components/Link.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useRouter.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouteNode.tsx","../../src/hooks/useRouterTransition.tsx","../../src/hooks/useRouteExit.tsx","../../src/hooks/useRouteEnter.tsx","../../../../shared/dom-utils/scroll-restore.ts","../../src/RouterProvider.tsx","../../src/context.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/components/RouteView/types.ts","../../src/components/RouteView/components.tsx","../../src/components/RouteView/RouteView.tsx","../../src/types.ts","../../src/components/Link.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useRouter.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouteNode.tsx","../../src/hooks/useRouterTransition.tsx","../../src/hooks/useRouteExit.tsx","../../src/hooks/useRouteEnter.tsx","../../../../shared/dom-utils/scroll-restore.ts","../../src/RouterProvider.tsx","../../src/context.ts"],"mappings":"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"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`preact/hooks`),t=require(`@real-router/core`),n=require(`@real-router/route-utils`),r=require(`preact`),i=require(`preact/compat`),a=require(`preact/jsx-runtime`),o=require(`@real-router/sources`),s=require(`@real-router/core/api`);function c(e){return null}c.displayName=`RouteView.Match`;function l(e){return null}l.displayName=`RouteView.Self`;function u(e){return null}u.displayName=`RouteView.NotFound`;function d(e,t,r){return t===``?!1:r?e===t:(0,n.startsWithSegment)(e,t)}function f(e,t){for(let n of(0,r.toChildArray)(e))(0,r.isValidElement)(n)&&(n.type===c||n.type===l||n.type===u?t.push(n):f(n.props.children,t))}function p(e,t,n){return(0,a.jsx)(r.Fragment,{children:n===void 0?e:(0,a.jsx)(i.Suspense,{fallback:n,children:e})},t)}function m(e,t){return e.type===u?(t.notFoundChildren=e.props.children,!0):e.type===l?(t.selfFound||=(t.selfChildren=e.props.children,t.selfFallback=e.props.fallback,!0),!0):!1}function h(e,t,n,r){let{segment:i,exact:a=!1,fallback:o}=e.props,s=n?`${n}.${i}`:i;return!r&&d(t,s,a)?p(e.props.children,s,o):null}function g(e,n,i,o){if(o.selfFound&&n===i){e.push(p(o.selfChildren,`__route-view-self__`,o.selfFallback));return}n===t.UNKNOWN_ROUTE&&o.notFoundChildren!==null&&e.push((0,a.jsx)(r.Fragment,{children:o.notFoundChildren},`__route-view-not-found__`))}function _(e,t,n){let r={selfChildren:null,selfFallback:void 0,selfFound:!1,notFoundChildren:null},i=!1,a=[];for(let o of e){if(m(o,r))continue;let e=h(o,t,n,i);e!==null&&(i=!0,a.push(e))}return i||g(a,t,n,r),{rendered:a,activeMatchFound:i}}function v(t,n,r){let[i,a]=(0,e.useState)(n);return(0,e.useEffect)(()=>{let e=()=>{a(e=>{let t=n();return Object.is(e,t)?e:t})};return e(),t(e)},[t,n]),i}const y=(0,r.createContext)(null),b=(0,r.createContext)(null),x=(0,r.createContext)(null),S=()=>{let t=(0,e.useContext)(b);if(!t)throw Error(`useRouter must be used within a RouterProvider`);return t};function C(n){let r=S(),i=(0,e.useMemo)(()=>(0,o.createRouteNodeSource)(r,n),[r,n]),{route:a,previousRoute:s}=v(i.subscribe,i.getSnapshot,i.getSnapshot),c=(0,e.useMemo)(()=>(0,t.getNavigator)(r),[r]);return(0,e.useMemo)(()=>({navigator:c,route:a,previousRoute:s}),[c,a,s])}function w({nodeName:t,children:n}){let{route:r}=C(t),i=(0,e.useMemo)(()=>{let e=[];return f(n,e),e},[n]);if(!r)return null;let{rendered:o}=_(i,r.name,t);return o.length>0?(0,a.jsx)(a.Fragment,{children:o}):null}w.displayName=`RouteView`;const T=Object.assign(w,{Match:c,Self:l,NotFound:u}),E=Object.freeze({}),D=Object.freeze({}),O=`data-real-router-announcer`;function k(e,t){let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=A(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),M(t)},f=setTimeout(()=>{if(a=!0,c!==null&&!o){let e=c;c=null,d(e,document.querySelector(`h1`))}},100),p=e.subscribe(({route:e})=>{if(i){i=!1;return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(o)return;let t=document.querySelector(`h1`),i=ee(e,n,r,t);if(!(!i||i===s)){if(!a){c=i;return}d(i,t)}})})});return{destroy(){o=!0,p(),clearTimeout(l),clearTimeout(f),j()}}}function A(){let e=document.querySelector(`[${O}]`);if(e)return e;let t=document.createElement(`div`);return t.setAttribute(`style`,`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0`),t.setAttribute(`aria-live`,`assertive`),t.setAttribute(`aria-atomic`,`true`),t.setAttribute(O,``),document.body.prepend(t),t}function j(){document.querySelector(`[${O}]`)?.remove()}function ee(e,t,n,r){if(n)return n(e);let i=(r?.textContent??``).trim(),a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function M(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const N=Object.freeze({destroy:()=>{}});function P(e,t){if(globalThis.window===void 0)return N;let n=t?.mode??`restore`;if(n===`native`)return N;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=t?.behavior??`auto`,o=t?.storageKey??`real-router:scroll`,s=()=>{try{let e=sessionStorage.getItem(o);return e?JSON.parse(e):{}}catch{return{}}},c=(e,t)=>{try{let n=s();n[e]=t,sessionStorage.setItem(o,JSON.stringify(n))}catch{}},l=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let u=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},d=e=>{let t=i?.();t?t.scrollTo({top:e,left:0,behavior:a}):globalThis.scrollTo({top:e,left:0,behavior:a})},f=e=>{let t=e.context?.url?.hash;if(t!==void 0){if(r&&t.length>0){let e=document.getElementById(t);if(e){e.scrollIntoView({behavior:a});return}}d(0);return}let n=globalThis.location.hash;if(r&&n.length>1){let e;try{e=decodeURIComponent(n.slice(1))}catch{e=n.slice(1)}let t=document.getElementById(e);if(t){t.scrollIntoView({behavior:a});return}}d(0)},p=!1,m=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;t&&c(F(t),u()),requestAnimationFrame(()=>{if(!p){if(n===`top`||!r){f(e);return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){d(s()[F(e)]??0);return}f(e)}}})}),h=()=>{let t=e.getState();t&&c(F(t),u())};return globalThis.addEventListener(`pagehide`,h),{destroy:()=>{if(!p){p=!0,m(),globalThis.removeEventListener(`pagehide`,h);try{history.scrollRestoration=l}catch{}}}}}function F(e){return`${e.name}:${I(e.params)}`}function I(e){return JSON.stringify(e,L)}function L(e,t){if(typeof t==`object`&&t&&!Array.isArray(t)){let e={},n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}const R=Object.freeze({destroy:()=>{}});function z(e){if(typeof document>`u`||typeof document.startViewTransition!=`function`)return R;let t=null,n=null,r=!1,i=()=>{t?.(),t=null},a=e.subscribeLeave(({signal:e})=>{if(!e.aborted)return r=!1,i(),new Promise(a=>{let o=new Promise(e=>{t=e});e.addEventListener(`abort`,()=>{r||(i(),n?.skipTransition?.(),a())},{once:!0});try{n=document.startViewTransition(()=>(a(),o))}catch{i(),a()}})}),o=e.subscribe(()=>{let e=t;r=!0,t=null,e===null?n=null:setTimeout(()=>{e(),n=null},0)});return{destroy:()=>{a(),o(),n?.skipTransition?.(),n=null,i()}}}function B(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}function V(e){return encodeURI(e).replaceAll(`#`,`%23`)}function H(e,t,n,r){try{let i=r?.hash,a;i!==void 0&&(a=i.startsWith(`#`)?i.slice(1):i);let o=e.buildUrl;if(o){let e=o(t,n,a===void 0?void 0:{hash:a});if(e!==void 0)return e}let s=e.buildPath(t,n);return a?`${s}#${V(a)}`:s}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function U(e,t,n,r,i){let a={...i};r!==void 0&&(a.hash=r);let o=e.getState();if(o?.name===t&&K(o.params,n)){let e=o.context?.url?.hash??``;e!==(r??e)&&(a.force=!0,a.hashChange=!0)}return e.navigate(t,n,a)}function W(e){return e?e.match(/\S+/g)??[]:[]}function G(e,t,n){if(e&&t){let e=W(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=W(n),i=new Set(r);for(let t of e)i.has(t)||(i.add(t),r.push(t));return r.join(` `)}return n??void 0}function K(e,t){if(Object.is(e,t))return!0;if(!e||!t)return!1;let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;let r=e,i=t;for(let e of n)if(!Object.is(r[e],i[e]))return!1;return!0}function q(e,t,n=!1,r=!0,i){let a=(0,o.createActiveRouteSource)(S(),e,t,i===void 0?{strict:n,ignoreQueryParams:r}:{strict:n,ignoreQueryParams:r,hash:i});return v(a.subscribe,a.getSnapshot,a.getSnapshot)}function J(e,t){return e.routeName===t.routeName&&e.className===t.className&&e.activeClassName===t.activeClassName&&e.activeStrict===t.activeStrict&&e.ignoreQueryParams===t.ignoreQueryParams&&e.onClick===t.onClick&&e.target===t.target&&e.style===t.style&&e.children===t.children&&e.hash===t.hash&&K(e.routeParams,t.routeParams)&&K(e.routeOptions,t.routeOptions)}const Y=(0,i.memo)(({routeName:t,routeParams:n=E,routeOptions:r=D,className:i,activeClassName:o=`active`,activeStrict:s=!1,ignoreQueryParams:c=!0,hash:l,onClick:u,target:d,children:f,...p})=>{let m=S(),h=q(t,n,s,c,l),g=(0,e.useMemo)(()=>H(m,t,n,l===void 0?void 0:{hash:l}),[m,t,n,l]),_=(0,e.useCallback)(e=>{u&&(u(e),e.defaultPrevented)||!B(e)||d===`_blank`||(e.preventDefault(),U(m,t,n,l,r).catch(()=>{}))},[u,d,m,t,n,r,l]),v=(0,e.useMemo)(()=>G(h,o,i),[h,o,i]);return(0,a.jsx)(`a`,{...p,href:g,className:v,onClick:_,children:f})},J);Y.displayName=`Link`;function X({children:t,fallback:n,onError:i}){let s=(0,o.createDismissableError)(S()),c=v(s.subscribe,s.getSnapshot,s.getSnapshot),l=(0,e.useRef)(i);return l.current=i,(0,e.useEffect)(()=>{c.error&&l.current?.(c.error,c.toRoute,c.fromRoute)},[c.version]),(0,a.jsxs)(r.Fragment,{children:[t,c.error?n(c.error,c.resetError):null]})}const Z=()=>{let t=(0,e.useContext)(x);if(!t)throw Error(`useNavigator must be used within a RouterProvider`);return t},Q=()=>(0,n.getRouteUtils)((0,s.getPluginApi)(S()).getTree()),$=()=>{let t=(0,e.useContext)(y);if(!t)throw Error(`useRoute must be used within a RouterProvider`);if(!t.route)throw Error(`useRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?`);return t};function te(){let e=(0,o.getTransitionSource)(S());return v(e.subscribe,e.getSnapshot,e.getSnapshot)}function ne(t,n){let r=S(),i=(0,e.useRef)(t),a=n?.skipSameRoute??!0;(0,e.useLayoutEffect)(()=>{i.current=t}),(0,e.useEffect)(()=>r.subscribeLeave(({route:e,nextRoute:t,signal:n})=>{if(!(a&&e.name===t.name)&&!n.aborted)return i.current({route:e,nextRoute:t,signal:n})}),[r,a])}function re(t,n){let{route:r,previousRoute:i}=$(),a=(0,e.useRef)(t),o=(0,e.useRef)(null),s=n?.skipSameRoute??!0;(0,e.useLayoutEffect)(()=>{a.current=t}),(0,e.useEffect)(()=>{r.transition.from&&(s&&r.transition.from===r.name||o.current===r||!i||(o.current=r,a.current({route:r,previousRoute:i})))},[r,i,s])}const ie=({router:n,children:r,announceNavigation:i,scrollRestoration:s,viewTransitions:c})=>{(0,e.useEffect)(()=>{if(!i)return;let e=k(n);return()=>{e.destroy()}},[i,n]);let l=s?.mode,u=s?.anchorScrolling,d=s?.behavior,f=s?.storageKey,p=s!==void 0;(0,e.useEffect)(()=>{if(!p)return;let e=P(n,{mode:l,anchorScrolling:u,behavior:d,storageKey:f,scrollContainer:s.scrollContainer});return()=>{e.destroy()}},[n,p,l,u,d,f]),(0,e.useEffect)(()=>{if(!c)return;let e=z(n);return()=>{e.destroy()}},[n,c]);let m=(0,e.useMemo)(()=>(0,t.getNavigator)(n),[n]),h=(0,e.useMemo)(()=>(0,o.createRouteSource)(n),[n]),{route:g,previousRoute:_}=v(h.subscribe,h.getSnapshot,h.getSnapshot),S=(0,e.useMemo)(()=>({navigator:m,route:g,previousRoute:_}),[m,g,_]);return(0,a.jsx)(b.Provider,{value:n,children:(0,a.jsx)(x.Provider,{value:m,children:(0,a.jsx)(y.Provider,{value:S,children:r})})})};exports.Link=Y,exports.NavigatorContext=x,exports.RouteContext=y,exports.RouteView=T,exports.RouterContext=b,exports.RouterErrorBoundary=X,exports.RouterProvider=ie,exports.useNavigator=Z,exports.useRoute=$,exports.useRouteEnter=re,exports.useRouteExit=ne,exports.useRouteNode=C,exports.useRouteUtils=Q,exports.useRouter=S,exports.useRouterTransition=te;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./useRoute-B3rj5MXo.js`);let t=require(`preact/hooks`),n=require(`@real-router/core`),r=require(`@real-router/route-utils`),i=require(`preact`),a=require(`preact/compat`),o=require(`preact/jsx-runtime`),s=require(`@real-router/sources`),c=require(`@real-router/core/api`);function l(e){return null}l.displayName=`RouteView.Match`;function u(e){return null}u.displayName=`RouteView.Self`;function d(e){return null}d.displayName=`RouteView.NotFound`;function f(e,t,n){return t===``?!1:n?e===t:(0,r.startsWithSegment)(e,t)}function p(e,t){for(let n of(0,i.toChildArray)(e))(0,i.isValidElement)(n)&&(n.type===l||n.type===u||n.type===d?t.push(n):p(n.props.children,t))}function m(e,t,n){return(0,o.jsx)(i.Fragment,{children:n===void 0?e:(0,o.jsx)(a.Suspense,{fallback:n,children:e})},t)}function h(e){return e.type===d||e.type===u}function g(e,t){if(e.type===d){t.notFoundChildren=e.props.children;return}t.selfFound||=(t.selfChildren=e.props.children,t.selfFallback=e.props.fallback,!0)}function _(e,t,n,r){let{segment:i,exact:a=!1,fallback:o,children:s}=e.props,c=n?`${n}.${i}`:i;return!r&&f(t,c,a)?m(s,c,o):null}function v(e,t,r,a){if(a.selfFound&&t===r){e.push(m(a.selfChildren,`__route-view-self__`,a.selfFallback));return}t===n.UNKNOWN_ROUTE&&a.notFoundChildren!==null&&e.push((0,o.jsx)(i.Fragment,{children:a.notFoundChildren},`__route-view-not-found__`))}function y(e,t,n){let r={selfChildren:null,selfFallback:void 0,selfFound:!1,notFoundChildren:null},i=!1,a=[];for(let o of e){if(h(o)){g(o,r);continue}let e=_(o,t,n,i);e!==null&&(i=!0,a.push(e))}return i||v(a,t,n,r),{rendered:a,activeMatchFound:i}}function b(e,n,r){let[i,a]=(0,t.useState)(n);return(0,t.useEffect)(()=>{let t=()=>{a(e=>{let t=n();return Object.is(e,t)?e:t})};return t(),e(t)},[e,n]),i}const x=e.a(e.n,`useNavigator`),S=e.a(e.i,`useRouter`);function C(e){let n=S(),r=x(),i=(0,s.createRouteNodeSource)(n,e),{route:a,previousRoute:o}=b(i.subscribe,i.getSnapshot,i.getSnapshot);return(0,t.useMemo)(()=>({navigator:r,route:a,previousRoute:o}),[r,a,o])}function w({nodeName:e,children:n}){let{route:r}=C(e),i=(0,t.useMemo)(()=>{let e=[];return p(n,e),e},[n]),a=r?.name,s=(0,t.useMemo)(()=>a===void 0?[]:y(i,a,e).rendered,[i,a,e]);return s.length>0?(0,o.jsx)(o.Fragment,{children:s}):null}w.displayName=`RouteView`;const T=Object.assign(w,{Match:l,Self:u,NotFound:d}),E=Object.freeze({}),D=Object.freeze({}),O=`data-real-router-announcer`,k=Object.freeze({destroy:()=>{}});function ee(e,t){if(typeof document>`u`)return k;let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=te(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),M(t)},f=setTimeout(()=>{if(a=!0,c!==null&&!o){let e=c;c=null,d(e,document.querySelector(`h1`))}},100),p=e.subscribe(({route:e})=>{if(i){i=!1;return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(o)return;let t=document.querySelector(`h1`),i=j(e,n,r,t);if(!(!i||i===s)){if(!a){c=i;return}d(i,t)}})})});return{destroy(){o=!0,p(),clearTimeout(l),clearTimeout(f),A()}}}function te(){let e=document.querySelector(`[${O}]`);if(e)return e;let t=document.createElement(`div`);return t.setAttribute(`style`,`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0`),t.setAttribute(`aria-live`,`assertive`),t.setAttribute(`aria-atomic`,`true`),t.setAttribute(O,``),(document.body??document.documentElement).prepend(t),t}function A(){document.querySelector(`[${O}]`)?.remove()}function j(e,t,n,r){if(n)try{let t=n(e);if(t)return t}catch(e){console.error(`[real-router] getAnnouncementText threw; falling back to default resolution.`,e)}let i=(r?.textContent??``).trim(),a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function M(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const N=Object.freeze({destroy:()=>{}});function P(e,t){if(globalThis.window===void 0)return N;let n=t?.mode??`restore`;if(n===`native`)return N;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=t?.behavior??`auto`,o=t?.storageKey??`real-router:scroll`,s,c=()=>{if(s!==void 0)return s;try{let e=sessionStorage.getItem(o);s=e?JSON.parse(e):{}}catch{s={}}return s},l=(e,t)=>{try{let n=c();if(n[e]===t)return;n[e]=t,sessionStorage.setItem(o,JSON.stringify(n))}catch{}},u=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let d=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},f=e=>{let t=i?.();t?t.scrollTo({top:e,left:0,behavior:a}):globalThis.scrollTo({top:e,left:0,behavior:a})},p=e=>{let t=e.context?.url?.hash;if(t!==void 0){if(r&&t.length>0){let e=document.getElementById(t);if(e){e.scrollIntoView({behavior:a});return}}f(0);return}let n=globalThis.location.hash;if(r&&n.length>1){let e;try{e=decodeURIComponent(n.slice(1))}catch{e=n.slice(1)}let t=document.getElementById(e);if(t){t.scrollIntoView({behavior:a});return}}f(0)},m=!1,h=!1,g=e=>{try{return I(e)}catch{return h||(h=!0,console.error(`[real-router] scroll-restore: route "${e.name}" has params that cannot be canonicalized (e.g. BigInt or cyclic structure). Scroll position will not be captured or restored for this route.`)),null}},_=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;if(t){let e=g(t);e!==null&&l(e,d())}requestAnimationFrame(()=>{if(!m){if(n===`top`||!r){p(e);return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){let t=g(e);f(t===null?0:c()[t]??0);return}p(e)}}})}),v=()=>{let t=e.getState();if(t){let e=g(t);e!==null&&l(e,d())}};return globalThis.addEventListener(`pagehide`,v),{destroy:()=>{if(!m){m=!0,_(),globalThis.removeEventListener(`pagehide`,v);try{history.scrollRestoration=u}catch{}}}}}const F=new WeakMap;function I(e){let t=F.get(e);if(t!==void 0)return t;let n=`${e.name}:${L(e.params)}`;return F.set(e,n),n}function L(e){return JSON.stringify(e,R)}function R(e,t){if(typeof t==`function`)return`<fn>`;if(typeof t==`symbol`)return`<sym>`;if(typeof t==`object`&&t&&!Array.isArray(t)){let e=Object.create(null),n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}const z=Object.freeze({destroy:()=>{}});function B(e){if(typeof document>`u`||typeof document.startViewTransition!=`function`)return z;let t=null,n=null,r=!1,i=()=>{t?.(),t=null},a=e.subscribeLeave(({signal:e})=>{if(!e.aborted)return r=!1,i(),new Promise(a=>{let o=new Promise(e=>{t=e});e.addEventListener(`abort`,()=>{r||(i(),n?.skipTransition?.(),a())},{once:!0});try{n=document.startViewTransition(()=>(a(),o))}catch{i(),a()}})}),o=e.subscribe(()=>{let e=t;r=!0,t=null,e===null?n=null:setTimeout(()=>{e(),n=null},0)});return{destroy:()=>{a(),o(),n?.skipTransition?.(),n=null,i()}}}function V(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}const H=/%[\dA-Fa-f]{2}/;function U(e){if(H.test(e))try{return encodeURI(decodeURIComponent(e)).replaceAll(`#`,`%23`)}catch{}return encodeURI(e).replaceAll(`#`,`%23`)}function W(e,t,n,r){try{let i=r?.hash,a;i!==void 0&&(a=i.startsWith(`#`)?i.slice(1):i);let o=e.buildUrl;if(o){let e=o(t,n,a===void 0?void 0:{hash:a});if(typeof e==`string`&&e.length>0)return e}let s=e.buildPath(t,n);if(typeof s!=`string`||s.length===0){console.error(`[real-router] Route "${t}" yielded an empty path. The element will render without an href attribute.`);return}return a?`${s}#${U(a)}`:s}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function G(e,t,n,r,i){let a={...i};r!==void 0&&(a.hash=r);let o=e.getState();if(o?.name===t&&X(o.params,n)){let e=o.context?.url?.hash??``;e!==(r??e)&&(a.force=!0,a.hashChange=!0)}return e.navigate(t,n,a)}const K=/\s/,q=/\S+/g;function J(e){return e?K.test(e)?e.match(q)??[]:[e]:[]}function Y(e,t,n){if(e&&t){let e=J(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=J(n),i=new Set(r);for(let t of e)i.has(t)||(i.add(t),r.push(t));return r.join(` `)}return n??void 0}function X(e,t){if(Object.is(e,t))return!0;if(!e||!t)return!1;let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;let r=e,i=t;for(let e of n)if(!Object.prototype.hasOwnProperty.call(t,e)||!Object.is(r[e],i[e]))return!1;return!0}function Z(e,n,r=!1,i=!0,a){let o=S(),c=(0,t.useMemo)(()=>a===void 0?{strict:r,ignoreQueryParams:i}:{strict:r,ignoreQueryParams:i,hash:a},[r,i,a]),l=(0,t.useMemo)(()=>(0,s.createActiveRouteSource)(o,e,n,c),[o,e,n,c]);return b(l.subscribe,l.getSnapshot,l.getSnapshot)}function ne(e,t){return e.routeName===t.routeName&&e.className===t.className&&e.activeClassName===t.activeClassName&&e.activeStrict===t.activeStrict&&e.ignoreQueryParams===t.ignoreQueryParams&&e.onClick===t.onClick&&e.target===t.target&&e.style===t.style&&e.children===t.children&&e.hash===t.hash&&X(e.routeParams,t.routeParams)&&X(e.routeOptions,t.routeOptions)}const Q=(0,a.memo)(({routeName:e,routeParams:t=E,routeOptions:n=D,className:r,activeClassName:i=`active`,activeStrict:a=!1,ignoreQueryParams:s=!0,hash:c,onClick:l,target:u,children:d,...f})=>{let p=S(),m=Z(e,t,a,s,c),h=W(p,e,t,c===void 0?void 0:{hash:c}),g=r=>{l&&(l(r),r.defaultPrevented)||!V(r)||u===`_blank`||(r.preventDefault(),G(p,e,t,c,n).catch(()=>{}))},_=Y(m,i,r);return(0,o.jsx)(`a`,{...f,href:h,className:_,onClick:g,children:d})},ne);Q.displayName=`Link`;function re({children:e,fallback:n,onError:r}){let a=(0,s.createDismissableError)(S()),c=b(a.subscribe,a.getSnapshot,a.getSnapshot),l=(0,t.useRef)(r);return(0,t.useLayoutEffect)(()=>{l.current=r}),(0,t.useEffect)(()=>{c.error&&l.current?.(c.error,c.toRoute,c.fromRoute)},[c.version]),(0,o.jsxs)(i.Fragment,{children:[e,c.error?n(c.error,c.resetError):null]})}const $=()=>(0,r.getRouteUtils)((0,c.getPluginApi)(S()).getTree());function ie(){let e=(0,s.getTransitionSource)(S());return b(e.subscribe,e.getSnapshot,e.getSnapshot)}function ae(e,n){let r=S(),i=(0,t.useRef)(e),a=n?.skipSameRoute??!0;(0,t.useLayoutEffect)(()=>{i.current=e}),(0,t.useEffect)(()=>r.subscribeLeave(({route:e,nextRoute:t,signal:n})=>{if(!(a&&e.name===t.name)&&!n.aborted)return i.current({route:e,nextRoute:t,signal:n})}),[r,a])}function oe(n,r){let{route:i,previousRoute:a}=e.t(),o=(0,t.useRef)(n),s=(0,t.useRef)(null),c=r?.skipSameRoute??!0;(0,t.useLayoutEffect)(()=>{o.current=n}),(0,t.useEffect)(()=>{i.transition.from&&(c&&i.transition.from===i.name||s.current===i||!a||(s.current=i,o.current({route:i,previousRoute:a})))},[i,a,c])}const se=({router:r,children:i,announceNavigation:a,scrollRestoration:c,viewTransitions:l})=>{(0,t.useEffect)(()=>{if(!a)return;let e=ee(r);return()=>{e.destroy()}},[a,r]);let u=c?.mode,d=c?.anchorScrolling,f=c?.behavior,p=c?.storageKey,m=c!==void 0;(0,t.useEffect)(()=>{if(!m)return;let e=P(r,{mode:u,anchorScrolling:d,behavior:f,storageKey:p,scrollContainer:c.scrollContainer});return()=>{e.destroy()}},[r,m,u,d,f,p]),(0,t.useEffect)(()=>{if(!l)return;let e=B(r);return()=>{e.destroy()}},[r,l]);let h=(0,n.getNavigator)(r),g=(0,t.useMemo)(()=>(0,s.createRouteSource)(r),[r]),{route:_,previousRoute:v}=b(g.subscribe,g.getSnapshot,g.getSnapshot),y=(0,t.useMemo)(()=>({navigator:h,route:_,previousRoute:v}),[h,_,v]);return(0,o.jsx)(e.i.Provider,{value:r,children:(0,o.jsx)(e.n.Provider,{value:h,children:(0,o.jsx)(e.r.Provider,{value:y,children:i})})})};exports.Link=Q,exports.NavigatorContext=e.n,exports.RouteContext=e.r,exports.RouteView=T,exports.RouterContext=e.i,exports.RouterErrorBoundary=re,exports.RouterProvider=se,exports.useNavigator=x,exports.useRoute=e.t,exports.useRouteEnter=oe,exports.useRouteExit=ae,exports.useRouteNode=C,exports.useRouteUtils=$,exports.useRouter=S,exports.useRouterTransition=ie;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|