@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.
- 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 +44 -57
- package/dist/esm/ContextProvider.js.map +1 -1
- package/dist/esm/client/ContextClient.js +5 -1
- 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 +50 -54
- package/src/client/ContextClient.ts +12 -7
- 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.1
|
|
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
|
|
|
@@ -425,7 +421,7 @@ export class ContextProvider implements IContextProvider {
|
|
|
425
421
|
}
|
|
426
422
|
|
|
427
423
|
public clearCurrentContext() {
|
|
428
|
-
this
|
|
424
|
+
this.setCurrentContextAsync(null);
|
|
429
425
|
}
|
|
430
426
|
|
|
431
427
|
dispose() {
|
|
@@ -442,7 +438,7 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
442
438
|
onCurrentContextChange: FrameworkEvent<
|
|
443
439
|
FrameworkEventInit<
|
|
444
440
|
{
|
|
445
|
-
context: ContextItem |
|
|
441
|
+
context: ContextItem | null;
|
|
446
442
|
},
|
|
447
443
|
IContextProvider
|
|
448
444
|
>
|
|
@@ -451,8 +447,8 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
451
447
|
onCurrentContextChanged: FrameworkEvent<
|
|
452
448
|
FrameworkEventInit<
|
|
453
449
|
{
|
|
454
|
-
next: ContextItem |
|
|
455
|
-
previous
|
|
450
|
+
next: ContextItem | null;
|
|
451
|
+
previous?: ContextItem | null;
|
|
456
452
|
},
|
|
457
453
|
IContextProvider
|
|
458
454
|
>
|
|
@@ -460,7 +456,7 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
460
456
|
onParentContextChanged: FrameworkEvent<
|
|
461
457
|
FrameworkEventInit<
|
|
462
458
|
{
|
|
463
|
-
context: ContextItem |
|
|
459
|
+
context: ContextItem | null;
|
|
464
460
|
},
|
|
465
461
|
IContextProvider
|
|
466
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,10 +29,10 @@ 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)
|
|
@@ -58,6 +58,11 @@ export class ContextClient extends Observable<ContextItem> {
|
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
public resolveContextAsync(id: string, opt?: { awaitResolve: boolean }): Promise<ContextItem> {
|
|
62
|
+
const fn = opt?.awaitResolve ? lastValueFrom : firstValueFrom;
|
|
63
|
+
return fn(this.resolveContext(id));
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
public dispose(): void {
|
|
62
67
|
this.#currentContext$.complete();
|
|
63
68
|
}
|
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);
|