@real-router/sources 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +4 -5
- package/src/BaseSource.ts +0 -95
- package/src/canonicalJson.ts +0 -110
- package/src/computeSnapshot.ts +0 -44
- package/src/createActiveNameSelector.ts +0 -182
- package/src/createActiveRouteSource.ts +0 -223
- package/src/createDismissableError.ts +0 -108
- package/src/createErrorSource.ts +0 -111
- package/src/createRouteNodeSource.ts +0 -130
- package/src/createRouteSource.ts +0 -56
- package/src/createTransitionSource.ts +0 -192
- package/src/index.ts +0 -35
- package/src/internal/noopDestroy.ts +0 -19
- package/src/internal/readContextHash.ts +0 -32
- package/src/normalizeActiveOptions.ts +0 -41
- package/src/stabilizeState.ts +0 -75
- package/src/types.ts +0 -63
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { ActiveRouteSourceOptions } from "./types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Normalized options shape — booleans are required (filled with defaults),
|
|
5
|
-
* `hash` stays `string | undefined` because `undefined` is the meaningful
|
|
6
|
-
* "ignore hash" sentinel that callers pass intentionally.
|
|
7
|
-
*/
|
|
8
|
-
export interface NormalizedActiveOptions {
|
|
9
|
-
strict: boolean;
|
|
10
|
-
ignoreQueryParams: boolean;
|
|
11
|
-
hash: string | undefined;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Default options for `createActiveRouteSource` and adapter-level helpers.
|
|
16
|
-
*
|
|
17
|
-
* Frozen to prevent accidental mutation by consumers.
|
|
18
|
-
*/
|
|
19
|
-
export const DEFAULT_ACTIVE_OPTIONS: Readonly<NormalizedActiveOptions> =
|
|
20
|
-
Object.freeze({
|
|
21
|
-
strict: false,
|
|
22
|
-
ignoreQueryParams: true,
|
|
23
|
-
hash: undefined,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Normalizes partial `ActiveRouteSourceOptions` into a fully-defaulted object.
|
|
28
|
-
*
|
|
29
|
-
* Use this to produce a stable options record for comparison, caching, or
|
|
30
|
-
* downstream consumers that require all fields present.
|
|
31
|
-
*/
|
|
32
|
-
export function normalizeActiveOptions(
|
|
33
|
-
options?: ActiveRouteSourceOptions,
|
|
34
|
-
): NormalizedActiveOptions {
|
|
35
|
-
return {
|
|
36
|
-
strict: options?.strict ?? DEFAULT_ACTIVE_OPTIONS.strict,
|
|
37
|
-
ignoreQueryParams:
|
|
38
|
-
options?.ignoreQueryParams ?? DEFAULT_ACTIVE_OPTIONS.ignoreQueryParams,
|
|
39
|
-
hash: options?.hash,
|
|
40
|
-
};
|
|
41
|
-
}
|
package/src/stabilizeState.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { readContextHash } from "./internal/readContextHash.js";
|
|
2
|
-
|
|
3
|
-
import type { State } from "@real-router/core";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* State-aware stabilization for route snapshots.
|
|
7
|
-
*
|
|
8
|
-
* Compares `path` (canonical name+params), `state.context.url.hash`
|
|
9
|
-
* (URL fragment, #532), and `state.transition.reload` (#605). When all
|
|
10
|
-
* three match (idempotent navigation), returns `prev` (preserving
|
|
11
|
-
* reference) so frameworks can skip re-renders. When any of them flips,
|
|
12
|
-
* returns `next` so consumers subscribing through `useRoute()` see the
|
|
13
|
-
* new state.
|
|
14
|
-
*
|
|
15
|
-
* `transition.reload === true` is the user's explicit signal for a
|
|
16
|
-
* non-idempotent navigation — `router.navigate(name, params, { reload:
|
|
17
|
-
* true })` is the canonical pairing for `invalidate(router, namespace)`
|
|
18
|
-
* and any cache-bust pattern. Bypassing stabilization for reloads makes
|
|
19
|
-
* `useRoute()` consumers see fresh `state.context.<namespace>` values
|
|
20
|
-
* written by the SSR loader plugin's `subscribeLeave` handler.
|
|
21
|
-
*
|
|
22
|
-
* Ignores `meta` (internal: auto-increment id), other `transition` fields
|
|
23
|
-
* (`from`, `segments`, `redirected`), and `state.context.navigation` /
|
|
24
|
-
* `state.context.browser` (transient transition metadata) — they don't
|
|
25
|
-
* affect render identity for idempotent navigations.
|
|
26
|
-
*
|
|
27
|
-
* Accepts `null` for compatibility with `RouterTransitionSnapshot`
|
|
28
|
-
* (toRoute/fromRoute are `State | null`).
|
|
29
|
-
*
|
|
30
|
-
* @internal Not exported from package public API.
|
|
31
|
-
*/
|
|
32
|
-
export function stabilizeState<T extends State | null | undefined>(
|
|
33
|
-
prev: T,
|
|
34
|
-
next: T,
|
|
35
|
-
): T {
|
|
36
|
-
if (prev === next) {
|
|
37
|
-
return prev;
|
|
38
|
-
}
|
|
39
|
-
if (prev?.path !== next?.path) {
|
|
40
|
-
return next;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// After the path check, both must be the same non-null State (paths
|
|
44
|
-
// matched, prev !== next reference). Read context.url.hash to detect
|
|
45
|
-
// same-path-different-hash navigation (#532) — render-relevant for
|
|
46
|
-
// tab-style UIs that subscribe via useRoute(). Optional chaining keeps
|
|
47
|
-
// the access null-safe without forbidden non-null assertions.
|
|
48
|
-
if (readContextHash(prev) !== readContextHash(next)) {
|
|
49
|
-
return next;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Explicit reload navigation (#605) — caller asked to bypass dedupe so
|
|
53
|
-
// observers see fresh `state.context` written by `invalidate()`-driven
|
|
54
|
-
// loader re-runs. The path equality above guarantees both prev and next
|
|
55
|
-
// are either non-null with matching paths or both nullish; only the
|
|
56
|
-
// non-null branch can carry a meaningful `transition.reload`.
|
|
57
|
-
if (readReloadFlag(next)) {
|
|
58
|
-
return next;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return prev;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function readReloadFlag(state: State | null | undefined): boolean {
|
|
65
|
-
// Defensive read: `transition` is mandatory in the public State type, but a
|
|
66
|
-
// plugin returning a malformed state (or a future fork) shouldn't crash the
|
|
67
|
-
// stabilizer with a TypeError. We cast to a structurally-loose shape so the
|
|
68
|
-
// optional chain is permitted; the runtime guard preserves dedup (false =
|
|
69
|
-
// not-a-reload) for malformed inputs.
|
|
70
|
-
const transition = (
|
|
71
|
-
state as { transition?: { reload?: boolean } } | null | undefined
|
|
72
|
-
)?.transition;
|
|
73
|
-
|
|
74
|
-
return transition?.reload === true;
|
|
75
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { Params, RouterError, State } from "@real-router/core";
|
|
2
|
-
|
|
3
|
-
export interface RouteSnapshot<P extends Params = Params> {
|
|
4
|
-
route: State<P> | undefined;
|
|
5
|
-
previousRoute: State | undefined;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface RouteNodeSnapshot<P extends Params = Params> {
|
|
9
|
-
route: State<P> | undefined;
|
|
10
|
-
previousRoute: State | undefined;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface RouterSource<T> {
|
|
14
|
-
subscribe: (listener: () => void) => () => void;
|
|
15
|
-
getSnapshot: () => T;
|
|
16
|
-
destroy: () => void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface ActiveRouteSourceOptions {
|
|
20
|
-
strict?: boolean;
|
|
21
|
-
ignoreQueryParams?: boolean;
|
|
22
|
-
/**
|
|
23
|
-
* URL fragment match (#532). When defined, the source is active iff the
|
|
24
|
-
* route matches AND `state.context.url.hash` (decoded, populated by
|
|
25
|
-
* browser/navigation URL plugins) equals this value:
|
|
26
|
-
*
|
|
27
|
-
* - `undefined` (default): hash is ignored — legacy route-only matching.
|
|
28
|
-
* - `""`: active only when the current URL has no fragment (or empty).
|
|
29
|
-
* - `"value"`: active only when the current fragment equals `"value"`.
|
|
30
|
-
*
|
|
31
|
-
* Hash-plugin runtimes leave `state.context.url` undefined, so any non-
|
|
32
|
-
* undefined `hash` option will produce `false` there — consistent with the
|
|
33
|
-
* documented limitation that hash-plugin doesn't support URL fragments.
|
|
34
|
-
*/
|
|
35
|
-
hash?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface RouterTransitionSnapshot {
|
|
39
|
-
isTransitioning: boolean;
|
|
40
|
-
isLeaveApproved: boolean;
|
|
41
|
-
toRoute: State | null;
|
|
42
|
-
fromRoute: State | null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface RouterErrorSnapshot {
|
|
46
|
-
error: RouterError | null;
|
|
47
|
-
toRoute: State | null;
|
|
48
|
-
fromRoute: State | null;
|
|
49
|
-
version: number;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface DismissableErrorSnapshot {
|
|
53
|
-
/** Currently visible error, or `null` if none (never seen or dismissed). */
|
|
54
|
-
error: RouterError | null;
|
|
55
|
-
/** Target route of the failed navigation. */
|
|
56
|
-
toRoute: State | null;
|
|
57
|
-
/** Source route at the time of failure. */
|
|
58
|
-
fromRoute: State | null;
|
|
59
|
-
/** Monotonic version counter from the underlying error source. */
|
|
60
|
-
version: number;
|
|
61
|
-
/** Dismisses the current error. Next error (new version) becomes visible again. */
|
|
62
|
-
resetError: () => void;
|
|
63
|
-
}
|