@equinor/fusion-framework-plugin-context-navigation 0.1.0 → 0.1.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 (218) hide show
  1. package/dist/esm/ContextNavigationConfigurator.js +178 -0
  2. package/dist/esm/ContextNavigationConfigurator.js.map +1 -0
  3. package/dist/esm/__tests__/active-app-navigation-events.test.js +115 -0
  4. package/dist/esm/__tests__/active-app-navigation-events.test.js.map +1 -0
  5. package/dist/esm/__tests__/apply-navigation.test.js +152 -0
  6. package/dist/esm/__tests__/apply-navigation.test.js.map +1 -0
  7. package/dist/esm/__tests__/enable.test.js +91 -0
  8. package/dist/esm/__tests__/enable.test.js.map +1 -0
  9. package/dist/esm/__tests__/guard-handlers.test.js +82 -0
  10. package/dist/esm/__tests__/guard-handlers.test.js.map +1 -0
  11. package/dist/esm/__tests__/plugin.test.js +483 -0
  12. package/dist/esm/__tests__/plugin.test.js.map +1 -0
  13. package/dist/esm/__tests__/reconcile.test.js +164 -0
  14. package/dist/esm/__tests__/reconcile.test.js.map +1 -0
  15. package/dist/esm/adapters/create-path-adapter.js +92 -0
  16. package/dist/esm/adapters/create-path-adapter.js.map +1 -0
  17. package/dist/esm/adapters/create-query-adapter.js +83 -0
  18. package/dist/esm/adapters/create-query-adapter.js.map +1 -0
  19. package/dist/esm/adapters/custom-adapter/create-custom-adapter.js +116 -0
  20. package/dist/esm/adapters/custom-adapter/create-custom-adapter.js.map +1 -0
  21. package/dist/esm/adapters/custom-adapter/index.js +5 -0
  22. package/dist/esm/adapters/custom-adapter/index.js.map +1 -0
  23. package/dist/esm/adapters/custom-adapter/normalize-string-result.js +37 -0
  24. package/dist/esm/adapters/custom-adapter/normalize-string-result.js.map +1 -0
  25. package/dist/esm/adapters/custom-adapter/to-app-relative.js +34 -0
  26. package/dist/esm/adapters/custom-adapter/to-app-relative.js.map +1 -0
  27. package/dist/esm/adapters/custom-adapter/to-full-path.js +28 -0
  28. package/dist/esm/adapters/custom-adapter/to-full-path.js.map +1 -0
  29. package/dist/esm/adapters/index.js +4 -0
  30. package/dist/esm/adapters/index.js.map +1 -0
  31. package/dist/esm/adapters/types.js +2 -0
  32. package/dist/esm/adapters/types.js.map +1 -0
  33. package/dist/esm/apply-navigation.js +102 -0
  34. package/dist/esm/apply-navigation.js.map +1 -0
  35. package/dist/esm/constants/context-query-param-key.js +8 -0
  36. package/dist/esm/constants/context-query-param-key.js.map +1 -0
  37. package/dist/esm/constants/index.js +3 -0
  38. package/dist/esm/constants/index.js.map +1 -0
  39. package/dist/esm/constants/uuid-pattern.js +8 -0
  40. package/dist/esm/constants/uuid-pattern.js.map +1 -0
  41. package/dist/esm/create-context-navigation-plugin.js +124 -0
  42. package/dist/esm/create-context-navigation-plugin.js.map +1 -0
  43. package/dist/esm/enable-context-navigation.js +40 -0
  44. package/dist/esm/enable-context-navigation.js.map +1 -0
  45. package/dist/esm/events.js +2 -0
  46. package/dist/esm/events.js.map +1 -0
  47. package/dist/esm/guard-handlers/consume-own-nav-token.js +29 -0
  48. package/dist/esm/guard-handlers/consume-own-nav-token.js.map +1 -0
  49. package/dist/esm/guard-handlers/guard-tick-deps.js +2 -0
  50. package/dist/esm/guard-handlers/guard-tick-deps.js.map +1 -0
  51. package/dist/esm/guard-handlers/guard-tick-payload.js +2 -0
  52. package/dist/esm/guard-handlers/guard-tick-payload.js.map +1 -0
  53. package/dist/esm/guard-handlers/handle-push-mode-guard.js +44 -0
  54. package/dist/esm/guard-handlers/handle-push-mode-guard.js.map +1 -0
  55. package/dist/esm/guard-handlers/handle-replace-mode-guard.js +40 -0
  56. package/dist/esm/guard-handlers/handle-replace-mode-guard.js.map +1 -0
  57. package/dist/esm/guard-handlers/index.js +5 -0
  58. package/dist/esm/guard-handlers/index.js.map +1 -0
  59. package/dist/esm/guard-handlers/is-in-app-scope.js +19 -0
  60. package/dist/esm/guard-handlers/is-in-app-scope.js.map +1 -0
  61. package/dist/esm/helpers/get-current-url.js +11 -0
  62. package/dist/esm/helpers/get-current-url.js.map +1 -0
  63. package/dist/esm/helpers/index.js +6 -0
  64. package/dist/esm/helpers/index.js.map +1 -0
  65. package/dist/esm/helpers/normalize-path-from-url.js +14 -0
  66. package/dist/esm/helpers/normalize-path-from-url.js.map +1 -0
  67. package/dist/esm/helpers/normalize-path.js +30 -0
  68. package/dist/esm/helpers/normalize-path.js.map +1 -0
  69. package/dist/esm/helpers/resolve-adapter.js +23 -0
  70. package/dist/esm/helpers/resolve-adapter.js.map +1 -0
  71. package/dist/esm/helpers/strip-query-params.js +14 -0
  72. package/dist/esm/helpers/strip-query-params.js.map +1 -0
  73. package/dist/esm/index.js +13 -0
  74. package/dist/esm/index.js.map +1 -0
  75. package/dist/esm/operators/active-app-navigation-events.js +52 -0
  76. package/dist/esm/operators/active-app-navigation-events.js.map +1 -0
  77. package/dist/esm/reconcile.js +76 -0
  78. package/dist/esm/reconcile.js.map +1 -0
  79. package/dist/esm/sources/app-first-source.js +41 -0
  80. package/dist/esm/sources/app-first-source.js.map +1 -0
  81. package/dist/esm/sources/context-first-source.js +47 -0
  82. package/dist/esm/sources/context-first-source.js.map +1 -0
  83. package/dist/esm/sources/index.js +4 -0
  84. package/dist/esm/sources/index.js.map +1 -0
  85. package/dist/esm/sources/types.js +16 -0
  86. package/dist/esm/sources/types.js.map +1 -0
  87. package/dist/esm/types.js +2 -0
  88. package/dist/esm/types.js.map +1 -0
  89. package/dist/esm/utils/has-custom-context-generators.js +14 -0
  90. package/dist/esm/utils/has-custom-context-generators.js.map +1 -0
  91. package/dist/esm/utils/legacy-app-navigation-fix.js +45 -0
  92. package/dist/esm/utils/legacy-app-navigation-fix.js.map +1 -0
  93. package/dist/esm/utils/resolve-context-from-url.js +37 -0
  94. package/dist/esm/utils/resolve-context-from-url.js.map +1 -0
  95. package/dist/esm/utils/url/build-app-route.js +20 -0
  96. package/dist/esm/utils/url/build-app-route.js.map +1 -0
  97. package/dist/esm/utils/url/build-context-url-for-strategy.js +43 -0
  98. package/dist/esm/utils/url/build-context-url-for-strategy.js.map +1 -0
  99. package/dist/esm/utils/url/index.js +7 -0
  100. package/dist/esm/utils/url/index.js.map +1 -0
  101. package/dist/esm/utils/url/parse-app-route.js +47 -0
  102. package/dist/esm/utils/url/parse-app-route.js.map +1 -0
  103. package/dist/esm/utils/url/resolve-context-id-from-url.js +29 -0
  104. package/dist/esm/utils/url/resolve-context-id-from-url.js.map +1 -0
  105. package/dist/esm/utils/url/strip-context-query-param.js +20 -0
  106. package/dist/esm/utils/url/strip-context-query-param.js.map +1 -0
  107. package/dist/esm/version.js +3 -0
  108. package/dist/esm/version.js.map +1 -0
  109. package/dist/tsconfig.tsbuildinfo +1 -0
  110. package/dist/types/ContextNavigationConfigurator.d.ts +125 -0
  111. package/dist/types/ContextNavigationConfigurator.d.ts.map +1 -0
  112. package/dist/types/__tests__/active-app-navigation-events.test.d.ts +2 -0
  113. package/dist/types/__tests__/active-app-navigation-events.test.d.ts.map +1 -0
  114. package/dist/types/__tests__/apply-navigation.test.d.ts +2 -0
  115. package/dist/types/__tests__/apply-navigation.test.d.ts.map +1 -0
  116. package/dist/types/__tests__/enable.test.d.ts +2 -0
  117. package/dist/types/__tests__/enable.test.d.ts.map +1 -0
  118. package/dist/types/__tests__/guard-handlers.test.d.ts +2 -0
  119. package/dist/types/__tests__/guard-handlers.test.d.ts.map +1 -0
  120. package/dist/types/__tests__/plugin.test.d.ts +2 -0
  121. package/dist/types/__tests__/plugin.test.d.ts.map +1 -0
  122. package/dist/types/__tests__/reconcile.test.d.ts +2 -0
  123. package/dist/types/__tests__/reconcile.test.d.ts.map +1 -0
  124. package/dist/types/adapters/create-path-adapter.d.ts +27 -0
  125. package/dist/types/adapters/create-path-adapter.d.ts.map +1 -0
  126. package/dist/types/adapters/create-query-adapter.d.ts +34 -0
  127. package/dist/types/adapters/create-query-adapter.d.ts.map +1 -0
  128. package/dist/types/adapters/custom-adapter/create-custom-adapter.d.ts +29 -0
  129. package/dist/types/adapters/custom-adapter/create-custom-adapter.d.ts.map +1 -0
  130. package/dist/types/adapters/custom-adapter/index.d.ts +5 -0
  131. package/dist/types/adapters/custom-adapter/index.d.ts.map +1 -0
  132. package/dist/types/adapters/custom-adapter/normalize-string-result.d.ts +21 -0
  133. package/dist/types/adapters/custom-adapter/normalize-string-result.d.ts.map +1 -0
  134. package/dist/types/adapters/custom-adapter/to-app-relative.d.ts +25 -0
  135. package/dist/types/adapters/custom-adapter/to-app-relative.d.ts.map +1 -0
  136. package/dist/types/adapters/custom-adapter/to-full-path.d.ts +22 -0
  137. package/dist/types/adapters/custom-adapter/to-full-path.d.ts.map +1 -0
  138. package/dist/types/adapters/index.d.ts +5 -0
  139. package/dist/types/adapters/index.d.ts.map +1 -0
  140. package/dist/types/adapters/types.d.ts +73 -0
  141. package/dist/types/adapters/types.d.ts.map +1 -0
  142. package/dist/types/apply-navigation.d.ts +88 -0
  143. package/dist/types/apply-navigation.d.ts.map +1 -0
  144. package/dist/types/constants/context-query-param-key.d.ts +8 -0
  145. package/dist/types/constants/context-query-param-key.d.ts.map +1 -0
  146. package/dist/types/constants/index.d.ts +3 -0
  147. package/dist/types/constants/index.d.ts.map +1 -0
  148. package/dist/types/constants/uuid-pattern.d.ts +8 -0
  149. package/dist/types/constants/uuid-pattern.d.ts.map +1 -0
  150. package/dist/types/create-context-navigation-plugin.d.ts +58 -0
  151. package/dist/types/create-context-navigation-plugin.d.ts.map +1 -0
  152. package/dist/types/enable-context-navigation.d.ts +21 -0
  153. package/dist/types/enable-context-navigation.d.ts.map +1 -0
  154. package/dist/types/events.d.ts +16 -0
  155. package/dist/types/events.d.ts.map +1 -0
  156. package/dist/types/guard-handlers/consume-own-nav-token.d.ts +21 -0
  157. package/dist/types/guard-handlers/consume-own-nav-token.d.ts.map +1 -0
  158. package/dist/types/guard-handlers/guard-tick-deps.d.ts +20 -0
  159. package/dist/types/guard-handlers/guard-tick-deps.d.ts.map +1 -0
  160. package/dist/types/guard-handlers/guard-tick-payload.d.ts +15 -0
  161. package/dist/types/guard-handlers/guard-tick-payload.d.ts.map +1 -0
  162. package/dist/types/guard-handlers/handle-push-mode-guard.d.ts +24 -0
  163. package/dist/types/guard-handlers/handle-push-mode-guard.d.ts.map +1 -0
  164. package/dist/types/guard-handlers/handle-replace-mode-guard.d.ts +19 -0
  165. package/dist/types/guard-handlers/handle-replace-mode-guard.d.ts.map +1 -0
  166. package/dist/types/guard-handlers/index.d.ts +7 -0
  167. package/dist/types/guard-handlers/index.d.ts.map +1 -0
  168. package/dist/types/guard-handlers/is-in-app-scope.d.ts +15 -0
  169. package/dist/types/guard-handlers/is-in-app-scope.d.ts.map +1 -0
  170. package/dist/types/helpers/get-current-url.d.ts +10 -0
  171. package/dist/types/helpers/get-current-url.d.ts.map +1 -0
  172. package/dist/types/helpers/index.d.ts +6 -0
  173. package/dist/types/helpers/index.d.ts.map +1 -0
  174. package/dist/types/helpers/normalize-path-from-url.d.ts +11 -0
  175. package/dist/types/helpers/normalize-path-from-url.d.ts.map +1 -0
  176. package/dist/types/helpers/normalize-path.d.ts +14 -0
  177. package/dist/types/helpers/normalize-path.d.ts.map +1 -0
  178. package/dist/types/helpers/resolve-adapter.d.ts +14 -0
  179. package/dist/types/helpers/resolve-adapter.d.ts.map +1 -0
  180. package/dist/types/helpers/strip-query-params.d.ts +12 -0
  181. package/dist/types/helpers/strip-query-params.d.ts.map +1 -0
  182. package/dist/types/index.d.ts +9 -0
  183. package/dist/types/index.d.ts.map +1 -0
  184. package/dist/types/operators/active-app-navigation-events.d.ts +47 -0
  185. package/dist/types/operators/active-app-navigation-events.d.ts.map +1 -0
  186. package/dist/types/reconcile.d.ts +43 -0
  187. package/dist/types/reconcile.d.ts.map +1 -0
  188. package/dist/types/sources/app-first-source.d.ts +14 -0
  189. package/dist/types/sources/app-first-source.d.ts.map +1 -0
  190. package/dist/types/sources/context-first-source.d.ts +15 -0
  191. package/dist/types/sources/context-first-source.d.ts.map +1 -0
  192. package/dist/types/sources/index.d.ts +4 -0
  193. package/dist/types/sources/index.d.ts.map +1 -0
  194. package/dist/types/sources/types.d.ts +61 -0
  195. package/dist/types/sources/types.d.ts.map +1 -0
  196. package/dist/types/types.d.ts +126 -0
  197. package/dist/types/types.d.ts.map +1 -0
  198. package/dist/types/utils/has-custom-context-generators.d.ts +13 -0
  199. package/dist/types/utils/has-custom-context-generators.d.ts.map +1 -0
  200. package/dist/types/utils/legacy-app-navigation-fix.d.ts +33 -0
  201. package/dist/types/utils/legacy-app-navigation-fix.d.ts.map +1 -0
  202. package/dist/types/utils/resolve-context-from-url.d.ts +20 -0
  203. package/dist/types/utils/resolve-context-from-url.d.ts.map +1 -0
  204. package/dist/types/utils/url/build-app-route.d.ts +11 -0
  205. package/dist/types/utils/url/build-app-route.d.ts.map +1 -0
  206. package/dist/types/utils/url/build-context-url-for-strategy.d.ts +14 -0
  207. package/dist/types/utils/url/build-context-url-for-strategy.d.ts.map +1 -0
  208. package/dist/types/utils/url/index.d.ts +8 -0
  209. package/dist/types/utils/url/index.d.ts.map +1 -0
  210. package/dist/types/utils/url/parse-app-route.d.ts +20 -0
  211. package/dist/types/utils/url/parse-app-route.d.ts.map +1 -0
  212. package/dist/types/utils/url/resolve-context-id-from-url.d.ts +8 -0
  213. package/dist/types/utils/url/resolve-context-id-from-url.d.ts.map +1 -0
  214. package/dist/types/utils/url/strip-context-query-param.d.ts +12 -0
  215. package/dist/types/utils/url/strip-context-query-param.d.ts.map +1 -0
  216. package/dist/types/version.d.ts +2 -0
  217. package/dist/types/version.d.ts.map +1 -0
  218. package/package.json +4 -4
@@ -0,0 +1,58 @@
1
+ import type { AppModuleProvider } from '@equinor/fusion-framework-module-app';
2
+ import type { IContextProvider } from '@equinor/fusion-framework-module-context';
3
+ import type { IEventModuleProvider } from '@equinor/fusion-framework-module-event';
4
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
5
+ import type { ContextNavigationConfig } from './types';
6
+ /**
7
+ * Arguments required to initialize the context-navigation plugin.
8
+ *
9
+ * Consumers never construct this directly — it is assembled by the framework's
10
+ * plugin registration callback from the initialized module providers.
11
+ */
12
+ export interface ContextNavigationPluginArgs {
13
+ /** Provides the currently active app and its resolved module instances. */
14
+ app: AppModuleProvider;
15
+ /** Provides browser navigation state and imperative navigation methods. */
16
+ navigation: INavigationProvider;
17
+ /** Provides the active context and mutation methods (e.g. setCurrentContextByIdAsync). */
18
+ context: IContextProvider;
19
+ /** Provides the cancelable event bus for dispatching plugin lifecycle events. */
20
+ event: IEventModuleProvider;
21
+ /** Fully resolved plugin configuration (adapters, sources, options). */
22
+ config: ContextNavigationConfig;
23
+ }
24
+ /** Event source token forwarded to all dispatched events. */
25
+ declare const eventSource: {
26
+ name: string;
27
+ version: string;
28
+ };
29
+ /** The type of the event source token attached to all context-navigation events. */
30
+ export type ContextNavigationEventSource = typeof eventSource;
31
+ /**
32
+ * Creates the context-navigation plugin runtime.
33
+ *
34
+ * Sets up two subscriptions:
35
+ *
36
+ * **Reconciler** — watches the portal context and app switches via the configured
37
+ * source factory. On each emission it encodes the active context into the app URL
38
+ * using the first matching adapter.
39
+ *
40
+ * **URL guard** — watches browser navigation state and detects when the URL no
41
+ * longer reflects the active context. Behavior depends on `navigationOptions.replace`:
42
+ *
43
+ * - `replace: true` (default) — each context change replaces the current history entry,
44
+ * so there is no meaningful back/forward stack within the context history. If the URL
45
+ * diverges from the active context (e.g. an external redirect stripped the context
46
+ * segment), the guard re-asserts the active context into the URL.
47
+ *
48
+ * - `replace: false` (push mode) — each context change pushes a new history entry, so
49
+ * back/forward navigations legitimately land on URLs with different context IDs. The
50
+ * guard detects this and drives context from the URL instead of overwriting it,
51
+ * keeping the browser history and context state in sync.
52
+ *
53
+ * @param args - Initialized module providers and resolved plugin config.
54
+ * @returns A teardown function compatible with {@link FrameworkPluginTeardown}.
55
+ */
56
+ export declare function createContextNavigationPlugin(args: ContextNavigationPluginArgs): () => void;
57
+ export {};
58
+ //# sourceMappingURL=create-context-navigation-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-context-navigation-plugin.d.ts","sourceRoot":"","sources":["../../src/create-context-navigation-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAEvF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAcvD;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,2EAA2E;IAC3E,GAAG,EAAE,iBAAiB,CAAC;IACvB,2EAA2E;IAC3E,UAAU,EAAE,mBAAmB,CAAC;IAChC,0FAA0F;IAC1F,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iFAAiF;IACjF,KAAK,EAAE,oBAAoB,CAAC;IAC5B,wEAAwE;IACxE,MAAM,EAAE,uBAAuB,CAAC;CACjC;AAED,6DAA6D;AAC7D,QAAA,MAAM,WAAW;;;CAAyC,CAAC;AAE3D,oFAAoF;AACpF,MAAM,MAAM,4BAA4B,GAAG,OAAO,WAAW,CAAC;AAI9D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,2BAA2B,GAAG,MAAM,IAAI,CA4H3F"}
@@ -0,0 +1,21 @@
1
+ import type { IModulesConfigurator } from '@equinor/fusion-framework-module';
2
+ import { ContextNavigationConfigurator } from './ContextNavigationConfigurator';
3
+ export type ContextNavigationBuilder = (builder: ContextNavigationConfigurator) => void | Promise<void>;
4
+ /**
5
+ * Registers the event-driven context-to-URL reconciler plugin for a portal.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // Minimal — all defaults (built-in adapters: custom > query > path)
10
+ * enableContextNavigation(configurator);
11
+ *
12
+ * // With custom adapter
13
+ * enableContextNavigation(configurator, (builder) => {
14
+ * builder.setPortalName('my-portal');
15
+ * builder.setDebug(true);
16
+ * builder.registerAdapter(myHashAdapter);
17
+ * });
18
+ * ```
19
+ */
20
+ export declare const enableContextNavigation: (configurator: IModulesConfigurator<any, any>, builder?: ContextNavigationBuilder) => void;
21
+ //# sourceMappingURL=enable-context-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable-context-navigation.d.ts","sourceRoot":"","sources":["../../src/enable-context-navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAM7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAKhF,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,6BAA6B,KACnC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,iBAEpB,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,YAClC,wBAAwB,KACjC,IAuBF,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framework-module-event';
2
+ import type { ContextNavigationNavigateDetail, ContextNavigationNavigatedDetail, ContextNavigationAdapterResolvedDetail, ContextNavigationSkippedDetail } from './types';
3
+ import type { ContextNavigationEventSource } from './create-context-navigation-plugin';
4
+ declare module '@equinor/fusion-framework-module-event' {
5
+ interface FrameworkEventMap {
6
+ /** Fired before context navigation. Cancelable — call `event.preventDefault()` to block. */
7
+ onContextNavigationNavigate: FrameworkEvent<FrameworkEventInit<ContextNavigationNavigateDetail, ContextNavigationEventSource>>;
8
+ /** Fired after context navigation completes. */
9
+ onContextNavigationNavigated: FrameworkEvent<FrameworkEventInit<ContextNavigationNavigatedDetail, ContextNavigationEventSource>>;
10
+ /** Fired when an adapter is resolved for an app. */
11
+ onContextNavigationAdapterResolved: FrameworkEvent<FrameworkEventInit<ContextNavigationAdapterResolvedDetail, ContextNavigationEventSource>>;
12
+ /** Fired when navigation is skipped. */
13
+ onContextNavigationSkipped: FrameworkEvent<FrameworkEventInit<ContextNavigationSkippedDetail, ContextNavigationEventSource>>;
14
+ }
15
+ }
16
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAEjG,OAAO,KAAK,EACV,+BAA+B,EAC/B,gCAAgC,EAChC,sCAAsC,EACtC,8BAA8B,EAC/B,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAEvF,OAAO,QAAQ,wCAAwC,CAAC;IACtD,UAAU,iBAAiB;QACzB,4FAA4F;QAC5F,2BAA2B,EAAE,cAAc,CACzC,kBAAkB,CAAC,+BAA+B,EAAE,4BAA4B,CAAC,CAClF,CAAC;QACF,gDAAgD;QAChD,4BAA4B,EAAE,cAAc,CAC1C,kBAAkB,CAAC,gCAAgC,EAAE,4BAA4B,CAAC,CACnF,CAAC;QACF,oDAAoD;QACpD,kCAAkC,EAAE,cAAc,CAChD,kBAAkB,CAAC,sCAAsC,EAAE,4BAA4B,CAAC,CACzF,CAAC;QACF,wCAAwC;QACxC,0BAA0B,EAAE,cAAc,CACxC,kBAAkB,CAAC,8BAA8B,EAAE,4BAA4B,CAAC,CACjF,CAAC;KACH;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { OwnNavigationTokens } from '../apply-navigation';
2
+ /**
3
+ * Consume an own-navigation token if the current URL matches one previously
4
+ * navigated to by the plugin itself.
5
+ *
6
+ * Intent: prevent infinite loops between the reconciler and the guard.
7
+ * When the reconciler calls `applyNavigation`, it records the target path as a
8
+ * token. The next `navigation.state$` emission triggers the guard, which would
9
+ * otherwise see a "new" URL and try to reconcile again. By checking and consuming
10
+ * the token here, the guard knows this URL change was self-initiated and bails.
11
+ *
12
+ * Each token is consumed (deleted from the set) exactly once. This ensures that
13
+ * a subsequent user-initiated back/forward navigation to the same path IS
14
+ * processed by the guard, since the token will no longer be present.
15
+ *
16
+ * @param currentURL - The current browser URL to check against known tokens.
17
+ * @param ownNavTokens - The set of normalized paths the plugin has navigated to.
18
+ * @returns `true` if this navigation was plugin-initiated (caller should bail).
19
+ */
20
+ export declare function consumeOwnNavToken(currentURL: URL, ownNavTokens: OwnNavigationTokens): boolean;
21
+ //# sourceMappingURL=consume-own-nav-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consume-own-nav-token.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/consume-own-nav-token.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,GAAG,EAAE,YAAY,EAAE,mBAAmB,GAAG,OAAO,CAS9F"}
@@ -0,0 +1,20 @@
1
+ import type { IContextProvider } from '@equinor/fusion-framework-module-context';
2
+ import type { ContextNavigationConfig } from '../types';
3
+ import type { ApplyNavigationDeps, OwnNavigationTokens } from '../apply-navigation';
4
+ /**
5
+ * Dependencies required by the URL guard handler functions.
6
+ *
7
+ * Extends {@link ApplyNavigationDeps} with the context provider needed
8
+ * to drive context from the URL in push mode.
9
+ */
10
+ export interface GuardTickDeps extends ApplyNavigationDeps {
11
+ /** Resolved plugin configuration (adapters, navigation options). */
12
+ config: ContextNavigationConfig;
13
+ /** Context provider for setting context from URL-decoded IDs in push mode. */
14
+ context: IContextProvider;
15
+ /** Own-navigation token set (inherited from ApplyNavigationDeps). */
16
+ ownNavTokens: OwnNavigationTokens;
17
+ /** Conditional debug logger. */
18
+ log: (msg: string) => void;
19
+ }
20
+ //# sourceMappingURL=guard-tick-deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard-tick-deps.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/guard-tick-deps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEpF;;;;;GAKG;AACH,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,oEAAoE;IACpE,MAAM,EAAE,uBAAuB,CAAC;IAChC,8EAA8E;IAC9E,OAAO,EAAE,gBAAgB,CAAC;IAC1B,qEAAqE;IACrE,YAAY,EAAE,mBAAmB,CAAC;IAClC,gCAAgC;IAChC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5B"}
@@ -0,0 +1,15 @@
1
+ import type { AppModulesInstance, FrameworkOptions } from '@equinor/fusion-framework-module-app';
2
+ import type { ContextModule } from '@equinor/fusion-framework-module-context';
3
+ /**
4
+ * Payload emitted on each URL guard tick, carrying the resolved app identity
5
+ * and its module instances so the guard can inspect app-level context state.
6
+ */
7
+ export interface GuardTickPayload {
8
+ /** The currently active app's key (used for URL scope checks). */
9
+ appKey: string;
10
+ /** The app's resolved module instances (provides access to context provider). */
11
+ appModules: AppModulesInstance<[ContextModule]>;
12
+ /** Routing strategy declared in the app manifest's build options. */
13
+ routingStrategy?: FrameworkOptions['contextRouting'];
14
+ }
15
+ //# sourceMappingURL=guard-tick-payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard-tick-payload.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/guard-tick-payload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACjG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,UAAU,EAAE,kBAAkB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAChD,qEAAqE;IACrE,eAAe,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;CACtD"}
@@ -0,0 +1,24 @@
1
+ import type { GuardTickPayload } from './guard-tick-payload';
2
+ import type { GuardTickDeps } from './guard-tick-deps';
3
+ /**
4
+ * Handle a URL guard tick in **push mode** (`navigationOptions.replace: false`).
5
+ *
6
+ * Intent: keep browser history and context state bidirectionally in sync.
7
+ *
8
+ * In push mode, each context change pushes a new history entry, so back/forward
9
+ * navigations legitimately land on URLs with different context IDs. When the guard
10
+ * detects a URL containing a context ID that differs from the active context, it
11
+ * interprets this as the user having navigated through history and drives context
12
+ * FROM the URL (rather than overwriting the URL).
13
+ *
14
+ * If the URL's context ID can't be resolved (stale bookmark, deleted context),
15
+ * the function falls back to re-asserting the active context into the URL so the
16
+ * address bar isn't left pointing at a broken resource.
17
+ *
18
+ * @param urlContextId - The context ID decoded from the current URL by the adapter.
19
+ * @param payload - The active app key and resolved modules.
20
+ * @param currentURL - The current browser URL.
21
+ * @param deps - Shared plugin dependencies including the context provider.
22
+ */
23
+ export declare function handlePushModeGuard(urlContextId: string, payload: GuardTickPayload, currentURL: URL, deps: GuardTickDeps): void;
24
+ //# sourceMappingURL=handle-push-mode-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-push-mode-guard.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/handle-push-mode-guard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,aAAa,GAClB,IAAI,CA6BN"}
@@ -0,0 +1,19 @@
1
+ import type { GuardTickPayload } from './guard-tick-payload';
2
+ import type { GuardTickDeps } from './guard-tick-deps';
3
+ /**
4
+ * Handle a URL guard tick in **replace mode** (`navigationOptions.replace: true`, the default).
5
+ *
6
+ * Intent: correct URL drift caused by external interference.
7
+ *
8
+ * In replace mode, context changes replace the current history entry, so there is
9
+ * no meaningful back/forward stack within the context history. A URL mismatch
10
+ * therefore means something external mutated the URL (a redirect, a router
11
+ * guard stripping segments, etc.). The fix is to re-assert the active context
12
+ * back into the URL, restoring the canonical app path.
13
+ *
14
+ * @param payload - The active app key and resolved modules.
15
+ * @param currentURL - The current browser URL that diverged from the active context.
16
+ * @param deps - Shared plugin dependencies.
17
+ */
18
+ export declare function handleReplaceModeGuard(payload: GuardTickPayload, currentURL: URL, deps: GuardTickDeps): void;
19
+ //# sourceMappingURL=handle-replace-mode-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-replace-mode-guard.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/handle-replace-mode-guard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,GAAG,EACf,IAAI,EAAE,aAAa,GAClB,IAAI,CA6BN"}
@@ -0,0 +1,7 @@
1
+ export type { GuardTickPayload } from './guard-tick-payload';
2
+ export type { GuardTickDeps } from './guard-tick-deps';
3
+ export { isInAppScope } from './is-in-app-scope';
4
+ export { consumeOwnNavToken } from './consume-own-nav-token';
5
+ export { handlePushModeGuard } from './handle-push-mode-guard';
6
+ export { handleReplaceModeGuard } from './handle-replace-mode-guard';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Determine whether the current URL falls within the active app's path namespace.
3
+ *
4
+ * The plugin must only guard URLs that belong to its own app. Navigations to
5
+ * other apps or external paths should be ignored entirely — they are another
6
+ * app instance's responsibility.
7
+ *
8
+ * Convention: all app URLs live under `/apps/{appKey}` or `/apps/{appKey}/...`.
9
+ *
10
+ * @param currentURL - The current browser URL to check.
11
+ * @param appKey - The app key used to derive the expected base path.
12
+ * @returns `true` if the URL belongs to this app's scope.
13
+ */
14
+ export declare function isInAppScope(currentURL: URL, appKey: string): boolean;
15
+ //# sourceMappingURL=is-in-app-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-in-app-scope.d.ts","sourceRoot":"","sources":["../../../src/guard-handlers/is-in-app-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIrE"}
@@ -0,0 +1,10 @@
1
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
2
+ /**
3
+ * Construct the current browser URL from the navigation provider's state.
4
+ *
5
+ * @param navigation - The navigation provider (for reading pathname and search).
6
+ * @param origin - The origin used to construct an absolute URL.
7
+ * @returns An absolute URL representing the current browser location.
8
+ */
9
+ export declare function getCurrentURL(navigation: INavigationProvider, origin: string): URL;
10
+ //# sourceMappingURL=get-current-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-current-url.d.ts","sourceRoot":"","sources":["../../../src/helpers/get-current-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAEvF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,CAElF"}
@@ -0,0 +1,6 @@
1
+ export { normalizePathFromURL } from './normalize-path-from-url';
2
+ export { normalizePath } from './normalize-path';
3
+ export { getCurrentURL } from './get-current-url';
4
+ export { resolveAdapter } from './resolve-adapter';
5
+ export { stripQueryParams } from './strip-query-params';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Normalize a URL to its path + search representation for comparison.
3
+ *
4
+ * Strips trailing slashes from the pathname so that `/apps/foo/` and
5
+ * `/apps/foo` compare as equal.
6
+ *
7
+ * @param url - The URL to normalize.
8
+ * @returns A string of the form `pathname + search` with trailing slash removed.
9
+ */
10
+ export declare function normalizePathFromURL(url: URL): string;
11
+ //# sourceMappingURL=normalize-path-from-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-path-from-url.d.ts","sourceRoot":"","sources":["../../../src/helpers/normalize-path-from-url.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAErD"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Normalizes a path string to ensure it is in a consistent format for comparison and processing.
3
+ *
4
+ * This function performs the following normalizations:
5
+ * - Ensures the path starts with a leading slash.
6
+ * - Removes any trailing slashes, except for the root path ("/").
7
+ * - Converts empty paths to the root path ("/").
8
+ * - Fixing multiple consecutive slashes to a single slash.
9
+ *
10
+ * @param path - The path string to normalize.
11
+ * @returns The normalized path string.
12
+ */
13
+ export declare function normalizePath(path: string): string;
14
+ //# sourceMappingURL=normalize-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-path.d.ts","sourceRoot":"","sources":["../../../src/helpers/normalize-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBlD"}
@@ -0,0 +1,14 @@
1
+ import type { AdapterResolutionContext, ContextNavigationAdapter, ContextNavigationAdapterInput } from '../adapters/types';
2
+ /**
3
+ * Iterate registered adapters and return the first one that can handle
4
+ * the given resolution context.
5
+ *
6
+ * - **Object adapters** are tested via `canHandle(ctx)`.
7
+ * - **Factory adapters** are invoked with `ctx`; a non-null return means match.
8
+ *
9
+ * @param ctx - The adapter resolution context (app key, app context, current URL).
10
+ * @param adapters - The registered adapters in evaluation order.
11
+ * @returns The first matching adapter, or `null` if none matched.
12
+ */
13
+ export declare function resolveAdapter(ctx: AdapterResolutionContext, adapters: readonly ContextNavigationAdapterInput[]): ContextNavigationAdapter | null;
14
+ //# sourceMappingURL=resolve-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-adapter.d.ts","sourceRoot":"","sources":["../../../src/helpers/resolve-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC9B,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,wBAAwB,EAC7B,QAAQ,EAAE,SAAS,6BAA6B,EAAE,GACjD,wBAAwB,GAAG,IAAI,CAUjC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strip all query parameters from a URL.
3
+ *
4
+ * Used on app switches to give the adapter a clean URL. The adapter's
5
+ * `encode()` will add back whatever params it needs (e.g. `$contextId`
6
+ * for query-strategy apps). On context-only changes within the same app,
7
+ * this function is not called — query params survive naturally.
8
+ *
9
+ * @param url - The URL to strip (mutated in-place).
10
+ */
11
+ export declare function stripQueryParams(url: URL): void;
12
+ //# sourceMappingURL=strip-query-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-query-params.d.ts","sourceRoot":"","sources":["../../../src/helpers/strip-query-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAE/C"}
@@ -0,0 +1,9 @@
1
+ export { createContextNavigationPlugin } from './create-context-navigation-plugin';
2
+ export type { ContextNavigationPluginArgs, ContextNavigationEventSource, } from './create-context-navigation-plugin';
3
+ export { ContextNavigationConfigurator } from './ContextNavigationConfigurator';
4
+ export { enableContextNavigation } from './enable-context-navigation';
5
+ export type { ContextNavigationConfig, ContextNavigationNavigateDetail, ContextNavigationNavigatedDetail, ContextNavigationAdapterResolvedDetail, ContextNavigationSkippedDetail, } from './types';
6
+ export { legacyAppNavigationFix } from './utils/legacy-app-navigation-fix';
7
+ import './events';
8
+ export { version } from './version';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAGhF,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAGtE,YAAY,EACV,uBAAuB,EACvB,+BAA+B,EAC/B,gCAAgC,EAChC,sCAAsC,EACtC,8BAA8B,GAC/B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAG3E,OAAO,UAAU,CAAC;AAGlB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { type Observable } from 'rxjs';
2
+ import type { AppModuleProvider, AppModulesInstance, FrameworkOptions } from '@equinor/fusion-framework-module-app';
3
+ import type { ContextModule } from '@equinor/fusion-framework-module-context';
4
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
5
+ /**
6
+ * Emission from the {@link activeAppNavigationEvents} stream.
7
+ *
8
+ * Represents the snapshot of the currently active app and its resolved modules
9
+ * at the moment a browser navigation state change occurred.
10
+ */
11
+ export interface ActiveAppNavigationEvent {
12
+ /** The key identifying the currently active application. */
13
+ appKey: string;
14
+ /** The app's resolved module instances, guaranteed to include the context module. */
15
+ appModules: AppModulesInstance<[ContextModule]>;
16
+ /** Routing strategy declared in the app manifest's build options. */
17
+ routingStrategy?: FrameworkOptions['contextRouting'];
18
+ }
19
+ /**
20
+ * RxJS operator factory that produces an emission each time the browser
21
+ * navigation state changes while a fully resolved app is present.
22
+ *
23
+ * Intent: decouple the URL guard from the mechanics of observing app readiness.
24
+ * The guard only needs to know "an app is active and a navigation just happened" —
25
+ * this operator encapsulates the four-level observable plumbing required to
26
+ * produce that signal:
27
+ *
28
+ * 1. **App switch** — outer `switchMap` on `app.current$`. If the portal switches
29
+ * to a different app (or clears the app), inner subscriptions auto-cancel.
30
+ * 2. **Module + manifest resolution** — middle `switchMap` on
31
+ * `currentApp.instance$.pipe(combineLatestWith(currentApp.manifest$))`.
32
+ * Waits until both the app's lazy modules and its manifest have resolved.
33
+ * Emits EMPTY if modules are null.
34
+ * 3. **Routing strategy extraction** — `manifest.build.options.contextRouting`
35
+ * is projected into the downstream payload so the guard can pass it to
36
+ * adapter resolution without a separate manifest lookup.
37
+ * 4. **Navigation event** — inner `map` on `navigation.state$`. Each state change
38
+ * (push, replace, popstate) triggers a downstream emission carrying the
39
+ * resolved app key, modules, and routing strategy.
40
+ *
41
+ * @param app - The app module provider (source of `current$`).
42
+ * @param navigation - The navigation provider (source of `state$`).
43
+ * @returns An observable that emits `{ appKey, appModules }` on every navigation
44
+ * event while an active app with resolved modules is present.
45
+ */
46
+ export declare function activeAppNavigationEvents(app: AppModuleProvider, navigation: INavigationProvider): Observable<ActiveAppNavigationEvent>;
47
+ //# sourceMappingURL=active-app-navigation-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active-app-navigation-events.d.ts","sourceRoot":"","sources":["../../../src/operators/active-app-navigation-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,UAAU,EAAqC,MAAM,MAAM,CAAC;AAEjF,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,UAAU,EAAE,kBAAkB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAChD,qEAAqE;IACrE,eAAe,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,iBAAiB,EACtB,UAAU,EAAE,mBAAmB,GAC9B,UAAU,CAAC,wBAAwB,CAAC,CA8BtC"}
@@ -0,0 +1,43 @@
1
+ import type { IEventModuleProvider } from '@equinor/fusion-framework-module-event';
2
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
3
+ import type { ContextNavigationConfig } from './types';
4
+ import type { ContextNavigationEventSource } from './create-context-navigation-plugin';
5
+ import type { ReconcilerSourceEntry } from './sources/types';
6
+ import { type ApplyNavigationDeps } from './apply-navigation';
7
+ /** Dependencies required by {@link reconcile}. */
8
+ export interface ReconcileDeps extends ApplyNavigationDeps {
9
+ event: IEventModuleProvider;
10
+ navigation: INavigationProvider;
11
+ config: ContextNavigationConfig;
12
+ eventSource: ContextNavigationEventSource;
13
+ }
14
+ /**
15
+ * Options that describe the trigger context for a reconciliation pass.
16
+ */
17
+ export interface ReconcileOptions {
18
+ /**
19
+ * Whether this reconciliation was triggered by an app switch.
20
+ *
21
+ * When `true`, all query parameters are stripped from the current URL
22
+ * before the adapter encodes the new URL. The adapter adds back whatever
23
+ * it needs (e.g. `$contextId` for query-strategy apps).
24
+ *
25
+ * @default false
26
+ */
27
+ isAppSwitch?: boolean;
28
+ }
29
+ /**
30
+ * Reconcile a source entry: resolve an adapter and apply navigation
31
+ * for the given app/context combination.
32
+ *
33
+ * Handles three context states:
34
+ * - `undefined` — context not yet resolved, skip.
35
+ * - `null` — context cleared, navigate to `nullContextUrl` if configured.
36
+ * - `ContextItem` — active context, encode via adapter and navigate.
37
+ *
38
+ * @param entry - The reconciler source entry with app key, modules, and context state.
39
+ * @param deps - Shared plugin dependencies.
40
+ * @param options - Optional trigger context (e.g. whether this is an app switch).
41
+ */
42
+ export declare function reconcile(entry: ReconcilerSourceEntry, deps: ReconcileDeps, options?: ReconcileOptions): void;
43
+ //# sourceMappingURL=reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAEvF,OAAO,KAAK,EAEV,uBAAuB,EAExB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE/E,kDAAkD;AAClD,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,KAAK,EAAE,oBAAoB,CAAC;IAC5B,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,uBAAuB,CAAC;IAChC,WAAW,EAAE,4BAA4B,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CA8EN"}
@@ -0,0 +1,14 @@
1
+ import { type ReconcilerSourceFactory } from './types';
2
+ /**
3
+ * App-first source factory — app switches lead, context follows.
4
+ *
5
+ * Stream composition:
6
+ * ```
7
+ * app.current$ → combineLatest(instance$, manifest$) → combineLatestWith(context.currentContext$)
8
+ * ```
9
+ *
10
+ * Use this for **app-portal** where the active app determines the navigation
11
+ * context. Context changes are reconciled within the scope of the current app.
12
+ */
13
+ export declare const appFirstSource: () => ReconcilerSourceFactory;
14
+ //# sourceMappingURL=app-first-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-first-source.d.ts","sourceRoot":"","sources":["../../../src/sources/app-first-source.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuB,KAAK,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,QAAO,uBAyCjC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type ReconcilerSourceFactory } from './types';
2
+ /**
3
+ * Context-first source factory — context changes lead, app follows.
4
+ *
5
+ * Stream composition:
6
+ * ```
7
+ * context.currentContext$ → combineLatestWith(app.current$ → combineLatest(instance$, manifest$))
8
+ * ```
9
+ *
10
+ * Use this for **context-portal** where the selected context drives all
11
+ * navigation. App switches are reconciled within the scope of the current
12
+ * context.
13
+ */
14
+ export declare const contextFirstSource: () => ReconcilerSourceFactory;
15
+ //# sourceMappingURL=context-first-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-first-source.d.ts","sourceRoot":"","sources":["../../../src/sources/context-first-source.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuB,KAAK,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAO,uBAiDrC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { appFirstSource } from './app-first-source';
2
+ export { contextFirstSource } from './context-first-source';
3
+ export { contextStateChanged, type ContextState, type ReconcilerPhase, type ReconcilerSourceEntry, type ReconcilerSourceDeps, type ReconcilerSourceFactory, } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EACL,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,SAAS,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { Observable } from 'rxjs';
2
+ import type { AppModuleProvider, AppModulesInstance, FrameworkOptions } from '@equinor/fusion-framework-module-app';
3
+ import type { ContextModule, ContextItem, IContextProvider } from '@equinor/fusion-framework-module-context';
4
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
5
+ /**
6
+ * The reconciler's view of context state.
7
+ *
8
+ * - `undefined` — context not yet resolved (initializing)
9
+ * - `null` — context intentionally cleared
10
+ * - `ContextItem` — active context
11
+ */
12
+ export type ContextState = ContextItem | null | undefined;
13
+ export type ReconcilerPhase = 'idle' | 'active' | 'cleared';
14
+ /**
15
+ * A single reconciliation entry emitted by the source factory.
16
+ *
17
+ * Contains everything the reconciler needs to decide whether and how
18
+ * to navigate.
19
+ */
20
+ export interface ReconcilerSourceEntry {
21
+ /** Current app key. */
22
+ appKey: string;
23
+ /** The app's loaded module instances (must include context). */
24
+ appModules: AppModulesInstance<[ContextModule]>;
25
+ /** The portal-level context state driving reconciliation. */
26
+ contextState: ContextState;
27
+ /** Routing strategy declared in the app manifest's build options. */
28
+ routingStrategy?: FrameworkOptions['contextRouting'];
29
+ }
30
+ /**
31
+ * Dependencies injected into a source factory.
32
+ */
33
+ export interface ReconcilerSourceDeps {
34
+ /** The app module provider (for watching app switches). */
35
+ app: AppModuleProvider;
36
+ /** The portal's context provider (for watching context changes). */
37
+ context: IContextProvider;
38
+ /** The navigation provider (for reading current URL). */
39
+ navigation: INavigationProvider;
40
+ }
41
+ /**
42
+ * A source factory produces the observable stream that drives the reconciler.
43
+ *
44
+ * The stream composition determines **what leads** — app switches or context
45
+ * changes — making it the primary extension point for portal-specific behavior.
46
+ *
47
+ * Built-in factories:
48
+ * - `createAppFirstSource` — app switches lead, context follows (app-portal)
49
+ * - `createContextFirstSource` — context changes lead, app follows (context-portal)
50
+ */
51
+ export type ReconcilerSourceFactory = (deps: ReconcilerSourceDeps) => Observable<ReconcilerSourceEntry>;
52
+ /**
53
+ * Equality comparator for `ContextState` values in `distinctUntilChanged`.
54
+ *
55
+ * Returns `true` when the two states represent the same context identity,
56
+ * preventing redundant reconciler emissions. Both `null` (cleared) and
57
+ * `undefined` (initializing) are compared by reference; active contexts
58
+ * are compared by `id`.
59
+ */
60
+ export declare const contextStateChanged: (a: ContextState, b: ContextState) => boolean;
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sources/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,gBAAgB,EACjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAIvF;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;AAI1D,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAI5D;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,UAAU,EAAE,kBAAkB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAChD,6DAA6D;IAC7D,YAAY,EAAE,YAAY,CAAC;IAC3B,qEAAqE;IACrE,eAAe,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,GAAG,EAAE,iBAAiB,CAAC;IACvB,oEAAoE;IACpE,OAAO,EAAE,gBAAgB,CAAC;IAC1B,yDAAyD;IACzD,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,IAAI,EAAE,oBAAoB,KACvB,UAAU,CAAC,qBAAqB,CAAC,CAAC;AAIvC;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,MAAO,YAAY,KAAK,YAAY,KAAG,OAItE,CAAC"}