@equinor/fusion-framework-module-context 4.0.0-next.8 → 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.
- package/CHANGELOG.md +25 -0
- package/dist/esm/ContextConfigBuilder.js +2 -2
- package/dist/esm/ContextConfigBuilder.js.map +1 -1
- package/dist/esm/ContextProvider.js +50 -58
- package/dist/esm/ContextProvider.js.map +1 -1
- package/dist/esm/client/ContextClient.js +11 -2
- package/dist/esm/client/ContextClient.js.map +1 -1
- package/dist/esm/configurator.js +4 -2
- package/dist/esm/configurator.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/module.js +33 -19
- package/dist/esm/module.js.map +1 -1
- package/dist/esm/{enable-context.js → utils/enable-context.js} +1 -1
- package/dist/esm/utils/enable-context.js.map +1 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/resolve-context-from-path.js +17 -0
- package/dist/esm/utils/resolve-context-from-path.js.map +1 -0
- package/dist/esm/utils/resolve-initial-context.js +16 -0
- package/dist/esm/utils/resolve-initial-context.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/ContextConfigBuilder.d.ts +1 -1
- package/dist/types/ContextProvider.d.ts +20 -20
- package/dist/types/client/ContextClient.d.ts +7 -4
- package/dist/types/configurator.d.ts +9 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types/module.d.ts +3 -1
- package/dist/types/{enable-context.d.ts → utils/enable-context.d.ts} +2 -2
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/resolve-context-from-path.d.ts +8 -0
- package/dist/types/utils/resolve-initial-context.d.ts +7 -0
- package/package.json +12 -7
- package/src/ContextConfigBuilder.ts +2 -2
- package/src/ContextProvider.ts +59 -55
- package/src/client/ContextClient.ts +23 -8
- package/src/configurator.ts +22 -3
- package/src/index.ts +1 -1
- package/src/module.ts +51 -16
- package/src/{enable-context.ts → utils/enable-context.ts} +3 -3
- package/src/utils/index.ts +2 -0
- package/src/utils/resolve-context-from-path.ts +34 -0
- package/src/utils/resolve-initial-context.ts +29 -0
- package/tsconfig.json +5 -2
- package/dist/esm/enable-context.js.map +0 -1
|
@@ -15,7 +15,7 @@ export declare class ContextConfigBuilder<TModules extends Array<AnyModule> = []
|
|
|
15
15
|
setContextParameterFn(fn: ContextModuleConfig['contextParameterFn']): void;
|
|
16
16
|
setValidateContext(fn: ContextModuleConfig['validateContext']): void;
|
|
17
17
|
setResolveContext(fn: ContextModuleConfig['resolveContext']): void;
|
|
18
|
-
|
|
18
|
+
setResolveInitialContext(fn: ContextModuleConfig['resolveInitialContext']): void;
|
|
19
19
|
setContextClient(client: {
|
|
20
20
|
get: QueryFn<ContextItem, GetContextParameters> | QueryCtorOptions<ContextItem, GetContextParameters>;
|
|
21
21
|
query: QueryFn<ContextItem[], QueryContextParameters> | QueryCtorOptions<ContextItem[], QueryContextParameters>;
|
|
@@ -8,8 +8,8 @@ import Query from '@equinor/fusion-query';
|
|
|
8
8
|
export interface IContextProvider {
|
|
9
9
|
readonly contextClient: ContextClient;
|
|
10
10
|
readonly queryClient: Query<ContextItem[], QueryContextParameters>;
|
|
11
|
-
readonly currentContext$: Observable<ContextItem | undefined>;
|
|
12
|
-
currentContext: ContextItem | undefined;
|
|
11
|
+
readonly currentContext$: Observable<ContextItem | null | undefined>;
|
|
12
|
+
currentContext: ContextItem | null | undefined;
|
|
13
13
|
queryContext(search: string): Observable<Array<ContextItem>>;
|
|
14
14
|
queryContextAsync(search: string): Promise<Array<ContextItem>>;
|
|
15
15
|
validateContext(item: ContextItem<Record<string, unknown>>): boolean;
|
|
@@ -20,40 +20,40 @@ export interface IContextProvider {
|
|
|
20
20
|
clearCurrentContext: VoidFunction;
|
|
21
21
|
setCurrentContextById(id: string): Observable<ContextItem<Record<string, unknown>>>;
|
|
22
22
|
setCurrentContextByIdAsync(id: string): Promise<ContextItem<Record<string, unknown>>>;
|
|
23
|
-
setCurrentContext(context: ContextItem<Record<string, unknown
|
|
23
|
+
setCurrentContext(context: ContextItem<Record<string, unknown>> | null, opt?: {
|
|
24
24
|
validate?: boolean;
|
|
25
25
|
resolve?: boolean;
|
|
26
|
-
}): Observable<ContextItem<Record<string, unknown
|
|
27
|
-
setCurrentContextAsync(context: ContextItem<Record<string, unknown
|
|
26
|
+
}): Observable<ContextItem<Record<string, unknown>> | null>;
|
|
27
|
+
setCurrentContextAsync(context: ContextItem<Record<string, unknown>> | null, opt?: {
|
|
28
28
|
validate?: boolean;
|
|
29
29
|
resolve?: boolean;
|
|
30
|
-
}): Promise<ContextItem<Record<string, unknown
|
|
30
|
+
}): Promise<ContextItem<Record<string, unknown>> | null>;
|
|
31
31
|
}
|
|
32
32
|
export declare class ContextProvider implements IContextProvider {
|
|
33
33
|
#private;
|
|
34
34
|
get contextClient(): ContextClient;
|
|
35
35
|
get queryClient(): Query<ContextItem<Record<string, unknown>>[], QueryContextParameters>;
|
|
36
|
-
get currentContext$(): Observable<ContextItem | undefined>;
|
|
37
|
-
get currentContext(): ContextItem | undefined;
|
|
38
|
-
set currentContext(context: ContextItem | undefined);
|
|
36
|
+
get currentContext$(): Observable<ContextItem | null | undefined>;
|
|
37
|
+
get currentContext(): ContextItem | undefined | null;
|
|
38
|
+
set currentContext(context: ContextItem | null | undefined);
|
|
39
39
|
constructor(args: {
|
|
40
40
|
config: ContextModuleConfig;
|
|
41
41
|
event?: ModuleType<EventModule>;
|
|
42
42
|
parentContext?: IContextProvider;
|
|
43
43
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}):
|
|
44
|
+
connectParentContext(provider: IContextProvider, opt?: {
|
|
45
|
+
skipFirst: boolean;
|
|
46
|
+
}): Subscription;
|
|
47
47
|
setCurrentContextById(id: string): Observable<ContextItem<Record<string, unknown>>>;
|
|
48
48
|
setCurrentContextByIdAsync(id: string): Promise<ContextItem<Record<string, unknown>>>;
|
|
49
|
-
setCurrentContext
|
|
49
|
+
setCurrentContext<T extends ContextItem<Record<string, unknown>> | null>(context: T, opt?: {
|
|
50
50
|
validate?: boolean;
|
|
51
51
|
resolve?: boolean;
|
|
52
|
-
}): Observable<
|
|
53
|
-
setCurrentContextAsync
|
|
52
|
+
}): Observable<T>;
|
|
53
|
+
setCurrentContextAsync<T extends ContextItem<Record<string, unknown>> | null>(context: T, opt?: {
|
|
54
54
|
validate?: boolean;
|
|
55
55
|
resolve?: boolean;
|
|
56
|
-
}): Promise<
|
|
56
|
+
}): Promise<T>;
|
|
57
57
|
queryContext(search: string): Observable<Array<ContextItem>>;
|
|
58
58
|
queryContextAsync(search: string): Promise<Array<ContextItem>>;
|
|
59
59
|
validateContext(item: ContextItem<Record<string, unknown>>): boolean;
|
|
@@ -68,14 +68,14 @@ export default ContextProvider;
|
|
|
68
68
|
declare module '@equinor/fusion-framework-module-event' {
|
|
69
69
|
interface FrameworkEventMap {
|
|
70
70
|
onCurrentContextChange: FrameworkEvent<FrameworkEventInit<{
|
|
71
|
-
context: ContextItem |
|
|
71
|
+
context: ContextItem | null;
|
|
72
72
|
}, IContextProvider>>;
|
|
73
73
|
onCurrentContextChanged: FrameworkEvent<FrameworkEventInit<{
|
|
74
|
-
next: ContextItem |
|
|
75
|
-
previous
|
|
74
|
+
next: ContextItem | null;
|
|
75
|
+
previous?: ContextItem | null;
|
|
76
76
|
}, IContextProvider>>;
|
|
77
77
|
onParentContextChanged: FrameworkEvent<FrameworkEventInit<{
|
|
78
|
-
context: ContextItem |
|
|
78
|
+
context: ContextItem | null;
|
|
79
79
|
}, IContextProvider>>;
|
|
80
80
|
onSetContextResolve: FrameworkEvent<FrameworkEventInit<{
|
|
81
81
|
context: ContextItem;
|
|
@@ -4,16 +4,19 @@ import { ContextItem } from '../types';
|
|
|
4
4
|
export type GetContextParameters = {
|
|
5
5
|
id: string;
|
|
6
6
|
};
|
|
7
|
-
export declare class ContextClient extends Observable<ContextItem> {
|
|
7
|
+
export declare class ContextClient extends Observable<ContextItem | null> {
|
|
8
8
|
#private;
|
|
9
|
-
get currentContext(): ContextItem | undefined;
|
|
10
|
-
get currentContext$(): Observable<ContextItem | undefined>;
|
|
9
|
+
get currentContext(): ContextItem | null | undefined;
|
|
10
|
+
get currentContext$(): Observable<ContextItem | null | undefined>;
|
|
11
11
|
get client(): Query<ContextItem, {
|
|
12
12
|
id: string;
|
|
13
13
|
}>;
|
|
14
14
|
constructor(options: QueryCtorOptions<ContextItem, GetContextParameters>);
|
|
15
|
-
setCurrentContext(idOrItem?: string | ContextItem): void;
|
|
15
|
+
setCurrentContext(idOrItem?: string | ContextItem | null): void;
|
|
16
16
|
resolveContext(id: string): Observable<ContextItem>;
|
|
17
|
+
resolveContextAsync(id: string, opt?: {
|
|
18
|
+
awaitResolve: boolean;
|
|
19
|
+
}): Promise<ContextItem>;
|
|
17
20
|
dispose(): void;
|
|
18
21
|
}
|
|
19
22
|
export default ContextClient;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObservableInput } from 'rxjs';
|
|
2
|
+
import { AnyModuleInstance, ModuleInitializerArgs, ModuleInstance } from '@equinor/fusion-framework-module';
|
|
2
3
|
import { ServicesModule, IApiProvider } from '@equinor/fusion-framework-module-services';
|
|
4
|
+
import { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
3
5
|
import { QueryCtorOptions } from '@equinor/fusion-query';
|
|
4
6
|
import { ContextFilterFn, ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
|
|
5
7
|
import { GetContextParameters } from './client/ContextClient';
|
|
6
8
|
import { ContextConfigBuilderCallback } from './ContextConfigBuilder';
|
|
7
|
-
import { IContextProvider } from 'ContextProvider';
|
|
9
|
+
import { type IContextProvider } from './ContextProvider';
|
|
8
10
|
export interface ContextModuleConfig {
|
|
9
11
|
client: {
|
|
10
12
|
get: QueryCtorOptions<ContextItem, GetContextParameters>;
|
|
@@ -20,6 +22,10 @@ export interface ContextModuleConfig {
|
|
|
20
22
|
}) => string | QueryContextParameters;
|
|
21
23
|
resolveContext?: (this: IContextProvider, item: ContextItem | null) => ReturnType<IContextProvider['resolveContext']>;
|
|
22
24
|
validateContext?: (this: IContextProvider, item: ContextItem | null) => ReturnType<IContextProvider['validateContext']>;
|
|
25
|
+
resolveInitialContext?: (args: {
|
|
26
|
+
ref?: AnyModuleInstance | any;
|
|
27
|
+
modules: ModuleInstance;
|
|
28
|
+
}) => ObservableInput<ContextItem | void>;
|
|
23
29
|
}
|
|
24
30
|
export interface IContextModuleConfigurator {
|
|
25
31
|
addConfigBuilder: (init: ContextConfigBuilderCallback) => void;
|
|
@@ -29,6 +35,6 @@ export declare class ContextModuleConfigurator implements IContextModuleConfigur
|
|
|
29
35
|
defaultExpireTime: number;
|
|
30
36
|
addConfigBuilder(init: ContextConfigBuilderCallback): void;
|
|
31
37
|
protected _getServiceProvider(init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule]>): Promise<IApiProvider>;
|
|
32
|
-
createConfig(init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule]>): Promise<ContextModuleConfig>;
|
|
38
|
+
createConfig(init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule, NavigationModule]>): Promise<ContextModuleConfig>;
|
|
33
39
|
}
|
|
34
40
|
export default ContextModuleConfigurator;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ContextModuleConfigurator, IContextModuleConfigurator, ContextModuleConfig, } from './configurator';
|
|
2
2
|
export { IContextProvider, ContextProvider } from './ContextProvider';
|
|
3
3
|
export { default, ContextModule, module as contextModule, moduleKey as contextModuleKey, } from './module';
|
|
4
|
-
export { enableContext } from './enable-context';
|
|
4
|
+
export { enableContext } from './utils/enable-context';
|
|
5
5
|
export * from './types';
|
package/dist/types/module.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Module } from '@equinor/fusion-framework-module';
|
|
2
2
|
import { EventModule } from '@equinor/fusion-framework-module-event';
|
|
3
3
|
import { ServicesModule } from '@equinor/fusion-framework-module-services';
|
|
4
|
+
import { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
4
5
|
import { IContextModuleConfigurator } from './configurator';
|
|
5
6
|
import { IContextProvider } from './ContextProvider';
|
|
6
7
|
export type ContextModuleKey = 'context';
|
|
7
8
|
export declare const moduleKey: ContextModuleKey;
|
|
8
9
|
export type ContextModule = Module<ContextModuleKey, IContextProvider, IContextModuleConfigurator, [
|
|
9
10
|
ServicesModule,
|
|
10
|
-
EventModule
|
|
11
|
+
EventModule,
|
|
12
|
+
NavigationModule
|
|
11
13
|
]>;
|
|
12
14
|
export declare const module: ContextModule;
|
|
13
15
|
declare module '@equinor/fusion-framework-module' {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { IModulesConfigurator, AnyModule, ModuleInitializerArgs } from '@equinor/fusion-framework-module';
|
|
2
|
-
import type { IContextModuleConfigurator } from '
|
|
3
|
-
import type { ContextConfigBuilder } from '
|
|
2
|
+
import type { IContextModuleConfigurator } from '../configurator';
|
|
3
|
+
import type { ContextConfigBuilder } from '../ContextConfigBuilder';
|
|
4
4
|
export declare const enableContext: (configurator: IModulesConfigurator<any, any>, builder?: (<TDeps extends AnyModule[] = []>(builder: ContextConfigBuilder<TDeps, ModuleInitializerArgs<IContextModuleConfigurator, TDeps>>) => void | Promise<void>) | undefined) => void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModuleType } from '@equinor/fusion-framework-module';
|
|
2
|
+
import { type ContextModule } from '../module';
|
|
3
|
+
export type ContextPathResolveArgs = {
|
|
4
|
+
extract?: (path: string) => string | undefined;
|
|
5
|
+
validate?: (contextId: string) => boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare const resolveContextFromPath: (context: ModuleType<ContextModule>, args?: ContextPathResolveArgs) => (path: string) => import("rxjs").Observable<import("..").ContextItem<Record<string, unknown>>>;
|
|
8
|
+
export default resolveContextFromPath;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ContextModuleConfig } from '../configurator';
|
|
2
|
+
import { ContextPathResolveArgs } from './resolve-context-from-path';
|
|
3
|
+
export declare const resolveContextFromParent: ContextModuleConfig['resolveInitialContext'];
|
|
4
|
+
export declare const resolveInitialContext: (options?: {
|
|
5
|
+
path?: ContextPathResolveArgs;
|
|
6
|
+
}) => Required<ContextModuleConfig>['resolveInitialContext'];
|
|
7
|
+
export default resolveInitialContext;
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-module-context",
|
|
3
|
-
"version": "4.0.0
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./dist/esm/index.js",
|
|
8
|
-
"./package.json": "./package.json"
|
|
8
|
+
"./package.json": "./package.json",
|
|
9
|
+
"./utils": "./dist/esm/utils/index.js"
|
|
9
10
|
},
|
|
10
11
|
"types": "index.d.ts",
|
|
11
12
|
"typesVersions": {
|
|
12
13
|
">=4.2": {
|
|
13
14
|
"*": [
|
|
14
15
|
"dist/types/*"
|
|
16
|
+
],
|
|
17
|
+
"utils": [
|
|
18
|
+
"dist/types/utils/index.d.ts"
|
|
15
19
|
]
|
|
16
20
|
}
|
|
17
21
|
},
|
|
@@ -31,18 +35,19 @@
|
|
|
31
35
|
"directory": "packages/modules/context"
|
|
32
36
|
},
|
|
33
37
|
"dependencies": {
|
|
34
|
-
"@equinor/fusion-query": "^3.0.
|
|
38
|
+
"@equinor/fusion-query": "^3.0.1",
|
|
35
39
|
"fast-deep-equal": "^3.1.3"
|
|
36
40
|
},
|
|
37
41
|
"devDependencies": {
|
|
38
|
-
"@equinor/fusion-framework-module": "^
|
|
39
|
-
"@equinor/fusion-framework-module-event": "^
|
|
40
|
-
"@equinor/fusion-framework-module-
|
|
42
|
+
"@equinor/fusion-framework-module": "^4.0.0",
|
|
43
|
+
"@equinor/fusion-framework-module-event": "^4.0.0",
|
|
44
|
+
"@equinor/fusion-framework-module-navigation": "^2.1.0",
|
|
45
|
+
"@equinor/fusion-framework-module-services": "^3.1.0",
|
|
41
46
|
"rxjs": "^7.5.7"
|
|
42
47
|
},
|
|
43
48
|
"peerDependencies": {
|
|
44
49
|
"@equinor/fusion-framework-module": ">=1.2.5",
|
|
45
50
|
"rxjs": "^7.5.7"
|
|
46
51
|
},
|
|
47
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "851d70038b9b015663981a9456247f3d5dd0c3a2"
|
|
48
53
|
}
|
|
@@ -65,8 +65,8 @@ export class ContextConfigBuilder<
|
|
|
65
65
|
this.config.resolveContext = fn;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
this.config.
|
|
68
|
+
setResolveInitialContext(fn: ContextModuleConfig['resolveInitialContext']) {
|
|
69
|
+
this.config.resolveInitialContext = fn;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
setContextClient(
|
package/src/ContextProvider.ts
CHANGED
|
@@ -31,8 +31,8 @@ export interface IContextProvider {
|
|
|
31
31
|
/** DANGER */
|
|
32
32
|
readonly queryClient: Query<ContextItem[], QueryContextParameters>;
|
|
33
33
|
|
|
34
|
-
readonly currentContext$: Observable<ContextItem | undefined>;
|
|
35
|
-
currentContext: ContextItem | undefined;
|
|
34
|
+
readonly currentContext$: Observable<ContextItem | null | undefined>;
|
|
35
|
+
currentContext: ContextItem | null | undefined;
|
|
36
36
|
queryContext(search: string): Observable<Array<ContextItem>>;
|
|
37
37
|
queryContextAsync(search: string): Promise<Array<ContextItem>>;
|
|
38
38
|
validateContext(item: ContextItem<Record<string, unknown>>): boolean;
|
|
@@ -50,14 +50,14 @@ export interface IContextProvider {
|
|
|
50
50
|
setCurrentContextByIdAsync(id: string): Promise<ContextItem<Record<string, unknown>>>;
|
|
51
51
|
|
|
52
52
|
setCurrentContext(
|
|
53
|
-
context: ContextItem<Record<string, unknown
|
|
53
|
+
context: ContextItem<Record<string, unknown>> | null,
|
|
54
54
|
opt?: { validate?: boolean; resolve?: boolean }
|
|
55
|
-
): Observable<ContextItem<Record<string, unknown
|
|
55
|
+
): Observable<ContextItem<Record<string, unknown>> | null>;
|
|
56
56
|
|
|
57
57
|
setCurrentContextAsync(
|
|
58
|
-
context: ContextItem<Record<string, unknown
|
|
58
|
+
context: ContextItem<Record<string, unknown>> | null,
|
|
59
59
|
opt?: { validate?: boolean; resolve?: boolean }
|
|
60
|
-
): Promise<ContextItem<Record<string, unknown
|
|
60
|
+
): Promise<ContextItem<Record<string, unknown>> | null>;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export class ContextProvider implements IContextProvider {
|
|
@@ -81,22 +81,25 @@ export class ContextProvider implements IContextProvider {
|
|
|
81
81
|
return this.#contextQuery;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
get currentContext$(): Observable<ContextItem | undefined> {
|
|
84
|
+
get currentContext$(): Observable<ContextItem | null | undefined> {
|
|
85
85
|
return this.#contextClient.currentContext$;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
get currentContext(): ContextItem | undefined {
|
|
88
|
+
get currentContext(): ContextItem | undefined | null {
|
|
89
89
|
return this.#contextClient.currentContext;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/** @deprecated do not use, will be removed */
|
|
93
|
-
set currentContext(context: ContextItem | undefined) {
|
|
93
|
+
set currentContext(context: ContextItem | null | undefined) {
|
|
94
94
|
console.warn(
|
|
95
95
|
'@deprecated',
|
|
96
96
|
'ContextProvider.currentContext',
|
|
97
97
|
'use setCurrentContextById|setCurrentContext|clearCurrentContext'
|
|
98
98
|
);
|
|
99
|
-
|
|
99
|
+
if (context === undefined) {
|
|
100
|
+
throw Error('not allowed to set current context as undefined undefined!');
|
|
101
|
+
}
|
|
102
|
+
this.setCurrentContextAsync(context);
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
constructor(args: {
|
|
@@ -150,20 +153,30 @@ export class ContextProvider implements IContextProvider {
|
|
|
150
153
|
/** observe event from child modules */
|
|
151
154
|
this.#event.addEventListener('onCurrentContextChanged', (e) => {
|
|
152
155
|
/** loop prevention */
|
|
153
|
-
if (e.source !== this) {
|
|
154
|
-
this.
|
|
156
|
+
if (e.source !== this && e.detail.next !== undefined) {
|
|
157
|
+
this.setCurrentContext(e.detail.next);
|
|
155
158
|
}
|
|
156
159
|
})
|
|
157
160
|
);
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
|
|
161
|
-
public
|
|
164
|
+
public connectParentContext(
|
|
162
165
|
provider: IContextProvider,
|
|
163
|
-
opt?: {
|
|
164
|
-
):
|
|
166
|
+
opt?: { skipFirst: boolean }
|
|
167
|
+
): Subscription {
|
|
165
168
|
const parentContext$ = provider.currentContext$.pipe(
|
|
166
|
-
filter((next) =>
|
|
169
|
+
filter((next, index) => {
|
|
170
|
+
if (opt?.skipFirst && index <= 1) {
|
|
171
|
+
console.debug(
|
|
172
|
+
'ContextProvider::connectParentContext',
|
|
173
|
+
'skipping first item',
|
|
174
|
+
next
|
|
175
|
+
);
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
return this.currentContext !== next;
|
|
179
|
+
}),
|
|
167
180
|
switchMap(async (next) => {
|
|
168
181
|
if (next) {
|
|
169
182
|
const onParentContextChanged = await this.#event?.dispatchEvent(
|
|
@@ -206,29 +219,7 @@ export class ContextProvider implements IContextProvider {
|
|
|
206
219
|
|
|
207
220
|
const subscription = parentContext$.subscribe();
|
|
208
221
|
this.#subscriptions.add(subscription);
|
|
209
|
-
|
|
210
|
-
return new Promise((resolve, reject) => {
|
|
211
|
-
if (opt?.setCurrent && provider.currentContext) {
|
|
212
|
-
subscription.add(reject);
|
|
213
|
-
subscription.add(
|
|
214
|
-
this.setCurrentContext(provider.currentContext, {
|
|
215
|
-
validate: true,
|
|
216
|
-
resolve: true,
|
|
217
|
-
}).subscribe({
|
|
218
|
-
error: (err) => {
|
|
219
|
-
subscription.remove(reject);
|
|
220
|
-
reject(err);
|
|
221
|
-
},
|
|
222
|
-
complete: () => {
|
|
223
|
-
subscription.remove(reject);
|
|
224
|
-
resolve(subscription);
|
|
225
|
-
},
|
|
226
|
-
})
|
|
227
|
-
);
|
|
228
|
-
} else {
|
|
229
|
-
return resolve(subscription);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
222
|
+
return subscription;
|
|
232
223
|
}
|
|
233
224
|
|
|
234
225
|
public setCurrentContextById(id: string): Observable<ContextItem<Record<string, unknown>>> {
|
|
@@ -236,7 +227,10 @@ export class ContextProvider implements IContextProvider {
|
|
|
236
227
|
try {
|
|
237
228
|
this.#contextClient
|
|
238
229
|
.resolveContext(id)
|
|
239
|
-
.pipe(
|
|
230
|
+
.pipe(
|
|
231
|
+
filter((item): item is ContextItem => !!item),
|
|
232
|
+
switchMap((item) => this.setCurrentContext(item))
|
|
233
|
+
)
|
|
240
234
|
.subscribe(subscriber);
|
|
241
235
|
} catch (err) {
|
|
242
236
|
subscriber.error(err);
|
|
@@ -248,16 +242,16 @@ export class ContextProvider implements IContextProvider {
|
|
|
248
242
|
return firstValueFrom(this.setCurrentContextById(id));
|
|
249
243
|
}
|
|
250
244
|
|
|
251
|
-
public setCurrentContext(
|
|
252
|
-
context:
|
|
245
|
+
public setCurrentContext<T extends ContextItem<Record<string, unknown>> | null>(
|
|
246
|
+
context: T,
|
|
253
247
|
opt?: { validate?: boolean; resolve?: boolean }
|
|
254
|
-
): Observable<
|
|
248
|
+
): Observable<T> {
|
|
255
249
|
return new Observable((subscriber) => {
|
|
256
250
|
if (context === this.currentContext) {
|
|
257
251
|
subscriber.next(context);
|
|
258
252
|
return subscriber.complete();
|
|
259
253
|
}
|
|
260
|
-
if (opt?.validate && !this.validateContext(context)) {
|
|
254
|
+
if (context && opt?.validate && !this.validateContext(context)) {
|
|
261
255
|
if (!opt.resolve) {
|
|
262
256
|
/** cannot resolve context, and provided is invalid */
|
|
263
257
|
this.#event?.dispatchEvent('onSetContextValidationFailed', {
|
|
@@ -309,7 +303,9 @@ export class ContextProvider implements IContextProvider {
|
|
|
309
303
|
return resolved;
|
|
310
304
|
}),
|
|
311
305
|
/** recursive set current context without validation and resolve */
|
|
312
|
-
switchMap((resolved) =>
|
|
306
|
+
switchMap((resolved) =>
|
|
307
|
+
this.setCurrentContext(resolved as unknown as T)
|
|
308
|
+
)
|
|
313
309
|
)
|
|
314
310
|
.subscribe(subscriber);
|
|
315
311
|
}
|
|
@@ -333,17 +329,17 @@ export class ContextProvider implements IContextProvider {
|
|
|
333
329
|
})
|
|
334
330
|
)
|
|
335
331
|
.subscribe((context) => {
|
|
336
|
-
this.#contextClient.setCurrentContext(context);
|
|
332
|
+
this.#contextClient.setCurrentContext(context ?? null);
|
|
337
333
|
subscriber.next(context);
|
|
338
334
|
subscriber.complete();
|
|
339
335
|
});
|
|
340
336
|
});
|
|
341
337
|
}
|
|
342
338
|
|
|
343
|
-
public async setCurrentContextAsync(
|
|
344
|
-
context:
|
|
339
|
+
public async setCurrentContextAsync<T extends ContextItem<Record<string, unknown>> | null>(
|
|
340
|
+
context: T,
|
|
345
341
|
opt?: { validate?: boolean; resolve?: boolean }
|
|
346
|
-
): Promise<
|
|
342
|
+
): Promise<T> {
|
|
347
343
|
return firstValueFrom(this.setCurrentContext(context, opt));
|
|
348
344
|
}
|
|
349
345
|
|
|
@@ -407,7 +403,15 @@ export class ContextProvider implements IContextProvider {
|
|
|
407
403
|
)
|
|
408
404
|
);
|
|
409
405
|
}
|
|
410
|
-
return this.#contextRelated.query(args).pipe(
|
|
406
|
+
return this.#contextRelated.query(args).pipe(
|
|
407
|
+
map(({ value }) => value),
|
|
408
|
+
catchError((err) => {
|
|
409
|
+
if (err.cause) {
|
|
410
|
+
throw err.cause;
|
|
411
|
+
}
|
|
412
|
+
throw err;
|
|
413
|
+
})
|
|
414
|
+
);
|
|
411
415
|
}
|
|
412
416
|
|
|
413
417
|
public relatedContextsAsync(
|
|
@@ -417,7 +421,7 @@ export class ContextProvider implements IContextProvider {
|
|
|
417
421
|
}
|
|
418
422
|
|
|
419
423
|
public clearCurrentContext() {
|
|
420
|
-
this
|
|
424
|
+
this.setCurrentContextAsync(null);
|
|
421
425
|
}
|
|
422
426
|
|
|
423
427
|
dispose() {
|
|
@@ -434,7 +438,7 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
434
438
|
onCurrentContextChange: FrameworkEvent<
|
|
435
439
|
FrameworkEventInit<
|
|
436
440
|
{
|
|
437
|
-
context: ContextItem |
|
|
441
|
+
context: ContextItem | null;
|
|
438
442
|
},
|
|
439
443
|
IContextProvider
|
|
440
444
|
>
|
|
@@ -443,8 +447,8 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
443
447
|
onCurrentContextChanged: FrameworkEvent<
|
|
444
448
|
FrameworkEventInit<
|
|
445
449
|
{
|
|
446
|
-
next: ContextItem |
|
|
447
|
-
previous
|
|
450
|
+
next: ContextItem | null;
|
|
451
|
+
previous?: ContextItem | null;
|
|
448
452
|
},
|
|
449
453
|
IContextProvider
|
|
450
454
|
>
|
|
@@ -452,7 +456,7 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
452
456
|
onParentContextChanged: FrameworkEvent<
|
|
453
457
|
FrameworkEventInit<
|
|
454
458
|
{
|
|
455
|
-
context: ContextItem |
|
|
459
|
+
context: ContextItem | null;
|
|
456
460
|
},
|
|
457
461
|
IContextProvider
|
|
458
462
|
>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Observable, BehaviorSubject, EMPTY } from 'rxjs';
|
|
1
|
+
import { Observable, BehaviorSubject, EMPTY, lastValueFrom, firstValueFrom } from 'rxjs';
|
|
2
2
|
import { catchError, map } from 'rxjs/operators';
|
|
3
3
|
|
|
4
4
|
import equal from 'fast-deep-equal';
|
|
@@ -9,16 +9,16 @@ import { ContextItem } from '../types';
|
|
|
9
9
|
|
|
10
10
|
export type GetContextParameters = { id: string };
|
|
11
11
|
|
|
12
|
-
export class ContextClient extends Observable<ContextItem> {
|
|
12
|
+
export class ContextClient extends Observable<ContextItem | null> {
|
|
13
13
|
#client: Query<ContextItem, { id: string }>;
|
|
14
14
|
/** might change to reactive state, for comparing state with reducer */
|
|
15
|
-
#currentContext$: BehaviorSubject<ContextItem | undefined>;
|
|
15
|
+
#currentContext$: BehaviorSubject<ContextItem | null | undefined>;
|
|
16
16
|
|
|
17
|
-
get currentContext(): ContextItem | undefined {
|
|
17
|
+
get currentContext(): ContextItem | null | undefined {
|
|
18
18
|
return this.#currentContext$.value;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
get currentContext$(): Observable<ContextItem | undefined> {
|
|
21
|
+
get currentContext$(): Observable<ContextItem | null | undefined> {
|
|
22
22
|
return this.#currentContext$.asObservable();
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -29,13 +29,14 @@ export class ContextClient extends Observable<ContextItem> {
|
|
|
29
29
|
constructor(options: QueryCtorOptions<ContextItem, GetContextParameters>) {
|
|
30
30
|
super((observer) => this.#currentContext$.subscribe(observer));
|
|
31
31
|
this.#client = new Query(options);
|
|
32
|
-
this.#currentContext$ = new BehaviorSubject<ContextItem | undefined>(undefined);
|
|
32
|
+
this.#currentContext$ = new BehaviorSubject<ContextItem | null | undefined>(undefined);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
public setCurrentContext(idOrItem?: string | ContextItem) {
|
|
35
|
+
public setCurrentContext(idOrItem?: string | ContextItem | null) {
|
|
36
36
|
if (typeof idOrItem === 'string') {
|
|
37
37
|
// TODO - compare context
|
|
38
38
|
this.resolveContext(idOrItem)
|
|
39
|
+
// TODO should this catch error?
|
|
39
40
|
.pipe(catchError(() => EMPTY))
|
|
40
41
|
.subscribe((value) => this.setCurrentContext(value));
|
|
41
42
|
/** only add context if not match */
|
|
@@ -45,7 +46,21 @@ export class ContextClient extends Observable<ContextItem> {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
public resolveContext(id: string): Observable<ContextItem> {
|
|
48
|
-
return this.#client.query({ id }).pipe(
|
|
49
|
+
return this.#client.query({ id }).pipe(
|
|
50
|
+
map((x) => x.value),
|
|
51
|
+
// unwrap error
|
|
52
|
+
catchError((err) => {
|
|
53
|
+
if (err.cause) {
|
|
54
|
+
throw err.cause;
|
|
55
|
+
}
|
|
56
|
+
throw err;
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public resolveContextAsync(id: string, opt?: { awaitResolve: boolean }): Promise<ContextItem> {
|
|
62
|
+
const fn = opt?.awaitResolve ? lastValueFrom : firstValueFrom;
|
|
63
|
+
return fn(this.resolveContext(id));
|
|
49
64
|
}
|
|
50
65
|
|
|
51
66
|
public dispose(): void {
|
package/src/configurator.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObservableInput } from 'rxjs';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AnyModuleInstance,
|
|
5
|
+
ModuleInitializerArgs,
|
|
6
|
+
ModuleInstance,
|
|
7
|
+
ModulesInstanceType,
|
|
8
|
+
} from '@equinor/fusion-framework-module';
|
|
2
9
|
import { ServicesModule, IApiProvider } from '@equinor/fusion-framework-module-services';
|
|
10
|
+
import { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
3
11
|
import { getContextSelector, queryContextSelector, relatedContextSelector } from './selectors';
|
|
4
12
|
import { QueryCtorOptions } from '@equinor/fusion-query';
|
|
5
13
|
import {
|
|
@@ -10,7 +18,8 @@ import {
|
|
|
10
18
|
} from './types';
|
|
11
19
|
import { GetContextParameters } from './client/ContextClient';
|
|
12
20
|
import { ContextConfigBuilder, ContextConfigBuilderCallback } from './ContextConfigBuilder';
|
|
13
|
-
import { IContextProvider } from 'ContextProvider';
|
|
21
|
+
import { type IContextProvider } from './ContextProvider';
|
|
22
|
+
import resolveInitialContext from './utils/resolve-initial-context';
|
|
14
23
|
|
|
15
24
|
export interface ContextModuleConfig {
|
|
16
25
|
client: {
|
|
@@ -41,6 +50,14 @@ export interface ContextModuleConfig {
|
|
|
41
50
|
this: IContextProvider,
|
|
42
51
|
item: ContextItem | null
|
|
43
52
|
) => ReturnType<IContextProvider['validateContext']>;
|
|
53
|
+
|
|
54
|
+
resolveInitialContext?: (
|
|
55
|
+
args: {
|
|
56
|
+
ref?: AnyModuleInstance | any;
|
|
57
|
+
modules: ModuleInstance;
|
|
58
|
+
}
|
|
59
|
+
// ...args: Parameters<ContextModule['postInitialize']>
|
|
60
|
+
) => ObservableInput<ContextItem | void>;
|
|
44
61
|
}
|
|
45
62
|
|
|
46
63
|
export interface IContextModuleConfigurator {
|
|
@@ -72,7 +89,7 @@ export class ContextModuleConfigurator implements IContextModuleConfigurator {
|
|
|
72
89
|
}
|
|
73
90
|
|
|
74
91
|
public async createConfig(
|
|
75
|
-
init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule]>
|
|
92
|
+
init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule, NavigationModule]>
|
|
76
93
|
): Promise<ContextModuleConfig> {
|
|
77
94
|
const config = await this.#configBuilders.reduce(async (cur, cb) => {
|
|
78
95
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -81,6 +98,8 @@ export class ContextModuleConfigurator implements IContextModuleConfigurator {
|
|
|
81
98
|
return Object.assign(cur, builder.config);
|
|
82
99
|
}, Promise.resolve({} as Partial<ContextModuleConfig>));
|
|
83
100
|
|
|
101
|
+
config.resolveInitialContext ??= resolveInitialContext();
|
|
102
|
+
|
|
84
103
|
// TODO - make less lazy
|
|
85
104
|
config.client ??= await (async (): Promise<ContextModuleConfig['client']> => {
|
|
86
105
|
const apiProvider = await this._getServiceProvider(init);
|