@fluixi/core 1.0.0-alpha.83 → 1.0.0-alpha.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/core.global.js +2 -1
- package/dist/cli/generate.cjs +4117 -292
- package/dist/cli/generate.mjs +4122 -292
- package/dist/cli/index.cjs +4117 -292
- package/dist/cli/index.mjs +4122 -292
- package/dist/cli/run.cjs +63 -1
- package/dist/cli/run.mjs +39 -1
- package/dist/src/cdn/chunk-VNLCQBFQ.mjs +747 -0
- package/dist/src/cdn/core.cjs +1279 -1
- package/dist/src/cdn/core.d.ts +3 -3
- package/dist/src/cdn/core.js +3 -3
- package/dist/src/cdn/core.mjs +642 -1
- package/dist/src/cdn/router-WMN2AA7E.mjs +66 -0
- package/dist/src/index.cjs +1201 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -11
- package/dist/src/index.mjs +1313 -1
- package/dist/src/jsx-dev-runtime.cjs +26 -1
- package/dist/src/jsx-dev-runtime.mjs +24 -1
- package/dist/src/jsx-runtime.cjs +26 -1
- package/dist/src/jsx-runtime.js +0 -9
- package/dist/src/jsx-runtime.mjs +24 -1
- package/dist/src/lib/client/chunk-2C2KDDQV.mjs +133 -0
- package/dist/src/lib/client/index.cjs +870 -1
- package/dist/src/lib/client/index.d.ts +17 -6
- package/dist/src/lib/client/index.d.ts.map +1 -1
- package/dist/src/lib/client/index.js +26 -19
- package/dist/src/lib/client/index.mjs +222 -1
- package/dist/src/lib/client/router-X526HSWQ.mjs +548 -0
- package/dist/src/lib/context/context.cjs +118 -1
- package/dist/src/lib/context/context.d.ts +19 -37
- package/dist/src/lib/context/context.d.ts.map +1 -1
- package/dist/src/lib/context/context.js +8 -45
- package/dist/src/lib/context/context.mjs +99 -1
- package/dist/src/lib/context/index.cjs +120 -1
- package/dist/src/lib/context/index.mjs +99 -1
- package/dist/src/lib/control-flow.cjs +35 -1
- package/dist/src/lib/control-flow.mjs +25 -1
- package/dist/src/lib/core.cjs +1200 -1
- package/dist/src/lib/core.d.ts +0 -2
- package/dist/src/lib/core.d.ts.map +1 -1
- package/dist/src/lib/core.js +14 -48
- package/dist/src/lib/core.mjs +1313 -1
- package/dist/src/lib/env/index.cjs +60 -1
- package/dist/src/lib/env/index.d.ts +5 -5
- package/dist/src/lib/env/index.js +5 -5
- package/dist/src/lib/env/index.mjs +39 -1
- package/dist/src/lib/i18n/index.cjs +108 -1
- package/dist/src/lib/i18n/index.d.ts +31 -10
- package/dist/src/lib/i18n/index.d.ts.map +1 -1
- package/dist/src/lib/i18n/index.js +31 -10
- package/dist/src/lib/i18n/index.mjs +88 -1
- package/dist/src/lib/index.cjs +633 -1
- package/dist/src/lib/index.d.ts +0 -2
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +5 -11
- package/dist/src/lib/index.mjs +721 -1
- package/dist/src/lib/isomorphic.cjs +85 -1
- package/dist/src/lib/isomorphic.d.ts +41 -8
- package/dist/src/lib/isomorphic.d.ts.map +1 -1
- package/dist/src/lib/isomorphic.js +38 -5
- package/dist/src/lib/isomorphic.mjs +64 -1
- package/dist/src/lib/jsx-runtime/index.cjs +21 -1
- package/dist/src/lib/jsx-runtime/index.d.ts +1 -1
- package/dist/src/lib/jsx-runtime/index.js +1 -11
- package/dist/src/lib/jsx-runtime/index.mjs +4 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +21 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +4 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +302 -8
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +15 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.js +19 -5
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +271 -8
- package/dist/src/lib/plugins/index.cjs +311 -8
- package/dist/src/lib/plugins/index.mjs +279 -8
- package/dist/src/lib/plugins/route-codegen.cjs +73 -8
- package/dist/src/lib/plugins/route-codegen.d.ts +0 -1
- package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -1
- package/dist/src/lib/plugins/route-codegen.js +4 -5
- package/dist/src/lib/plugins/route-codegen.mjs +52 -8
- package/dist/src/lib/plugins/route-scanner.cjs +189 -1
- package/dist/src/lib/plugins/route-scanner.d.ts +1 -2
- package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -1
- package/dist/src/lib/plugins/route-scanner.js +7 -8
- package/dist/src/lib/plugins/route-scanner.mjs +158 -1
- package/dist/src/lib/plugins/vite.cjs +27 -1
- package/dist/src/lib/plugins/vite.mjs +6 -1
- package/dist/src/lib/render/await.cjs +38 -1
- package/dist/src/lib/render/await.d.ts +18 -0
- package/dist/src/lib/render/await.d.ts.map +1 -1
- package/dist/src/lib/render/await.js +20 -2
- package/dist/src/lib/render/await.mjs +17 -1
- package/dist/src/lib/render/component.cjs +221 -1
- package/dist/src/lib/render/component.d.ts +3 -44
- package/dist/src/lib/render/component.d.ts.map +1 -1
- package/dist/src/lib/render/component.js +23 -55
- package/dist/src/lib/render/component.mjs +214 -1
- package/dist/src/lib/render/deferred.cjs +175 -1
- package/dist/src/lib/render/deferred.js +5 -5
- package/dist/src/lib/render/deferred.mjs +158 -1
- package/dist/src/lib/render/index.cjs +573 -1
- package/dist/src/lib/render/index.d.ts +3 -17
- package/dist/src/lib/render/index.d.ts.map +1 -1
- package/dist/src/lib/render/index.js +8 -22
- package/dist/src/lib/render/index.mjs +590 -1
- package/dist/src/lib/render/lazy.cjs +67 -1
- package/dist/src/lib/render/lazy.d.ts +22 -1
- package/dist/src/lib/render/lazy.d.ts.map +1 -1
- package/dist/src/lib/render/lazy.js +26 -5
- package/dist/src/lib/render/lazy.mjs +50 -1
- package/dist/src/lib/render/suspense.cjs +141 -1
- package/dist/src/lib/render/suspense.d.ts +40 -0
- package/dist/src/lib/render/suspense.d.ts.map +1 -1
- package/dist/src/lib/render/suspense.js +46 -6
- package/dist/src/lib/render/suspense.mjs +136 -1
- package/dist/src/lib/render/versions.cjs +35 -1
- package/dist/src/lib/render/versions.js +6 -6
- package/dist/src/lib/render/versions.mjs +14 -1
- package/dist/src/lib/router/data.cjs +230 -1
- package/dist/src/lib/router/data.d.ts +1 -13
- package/dist/src/lib/router/data.d.ts.map +1 -1
- package/dist/src/lib/router/data.js +0 -12
- package/dist/src/lib/router/data.mjs +214 -1
- package/dist/src/lib/router/index.cjs +627 -1
- package/dist/src/lib/router/index.d.ts +62 -10
- package/dist/src/lib/router/index.d.ts.map +1 -1
- package/dist/src/lib/router/index.js +85 -33
- package/dist/src/lib/router/index.mjs +639 -1
- package/dist/src/lib/server/hydration.cjs +169 -1
- package/dist/src/lib/server/hydration.d.ts +15 -55
- package/dist/src/lib/server/hydration.d.ts.map +1 -1
- package/dist/src/lib/server/hydration.js +23 -62
- package/dist/src/lib/server/hydration.mjs +148 -1
- package/dist/src/lib/server/index.cjs +401 -11
- package/dist/src/lib/server/index.d.ts +30 -6
- package/dist/src/lib/server/index.d.ts.map +1 -1
- package/dist/src/lib/server/index.js +34 -11
- package/dist/src/lib/server/index.mjs +379 -11
- package/dist/src/lib/server/reactive.cjs +197 -1
- package/dist/src/lib/server/reactive.d.ts +18 -77
- package/dist/src/lib/server/reactive.d.ts.map +1 -1
- package/dist/src/lib/server/reactive.js +19 -78
- package/dist/src/lib/server/reactive.mjs +176 -1
- package/dist/src/lib/theme/index.cjs +110 -1
- package/dist/src/lib/theme/index.d.ts +19 -4
- package/dist/src/lib/theme/index.d.ts.map +1 -1
- package/dist/src/lib/theme/index.js +17 -2
- package/dist/src/lib/theme/index.mjs +89 -1
- package/dist/src/lib/utils/index.cjs +209 -1
- package/dist/src/lib/utils/index.d.ts +0 -93
- package/dist/src/lib/utils/index.d.ts.map +1 -1
- package/dist/src/lib/utils/index.js +0 -93
- package/dist/src/lib/utils/index.mjs +188 -1
- package/dist/src/routes.cjs +37 -1
- package/dist/src/routes.d.ts +1 -1
- package/dist/src/routes.js +2 -2
- package/dist/src/routes.mjs +17 -1
- package/dist/src/server.cjs +400 -11
- package/dist/src/server.d.ts +0 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +0 -1
- package/dist/src/server.mjs +377 -11
- package/dist/src/utils.cjs +21 -1
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.js +1 -1
- package/dist/src/utils.mjs +4 -1
- package/dist/src/version.generated.cjs +26 -1
- package/dist/src/version.generated.d.ts +1 -1
- package/dist/src/version.generated.js +2 -2
- package/dist/src/version.generated.mjs +5 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +17 -16
- package/src/index.ts +2 -14
- package/dist/src/cdn/chunk-55BT3H6E.mjs +0 -1
- package/dist/src/cdn/router-5JJZBK4E.mjs +0 -1
- package/dist/src/lib/client/chunk-SM4WHBOP.mjs +0 -1
- package/dist/src/lib/client/router-IBD4WPQT.mjs +0 -1
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Fluixi adapter for the framework-agnostic @fluixi/router core.
|
|
3
2
|
*
|
|
4
3
|
* Renders the resolved match tree TOP-DOWN. Each layer's component is rendered
|
|
5
4
|
* inside the PARENT layer's <Outlet/> scope, so a child route inherits whatever
|
|
6
5
|
* context a parent layout provides. <Outlet/> is reactive but keyed on the child's
|
|
7
6
|
* component reference, so it only re-renders when the child route at that depth
|
|
8
|
-
* actually changes
|
|
7
|
+
* actually changes: sibling navigation reuses the layout, deeper navigation
|
|
9
8
|
* leaves shallower layouts untouched.
|
|
10
9
|
*
|
|
11
10
|
* No parentGate, no deferred content memo: a child is rendered straight from the
|
|
@@ -25,12 +24,26 @@ export interface RouterProps<C = any> {
|
|
|
25
24
|
base?: string;
|
|
26
25
|
history?: HistoryAdapter;
|
|
27
26
|
/**
|
|
28
|
-
* Rendered when the current URL matches no route
|
|
27
|
+
* Rendered when the current URL matches no route, a component, an element, or any renderable.
|
|
29
28
|
* Defaults to a minimal built-in 404 so an unmatched URL never renders a blank page. For a 404
|
|
30
|
-
* that keeps your layout/chrome, add a catch-all file route instead (`[...slug].tsx`
|
|
29
|
+
* that keeps your layout/chrome, add a catch-all file route instead (`[...slug].tsx` -> `*`).
|
|
31
30
|
*/
|
|
32
31
|
notFound?: any;
|
|
33
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* The router. Matches the current URL against `routes` and renders what matches.
|
|
35
|
+
*
|
|
36
|
+
* Supplies the router context everything below reaches through `useRouter`,
|
|
37
|
+
* `useNavigate` and `Link`, so those only work inside it. `history` defaults to a
|
|
38
|
+
* browser history; pass a memory history for tests or a server render. An unmatched URL
|
|
39
|
+
* renders `notFound`, which defaults to a minimal built-in page so a bad URL is never
|
|
40
|
+
* blank. For a 404 that keeps your layout, add a catch-all file route instead.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* html`<${Router} routes=${routes} base="/app" />`;
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
34
47
|
export declare function Router<C = any>(props: RouterProps<C>): any;
|
|
35
48
|
/** Renders this layout's child route, inside this layout's context. */
|
|
36
49
|
export declare function Outlet(): any;
|
|
@@ -39,6 +52,14 @@ export declare function Redirect(props: {
|
|
|
39
52
|
to: string;
|
|
40
53
|
replace?: boolean;
|
|
41
54
|
}): null;
|
|
55
|
+
/**
|
|
56
|
+
* The router context: the router itself, the current match, and the location.
|
|
57
|
+
*
|
|
58
|
+
* Safe to call during a server render, where a detached context yields a no-op stub
|
|
59
|
+
* rather than throwing, since an SSR pass has nowhere to navigate to. On the client a
|
|
60
|
+
* missing router is genuine misuse and throws, because the alternative is a component
|
|
61
|
+
* that silently never navigates.
|
|
62
|
+
*/
|
|
42
63
|
export declare function useRouter(): RouterCtxValue;
|
|
43
64
|
/**
|
|
44
65
|
* Reactive merged params across all matched layers, as an accessor. Deep-equal
|
|
@@ -50,7 +71,7 @@ export declare function useParams<T extends Record<string, string> = Record<stri
|
|
|
50
71
|
export declare function useLevelParams(): Record<string, string>;
|
|
51
72
|
/**
|
|
52
73
|
* Reactive accessor for a single route param. Default `===` equality on the
|
|
53
|
-
* string value, so it only re-triggers when
|
|
74
|
+
* string value, so it only re-triggers when this key changes, not when other
|
|
54
75
|
* params at the same level change.
|
|
55
76
|
*/
|
|
56
77
|
export declare function useParam(key: string): () => string | undefined;
|
|
@@ -99,7 +120,7 @@ export interface LinkNavigationOptions {
|
|
|
99
120
|
replace?: boolean;
|
|
100
121
|
/**
|
|
101
122
|
* Called with the resolved URL before navigating. Return false to leave the click
|
|
102
|
-
* alone
|
|
123
|
+
* alone, for a section of the app that must load as a document (a different
|
|
103
124
|
* bundle, a server-rendered admin area, a file route).
|
|
104
125
|
*/
|
|
105
126
|
shouldNavigate?: (url: URL, anchor: HTMLAnchorElement) => boolean;
|
|
@@ -117,16 +138,32 @@ export interface LinkNavigationOptions {
|
|
|
117
138
|
* <article onClick={onClick} innerHTML={doc.html} />
|
|
118
139
|
* ```
|
|
119
140
|
*
|
|
120
|
-
* The anchors stay real anchors
|
|
141
|
+
* The anchors stay real anchors: middle-click, right-click -> open in new tab, "copy
|
|
121
142
|
* link address" and crawlers all keep working, because the element is untouched and only
|
|
122
143
|
* a plain left-click is intercepted.
|
|
123
144
|
*
|
|
124
145
|
* Left alone: modified clicks, anything but the primary button, an already-prevented
|
|
125
146
|
* event, `target`, `download`, `rel="external"`, a non-http scheme (`mailto:`, `tel:`),
|
|
126
|
-
* another origin, and a hash pointing inside the current page
|
|
147
|
+
* another origin, and a hash pointing inside the current page, that last one is the
|
|
127
148
|
* browser's scroll, and hijacking it breaks in-page anchors.
|
|
128
149
|
*/
|
|
129
150
|
export declare function useLinkNavigation(options?: LinkNavigationOptions): (event: MouseEvent) => void;
|
|
151
|
+
/**
|
|
152
|
+
* A function that navigates, for use outside a `Link`.
|
|
153
|
+
*
|
|
154
|
+
* Reach for it after an action rather than for a plain link: a form that redirects on
|
|
155
|
+
* success, a guard that bounces an unauthenticated visitor. Prefer `Link` for anything a
|
|
156
|
+
* visitor clicks, since an anchor is what middle-click, copy-link and a crawler expect.
|
|
157
|
+
*
|
|
158
|
+
* Navigation is a no-op during a server render, for the reason `useRouter` explains.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* const navigate = useNavigate();
|
|
163
|
+
* await save(form);
|
|
164
|
+
* navigate(`/posts/${id}`, { replace: true });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
130
167
|
export declare function useNavigate(): (to: string, options?: NavigateOptions) => void;
|
|
131
168
|
/**
|
|
132
169
|
* The resolved data for the nearest route that declared a `data` loader. Always
|
|
@@ -147,13 +184,28 @@ export interface LinkProps {
|
|
|
147
184
|
slot?: string;
|
|
148
185
|
children?: any;
|
|
149
186
|
/**
|
|
150
|
-
* Everything else is forwarded onto the `<a
|
|
187
|
+
* Everything else is forwarded onto the `<a>`: id, style, title, aria-*,
|
|
151
188
|
* data-*, event handlers. Typed openly because the forwarding is
|
|
152
189
|
* allow-by-default: a prop this interface forgot still reaches the DOM, and
|
|
153
190
|
* refusing it here would only mean the type disagreeing with the runtime.
|
|
154
191
|
*/
|
|
155
192
|
[key: string]: unknown;
|
|
156
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* An anchor that navigates without a full page load.
|
|
196
|
+
*
|
|
197
|
+
* Renders a real `<a href>`, so middle-click, copy-link, and a crawler all behave. A
|
|
198
|
+
* plain left click is intercepted and routed instead.
|
|
199
|
+
*
|
|
200
|
+
* Active state defaults to the current pathname matching `href`, and `activeClass` is
|
|
201
|
+
* added while it holds. Override `active` when a section link should stay lit for its
|
|
202
|
+
* children.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* html`<${Link} href="/about" activeClass="current">About</${Link}>`;
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
157
209
|
export declare function Link(props: LinkProps): any;
|
|
158
210
|
/** Alias for {@link Link}. */
|
|
159
211
|
export declare const A: typeof Link;
|
|
@@ -180,7 +232,7 @@ export interface FormProps {
|
|
|
180
232
|
export declare function Form(props: FormProps): any;
|
|
181
233
|
/**
|
|
182
234
|
* Download the lazy component chunks for the route(s) matching `pathname` and resolve when
|
|
183
|
-
* they're all loaded. Await this
|
|
235
|
+
* they're all loaded. Await this before hydrating: once each matched lazy file-route is
|
|
184
236
|
* resolved it renders synchronously on the first pass (no Suspense fallback, no late
|
|
185
237
|
* re-render), so hydration adopts the server DOM in place instead of building a duplicate
|
|
186
238
|
* subtree next to it. No-op for routes with no lazy components. Safe to call when the URL
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/router/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/router/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Fluixi adapter for the framework-agnostic @fluixi/router core.
|
|
3
2
|
*
|
|
4
3
|
* Renders the resolved match tree TOP-DOWN. Each layer's component is rendered
|
|
5
4
|
* inside the PARENT layer's <Outlet/> scope, so a child route inherits whatever
|
|
6
5
|
* context a parent layout provides. <Outlet/> is reactive but keyed on the child's
|
|
7
6
|
* component reference, so it only re-renders when the child route at that depth
|
|
8
|
-
* actually changes
|
|
7
|
+
* actually changes: sibling navigation reuses the layout, deeper navigation
|
|
9
8
|
* leaves shallower layouts untouched.
|
|
10
9
|
*
|
|
11
10
|
* No parentGate, no deferred content memo: a child is rendered straight from the
|
|
@@ -15,7 +14,7 @@
|
|
|
15
14
|
import { createSignal, createMemo, createResource, createEffect, getOwner, onCleanup, untrack, } from '@fluixi/reactive/signal';
|
|
16
15
|
import { insert, createComponent, createNativeElement, setAttribute, } from '@fluixi/dom';
|
|
17
16
|
// Reactive context (not fluixi createProvider, which destructures children
|
|
18
|
-
// eagerly) so a `get children()` getter renders
|
|
17
|
+
// eagerly) so a `get children()` getter renders after the context is stamped.
|
|
19
18
|
import { createContext, useContext } from '@fluixi/reactive/signal';
|
|
20
19
|
import { get } from '@fluixi/utils/object';
|
|
21
20
|
import { deepEqual } from '@fluixi/utils/compare';
|
|
@@ -59,14 +58,14 @@ function renderLayer(m, depth, base) {
|
|
|
59
58
|
});
|
|
60
59
|
if (!data)
|
|
61
60
|
return buildPage();
|
|
62
|
-
// Gate on the data being resolved
|
|
61
|
+
// Gate on the data being resolved, like the old router, so the page reads
|
|
63
62
|
// ready data (rd() returns the value, not a thrown promise) and works without a
|
|
64
63
|
// Suspense boundary. Signal-gated (`ready` only flips when loading actually
|
|
65
64
|
// changes) so navigation re-renders don't re-run this and rebuild the page.
|
|
66
65
|
const res = data;
|
|
67
66
|
const isLoading = () => res.loading;
|
|
68
67
|
// untrack the initial read so the enclosing render memo doesn't subscribe to the
|
|
69
|
-
// resource state (that would re-run renderLayer and recreate the resource
|
|
68
|
+
// resource state (that would re-run renderLayer and recreate the resource, a loop).
|
|
70
69
|
const [ready, setReady] = createSignal(untrack(() => !isLoading()));
|
|
71
70
|
createEffect(() => setReady(!isLoading()));
|
|
72
71
|
return createMemo(() => (ready() ? buildPage() : null));
|
|
@@ -83,7 +82,7 @@ function renderChild(ctx) {
|
|
|
83
82
|
// signal write (no value check), so a memo that read `matched` would re-run on
|
|
84
83
|
// every navigation and re-render the child. A signal only notifies when its value
|
|
85
84
|
// actually changes, so the render memo below re-runs only when the route at this
|
|
86
|
-
// depth changes
|
|
85
|
+
// depth changes: sibling navigation reuses the layout, deeper navigation leaves
|
|
87
86
|
// this level untouched. The child is rendered INLINE (no detached createRoot), so
|
|
88
87
|
// it stays connected to the Suspense / context owner chain.
|
|
89
88
|
const [childComp, setChildComp] = createSignal(untrack(() => ctx.matched()[childIdx]?.component));
|
|
@@ -94,8 +93,8 @@ function renderChild(ctx) {
|
|
|
94
93
|
return createMemo(() => {
|
|
95
94
|
const component = childComp();
|
|
96
95
|
if (!component) {
|
|
97
|
-
// No route at this depth. At the
|
|
98
|
-
// URL matched nothing
|
|
96
|
+
// No route at this depth. At the root (the only ctx carrying `notFound`) that means the
|
|
97
|
+
// URL matched nothing: render the not-found fallback instead of a blank page. Nested
|
|
99
98
|
// Outlets have no `notFound`, so they stay null (a missing child is just an empty Outlet).
|
|
100
99
|
return ctx.notFound ? ctx.notFound() : null;
|
|
101
100
|
}
|
|
@@ -110,8 +109,8 @@ function renderChild(ctx) {
|
|
|
110
109
|
/**
|
|
111
110
|
* Resolve the Router's `notFound` prop to a renderable view. A component is instantiated; an
|
|
112
111
|
* element/value is returned as-is; when omitted, a minimal built-in 404 keeps the page from
|
|
113
|
-
* rendering blank. Prefer a catch-all file route (`[...slug].tsx`
|
|
114
|
-
* inside your layout
|
|
112
|
+
* rendering blank. Prefer a catch-all file route (`[...slug].tsx` -> `*`) when the 404 should sit
|
|
113
|
+
* inside your layout, this prop is the app-level fallback for an otherwise unmatched URL.
|
|
115
114
|
*/
|
|
116
115
|
function renderNotFound(notFound) {
|
|
117
116
|
if (notFound == null)
|
|
@@ -135,6 +134,20 @@ function buildDefaultNotFound() {
|
|
|
135
134
|
el.appendChild(p);
|
|
136
135
|
return el;
|
|
137
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* The router. Matches the current URL against `routes` and renders what matches.
|
|
139
|
+
*
|
|
140
|
+
* Supplies the router context everything below reaches through `useRouter`,
|
|
141
|
+
* `useNavigate` and `Link`, so those only work inside it. `history` defaults to a
|
|
142
|
+
* browser history; pass a memory history for tests or a server render. An unmatched URL
|
|
143
|
+
* renders `notFound`, which defaults to a minimal built-in page so a bad URL is never
|
|
144
|
+
* blank. For a 404 that keeps your layout, add a catch-all file route instead.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* html`<${Router} routes=${routes} base="/app" />`;
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
138
151
|
export function Router(props) {
|
|
139
152
|
const history = props.history ?? createBrowserHistory();
|
|
140
153
|
const router = createCoreRouter({
|
|
@@ -148,7 +161,7 @@ export function Router(props) {
|
|
|
148
161
|
unsub();
|
|
149
162
|
router.destroy();
|
|
150
163
|
});
|
|
151
|
-
// Drop pathless layers (no component)
|
|
164
|
+
// Drop pathless layers (no component), their params still appear in the merged
|
|
152
165
|
// params exposed by RouterContext.
|
|
153
166
|
const matched = createMemo(() => (state().match?.matched ?? []).filter((m) => m.component));
|
|
154
167
|
const ctx = {
|
|
@@ -162,12 +175,12 @@ export function Router(props) {
|
|
|
162
175
|
matched,
|
|
163
176
|
params: ctx.params,
|
|
164
177
|
location: ctx.location,
|
|
165
|
-
// Only the root carries this
|
|
178
|
+
// Only the root carries this: renderChild shows it when the URL matched nothing.
|
|
166
179
|
notFound: () => renderNotFound(props.notFound),
|
|
167
180
|
};
|
|
168
181
|
// Build the root view once, lazily, inside the provider's children getter: the
|
|
169
182
|
// getter must run in the provider scope (so components can useRouter), but the
|
|
170
|
-
// reactive provider re-invokes it whenever content changes
|
|
183
|
+
// reactive provider re-invokes it whenever content changes: caching keeps the
|
|
171
184
|
// root chain from being rebuilt on every navigation.
|
|
172
185
|
let rootView;
|
|
173
186
|
return RouterContext.Provider({
|
|
@@ -190,7 +203,7 @@ export function Redirect(props) {
|
|
|
190
203
|
const ctx = useContext(RouterContext);
|
|
191
204
|
// Nothing to do without a router, and nothing to navigate on the server.
|
|
192
205
|
if (ctx && typeof window !== 'undefined') {
|
|
193
|
-
// Navigate
|
|
206
|
+
// Navigate after the current render commits. Navigating during render (an effect
|
|
194
207
|
// running mid-render) updated the location but the route never re-matched, so the
|
|
195
208
|
// target never showed. Guard against firing if this Redirect is torn down first.
|
|
196
209
|
let cancelled = false;
|
|
@@ -204,9 +217,9 @@ export function Redirect(props) {
|
|
|
204
217
|
}
|
|
205
218
|
// ─── Hooks ──────────────────────────────────────────────────────────────────
|
|
206
219
|
// Safe stub returned by useRouter on the SERVER when no RouterContext is on the owner
|
|
207
|
-
// chain. That happens during a late/detached re-render
|
|
208
|
-
// settling
|
|
209
|
-
// root
|
|
220
|
+
// chain. That happens during a late/detached re-render: e.g. a slow data resource
|
|
221
|
+
// settling after renderToStringAsync already serialized the response and disposed the
|
|
222
|
+
// root: whose output is discarded. Returning this (instead of throwing) prevents a
|
|
210
223
|
// floating rejection that crashes the dev server / shows an error overlay seconds
|
|
211
224
|
// after the page already rendered.
|
|
212
225
|
const _ssrRouterStub = {
|
|
@@ -214,12 +227,20 @@ const _ssrRouterStub = {
|
|
|
214
227
|
location: () => ({ pathname: '', search: '', hash: '', query: {} }),
|
|
215
228
|
params: () => ({}),
|
|
216
229
|
};
|
|
230
|
+
/**
|
|
231
|
+
* The router context: the router itself, the current match, and the location.
|
|
232
|
+
*
|
|
233
|
+
* Safe to call during a server render, where a detached context yields a no-op stub
|
|
234
|
+
* rather than throwing, since an SSR pass has nowhere to navigate to. On the client a
|
|
235
|
+
* missing router is genuine misuse and throws, because the alternative is a component
|
|
236
|
+
* that silently never navigates.
|
|
237
|
+
*/
|
|
217
238
|
export function useRouter() {
|
|
218
239
|
const ctx = useContext(RouterContext);
|
|
219
240
|
if (ctx)
|
|
220
241
|
return ctx;
|
|
221
242
|
// On the server, degrade to a no-op stub (see above). On the client, a missing
|
|
222
|
-
// router is genuine misuse
|
|
243
|
+
// router is genuine misuse: throw.
|
|
223
244
|
if (typeof window === 'undefined')
|
|
224
245
|
return _ssrRouterStub;
|
|
225
246
|
throw new Error('[router] useRouter must be used within <Router>');
|
|
@@ -241,7 +262,7 @@ export function useLevelParams() {
|
|
|
241
262
|
}
|
|
242
263
|
/**
|
|
243
264
|
* Reactive accessor for a single route param. Default `===` equality on the
|
|
244
|
-
* string value, so it only re-triggers when
|
|
265
|
+
* string value, so it only re-triggers when this key changes, not when other
|
|
245
266
|
* params at the same level change.
|
|
246
267
|
*/
|
|
247
268
|
export function useParam(key) {
|
|
@@ -331,13 +352,13 @@ export function useLocation() {
|
|
|
331
352
|
* <article onClick={onClick} innerHTML={doc.html} />
|
|
332
353
|
* ```
|
|
333
354
|
*
|
|
334
|
-
* The anchors stay real anchors
|
|
355
|
+
* The anchors stay real anchors: middle-click, right-click -> open in new tab, "copy
|
|
335
356
|
* link address" and crawlers all keep working, because the element is untouched and only
|
|
336
357
|
* a plain left-click is intercepted.
|
|
337
358
|
*
|
|
338
359
|
* Left alone: modified clicks, anything but the primary button, an already-prevented
|
|
339
360
|
* event, `target`, `download`, `rel="external"`, a non-http scheme (`mailto:`, `tel:`),
|
|
340
|
-
* another origin, and a hash pointing inside the current page
|
|
361
|
+
* another origin, and a hash pointing inside the current page, that last one is the
|
|
341
362
|
* browser's scroll, and hijacking it breaks in-page anchors.
|
|
342
363
|
*/
|
|
343
364
|
export function useLinkNavigation(options = {}) {
|
|
@@ -372,6 +393,22 @@ export function useLinkNavigation(options = {}) {
|
|
|
372
393
|
ctx.router.navigate(url.pathname + url.search + url.hash, { replace: options.replace });
|
|
373
394
|
};
|
|
374
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* A function that navigates, for use outside a `Link`.
|
|
398
|
+
*
|
|
399
|
+
* Reach for it after an action rather than for a plain link: a form that redirects on
|
|
400
|
+
* success, a guard that bounces an unauthenticated visitor. Prefer `Link` for anything a
|
|
401
|
+
* visitor clicks, since an anchor is what middle-click, copy-link and a crawler expect.
|
|
402
|
+
*
|
|
403
|
+
* Navigation is a no-op during a server render, for the reason `useRouter` explains.
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```ts
|
|
407
|
+
* const navigate = useNavigate();
|
|
408
|
+
* await save(form);
|
|
409
|
+
* navigate(`/posts/${id}`, { replace: true });
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
375
412
|
export function useNavigate() {
|
|
376
413
|
// useRouter is SSR-safe (returns a no-op stub on the server when the context is
|
|
377
414
|
// detached), so navigation degrades to a no-op during SSR and only throws on
|
|
@@ -400,18 +437,33 @@ const LINK_OWN_PROPS = new Set([
|
|
|
400
437
|
'replace',
|
|
401
438
|
'children',
|
|
402
439
|
]);
|
|
440
|
+
/**
|
|
441
|
+
* An anchor that navigates without a full page load.
|
|
442
|
+
*
|
|
443
|
+
* Renders a real `<a href>`, so middle-click, copy-link, and a crawler all behave. A
|
|
444
|
+
* plain left click is intercepted and routed instead.
|
|
445
|
+
*
|
|
446
|
+
* Active state defaults to the current pathname matching `href`, and `activeClass` is
|
|
447
|
+
* added while it holds. Override `active` when a section link should stay lit for its
|
|
448
|
+
* children.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```ts
|
|
452
|
+
* html`<${Link} href="/about" activeClass="current">About</${Link}>`;
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
403
455
|
export function Link(props) {
|
|
404
456
|
const ctx = useContext(RouterContext);
|
|
405
457
|
const navigate = () => ctx?.router.navigate(read(props.href) ?? '', { replace: read(props.replace) });
|
|
406
|
-
// createNativeElement branches on isServer()
|
|
458
|
+
// createNativeElement branches on isServer() -> a real ServerNode <a> (serialized as a true
|
|
407
459
|
// element, not an escaped string) on the server, a real DOM <a> on the client.
|
|
408
460
|
const a = createNativeElement('a');
|
|
409
461
|
setAttribute(a, 'href', read(props.href) ?? '');
|
|
410
462
|
if (props.slot)
|
|
411
463
|
setAttribute(a, 'slot', read(props.slot));
|
|
412
|
-
// Forward any other author attributes (data-*, aria-*, style, id, title, role,
|
|
464
|
+
// Forward any other author attributes (data-*, aria-*, style, id, title, role, ...)
|
|
413
465
|
// onto the <a>, the way <Form> does. Without this a component composed via
|
|
414
|
-
// `as={Link}` (polymorphic) silently loses its styling hooks
|
|
466
|
+
// `as={Link}` (polymorphic) silently loses its styling hooks: e.g. @fluixi-ui
|
|
415
467
|
// parts carry `data-*` slots + inline styles that would otherwise be dropped, so
|
|
416
468
|
// the element renders unstyled. Own-props handled elsewhere are skipped:
|
|
417
469
|
// href/slot above, class/className/active/activeClass in the effect, and
|
|
@@ -419,7 +471,7 @@ export function Link(props) {
|
|
|
419
471
|
// Keys, not entries: `Object.entries` reads every prop, and `children` is a getter
|
|
420
472
|
// that builds fresh nodes per access. Under hydration that discarded first build
|
|
421
473
|
// consumes the server's nodes, so the real read below produced a second copy of
|
|
422
|
-
// them
|
|
474
|
+
// them, a duplicated logo and pager on every prerendered page.
|
|
423
475
|
for (const k of Object.keys(props)) {
|
|
424
476
|
if (LINK_OWN_PROPS.has(k))
|
|
425
477
|
continue;
|
|
@@ -444,7 +496,7 @@ export function Link(props) {
|
|
|
444
496
|
setAttribute(a, 'class', base);
|
|
445
497
|
}
|
|
446
498
|
// Client only: keep href + active class in sync with reactive props / location.
|
|
447
|
-
// (Skipped on the server
|
|
499
|
+
// (Skipped on the server: `a` is a ServerNode without these DOM setters; the static
|
|
448
500
|
// href/class were set above.)
|
|
449
501
|
if (typeof a.addEventListener === 'function') {
|
|
450
502
|
createEffect(() => {
|
|
@@ -476,18 +528,18 @@ export const A = Link;
|
|
|
476
528
|
*/
|
|
477
529
|
export function Form(props) {
|
|
478
530
|
const action = props.action;
|
|
479
|
-
const cls = (props.className ?? props.class); // compiler passes class
|
|
531
|
+
const cls = (props.className ?? props.class); // compiler passes class -> className
|
|
480
532
|
const url = action.url ?? '';
|
|
481
533
|
// createNativeElement/setAttribute branch on isServer(), so this builds a real ServerNode
|
|
482
|
-
// <form> on the server (serialized as a true element,
|
|
483
|
-
// DOM <form> on the client
|
|
534
|
+
// <form> on the server (serialized as a true element, not an escaped string) and a real
|
|
535
|
+
// DOM <form> on the client: hydration reuses the same element.
|
|
484
536
|
const form = createNativeElement('form');
|
|
485
537
|
setAttribute(form, 'method', 'post');
|
|
486
538
|
if (url)
|
|
487
539
|
setAttribute(form, 'action', url);
|
|
488
540
|
if (cls)
|
|
489
541
|
setAttribute(form, 'class', cls);
|
|
490
|
-
// Keys, not entries
|
|
542
|
+
// Keys, not entries, same reason as Link: reading `children` here would build its
|
|
491
543
|
// nodes once and throw them away.
|
|
492
544
|
for (const k of Object.keys(props)) {
|
|
493
545
|
if (k === 'action' || k === 'children' || k === 'class' || k === 'className')
|
|
@@ -513,7 +565,7 @@ export function Form(props) {
|
|
|
513
565
|
}
|
|
514
566
|
// Read children ONCE: the compiler emits `get children()` as a getter that builds fresh
|
|
515
567
|
// nodes on every access, so reading it twice (here + the null check) created a duplicate
|
|
516
|
-
// set
|
|
568
|
+
// set: under hydration that meant two <input>s in the form.
|
|
517
569
|
const children = props.children;
|
|
518
570
|
if (children != null)
|
|
519
571
|
insert(form, children);
|
|
@@ -522,7 +574,7 @@ export function Form(props) {
|
|
|
522
574
|
// ─── Hydration preload ───────────────────────────────────────────────────────────
|
|
523
575
|
/**
|
|
524
576
|
* Download the lazy component chunks for the route(s) matching `pathname` and resolve when
|
|
525
|
-
* they're all loaded. Await this
|
|
577
|
+
* they're all loaded. Await this before hydrating: once each matched lazy file-route is
|
|
526
578
|
* resolved it renders synchronously on the first pass (no Suspense fallback, no late
|
|
527
579
|
* re-render), so hydration adopts the server DOM in place instead of building a duplicate
|
|
528
580
|
* subtree next to it. No-op for routes with no lazy components. Safe to call when the URL
|
|
@@ -542,7 +594,7 @@ export async function preloadRoutes(routes, pathname) {
|
|
|
542
594
|
}
|
|
543
595
|
// ─── Re-exports ────────────────────────────────────────────────────────────────
|
|
544
596
|
export { createMemoryHistory, createBrowserHistory, matchRoutes, matchPath, } from '@fluixi/router';
|
|
545
|
-
// Action/cache/lazy layer is orthogonal to routing
|
|
597
|
+
// Action/cache/lazy layer is orthogonal to routing: re-export so a route file can
|
|
546
598
|
// swap its import path wholesale. (Routing hooks above are the router ones.)
|
|
547
599
|
export { cache, action, revalidate, createAsync, useSubmission, useAction, } from './data.js';
|
|
548
600
|
export { lazy } from '../render/lazy.js';
|