@takazudo/zfb-runtime 2.5.2 → 2.7.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 +47 -16
- package/dist/client-router/events.js +2 -1
- package/dist/client-router/events.js.map +1 -1
- package/dist/client-router/history-safe.d.ts +2 -0
- package/dist/client-router/history-safe.js +34 -0
- package/dist/client-router/history-safe.js.map +1 -0
- package/dist/client-router/index.js +5 -1
- package/dist/client-router/index.js.map +1 -1
- package/dist/client-router/router.d.ts +8 -2
- package/dist/client-router/router.js +187 -99
- package/dist/client-router/router.js.map +1 -1
- package/dist/client-router-component.d.ts +74 -0
- package/dist/client-router-component.js +157 -0
- package/dist/client-router-component.js.map +1 -0
- package/dist/client-router.d.ts +1 -72
- package/dist/client-router.js +19 -146
- package/dist/client-router.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/snapshot.d.ts +31 -0
- package/dist/snapshot.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ import type {
|
|
|
79
79
|
|
|
80
80
|
```ts
|
|
81
81
|
import {
|
|
82
|
-
ClientRouter, // framework-agnostic <head> helper —
|
|
82
|
+
ClientRouter, // framework-agnostic <head> helper — mount it to opt a page into SPA navigation
|
|
83
83
|
navigate, // imperative navigation
|
|
84
84
|
supportsViewTransitions, // browser capability check
|
|
85
85
|
transitionEnabledOnThisPage, // reads zfb-view-transitions-enabled meta
|
|
@@ -104,6 +104,13 @@ import type { ContentSnapshot } from "@takazudo/zfb-runtime/snapshot";
|
|
|
104
104
|
import { ClientRouter } from "@takazudo/zfb-runtime/client-router";
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
The two differ in one way that matters: the root barrel is **side-effect-free**
|
|
108
|
+
— importing anything from it, `ClientRouter` included, registers no listeners
|
|
109
|
+
and touches no history — while evaluating the `./client-router` subpath calls
|
|
110
|
+
`init()` and activates the router on the current page. See [Enabling SPA
|
|
111
|
+
soft-navigation](#enabling-spa-soft-navigation-the-runtime-ships-automatically)
|
|
112
|
+
below for how a normal zfb build gets that activation for you.
|
|
113
|
+
|
|
107
114
|
#### Enabling SPA soft-navigation (the runtime ships automatically)
|
|
108
115
|
|
|
109
116
|
Mounting `<ClientRouter />` in your layout `<head>` is normally **all you need**.
|
|
@@ -146,9 +153,15 @@ export default function Layout({ children }) {
|
|
|
146
153
|
SPA navigation set so traversal behavior is deterministic.
|
|
147
154
|
|
|
148
155
|
**How the runtime reaches the browser.** `<ClientRouter />` itself only renders
|
|
149
|
-
SSR `<head>` tags
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
SSR `<head>` tags, and the module it lives in is pure: importing `ClientRouter`
|
|
157
|
+
from the `@takazudo/zfb-runtime` barrel registers nothing and runs no code on
|
|
158
|
+
the page. Everything the router does at startup — seeding this page's history
|
|
159
|
+
entry and scroll position, marking the scripts the initial load already ran, and
|
|
160
|
+
registering the `popstate` / `load` / `pageshow` / scroll listeners plus the
|
|
161
|
+
click and form-submit intercepts — happens inside a single `init()` call.
|
|
162
|
+
|
|
163
|
+
`init()` is invoked as a side effect when `@takazudo/zfb-runtime/client-router`
|
|
164
|
+
is evaluated in the browser, guarded so it never runs during SSR:
|
|
152
165
|
|
|
153
166
|
```ts
|
|
154
167
|
// inside @takazudo/zfb-runtime — client-router.ts
|
|
@@ -157,6 +170,9 @@ if (typeof document !== "undefined") {
|
|
|
157
170
|
}
|
|
158
171
|
```
|
|
159
172
|
|
|
173
|
+
`init()` is idempotent: calling it again (a second `<ClientRouter />` mount, an
|
|
174
|
+
HMR re-run, a manual call) is a no-op for the parts already done.
|
|
175
|
+
|
|
160
176
|
To get that side-effect import into the client bundle, zfb's island scanner
|
|
161
177
|
detects when a page transitively reaches `<ClientRouter />` and injects
|
|
162
178
|
`import "@takazudo/zfb-runtime/client-router"` into the islands asset
|
|
@@ -188,7 +204,10 @@ trigger — firing on them would ship the runtime to projects that only referenc
|
|
|
188
204
|
`rt.ClientRouter`, and
|
|
189
205
|
- a type-only import — `import type { ClientRouter }` (or `{ type ClientRouter }`).
|
|
190
206
|
|
|
191
|
-
|
|
207
|
+
When detection misses, nothing else picks up the slack: the barrel import is
|
|
208
|
+
side-effect-free, so an undetected `<ClientRouter />` renders its meta tags into
|
|
209
|
+
`<head>` and no runtime is ever shipped to activate against them. If
|
|
210
|
+
soft-navigation is not working because your reference takes one of these forms
|
|
192
211
|
(or the mounting module is otherwise not reachable from a page), force the
|
|
193
212
|
runtime in with an explicit side-effect import from a page-reachable
|
|
194
213
|
`"use client"` island. The island renders nothing; running its bundle in the
|
|
@@ -228,17 +247,29 @@ for the full API.
|
|
|
228
247
|
|
|
229
248
|
#### `navigate()` needs `<ClientRouter />` mounted on the current page
|
|
230
249
|
|
|
231
|
-
The root barrel exports `navigate` and `syncHistoryEntry`, but **not** `init
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
250
|
+
The root barrel exports `navigate` and `syncHistoryEntry`, but **not** `init`,
|
|
251
|
+
and importing from that barrel installs no interception listeners. Each helper
|
|
252
|
+
still does exactly what its own docs say when you call it — a direct
|
|
253
|
+
`navigate()` call navigates, `syncHistoryEntry()` writes its history entry —
|
|
254
|
+
but nothing starts intercepting the user's link clicks and form submits on
|
|
255
|
+
your behalf.
|
|
256
|
+
|
|
257
|
+
Soft navigation needs two separate things on the current page:
|
|
258
|
+
|
|
259
|
+
1. **The opt-in meta tag.** `navigate()` reaches `<meta
|
|
260
|
+
name="zfb-view-transitions-enabled">`, which `<ClientRouter />` renders into
|
|
261
|
+
`<head>`, before it will do a soft swap; with that tag absent it falls back
|
|
262
|
+
to a full `location.href` load.
|
|
263
|
+
2. **An activated router.** That comes from `init()` — in a normal zfb build,
|
|
264
|
+
from the `import "@takazudo/zfb-runtime/client-router"` the island scanner
|
|
265
|
+
injects once it sees a page reach `<ClientRouter />` (see above).
|
|
266
|
+
|
|
267
|
+
So the answer for both is the same: mount `<ClientRouter />` in the layout
|
|
268
|
+
`<head>` of every page that should be soft-navigable, and let the build ship
|
|
269
|
+
the runtime. `init` itself is exported from the
|
|
270
|
+
`@takazudo/zfb-runtime/client-router` subpath, not the root barrel, for the
|
|
271
|
+
rare case where you want to call it directly instead of relying on the
|
|
272
|
+
subpath's own import-time activation.
|
|
242
273
|
|
|
243
274
|
#### Persisting elements and island state across navigations (`data-zfb-transition-persist`)
|
|
244
275
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
|
+
import { safeReplaceState } from "./history-safe.js";
|
|
2
3
|
import { swap } from "./swap-functions.js";
|
|
3
4
|
export const TRANSITION_BEFORE_PREPARATION = "zfb:before-preparation";
|
|
4
5
|
export const TRANSITION_AFTER_PREPARATION = "zfb:after-preparation";
|
|
@@ -99,7 +100,7 @@ export async function doPreparation(from, to, direction, navigationType, sourceE
|
|
|
99
100
|
export const updateScrollPosition = (positions) => {
|
|
100
101
|
if (history.state) {
|
|
101
102
|
history.scrollRestoration = "manual";
|
|
102
|
-
|
|
103
|
+
safeReplaceState({ ...history.state, ...positions }, "");
|
|
103
104
|
}
|
|
104
105
|
};
|
|
105
106
|
export async function doSwap(afterPreparation, viewTransition, afterDispatch) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/client-router/events.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"dom\" />\nimport { swap } from \"./swap-functions.js\";\nimport type { Direction, NavigationTypeString } from \"./types.js\";\n\nexport const TRANSITION_BEFORE_PREPARATION = \"zfb:before-preparation\";\nexport const TRANSITION_AFTER_PREPARATION = \"zfb:after-preparation\";\nexport const TRANSITION_BEFORE_SWAP = \"zfb:before-swap\";\nexport const TRANSITION_AFTER_SWAP = \"zfb:after-swap\";\nexport const TRANSITION_PAGE_LOAD = \"zfb:page-load\";\nexport const TRANSITION_NAVIGATION_ABORTED = \"zfb:navigation-aborted\";\n\ntype Events =\n | \"zfb:after-preparation\"\n | \"zfb:after-swap\"\n | \"zfb:page-load\"\n | \"zfb:navigation-aborted\";\nexport const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));\nexport const onPageLoad = () => triggerEvent(\"zfb:page-load\");\n\n/*\n * Common stuff\n */\nclass BeforeEvent extends Event {\n readonly from: URL;\n to: URL;\n direction: Direction | string;\n readonly navigationType: NavigationTypeString;\n readonly sourceElement: Element | undefined;\n readonly info: any;\n newDocument: Document;\n readonly signal: AbortSignal;\n\n constructor(\n type: string,\n eventInitDict: EventInit | undefined,\n from: URL,\n to: URL,\n direction: Direction | string,\n navigationType: NavigationTypeString,\n sourceElement: Element | undefined,\n info: any,\n newDocument: Document,\n signal: AbortSignal,\n ) {\n super(type, eventInitDict);\n this.from = from;\n this.to = to;\n this.direction = direction;\n this.navigationType = navigationType;\n this.sourceElement = sourceElement;\n this.info = info;\n this.newDocument = newDocument;\n this.signal = signal;\n\n Object.defineProperties(this, {\n from: { enumerable: true },\n to: { enumerable: true, writable: true },\n direction: { enumerable: true, writable: true },\n navigationType: { enumerable: true },\n sourceElement: { enumerable: true },\n info: { enumerable: true },\n newDocument: { enumerable: true, writable: true },\n signal: { enumerable: true },\n });\n }\n}\n\n/*\n * TransitionBeforePreparationEvent\n\n */\nexport const isTransitionBeforePreparationEvent = (\n value: any,\n): value is TransitionBeforePreparationEvent =>\n typeof value === \"object\" && value !== null && value.type === TRANSITION_BEFORE_PREPARATION;\nexport class TransitionBeforePreparationEvent extends BeforeEvent {\n formData: FormData | undefined;\n loader: () => Promise<void>;\n constructor(\n from: URL,\n to: URL,\n direction: Direction | string,\n navigationType: NavigationTypeString,\n sourceElement: Element | undefined,\n info: any,\n newDocument: Document,\n signal: AbortSignal,\n formData: FormData | undefined,\n loader: (event: TransitionBeforePreparationEvent) => Promise<void>,\n ) {\n super(\n TRANSITION_BEFORE_PREPARATION,\n { cancelable: true },\n from,\n to,\n direction,\n navigationType,\n sourceElement,\n info,\n newDocument,\n signal,\n );\n this.formData = formData;\n this.loader = loader.bind(this, this);\n Object.defineProperties(this, {\n formData: { enumerable: true },\n loader: { enumerable: true, writable: true },\n });\n }\n}\n\n/*\n * TransitionBeforeSwapEvent\n */\nexport const isTransitionBeforeSwapEvent = (value: any): value is TransitionBeforeSwapEvent =>\n typeof value === \"object\" && value !== null && value.type === TRANSITION_BEFORE_SWAP;\nexport class TransitionBeforeSwapEvent extends BeforeEvent {\n override readonly direction: Direction | string;\n readonly viewTransition: ViewTransition;\n swap: () => void;\n\n constructor(afterPreparation: BeforeEvent, viewTransition: ViewTransition) {\n super(\n TRANSITION_BEFORE_SWAP,\n undefined,\n afterPreparation.from,\n afterPreparation.to,\n afterPreparation.direction,\n afterPreparation.navigationType,\n afterPreparation.sourceElement,\n afterPreparation.info,\n afterPreparation.newDocument,\n afterPreparation.signal,\n );\n this.direction = afterPreparation.direction;\n this.viewTransition = viewTransition;\n this.swap = () => swap(this.newDocument);\n\n Object.defineProperties(this, {\n direction: { enumerable: true },\n viewTransition: { enumerable: true },\n swap: { enumerable: true, writable: true },\n });\n }\n}\n\nexport async function doPreparation(\n from: URL,\n to: URL,\n direction: Direction | string,\n navigationType: NavigationTypeString,\n sourceElement: Element | undefined,\n info: any,\n signal: AbortSignal,\n formData: FormData | undefined,\n defaultLoader: (event: TransitionBeforePreparationEvent) => Promise<void>,\n) {\n const event = new TransitionBeforePreparationEvent(\n from,\n to,\n direction,\n navigationType,\n sourceElement,\n info,\n window.document,\n signal,\n formData,\n defaultLoader,\n );\n if (document.dispatchEvent(event)) {\n await event.loader();\n if (!event.defaultPrevented) {\n triggerEvent(\"zfb:after-preparation\");\n if (event.navigationType !== \"traverse\") {\n // save the current scroll position before we change the DOM and transition to the new page\n updateScrollPosition({ scrollX, scrollY });\n }\n }\n }\n return event;\n}\n\n// only update history entries that are managed by us\n// leave other entries alone and do not accidentally add state.\nexport const updateScrollPosition = (positions: { scrollX: number; scrollY: number }) => {\n if (history.state) {\n history.scrollRestoration = \"manual\";\n history.replaceState({ ...history.state, ...positions }, \"\");\n }\n};\n\nexport async function doSwap(\n afterPreparation: BeforeEvent,\n viewTransition: ViewTransition,\n afterDispatch?: () => Promise<void>,\n) {\n const event = new TransitionBeforeSwapEvent(afterPreparation, viewTransition);\n document.dispatchEvent(event);\n if (afterDispatch) {\n await afterDispatch();\n }\n event.swap();\n return event;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/client-router/events.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"dom\" />\nimport { safeReplaceState } from \"./history-safe.js\";\nimport { swap } from \"./swap-functions.js\";\nimport type { Direction, NavigationTypeString } from \"./types.js\";\n\nexport const TRANSITION_BEFORE_PREPARATION = \"zfb:before-preparation\";\nexport const TRANSITION_AFTER_PREPARATION = \"zfb:after-preparation\";\nexport const TRANSITION_BEFORE_SWAP = \"zfb:before-swap\";\nexport const TRANSITION_AFTER_SWAP = \"zfb:after-swap\";\nexport const TRANSITION_PAGE_LOAD = \"zfb:page-load\";\nexport const TRANSITION_NAVIGATION_ABORTED = \"zfb:navigation-aborted\";\n\ntype Events =\n | \"zfb:after-preparation\"\n | \"zfb:after-swap\"\n | \"zfb:page-load\"\n | \"zfb:navigation-aborted\";\nexport const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));\nexport const onPageLoad = () => triggerEvent(\"zfb:page-load\");\n\n/*\n * Common stuff\n */\nclass BeforeEvent extends Event {\n readonly from: URL;\n to: URL;\n direction: Direction | string;\n readonly navigationType: NavigationTypeString;\n readonly sourceElement: Element | undefined;\n readonly info: any;\n newDocument: Document;\n readonly signal: AbortSignal;\n\n constructor(\n type: string,\n eventInitDict: EventInit | undefined,\n from: URL,\n to: URL,\n direction: Direction | string,\n navigationType: NavigationTypeString,\n sourceElement: Element | undefined,\n info: any,\n newDocument: Document,\n signal: AbortSignal,\n ) {\n super(type, eventInitDict);\n this.from = from;\n this.to = to;\n this.direction = direction;\n this.navigationType = navigationType;\n this.sourceElement = sourceElement;\n this.info = info;\n this.newDocument = newDocument;\n this.signal = signal;\n\n Object.defineProperties(this, {\n from: { enumerable: true },\n to: { enumerable: true, writable: true },\n direction: { enumerable: true, writable: true },\n navigationType: { enumerable: true },\n sourceElement: { enumerable: true },\n info: { enumerable: true },\n newDocument: { enumerable: true, writable: true },\n signal: { enumerable: true },\n });\n }\n}\n\n/*\n * TransitionBeforePreparationEvent\n\n */\nexport const isTransitionBeforePreparationEvent = (\n value: any,\n): value is TransitionBeforePreparationEvent =>\n typeof value === \"object\" && value !== null && value.type === TRANSITION_BEFORE_PREPARATION;\nexport class TransitionBeforePreparationEvent extends BeforeEvent {\n formData: FormData | undefined;\n loader: () => Promise<void>;\n constructor(\n from: URL,\n to: URL,\n direction: Direction | string,\n navigationType: NavigationTypeString,\n sourceElement: Element | undefined,\n info: any,\n newDocument: Document,\n signal: AbortSignal,\n formData: FormData | undefined,\n loader: (event: TransitionBeforePreparationEvent) => Promise<void>,\n ) {\n super(\n TRANSITION_BEFORE_PREPARATION,\n { cancelable: true },\n from,\n to,\n direction,\n navigationType,\n sourceElement,\n info,\n newDocument,\n signal,\n );\n this.formData = formData;\n this.loader = loader.bind(this, this);\n Object.defineProperties(this, {\n formData: { enumerable: true },\n loader: { enumerable: true, writable: true },\n });\n }\n}\n\n/*\n * TransitionBeforeSwapEvent\n */\nexport const isTransitionBeforeSwapEvent = (value: any): value is TransitionBeforeSwapEvent =>\n typeof value === \"object\" && value !== null && value.type === TRANSITION_BEFORE_SWAP;\nexport class TransitionBeforeSwapEvent extends BeforeEvent {\n override readonly direction: Direction | string;\n readonly viewTransition: ViewTransition;\n swap: () => void;\n\n constructor(afterPreparation: BeforeEvent, viewTransition: ViewTransition) {\n super(\n TRANSITION_BEFORE_SWAP,\n undefined,\n afterPreparation.from,\n afterPreparation.to,\n afterPreparation.direction,\n afterPreparation.navigationType,\n afterPreparation.sourceElement,\n afterPreparation.info,\n afterPreparation.newDocument,\n afterPreparation.signal,\n );\n this.direction = afterPreparation.direction;\n this.viewTransition = viewTransition;\n this.swap = () => swap(this.newDocument);\n\n Object.defineProperties(this, {\n direction: { enumerable: true },\n viewTransition: { enumerable: true },\n swap: { enumerable: true, writable: true },\n });\n }\n}\n\nexport async function doPreparation(\n from: URL,\n to: URL,\n direction: Direction | string,\n navigationType: NavigationTypeString,\n sourceElement: Element | undefined,\n info: any,\n signal: AbortSignal,\n formData: FormData | undefined,\n defaultLoader: (event: TransitionBeforePreparationEvent) => Promise<void>,\n) {\n const event = new TransitionBeforePreparationEvent(\n from,\n to,\n direction,\n navigationType,\n sourceElement,\n info,\n window.document,\n signal,\n formData,\n defaultLoader,\n );\n if (document.dispatchEvent(event)) {\n await event.loader();\n if (!event.defaultPrevented) {\n triggerEvent(\"zfb:after-preparation\");\n if (event.navigationType !== \"traverse\") {\n // save the current scroll position before we change the DOM and transition to the new page\n updateScrollPosition({ scrollX, scrollY });\n }\n }\n }\n return event;\n}\n\n// only update history entries that are managed by us\n// leave other entries alone and do not accidentally add state.\nexport const updateScrollPosition = (positions: { scrollX: number; scrollY: number }) => {\n if (history.state) {\n history.scrollRestoration = \"manual\";\n safeReplaceState({ ...history.state, ...positions }, \"\");\n }\n};\n\nexport async function doSwap(\n afterPreparation: BeforeEvent,\n viewTransition: ViewTransition,\n afterDispatch?: () => Promise<void>,\n) {\n const event = new TransitionBeforeSwapEvent(afterPreparation, viewTransition);\n document.dispatchEvent(event);\n if (afterDispatch) {\n await afterDispatch();\n }\n event.swap();\n return event;\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
// zfb-only addition (no Astro upstream — #2424).
|
|
3
|
+
//
|
|
4
|
+
// Inside an `about:srcdoc` document (e.g. an SPA-preview iframe shell),
|
|
5
|
+
// Chromium refuses `history.replaceState`/`pushState` and throws. The router
|
|
6
|
+
// calls these unconditionally — at module init and from several
|
|
7
|
+
// navigation-adjacent paths — so a zfb page loaded via `srcdoc` would break
|
|
8
|
+
// on the very first call. These wrappers swallow that failure so the router
|
|
9
|
+
// degrades silently instead of propagating the throw.
|
|
10
|
+
//
|
|
11
|
+
// In a normal document the History API never throws here, so the try/catch
|
|
12
|
+
// is a no-op passthrough: same call, same arguments, same behavior.
|
|
13
|
+
//
|
|
14
|
+
// `...args` (rather than naming `data`/`unused`/`url`) preserves the exact
|
|
15
|
+
// call arity — several call sites omit the trailing `url` argument, and
|
|
16
|
+
// spreading a shorter tuple calls the native method with that same shorter
|
|
17
|
+
// arity rather than passing an explicit `undefined`.
|
|
18
|
+
export function safeReplaceState(...args) {
|
|
19
|
+
try {
|
|
20
|
+
history.replaceState(...args);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// e.g. about:srcdoc — degrade silently, see file header.
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function safePushState(...args) {
|
|
27
|
+
try {
|
|
28
|
+
history.pushState(...args);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// e.g. about:srcdoc — degrade silently, see file header.
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=history-safe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-safe.js","sourceRoot":"","sources":["../../src/client-router/history-safe.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,iDAAiD;AACjD,EAAE;AACF,wEAAwE;AACxE,6EAA6E;AAC7E,gEAAgE;AAChE,4EAA4E;AAC5E,4EAA4E;AAC5E,sDAAsD;AACtD,EAAE;AACF,2EAA2E;AAC3E,oEAAoE;AACpE,EAAE;AACF,2EAA2E;AAC3E,wEAAwE;AACxE,2EAA2E;AAC3E,qDAAqD;AAErD,MAAM,UAAU,gBAAgB,CAAC,GAAG,IAAyC;IAC3E,IAAI,CAAC;QACH,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAG,IAAsC;IACrE,IAAI,CAAC;QACH,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC","sourcesContent":["/// <reference lib=\"dom\" />\n// zfb-only addition (no Astro upstream — #2424).\n//\n// Inside an `about:srcdoc` document (e.g. an SPA-preview iframe shell),\n// Chromium refuses `history.replaceState`/`pushState` and throws. The router\n// calls these unconditionally — at module init and from several\n// navigation-adjacent paths — so a zfb page loaded via `srcdoc` would break\n// on the very first call. These wrappers swallow that failure so the router\n// degrades silently instead of propagating the throw.\n//\n// In a normal document the History API never throws here, so the try/catch\n// is a no-op passthrough: same call, same arguments, same behavior.\n//\n// `...args` (rather than naming `data`/`unused`/`url`) preserves the exact\n// call arity — several call sites omit the trailing `url` argument, and\n// spreading a shorter tuple calls the native method with that same shorter\n// arity rather than passing an explicit `undefined`.\n\nexport function safeReplaceState(...args: Parameters<History[\"replaceState\"]>): void {\n try {\n history.replaceState(...args);\n } catch {\n // e.g. about:srcdoc — degrade silently, see file header.\n }\n}\n\nexport function safePushState(...args: Parameters<History[\"pushState\"]>): void {\n try {\n history.pushState(...args);\n } catch {\n // e.g. about:srcdoc — degrade silently, see file header.\n }\n}\n"]}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// Public API surface for the client-router module.
|
|
2
2
|
// This file is the barrel for @takazudo/zfb-runtime's client-router export.
|
|
3
3
|
// W3D adds the <ClientRouter /> component and ClientRouterProps re-exports.
|
|
4
|
-
// Component (W3D).
|
|
4
|
+
// Component (W3D). Re-exported via the activation shim `../client-router.js`
|
|
5
|
+
// (not `../client-router-component.js` directly) so importing this subpath
|
|
6
|
+
// barrel — the target of the islands bundler's auto-injected
|
|
7
|
+
// `import "@takazudo/zfb-runtime/client-router"` — keeps activating the
|
|
8
|
+
// router at module eval, byte-compatible with pre-split behavior (#2437).
|
|
5
9
|
export { ClientRouter } from "../client-router.js";
|
|
6
10
|
export { TRANSITION_BEFORE_PREPARATION, TRANSITION_AFTER_PREPARATION, TRANSITION_BEFORE_SWAP, TRANSITION_AFTER_SWAP, TRANSITION_PAGE_LOAD, TRANSITION_NAVIGATION_ABORTED, TransitionBeforePreparationEvent, TransitionBeforeSwapEvent, isTransitionBeforePreparationEvent, isTransitionBeforeSwapEvent, } from "./events.js";
|
|
7
11
|
export { swapFunctions, swap } from "./swap-functions.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client-router/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,4EAA4E;AAC5E,4EAA4E;AAE5E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client-router/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,4EAA4E;AAC5E,4EAA4E;AAE5E,6EAA6E;AAC7E,2EAA2E;AAC3E,6DAA6D;AAC7D,wEAAwE;AACxE,0EAA0E;AAC1E,OAAO,EAAE,YAAY,EAA0B,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,6BAA6B,EAC7B,gCAAgC,EAChC,yBAAyB,EACzB,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAUrB,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE1D,yBAAyB;AACzB,sEAAsE;AACtE,oDAAoD;AACpD,yFAAyF;AACzF,iFAAiF;AACjF,OAAO,EACL,QAAQ,EACR,uBAAuB,EACvB,2BAA2B,EAC3B,IAAI,EACJ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,kCAAkC;AAClC,8EAA8E;AAC9E,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,eAAe,CAAC","sourcesContent":["// Public API surface for the client-router module.\n// This file is the barrel for @takazudo/zfb-runtime's client-router export.\n// W3D adds the <ClientRouter /> component and ClientRouterProps re-exports.\n\n// Component (W3D). Re-exported via the activation shim `../client-router.js`\n// (not `../client-router-component.js` directly) so importing this subpath\n// barrel — the target of the islands bundler's auto-injected\n// `import \"@takazudo/zfb-runtime/client-router\"` — keeps activating the\n// router at module eval, byte-compatible with pre-split behavior (#2437).\nexport { ClientRouter, type ClientRouterProps } from \"../client-router.js\";\n\nexport {\n TRANSITION_BEFORE_PREPARATION,\n TRANSITION_AFTER_PREPARATION,\n TRANSITION_BEFORE_SWAP,\n TRANSITION_AFTER_SWAP,\n TRANSITION_PAGE_LOAD,\n TRANSITION_NAVIGATION_ABORTED,\n TransitionBeforePreparationEvent,\n TransitionBeforeSwapEvent,\n isTransitionBeforePreparationEvent,\n isTransitionBeforeSwapEvent,\n} from \"./events.js\";\n\nexport type {\n Direction,\n Fallback,\n NavigationTypeString,\n Options,\n SyncHistoryEntryOptions,\n} from \"./types.js\";\n\nexport { swapFunctions, swap } from \"./swap-functions.js\";\n\n// Router public surface.\n// - W3C1: `supportsViewTransitions`, `transitionEnabledOnThisPage`.\n// - W3C2: `navigate()` (public navigation entry).\n// - W3C3: `init()` (idempotent bootstrap: registers click + form intercept listeners).\n// - W2 (#1377): `syncHistoryEntry()` (history bookkeeping without navigation).\nexport {\n navigate,\n supportsViewTransitions,\n transitionEnabledOnThisPage,\n init,\n syncHistoryEntry,\n} from \"./router.js\";\nexport type { InitOptions } from \"./router.js\";\n\n// Prefetch public surface (#276).\n// `init` from prefetch.ts is re-exported as `prefetchInit` to avoid colliding\n// with the router's `init` above.\nexport { prefetch, init as prefetchInit } from \"./prefetch.js\";\nexport type { PrefetchStrategy, PrefetchInitOptions, PrefetchOptions } from \"./prefetch.js\";\n"]}
|
|
@@ -35,8 +35,14 @@ export interface InitOptions {
|
|
|
35
35
|
prefetchAll?: boolean;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* Bootstrap the client router on this page: restore its history entry, mark
|
|
39
|
+
* the already-executed scripts, and wire up the navigation, click and
|
|
40
|
+
* form-submit listeners. Safe to call multiple times — each of the two phases
|
|
41
|
+
* runs at most once (idempotent).
|
|
42
|
+
*
|
|
43
|
+
* Evaluating this module does nothing; every side effect the router performs
|
|
44
|
+
* at startup happens here (#2436). Two once-guards rather than one, because
|
|
45
|
+
* the phases have different eligibility — see `pageStateSeeded`.
|
|
40
46
|
*
|
|
41
47
|
* @param _options - Forward-compat hook matching Astro's init() signature. Ignored in v1.
|
|
42
48
|
*/
|