@moku-labs/web 2.1.1 → 2.2.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 +1 -0
- package/dist/browser.d.mts +47 -1
- package/dist/browser.mjs +74 -1
- package/dist/index.cjs +75 -0
- package/dist/index.d.cts +47 -1
- package/dist/index.d.mts +47 -1
- package/dist/index.mjs +74 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,6 +141,7 @@ route("/board/{id}/issue/{issueId}")
|
|
|
141
141
|
- **`viewTransitions`** accepts `boolean` (`true` → `"crossfade"`, `false` → `"none"`) **or** a named `TransitionMode` (`"none" | "crossfade" | "slide" | "morph"`). A named transition tags the swap so your CSS can target it two ways — `:root[data-view-transition~="slide"]` (every View-Transitions engine) and the standards-track `:active-view-transition-type(slide)` — and a shared `view-transition-name` left across the swap morphs one element into another. Reduced-motion and unsupported browsers fall back to an instant swap.
|
|
142
142
|
- **`scrollRestoration`** is `"top"` (reset, the default) or `"preserve"` (keep the current scroll — e.g. opening an overlay route over content that must stay still). Back/forward always restores its saved position.
|
|
143
143
|
- **`ctx.navigate(path, options?)`** — every island can navigate programmatically with no `app` handle (an always-present context member, like `ctx.set`/`ctx.url`). `app.spa.navigate` takes the same optional `{ scroll }`.
|
|
144
|
+
- **`navigate(path, options?)` / `hardNavigate(url)`** — importable from `@moku-labs/web/browser` for module-scope callers (shared chrome/nav helpers with no `app` or island `ctx`); they bind to the single booted app and no-op before `app.start()`. `hardNavigate` (also `app.spa.hardNavigate`) does a REAL full-page load for crossing a boundary the SPA can't swap — a different layout or an auth split — by detaching the SPA's own interceptor first, so `location.assign` isn't caught and converted to a region swap.
|
|
144
145
|
|
|
145
146
|
```ts
|
|
146
147
|
createIsland("issue", {
|
package/dist/browser.d.mts
CHANGED
|
@@ -1395,6 +1395,16 @@ interface SpaKernel {
|
|
|
1395
1395
|
* kernel.processNav("/about");
|
|
1396
1396
|
*/
|
|
1397
1397
|
processNav(path: string, options?: NavigateOptions): void;
|
|
1398
|
+
/**
|
|
1399
|
+
* Cross a boundary the SPA cannot swap (different layout / auth split) with a REAL
|
|
1400
|
+
* full-page load — detaches the interceptor first so the navigation isn't caught.
|
|
1401
|
+
*
|
|
1402
|
+
* @param url - The destination URL.
|
|
1403
|
+
* @returns void
|
|
1404
|
+
* @example
|
|
1405
|
+
* kernel.hardNavigate("/signin/");
|
|
1406
|
+
*/
|
|
1407
|
+
hardNavigate(url: string): void;
|
|
1398
1408
|
/**
|
|
1399
1409
|
* Query the swap region and mount islands for matching elements.
|
|
1400
1410
|
*
|
|
@@ -1456,6 +1466,17 @@ type SpaApi = {
|
|
|
1456
1466
|
* app.spa.navigate("/about");
|
|
1457
1467
|
*/
|
|
1458
1468
|
navigate(path: string, options?: NavigateOptions): void;
|
|
1469
|
+
/**
|
|
1470
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
1471
|
+
* full-page navigation. Detaches the SPA interceptor first, so the navigation is a true
|
|
1472
|
+
* document load (rendering the destination's own layout) rather than an intercepted swap.
|
|
1473
|
+
*
|
|
1474
|
+
* @param url - The destination URL (internal path or absolute).
|
|
1475
|
+
* @returns void
|
|
1476
|
+
* @example
|
|
1477
|
+
* app.spa.hardNavigate("/signin/"); // sign-out / 401: leave the app chrome for the auth split
|
|
1478
|
+
*/
|
|
1479
|
+
hardNavigate(url: string): void;
|
|
1459
1480
|
/**
|
|
1460
1481
|
* Read the current resolved URL.
|
|
1461
1482
|
*
|
|
@@ -1827,6 +1848,31 @@ declare function createIsland<S extends object = object, A = unknown>(name: stri
|
|
|
1827
1848
|
*/
|
|
1828
1849
|
declare const lazyEmbed: IslandDef;
|
|
1829
1850
|
//#endregion
|
|
1851
|
+
//#region src/plugins/spa/lifecycle.d.ts
|
|
1852
|
+
/**
|
|
1853
|
+
* Navigate the booted SPA to an internal path — the SAME swap pipeline as a link click,
|
|
1854
|
+
* `ctx.navigate`, or `app.spa.navigate`, for module-scope callers with no `app`/island `ctx`.
|
|
1855
|
+
* No-op before `app.start()`. Build `path` from the route map's `urls`, never a literal.
|
|
1856
|
+
*
|
|
1857
|
+
* @param path - The internal destination path (e.g. `urls.toUrl("board", { id })`).
|
|
1858
|
+
* @param options - Optional per-navigation overrides (e.g. `{ scroll: "preserve" }`).
|
|
1859
|
+
* @example
|
|
1860
|
+
* import { navigate } from "@moku-labs/web/browser";
|
|
1861
|
+
* navigate(urls.toUrl("issue", { id, issueId }));
|
|
1862
|
+
*/
|
|
1863
|
+
declare function navigate(path: string, options?: NavigateOptions): void;
|
|
1864
|
+
/**
|
|
1865
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
1866
|
+
* full-page load — detaches the SPA interceptor first so the navigation isn't caught and
|
|
1867
|
+
* converted to a swap. For module-scope callers with no `app`/island `ctx`. No-op before boot.
|
|
1868
|
+
*
|
|
1869
|
+
* @param url - The destination URL (internal path or absolute).
|
|
1870
|
+
* @example
|
|
1871
|
+
* import { hardNavigate } from "@moku-labs/web/browser";
|
|
1872
|
+
* hardNavigate(urls.toUrl("signin", {})); // sign-out / 401: leave the app chrome for the auth split
|
|
1873
|
+
*/
|
|
1874
|
+
declare function hardNavigate(url: string): void;
|
|
1875
|
+
//#endregion
|
|
1830
1876
|
//#region src/plugins/spa/index.d.ts
|
|
1831
1877
|
/**
|
|
1832
1878
|
* SPA plugin — progressive client-side navigation layered over the static site:
|
|
@@ -2614,4 +2660,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
2614
2660
|
*/
|
|
2615
2661
|
declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$5, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common").LogConfig, import("@moku-labs/common").LogState, import("@moku-labs/common").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common").EnvConfig, import("@moku-labs/common").EnvState, import("@moku-labs/common").EnvApi>]>>;
|
|
2616
2662
|
//#endregion
|
|
2617
|
-
export { type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports as Content, types_d_exports$1 as Data, type Env, types_d_exports$2 as Head, type Log, types_d_exports$3 as Router, types_d_exports$4 as Spa, browserEnv, buildArticleHead, canonical, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, envPlugin, feedLink, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
|
2663
|
+
export { type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports as Content, types_d_exports$1 as Data, type Env, types_d_exports$2 as Head, type Log, types_d_exports$3 as Router, types_d_exports$4 as Spa, browserEnv, buildArticleHead, canonical, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, envPlugin, feedLink, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
package/dist/browser.mjs
CHANGED
|
@@ -2259,6 +2259,17 @@ function createApi(ctx) {
|
|
|
2259
2259
|
ctx.state.kernel?.processNav(path, options);
|
|
2260
2260
|
},
|
|
2261
2261
|
/**
|
|
2262
|
+
* Cross a boundary the SPA cannot swap (different layout / auth split) with a REAL
|
|
2263
|
+
* full-page load — detaches the interceptor first so the navigation isn't intercepted.
|
|
2264
|
+
*
|
|
2265
|
+
* @param url - The destination URL.
|
|
2266
|
+
* @example
|
|
2267
|
+
* app.spa.hardNavigate("/signin/");
|
|
2268
|
+
*/
|
|
2269
|
+
hardNavigate(url) {
|
|
2270
|
+
ctx.state.kernel?.hardNavigate(url);
|
|
2271
|
+
},
|
|
2272
|
+
/**
|
|
2262
2273
|
* Read the current resolved URL.
|
|
2263
2274
|
*
|
|
2264
2275
|
* @returns The current pathname + search.
|
|
@@ -4232,6 +4243,23 @@ function createSpaKernel(state, config, emit, deps) {
|
|
|
4232
4243
|
navigateProgrammatic(path, options?.scroll);
|
|
4233
4244
|
},
|
|
4234
4245
|
/**
|
|
4246
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
4247
|
+
* full-page navigation. The click / Navigation-API interceptor catches even
|
|
4248
|
+
* `location.assign`, converting it to a region swap — so this DETACHES that interceptor
|
|
4249
|
+
* first (the same teardown `dispose` runs) and only THEN assigns, guaranteeing a true
|
|
4250
|
+
* document load that renders the destination's own layout. No-op headless.
|
|
4251
|
+
*
|
|
4252
|
+
* @param url - The destination URL (internal path or absolute).
|
|
4253
|
+
* @example
|
|
4254
|
+
* kernel.hardNavigate("/signin/");
|
|
4255
|
+
*/
|
|
4256
|
+
hardNavigate(url) {
|
|
4257
|
+
if (typeof document === "undefined") return;
|
|
4258
|
+
state.destroyRouter?.();
|
|
4259
|
+
state.destroyRouter = null;
|
|
4260
|
+
location.assign(url);
|
|
4261
|
+
},
|
|
4262
|
+
/**
|
|
4235
4263
|
* Scan the swap region and mount islands for matching elements.
|
|
4236
4264
|
*
|
|
4237
4265
|
* @example
|
|
@@ -4286,6 +4314,49 @@ function initSpa(ctx) {
|
|
|
4286
4314
|
let teardown;
|
|
4287
4315
|
/** Captured log ref — onStop has no `ctx.log` (spec/08 §4). */
|
|
4288
4316
|
let logRef;
|
|
4317
|
+
/** The booted app's navigators, or undefined before boot / after stop (single-app-per-document). */
|
|
4318
|
+
let boundNavigators;
|
|
4319
|
+
/**
|
|
4320
|
+
* Bind the running app's navigators from its kernel — called by the plugin's `onStart` after
|
|
4321
|
+
* `kernel.boot()`, so the module-level {@link navigate}/{@link hardNavigate} delegate to it.
|
|
4322
|
+
*
|
|
4323
|
+
* @param kernel - The booted spa kernel.
|
|
4324
|
+
* @example
|
|
4325
|
+
* bindKernelNavigators(ctx.state.kernel);
|
|
4326
|
+
*/
|
|
4327
|
+
function bindKernelNavigators(kernel) {
|
|
4328
|
+
boundNavigators = {
|
|
4329
|
+
navigate: (path, options) => kernel.processNav(path, options),
|
|
4330
|
+
hardNavigate: (url) => kernel.hardNavigate(url)
|
|
4331
|
+
};
|
|
4332
|
+
}
|
|
4333
|
+
/**
|
|
4334
|
+
* Navigate the booted SPA to an internal path — the SAME swap pipeline as a link click,
|
|
4335
|
+
* `ctx.navigate`, or `app.spa.navigate`, for module-scope callers with no `app`/island `ctx`.
|
|
4336
|
+
* No-op before `app.start()`. Build `path` from the route map's `urls`, never a literal.
|
|
4337
|
+
*
|
|
4338
|
+
* @param path - The internal destination path (e.g. `urls.toUrl("board", { id })`).
|
|
4339
|
+
* @param options - Optional per-navigation overrides (e.g. `{ scroll: "preserve" }`).
|
|
4340
|
+
* @example
|
|
4341
|
+
* import { navigate } from "@moku-labs/web/browser";
|
|
4342
|
+
* navigate(urls.toUrl("issue", { id, issueId }));
|
|
4343
|
+
*/
|
|
4344
|
+
function navigate(path, options) {
|
|
4345
|
+
boundNavigators?.navigate(path, options);
|
|
4346
|
+
}
|
|
4347
|
+
/**
|
|
4348
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
4349
|
+
* full-page load — detaches the SPA interceptor first so the navigation isn't caught and
|
|
4350
|
+
* converted to a swap. For module-scope callers with no `app`/island `ctx`. No-op before boot.
|
|
4351
|
+
*
|
|
4352
|
+
* @param url - The destination URL (internal path or absolute).
|
|
4353
|
+
* @example
|
|
4354
|
+
* import { hardNavigate } from "@moku-labs/web/browser";
|
|
4355
|
+
* hardNavigate(urls.toUrl("signin", {})); // sign-out / 401: leave the app chrome for the auth split
|
|
4356
|
+
*/
|
|
4357
|
+
function hardNavigate(url) {
|
|
4358
|
+
boundNavigators?.hardNavigate(url);
|
|
4359
|
+
}
|
|
4289
4360
|
/**
|
|
4290
4361
|
* Capture the teardown + log handles during `onStart` (no-op without a DOM —
|
|
4291
4362
|
* the SSR/build guard, so onStop has nothing to release). The kernel built in
|
|
@@ -4318,6 +4389,7 @@ function disposeSpa() {
|
|
|
4318
4389
|
} finally {
|
|
4319
4390
|
teardown = void 0;
|
|
4320
4391
|
logRef = void 0;
|
|
4392
|
+
boundNavigators = void 0;
|
|
4321
4393
|
}
|
|
4322
4394
|
}
|
|
4323
4395
|
//#endregion
|
|
@@ -4692,6 +4764,7 @@ const spaPlugin = createPlugin$1("spa", {
|
|
|
4692
4764
|
onStart(ctx) {
|
|
4693
4765
|
captureTeardown(ctx);
|
|
4694
4766
|
ctx.state.kernel?.boot();
|
|
4767
|
+
if (ctx.state.kernel) bindKernelNavigators(ctx.state.kernel);
|
|
4695
4768
|
},
|
|
4696
4769
|
onStop: disposeSpa
|
|
4697
4770
|
});
|
|
@@ -5335,4 +5408,4 @@ const createApp = core.createApp;
|
|
|
5335
5408
|
*/
|
|
5336
5409
|
const createPlugin = core.createPlugin;
|
|
5337
5410
|
//#endregion
|
|
5338
|
-
export { types_exports as Content, types_exports$1 as Data, types_exports$2 as Head, types_exports$3 as Router, types_exports$4 as Spa, browserEnv, buildArticleHead, canonical, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, envPlugin, feedLink, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
|
5411
|
+
export { types_exports as Content, types_exports$1 as Data, types_exports$2 as Head, types_exports$3 as Router, types_exports$4 as Spa, browserEnv, buildArticleHead, canonical, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, envPlugin, feedLink, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
package/dist/index.cjs
CHANGED
|
@@ -9217,6 +9217,17 @@ function createApi(ctx) {
|
|
|
9217
9217
|
ctx.state.kernel?.processNav(path, options);
|
|
9218
9218
|
},
|
|
9219
9219
|
/**
|
|
9220
|
+
* Cross a boundary the SPA cannot swap (different layout / auth split) with a REAL
|
|
9221
|
+
* full-page load — detaches the interceptor first so the navigation isn't intercepted.
|
|
9222
|
+
*
|
|
9223
|
+
* @param url - The destination URL.
|
|
9224
|
+
* @example
|
|
9225
|
+
* app.spa.hardNavigate("/signin/");
|
|
9226
|
+
*/
|
|
9227
|
+
hardNavigate(url) {
|
|
9228
|
+
ctx.state.kernel?.hardNavigate(url);
|
|
9229
|
+
},
|
|
9230
|
+
/**
|
|
9220
9231
|
* Read the current resolved URL.
|
|
9221
9232
|
*
|
|
9222
9233
|
* @returns The current pathname + search.
|
|
@@ -10938,6 +10949,23 @@ function createSpaKernel(state, config, emit, deps) {
|
|
|
10938
10949
|
navigateProgrammatic(path, options?.scroll);
|
|
10939
10950
|
},
|
|
10940
10951
|
/**
|
|
10952
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
10953
|
+
* full-page navigation. The click / Navigation-API interceptor catches even
|
|
10954
|
+
* `location.assign`, converting it to a region swap — so this DETACHES that interceptor
|
|
10955
|
+
* first (the same teardown `dispose` runs) and only THEN assigns, guaranteeing a true
|
|
10956
|
+
* document load that renders the destination's own layout. No-op headless.
|
|
10957
|
+
*
|
|
10958
|
+
* @param url - The destination URL (internal path or absolute).
|
|
10959
|
+
* @example
|
|
10960
|
+
* kernel.hardNavigate("/signin/");
|
|
10961
|
+
*/
|
|
10962
|
+
hardNavigate(url) {
|
|
10963
|
+
if (typeof document === "undefined") return;
|
|
10964
|
+
state.destroyRouter?.();
|
|
10965
|
+
state.destroyRouter = null;
|
|
10966
|
+
location.assign(url);
|
|
10967
|
+
},
|
|
10968
|
+
/**
|
|
10941
10969
|
* Scan the swap region and mount islands for matching elements.
|
|
10942
10970
|
*
|
|
10943
10971
|
* @example
|
|
@@ -10992,6 +11020,49 @@ function initSpa(ctx) {
|
|
|
10992
11020
|
let teardown;
|
|
10993
11021
|
/** Captured log ref — onStop has no `ctx.log` (spec/08 §4). */
|
|
10994
11022
|
let logRef;
|
|
11023
|
+
/** The booted app's navigators, or undefined before boot / after stop (single-app-per-document). */
|
|
11024
|
+
let boundNavigators;
|
|
11025
|
+
/**
|
|
11026
|
+
* Bind the running app's navigators from its kernel — called by the plugin's `onStart` after
|
|
11027
|
+
* `kernel.boot()`, so the module-level {@link navigate}/{@link hardNavigate} delegate to it.
|
|
11028
|
+
*
|
|
11029
|
+
* @param kernel - The booted spa kernel.
|
|
11030
|
+
* @example
|
|
11031
|
+
* bindKernelNavigators(ctx.state.kernel);
|
|
11032
|
+
*/
|
|
11033
|
+
function bindKernelNavigators(kernel) {
|
|
11034
|
+
boundNavigators = {
|
|
11035
|
+
navigate: (path, options) => kernel.processNav(path, options),
|
|
11036
|
+
hardNavigate: (url) => kernel.hardNavigate(url)
|
|
11037
|
+
};
|
|
11038
|
+
}
|
|
11039
|
+
/**
|
|
11040
|
+
* Navigate the booted SPA to an internal path — the SAME swap pipeline as a link click,
|
|
11041
|
+
* `ctx.navigate`, or `app.spa.navigate`, for module-scope callers with no `app`/island `ctx`.
|
|
11042
|
+
* No-op before `app.start()`. Build `path` from the route map's `urls`, never a literal.
|
|
11043
|
+
*
|
|
11044
|
+
* @param path - The internal destination path (e.g. `urls.toUrl("board", { id })`).
|
|
11045
|
+
* @param options - Optional per-navigation overrides (e.g. `{ scroll: "preserve" }`).
|
|
11046
|
+
* @example
|
|
11047
|
+
* import { navigate } from "@moku-labs/web/browser";
|
|
11048
|
+
* navigate(urls.toUrl("issue", { id, issueId }));
|
|
11049
|
+
*/
|
|
11050
|
+
function navigate(path, options) {
|
|
11051
|
+
boundNavigators?.navigate(path, options);
|
|
11052
|
+
}
|
|
11053
|
+
/**
|
|
11054
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
11055
|
+
* full-page load — detaches the SPA interceptor first so the navigation isn't caught and
|
|
11056
|
+
* converted to a swap. For module-scope callers with no `app`/island `ctx`. No-op before boot.
|
|
11057
|
+
*
|
|
11058
|
+
* @param url - The destination URL (internal path or absolute).
|
|
11059
|
+
* @example
|
|
11060
|
+
* import { hardNavigate } from "@moku-labs/web/browser";
|
|
11061
|
+
* hardNavigate(urls.toUrl("signin", {})); // sign-out / 401: leave the app chrome for the auth split
|
|
11062
|
+
*/
|
|
11063
|
+
function hardNavigate(url) {
|
|
11064
|
+
boundNavigators?.hardNavigate(url);
|
|
11065
|
+
}
|
|
10995
11066
|
/**
|
|
10996
11067
|
* Capture the teardown + log handles during `onStart` (no-op without a DOM —
|
|
10997
11068
|
* the SSR/build guard, so onStop has nothing to release). The kernel built in
|
|
@@ -11024,6 +11095,7 @@ function disposeSpa() {
|
|
|
11024
11095
|
} finally {
|
|
11025
11096
|
teardown = void 0;
|
|
11026
11097
|
logRef = void 0;
|
|
11098
|
+
boundNavigators = void 0;
|
|
11027
11099
|
}
|
|
11028
11100
|
}
|
|
11029
11101
|
//#endregion
|
|
@@ -11398,6 +11470,7 @@ const spaPlugin = createPlugin$1("spa", {
|
|
|
11398
11470
|
onStart(ctx) {
|
|
11399
11471
|
captureTeardown(ctx);
|
|
11400
11472
|
ctx.state.kernel?.boot();
|
|
11473
|
+
if (ctx.state.kernel) bindKernelNavigators(ctx.state.kernel);
|
|
11401
11474
|
},
|
|
11402
11475
|
onStop: disposeSpa
|
|
11403
11476
|
});
|
|
@@ -13710,6 +13783,7 @@ Object.defineProperty(exports, "envPlugin", {
|
|
|
13710
13783
|
});
|
|
13711
13784
|
exports.feedLink = feedLink;
|
|
13712
13785
|
exports.fileSystemContent = fileSystemContent;
|
|
13786
|
+
exports.hardNavigate = hardNavigate;
|
|
13713
13787
|
exports.headPlugin = headPlugin;
|
|
13714
13788
|
exports.hreflang = hreflang;
|
|
13715
13789
|
exports.i18nPlugin = i18nPlugin;
|
|
@@ -13722,6 +13796,7 @@ Object.defineProperty(exports, "logPlugin", {
|
|
|
13722
13796
|
}
|
|
13723
13797
|
});
|
|
13724
13798
|
exports.meta = meta;
|
|
13799
|
+
exports.navigate = navigate;
|
|
13725
13800
|
exports.og = og;
|
|
13726
13801
|
Object.defineProperty(exports, "processEnv", {
|
|
13727
13802
|
enumerable: true,
|
package/dist/index.d.cts
CHANGED
|
@@ -1396,6 +1396,16 @@ interface SpaKernel {
|
|
|
1396
1396
|
* kernel.processNav("/about");
|
|
1397
1397
|
*/
|
|
1398
1398
|
processNav(path: string, options?: NavigateOptions): void;
|
|
1399
|
+
/**
|
|
1400
|
+
* Cross a boundary the SPA cannot swap (different layout / auth split) with a REAL
|
|
1401
|
+
* full-page load — detaches the interceptor first so the navigation isn't caught.
|
|
1402
|
+
*
|
|
1403
|
+
* @param url - The destination URL.
|
|
1404
|
+
* @returns void
|
|
1405
|
+
* @example
|
|
1406
|
+
* kernel.hardNavigate("/signin/");
|
|
1407
|
+
*/
|
|
1408
|
+
hardNavigate(url: string): void;
|
|
1399
1409
|
/**
|
|
1400
1410
|
* Query the swap region and mount islands for matching elements.
|
|
1401
1411
|
*
|
|
@@ -1457,6 +1467,17 @@ type SpaApi = {
|
|
|
1457
1467
|
* app.spa.navigate("/about");
|
|
1458
1468
|
*/
|
|
1459
1469
|
navigate(path: string, options?: NavigateOptions): void;
|
|
1470
|
+
/**
|
|
1471
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
1472
|
+
* full-page navigation. Detaches the SPA interceptor first, so the navigation is a true
|
|
1473
|
+
* document load (rendering the destination's own layout) rather than an intercepted swap.
|
|
1474
|
+
*
|
|
1475
|
+
* @param url - The destination URL (internal path or absolute).
|
|
1476
|
+
* @returns void
|
|
1477
|
+
* @example
|
|
1478
|
+
* app.spa.hardNavigate("/signin/"); // sign-out / 401: leave the app chrome for the auth split
|
|
1479
|
+
*/
|
|
1480
|
+
hardNavigate(url: string): void;
|
|
1460
1481
|
/**
|
|
1461
1482
|
* Read the current resolved URL.
|
|
1462
1483
|
*
|
|
@@ -3747,6 +3768,31 @@ declare function createIsland<S extends object = object, A = unknown>(name: stri
|
|
|
3747
3768
|
*/
|
|
3748
3769
|
declare const lazyEmbed: IslandDef;
|
|
3749
3770
|
//#endregion
|
|
3771
|
+
//#region src/plugins/spa/lifecycle.d.ts
|
|
3772
|
+
/**
|
|
3773
|
+
* Navigate the booted SPA to an internal path — the SAME swap pipeline as a link click,
|
|
3774
|
+
* `ctx.navigate`, or `app.spa.navigate`, for module-scope callers with no `app`/island `ctx`.
|
|
3775
|
+
* No-op before `app.start()`. Build `path` from the route map's `urls`, never a literal.
|
|
3776
|
+
*
|
|
3777
|
+
* @param path - The internal destination path (e.g. `urls.toUrl("board", { id })`).
|
|
3778
|
+
* @param options - Optional per-navigation overrides (e.g. `{ scroll: "preserve" }`).
|
|
3779
|
+
* @example
|
|
3780
|
+
* import { navigate } from "@moku-labs/web/browser";
|
|
3781
|
+
* navigate(urls.toUrl("issue", { id, issueId }));
|
|
3782
|
+
*/
|
|
3783
|
+
declare function navigate(path: string, options?: NavigateOptions): void;
|
|
3784
|
+
/**
|
|
3785
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
3786
|
+
* full-page load — detaches the SPA interceptor first so the navigation isn't caught and
|
|
3787
|
+
* converted to a swap. For module-scope callers with no `app`/island `ctx`. No-op before boot.
|
|
3788
|
+
*
|
|
3789
|
+
* @param url - The destination URL (internal path or absolute).
|
|
3790
|
+
* @example
|
|
3791
|
+
* import { hardNavigate } from "@moku-labs/web/browser";
|
|
3792
|
+
* hardNavigate(urls.toUrl("signin", {})); // sign-out / 401: leave the app chrome for the auth split
|
|
3793
|
+
*/
|
|
3794
|
+
declare function hardNavigate(url: string): void;
|
|
3795
|
+
//#endregion
|
|
3750
3796
|
//#region src/plugins/spa/index.d.ts
|
|
3751
3797
|
/**
|
|
3752
3798
|
* SPA plugin — progressive client-side navigation layered over the static site:
|
|
@@ -3946,4 +3992,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3946
3992
|
*/
|
|
3947
3993
|
declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$8, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common").LogConfig, import("@moku-labs/common").LogState, import("@moku-labs/common").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common").EnvConfig, import("@moku-labs/common").EnvState, import("@moku-labs/common").EnvApi>]>>;
|
|
3948
3994
|
//#endregion
|
|
3949
|
-
export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Content, types_d_exports$3 as Data, types_d_exports$4 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$5 as Head, type Log, types_d_exports$6 as Router, types_d_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
|
3995
|
+
export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Content, types_d_exports$3 as Data, types_d_exports$4 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$5 as Head, type Log, types_d_exports$6 as Router, types_d_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
package/dist/index.d.mts
CHANGED
|
@@ -1394,6 +1394,16 @@ interface SpaKernel {
|
|
|
1394
1394
|
* kernel.processNav("/about");
|
|
1395
1395
|
*/
|
|
1396
1396
|
processNav(path: string, options?: NavigateOptions): void;
|
|
1397
|
+
/**
|
|
1398
|
+
* Cross a boundary the SPA cannot swap (different layout / auth split) with a REAL
|
|
1399
|
+
* full-page load — detaches the interceptor first so the navigation isn't caught.
|
|
1400
|
+
*
|
|
1401
|
+
* @param url - The destination URL.
|
|
1402
|
+
* @returns void
|
|
1403
|
+
* @example
|
|
1404
|
+
* kernel.hardNavigate("/signin/");
|
|
1405
|
+
*/
|
|
1406
|
+
hardNavigate(url: string): void;
|
|
1397
1407
|
/**
|
|
1398
1408
|
* Query the swap region and mount islands for matching elements.
|
|
1399
1409
|
*
|
|
@@ -1455,6 +1465,17 @@ type SpaApi = {
|
|
|
1455
1465
|
* app.spa.navigate("/about");
|
|
1456
1466
|
*/
|
|
1457
1467
|
navigate(path: string, options?: NavigateOptions): void;
|
|
1468
|
+
/**
|
|
1469
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
1470
|
+
* full-page navigation. Detaches the SPA interceptor first, so the navigation is a true
|
|
1471
|
+
* document load (rendering the destination's own layout) rather than an intercepted swap.
|
|
1472
|
+
*
|
|
1473
|
+
* @param url - The destination URL (internal path or absolute).
|
|
1474
|
+
* @returns void
|
|
1475
|
+
* @example
|
|
1476
|
+
* app.spa.hardNavigate("/signin/"); // sign-out / 401: leave the app chrome for the auth split
|
|
1477
|
+
*/
|
|
1478
|
+
hardNavigate(url: string): void;
|
|
1458
1479
|
/**
|
|
1459
1480
|
* Read the current resolved URL.
|
|
1460
1481
|
*
|
|
@@ -3745,6 +3766,31 @@ declare function createIsland<S extends object = object, A = unknown>(name: stri
|
|
|
3745
3766
|
*/
|
|
3746
3767
|
declare const lazyEmbed: IslandDef;
|
|
3747
3768
|
//#endregion
|
|
3769
|
+
//#region src/plugins/spa/lifecycle.d.ts
|
|
3770
|
+
/**
|
|
3771
|
+
* Navigate the booted SPA to an internal path — the SAME swap pipeline as a link click,
|
|
3772
|
+
* `ctx.navigate`, or `app.spa.navigate`, for module-scope callers with no `app`/island `ctx`.
|
|
3773
|
+
* No-op before `app.start()`. Build `path` from the route map's `urls`, never a literal.
|
|
3774
|
+
*
|
|
3775
|
+
* @param path - The internal destination path (e.g. `urls.toUrl("board", { id })`).
|
|
3776
|
+
* @param options - Optional per-navigation overrides (e.g. `{ scroll: "preserve" }`).
|
|
3777
|
+
* @example
|
|
3778
|
+
* import { navigate } from "@moku-labs/web/browser";
|
|
3779
|
+
* navigate(urls.toUrl("issue", { id, issueId }));
|
|
3780
|
+
*/
|
|
3781
|
+
declare function navigate(path: string, options?: NavigateOptions): void;
|
|
3782
|
+
/**
|
|
3783
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
3784
|
+
* full-page load — detaches the SPA interceptor first so the navigation isn't caught and
|
|
3785
|
+
* converted to a swap. For module-scope callers with no `app`/island `ctx`. No-op before boot.
|
|
3786
|
+
*
|
|
3787
|
+
* @param url - The destination URL (internal path or absolute).
|
|
3788
|
+
* @example
|
|
3789
|
+
* import { hardNavigate } from "@moku-labs/web/browser";
|
|
3790
|
+
* hardNavigate(urls.toUrl("signin", {})); // sign-out / 401: leave the app chrome for the auth split
|
|
3791
|
+
*/
|
|
3792
|
+
declare function hardNavigate(url: string): void;
|
|
3793
|
+
//#endregion
|
|
3748
3794
|
//#region src/plugins/spa/index.d.ts
|
|
3749
3795
|
/**
|
|
3750
3796
|
* SPA plugin — progressive client-side navigation layered over the static site:
|
|
@@ -3944,4 +3990,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3944
3990
|
*/
|
|
3945
3991
|
declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$8, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common").LogConfig, import("@moku-labs/common").LogState, import("@moku-labs/common").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common").EnvConfig, import("@moku-labs/common").EnvState, import("@moku-labs/common").EnvApi>]>>;
|
|
3946
3992
|
//#endregion
|
|
3947
|
-
export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Content, types_d_exports$3 as Data, types_d_exports$4 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$5 as Head, type Log, types_d_exports$6 as Router, types_d_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
|
3993
|
+
export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Content, types_d_exports$3 as Data, types_d_exports$4 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$5 as Head, type Log, types_d_exports$6 as Router, types_d_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
package/dist/index.mjs
CHANGED
|
@@ -9204,6 +9204,17 @@ function createApi(ctx) {
|
|
|
9204
9204
|
ctx.state.kernel?.processNav(path, options);
|
|
9205
9205
|
},
|
|
9206
9206
|
/**
|
|
9207
|
+
* Cross a boundary the SPA cannot swap (different layout / auth split) with a REAL
|
|
9208
|
+
* full-page load — detaches the interceptor first so the navigation isn't intercepted.
|
|
9209
|
+
*
|
|
9210
|
+
* @param url - The destination URL.
|
|
9211
|
+
* @example
|
|
9212
|
+
* app.spa.hardNavigate("/signin/");
|
|
9213
|
+
*/
|
|
9214
|
+
hardNavigate(url) {
|
|
9215
|
+
ctx.state.kernel?.hardNavigate(url);
|
|
9216
|
+
},
|
|
9217
|
+
/**
|
|
9207
9218
|
* Read the current resolved URL.
|
|
9208
9219
|
*
|
|
9209
9220
|
* @returns The current pathname + search.
|
|
@@ -10925,6 +10936,23 @@ function createSpaKernel(state, config, emit, deps) {
|
|
|
10925
10936
|
navigateProgrammatic(path, options?.scroll);
|
|
10926
10937
|
},
|
|
10927
10938
|
/**
|
|
10939
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
10940
|
+
* full-page navigation. The click / Navigation-API interceptor catches even
|
|
10941
|
+
* `location.assign`, converting it to a region swap — so this DETACHES that interceptor
|
|
10942
|
+
* first (the same teardown `dispose` runs) and only THEN assigns, guaranteeing a true
|
|
10943
|
+
* document load that renders the destination's own layout. No-op headless.
|
|
10944
|
+
*
|
|
10945
|
+
* @param url - The destination URL (internal path or absolute).
|
|
10946
|
+
* @example
|
|
10947
|
+
* kernel.hardNavigate("/signin/");
|
|
10948
|
+
*/
|
|
10949
|
+
hardNavigate(url) {
|
|
10950
|
+
if (typeof document === "undefined") return;
|
|
10951
|
+
state.destroyRouter?.();
|
|
10952
|
+
state.destroyRouter = null;
|
|
10953
|
+
location.assign(url);
|
|
10954
|
+
},
|
|
10955
|
+
/**
|
|
10928
10956
|
* Scan the swap region and mount islands for matching elements.
|
|
10929
10957
|
*
|
|
10930
10958
|
* @example
|
|
@@ -10979,6 +11007,49 @@ function initSpa(ctx) {
|
|
|
10979
11007
|
let teardown;
|
|
10980
11008
|
/** Captured log ref — onStop has no `ctx.log` (spec/08 §4). */
|
|
10981
11009
|
let logRef;
|
|
11010
|
+
/** The booted app's navigators, or undefined before boot / after stop (single-app-per-document). */
|
|
11011
|
+
let boundNavigators;
|
|
11012
|
+
/**
|
|
11013
|
+
* Bind the running app's navigators from its kernel — called by the plugin's `onStart` after
|
|
11014
|
+
* `kernel.boot()`, so the module-level {@link navigate}/{@link hardNavigate} delegate to it.
|
|
11015
|
+
*
|
|
11016
|
+
* @param kernel - The booted spa kernel.
|
|
11017
|
+
* @example
|
|
11018
|
+
* bindKernelNavigators(ctx.state.kernel);
|
|
11019
|
+
*/
|
|
11020
|
+
function bindKernelNavigators(kernel) {
|
|
11021
|
+
boundNavigators = {
|
|
11022
|
+
navigate: (path, options) => kernel.processNav(path, options),
|
|
11023
|
+
hardNavigate: (url) => kernel.hardNavigate(url)
|
|
11024
|
+
};
|
|
11025
|
+
}
|
|
11026
|
+
/**
|
|
11027
|
+
* Navigate the booted SPA to an internal path — the SAME swap pipeline as a link click,
|
|
11028
|
+
* `ctx.navigate`, or `app.spa.navigate`, for module-scope callers with no `app`/island `ctx`.
|
|
11029
|
+
* No-op before `app.start()`. Build `path` from the route map's `urls`, never a literal.
|
|
11030
|
+
*
|
|
11031
|
+
* @param path - The internal destination path (e.g. `urls.toUrl("board", { id })`).
|
|
11032
|
+
* @param options - Optional per-navigation overrides (e.g. `{ scroll: "preserve" }`).
|
|
11033
|
+
* @example
|
|
11034
|
+
* import { navigate } from "@moku-labs/web/browser";
|
|
11035
|
+
* navigate(urls.toUrl("issue", { id, issueId }));
|
|
11036
|
+
*/
|
|
11037
|
+
function navigate(path, options) {
|
|
11038
|
+
boundNavigators?.navigate(path, options);
|
|
11039
|
+
}
|
|
11040
|
+
/**
|
|
11041
|
+
* Cross a boundary the SPA cannot swap (a different layout, the auth split) with a REAL
|
|
11042
|
+
* full-page load — detaches the SPA interceptor first so the navigation isn't caught and
|
|
11043
|
+
* converted to a swap. For module-scope callers with no `app`/island `ctx`. No-op before boot.
|
|
11044
|
+
*
|
|
11045
|
+
* @param url - The destination URL (internal path or absolute).
|
|
11046
|
+
* @example
|
|
11047
|
+
* import { hardNavigate } from "@moku-labs/web/browser";
|
|
11048
|
+
* hardNavigate(urls.toUrl("signin", {})); // sign-out / 401: leave the app chrome for the auth split
|
|
11049
|
+
*/
|
|
11050
|
+
function hardNavigate(url) {
|
|
11051
|
+
boundNavigators?.hardNavigate(url);
|
|
11052
|
+
}
|
|
10982
11053
|
/**
|
|
10983
11054
|
* Capture the teardown + log handles during `onStart` (no-op without a DOM —
|
|
10984
11055
|
* the SSR/build guard, so onStop has nothing to release). The kernel built in
|
|
@@ -11011,6 +11082,7 @@ function disposeSpa() {
|
|
|
11011
11082
|
} finally {
|
|
11012
11083
|
teardown = void 0;
|
|
11013
11084
|
logRef = void 0;
|
|
11085
|
+
boundNavigators = void 0;
|
|
11014
11086
|
}
|
|
11015
11087
|
}
|
|
11016
11088
|
//#endregion
|
|
@@ -11385,6 +11457,7 @@ const spaPlugin = createPlugin$1("spa", {
|
|
|
11385
11457
|
onStart(ctx) {
|
|
11386
11458
|
captureTeardown(ctx);
|
|
11387
11459
|
ctx.state.kernel?.boot();
|
|
11460
|
+
if (ctx.state.kernel) bindKernelNavigators(ctx.state.kernel);
|
|
11388
11461
|
},
|
|
11389
11462
|
onStop: disposeSpa
|
|
11390
11463
|
});
|
|
@@ -13608,4 +13681,4 @@ const createApp = core.createApp;
|
|
|
13608
13681
|
*/
|
|
13609
13682
|
const createPlugin = core.createPlugin;
|
|
13610
13683
|
//#endregion
|
|
13611
|
-
export { types_exports as Build, types_exports$1 as Cli, types_exports$2 as Content, types_exports$3 as Data, types_exports$4 as Deploy, EmbedFacadeButton, GalleryTrack, types_exports$5 as Head, types_exports$6 as Router, types_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
|
13684
|
+
export { types_exports as Build, types_exports$1 as Cli, types_exports$2 as Content, types_exports$3 as Data, types_exports$4 as Deploy, EmbedFacadeButton, GalleryTrack, types_exports$5 as Head, types_exports$6 as Router, types_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|
package/package.json
CHANGED