@rnzeus/atlas 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/README.md +21 -0
  2. package/dist/config/internal.d.ts +1 -0
  3. package/dist/config/internal.js +1 -0
  4. package/dist/config/navigation/index.d.ts +1 -0
  5. package/dist/config/navigation/index.js +1 -0
  6. package/dist/config/navigation/types.d.ts +55 -0
  7. package/dist/config/navigation/types.js +1 -0
  8. package/dist/config/navigation.types.d.ts +25 -0
  9. package/dist/config/navigation.types.js +1 -0
  10. package/dist/hooks/README.md +11 -0
  11. package/dist/hooks/index.d.ts +1 -0
  12. package/dist/hooks/index.js +1 -0
  13. package/dist/hooks/internal.d.ts +1 -0
  14. package/dist/hooks/internal.js +1 -0
  15. package/dist/hooks/use-path-navigation/README.md +66 -0
  16. package/dist/hooks/use-path-navigation/hook.d.ts +119 -0
  17. package/dist/hooks/use-path-navigation/hook.js +52 -0
  18. package/dist/hooks/use-path-navigation/index.d.ts +1 -0
  19. package/dist/hooks/use-path-navigation/index.js +1 -0
  20. package/dist/services/README.md +17 -0
  21. package/dist/services/index.d.ts +4 -0
  22. package/dist/services/index.js +3 -0
  23. package/dist/services/internal.d.ts +1 -0
  24. package/dist/services/internal.js +1 -0
  25. package/dist/services/navigation/README.md +131 -0
  26. package/dist/services/navigation/api.d.ts +5 -0
  27. package/dist/services/navigation/api.js +11 -0
  28. package/dist/services/navigation/chain-builder.d.ts +16 -0
  29. package/dist/services/navigation/chain-builder.js +31 -0
  30. package/dist/services/navigation/index.d.ts +3 -0
  31. package/dist/services/navigation/index.js +3 -0
  32. package/dist/services/navigation/service.d.ts +55 -0
  33. package/dist/services/navigation/service.js +536 -0
  34. package/dist/services/navigation/types.d.ts +13 -0
  35. package/dist/services/navigation/types.js +1 -0
  36. package/dist/services/navigation/zod-adapter.d.ts +22 -0
  37. package/dist/services/navigation/zod-adapter.js +36 -0
  38. package/dist/services/transport/README.md +79 -0
  39. package/dist/services/transport/build-query.d.ts +2 -0
  40. package/dist/services/transport/build-query.js +3 -0
  41. package/dist/services/transport/create-transport-methods.d.ts +8 -0
  42. package/dist/services/transport/create-transport-methods.js +34 -0
  43. package/dist/services/transport/error-exception.d.ts +8 -0
  44. package/dist/services/transport/error-exception.js +16 -0
  45. package/dist/services/transport/index.d.ts +3 -0
  46. package/dist/services/transport/index.js +2 -0
  47. package/dist/services/transport/read-response-body.d.ts +3 -0
  48. package/dist/services/transport/read-response-body.js +27 -0
  49. package/dist/services/transport/service.d.ts +22 -0
  50. package/dist/services/transport/service.js +102 -0
  51. package/dist/services/transport/types.d.ts +4 -0
  52. package/dist/services/transport/types.js +1 -0
  53. package/dist/ui/README.md +17 -0
  54. package/dist/ui/debug-dock/README.md +58 -0
  55. package/dist/ui/debug-dock/debug-dock.d.ts +13 -0
  56. package/dist/ui/debug-dock/debug-dock.js +20 -0
  57. package/dist/ui/debug-dock/index.d.ts +2 -0
  58. package/dist/ui/debug-dock/index.js +1 -0
  59. package/dist/ui/debug-dock/styles.d.ts +8 -0
  60. package/dist/ui/debug-dock/styles.js +25 -0
  61. package/dist/ui/debug-dock/use-debug-dock.d.ts +20 -0
  62. package/dist/ui/debug-dock/use-debug-dock.js +71 -0
  63. package/dist/ui/index.d.ts +2 -0
  64. package/dist/ui/index.js +2 -0
  65. package/dist/ui/toast/README.md +62 -0
  66. package/dist/ui/toast/context.d.ts +7 -0
  67. package/dist/ui/toast/context.js +6 -0
  68. package/dist/ui/toast/index.d.ts +5 -0
  69. package/dist/ui/toast/index.js +2 -0
  70. package/dist/ui/toast/toast-plate/README.md +38 -0
  71. package/dist/ui/toast/toast-plate/index.d.ts +2 -0
  72. package/dist/ui/toast/toast-plate/index.js +1 -0
  73. package/dist/ui/toast/toast-plate/toast-plate.d.ts +9 -0
  74. package/dist/ui/toast/toast-plate/toast-plate.js +11 -0
  75. package/dist/ui/toast/toast-plate/use-toast-plate.d.ts +4 -0
  76. package/dist/ui/toast/toast-plate/use-toast-plate.js +33 -0
  77. package/dist/ui/toast/toast-provider.d.ts +10 -0
  78. package/dist/ui/toast/toast-provider.js +53 -0
  79. package/dist/ui/toast/toast-viewport/README.md +38 -0
  80. package/dist/ui/toast/toast-viewport/index.d.ts +2 -0
  81. package/dist/ui/toast/toast-viewport/index.js +1 -0
  82. package/dist/ui/toast/toast-viewport/styles.d.ts +5 -0
  83. package/dist/ui/toast/toast-viewport/styles.js +10 -0
  84. package/dist/ui/toast/toast-viewport/toast-viewport.d.ts +10 -0
  85. package/dist/ui/toast/toast-viewport/toast-viewport.js +13 -0
  86. package/dist/ui/toast/types.d.ts +25 -0
  87. package/dist/ui/toast/types.js +1 -0
  88. package/dist/ui/toast/use-toast.d.ts +1 -0
  89. package/dist/ui/toast/use-toast.js +5 -0
  90. package/dist/utils/README.md +23 -0
  91. package/dist/utils/create-typography/README.md +71 -0
  92. package/dist/utils/create-typography/helper.d.ts +23 -0
  93. package/dist/utils/create-typography/helper.js +72 -0
  94. package/dist/utils/create-typography/index.d.ts +1 -0
  95. package/dist/utils/create-typography/index.js +1 -0
  96. package/dist/utils/define-route/README.md +50 -0
  97. package/dist/utils/define-route/helper.d.ts +2 -0
  98. package/dist/utils/define-route/helper.js +1 -0
  99. package/dist/utils/define-route/index.d.ts +1 -0
  100. package/dist/utils/define-route/index.js +1 -0
  101. package/dist/utils/display-name/README.md +46 -0
  102. package/dist/utils/display-name/helper.d.ts +2 -0
  103. package/dist/utils/display-name/helper.js +91 -0
  104. package/dist/utils/display-name/index.d.ts +1 -0
  105. package/dist/utils/display-name/index.js +1 -0
  106. package/dist/utils/index.d.ts +3 -0
  107. package/dist/utils/index.js +3 -0
  108. package/dist/utils/internal.d.ts +3 -0
  109. package/dist/utils/internal.js +3 -0
  110. package/package.json +74 -0
package/dist/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # `@rnzeus/atlas`
2
+
3
+ ✨ A shared toolkit of services, utilities, helpers, and hooks.
4
+
5
+ ## Documentation
6
+
7
+ - [`Services`](./services/README.md)
8
+ - [`Hooks`](./hooks/README.md)
9
+ - [`Utilities`](./utils/README.md)
10
+ - [`UI`](./ui/README.md)
11
+
12
+ ## Installation
13
+
14
+ This package has peer dependencies that should be present in your app.
15
+
16
+ Install missing peers:
17
+
18
+ ```sh
19
+ # yarn
20
+ yarn add @react-navigation/native qs
21
+ ```
@@ -0,0 +1 @@
1
+ export * from './navigation';
@@ -0,0 +1 @@
1
+ export * from './navigation';
@@ -0,0 +1 @@
1
+ export * from './types';
@@ -0,0 +1 @@
1
+ export * from './types';
@@ -0,0 +1,55 @@
1
+ import type { LinkingOptions, NavigationContainerRef, ParamListBase } from '@react-navigation/native';
2
+ export type NavigationStrict = boolean;
3
+ export type NavigationErrorCtx = {
4
+ type: 'build';
5
+ route: RouteDef<any, any>;
6
+ input: unknown;
7
+ } | {
8
+ type: 'query';
9
+ route: RouteDef<any, any>;
10
+ input: unknown;
11
+ };
12
+ export type NavigationOnError = (error: Error, ctx: NavigationErrorCtx) => void;
13
+ export type ConfigureNavigationOptions = {
14
+ ref: NavigationContainerRef<ParamListBase>;
15
+ linking: LinkingOptions<ParamListBase>;
16
+ strict?: NavigationStrict;
17
+ onError?: NavigationOnError;
18
+ };
19
+ export type SchemaLike<T> = {
20
+ safeParse: (input: unknown) => {
21
+ success: true;
22
+ data: T;
23
+ } | {
24
+ success: false;
25
+ error: unknown;
26
+ };
27
+ };
28
+ export type RouteDef<P = undefined, Q = undefined> = {
29
+ path: string;
30
+ name: string;
31
+ linking: string;
32
+ key?: string;
33
+ __params?: P;
34
+ __query?: Q;
35
+ paramsSchema?: SchemaLike<P>;
36
+ querySchema?: SchemaLike<Q>;
37
+ };
38
+ export type RouteParams<R> = R extends RouteDef<infer P, any> ? P : never;
39
+ export type RouteQuery<R> = R extends RouteDef<any, infer Q> ? Q : never;
40
+ export type BuiltPath<R extends RouteDef<any, any> = RouteDef<any, any>> = string & {
41
+ readonly __brand: 'BuiltPath';
42
+ readonly __route?: R;
43
+ };
44
+ export type QueryOptions = Partial<{
45
+ encode: boolean;
46
+ nested: 'json';
47
+ debug: boolean;
48
+ /**
49
+ * Keep `null` values in the output query string.
50
+ *
51
+ * When enabled, `null` is serialized as the string `"null"`,
52
+ * which can be safely round-tripped with `JSON.parse`.
53
+ */
54
+ nullable: boolean;
55
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ export type RouteDef<P = undefined, Q = undefined> = {
2
+ path: string;
3
+ name: string;
4
+ linking: string;
5
+ key?: string;
6
+ __params?: P;
7
+ __query?: Q;
8
+ };
9
+ export type RouteParams<R> = R extends RouteDef<infer P, any> ? P : never;
10
+ export type RouteQuery<R> = R extends RouteDef<any, infer Q> ? Q : never;
11
+ export type BuiltPath<R extends RouteDef<any, any> = RouteDef<any, any>> = string & {
12
+ readonly __brand: 'BuiltPath';
13
+ readonly __route?: R;
14
+ };
15
+ export type StrictMode = 'off' | 'warn' | 'throw';
16
+ export type ValidationResult = {
17
+ ok: true;
18
+ } | {
19
+ ok: false;
20
+ message: string;
21
+ };
22
+ export type NavigationValidator = {
23
+ validateBuild?: <R extends RouteDef<any, any>>(route: R, params: unknown) => ValidationResult;
24
+ validateQuery?: <R extends RouteDef<any, any>>(route: R, query: unknown) => ValidationResult;
25
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ # `@rnzeus/atlas/hooks`
2
+
3
+ ← [`@rnzeus/atlas`](../README.md)
4
+
5
+ ## Documentation
6
+
7
+ - **[`use-path-navigation`](./use-path-navigation/README.md)** — navigate by path strings using the Navigation service.
8
+
9
+ ```ts
10
+ import {usePathNavigation} from '@rnzeus/atlas/hooks';
11
+ ```
@@ -0,0 +1 @@
1
+ export { usePathNavigation } from './use-path-navigation';
@@ -0,0 +1 @@
1
+ export { usePathNavigation } from './use-path-navigation';
@@ -0,0 +1 @@
1
+ export * from './use-path-navigation';
@@ -0,0 +1 @@
1
+ export * from './use-path-navigation';
@@ -0,0 +1,66 @@
1
+ # `@rnzeus/atlas/hooks/use-path-navigation`
2
+
3
+ ← [`@rnzeus/atlas/hooks`](../README.md)
4
+
5
+ ## Purpose
6
+
7
+ Navigate using **typed branded paths** from inside React components (React Navigation), powered by the Atlas `Navigation` service.
8
+
9
+ ## Import
10
+
11
+ ```ts
12
+ import {usePathNavigation} from '@rnzeus/atlas/hooks';
13
+ ```
14
+
15
+ ## API (public surface)
16
+
17
+ `usePathNavigation<N extends NavigationProp<ParamListBase>>()` returns:
18
+
19
+ - Navigation (safe, path-based)
20
+ - `navigate(path: BuiltPath): void`
21
+ - `push(path: BuiltPath): void`
22
+ - `replace(path: BuiltPath): void`
23
+ - `popTo(path: BuiltPath): void`
24
+ - `reset(path: BuiltPath): void`
25
+ - `popToTop(): void`
26
+ - `goBack(): void`
27
+ - Builders
28
+ - `build(route, params?)` → `BuiltPath`
29
+ - `query(builtPath, query?, opts?)` → `BuiltPath`
30
+ - `chain(route, params?)` → `ChainBuilder` (fluent `query().navigate()/push()/reset()`)
31
+ - Raw (whitelist from React Navigation)
32
+ - `setParams(...)`
33
+ - `setOptions(...)` (typed based on `N`)
34
+ - `getState?()`, `addListener?()`, `removeListener?()`, `isFocused?()`, `canGoBack?()`, `getParent?()`, `dispatch?()`
35
+
36
+ ## Usage (minimal)
37
+
38
+ ```tsx
39
+ import {usePathNavigation} from '@rnzeus/atlas/hooks';
40
+ import {defineRoute} from '@rnzeus/atlas/utils';
41
+
42
+ export function GoToBooking() {
43
+ const nav = usePathNavigation();
44
+
45
+ const BOOKING = defineRoute()({
46
+ name: 'Booking',
47
+ path: 'non-tabbar/booking/:id',
48
+ linking: 'booking',
49
+ });
50
+
51
+ return <Button title="Go" onPress={() => nav.navigate(nav.build(BOOKING, {id: 42}))} />;
52
+ }
53
+ ```
54
+
55
+ ## Notes
56
+
57
+ - **Requirements**:
58
+ - must be used inside a React Navigation tree (`useNavigation()` must work)
59
+ - `Navigation.linkingConfig` must be configured once at app bootstrap (path parsing depends on it)
60
+ - **How it works**: the hook dispatches actions via local `navigation`, so it does not require a global `navRef`.
61
+ - **Builders**: `build` / `query` / `chain` are built on top of the `Navigation` service. Prefer branded paths (`BuiltPath`) over raw strings.
62
+
63
+ ## Sources
64
+
65
+ - [`hook`](./hook.js)
66
+ - [`index`](./index.js)
@@ -0,0 +1,119 @@
1
+ import type { NavigationProp, ParamListBase } from '@react-navigation/native';
2
+ import type { BuiltPath, QueryOptions, RouteDef, RouteParams, RouteQuery } from '../../config/internal';
3
+ import { ChainBuilder } from '../../services/internal';
4
+ /**
5
+ * N is the navigation type (NavigationProp / NativeStackNavigationProp / etc),
6
+ * so the consumer can pass the "correct" nav type and get the setOptions type.
7
+ */
8
+ declare const usePathNavigation: <N extends NavigationProp<ParamListBase> = NavigationProp<ParamListBase>>() => {
9
+ getState: () => Readonly<{
10
+ key: string;
11
+ index: number;
12
+ routeNames: string[];
13
+ history?: unknown[];
14
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
15
+ type: string;
16
+ stale: false;
17
+ }>;
18
+ addListener: <EventName extends keyof import("@react-navigation/core").EventMapCore<Readonly<{
19
+ key: string;
20
+ index: number;
21
+ routeNames: string[];
22
+ history?: unknown[];
23
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
24
+ type: string;
25
+ stale: false;
26
+ }>>>(type: EventName, callback: import("@react-navigation/core").EventListenerCallback<import("@react-navigation/core").EventMapCore<Readonly<{
27
+ key: string;
28
+ index: number;
29
+ routeNames: string[];
30
+ history?: unknown[];
31
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
32
+ type: string;
33
+ stale: false;
34
+ }>>, EventName, import("@react-navigation/core").EventMapCore<Readonly<{
35
+ key: string;
36
+ index: number;
37
+ routeNames: string[];
38
+ history?: unknown[];
39
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
40
+ type: string;
41
+ stale: false;
42
+ }>>[EventName]["canPreventDefault"]>) => () => void;
43
+ removeListener: <EventName extends keyof import("@react-navigation/core").EventMapCore<Readonly<{
44
+ key: string;
45
+ index: number;
46
+ routeNames: string[];
47
+ history?: unknown[];
48
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
49
+ type: string;
50
+ stale: false;
51
+ }>>>(type: EventName, callback: import("@react-navigation/core").EventListenerCallback<import("@react-navigation/core").EventMapCore<Readonly<{
52
+ key: string;
53
+ index: number;
54
+ routeNames: string[];
55
+ history?: unknown[];
56
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
57
+ type: string;
58
+ stale: false;
59
+ }>>, EventName, import("@react-navigation/core").EventMapCore<Readonly<{
60
+ key: string;
61
+ index: number;
62
+ routeNames: string[];
63
+ history?: unknown[];
64
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
65
+ type: string;
66
+ stale: false;
67
+ }>>[EventName]["canPreventDefault"]>) => void;
68
+ isFocused: () => boolean;
69
+ canGoBack: () => boolean;
70
+ getParent: <T = NavigationProp<ParamListBase, string, string | undefined, Readonly<{
71
+ key: string;
72
+ index: number;
73
+ routeNames: string[];
74
+ history?: unknown[];
75
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
76
+ type: string;
77
+ stale: false;
78
+ }>, {}, {}> | undefined>(id?: string | undefined) => T;
79
+ dispatch: (action: Readonly<{
80
+ type: string;
81
+ payload?: object;
82
+ source?: string;
83
+ target?: string;
84
+ }> | ((state: Readonly<Readonly<{
85
+ key: string;
86
+ index: number;
87
+ routeNames: string[];
88
+ history?: unknown[];
89
+ routes: import("@react-navigation/routers").NavigationRoute<ParamListBase, string>[];
90
+ type: string;
91
+ stale: false;
92
+ }>>) => Readonly<{
93
+ type: string;
94
+ payload?: object;
95
+ source?: string;
96
+ target?: string;
97
+ }>)) => void;
98
+ setParams: N["setParams"];
99
+ replaceParams: N["replaceParams"];
100
+ setOptions: N extends {
101
+ setOptions: infer F;
102
+ } ? F : never;
103
+ navigate: (path: BuiltPath) => void;
104
+ push: (path: BuiltPath) => void;
105
+ replace: (path: BuiltPath) => void;
106
+ popTo: (path: BuiltPath) => void;
107
+ reset: (path: BuiltPath) => void;
108
+ popToTop: () => void;
109
+ goBack: () => void;
110
+ build: <R extends RouteDef<any, any>>(route: R, ...args: RouteParams<R> extends undefined ? [] : [params: RouteParams<R>]) => BuiltPath<R>;
111
+ query: {
112
+ <R extends RouteDef<any, undefined>>(url: BuiltPath<R>): BuiltPath<R>;
113
+ <R extends RouteDef<any, undefined>>(url: BuiltPath<R>, q: undefined, opts?: QueryOptions): BuiltPath<R>;
114
+ <R extends RouteDef<any, any>>(url: BuiltPath<R>, q: RouteQuery<R>, opts?: QueryOptions): BuiltPath<R>;
115
+ <R extends RouteDef<any, any>>(url: BuiltPath<R>, q?: RouteQuery<R>, opts?: QueryOptions): BuiltPath<R>;
116
+ };
117
+ chain: <R extends RouteDef<any, any>>(route: R, ...args: RouteParams<R> extends undefined ? [] : [params: RouteParams<R>]) => ChainBuilder<R>;
118
+ };
119
+ export default usePathNavigation;
@@ -0,0 +1,52 @@
1
+ import { useNavigation } from '@react-navigation/native';
2
+ import { ChainBuilder, Navigation } from '../../services/internal';
3
+ /**
4
+ * N is the navigation type (NavigationProp / NativeStackNavigationProp / etc),
5
+ * so the consumer can pass the "correct" nav type and get the setOptions type.
6
+ */
7
+ const usePathNavigation = () => {
8
+ const navigation = useNavigation();
9
+ const build = (route, ...args) => {
10
+ if (args.length === 0)
11
+ return Navigation.build(route);
12
+ return Navigation.build(route, args[0]);
13
+ };
14
+ const query = ((url, q, opts) => Navigation.query(url, q, opts));
15
+ // chaining
16
+ const chain = (route, ...args) => {
17
+ const base = build(route, ...args);
18
+ return new ChainBuilder(base, navigation, query);
19
+ };
20
+ const raw = {
21
+ // state + events
22
+ getState: navigation.getState?.bind(navigation),
23
+ addListener: navigation.addListener?.bind(navigation),
24
+ removeListener: navigation.removeListener?.bind(navigation),
25
+ isFocused: navigation.isFocused?.bind(navigation),
26
+ canGoBack: navigation.canGoBack?.bind(navigation),
27
+ getParent: navigation.getParent?.bind(navigation),
28
+ // advanced
29
+ dispatch: navigation.dispatch?.bind(navigation),
30
+ // params/options (type depends on N)
31
+ setParams: navigation.setParams?.bind(navigation),
32
+ replaceParams: navigation.replaceParams?.bind(navigation),
33
+ setOptions: navigation.setOptions?.bind(navigation),
34
+ };
35
+ return {
36
+ // navigation (safe, path-based)
37
+ navigate: (path) => Navigation.navigate(path, navigation),
38
+ push: (path) => Navigation.push(path),
39
+ replace: (path) => Navigation.replace(path),
40
+ popTo: (path) => Navigation.popTo(path, navigation),
41
+ reset: (path) => Navigation.reset(path),
42
+ popToTop: () => Navigation.popToTop(navigation),
43
+ goBack: () => Navigation.goBack(),
44
+ // builders
45
+ build,
46
+ query,
47
+ chain,
48
+ // raw (whitelist)
49
+ ...raw,
50
+ };
51
+ };
52
+ export default usePathNavigation;
@@ -0,0 +1 @@
1
+ export { default as usePathNavigation } from './hook';
@@ -0,0 +1 @@
1
+ export { default as usePathNavigation } from './hook';
@@ -0,0 +1,17 @@
1
+ # `@rnzeus/atlas/services`
2
+
3
+ ← [`@rnzeus/atlas`](../README.md)
4
+
5
+ ## Documentation
6
+
7
+ - **[`Transport`](./transport/README.md)** — a base `fetch` transport with query params, default headers, error normalization, and `get/post/put/delete`. Instantiate with base URL and defaults, then call verb methods from modules that own API paths.
8
+
9
+ ```ts
10
+ import {Transport} from '@rnzeus/atlas/services';
11
+ ```
12
+
13
+ - **[`Navigation`](./navigation/README.md)** — programmatic path-based navigation on top of React Navigation (navigate/push/replace/popTo/reset + URL helpers). Call `configureNavigation()` once with a ref and linking config, then use `Navigation` (or `usePathNavigation`) with `defineRoute()` and `BuiltPath` for type-safe paths.
14
+
15
+ ```ts
16
+ import {Navigation, configureNavigation} from '@rnzeus/atlas/services';
17
+ ```
@@ -0,0 +1,4 @@
1
+ export { Navigation } from './navigation';
2
+ export { configureNavigation } from './navigation';
3
+ export type { TransportOptions } from './transport';
4
+ export { Transport, TransportErrorException } from './transport';
@@ -0,0 +1,3 @@
1
+ export { Navigation } from './navigation';
2
+ export { configureNavigation } from './navigation';
3
+ export { Transport, TransportErrorException } from './transport';
@@ -0,0 +1 @@
1
+ export * from './navigation';
@@ -0,0 +1 @@
1
+ export * from './navigation';
@@ -0,0 +1,131 @@
1
+ # `@rnzeus/atlas/services/navigation`
2
+
3
+ ← [`@rnzeus/atlas/services`](../README.md)
4
+
5
+ ## Purpose
6
+
7
+ Programmatic path-based navigation on top of React Navigation. Supports nested stacks, safe `popTo()` behavior, **branded typed paths** (`BuiltPath`), and optional runtime validation (schema-based, e.g. Zod).
8
+
9
+ ## Import
10
+
11
+ ```ts
12
+ import {Navigation, configureNavigation} from '@rnzeus/atlas/services';
13
+ ```
14
+
15
+ ## API (public surface)
16
+
17
+ - Configuration (required for path parsing)
18
+ - `Navigation.linkingConfig = linking`
19
+ - Optional (required for “global” navigation outside React tree)
20
+ - `Navigation.navRef = navRef`
21
+ - Convenience configuration
22
+ - `configureNavigation({ ref, linking, strict?, onError? })`
23
+ - Navigation actions
24
+ - **Safe (preferred)**:
25
+ - `navigate(path: BuiltPath, navigation?)`
26
+ - `push(path: BuiltPath, navigation?)`
27
+ - `replace(path: BuiltPath, navigation?)`
28
+ - `popTo(path: BuiltPath, navigation?)`
29
+ - `reset(path: BuiltPath)`
30
+ - **Unsafe (strings)**:
31
+ - `navigateUnsafe(path: string, navigation?)`
32
+ - `pushUnsafe(path: string, navigation?)`
33
+ - `replaceUnsafe(path: string, navigation?)`
34
+ - `popToUnsafe(path: string, navigation?)`
35
+ - `resetUnsafe(path: string)`
36
+ - `popToTop(navigation?)`
37
+ - `goBack()`
38
+ - Helpers
39
+ - `getCurrentPath()`
40
+ - `build(route, params?)` → `BuiltPath`
41
+ - `query(url: BuiltPath, query?, opts?)` → `BuiltPath` (see `QueryOptions`)
42
+
43
+ ## Usage (minimal)
44
+
45
+ ```ts
46
+ import {Navigation, configureNavigation} from '@rnzeus/atlas/services';
47
+ import {defineRoute} from '@rnzeus/atlas/utils';
48
+
49
+ // Configure once at app bootstrap (must include full nesting config).
50
+ configureNavigation({ref: navRef, linking, strict: false});
51
+
52
+ const BOOKING = defineRoute<{id: number}, {step?: string}>()({
53
+ name: 'Booking',
54
+ path: 'non-tabbar/booking/:id',
55
+ linking: 'booking',
56
+ });
57
+
58
+ const url = Navigation.query(Navigation.build(BOOKING, {id: 42}), {step: 'seats'});
59
+ Navigation.navigate(url);
60
+ ```
61
+
62
+ ## Usage (optional validation: Zod)
63
+
64
+ ```ts
65
+ import {Navigation} from '@rnzeus/atlas/services';
66
+ import {defineRoute} from '@rnzeus/atlas/utils';
67
+ import {z} from 'zod';
68
+
69
+ const SCHEDULE_DETAIL = defineRoute<{id: string}>()({
70
+ name: 'ScheduleDetail',
71
+ path: 'schedule/:id',
72
+ linking: 'schedule-detail',
73
+ paramsSchema: z.object({id: z.string().min(1)}),
74
+ });
75
+
76
+ const SCHEDULE_LIST = defineRoute<undefined, {direction: 'inbound' | 'outbound'}>()({
77
+ name: 'ScheduleList',
78
+ path: 'schedule',
79
+ linking: 'schedule-list',
80
+ querySchema: z.object({direction: z.enum(['inbound', 'outbound'])}),
81
+ });
82
+
83
+ // strict=true is recommended only for development/test.
84
+ // In production builds prefer strict=false and report via onError.
85
+ Navigation.strict = true;
86
+ Navigation.onError = (error, ctx) => {
87
+ // send to your logger/sentry and decide how to handle it
88
+ };
89
+
90
+ const url = Navigation.query(Navigation.build(SCHEDULE_LIST), {direction: 'inbound'});
91
+ Navigation.navigate(url);
92
+ ```
93
+
94
+ Then, inside the target screen/component you can access the parsed values via React Navigation `route.params`:
95
+
96
+ ```tsx
97
+ import {useRoute} from '@react-navigation/native';
98
+
99
+ export function BookingScreen() {
100
+ const route = useRoute<any>();
101
+ const id = route.params?.id;
102
+ const step = route.params?.step;
103
+
104
+ return null;
105
+ }
106
+ ```
107
+
108
+ ## Notes
109
+
110
+ - **Linking is required**: all path-based methods rely on `linking.config` to parse a path into navigation state.
111
+ - **Inside vs outside React tree**:
112
+ - if you pass a `navigation` object (local navigation), `navRef` is not required
113
+ - if you do not pass `navigation`, `navRef` must be set and ready
114
+ - **`popTo(path)` behavior**: tries to pop within the current stack when possible, otherwise navigates to the nearest existing parent and then to the leaf.
115
+ - **URL helpers**:
116
+ - `build(route, params?)` replaces `:param` tokens in `route.path` and returns a **branded** `BuiltPath` tied to the route definition.
117
+ - `query(builtPath, query)` merges with existing query and drops empty values; returns `BuiltPath` again.
118
+ - `QueryOptions`: `{ encode?: boolean; nested?: 'json'; debug?: boolean; nullable?: boolean }`
119
+ - **Validation (optional)**:
120
+ - By default, the service validates using `route.paramsSchema` / `route.querySchema` if present (any schema with `safeParse()`).
121
+ - Validation is invoked inside `build()` and `query()` (when a route can be recovered from the branded `BuiltPath`).
122
+ - In **strict mode** (`strict=true`) validation failures throw; in non-strict mode they only call `onError` and log warnings.
123
+ - **Errors**: navigation methods do not throw for missing `linking`/`navRef` (they log warnings). Validation errors throw only when `strict=true`.
124
+
125
+ ## Sources
126
+
127
+ - [`service`](./service.js)
128
+ - [`api`](./api.js)
129
+ - [`chain-builder`](./chain-builder.js)
130
+ - [`types`](./types.js)
131
+ - [`index`](./index.js)
@@ -0,0 +1,5 @@
1
+ import type { ConfigureNavigationOptions } from '../../config/internal';
2
+ /**
3
+ * Configure the global Navigation service.
4
+ */
5
+ export default function configureNavigation({ ref, linking, strict, onError }: ConfigureNavigationOptions): void;
@@ -0,0 +1,11 @@
1
+ import Navigation from './service';
2
+ /**
3
+ * Configure the global Navigation service.
4
+ */
5
+ export default function configureNavigation({ ref, linking, strict = false, onError }) {
6
+ Navigation.navRef = ref;
7
+ Navigation.linkingConfig = linking;
8
+ Navigation.strict = strict;
9
+ if (onError)
10
+ Navigation.onError = onError;
11
+ }
@@ -0,0 +1,16 @@
1
+ import type { NavigationProp } from '@react-navigation/native';
2
+ import type { BuiltPath, QueryOptions, RouteDef, RouteQuery } from '../../config/internal';
3
+ declare class ChainBuilder<R extends RouteDef<any, any>> {
4
+ private path;
5
+ private navigation;
6
+ private queryFn;
7
+ constructor(path: BuiltPath<R>, navigation: NavigationProp<any>, queryFn: <RR extends RouteDef<any, any>>(url: BuiltPath<RR>, q?: any, opts?: QueryOptions) => BuiltPath<RR>);
8
+ query(...args: RouteQuery<R> extends undefined ? [q?: undefined, opts?: QueryOptions] : [q: RouteQuery<R>, opts?: QueryOptions]): this;
9
+ value(): BuiltPath<R>;
10
+ navigate(): void;
11
+ push(): void;
12
+ replace(): void;
13
+ popTo(): void;
14
+ reset(): void;
15
+ }
16
+ export default ChainBuilder;
@@ -0,0 +1,31 @@
1
+ import Navigation from './service';
2
+ class ChainBuilder {
3
+ constructor(path, navigation, queryFn) {
4
+ this.path = path;
5
+ this.navigation = navigation;
6
+ this.queryFn = queryFn;
7
+ }
8
+ query(...args) {
9
+ this.path = this.queryFn(this.path, args[0], args[1]);
10
+ return this;
11
+ }
12
+ value() {
13
+ return this.path;
14
+ }
15
+ navigate() {
16
+ Navigation.navigate(this.path, this.navigation);
17
+ }
18
+ push() {
19
+ Navigation.push(this.path);
20
+ }
21
+ replace() {
22
+ Navigation.replace(this.path);
23
+ }
24
+ popTo() {
25
+ Navigation.popTo(this.path, this.navigation);
26
+ }
27
+ reset() {
28
+ Navigation.reset(this.path);
29
+ }
30
+ }
31
+ export default ChainBuilder;
@@ -0,0 +1,3 @@
1
+ export { default as configureNavigation } from './api';
2
+ export { default as ChainBuilder } from './chain-builder';
3
+ export { default as Navigation } from './service';
@@ -0,0 +1,3 @@
1
+ export { default as configureNavigation } from './api';
2
+ export { default as ChainBuilder } from './chain-builder';
3
+ export { default as Navigation } from './service';