create-coralite 1.0.0 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-coralite",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Coralite scaffolding script",
5
5
  "bin": {
6
6
  "create-coralite": "bin/index.js",
@@ -181,6 +181,8 @@ Do NOT delete the `ref` attribute, and do NOT add an empty `client({ refs }) { r
181
181
 
182
182
  Top-level imports are reserved for `definePage` / `definePlugin` and modules used by isomorphic code (`getters`, `style`, `slots`). Modules used by `server()`, `client()`, or `paths()` must be loaded with dynamic `await import()` inside the block (`CORALITE-E301`).
183
183
 
184
+ - **Lazy dependency stylesheets (`await import('*.css')`)**: Load dependency or local `.css` files lazily inside component and page `client()` blocks (or transitive client `.js` helpers) via `await import('pkg/styles.css', options)`, which bundles CSS at build time into hashed `assets/css/` assets, injects `<link rel="stylesheet">` into `<head>` in deterministic manifest order at runtime, and resolves to `{ default: link.sheet ?? null, link }`. Both flat options (`{ media, nonce, crossorigin, referrerPolicy, signal, force }`) and Import Attributes (`{ with: { type: 'css', ... }, signal, force }`) are supported. Static top-level `.css` imports or dynamic `.css` imports outside `client()` throw `CORALITE-E109`; unresolvable `.css` files throw `CORALITE-E403`.
185
+
184
186
  ## 4. Serialization boundary
185
187
 
186
188
  - `server()` runs in Node.js at build time and is stripped from the browser bundle. It returns an object to initialize/hydrate `state`.
@@ -212,3 +214,16 @@ Top-level imports are reserved for `definePage` / `definePlugin` and modules use
212
214
  - `tests/fixtures/` — component test fixtures (`.html`)
213
215
  - `public/` — static assets copied verbatim to output
214
216
  - `coralite.config.js` — project & plugin configuration
217
+
218
+ ## 8. SPA Router (opt-in)
219
+
220
+ The opt-in router plugin (`coralite/plugins/router`) provides single-page application navigation. Register it in `coralite.config.js` under `plugins` (`plugins: [router({ ... })]`). Registration gates ALL SPA behavior — without it, every SPA navigation behavior (link interception, popstate, guards, head reconciliation) is inert: a `data-router-outlet` marker alone does nothing, and the page behaves as a standard multi-page app.
221
+
222
+ - **Outlets**: Any element carrying the outlet attribute (default `data-router-outlet`) or the reserved `<router-outlet>` tag is an outlet. Every SPA-routed page MUST have an outlet or client navigation fails; outlet-less pages are auto-wrapped by default. Set `autoWrap: false` to disable automatic body wrapping; outlet-less pages then render as authored and still resolve tokens normally. Set `outletOnly: true` to skip link interception when the live document has no outlet, so those clicks use native browser navigation. `router.navigate()` is NOT affected by `outletOnly` and still updates history before failing if no outlet exists, so do not call it from outlet-less pages. Everything outside the outlet (navbar, background audio, open sockets) is never touched by the router — those component instances and their state persist across every route swap.
223
+ - **Client API**: `client({ router })` injects the router: `navigate(path, { replace })`, `current()`, `beforeEach(guard)` (returns the unregister function), and the `viewTransitions` getter. Also available on `window.__coralite_router__`.
224
+ - **Guards**: `beforeEach` guards may return `true`/`undefined` (allow), `false` (block), a relative or same-origin path (soft redirect; redirect chains are capped at depth 10), or an `http(s)` URL (hard redirect via `window.location.replace()`).
225
+ - **Guard placement**: The guard list lives in the router's client-init scope and PERSISTS across the whole SPA session — an outlet swap does not reset it, and nothing auto-unregisters a guard when its route leaves. App-wide guards (auth, redirects) MUST be registered in a persistent shell component OUTSIDE the outlet (it connects once, so the guard registers exactly once). Route-scoped guards MUST capture the function returned by `beforeEach` and call it on their component `signal` abort. Registering guards inside a route component's `client()` without unregistering accumulates one extra guard per visit.
226
+ - **State scoping**: Component `state` is route-scoped — on navigation the old outlet is disconnected (its `signal` aborts), and the new route hydrates from its pre-built HTML, so `state` mutations are lost when the route leaves. App-scoped state belongs in the global `store` (declared in `coralite.config.js`), which the router never touches and which survives every swap. Release imperative resources a component allocates (workers, canvas/WebGL contexts, external library handles) when the component is torn down — hook teardown to the `signal` `abort` event.
227
+ - **Navigation events**: Cancelable `coralite:navigating` (fired before the swap) and post-swap `coralite:navigated` on `window`, both with `detail: { from, to }`.
228
+
229
+ Full contract: https://coralite.dev/docs/reference/plugins/router.html — patterns guide: https://coralite.dev/docs/guide/spa-router.html
@@ -102,6 +102,7 @@ When generating or editing Coralite files (`src/components/*.html`, `src/pages/*
102
102
  - Top-level imports are reserved for `definePage` / `definePlugin` and modules used by isomorphic code (`getters`, `style`, `slots`).
103
103
  - `server()` runs in Node.js at build time and is stripped from the browser bundle. It returns an object to initialize/hydrate `state`.
104
104
  - `client()` is serialized to run in the browser and cannot reference module-scope variables or top-level imports. Modules used by `server()`, `client()`, or `paths()` must be loaded with dynamic `await import()` inside the block (`CORALITE-E301`).
105
+ - **Lazy dependency stylesheets (`await import('*.css')`)**: Load dependency or local `.css` files lazily inside component and page `client()` blocks (or transitive client `.js` helpers) via `await import('pkg/styles.css', options)` (`{ default: link.sheet ?? null, link }`). Static top-level `.css` imports or dynamic `.css` imports outside `client()` throw `CORALITE-E109`; unresolvable `.css` files throw `CORALITE-E403`.
105
106
 
106
107
  ## 4. No defensive guards in deterministic blocks
107
108
 
@@ -121,3 +122,14 @@ When generating or editing Coralite files (`src/components/*.html`, `src/pages/*
121
122
  - `pnpm build` — build production output to `dist/`
122
123
  - `pnpm check` — validate components, pages, and plugins (`coralite check`)
123
124
  - `pnpm fix` — auto-fix safe validation diagnostics (`coralite fix`)
125
+
126
+ ## 7. SPA Router (opt-in)
127
+
128
+ The opt-in router plugin (`coralite/plugins/router`) gates ALL SPA behavior: without registration in `coralite.config.js`, a `data-router-outlet` marker is inert and the app stays multi-page.
129
+
130
+ - **Outlets**: The routed region is any element with the outlet attribute (default `data-router-outlet`) or the reserved `<router-outlet>` tag. Every SPA-routed page MUST have an outlet or client navigation fails. Set `autoWrap: false` to disable automatic body wrapping; outlet-less pages render as authored and still resolve tokens. Set `outletOnly: true` so links on outlet-less pages use native navigation instead of being intercepted. `router.navigate()` is NOT affected by `outletOnly` and still updates history before failing without an outlet — do not call it from outlet-less pages. Elements OUTSIDE the outlet are untouched by the router and persist across route swaps.
131
+ - **Client API**: `client({ router })` injects `navigate(path, { replace })`, `current()`, `beforeEach(guard)` (returns the unregister function), and the `viewTransitions` getter.
132
+ - **Guard placement**: The guard list persists for the whole SPA session — outlet swaps never reset it, and nothing auto-unregisters. App-wide guards MUST be registered in a persistent shell component OUTSIDE the outlet; route-scoped guards MUST unregister on component `signal` abort, or every visit accumulates another guard.
133
+ - **State scoping**: Component `state` is route-scoped (lost when the route leaves; the new route re-hydrates from its pre-built HTML). App-scoped state MUST live in the global `store`, which survives every swap. Teardown imperative resources on `signal` abort.
134
+
135
+ Full contract: https://coralite.dev/docs/reference/plugins/router.html — patterns guide: https://coralite.dev/docs/guide/spa-router.html
@@ -99,6 +99,7 @@ alwaysApply: false
99
99
  - Top-level imports are reserved for `definePage` / `definePlugin` and modules used by isomorphic code (`getters`, `style`, `slots`).
100
100
  - `server()` runs in Node.js at build time and is stripped from the browser bundle. It returns an object to initialize/hydrate `state`.
101
101
  - `client()` is serialized to run in the browser and cannot reference module-scope variables or top-level imports. Modules used by `server()`, `client()`, or `paths()` must be loaded with dynamic `await import()` inside the block (`CORALITE-E301`).
102
+ - **Lazy dependency stylesheets (`await import('*.css')`)**: Load dependency or local `.css` files lazily inside component and page `client()` blocks (or transitive client `.js` helpers) via `await import('pkg/styles.css', options)` (`{ default: link.sheet ?? null, link }`). Static top-level `.css` imports or dynamic `.css` imports outside `client()` throw `CORALITE-E109`; unresolvable `.css` files throw `CORALITE-E403`.
102
103
 
103
104
  ## 3. No defensive guards in deterministic blocks
104
105
 
@@ -111,3 +112,14 @@ alwaysApply: false
111
112
 
112
113
  - **Factory functions over classes**: Default to factory functions (`createX`). No `this` outside class bodies; always use destructured context (`state`, `refs`, `emit`, `root`).
113
114
  - **Scoped CSS**: Use `:host` for the custom element root and `:host-context(.selector)` for ancestor themes. Write `.child` directly instead of `:host .child`.
115
+
116
+ ## 5. SPA Router (opt-in)
117
+
118
+ The opt-in router plugin (`coralite/plugins/router`) gates ALL SPA behavior: without registration in `coralite.config.js`, a `data-router-outlet` marker is inert and the app stays multi-page.
119
+
120
+ - **Outlets**: The routed region is any element with the outlet attribute (default `data-router-outlet`) or the reserved `<router-outlet>` tag. Every SPA-routed page MUST have an outlet or client navigation fails. Set `autoWrap: false` to disable automatic body wrapping; outlet-less pages render as authored and still resolve tokens. Set `outletOnly: true` so links on outlet-less pages use native navigation instead of being intercepted. `router.navigate()` is NOT affected by `outletOnly` and still updates history before failing without an outlet — do not call it from outlet-less pages. Elements OUTSIDE the outlet are untouched by the router and persist across route swaps.
121
+ - **Client API**: `client({ router })` injects `navigate(path, { replace })`, `current()`, `beforeEach(guard)` (returns the unregister function), and the `viewTransitions` getter.
122
+ - **Guard placement**: The guard list persists for the whole SPA session — outlet swaps never reset it, and nothing auto-unregisters. App-wide guards MUST be registered in a persistent shell component OUTSIDE the outlet; route-scoped guards MUST unregister on component `signal` abort, or every visit accumulates another guard.
123
+ - **State scoping**: Component `state` is route-scoped (lost when the route leaves; the new route re-hydrates from its pre-built HTML). App-scoped state MUST live in the global `store`, which survives every swap. Teardown imperative resources on `signal` abort.
124
+
125
+ Full contract: https://coralite.dev/docs/reference/plugins/router.html — patterns guide: https://coralite.dev/docs/guide/spa-router.html
@@ -181,6 +181,8 @@ Do NOT delete the `ref` attribute, and do NOT add an empty `client({ refs }) { r
181
181
 
182
182
  Top-level imports are reserved for `definePage` / `definePlugin` and modules used by isomorphic code (`getters`, `style`, `slots`). Modules used by `server()`, `client()`, or `paths()` must be loaded with dynamic `await import()` inside the block (`CORALITE-E301`).
183
183
 
184
+ - **Lazy dependency stylesheets (`await import('*.css')`)**: Load dependency or local `.css` files lazily inside component and page `client()` blocks (or transitive client `.js` helpers) via `await import('pkg/styles.css', options)`, which bundles CSS at build time into hashed `assets/css/` assets, injects `<link rel="stylesheet">` into `<head>` in deterministic manifest order at runtime, and resolves to `{ default: link.sheet ?? null, link }`. Both flat options (`{ media, nonce, crossorigin, referrerPolicy, signal, force }`) and Import Attributes (`{ with: { type: 'css', ... }, signal, force }`) are supported. Static top-level `.css` imports or dynamic `.css` imports outside `client()` throw `CORALITE-E109`; unresolvable `.css` files throw `CORALITE-E403`.
185
+
184
186
  ## 4. Serialization boundary
185
187
 
186
188
  - `server()` runs in Node.js at build time and is stripped from the browser bundle. It returns an object to initialize/hydrate `state`.
@@ -212,3 +214,16 @@ Top-level imports are reserved for `definePage` / `definePlugin` and modules use
212
214
  - `tests/fixtures/` — component test fixtures (`.html`)
213
215
  - `public/` — static assets copied verbatim to output
214
216
  - `coralite.config.js` — project & plugin configuration
217
+
218
+ ## 8. SPA Router (opt-in)
219
+
220
+ The opt-in router plugin (`coralite/plugins/router`) provides single-page application navigation. Register it in `coralite.config.js` under `plugins` (`plugins: [router({ ... })]`). Registration gates ALL SPA behavior — without it, every SPA navigation behavior (link interception, popstate, guards, head reconciliation) is inert: a `data-router-outlet` marker alone does nothing, and the page behaves as a standard multi-page app.
221
+
222
+ - **Outlets**: Any element carrying the outlet attribute (default `data-router-outlet`) or the reserved `<router-outlet>` tag is an outlet. Every SPA-routed page MUST have an outlet or client navigation fails; outlet-less pages are auto-wrapped by default. Set `autoWrap: false` to disable automatic body wrapping; outlet-less pages then render as authored and still resolve tokens normally. Set `outletOnly: true` to skip link interception when the live document has no outlet, so those clicks use native browser navigation. `router.navigate()` is NOT affected by `outletOnly` and still updates history before failing if no outlet exists, so do not call it from outlet-less pages. Everything outside the outlet (navbar, background audio, open sockets) is never touched by the router — those component instances and their state persist across every route swap.
223
+ - **Client API**: `client({ router })` injects the router: `navigate(path, { replace })`, `current()`, `beforeEach(guard)` (returns the unregister function), and the `viewTransitions` getter. Also available on `window.__coralite_router__`.
224
+ - **Guards**: `beforeEach` guards may return `true`/`undefined` (allow), `false` (block), a relative or same-origin path (soft redirect; redirect chains are capped at depth 10), or an `http(s)` URL (hard redirect via `window.location.replace()`).
225
+ - **Guard placement**: The guard list lives in the router's client-init scope and PERSISTS across the whole SPA session — an outlet swap does not reset it, and nothing auto-unregisters a guard when its route leaves. App-wide guards (auth, redirects) MUST be registered in a persistent shell component OUTSIDE the outlet (it connects once, so the guard registers exactly once). Route-scoped guards MUST capture the function returned by `beforeEach` and call it on their component `signal` abort. Registering guards inside a route component's `client()` without unregistering accumulates one extra guard per visit.
226
+ - **State scoping**: Component `state` is route-scoped — on navigation the old outlet is disconnected (its `signal` aborts), and the new route hydrates from its pre-built HTML, so `state` mutations are lost when the route leaves. App-scoped state belongs in the global `store` (declared in `coralite.config.js`), which the router never touches and which survives every swap. Release imperative resources a component allocates (workers, canvas/WebGL contexts, external library handles) when the component is torn down — hook teardown to the `signal` `abort` event.
227
+ - **Navigation events**: Cancelable `coralite:navigating` (fired before the swap) and post-swap `coralite:navigated` on `window`, both with `detail: { from, to }`.
228
+
229
+ Full contract: https://coralite.dev/docs/reference/plugins/router.html — patterns guide: https://coralite.dev/docs/guide/spa-router.html
@@ -11,6 +11,6 @@
11
11
  "fix": "coralite fix"
12
12
  },
13
13
  "devDependencies": {
14
- "coralite": "^1.0.0"
14
+ "coralite": "^1.1.0"
15
15
  }
16
16
  }
@@ -181,6 +181,8 @@ Do NOT delete the `ref` attribute, and do NOT add an empty `client({ refs }) { r
181
181
 
182
182
  Top-level imports are reserved for `definePage` / `definePlugin` and modules used by isomorphic code (`getters`, `style`, `slots`). Modules used by `server()`, `client()`, or `paths()` must be loaded with dynamic `await import()` inside the block (`CORALITE-E301`).
183
183
 
184
+ - **Lazy dependency stylesheets (`await import('*.css')`)**: Load dependency or local `.css` files lazily inside component and page `client()` blocks (or transitive client `.js` helpers) via `await import('pkg/styles.css', options)`, which bundles CSS at build time into hashed `assets/css/` assets, injects `<link rel="stylesheet">` into `<head>` in deterministic manifest order at runtime, and resolves to `{ default: link.sheet ?? null, link }`. Both flat options (`{ media, nonce, crossorigin, referrerPolicy, signal, force }`) and Import Attributes (`{ with: { type: 'css', ... }, signal, force }`) are supported. Static top-level `.css` imports or dynamic `.css` imports outside `client()` throw `CORALITE-E109`; unresolvable `.css` files throw `CORALITE-E403`.
185
+
184
186
  ## 4. Serialization boundary
185
187
 
186
188
  - `server()` runs in Node.js at build time and is stripped from the browser bundle. It returns an object to initialize/hydrate `state`.
@@ -212,3 +214,16 @@ Top-level imports are reserved for `definePage` / `definePlugin` and modules use
212
214
  - `tests/fixtures/` — component test fixtures (`.html`)
213
215
  - `public/` — static assets copied verbatim to output
214
216
  - `coralite.config.js` — project & plugin configuration
217
+
218
+ ## 8. SPA Router (opt-in)
219
+
220
+ The opt-in router plugin (`coralite/plugins/router`) provides single-page application navigation. Register it in `coralite.config.js` under `plugins` (`plugins: [router({ ... })]`). Registration gates ALL SPA behavior — without it, every SPA navigation behavior (link interception, popstate, guards, head reconciliation) is inert: a `data-router-outlet` marker alone does nothing, and the page behaves as a standard multi-page app.
221
+
222
+ - **Outlets**: Any element carrying the outlet attribute (default `data-router-outlet`) or the reserved `<router-outlet>` tag is an outlet. Every SPA-routed page MUST have an outlet or client navigation fails; outlet-less pages are auto-wrapped by default. Set `autoWrap: false` to disable automatic body wrapping; outlet-less pages then render as authored and still resolve tokens normally. Set `outletOnly: true` to skip link interception when the live document has no outlet, so those clicks use native browser navigation. `router.navigate()` is NOT affected by `outletOnly` and still updates history before failing if no outlet exists, so do not call it from outlet-less pages. Everything outside the outlet (navbar, background audio, open sockets) is never touched by the router — those component instances and their state persist across every route swap.
223
+ - **Client API**: `client({ router })` injects the router: `navigate(path, { replace })`, `current()`, `beforeEach(guard)` (returns the unregister function), and the `viewTransitions` getter. Also available on `window.__coralite_router__`.
224
+ - **Guards**: `beforeEach` guards may return `true`/`undefined` (allow), `false` (block), a relative or same-origin path (soft redirect; redirect chains are capped at depth 10), or an `http(s)` URL (hard redirect via `window.location.replace()`).
225
+ - **Guard placement**: The guard list lives in the router's client-init scope and PERSISTS across the whole SPA session — an outlet swap does not reset it, and nothing auto-unregisters a guard when its route leaves. App-wide guards (auth, redirects) MUST be registered in a persistent shell component OUTSIDE the outlet (it connects once, so the guard registers exactly once). Route-scoped guards MUST capture the function returned by `beforeEach` and call it on their component `signal` abort. Registering guards inside a route component's `client()` without unregistering accumulates one extra guard per visit.
226
+ - **State scoping**: Component `state` is route-scoped — on navigation the old outlet is disconnected (its `signal` aborts), and the new route hydrates from its pre-built HTML, so `state` mutations are lost when the route leaves. App-scoped state belongs in the global `store` (declared in `coralite.config.js`), which the router never touches and which survives every swap. Release imperative resources a component allocates (workers, canvas/WebGL contexts, external library handles) when the component is torn down — hook teardown to the `signal` `abort` event.
227
+ - **Navigation events**: Cancelable `coralite:navigating` (fired before the swap) and post-swap `coralite:navigated` on `window`, both with `detail: { from, to }`.
228
+
229
+ Full contract: https://coralite.dev/docs/reference/plugins/router.html — patterns guide: https://coralite.dev/docs/guide/spa-router.html
@@ -18,6 +18,6 @@
18
18
  "node": ">=22.22.2"
19
19
  },
20
20
  "devDependencies": {
21
- "coralite": "^1.0.0"
21
+ "coralite": "^1.1.0"
22
22
  }
23
23
  }
@@ -181,6 +181,8 @@ Do NOT delete the `ref` attribute, and do NOT add an empty `client({ refs }) { r
181
181
 
182
182
  Top-level imports are reserved for `definePage` / `definePlugin` and modules used by isomorphic code (`getters`, `style`, `slots`). Modules used by `server()`, `client()`, or `paths()` must be loaded with dynamic `await import()` inside the block (`CORALITE-E301`).
183
183
 
184
+ - **Lazy dependency stylesheets (`await import('*.css')`)**: Load dependency or local `.css` files lazily inside component and page `client()` blocks (or transitive client `.js` helpers) via `await import('pkg/styles.css', options)`, which bundles CSS at build time into hashed `assets/css/` assets, injects `<link rel="stylesheet">` into `<head>` in deterministic manifest order at runtime, and resolves to `{ default: link.sheet ?? null, link }`. Both flat options (`{ media, nonce, crossorigin, referrerPolicy, signal, force }`) and Import Attributes (`{ with: { type: 'css', ... }, signal, force }`) are supported. Static top-level `.css` imports or dynamic `.css` imports outside `client()` throw `CORALITE-E109`; unresolvable `.css` files throw `CORALITE-E403`.
185
+
184
186
  ## 4. Serialization boundary
185
187
 
186
188
  - `server()` runs in Node.js at build time and is stripped from the browser bundle. It returns an object to initialize/hydrate `state`.
@@ -212,3 +214,16 @@ Top-level imports are reserved for `definePage` / `definePlugin` and modules use
212
214
  - `tests/fixtures/` — component test fixtures (`.html`)
213
215
  - `public/` — static assets copied verbatim to output
214
216
  - `coralite.config.js` — project & plugin configuration
217
+
218
+ ## 8. SPA Router (opt-in)
219
+
220
+ The opt-in router plugin (`coralite/plugins/router`) provides single-page application navigation. Register it in `coralite.config.js` under `plugins` (`plugins: [router({ ... })]`). Registration gates ALL SPA behavior — without it, every SPA navigation behavior (link interception, popstate, guards, head reconciliation) is inert: a `data-router-outlet` marker alone does nothing, and the page behaves as a standard multi-page app.
221
+
222
+ - **Outlets**: Any element carrying the outlet attribute (default `data-router-outlet`) or the reserved `<router-outlet>` tag is an outlet. Every SPA-routed page MUST have an outlet or client navigation fails; outlet-less pages are auto-wrapped by default. Set `autoWrap: false` to disable automatic body wrapping; outlet-less pages then render as authored and still resolve tokens normally. Set `outletOnly: true` to skip link interception when the live document has no outlet, so those clicks use native browser navigation. `router.navigate()` is NOT affected by `outletOnly` and still updates history before failing if no outlet exists, so do not call it from outlet-less pages. Everything outside the outlet (navbar, background audio, open sockets) is never touched by the router — those component instances and their state persist across every route swap.
223
+ - **Client API**: `client({ router })` injects the router: `navigate(path, { replace })`, `current()`, `beforeEach(guard)` (returns the unregister function), and the `viewTransitions` getter. Also available on `window.__coralite_router__`.
224
+ - **Guards**: `beforeEach` guards may return `true`/`undefined` (allow), `false` (block), a relative or same-origin path (soft redirect; redirect chains are capped at depth 10), or an `http(s)` URL (hard redirect via `window.location.replace()`).
225
+ - **Guard placement**: The guard list lives in the router's client-init scope and PERSISTS across the whole SPA session — an outlet swap does not reset it, and nothing auto-unregisters a guard when its route leaves. App-wide guards (auth, redirects) MUST be registered in a persistent shell component OUTSIDE the outlet (it connects once, so the guard registers exactly once). Route-scoped guards MUST capture the function returned by `beforeEach` and call it on their component `signal` abort. Registering guards inside a route component's `client()` without unregistering accumulates one extra guard per visit.
226
+ - **State scoping**: Component `state` is route-scoped — on navigation the old outlet is disconnected (its `signal` aborts), and the new route hydrates from its pre-built HTML, so `state` mutations are lost when the route leaves. App-scoped state belongs in the global `store` (declared in `coralite.config.js`), which the router never touches and which survives every swap. Release imperative resources a component allocates (workers, canvas/WebGL contexts, external library handles) when the component is torn down — hook teardown to the `signal` `abort` event.
227
+ - **Navigation events**: Cancelable `coralite:navigating` (fired before the swap) and post-swap `coralite:navigated` on `window`, both with `detail: { from, to }`.
228
+
229
+ Full contract: https://coralite.dev/docs/reference/plugins/router.html — patterns guide: https://coralite.dev/docs/guide/spa-router.html
@@ -11,6 +11,6 @@
11
11
  "fix": "coralite fix"
12
12
  },
13
13
  "devDependencies": {
14
- "coralite": "^1.0.0"
14
+ "coralite": "^1.1.0"
15
15
  }
16
16
  }