@omerdlw/base-framework 2.0.1 → 3.0.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 +4 -1
- package/dist/{chunk-XASQT4CQ.js → chunk-66EYJBIP.js} +47 -27
- package/dist/chunk-66EYJBIP.js.map +1 -0
- package/dist/{chunk-SKBITB5X.js → chunk-CYU6SGAL.js} +3 -3
- package/dist/{chunk-SKBITB5X.js.map → chunk-CYU6SGAL.js.map} +1 -1
- package/dist/{chunk-6SG7V77J.js → chunk-HHWRTQKQ.js} +100 -67
- package/dist/chunk-HHWRTQKQ.js.map +1 -0
- package/dist/chunk-HLL5EHXC.js +485 -0
- package/dist/chunk-HLL5EHXC.js.map +1 -0
- package/dist/{chunk-A5RE3F6O.js → chunk-JIXBFFRD.js} +193 -357
- package/dist/chunk-JIXBFFRD.js.map +1 -0
- package/dist/{chunk-6ZJVLUBE.js → chunk-M57SNWXK.js} +8 -6
- package/dist/chunk-M57SNWXK.js.map +1 -0
- package/dist/chunk-RIOKLMYM.js +145 -0
- package/dist/chunk-RIOKLMYM.js.map +1 -0
- package/dist/{chunk-QXR55VVS.js → chunk-TG6NMHXI.js} +241 -162
- package/dist/chunk-TG6NMHXI.js.map +1 -0
- package/dist/index.js +7 -5
- package/dist/modules/ambient/analyze.d.ts +18 -3
- package/dist/modules/ambient/analyze.d.ts.map +1 -1
- package/dist/modules/ambient/dom.d.ts +14 -1
- package/dist/modules/ambient/dom.d.ts.map +1 -1
- package/dist/modules/ambient/hooks.d.ts.map +1 -1
- package/dist/modules/ambient/index.d.ts +2 -2
- package/dist/modules/ambient/index.d.ts.map +1 -1
- package/dist/modules/ambient/index.js +1 -1
- package/dist/modules/ambient/server/index.d.ts +1 -1
- package/dist/modules/ambient/server/index.d.ts.map +1 -1
- package/dist/modules/ambient/server/index.js +2 -2
- package/dist/modules/ambient/server/index.js.map +1 -1
- package/dist/modules/ambient/settings.d.ts +1 -0
- package/dist/modules/ambient/settings.d.ts.map +1 -1
- package/dist/modules/ambient/types.d.ts +13 -0
- package/dist/modules/ambient/types.d.ts.map +1 -1
- package/dist/modules/ambient/worker/index.js +1 -1
- package/dist/modules/context-menu/index.js +4 -3
- package/dist/modules/dock/cards.d.ts.map +1 -1
- package/dist/modules/dock/constants.d.ts +1 -20
- package/dist/modules/dock/constants.d.ts.map +1 -1
- package/dist/modules/dock/index.js +3 -2
- package/dist/modules/dock/routing/guards.d.ts +1 -1
- package/dist/modules/dock/routing/navigation.d.ts +7 -4
- package/dist/modules/dock/routing/navigation.d.ts.map +1 -1
- package/dist/modules/dock/runtime/display.d.ts +31 -2
- package/dist/modules/dock/runtime/display.d.ts.map +1 -1
- package/dist/modules/dock/runtime/dock.d.ts +2 -2
- package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
- package/dist/modules/dock/types.d.ts +5 -27
- package/dist/modules/dock/types.d.ts.map +1 -1
- package/dist/modules/index.d.ts +3 -2
- package/dist/modules/index.d.ts.map +1 -1
- package/dist/modules/index.js +7 -5
- package/dist/modules/loading/context.d.ts.map +1 -1
- package/dist/modules/loading/index.js +1 -1
- package/dist/modules/navigation/constants.d.ts +37 -0
- package/dist/modules/navigation/constants.d.ts.map +1 -0
- package/dist/modules/navigation/context.d.ts +10 -0
- package/dist/modules/navigation/context.d.ts.map +1 -0
- package/dist/modules/navigation/hooks.d.ts +29 -0
- package/dist/modules/navigation/hooks.d.ts.map +1 -0
- package/dist/modules/navigation/index.d.ts +10 -0
- package/dist/modules/navigation/index.d.ts.map +1 -0
- package/dist/modules/navigation/index.js +81 -0
- package/dist/modules/navigation/index.js.map +1 -0
- package/dist/modules/navigation/listeners.d.ts +15 -0
- package/dist/modules/navigation/listeners.d.ts.map +1 -0
- package/dist/modules/navigation/module.d.ts +25 -0
- package/dist/modules/navigation/module.d.ts.map +1 -0
- package/dist/modules/navigation/navigator.d.ts +8 -0
- package/dist/modules/navigation/navigator.d.ts.map +1 -0
- package/dist/modules/navigation/settings.d.ts +10 -0
- package/dist/modules/navigation/settings.d.ts.map +1 -0
- package/dist/modules/navigation/state.d.ts +20 -0
- package/dist/modules/navigation/state.d.ts.map +1 -0
- package/dist/modules/navigation/types.d.ts +168 -0
- package/dist/modules/navigation/types.d.ts.map +1 -0
- package/dist/modules/navigation/utils.d.ts +11 -0
- package/dist/modules/navigation/utils.d.ts.map +1 -0
- package/docs/getting-started.md +2 -0
- package/docs/modules/README.md +5 -1
- package/docs/modules/ambient.md +9 -6
- package/docs/modules/dock.md +12 -10
- package/docs/modules/loading.md +2 -2
- package/docs/modules/navigation.md +216 -0
- package/docs/proposals/navigation.md +209 -0
- package/package.json +6 -1
- package/templates/AGENTS.md +2 -0
- package/dist/chunk-6SG7V77J.js.map +0 -1
- package/dist/chunk-6ZJVLUBE.js.map +0 -1
- package/dist/chunk-A5RE3F6O.js.map +0 -1
- package/dist/chunk-QXR55VVS.js.map +0 -1
- package/dist/chunk-XASQT4CQ.js.map +0 -1
- package/dist/modules/dock/routing/transactions.d.ts +0 -21
- package/dist/modules/dock/routing/transactions.d.ts.map +0 -1
package/dist/modules/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { defaultModules } from '../chunk-
|
|
2
|
+
export { defaultModules } from '../chunk-M57SNWXK.js';
|
|
3
|
+
export { navigationModule } from '../chunk-RIOKLMYM.js';
|
|
3
4
|
export { modalModule } from '../chunk-FIMPHODX.js';
|
|
4
5
|
import '../chunk-7HQMXTNP.js';
|
|
5
|
-
export { ambientModule } from '../chunk-
|
|
6
|
+
export { ambientModule } from '../chunk-TG6NMHXI.js';
|
|
6
7
|
export { backgroundModule } from '../chunk-CGHZSSFR.js';
|
|
7
|
-
export { contextMenuModule } from '../chunk-
|
|
8
|
-
export { dockModule } from '../chunk-
|
|
8
|
+
export { contextMenuModule } from '../chunk-CYU6SGAL.js';
|
|
9
|
+
export { dockModule } from '../chunk-JIXBFFRD.js';
|
|
10
|
+
import '../chunk-HLL5EHXC.js';
|
|
9
11
|
import '../chunk-QI3ALLIB.js';
|
|
10
12
|
export { notificationModule } from '../chunk-SYAVGTOX.js';
|
|
11
13
|
export { mediaModule } from '../chunk-R2YGFJDJ.js';
|
|
12
14
|
export { controlsModule } from '../chunk-4GMQKD6F.js';
|
|
13
|
-
export { loadingModule } from '../chunk-
|
|
15
|
+
export { loadingModule } from '../chunk-66EYJBIP.js';
|
|
14
16
|
import '../chunk-7TAVYJ3A.js';
|
|
15
17
|
import '../chunk-GF7TUX5I.js';
|
|
16
18
|
import '../chunk-TV3WEF5G.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/modules/loading/context.tsx"],"names":[],"mappings":"AAyBA,OAAO,EAEL,KAAK,mBAAmB,EAExB,KAAK,oBAAoB,EAEzB,KAAK,oBAAoB,EAE1B,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,cAAc,qDACmD,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/modules/loading/context.tsx"],"names":[],"mappings":"AAyBA,OAAO,EAEL,KAAK,mBAAmB,EAExB,KAAK,oBAAoB,EAEzB,KAAK,oBAAoB,EAE1B,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,cAAc,qDACmD,CAAC;AAU/E,eAAO,MAAM,kBAAkB,uDAE9B,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE,oBAAoB,+BAqJjE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { DEFAULT_LOADING_STATE, DEFAULT_LOADING_STATE_WITH_PAGE, INERT_LOADING_ACTIONS, LOADING_REGISTRY_KEY, LoadingContext, LoadingOverlay, LoadingProvider, NOOP_LOADING_STORE, calculateRemainingMinDuration, defineLoading, loadingModule, loadingTheme, normalizeLoadingOptions, resolveLoadingState, selectPageLoading, useLoading, useLoadingActions, useLoadingOverlayModel, useLoadingRegistration, useLoadingState, useOptionalLoadingActions, useOptionalLoadingState } from '../../chunk-
|
|
2
|
+
export { DEFAULT_LOADING_STATE, DEFAULT_LOADING_STATE_WITH_PAGE, INERT_LOADING_ACTIONS, LOADING_REGISTRY_KEY, LoadingContext, LoadingOverlay, LoadingProvider, NOOP_LOADING_STORE, calculateRemainingMinDuration, defineLoading, loadingModule, loadingTheme, normalizeLoadingOptions, resolveLoadingState, selectPageLoading, useLoading, useLoadingActions, useLoadingOverlayModel, useLoadingRegistration, useLoadingState, useOptionalLoadingActions, useOptionalLoadingState } from '../../chunk-66EYJBIP.js';
|
|
3
3
|
import '../../chunk-7TAVYJ3A.js';
|
|
4
4
|
import '../../chunk-GF7TUX5I.js';
|
|
5
5
|
import '../../chunk-TV3WEF5G.js';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const NAVIGATION_STATUS: Readonly<{
|
|
2
|
+
readonly PENDING: "pending";
|
|
3
|
+
readonly COMPLETED: "completed";
|
|
4
|
+
readonly CANCELLED: "cancelled";
|
|
5
|
+
readonly FAILED: "failed";
|
|
6
|
+
readonly TIMED_OUT: "timed-out";
|
|
7
|
+
}>;
|
|
8
|
+
export declare const NAVIGATION_PHASE: Readonly<{
|
|
9
|
+
readonly LEAVING: "leaving";
|
|
10
|
+
readonly ROUTING: "routing";
|
|
11
|
+
}>;
|
|
12
|
+
export declare const NAVIGATION_REASON: Readonly<{
|
|
13
|
+
readonly GUARD: "guard";
|
|
14
|
+
readonly RETURNED: "returned";
|
|
15
|
+
readonly SUPERSEDED: "superseded";
|
|
16
|
+
readonly TIME_OUT: "time-out";
|
|
17
|
+
}>;
|
|
18
|
+
export declare const NAVIGATION_SOURCE: Readonly<{
|
|
19
|
+
readonly HISTORY: "history";
|
|
20
|
+
readonly NAVIGATE: "navigate";
|
|
21
|
+
}>;
|
|
22
|
+
export declare const NAVIGATION_EVENTS: Readonly<{
|
|
23
|
+
/** A trip started (phase `leaving`). */
|
|
24
|
+
readonly START: "NAVIGATION_START";
|
|
25
|
+
/** The router was asked for the route (phase `routing`). */
|
|
26
|
+
readonly COMMIT: "NAVIGATION_COMMIT";
|
|
27
|
+
/** The trip settled, whatever its status. */
|
|
28
|
+
readonly END: "NAVIGATION_END";
|
|
29
|
+
}>;
|
|
30
|
+
export declare const NAVIGATION_INTENT_DELAY_MS = 180;
|
|
31
|
+
export declare const NAVIGATION_PREFETCH_TTL_MS: number;
|
|
32
|
+
export declare const NAVIGATION_ARRIVAL_TTL_MS = 20000;
|
|
33
|
+
export declare const NAVIGATION_MAX_HOLD_MS = 5000;
|
|
34
|
+
export declare const NAVIGATION_TIMEOUT_MS = 15000;
|
|
35
|
+
/** Links with this attribute set to `"false"` are never warmed on intent. */
|
|
36
|
+
export declare const NAVIGATION_PREFETCH_ATTRIBUTE = "data-prefetch";
|
|
37
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB;;;;;;EAMwB,CAAC;AAEvD,eAAO,MAAM,gBAAgB;;;EAGwB,CAAC;AAEtD,eAAO,MAAM,iBAAiB;;;;;EAKnB,CAAC;AAEZ,eAAO,MAAM,iBAAiB;;;EAGnB,CAAC;AAEZ,eAAO,MAAM,iBAAiB;IAC5B,wCAAwC;;IAExC,4DAA4D;;IAE5D,6CAA6C;;EAEpC,CAAC;AAEZ,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,0BAA0B,QAAa,CAAC;AACrD,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAChD,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAC5C,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { NavigationActions, NavigationRuntime, NavigationState } from "./types";
|
|
3
|
+
export declare const NavigationContext: import("react").Context<NavigationRuntime | null>;
|
|
4
|
+
/** What readers get without the module: no trips, nothing held or warmed. */
|
|
5
|
+
export declare const INERT_NAVIGATION_ACTIONS: NavigationActions;
|
|
6
|
+
export declare const NOOP_NAVIGATION_STORE: import("../../utils").ExternalStore<NavigationState>;
|
|
7
|
+
export declare function NavigationProvider({ children }: {
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASrE,OAAO,KAAK,EACV,iBAAiB,EAGjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB,eAAO,MAAM,iBAAiB,mDAI3B,CAAC;AAKJ,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,EAAE,iBAYrC,CAAC;AAEH,eAAO,MAAM,qBAAqB,kDAEjC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BA0BxE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { NavigationActions, NavigationHold, NavigationHoldOptions, NavigationIntentListener, NavigationPayloadKey, NavigationPayloadValue, NavigationState, NavigationTrip } from "./types";
|
|
2
|
+
/** The navigator's actions. Throws outside `NavigationProvider`. */
|
|
3
|
+
export declare function useNavigation(): NavigationActions;
|
|
4
|
+
/** The navigator's actions, or inert ones when the module is not installed. */
|
|
5
|
+
export declare function useOptionalNavigation(): NavigationActions;
|
|
6
|
+
export declare function useNavigationState(): NavigationState;
|
|
7
|
+
export declare function useNavigationState<T>(selector: (state: NavigationState) => T, isEqual?: (a: T, b: T) => boolean): T;
|
|
8
|
+
/**
|
|
9
|
+
* Holds every trip leaving while this component is mounted, until the
|
|
10
|
+
* returned promise settles (capped by `maxHoldMs`). Pass `false` or `null`
|
|
11
|
+
* to hold nothing. Watch `trip.signal` to undo an exit that never lands.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useNavigationHold(hold: NavigationHold | false | null | undefined, { history }?: NavigationHoldOptions): void;
|
|
14
|
+
/**
|
|
15
|
+
* Adds `key` to the payload of every trip leaving while this component is
|
|
16
|
+
* mounted. A function is called when the trip starts.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useNavigationPayload<K extends NavigationPayloadKey>(key: K, value: NavigationPayloadValue<K>): void;
|
|
19
|
+
/** Called with each path the navigator warms, from links, the dock or code. */
|
|
20
|
+
export declare function useNavigationIntent(listener: NavigationIntentListener): void;
|
|
21
|
+
/** The trip leaving the current page, while it is under way. */
|
|
22
|
+
export declare function useDeparture(): NavigationTrip | null;
|
|
23
|
+
/**
|
|
24
|
+
* The trip that brought the page to `pathname` (default: the current one),
|
|
25
|
+
* from the moment the router is asked for it until `arrivalTtlMs` later or
|
|
26
|
+
* until the page is left. A route's `loading.tsx` reads it too.
|
|
27
|
+
*/
|
|
28
|
+
export declare function useArrival(pathname?: string): NavigationTrip | null;
|
|
29
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/hooks.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACf,MAAM,SAAS,CAAC;AAGjB,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,iBAAiB,CAMjD;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,IAAI,iBAAiB,CAEzD;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAAC;AACtD,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,CAAC,EACvC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAChC,CAAC,CAAC;AAsBL;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,EAC/C,EAAE,OAAc,EAAE,GAAE,qBAA0B,GAC7C,IAAI,CAWN;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,oBAAoB,EACjE,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAC/B,IAAI,CAaN;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAO5E;AAED,gEAAgE;AAChE,wBAAgB,YAAY,IAAI,cAAc,GAAG,IAAI,CAMpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAKnE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type * from "./types";
|
|
2
|
+
export { navigationModule } from "./module";
|
|
3
|
+
export { INERT_NAVIGATION_ACTIONS, NavigationContext, NavigationProvider, } from "./context";
|
|
4
|
+
export { useArrival, useDeparture, useNavigation, useNavigationHold, useNavigationIntent, useNavigationPayload, useNavigationState, useOptionalNavigation, } from "./hooks";
|
|
5
|
+
export { createNavigator } from "./navigator";
|
|
6
|
+
export { watchHistory, watchIntent } from "./listeners";
|
|
7
|
+
export { configureNavigation, getNavigationSettings, } from "./settings";
|
|
8
|
+
export { NAVIGATION_EVENTS, NAVIGATION_PHASE, NAVIGATION_REASON, NAVIGATION_SOURCE, NAVIGATION_STATUS, } from "./constants";
|
|
9
|
+
export { isSafeInternalHref, locationKeyOf, pathOf } from "./utils";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,SAAS,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { NavigationContext, INERT_NAVIGATION_ACTIONS, NOOP_NAVIGATION_STORE } from '../../chunk-RIOKLMYM.js';
|
|
3
|
+
export { INERT_NAVIGATION_ACTIONS, NavigationContext, NavigationProvider, navigationModule, watchHistory, watchIntent } from '../../chunk-RIOKLMYM.js';
|
|
4
|
+
import { isSamePathname, tripDestination } from '../../chunk-HLL5EHXC.js';
|
|
5
|
+
export { NAVIGATION_EVENTS, NAVIGATION_PHASE, NAVIGATION_REASON, NAVIGATION_SOURCE, NAVIGATION_STATUS, configureNavigation, createNavigator, getNavigationSettings, isSafeInternalHref, locationKeyOf, pathOf } from '../../chunk-HLL5EHXC.js';
|
|
6
|
+
import '../../chunk-GF7TUX5I.js';
|
|
7
|
+
import { useRequiredContext, useStore, useIsomorphicLayoutEffect } from '../../chunk-TV3WEF5G.js';
|
|
8
|
+
import { useContext, useEffect, useRef } from 'react';
|
|
9
|
+
import { usePathname } from 'next/navigation';
|
|
10
|
+
|
|
11
|
+
function useNavigation() {
|
|
12
|
+
return useRequiredContext(
|
|
13
|
+
NavigationContext,
|
|
14
|
+
"useNavigation",
|
|
15
|
+
"NavigationProvider"
|
|
16
|
+
).actions;
|
|
17
|
+
}
|
|
18
|
+
function useOptionalNavigation() {
|
|
19
|
+
return useContext(NavigationContext)?.actions ?? INERT_NAVIGATION_ACTIONS;
|
|
20
|
+
}
|
|
21
|
+
function useNavigationState(selector, isEqual) {
|
|
22
|
+
const store = useContext(NavigationContext)?.store ?? NOOP_NAVIGATION_STORE;
|
|
23
|
+
return useStore(
|
|
24
|
+
store,
|
|
25
|
+
selector,
|
|
26
|
+
isEqual
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
function useLatest(value) {
|
|
30
|
+
const ref = useRef(value);
|
|
31
|
+
useIsomorphicLayoutEffect(() => {
|
|
32
|
+
ref.current = value;
|
|
33
|
+
}, [value]);
|
|
34
|
+
return ref;
|
|
35
|
+
}
|
|
36
|
+
function useNavigationHold(hold, { history = true } = {}) {
|
|
37
|
+
const { hold: register } = useOptionalNavigation();
|
|
38
|
+
const latest = useLatest(hold);
|
|
39
|
+
const enabled = Boolean(hold);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!enabled) return;
|
|
42
|
+
return register((trip) => {
|
|
43
|
+
const run = latest.current;
|
|
44
|
+
return run ? run(trip) : void 0;
|
|
45
|
+
}, { history });
|
|
46
|
+
}, [enabled, history, latest, register]);
|
|
47
|
+
}
|
|
48
|
+
function useNavigationPayload(key, value) {
|
|
49
|
+
const { provide } = useOptionalNavigation();
|
|
50
|
+
const latest = useLatest(value);
|
|
51
|
+
useEffect(
|
|
52
|
+
() => provide(key, (() => {
|
|
53
|
+
const current = latest.current;
|
|
54
|
+
return typeof current === "function" ? current() : current;
|
|
55
|
+
})),
|
|
56
|
+
[key, latest, provide]
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
function useNavigationIntent(listener) {
|
|
60
|
+
const { onIntent } = useOptionalNavigation();
|
|
61
|
+
const latest = useLatest(listener);
|
|
62
|
+
useEffect(
|
|
63
|
+
() => onIntent((path, href) => latest.current(path, href)),
|
|
64
|
+
[latest, onIntent]
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function useDeparture() {
|
|
68
|
+
const pathname = usePathname();
|
|
69
|
+
const active = useNavigationState((state) => state.active);
|
|
70
|
+
return active && !isSamePathname(tripDestination(active), pathname) ? active : null;
|
|
71
|
+
}
|
|
72
|
+
function useArrival(pathname) {
|
|
73
|
+
const routePathname = usePathname();
|
|
74
|
+
const target = pathname ?? routePathname;
|
|
75
|
+
const { arrival } = useOptionalNavigation();
|
|
76
|
+
return useNavigationState(() => arrival(target));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { useArrival, useDeparture, useNavigation, useNavigationHold, useNavigationIntent, useNavigationPayload, useNavigationState, useOptionalNavigation };
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/navigation/hooks.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport { useContext, useEffect, useRef } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { useIsomorphicLayoutEffect, useRequiredContext, useStore } from \"@/hooks\";\nimport {\n INERT_NAVIGATION_ACTIONS,\n NOOP_NAVIGATION_STORE,\n NavigationContext,\n} from \"./context\";\nimport { tripDestination } from \"./state\";\nimport type {\n NavigationActions,\n NavigationHold,\n NavigationHoldOptions,\n NavigationIntentListener,\n NavigationPayloadKey,\n NavigationPayloadValue,\n NavigationState,\n NavigationTrip,\n} from \"./types\";\nimport { isSamePathname } from \"./utils\";\n\n/** The navigator's actions. Throws outside `NavigationProvider`. */\nexport function useNavigation(): NavigationActions {\n return useRequiredContext(\n NavigationContext,\n \"useNavigation\",\n \"NavigationProvider\",\n ).actions;\n}\n\n/** The navigator's actions, or inert ones when the module is not installed. */\nexport function useOptionalNavigation(): NavigationActions {\n return useContext(NavigationContext)?.actions ?? INERT_NAVIGATION_ACTIONS;\n}\n\nexport function useNavigationState(): NavigationState;\nexport function useNavigationState<T>(\n selector: (state: NavigationState) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useNavigationState<T = NavigationState>(\n selector?: (state: NavigationState) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T {\n const store = useContext(NavigationContext)?.store ?? NOOP_NAVIGATION_STORE;\n return useStore(\n store,\n selector as (state: NavigationState) => T,\n isEqual,\n );\n}\n\n/** The latest value of `value`, readable from callbacks registered once. */\nfunction useLatest<T>(value: T) {\n const ref = useRef(value);\n useIsomorphicLayoutEffect(() => {\n ref.current = value;\n }, [value]);\n return ref;\n}\n\n/**\n * Holds every trip leaving while this component is mounted, until the\n * returned promise settles (capped by `maxHoldMs`). Pass `false` or `null`\n * to hold nothing. Watch `trip.signal` to undo an exit that never lands.\n */\nexport function useNavigationHold(\n hold: NavigationHold | false | null | undefined,\n { history = true }: NavigationHoldOptions = {},\n): void {\n const { hold: register } = useOptionalNavigation();\n const latest = useLatest(hold);\n const enabled = Boolean(hold);\n useEffect(() => {\n if (!enabled) return;\n return register((trip) => {\n const run = latest.current;\n return run ? run(trip) : undefined;\n }, { history });\n }, [enabled, history, latest, register]);\n}\n\n/**\n * Adds `key` to the payload of every trip leaving while this component is\n * mounted. A function is called when the trip starts.\n */\nexport function useNavigationPayload<K extends NavigationPayloadKey>(\n key: K,\n value: NavigationPayloadValue<K>,\n): void {\n const { provide } = useOptionalNavigation();\n const latest = useLatest(value);\n useEffect(\n () =>\n provide(key, (() => {\n const current = latest.current;\n return typeof current === \"function\"\n ? (current as () => unknown)()\n : current;\n }) as NavigationPayloadValue<K>),\n [key, latest, provide],\n );\n}\n\n/** Called with each path the navigator warms, from links, the dock or code. */\nexport function useNavigationIntent(listener: NavigationIntentListener): void {\n const { onIntent } = useOptionalNavigation();\n const latest = useLatest(listener);\n useEffect(\n () => onIntent((path, href) => latest.current(path, href)),\n [latest, onIntent],\n );\n}\n\n/** The trip leaving the current page, while it is under way. */\nexport function useDeparture(): NavigationTrip | null {\n const pathname = usePathname();\n const active = useNavigationState((state) => state.active);\n return active && !isSamePathname(tripDestination(active), pathname)\n ? active\n : null;\n}\n\n/**\n * The trip that brought the page to `pathname` (default: the current one),\n * from the moment the router is asked for it until `arrivalTtlMs` later or\n * until the page is left. A route's `loading.tsx` reads it too.\n */\nexport function useArrival(pathname?: string): NavigationTrip | null {\n const routePathname = usePathname();\n const target = pathname ?? routePathname;\n const { arrival } = useOptionalNavigation();\n return useNavigationState(() => arrival(target));\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { NavigationSettings, Navigator } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Prefetches internal links on intent: after `intent.delayMs` of mouse hover,
|
|
4
|
+
* and at once on pointerdown or focus. Returns the cleanup.
|
|
5
|
+
*/
|
|
6
|
+
export declare function watchIntent(navigator: Pick<Navigator, "prefetch">, settings: () => NavigationSettings, doc?: Document): () => void;
|
|
7
|
+
/**
|
|
8
|
+
* Turns back/forward steps into trips. While a hold wants history steps, the
|
|
9
|
+
* step is swallowed before the router sees it (a capture listener on
|
|
10
|
+
* `window` runs first), the holds run, and the same `popstate` is replayed
|
|
11
|
+
* for the router. Stepping back to the origin during the hold cancels the
|
|
12
|
+
* trip. Returns the cleanup.
|
|
13
|
+
*/
|
|
14
|
+
export declare function watchHistory(navigator: Pick<Navigator, "cancel" | "depart" | "holdsHistory" | "store">, win?: Window): () => void;
|
|
15
|
+
//# sourceMappingURL=listeners.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listeners.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/listeners.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAQ7D;;;GAGG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EACtC,QAAQ,EAAE,MAAM,kBAAkB,EAClC,GAAG,GAAE,QAAmB,GACvB,MAAM,IAAI,CAmDZ;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,OAAO,CAAC,EAC1E,GAAG,GAAE,MAAe,GACnB,MAAM,IAAI,CA2CZ"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { NavigationTrip } from "./types";
|
|
2
|
+
export declare const navigationModule: import("@omerdlw/base-framework/kernel").CoreModule<"navigation", import("./types").NavigationRuntime, never, never>;
|
|
3
|
+
interface NavigationEventPayload {
|
|
4
|
+
from: string;
|
|
5
|
+
source: string;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
to: string;
|
|
8
|
+
trip: NavigationTrip;
|
|
9
|
+
type: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
declare module "@omerdlw/base-framework/events" {
|
|
13
|
+
interface FrameworkEventMap {
|
|
14
|
+
NAVIGATION_START: NavigationEventPayload;
|
|
15
|
+
NAVIGATION_COMMIT: NavigationEventPayload;
|
|
16
|
+
NAVIGATION_END: NavigationEventPayload;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
declare module "@omerdlw/base-framework/kernel" {
|
|
20
|
+
interface CoreModules {
|
|
21
|
+
navigation: typeof navigationModule;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/module.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,eAAO,MAAM,gBAAgB,sHAI3B,CAAC;AAEH,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,iBAAiB;QACzB,gBAAgB,EAAE,sBAAsB,CAAC;QACzC,iBAAiB,EAAE,sBAAsB,CAAC;QAC1C,cAAc,EAAE,sBAAsB,CAAC;KACxC;CACF;AAED,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,WAAW;QACnB,UAAU,EAAE,OAAO,gBAAgB,CAAC;KACrC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Navigator, NavigatorOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* The navigation state machine: one active trip at a time, from the first
|
|
4
|
+
* intent through holds and the router call to arrival. Pure: no React, no
|
|
5
|
+
* Next; the provider binds a router and reports arrivals.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createNavigator(options?: NavigatorOptions): Navigator;
|
|
8
|
+
//# sourceMappingURL=navigator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigator.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/navigator.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAcV,SAAS,EACT,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAqBjB;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,SAAS,CA2YzE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NavigationSettings, NavigationSettingsInput } from "./types";
|
|
2
|
+
export declare function getNavigationSettings(): NavigationSettings;
|
|
3
|
+
export declare function mergeNavigationSettings(base: NavigationSettings, input: NavigationSettingsInput): NavigationSettings;
|
|
4
|
+
/**
|
|
5
|
+
* Sets intent prefetch, the warm cache, hold and arrival windows and the
|
|
6
|
+
* route timeout for every navigator. Returns a function that restores the
|
|
7
|
+
* previous settings.
|
|
8
|
+
*/
|
|
9
|
+
export declare function configureNavigation(input: NavigationSettingsInput): () => void;
|
|
10
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/settings.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AA0BjB,wBAAgB,qBAAqB,IAAI,kBAAkB,CAE1D;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,kBAAkB,EACxB,KAAK,EAAE,uBAAuB,GAC7B,kBAAkB,CAWpB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,IAAI,CAO9E"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { NavigationPayload, NavigationState, NavigationStatus, NavigationTrip } from "./types";
|
|
2
|
+
export declare function createNavigationState(location?: string): NavigationState;
|
|
3
|
+
export declare function createTrip({ from, href, id, payload, signal, source, startedAt, }: {
|
|
4
|
+
from: string;
|
|
5
|
+
href: string;
|
|
6
|
+
id: number;
|
|
7
|
+
payload?: NavigationPayload;
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
source: string;
|
|
10
|
+
startedAt: number;
|
|
11
|
+
}): NavigationTrip;
|
|
12
|
+
export declare function settleTrip(trip: NavigationTrip, status: NavigationStatus, { arrivedAt, endedAt, error, reason, }: {
|
|
13
|
+
arrivedAt?: string;
|
|
14
|
+
endedAt: number;
|
|
15
|
+
error?: unknown;
|
|
16
|
+
reason?: string | null;
|
|
17
|
+
}): NavigationTrip;
|
|
18
|
+
/** Where a trip ends up: where it landed, else where it was headed. */
|
|
19
|
+
export declare const tripDestination: (trip: NavigationTrip) => string;
|
|
20
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACf,MAAM,SAAS,CAAC;AAGjB,wBAAgB,qBAAqB,CAAC,QAAQ,SAAK,GAAG,eAAe,CAEpE;AAED,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,IAAI,EACJ,EAAE,EACF,OAAY,EACZ,MAAM,EACN,MAAM,EACN,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,cAAc,CAajB;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,EACxB,EACE,SAAS,EACT,OAAO,EACP,KAAY,EACZ,MAAa,GACd,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GACA,cAAc,CAIhB;AAED,uEAAuE;AACvE,eAAO,MAAM,eAAe,GAAI,MAAM,cAAc,KAAG,MAC5B,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { ExternalStore } from "../../utils";
|
|
2
|
+
/**
|
|
3
|
+
* What a departing page hands the destination. Empty by default: apps add
|
|
4
|
+
* their own keys by augmentation, so the framework depends on none of them.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* declare module "@omerdlw/base-framework/modules/navigation" {
|
|
8
|
+
* interface NavigationPayload {
|
|
9
|
+
* palette?: AmbientPalette | null;
|
|
10
|
+
* }
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export interface NavigationPayload {
|
|
15
|
+
}
|
|
16
|
+
export type NavigationPayloadKey = keyof NavigationPayload & string;
|
|
17
|
+
export type NavigationStatus = "pending" | "completed" | "cancelled" | "failed" | "timed-out";
|
|
18
|
+
/** `leaving`: holds run, the route has not been asked for yet. `routing`: it has. */
|
|
19
|
+
export type NavigationPhase = "leaving" | "routing";
|
|
20
|
+
export interface NavigationTrip {
|
|
21
|
+
/** Where the trip actually landed, when it differs from `to` (a redirect). */
|
|
22
|
+
arrivedAt?: string;
|
|
23
|
+
endedAt?: number;
|
|
24
|
+
error?: unknown;
|
|
25
|
+
/** The location key the trip left from. */
|
|
26
|
+
from: string;
|
|
27
|
+
/** The href as given, passed to the router unchanged. */
|
|
28
|
+
href: string;
|
|
29
|
+
id: number;
|
|
30
|
+
payload: Readonly<NavigationPayload>;
|
|
31
|
+
phase: NavigationPhase;
|
|
32
|
+
reason?: string | null;
|
|
33
|
+
/** Aborts when the trip is cancelled, fails or times out. */
|
|
34
|
+
signal: AbortSignal;
|
|
35
|
+
/** `dock`, `history`, `navigate`, or whatever the caller passed. */
|
|
36
|
+
source: string;
|
|
37
|
+
startedAt: number;
|
|
38
|
+
status: NavigationStatus;
|
|
39
|
+
/** The destination's location key (pathname, search and hash). */
|
|
40
|
+
to: string;
|
|
41
|
+
}
|
|
42
|
+
export interface NavigationState {
|
|
43
|
+
active: NavigationTrip | null;
|
|
44
|
+
last: NavigationTrip | null;
|
|
45
|
+
/** The location key the navigator last saw arrive. */
|
|
46
|
+
location: string;
|
|
47
|
+
}
|
|
48
|
+
export type NavigationPrefetchKind = "auto" | "full" | "temporary";
|
|
49
|
+
export interface NavigationRouter {
|
|
50
|
+
back?(): void;
|
|
51
|
+
prefetch(href: string, options?: {
|
|
52
|
+
kind?: NavigationPrefetchKind;
|
|
53
|
+
onInvalidate?: () => void;
|
|
54
|
+
}): void;
|
|
55
|
+
push(href: string, options?: {
|
|
56
|
+
scroll?: boolean;
|
|
57
|
+
}): void;
|
|
58
|
+
replace(href: string, options?: {
|
|
59
|
+
scroll?: boolean;
|
|
60
|
+
}): void;
|
|
61
|
+
}
|
|
62
|
+
export interface NavigationBlock {
|
|
63
|
+
blocked: boolean;
|
|
64
|
+
message?: string;
|
|
65
|
+
[key: string]: unknown;
|
|
66
|
+
}
|
|
67
|
+
export interface NavigateOptions {
|
|
68
|
+
/** Skip `guard`. Holds still run. */
|
|
69
|
+
force?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Runs once the trip has started and before holds. A `blocked` result
|
|
72
|
+
* cancels the trip with reason `blocked`. The dock runs its guards here.
|
|
73
|
+
*/
|
|
74
|
+
guard?: (trip: NavigationTrip) => NavigationBlock | boolean | Promise<NavigationBlock | boolean>;
|
|
75
|
+
/** Runs right before the router is called, once guard and holds passed. */
|
|
76
|
+
onCommit?: (trip: NavigationTrip) => void;
|
|
77
|
+
/** Merged over what `provide` contributes. */
|
|
78
|
+
payload?: Partial<NavigationPayload>;
|
|
79
|
+
replace?: boolean;
|
|
80
|
+
scroll?: boolean;
|
|
81
|
+
source?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface NavigationResult {
|
|
84
|
+
blocked?: NavigationBlock;
|
|
85
|
+
/** `true` when the router was asked for the route. */
|
|
86
|
+
ok: boolean;
|
|
87
|
+
trip: NavigationTrip | null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Runs when a trip leaves. The trip commits once every returned promise
|
|
91
|
+
* settles, or after `maxHoldMs`. Watch `trip.signal` to undo an exit that
|
|
92
|
+
* never lands.
|
|
93
|
+
*/
|
|
94
|
+
export type NavigationHold = (trip: NavigationTrip) => void | Promise<unknown>;
|
|
95
|
+
export interface NavigationHoldOptions {
|
|
96
|
+
/** Also hold back/forward steps. Default `true`. */
|
|
97
|
+
history?: boolean;
|
|
98
|
+
}
|
|
99
|
+
export type NavigationPayloadValue<K extends NavigationPayloadKey> = NavigationPayload[K] | (() => NavigationPayload[K]);
|
|
100
|
+
export type NavigationIntentListener = (path: string, href: string) => void;
|
|
101
|
+
export interface NavigationPrefetchOptions {
|
|
102
|
+
/** Skip the warm cache and prefetch again. */
|
|
103
|
+
force?: boolean;
|
|
104
|
+
kind?: NavigationPrefetchKind;
|
|
105
|
+
}
|
|
106
|
+
export interface NavigationIntentSettings {
|
|
107
|
+
/** Mouse dwell before a hovered link is prefetched. */
|
|
108
|
+
delayMs: number;
|
|
109
|
+
/** Which links to warm. Internal hrefs only, whatever this returns. */
|
|
110
|
+
match: (href: string) => boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface NavigationSettings {
|
|
113
|
+
/** How long a settled trip stays readable by `useArrival`. */
|
|
114
|
+
arrivalTtlMs: number;
|
|
115
|
+
/** Document-level intent prefetch for `a[href]`; `false` turns it off. */
|
|
116
|
+
intent: NavigationIntentSettings | false;
|
|
117
|
+
/** Cap on holds; past it the trip commits anyway. */
|
|
118
|
+
maxHoldMs: number;
|
|
119
|
+
prefetchKind: NavigationPrefetchKind;
|
|
120
|
+
/** How long a warmed path is not prefetched again. */
|
|
121
|
+
prefetchTtlMs: number;
|
|
122
|
+
/** Patience once the route was asked for; then the trip times out. */
|
|
123
|
+
timeoutMs: number;
|
|
124
|
+
}
|
|
125
|
+
export interface NavigationSettingsInput extends Partial<Omit<NavigationSettings, "intent">> {
|
|
126
|
+
intent?: Partial<NavigationIntentSettings> | boolean;
|
|
127
|
+
}
|
|
128
|
+
export interface NavigatorOptions {
|
|
129
|
+
emit?: (event: string, payload: Record<string, unknown>) => void;
|
|
130
|
+
/** Runs `callback` after the next paint. */
|
|
131
|
+
nextFrame?: (callback: () => void) => void;
|
|
132
|
+
now?: () => number;
|
|
133
|
+
/** The browser's current location key, or `null` off the browser. */
|
|
134
|
+
readLocation?: () => string | null;
|
|
135
|
+
router?: NavigationRouter | null;
|
|
136
|
+
settings?: () => NavigationSettings;
|
|
137
|
+
}
|
|
138
|
+
export interface NavigationActions {
|
|
139
|
+
/** The fresh trip that ended at `pathname`, or `null`. */
|
|
140
|
+
arrival(pathname: string): NavigationTrip | null;
|
|
141
|
+
/** Tells the navigator the location changed. The provider calls it. */
|
|
142
|
+
arrive(location: string): void;
|
|
143
|
+
/** Cancels the active trip. */
|
|
144
|
+
cancel(reason?: string | null): boolean;
|
|
145
|
+
/** Starts a trip from the browser's own back/forward step. */
|
|
146
|
+
depart(to: string, options?: {
|
|
147
|
+
replay?: () => void;
|
|
148
|
+
source?: string;
|
|
149
|
+
}): NavigationTrip | null;
|
|
150
|
+
hold(hold: NavigationHold, options?: NavigationHoldOptions): () => void;
|
|
151
|
+
/** Whether a hold wants back/forward steps. */
|
|
152
|
+
holdsHistory(): boolean;
|
|
153
|
+
navigate(href: string, options?: NavigateOptions): Promise<NavigationResult>;
|
|
154
|
+
onIntent(listener: NavigationIntentListener): () => void;
|
|
155
|
+
prefetch(href: string, options?: NavigationPrefetchOptions): boolean;
|
|
156
|
+
provide<K extends NavigationPayloadKey>(key: K, value: NavigationPayloadValue<K>): () => void;
|
|
157
|
+
/** Points the navigator at another router (the provider's). */
|
|
158
|
+
setRouter(router: NavigationRouter | null): void;
|
|
159
|
+
}
|
|
160
|
+
export interface Navigator extends NavigationActions {
|
|
161
|
+
dispose(): void;
|
|
162
|
+
store: ExternalStore<NavigationState>;
|
|
163
|
+
}
|
|
164
|
+
export interface NavigationRuntime {
|
|
165
|
+
actions: NavigationActions;
|
|
166
|
+
store: ExternalStore<NavigationState>;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function isSafeInternalHref(value: unknown): boolean;
|
|
2
|
+
/** The pathname of an href, without search, hash or trailing slash. */
|
|
3
|
+
export declare function pathOf(href: string): string;
|
|
4
|
+
/** An href's location key: normalized pathname plus its search and hash. */
|
|
5
|
+
export declare function locationKeyOf(href: string): string;
|
|
6
|
+
export declare function isSameLocation(left: string, right: string): boolean;
|
|
7
|
+
export declare function isSamePathname(left: string, right: string): boolean;
|
|
8
|
+
export declare function readWindowLocation(): string | null;
|
|
9
|
+
/** The link with an internal href around `target`, or `null`. */
|
|
10
|
+
export declare function internalLinkOf(target: EventTarget | null): Element | null;
|
|
11
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/modules/navigation/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG1D;AAED,uEAAuE;AACvE,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAIlD;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAKzE"}
|
package/docs/getting-started.md
CHANGED
|
@@ -77,6 +77,7 @@ import { ambientModule } from "@omerdlw/base-framework/modules/ambient";
|
|
|
77
77
|
import { backgroundModule } from "@omerdlw/base-framework/modules/background";
|
|
78
78
|
import { controlsModule } from "@omerdlw/base-framework/modules/controls";
|
|
79
79
|
import { loadingModule } from "@omerdlw/base-framework/modules/loading";
|
|
80
|
+
import { navigationModule } from "@omerdlw/base-framework/modules/navigation";
|
|
80
81
|
import { contextMenuModule } from "@omerdlw/base-framework/modules/context-menu";
|
|
81
82
|
|
|
82
83
|
// Define the modules your application uses
|
|
@@ -88,6 +89,7 @@ const modules = [
|
|
|
88
89
|
backgroundModule,
|
|
89
90
|
controlsModule,
|
|
90
91
|
loadingModule,
|
|
92
|
+
navigationModule,
|
|
91
93
|
contextMenuModule,
|
|
92
94
|
];
|
|
93
95
|
|
package/docs/modules/README.md
CHANGED
|
@@ -12,6 +12,7 @@ One page per module/core entry. Each page answers, from the big picture down to
|
|
|
12
12
|
| Dock | `@omerdlw/base-framework/modules/dock` | [dock.md](./dock.md) | The only chrome: card stack, surfaces/flows, HUD, operations, status overlays, guards, breadcrumbs | `dock` | `dock` |
|
|
13
13
|
| Modal | `@omerdlw/base-framework/modules/modal` | [modal.md](./modal.md) | Promise-based stacked dialogs | `modal` | `modal` |
|
|
14
14
|
| Notification | `@omerdlw/base-framework/modules/notification` | [notification.md](./notification.md) | Single-slot toasts docked to the dock; event-driven feedback | `notification` | — |
|
|
15
|
+
| Navigation | `@omerdlw/base-framework/modules/navigation` | [navigation.md](./navigation.md) | Trips: exit holds, payload to the next page, back-button hold, intent prefetch | — | — |
|
|
15
16
|
| Loading | `@omerdlw/base-framework/modules/loading` | [loading.md](./loading.md) | Loading overlay + busy flag | `loading` | `loading` |
|
|
16
17
|
| Background | `@omerdlw/base-framework/modules/background` | [background.md](./background.md) | Image / video / YouTube layer behind the page | `background` | `background` |
|
|
17
18
|
| Media | `@omerdlw/base-framework/modules/media` | [media.md](./media.md) | The active media session the dock controls operate on | `media` | `media` |
|
|
@@ -44,6 +45,7 @@ Modules never import each other. They connect through three channels only:
|
|
|
44
45
|
| dock → `loading` | `definePeer` | Page-loading flag; `stopLoading()` after navigation. |
|
|
45
46
|
| dock → `media` | `definePeer` | Play/pause icon, media controls. |
|
|
46
47
|
| dock → `notification` | `definePeer` | Is a toast visible (breadcrumbs yield). |
|
|
48
|
+
| dock → `navigation` | `useModule` | Transactions are its trips; card prefetch uses its warm cache. Without it the dock runs its own navigator. |
|
|
47
49
|
| background → `media` | `definePeer` | Registers the background video as source `background`. |
|
|
48
50
|
| ambient → `background` | `useModuleState` | Poster URL as the default tint image. |
|
|
49
51
|
| context-menu → `dock` | `useModuleState` | Active card as the default menu header. |
|
|
@@ -55,7 +57,7 @@ Every `definePeer`/`useModuleState`/`useModule` call needs the **peer id as a st
|
|
|
55
57
|
|
|
56
58
|
## 3. Install-time facts
|
|
57
59
|
|
|
58
|
-
- `src/modules/index.ts` exports every module and `defaultModules` (`background, ambient, dock, controls, contextMenu, loading, media, modal, notification`); it is the only place that lists them all. `src/app/providers.tsx` passes the list to `CoreProvider`.
|
|
60
|
+
- `src/modules/index.ts` exports every module and `defaultModules` (`background, ambient, navigation, dock, controls, contextMenu, loading, media, modal, notification`); it is the only place that lists them all. `src/app/providers.tsx` passes the list to `CoreProvider`.
|
|
59
61
|
- Install a subset to ship less: `modules={[dockModule, notificationModule, loadingModule]}`.
|
|
60
62
|
- Module ids are **camelCase** (`contextMenu`); the folder and theme id may be kebab-case (`context-menu`).
|
|
61
63
|
- A module is installable when it has a `module.tsx` (or `module.ts`) with `defineModule`; the order of the list does not matter (`uses` sorts it).
|
|
@@ -97,6 +99,7 @@ Rules of thumb:
|
|
|
97
99
|
| loading | ✅ | ✅ | ✅ | ✅ | — | ✅ | — | |
|
|
98
100
|
| media | ✅ | ✅ | ✅ | ✅ | — | ✅ | — | |
|
|
99
101
|
| modal | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
102
|
+
| navigation | ✅ | ✅ | ✅ | ✅ | ✅ | — | — | `navigator.ts`, `listeners.ts`, `settings.ts` |
|
|
100
103
|
| notification | ✅ | `module.ts` | ✅ | ✅ | — | ✅ | ✅ | |
|
|
101
104
|
|
|
102
105
|
### 4.2 Why some optional slots are absent
|
|
@@ -106,6 +109,7 @@ Rules of thumb:
|
|
|
106
109
|
| `ambient` | `overlay`, `motion` | Renders nothing: it writes CSS custom properties; transitions are CSS classes from the theme. |
|
|
107
110
|
| `controls` | `context`, `motion` | Stateless: entries live in the registry and layout is measured from the DOM. No animation. |
|
|
108
111
|
| `loading` | `motion`, `state` | The overlay renders `Spinner` (or a skeleton) and mounts/unmounts instantly; state is a small `useState` in the provider. |
|
|
112
|
+
| `navigation` | `overlay`, `motion` | Renders nothing: it binds the router and listens to the document; animation is the app's, in its holds. |
|
|
109
113
|
| `media` | `motion` | Renders nothing; `overlay.tsx` holds only the components that return `null` (`MediaSource`, `MediaOverlay`). |
|
|
110
114
|
| `notification` | builder | Toasts are imperative: `useToast` (in `hooks.ts`) plays the builder role. |
|
|
111
115
|
| core `error` | provider, builder, view | Boundaries are class components configured through props; `boundary.tsx` is the view, `listener.ts` and `reporter.ts` are topic files. |
|