@equinor/fusion-framework-module-context 4.0.0-next.9 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/esm/ContextConfigBuilder.js +2 -2
  3. package/dist/esm/ContextConfigBuilder.js.map +1 -1
  4. package/dist/esm/ContextProvider.js +44 -57
  5. package/dist/esm/ContextProvider.js.map +1 -1
  6. package/dist/esm/client/ContextClient.js +5 -1
  7. package/dist/esm/client/ContextClient.js.map +1 -1
  8. package/dist/esm/configurator.js +4 -2
  9. package/dist/esm/configurator.js.map +1 -1
  10. package/dist/esm/index.js +1 -1
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/esm/module.js +33 -19
  13. package/dist/esm/module.js.map +1 -1
  14. package/dist/esm/{enable-context.js → utils/enable-context.js} +1 -1
  15. package/dist/esm/utils/enable-context.js.map +1 -0
  16. package/dist/esm/utils/index.js +3 -0
  17. package/dist/esm/utils/index.js.map +1 -0
  18. package/dist/esm/utils/resolve-context-from-path.js +17 -0
  19. package/dist/esm/utils/resolve-context-from-path.js.map +1 -0
  20. package/dist/esm/utils/resolve-initial-context.js +16 -0
  21. package/dist/esm/utils/resolve-initial-context.js.map +1 -0
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/dist/types/ContextConfigBuilder.d.ts +1 -1
  24. package/dist/types/ContextProvider.d.ts +20 -20
  25. package/dist/types/client/ContextClient.d.ts +7 -4
  26. package/dist/types/configurator.d.ts +9 -3
  27. package/dist/types/index.d.ts +1 -1
  28. package/dist/types/module.d.ts +3 -1
  29. package/dist/types/{enable-context.d.ts → utils/enable-context.d.ts} +2 -2
  30. package/dist/types/utils/index.d.ts +2 -0
  31. package/dist/types/utils/resolve-context-from-path.d.ts +8 -0
  32. package/dist/types/utils/resolve-initial-context.d.ts +7 -0
  33. package/package.json +12 -7
  34. package/src/ContextConfigBuilder.ts +2 -2
  35. package/src/ContextProvider.ts +50 -54
  36. package/src/client/ContextClient.ts +12 -7
  37. package/src/configurator.ts +22 -3
  38. package/src/index.ts +1 -1
  39. package/src/module.ts +51 -16
  40. package/src/{enable-context.ts → utils/enable-context.ts} +3 -3
  41. package/src/utils/index.ts +2 -0
  42. package/src/utils/resolve-context-from-path.ts +34 -0
  43. package/src/utils/resolve-initial-context.ts +29 -0
  44. package/tsconfig.json +5 -2
  45. package/dist/esm/enable-context.js.map +0 -1
package/src/module.ts CHANGED
@@ -1,10 +1,14 @@
1
+ import { catchError, EMPTY, from, Observable, switchMap, filter, Subscription } from 'rxjs';
2
+
1
3
  import { Module, ModulesInstance } from '@equinor/fusion-framework-module';
2
4
 
3
5
  import { EventModule } from '@equinor/fusion-framework-module-event';
4
6
  import { ServicesModule } from '@equinor/fusion-framework-module-services';
7
+ import { NavigationModule } from '@equinor/fusion-framework-module-navigation';
5
8
 
6
9
  import { IContextModuleConfigurator, ContextModuleConfigurator } from './configurator';
7
10
  import { IContextProvider, ContextProvider } from './ContextProvider';
11
+ import { ContextItem } from 'types';
8
12
 
9
13
  export type ContextModuleKey = 'context';
10
14
 
@@ -14,34 +18,65 @@ export type ContextModule = Module<
14
18
  ContextModuleKey,
15
19
  IContextProvider,
16
20
  IContextModuleConfigurator,
17
- [ServicesModule, EventModule]
21
+ [ServicesModule, EventModule, NavigationModule]
18
22
  >;
19
23
 
20
24
  export const module: ContextModule = {
21
25
  name: moduleKey,
22
26
  configure: () => new ContextModuleConfigurator(),
23
- initialize: async (args) => {
27
+ initialize: async function (args) {
24
28
  const config = await (args.config as ContextModuleConfigurator).createConfig(args);
25
29
  const event = args.hasModule('event') ? await args.requireInstance('event') : undefined;
26
30
  const parentProvider = (args.ref as ModulesInstance<[ContextModule]>)?.context;
27
31
  const provider = new ContextProvider({ config, event, parentContext: parentProvider });
28
32
 
29
- // TODO add option for skipping this step
30
- if (parentProvider) {
31
- try {
32
- await provider.connectParentContextAsync(parentProvider, {
33
- setCurrent: !config.skipInitialContext,
34
- });
35
- } catch (err) {
36
- console.warn('provider.connectParentContext', 'failed to set parent context', err);
37
- }
38
- }
33
+ const subscription = new Subscription(() => provider.dispose());
39
34
 
40
- return provider;
41
- },
35
+ this.postInitialize = (args) =>
36
+ new Observable((subscriber) => {
37
+ const resolveInitialContext$ = config.resolveInitialContext
38
+ ? from(config.resolveInitialContext(args)).pipe(
39
+ filter((item): item is ContextItem => !!item),
40
+ switchMap((item) =>
41
+ args.modules.context.setCurrentContext(item, {
42
+ validate: true,
43
+ resolve: true,
44
+ })
45
+ )
46
+ )
47
+ : EMPTY;
42
48
 
43
- dispose: (args) => {
44
- (args.instance as ContextProvider).dispose();
49
+ subscriber.add(
50
+ resolveInitialContext$
51
+ .pipe(
52
+ catchError((err) => {
53
+ console.warn(
54
+ 'ContextModule.postInitialize',
55
+ 'failed to resolve initial context',
56
+ err
57
+ );
58
+ return EMPTY;
59
+ })
60
+ )
61
+ .subscribe({
62
+ next: (item) => {
63
+ console.debug(
64
+ 'ContextModule.postInitialize',
65
+ `initial context was resolved to [${item ? item.id : 'none'}]`,
66
+ item
67
+ );
68
+ },
69
+ complete: () => {
70
+ provider.connectParentContext(parentProvider, { skipFirst: true });
71
+ subscriber.complete();
72
+ },
73
+ })
74
+ );
75
+ });
76
+
77
+ this.dispose = () => subscription.unsubscribe();
78
+
79
+ return provider;
45
80
  },
46
81
  };
47
82
 
@@ -3,10 +3,10 @@ import type {
3
3
  AnyModule,
4
4
  ModuleInitializerArgs,
5
5
  } from '@equinor/fusion-framework-module';
6
- import type { IContextModuleConfigurator } from './configurator';
7
- import type { ContextConfigBuilder } from './ContextConfigBuilder';
6
+ import type { IContextModuleConfigurator } from '../configurator';
7
+ import type { ContextConfigBuilder } from '../ContextConfigBuilder';
8
8
 
9
- import { module } from './module';
9
+ import { module } from '../module';
10
10
 
11
11
  /**
12
12
  * Method for enabling the Service module
@@ -0,0 +1,2 @@
1
+ export { enableContext } from './enable-context';
2
+ export { resolveInitialContext } from './resolve-initial-context';
@@ -0,0 +1,34 @@
1
+ import { EMPTY } from 'rxjs';
2
+
3
+ import { ModuleType } from '@equinor/fusion-framework-module';
4
+
5
+ import { type ContextModule } from '../module';
6
+
7
+ export type ContextPathResolveArgs = {
8
+ extract?: (path: string) => string | undefined;
9
+ validate?: (contextId: string) => boolean;
10
+ };
11
+
12
+ const matchGUID =
13
+ /^(?:(?:[0-9a-fA-F]){8}-(?:[0-9a-fA-F]){4}-(?:[0-9a-fA-F]){4}-(?:[0-9a-fA-F]){4}-(?:[0-9a-fA-F]){12})$/;
14
+
15
+ const extractContextIdFromPath = (path: string): string | undefined =>
16
+ path.replace(/^\/+/, '').split('/').shift();
17
+
18
+ const validateContextId = (contextId: string): boolean => !!contextId.match(matchGUID);
19
+
20
+ export const resolveContextFromPath =
21
+ (context: ModuleType<ContextModule>, args?: ContextPathResolveArgs) => (path: string) => {
22
+ const { extract = extractContextIdFromPath, validate = validateContextId } = args ?? {};
23
+ const contextId = extract(path);
24
+ if (!contextId) {
25
+ return EMPTY;
26
+ }
27
+ if (validate(contextId)) {
28
+ return context.contextClient.resolveContext(contextId);
29
+ }
30
+
31
+ throw Error(`Failed to validate context [${contextId}] from path [${path}]`);
32
+ };
33
+
34
+ export default resolveContextFromPath;
@@ -0,0 +1,29 @@
1
+ import { ModulesInstance } from '@equinor/fusion-framework-module';
2
+ import { ContextModule } from '../module';
3
+ import { type ContextModuleConfig } from '../configurator';
4
+ import { concat, EMPTY, first, of } from 'rxjs';
5
+
6
+ import { ContextPathResolveArgs, resolveContextFromPath } from './resolve-context-from-path';
7
+
8
+ export const resolveContextFromParent: ContextModuleConfig['resolveInitialContext'] = ({ ref }) => {
9
+ const parentContext = (ref as ModulesInstance<[ContextModule]>)?.context;
10
+ if (!parentContext) {
11
+ throw Error(['resolveContextFromNavigation', 'ref does not support context!'].join('\n'));
12
+ }
13
+ return parentContext.currentContext ? of(parentContext.currentContext) : EMPTY;
14
+ };
15
+
16
+ export const resolveInitialContext =
17
+ (options?: {
18
+ path?: ContextPathResolveArgs;
19
+ }): Required<ContextModuleConfig>['resolveInitialContext'] =>
20
+ ({ ref, modules }) => {
21
+ const { context, navigation } = modules;
22
+ const pathResolver = resolveContextFromPath(context, options?.path);
23
+ return concat(
24
+ navigation ? pathResolver(navigation.path.pathname) : EMPTY,
25
+ resolveContextFromParent({ ref, modules })
26
+ ).pipe(first());
27
+ };
28
+
29
+ export default resolveInitialContext;
package/tsconfig.json CHANGED
@@ -14,11 +14,14 @@
14
14
  "path": "../module"
15
15
  },
16
16
  {
17
- "path": "../services"
17
+ "path": "../navigation"
18
18
  },
19
19
  {
20
20
  "path": "../event"
21
- }
21
+ },
22
+ {
23
+ "path": "../services"
24
+ },
22
25
  ],
23
26
  "include": [
24
27
  "src/**/*",
@@ -1 +0,0 @@
1
- {"version":3,"file":"enable-context.js","sourceRoot":"","sources":["../../src/enable-context.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMlC,MAAM,CAAC,MAAM,aAAa,GAAG,CAEzB,YAA4C,EAC5C,OAKyB,EACrB,EAAE;IACN,YAAY,CAAC,SAAS,CAAC;QACnB,MAAM;QACN,SAAS,EAAE,CAAC,mBAAmB,EAAE,EAAE;YAC/B,OAAO,IAAI,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC7D,CAAC;KACJ,CAAC,CAAC;AACP,CAAC,CAAC"}