@symbiote-native/navigation 1.0.0 → 2.0.1

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 (195) hide show
  1. package/README.md +159 -0
  2. package/package.json +14 -12
  3. package/build/angular/drawer/index.d.ts +0 -76
  4. package/build/angular/drawer/index.js +0 -508
  5. package/build/angular/drawer-screen.directive.d.ts +0 -14
  6. package/build/angular/drawer-screen.directive.js +0 -87
  7. package/build/angular/index.d.ts +0 -23
  8. package/build/angular/index.js +0 -22
  9. package/build/angular/injectors/index.d.ts +0 -13
  10. package/build/angular/injectors/index.js +0 -8
  11. package/build/angular/injectors/inject-drawer-navigation.d.ts +0 -4
  12. package/build/angular/injectors/inject-drawer-navigation.js +0 -12
  13. package/build/angular/injectors/inject-focus-effect.d.ts +0 -2
  14. package/build/angular/injectors/inject-focus-effect.js +0 -29
  15. package/build/angular/injectors/inject-is-focused.d.ts +0 -2
  16. package/build/angular/injectors/inject-is-focused.js +0 -20
  17. package/build/angular/injectors/inject-navigation-state.d.ts +0 -3
  18. package/build/angular/injectors/inject-navigation-state.js +0 -35
  19. package/build/angular/injectors/inject-navigation.d.ts +0 -7
  20. package/build/angular/injectors/inject-navigation.js +0 -16
  21. package/build/angular/injectors/inject-route.d.ts +0 -3
  22. package/build/angular/injectors/inject-route.js +0 -20
  23. package/build/angular/injectors/inject-stack-navigation.d.ts +0 -4
  24. package/build/angular/injectors/inject-stack-navigation.js +0 -15
  25. package/build/angular/injectors/inject-tab-navigation.d.ts +0 -4
  26. package/build/angular/injectors/inject-tab-navigation.js +0 -11
  27. package/build/angular/linking.d.ts +0 -3
  28. package/build/angular/linking.js +0 -43
  29. package/build/angular/navigation-context.service.d.ts +0 -13
  30. package/build/angular/navigation-context.service.js +0 -105
  31. package/build/angular/navigation-scope.directive.d.ts +0 -10
  32. package/build/angular/navigation-scope.directive.js +0 -90
  33. package/build/angular/screen.directive.d.ts +0 -22
  34. package/build/angular/screen.directive.js +0 -90
  35. package/build/angular/search-bar-ref.directive.d.ts +0 -10
  36. package/build/angular/search-bar-ref.directive.js +0 -88
  37. package/build/angular/stack/index.d.ts +0 -55
  38. package/build/angular/stack/index.js +0 -386
  39. package/build/angular/tab-screen.directive.d.ts +0 -14
  40. package/build/angular/tab-screen.directive.js +0 -87
  41. package/build/angular/tabs/index.d.ts +0 -42
  42. package/build/angular/tabs/index.js +0 -263
  43. package/build/core/constants.d.ts +0 -27
  44. package/build/core/constants.js +0 -61
  45. package/build/core/drawer-options/index.d.ts +0 -64
  46. package/build/core/drawer-options/index.js +0 -200
  47. package/build/core/drawer-router-state/index.d.ts +0 -21
  48. package/build/core/drawer-router-state/index.js +0 -40
  49. package/build/core/guards.d.ts +0 -2
  50. package/build/core/guards.js +0 -22
  51. package/build/core/header-bar-buttons.d.ts +0 -9
  52. package/build/core/header-bar-buttons.js +0 -163
  53. package/build/core/index.d.ts +0 -29
  54. package/build/core/index.js +0 -32
  55. package/build/core/linking-config/index.d.ts +0 -13
  56. package/build/core/linking-config/index.js +0 -171
  57. package/build/core/navigation-events/index.d.ts +0 -16
  58. package/build/core/navigation-events/index.js +0 -57
  59. package/build/core/navigator-handles/index.d.ts +0 -30
  60. package/build/core/navigator-handles/index.js +0 -15
  61. package/build/core/navigator-props.d.ts +0 -216
  62. package/build/core/navigator-props.js +0 -7
  63. package/build/core/navigator-state/index.d.ts +0 -36
  64. package/build/core/navigator-state/index.js +0 -81
  65. package/build/core/render-drawer.d.ts +0 -13
  66. package/build/core/render-drawer.js +0 -88
  67. package/build/core/render-stack.d.ts +0 -35
  68. package/build/core/render-stack.js +0 -294
  69. package/build/core/render-tabs.d.ts +0 -20
  70. package/build/core/render-tabs.js +0 -97
  71. package/build/core/screen-options.d.ts +0 -4
  72. package/build/core/screen-options.js +0 -133
  73. package/build/core/search-bar-commands.d.ts +0 -10
  74. package/build/core/search-bar-commands.js +0 -42
  75. package/build/core/state-persistence/index.d.ts +0 -3
  76. package/build/core/state-persistence/index.js +0 -23
  77. package/build/core/tab-options.d.ts +0 -13
  78. package/build/core/tab-options.js +0 -10
  79. package/build/core/tab-router-state/index.d.ts +0 -19
  80. package/build/core/tab-router-state/index.js +0 -51
  81. package/build/react/collect-registry.d.ts +0 -4
  82. package/build/react/collect-registry.js +0 -15
  83. package/build/react/drawer/index.d.ts +0 -29
  84. package/build/react/drawer/index.js +0 -277
  85. package/build/react/drawer-screen.d.ts +0 -14
  86. package/build/react/drawer-screen.js +0 -8
  87. package/build/react/hooks/index.d.ts +0 -12
  88. package/build/react/hooks/index.js +0 -8
  89. package/build/react/hooks/use-drawer-navigation.d.ts +0 -4
  90. package/build/react/hooks/use-drawer-navigation.js +0 -12
  91. package/build/react/hooks/use-focus-effect.d.ts +0 -2
  92. package/build/react/hooks/use-focus-effect.js +0 -29
  93. package/build/react/hooks/use-is-focused.d.ts +0 -1
  94. package/build/react/hooks/use-is-focused.js +0 -22
  95. package/build/react/hooks/use-navigation-state/index.d.ts +0 -2
  96. package/build/react/hooks/use-navigation-state/index.js +0 -39
  97. package/build/react/hooks/use-navigation.d.ts +0 -7
  98. package/build/react/hooks/use-navigation.js +0 -16
  99. package/build/react/hooks/use-route.d.ts +0 -2
  100. package/build/react/hooks/use-route.js +0 -8
  101. package/build/react/hooks/use-stack-navigation.d.ts +0 -4
  102. package/build/react/hooks/use-stack-navigation.js +0 -14
  103. package/build/react/hooks/use-tab-navigation.d.ts +0 -4
  104. package/build/react/hooks/use-tab-navigation.js +0 -12
  105. package/build/react/index.d.ts +0 -24
  106. package/build/react/index.js +0 -21
  107. package/build/react/linking.d.ts +0 -3
  108. package/build/react/linking.js +0 -47
  109. package/build/react/navigation-context.d.ts +0 -10
  110. package/build/react/navigation-context.js +0 -22
  111. package/build/react/screen.d.ts +0 -22
  112. package/build/react/screen.js +0 -7
  113. package/build/react/stack/index.d.ts +0 -13
  114. package/build/react/stack/index.js +0 -202
  115. package/build/react/tab-screen.d.ts +0 -15
  116. package/build/react/tab-screen.js +0 -8
  117. package/build/react/tabs/index.d.ts +0 -12
  118. package/build/react/tabs/index.js +0 -116
  119. package/build/register.d.ts +0 -7
  120. package/build/register.js +0 -58
  121. package/build/vue/composables/index.d.ts +0 -12
  122. package/build/vue/composables/index.js +0 -8
  123. package/build/vue/composables/use-drawer-navigation.d.ts +0 -5
  124. package/build/vue/composables/use-drawer-navigation.js +0 -15
  125. package/build/vue/composables/use-focus-effect.d.ts +0 -1
  126. package/build/vue/composables/use-focus-effect.js +0 -31
  127. package/build/vue/composables/use-is-focused.d.ts +0 -2
  128. package/build/vue/composables/use-is-focused.js +0 -28
  129. package/build/vue/composables/use-navigation-state.d.ts +0 -3
  130. package/build/vue/composables/use-navigation-state.js +0 -29
  131. package/build/vue/composables/use-navigation.d.ts +0 -8
  132. package/build/vue/composables/use-navigation.js +0 -13
  133. package/build/vue/composables/use-route.d.ts +0 -3
  134. package/build/vue/composables/use-route.js +0 -9
  135. package/build/vue/composables/use-stack-navigation.d.ts +0 -5
  136. package/build/vue/composables/use-stack-navigation.js +0 -18
  137. package/build/vue/composables/use-tab-navigation.d.ts +0 -5
  138. package/build/vue/composables/use-tab-navigation.js +0 -15
  139. package/build/vue/drawer/index.d.ts +0 -19
  140. package/build/vue/drawer/index.js +0 -390
  141. package/build/vue/drawer-screen.d.ts +0 -14
  142. package/build/vue/drawer-screen.js +0 -12
  143. package/build/vue/index.d.ts +0 -21
  144. package/build/vue/index.js +0 -19
  145. package/build/vue/linking.d.ts +0 -3
  146. package/build/vue/linking.js +0 -57
  147. package/build/vue/navigation-context.d.ts +0 -16
  148. package/build/vue/navigation-context.js +0 -65
  149. package/build/vue/screen.d.ts +0 -21
  150. package/build/vue/screen.js +0 -12
  151. package/build/vue/stack/index.d.ts +0 -9
  152. package/build/vue/stack/index.js +0 -279
  153. package/build/vue/tab-screen.d.ts +0 -14
  154. package/build/vue/tab-screen.js +0 -11
  155. package/build/vue/tabs/index.d.ts +0 -10
  156. package/build/vue/tabs/index.js +0 -209
  157. package/build-ngc/angular/drawer.d.ts +0 -79
  158. package/build-ngc/angular/drawer.js +0 -475
  159. package/build-ngc/angular/drawer.js.map +0 -1
  160. package/build-ngc/angular/stack.d.ts +0 -58
  161. package/build-ngc/angular/stack.js +0 -402
  162. package/build-ngc/angular/stack.js.map +0 -1
  163. package/build-ngc/angular/tabs.d.ts +0 -45
  164. package/build-ngc/angular/tabs.js +0 -231
  165. package/build-ngc/angular/tabs.js.map +0 -1
  166. package/build-ngc/core/drawer-options.d.ts +0 -64
  167. package/build-ngc/core/drawer-options.js +0 -201
  168. package/build-ngc/core/drawer-options.js.map +0 -1
  169. package/build-ngc/core/drawer-router-state.d.ts +0 -21
  170. package/build-ngc/core/drawer-router-state.js +0 -41
  171. package/build-ngc/core/drawer-router-state.js.map +0 -1
  172. package/build-ngc/core/href.d.ts +0 -16
  173. package/build-ngc/core/href.js +0 -55
  174. package/build-ngc/core/href.js.map +0 -1
  175. package/build-ngc/core/linking-config.d.ts +0 -13
  176. package/build-ngc/core/linking-config.js +0 -172
  177. package/build-ngc/core/linking-config.js.map +0 -1
  178. package/build-ngc/core/navigation-events.d.ts +0 -16
  179. package/build-ngc/core/navigation-events.js +0 -58
  180. package/build-ngc/core/navigation-events.js.map +0 -1
  181. package/build-ngc/core/navigator-handles.d.ts +0 -30
  182. package/build-ngc/core/navigator-handles.js +0 -16
  183. package/build-ngc/core/navigator-handles.js.map +0 -1
  184. package/build-ngc/core/navigator-state.d.ts +0 -36
  185. package/build-ngc/core/navigator-state.js +0 -82
  186. package/build-ngc/core/navigator-state.js.map +0 -1
  187. package/build-ngc/core/search-params.d.ts +0 -9
  188. package/build-ngc/core/search-params.js +0 -60
  189. package/build-ngc/core/search-params.js.map +0 -1
  190. package/build-ngc/core/state-persistence.d.ts +0 -3
  191. package/build-ngc/core/state-persistence.js +0 -24
  192. package/build-ngc/core/state-persistence.js.map +0 -1
  193. package/build-ngc/core/tab-router-state.d.ts +0 -19
  194. package/build-ngc/core/tab-router-state.js +0 -52
  195. package/build-ngc/core/tab-router-state.js.map +0 -1
@@ -1,55 +0,0 @@
1
- // Href: the URL-shaped navigation target the web-router facade takes, mirroring Expo Router's
2
- // `Href = string | { pathname, params }` (react-router's `to`, vue-router's `to`). resolveHref
3
- // turns either form into the { name, params } our by-name navigator handle already pushes —
4
- // path params (:id) come from the linking config, query/object params merge on top.
5
- //
6
- // This is why the web facade REQUIRES a linking config: the config IS the route table (name<->path
7
- // map), exactly as react-router/vue-router require a route table before you can navigate by path.
8
- import { resolveRouteFromUrl, resolveUrlFromRoute } from './linking-config';
9
- import { parseSearchParams, splitPathnameQuery, stringifySearchParams } from './search-params';
10
- function isRecord(value) {
11
- return typeof value === 'object' && value !== null && !Array.isArray(value);
12
- }
13
- // Peels either Href form down to a bare pathname plus explicit params: a string href's query
14
- // string is parsed into params, an object href's params are taken as-is. Path params (:id) are
15
- // resolved later against the config, not here.
16
- function normalizeHref(href) {
17
- if (typeof href === 'string') {
18
- const { pathname, query } = splitPathnameQuery(href);
19
- return { pathname, params: parseSearchParams(query) };
20
- }
21
- return { pathname: href.pathname, params: { ...href.params } };
22
- }
23
- // A full-scheme href ('myapp://user/42') is passed through; a bare path ('users/42') gets the
24
- // leading slash resolveRouteFromUrl's non-prefixed branch expects.
25
- function toMatchableUrl(pathname) {
26
- if (pathname.includes('://') || pathname.startsWith('/'))
27
- return pathname;
28
- return `/${pathname}`;
29
- }
30
- export function resolveHref(config, href) {
31
- const { pathname, params } = normalizeHref(href);
32
- const route = resolveRouteFromUrl(config, toMatchableUrl(pathname));
33
- if (route === null)
34
- return null;
35
- const pathParams = isRecord(route.params) ? route.params : {};
36
- const merged = { ...pathParams, ...params };
37
- return {
38
- name: route.name,
39
- params: Object.keys(merged).length > 0 ? merged : undefined,
40
- };
41
- }
42
- // Collapses an Href to its display/serialized string form ('/users/42?tab=posts'), for a <Link>'s
43
- // accessibility value or a usePathname read. A string href is already that; an object href joins
44
- // its pathname with the serialized query.
45
- export function stringifyHref(href) {
46
- if (typeof href === 'string')
47
- return href;
48
- return `${href.pathname}${stringifySearchParams(href.params ?? {})}`;
49
- }
50
- // The reverse direction — a live route back to its URL string — so usePathname/useUnstableGlobalHref
51
- // have one entry point. Thin pass-through to the linking config's route->url fold.
52
- export function hrefFromRoute(config, route) {
53
- return resolveUrlFromRoute(config, route);
54
- }
55
- //# sourceMappingURL=href.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"href.js","sourceRoot":"","sources":["../../src/core/href.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,+FAA+F;AAC/F,4FAA4F;AAC5F,oFAAoF;AACpF,EAAE;AACF,mGAAmG;AACnG,kGAAkG;AAGlG,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAgB/F,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,6FAA6F;AAC7F,+FAA+F;AAC/F,+CAA+C;AAC/C,SAAS,aAAa,CAAC,IAAW;IAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACjE,CAAC;AAED,8FAA8F;AAC9F,mEAAmE;AACnE,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1E,OAAO,IAAI,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAsB,EAAE,IAAW;IAC7D,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpE,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,MAAM,MAAM,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,EAAE,CAAC;IAC5C,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;KAC5D,CAAC;AACJ,CAAC;AAED,kGAAkG;AAClG,iGAAiG;AACjG,0CAA0C;AAC1C,MAAM,UAAU,aAAa,CAAC,IAAW;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,GAAG,IAAI,CAAC,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;AACvE,CAAC;AAED,qGAAqG;AACrG,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,MAAsB,EAAE,KAAsB;IAC1E,OAAO,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC"}
@@ -1,13 +0,0 @@
1
- import type { IRoute } from './navigator-state';
2
- export type IScreenLinkingConfig = string | {
3
- path?: string;
4
- screens?: Record<string, IScreenLinkingConfig>;
5
- };
6
- export type ILinkingConfig = {
7
- prefixes: string[];
8
- config: {
9
- screens: Record<string, IScreenLinkingConfig>;
10
- };
11
- };
12
- export declare function resolveRouteFromUrl(config: ILinkingConfig, url: string): IRoute<unknown> | null;
13
- export declare function resolveUrlFromRoute(config: ILinkingConfig, route: IRoute<unknown>): string | null;
@@ -1,172 +0,0 @@
1
- // Linking config: the piece @react-navigation's `NavigationContainer`'s `linking` prop provides
2
- // on top of the framework-agnostic `Linking` module (core/engine/src/linking) — resolving a URL
3
- // ('myapp://user/42', '/user/42') to a route, and a route back to a URL. This is OUR OWN type,
4
- // not imported from react-navigation, kept close to its shape (`prefixes` + `config.screens`)
5
- // only so the DX is familiar.
6
- //
7
- // Why hand-rolled matching instead of react-router's `matchPath`/`generatePath` (evaluated per
8
- // task): react-router 8's package has no subpath export for the pure `lib/router/utils.ts`
9
- // matcher — its only general entry point (`.`) eagerly imports `./lib/dom/*`
10
- // (BrowserRouter/ScrollRestoration/cookies) and `./lib/server-runtime/*`, code that assumes DOM
11
- // and Node globals a Metro/Hermes RN bundle doesn't have; its `peerDependencies` also pin
12
- // `react-dom`, which this DOM-free monorepo never installs (see CLAUDE.md
13
- // react_native_is_an_explicit_top_level_peer — no foreign runtime singleton gets smuggled in).
14
- // On top of the bundling risk, `matchPath`'s/`generatePath`'s param-name extraction is a
15
- // template-literal-type trick that only fires for a compile-time LITERAL path string; our
16
- // patterns come from a runtime config object (`Path` widens to plain `string`), so the generic
17
- // degrades to an empty params type and using the result would force an `as` cast — forbidden by
18
- // this project's TS conventions. A minimal `:param`-segment matcher sidesteps both problems and
19
- // is the right size for a single flat Stack (no optional/splat segments — no nested-navigator use
20
- // for them yet).
21
- import { dlog } from '@symbiote-native/engine';
22
- import { isRecord } from './guards';
23
- // Strips leading/trailing slashes so segments join predictably regardless of how the caller
24
- // wrote a path ('feed/:sort', '/feed/:sort/', etc).
25
- function normalizeSegment(segment) {
26
- return segment.replace(/^\/+|\/+$/g, '');
27
- }
28
- function joinPath(parent, child) {
29
- const parts = [normalizeSegment(parent), normalizeSegment(child)].filter(part => part.length > 0);
30
- return parts.join('/');
31
- }
32
- // Walks `screens` recursively, accumulating the path down to each LEAF screen. Unlike
33
- // react-navigation (which resolves nested config into nested navigation state), our navigator is
34
- // a single flat Stack — a `screens` group with no `path` of its own is transparent (consumes no
35
- // URL segment); a group WITH a `path` but no nested `screens` is itself a leaf using that path.
36
- function flattenScreens(screens, parentPath, out) {
37
- for (const [name, entry] of Object.entries(screens)) {
38
- if (typeof entry === 'string') {
39
- out.push({ name, pattern: joinPath(parentPath, entry) });
40
- continue;
41
- }
42
- const nextParent = entry.path !== undefined ? joinPath(parentPath, entry.path) : parentPath;
43
- if (entry.screens !== undefined) {
44
- flattenScreens(entry.screens, nextParent, out);
45
- }
46
- else if (entry.path !== undefined) {
47
- out.push({ name, pattern: nextParent });
48
- }
49
- else {
50
- dlog(`linking-config: screen "${name}" has neither a path nor nested screens, skipping`);
51
- }
52
- }
53
- return out;
54
- }
55
- function dynamicSegmentCount(pattern) {
56
- if (pattern.length === 0)
57
- return 0;
58
- return pattern.split('/').filter(segment => segment.startsWith(':')).length;
59
- }
60
- function segmentCount(pattern) {
61
- return pattern.length === 0 ? 0 : pattern.split('/').length;
62
- }
63
- // More static segments should win over a param that would also match (e.g. a literal
64
- // '/user/me' pattern over '/user/:id'), mirroring how react-navigation prefers exact matches.
65
- function bySpecificity(a, b) {
66
- const dynamicDiff = dynamicSegmentCount(a.pattern) - dynamicSegmentCount(b.pattern);
67
- if (dynamicDiff !== 0)
68
- return dynamicDiff;
69
- return segmentCount(b.pattern) - segmentCount(a.pattern);
70
- }
71
- function matchPattern(pattern, pathname) {
72
- const patternSegments = pattern.length === 0 ? [] : pattern.split('/');
73
- const pathSegments = pathname.length === 0 ? [] : pathname.split('/');
74
- if (patternSegments.length !== pathSegments.length)
75
- return null;
76
- const params = {};
77
- for (let index = 0; index < patternSegments.length; index += 1) {
78
- const patternSegment = patternSegments[index];
79
- const pathSegment = pathSegments[index];
80
- if (patternSegment.startsWith(':')) {
81
- params[patternSegment.slice(1)] = decodeURIComponent(pathSegment);
82
- }
83
- else if (patternSegment !== pathSegment) {
84
- return null;
85
- }
86
- }
87
- return params;
88
- }
89
- function stripQueryAndHash(url) {
90
- const match = /[?#]/.exec(url);
91
- return match === null ? url : url.slice(0, match.index);
92
- }
93
- // Resolves a full URL down to the bare path segment string ('user/42', no leading slash) by
94
- // stripping the longest matching configured prefix, falling back to treating the URL as an
95
- // already-bare path when it starts with '/' (the task's second example form). Returns null when
96
- // neither applies — an unrecognized scheme/host, not "no route matched".
97
- function extractPathname(config, url) {
98
- const withoutQuery = stripQueryAndHash(url);
99
- const sortedPrefixes = [...config.prefixes].sort((a, b) => b.length - a.length);
100
- for (const prefix of sortedPrefixes) {
101
- if (withoutQuery.startsWith(prefix)) {
102
- return normalizeSegment(withoutQuery.slice(prefix.length));
103
- }
104
- }
105
- if (withoutQuery.startsWith('/'))
106
- return normalizeSegment(withoutQuery);
107
- return null;
108
- }
109
- export function resolveRouteFromUrl(config, url) {
110
- const pathname = extractPathname(config, url);
111
- if (pathname === null) {
112
- dlog(`linking-config: url "${url}" matched no configured prefix`);
113
- return null;
114
- }
115
- const candidates = flattenScreens(config.config.screens, '', []).sort(bySpecificity);
116
- for (const candidate of candidates) {
117
- const params = matchPattern(candidate.pattern, pathname);
118
- if (params !== null) {
119
- dlog(`linking-config: resolved "${url}" -> ${candidate.name}`);
120
- // `key` is not real route identity here — the navigator mints its own on push/replace
121
- // (stack.ts's createRoute); `name` is a stable enough placeholder to satisfy IRoute's shape.
122
- return {
123
- key: candidate.name,
124
- name: candidate.name,
125
- params: Object.keys(params).length > 0 ? params : undefined,
126
- };
127
- }
128
- }
129
- dlog(`linking-config: url "${url}" (path "${pathname}") matched no configured screen`);
130
- return null;
131
- }
132
- // The inverse of matchPattern: fills a pattern's ':param' segments from `params`, or returns
133
- // null when a required param is missing (mirrors react-router's generatePath throwing, minus the
134
- // throw — a resolver returning null reads more naturally at the call site here).
135
- function fillPattern(pattern, params) {
136
- if (pattern.length === 0)
137
- return '';
138
- const source = isRecord(params) ? params : {};
139
- const segments = [];
140
- for (const segment of pattern.split('/')) {
141
- if (!segment.startsWith(':')) {
142
- segments.push(segment);
143
- continue;
144
- }
145
- const value = source[segment.slice(1)];
146
- if (value === undefined || value === null)
147
- return null;
148
- segments.push(encodeURIComponent(String(value)));
149
- }
150
- return segments.join('/');
151
- }
152
- export function resolveUrlFromRoute(config, route) {
153
- const candidate = flattenScreens(config.config.screens, '', []).find(entry => entry.name === route.name);
154
- if (candidate === undefined) {
155
- dlog(`linking-config: no configured screen for route name "${route.name}"`);
156
- return null;
157
- }
158
- const path = fillPattern(candidate.pattern, route.params);
159
- if (path === null) {
160
- dlog(`linking-config: route "${route.name}" is missing a param required by "${candidate.pattern}"`);
161
- return null;
162
- }
163
- const prefix = config.prefixes[0];
164
- if (prefix === undefined)
165
- return path.length > 0 ? `/${path}` : '/';
166
- // A prefix already carrying its own trailing separator ('myapp://') must not be truncated to
167
- // 'myapp:/' by naively slicing one char off — only add a '/' when the prefix doesn't have one.
168
- if (path.length === 0)
169
- return prefix;
170
- return prefix.endsWith('/') ? `${prefix}${path}` : `${prefix}/${path}`;
171
- }
172
- //# sourceMappingURL=linking-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"linking-config.js","sourceRoot":"","sources":["../../src/core/linking-config.ts"],"names":[],"mappings":"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"}
@@ -1,16 +0,0 @@
1
- export declare const NAVIGATION_EVENT_FOCUS = "focus";
2
- export declare const NAVIGATION_EVENT_BLUR = "blur";
3
- export declare const NAVIGATION_EVENT_STATE = "state";
4
- export declare const NAVIGATION_EVENT_BEFORE_REMOVE = "beforeRemove";
5
- export type INavigationEventName = typeof NAVIGATION_EVENT_FOCUS | typeof NAVIGATION_EVENT_BLUR | typeof NAVIGATION_EVENT_STATE | typeof NAVIGATION_EVENT_BEFORE_REMOVE;
6
- export type INavigationEventListener<TData = unknown> = (data: TData) => void;
7
- export type INavigationEmitter = {
8
- emit: (event: INavigationEventName, data?: unknown) => void;
9
- addListener: (event: INavigationEventName, listener: INavigationEventListener) => () => void;
10
- };
11
- export declare function createNavigationEmitter(): INavigationEmitter;
12
- export type IFocusTransition = {
13
- blurKey?: string;
14
- focusKey?: string;
15
- };
16
- export declare function diffFocusedRoute(prevKey: string | undefined, nextKey: string | undefined): IFocusTransition;
@@ -1,58 +0,0 @@
1
- // The framework-agnostic half of what @react-navigation exposes as `navigation.addListener` /
2
- // `useFocusEffect` / `useIsFocused` / `useNavigationState`: a plain pub/sub emitter, zero React.
3
- // addListener is NOT React-specific there either — React's hooks are thin useEffect wrappers
4
- // around exactly this subscribe/unsubscribe shape (confirmed against the 8.x docs: `const
5
- // unsubscribe = navigation.addListener('focus', cb); return unsubscribe;` inside a bare
6
- // `useEffect`). One emitter per route (created by the adapter, e.g. stack.ts's per-route
7
- // `emitters` map) carries that route's own focus/blur/state lifecycle; every adapter's lifecycle
8
- // hooks subscribe to it, matching this file's single responsibility split from `constants.ts`
9
- // (which only names Fabric view/prop-key strings, not this JS-only event system).
10
- //
11
- // diffFocusedRoute below centralizes the "which route lost focus, which gained it" comparison
12
- // that tabs.ts and drawer.ts independently reimplemented in all three adapters (each watching its
13
- // own router state for the focused index/key changing, then manually emitting BLUR to the old key
14
- // and FOCUS to the new one, plus an initial FOCUS seed on first mount) — the diff is pure and
15
- // identical everywhere; only WHEN to run it differs per framework (a `useEffect` dependency array,
16
- // a Vue `watch`, an idempotent-per-read Angular method), so that half stays adapter-owned.
17
- import { dlog } from '@symbiote-native/engine';
18
- export const NAVIGATION_EVENT_FOCUS = 'focus';
19
- export const NAVIGATION_EVENT_BLUR = 'blur';
20
- export const NAVIGATION_EVENT_STATE = 'state';
21
- export const NAVIGATION_EVENT_BEFORE_REMOVE = 'beforeRemove';
22
- export function createNavigationEmitter() {
23
- const listenersByEvent = new Map();
24
- function addListener(event, listener) {
25
- let listeners = listenersByEvent.get(event);
26
- if (!listeners) {
27
- listeners = new Set();
28
- listenersByEvent.set(event, listeners);
29
- }
30
- listeners.add(listener);
31
- return () => {
32
- listeners?.delete(listener);
33
- };
34
- }
35
- function emit(event, data) {
36
- const listeners = listenersByEvent.get(event);
37
- // Investigation instrumentation (flicker-on-focus bug): every emission, whether or not a
38
- // listener is attached, so the log stream shows if focus/blur ever fires with 0 subscribers
39
- // (a silent no-op) vs racing an actual effect. Kept behind DEBUG, never removed.
40
- dlog(`Navigation emitter: emit "${event}" (${listeners?.size ?? 0} listener(s)) at t=${Date.now()}`);
41
- if (!listeners)
42
- return;
43
- for (const listener of listeners)
44
- listener(data);
45
- }
46
- return { emit, addListener };
47
- }
48
- export function diffFocusedRoute(prevKey, nextKey) {
49
- if (prevKey === nextKey)
50
- return {};
51
- const transition = {};
52
- if (prevKey !== undefined)
53
- transition.blurKey = prevKey;
54
- if (nextKey !== undefined)
55
- transition.focusKey = nextKey;
56
- return transition;
57
- }
58
- //# sourceMappingURL=navigation-events.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigation-events.js","sourceRoot":"","sources":["../../src/core/navigation-events.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,iGAAiG;AACjG,6FAA6F;AAC7F,0FAA0F;AAC1F,wFAAwF;AACxF,yFAAyF;AACzF,iGAAiG;AACjG,8FAA8F;AAC9F,kFAAkF;AAClF,EAAE;AACF,8FAA8F;AAC9F,kGAAkG;AAClG,kGAAkG;AAClG,8FAA8F;AAC9F,mGAAmG;AACnG,2FAA2F;AAE3F,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAE/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAC9C,MAAM,CAAC,MAAM,8BAA8B,GAAG,cAAc,CAAC;AAe7D,MAAM,UAAU,uBAAuB;IACrC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuD,CAAC;IAExF,SAAS,WAAW,CAClB,KAA2B,EAC3B,QAAkC;QAElC,IAAI,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;YACtB,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAExB,OAAO,GAAG,EAAE;YACV,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC;IAED,SAAS,IAAI,CAAC,KAA2B,EAAE,IAAc;QACvD,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9C,yFAAyF;QACzF,4FAA4F;QAC5F,iFAAiF;QACjF,IAAI,CACF,6BAA6B,KAAK,MAAM,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,IAAI,CAAC,GAAG,EAAE,EAAE,CAC/F,CAAC;QACF,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,KAAK,MAAM,QAAQ,IAAI,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAC/B,CAAC;AAeD,MAAM,UAAU,gBAAgB,CAC9B,OAA2B,EAC3B,OAA2B;IAE3B,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,IAAI,OAAO,KAAK,SAAS;QAAE,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IACxD,IAAI,OAAO,KAAK,SAAS;QAAE,UAAU,CAAC,QAAQ,GAAG,OAAO,CAAC;IACzD,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -1,30 +0,0 @@
1
- import type { INavigatorState } from './navigator-state';
2
- import type { IDrawerScreenOptions } from './drawer-options';
3
- export type INavigatorHandle = {
4
- push: (name: string, params?: unknown) => void;
5
- pop: (count?: number) => void;
6
- popToTop: () => void;
7
- popTo: (key: string) => void;
8
- replace: (name: string, params?: unknown) => void;
9
- setParams: (params: unknown, key?: string) => void;
10
- reset: (state: INavigatorState) => void;
11
- canGoBack: () => boolean;
12
- };
13
- export type ITabNavigatorHandle = {
14
- jumpTo: (name: string, params?: unknown) => void;
15
- setParams: (params: unknown, key: string) => void;
16
- };
17
- export type IDrawerNavigatorHandle = {
18
- openDrawer: () => void;
19
- closeDrawer: () => void;
20
- toggleDrawer: () => void;
21
- jumpTo: (name: string) => void;
22
- };
23
- export type IDrawerDescriptorMap = Record<string, {
24
- options: IDrawerScreenOptions;
25
- navigation: IDrawerNavigatorHandle;
26
- }>;
27
- export type IAnyNavigatorHandle = INavigatorHandle | ITabNavigatorHandle | IDrawerNavigatorHandle;
28
- export declare function isStackNavigatorHandle(handle: IAnyNavigatorHandle): handle is INavigatorHandle;
29
- export declare function isDrawerNavigatorHandle(handle: IAnyNavigatorHandle): handle is IDrawerNavigatorHandle;
30
- export declare function isTabNavigatorHandle(handle: IAnyNavigatorHandle): handle is ITabNavigatorHandle;
@@ -1,16 +0,0 @@
1
- // Imperative navigator handles: framework-agnostic (scalars, `unknown`, plain function
2
- // signatures over `INavigatorState`/`IDrawerScreenOptions` — no framework element, ref, or
3
- // children in any field), so each shape is declared once here and every adapter re-exports it
4
- // verbatim (see CLAUDE.md <prop_types_split_agnostic_vs_per_adapter>).
5
- export function isStackNavigatorHandle(handle) {
6
- return 'push' in handle;
7
- }
8
- export function isDrawerNavigatorHandle(handle) {
9
- return 'openDrawer' in handle;
10
- }
11
- // jumpTo exists on both Tab and Drawer handles, so a Tab handle is a jumpTo-having handle that
12
- // isn't a Drawer handle (Drawer's own openDrawer/closeDrawer/toggleDrawer rule it out).
13
- export function isTabNavigatorHandle(handle) {
14
- return 'jumpTo' in handle && !isDrawerNavigatorHandle(handle);
15
- }
16
- //# sourceMappingURL=navigator-handles.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigator-handles.js","sourceRoot":"","sources":["../../src/core/navigator-handles.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,2FAA2F;AAC3F,8FAA8F;AAC9F,uEAAuE;AA6CvE,MAAM,UAAU,sBAAsB,CAAC,MAA2B;IAChE,OAAO,MAAM,IAAI,MAAM,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,MAA2B;IAE3B,OAAO,YAAY,IAAI,MAAM,CAAC;AAChC,CAAC;AAED,+FAA+F;AAC/F,wFAAwF;AACxF,MAAM,UAAU,oBAAoB,CAAC,MAA2B;IAC9D,OAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChE,CAAC"}
@@ -1,36 +0,0 @@
1
- export type IRoute<TParams = undefined> = Readonly<{
2
- key: string;
3
- name: string;
4
- params: TParams;
5
- }>;
6
- type IRouteEntry = IRoute<unknown>;
7
- export type INavigatorState = Readonly<{
8
- routes: readonly IRouteEntry[];
9
- }>;
10
- export type INavigatorAction = {
11
- type: 'push';
12
- route: IRouteEntry;
13
- } | {
14
- type: 'pop';
15
- count?: number;
16
- } | {
17
- type: 'popToTop';
18
- } | {
19
- type: 'popTo';
20
- key: string;
21
- } | {
22
- type: 'replace';
23
- route: IRouteEntry;
24
- } | {
25
- type: 'setParams';
26
- key?: string;
27
- params: unknown;
28
- } | {
29
- type: 'reset';
30
- state: INavigatorState;
31
- };
32
- export declare function createInitialNavigatorState(initialRoute: IRouteEntry): INavigatorState;
33
- export declare function navigatorReducer(state: INavigatorState, action: INavigatorAction): INavigatorState;
34
- export declare function computeActivityState(index: number, routesLength: number): number;
35
- export declare function isTopRoute(index: number, routesLength: number): boolean;
36
- export {};
@@ -1,82 +0,0 @@
1
- // Navigator: the logic half (framework-agnostic, zero render). A pure reducer over a route
2
- // stack — push/pop/popToTop/popTo/replace — mirroring what @react-navigation/native-stack keeps
3
- // in its router, minus the React-specific action-creator/linking machinery. Route identity
4
- // (`key`) is generated by the CALLER (the adapter, via React's useId or an equivalent) — the
5
- // reducer never invents identity itself, so it stays a pure (state, action) => state function.
6
- import { SCREEN_ACTIVITY_STATE_FOCUSED, SCREEN_ACTIVITY_STATE_INACTIVE } from './constants';
7
- import { mergeParams } from './guards';
8
- export function createInitialNavigatorState(initialRoute) {
9
- return { routes: [initialRoute] };
10
- }
11
- // The stack never pops its last route — mirrors the library refusing to pop the initial screen;
12
- // the caller (e.g. a hardware back handler) decides what a pop-at-root means for the host app.
13
- export function navigatorReducer(state, action) {
14
- switch (action.type) {
15
- case 'push':
16
- return { routes: [...state.routes, action.route] };
17
- case 'pop': {
18
- if (state.routes.length <= 1)
19
- return state;
20
- const count = action.count ?? 1;
21
- const nextLength = Math.max(1, state.routes.length - count);
22
- return { routes: state.routes.slice(0, nextLength) };
23
- }
24
- case 'popToTop':
25
- return state.routes.length <= 1 ? state : { routes: state.routes.slice(0, 1) };
26
- case 'popTo': {
27
- const index = state.routes.findIndex(route => route.key === action.key);
28
- if (index === -1)
29
- return state;
30
- return { routes: state.routes.slice(0, index + 1) };
31
- }
32
- case 'replace': {
33
- if (state.routes.length === 0)
34
- return { routes: [action.route] };
35
- return { routes: [...state.routes.slice(0, -1), action.route] };
36
- }
37
- // Mirrors @react-navigation's CommonActions.setParams: merges onto the route matched by
38
- // `key`, defaulting to the focused (top-of-stack) route when omitted — same shape as its
39
- // `source`-defaults-to-focused-route behavior, minus the cross-navigator target routing this
40
- // single-navigator reducer has no need for.
41
- case 'setParams': {
42
- const targetKey = action.key ?? state.routes[state.routes.length - 1]?.key;
43
- if (targetKey === undefined)
44
- return state;
45
- const index = state.routes.findIndex(route => route.key === targetKey);
46
- if (index === -1)
47
- return state;
48
- const target = state.routes[index];
49
- const nextRoute = {
50
- ...target,
51
- params: mergeParams(target.params, action.params),
52
- };
53
- return {
54
- routes: [...state.routes.slice(0, index), nextRoute, ...state.routes.slice(index + 1)],
55
- };
56
- }
57
- // Mirrors @react-navigation's CommonActions.reset / BaseRouter's RESET handler: the payload
58
- // state replaces the current one verbatim, no merge — full rehydration (e.g. restoring a
59
- // persisted stack) is just a reset with the deserialized state as the payload.
60
- case 'reset':
61
- return action.state;
62
- default:
63
- return state;
64
- }
65
- }
66
- // Mirrors @react-navigation/native-stack's actual algorithm (NativeStackView.native.tsx:
67
- // `activityState={isInactive ? 0 : 2}`, where isInactive = index > state.index) — NOT a
68
- // three-way top/one-below/rest split. A route index beyond the focused one only exists for a
69
- // preloaded-but-not-yet-navigated-to screen, a feature this reducer doesn't implement, so the
70
- // focused index is always routesLength - 1 (the last route) and every currently-mounted route is
71
- // FOCUSED. This is required, not just simpler: react-native-screens' native RNSScreen.mm asserts
72
- // an already-mounted NativeStack screen's activityState can never decrease via a plain prop
73
- // update ("activityState can only progress in NativeStack") — since no mounted route's index ever
74
- // exceeds routesLength - 1, this formula never produces a decrease across a push or pop.
75
- export function computeActivityState(index, routesLength) {
76
- const focusedIndex = routesLength - 1;
77
- return index > focusedIndex ? SCREEN_ACTIVITY_STATE_INACTIVE : SCREEN_ACTIVITY_STATE_FOCUSED;
78
- }
79
- export function isTopRoute(index, routesLength) {
80
- return index === routesLength - 1;
81
- }
82
- //# sourceMappingURL=navigator-state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigator-state.js","sourceRoot":"","sources":["../../src/core/navigator-state.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- export type ISearchParamValue = string | number | boolean | (string | number)[];
2
- export type ISearchParams = Record<string, ISearchParamValue | undefined>;
3
- export declare function splitPathnameQuery(url: string): {
4
- pathname: string;
5
- query: string;
6
- };
7
- export declare function parseSearchParams(query: string): Record<string, string | string[]>;
8
- export declare function stringifySearchParams(params: ISearchParams): string;
9
- export declare function segmentsFromPathname(pathname: string): string[];
@@ -1,60 +0,0 @@
1
- // Query-string <-> params for the web-router facade (the URL layer Expo Router / react-router /
2
- // vue-router share). Local vs global search params (Expo's useLocalSearchParams /
3
- // useGlobalSearchParams) read off this same scalar model; the adapters own only the hook wiring.
4
- // Splits a raw href string into its path and its query+hash tail ('/users/42?tab=posts' ->
5
- // { pathname: '/users/42', query: '?tab=posts' }). The linking config matches on the path alone,
6
- // so the query is peeled off here and parsed back into params by the caller.
7
- export function splitPathnameQuery(url) {
8
- const match = /[?#]/.exec(url);
9
- if (match === null)
10
- return { pathname: url, query: '' };
11
- return { pathname: url.slice(0, match.index), query: url.slice(match.index) };
12
- }
13
- // Parses a query string ('?a=1&b=2&b=3', leading '?'/'#' optional) into params, collapsing a
14
- // repeated key into an array ('b' -> ['2', '3']). Values arrive as strings — the URL carries no
15
- // type — so a consumer that wants a number coerces at the read site.
16
- export function parseSearchParams(query) {
17
- const trimmed = query.replace(/^[?#]/, '');
18
- if (trimmed.length === 0)
19
- return {};
20
- const out = {};
21
- for (const pair of trimmed.split('&')) {
22
- if (pair.length === 0)
23
- continue;
24
- const eq = pair.indexOf('=');
25
- const key = decodeURIComponent(eq === -1 ? pair : pair.slice(0, eq));
26
- const value = decodeURIComponent((eq === -1 ? '' : pair.slice(eq + 1)).replace(/\+/g, ' '));
27
- const existing = out[key];
28
- if (existing === undefined)
29
- out[key] = value;
30
- else if (Array.isArray(existing))
31
- existing.push(value);
32
- else
33
- out[key] = [existing, value];
34
- }
35
- return out;
36
- }
37
- // The inverse: params -> '?a=1&b=2&b=3' (empty string when nothing to serialize, so a caller can
38
- // concatenate it onto a pathname unconditionally). Undefined values drop out; arrays repeat the key.
39
- export function stringifySearchParams(params) {
40
- const parts = [];
41
- for (const [key, value] of Object.entries(params)) {
42
- if (value === undefined)
43
- continue;
44
- const encodedKey = encodeURIComponent(key);
45
- if (Array.isArray(value)) {
46
- for (const item of value)
47
- parts.push(`${encodedKey}=${encodeURIComponent(String(item))}`);
48
- }
49
- else {
50
- parts.push(`${encodedKey}=${encodeURIComponent(String(value))}`);
51
- }
52
- }
53
- return parts.length > 0 ? `?${parts.join('&')}` : '';
54
- }
55
- // Splits a pathname into its non-empty segments ('/users/42' -> ['users', '42']), the shape
56
- // Expo's useSegments returns.
57
- export function segmentsFromPathname(pathname) {
58
- return pathname.split('/').filter(segment => segment.length > 0);
59
- }
60
- //# sourceMappingURL=search-params.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-params.js","sourceRoot":"","sources":["../../src/core/search-params.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { INavigatorState } from './navigator-state';
2
- export declare function serializeNavigatorState(state: INavigatorState): unknown;
3
- export declare function deserializeNavigatorState(raw: unknown): INavigatorState;
@@ -1,24 +0,0 @@
1
- // Lightweight state persistence: pure serialize/deserialize for INavigatorState, the primitive
2
- // @react-navigation's `initialState`/`onStateChange` persistence recipe is built on. Routes are
3
- // already `{key, name, params}` — plain data, no functions/refs/class instances — so a JSON-safe
4
- // passthrough is sufficient; no framework wiring lives here yet (that's an adapter-level task).
5
- import { isRecord } from './guards';
6
- // No `'params' in value` check: a route pushed with no params serializes to `{key, name,
7
- // params: undefined}`, and JSON.stringify drops undefined-valued keys — a JSON round trip of a
8
- // perfectly valid route legitimately arrives here without a `params` key at all.
9
- function isRoute(value) {
10
- return isRecord(value) && typeof value.key === 'string' && typeof value.name === 'string';
11
- }
12
- function isNavigatorState(value) {
13
- return isRecord(value) && Array.isArray(value.routes) && value.routes.every(isRoute);
14
- }
15
- export function serializeNavigatorState(state) {
16
- return state;
17
- }
18
- export function deserializeNavigatorState(raw) {
19
- if (!isNavigatorState(raw)) {
20
- throw new Error('deserializeNavigatorState: persisted value is not a valid navigator state');
21
- }
22
- return raw;
23
- }
24
- //# sourceMappingURL=state-persistence.js.map