@equinor/fusion-framework-module-context 2.0.15 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import type { AnyModule, ModuleInitializerArgs, Modules, ModuleType } from '@equ
2
2
  import type { QueryCtorOptions, QueryFn } from '@equinor/fusion-query';
3
3
  import type { GetContextParameters } from './client/ContextClient';
4
4
  import type { ContextModuleConfig, ContextModuleConfigurator, IContextModuleConfigurator } from './configurator';
5
- import type { ContextItem, QueryContextParameters } from './types';
5
+ import type { ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
6
6
  export type ContextConfigBuilderCallback = <TDeps extends Array<AnyModule> = []>(builder: ContextConfigBuilder<TDeps, ModuleInitializerArgs<IContextModuleConfigurator, TDeps>>) => void | Promise<void>;
7
7
  export declare class ContextConfigBuilder<TModules extends Array<AnyModule> = [], TInit extends ModuleInitializerArgs<any, any> = ModuleInitializerArgs<ContextModuleConfigurator, TModules>> {
8
8
  #private;
@@ -13,8 +13,11 @@ export declare class ContextConfigBuilder<TModules extends Array<AnyModule> = []
13
13
  setContextType(type: ContextModuleConfig['contextType']): void;
14
14
  setContextFilter(filter: ContextModuleConfig['contextFilter']): void;
15
15
  setContextParameterFn(fn: ContextModuleConfig['contextParameterFn']): void;
16
+ setValidateContext(fn: ContextModuleConfig['validateContext']): void;
17
+ setResolveContext(fn: ContextModuleConfig['resolveContext']): void;
16
18
  setContextClient(client: {
17
19
  get: QueryFn<ContextItem, GetContextParameters> | QueryCtorOptions<ContextItem, GetContextParameters>;
18
20
  query: QueryFn<ContextItem[], QueryContextParameters> | QueryCtorOptions<ContextItem[], QueryContextParameters>;
21
+ related?: QueryFn<ContextItem[], RelatedContextParameters> | QueryCtorOptions<ContextItem[], RelatedContextParameters>;
19
22
  }, expire?: number): void;
20
23
  }
@@ -1,7 +1,7 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { ContextModuleConfig } from './configurator';
3
3
  import { ContextClient } from './client/ContextClient';
4
- import { ContextItem, QueryContextParameters } from './types';
4
+ import { ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
5
5
  import { ModuleType } from '@equinor/fusion-framework-module';
6
6
  import { EventModule, FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framework-module-event';
7
7
  import Query from '@equinor/fusion-query';
@@ -12,6 +12,11 @@ export interface IContextProvider {
12
12
  currentContext: ContextItem | undefined;
13
13
  queryContext(search: string): Observable<Array<ContextItem>>;
14
14
  queryContextAsync(search: string): Promise<Array<ContextItem>>;
15
+ validateContext(item: ContextItem<Record<string, unknown>>): boolean;
16
+ resolveContext: (current: ContextItem) => Observable<ContextItem>;
17
+ resolveContextAsync: (current: ContextItem) => Promise<ContextItem>;
18
+ relatedContexts: (args: RelatedContextParameters) => Observable<Array<ContextItem<Record<string, unknown>>>>;
19
+ relatedContextsAsync: (args: RelatedContextParameters) => Promise<Array<ContextItem<Record<string, unknown>>>>;
15
20
  clearCurrentContext: VoidFunction;
16
21
  }
17
22
  export declare class ContextProvider implements IContextProvider {
@@ -26,8 +31,17 @@ export declare class ContextProvider implements IContextProvider {
26
31
  event?: ModuleType<EventModule>;
27
32
  parentContext?: IContextProvider;
28
33
  });
34
+ setCurrentContext(context: ContextItem<Record<string, unknown>>, opt?: {
35
+ validate?: boolean;
36
+ resolve?: boolean;
37
+ }): Promise<ContextItem<Record<string, unknown>>>;
29
38
  queryContext(search: string): Observable<Array<ContextItem>>;
30
39
  queryContextAsync(search: string): Promise<Array<ContextItem>>;
40
+ validateContext(item: ContextItem<Record<string, unknown>>): boolean;
41
+ resolveContext(item: ContextItem<Record<string, unknown>>): Observable<ContextItem<Record<string, unknown>>>;
42
+ resolveContextAsync(item: ContextItem<Record<string, unknown>>): Promise<ContextItem<Record<string, unknown>>>;
43
+ relatedContexts(args: RelatedContextParameters): Observable<Array<ContextItem<Record<string, unknown>>>>;
44
+ relatedContextsAsync(args: RelatedContextParameters): Promise<Array<ContextItem<Record<string, unknown>>>>;
31
45
  clearCurrentContext(): void;
32
46
  dispose(): void;
33
47
  }
@@ -41,5 +55,15 @@ declare module '@equinor/fusion-framework-module-event' {
41
55
  next: ContextItem | undefined;
42
56
  previous: ContextItem | undefined;
43
57
  }, IContextProvider>>;
58
+ onParentContextChanged: FrameworkEvent<FrameworkEventInit<{
59
+ context: ContextItem | undefined;
60
+ }, IContextProvider>>;
61
+ onSetContextResolve: FrameworkEvent<FrameworkEventInit<{
62
+ context: ContextItem;
63
+ }, IContextProvider>>;
64
+ onSetContextResolved: FrameworkEvent<FrameworkEventInit<{
65
+ input: ContextItem;
66
+ result?: ContextItem | null;
67
+ }, IContextProvider>>;
44
68
  }
45
69
  }
@@ -1,13 +1,15 @@
1
1
  import { ModuleInitializerArgs } from '@equinor/fusion-framework-module';
2
2
  import { ServicesModule, IApiProvider } from '@equinor/fusion-framework-module-services';
3
3
  import { QueryCtorOptions } from '@equinor/fusion-query';
4
- import { ContextFilterFn, ContextItem, QueryContextParameters } from './types';
4
+ import { ContextFilterFn, ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
5
5
  import { GetContextParameters } from './client/ContextClient';
6
6
  import { ContextConfigBuilderCallback } from './ContextConfigBuilder';
7
+ import { IContextProvider } from 'ContextProvider';
7
8
  export interface ContextModuleConfig {
8
9
  client: {
9
10
  get: QueryCtorOptions<ContextItem, GetContextParameters>;
10
11
  query: QueryCtorOptions<ContextItem[], QueryContextParameters>;
12
+ related?: QueryCtorOptions<ContextItem[], RelatedContextParameters>;
11
13
  };
12
14
  contextType?: string[];
13
15
  contextFilter?: ContextFilterFn;
@@ -15,6 +17,8 @@ export interface ContextModuleConfig {
15
17
  search: string;
16
18
  type: ContextModuleConfig['contextType'];
17
19
  }) => string | QueryContextParameters;
20
+ resolveContext?: (this: IContextProvider, item: ContextItem | null) => ReturnType<IContextProvider['resolveContext']>;
21
+ validateContext?: (this: IContextProvider, item: ContextItem | null) => ReturnType<IContextProvider['validateContext']>;
18
22
  }
19
23
  export interface IContextModuleConfigurator {
20
24
  addConfigBuilder: (init: ContextConfigBuilderCallback) => void;
@@ -1,3 +1,4 @@
1
1
  import type { ContextItem } from './types';
2
2
  export declare const getContextSelector: (response: Response) => Promise<ContextItem>;
3
3
  export declare const queryContextSelector: (response: Response) => Promise<ContextItem[]>;
4
+ export declare const relatedContextSelector: (response: Response) => Promise<ContextItem[]>;
@@ -23,4 +23,10 @@ export type QueryContextParameters = {
23
23
  externalId?: string;
24
24
  };
25
25
  };
26
+ export type RelatedContextParameters = {
27
+ item: ContextItem;
28
+ filter?: {
29
+ type?: string[];
30
+ };
31
+ };
26
32
  export type ContextFilterFn = (items: ContextItem[]) => ContextItem[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/fusion-framework-module-context",
3
- "version": "2.0.15",
3
+ "version": "3.0.1",
4
4
  "description": "",
5
5
  "main": "./dist/esm/index.js",
6
6
  "exports": {
@@ -31,18 +31,18 @@
31
31
  "directory": "packages/modules/context"
32
32
  },
33
33
  "dependencies": {
34
- "@equinor/fusion-query": "^2.0.7",
34
+ "@equinor/fusion-query": "^3.0.0",
35
35
  "fast-deep-equal": "^3.1.3"
36
36
  },
37
37
  "devDependencies": {
38
- "@equinor/fusion-framework-module": "^2.0.1",
39
- "@equinor/fusion-framework-module-event": "^2.0.1",
40
- "@equinor/fusion-framework-module-services": "^2.6.0",
38
+ "@equinor/fusion-framework-module": "^3.0.0",
39
+ "@equinor/fusion-framework-module-event": "^3.0.0",
40
+ "@equinor/fusion-framework-module-services": "^3.0.0",
41
41
  "rxjs": "^7.5.7"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@equinor/fusion-framework-module": ">=1.2.5",
45
45
  "rxjs": "^7.5.7"
46
46
  },
47
- "gitHead": "58e2b934160c8bfe90be1e8de7706bf1d339e303"
47
+ "gitHead": "f372db4cbee1e6a61491e331efd38fdf3460ab89"
48
48
  }
@@ -15,7 +15,7 @@ import type {
15
15
  IContextModuleConfigurator,
16
16
  } from './configurator';
17
17
 
18
- import type { ContextItem, QueryContextParameters } from './types';
18
+ import type { ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
19
19
 
20
20
  export type ContextConfigBuilderCallback = <TDeps extends Array<AnyModule> = []>(
21
21
  builder: ContextConfigBuilder<TDeps, ModuleInitializerArgs<IContextModuleConfigurator, TDeps>>
@@ -57,6 +57,14 @@ export class ContextConfigBuilder<
57
57
  this.config.contextParameterFn = fn;
58
58
  }
59
59
 
60
+ setValidateContext(fn: ContextModuleConfig['validateContext']) {
61
+ this.config.validateContext = fn;
62
+ }
63
+
64
+ setResolveContext(fn: ContextModuleConfig['resolveContext']) {
65
+ this.config.resolveContext = fn;
66
+ }
67
+
60
68
  setContextClient(
61
69
  client: {
62
70
  get:
@@ -65,6 +73,9 @@ export class ContextConfigBuilder<
65
73
  query:
66
74
  | QueryFn<ContextItem[], QueryContextParameters>
67
75
  | QueryCtorOptions<ContextItem[], QueryContextParameters>;
76
+ related?:
77
+ | QueryFn<ContextItem[], RelatedContextParameters>
78
+ | QueryCtorOptions<ContextItem[], RelatedContextParameters>;
68
79
  },
69
80
  expire = 1 * 60 * 1000
70
81
  ): void {
@@ -91,5 +102,19 @@ export class ContextConfigBuilder<
91
102
  }
92
103
  : client.query,
93
104
  };
105
+ if (client.related) {
106
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
107
+ this.config.client!.related =
108
+ typeof client.related === 'function'
109
+ ? {
110
+ // TODO - might cast to checksum
111
+ key: (args) => JSON.stringify(args),
112
+ client: {
113
+ fn: client.related,
114
+ },
115
+ expire,
116
+ }
117
+ : client.related;
118
+ }
94
119
  }
95
120
  }
@@ -1,10 +1,10 @@
1
- import { lastValueFrom, Observable, Subscription } from 'rxjs';
2
- import { map, pairwise } from 'rxjs/operators';
1
+ import { lastValueFrom, Observable, Subscription, throwError } from 'rxjs';
2
+ import { filter, map, pairwise, switchMap } from 'rxjs/operators';
3
3
 
4
4
  import { ContextModuleConfig } from './configurator';
5
5
 
6
6
  import { ContextClient } from './client/ContextClient';
7
- import { ContextItem, QueryContextParameters } from './types';
7
+ import { ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
8
8
  import { ModuleType } from '@equinor/fusion-framework-module';
9
9
  import {
10
10
  EventModule,
@@ -27,12 +27,22 @@ export interface IContextProvider {
27
27
  currentContext: ContextItem | undefined;
28
28
  queryContext(search: string): Observable<Array<ContextItem>>;
29
29
  queryContextAsync(search: string): Promise<Array<ContextItem>>;
30
+ validateContext(item: ContextItem<Record<string, unknown>>): boolean;
31
+ resolveContext: (current: ContextItem) => Observable<ContextItem>;
32
+ resolveContextAsync: (current: ContextItem) => Promise<ContextItem>;
33
+ relatedContexts: (
34
+ args: RelatedContextParameters
35
+ ) => Observable<Array<ContextItem<Record<string, unknown>>>>;
36
+ relatedContextsAsync: (
37
+ args: RelatedContextParameters
38
+ ) => Promise<Array<ContextItem<Record<string, unknown>>>>;
30
39
  clearCurrentContext: VoidFunction;
31
40
  }
32
41
 
33
42
  export class ContextProvider implements IContextProvider {
34
43
  #contextClient: ContextClient;
35
44
  #contextQuery: Query<Array<ContextItem>, QueryContextParameters>;
45
+ #contextRelated?: Query<Array<ContextItem>, RelatedContextParameters>;
36
46
 
37
47
  #event?: ModuleType<EventModule>;
38
48
 
@@ -59,24 +69,7 @@ export class ContextProvider implements IContextProvider {
59
69
  }
60
70
 
61
71
  set currentContext(context: ContextItem | undefined) {
62
- if (this.#event) {
63
- /** notify listeners that context is about to change */
64
- this.#event
65
- .dispatchEvent('onCurrentContextChange', {
66
- source: this,
67
- canBubble: true,
68
- cancelable: true,
69
- detail: { context },
70
- })
71
- .then((e) => {
72
- /** check if setting context was prevented by listener */
73
- if (!e.canceled) {
74
- this.#contextClient.setCurrentContext(context);
75
- }
76
- });
77
- } else {
78
- this.#contextClient.setCurrentContext(context);
79
- }
72
+ context ? this.setCurrentContext(context) : this.clearCurrentContext();
80
73
  }
81
74
 
82
75
  constructor(args: {
@@ -86,11 +79,19 @@ export class ContextProvider implements IContextProvider {
86
79
  }) {
87
80
  const { config, event, parentContext } = args;
88
81
 
82
+ config.resolveContext && (this.resolveContext = config.resolveContext?.bind(this));
83
+ config.validateContext && (this.validateContext = config.validateContext?.bind(this));
84
+
89
85
  this.#contextType = config.contextType;
90
86
  this.#contextFilter = config.contextFilter;
91
87
 
92
88
  this.#contextClient = new ContextClient(config.client.get);
93
89
  this.#contextQuery = new Query(config.client.query);
90
+
91
+ if (config.client.related) {
92
+ this.#contextRelated = new Query(config.client.related);
93
+ }
94
+
94
95
  this.#contextParameterFn =
95
96
  config.contextParameterFn ??
96
97
  ((args: Parameters<Required<ContextModuleConfig>['contextParameterFn']>[0]) => ({
@@ -127,13 +128,104 @@ export class ContextProvider implements IContextProvider {
127
128
 
128
129
  if (parentContext) {
129
130
  this.#subscriptions.add(
130
- parentContext.contextClient.currentContext$.subscribe(
131
- (next) => (this.currentContext = next)
132
- )
131
+ parentContext.contextClient.currentContext$
132
+ .pipe(
133
+ switchMap(async (next) => {
134
+ if (next) {
135
+ const onParentContextChanged = await this.#event?.dispatchEvent(
136
+ 'onParentContextChanged',
137
+ {
138
+ source: this,
139
+ detail: next,
140
+ cancelable: true,
141
+ }
142
+ );
143
+ return { next, canceled: onParentContextChanged?.canceled };
144
+ }
145
+ return { next };
146
+ }),
147
+ filter((x) => !x.canceled),
148
+ map(({ next }) => next)
149
+ )
150
+ .subscribe(async (next) => {
151
+ if (next) {
152
+ try {
153
+ await this.setCurrentContext(next, {
154
+ validate: true,
155
+ resolve: true,
156
+ });
157
+ } catch (err) {
158
+ console.warn('ContextProvider::onParentContextChanged', err);
159
+ }
160
+ } else {
161
+ this.clearCurrentContext();
162
+ }
163
+ })
133
164
  );
134
165
  }
135
166
  }
136
167
 
168
+ public async setCurrentContext(
169
+ context: ContextItem<Record<string, unknown>>,
170
+ opt?: { validate?: boolean; resolve?: boolean }
171
+ ): Promise<ContextItem<Record<string, unknown>>> {
172
+ if (context === this.currentContext) {
173
+ return context;
174
+ }
175
+ if (opt?.validate && !this.validateContext(context)) {
176
+ if (opt.resolve) {
177
+ /** notify listeners about to resolve invalid context */
178
+ const onSetContextResolve = await this.#event?.dispatchEvent(
179
+ 'onSetContextResolve',
180
+ {
181
+ source: this,
182
+ cancelable: true,
183
+ detail: { context },
184
+ }
185
+ );
186
+ if (onSetContextResolve?.canceled) {
187
+ throw Error('resolving of context was canceled');
188
+ }
189
+
190
+ try {
191
+ const resolvedContext = await this.resolveContextAsync(context);
192
+ /** notify listeners about to resolved invalid context */
193
+ const onSetContextResolved = await this.#event?.dispatchEvent(
194
+ 'onSetContextResolved',
195
+ {
196
+ source: this,
197
+ cancelable: true,
198
+ detail: { input: context, result: resolvedContext },
199
+ }
200
+ );
201
+ if (onSetContextResolved?.canceled) {
202
+ throw Error('resolving of context was canceled');
203
+ }
204
+ return this.setCurrentContext(resolvedContext);
205
+ } catch (err) {
206
+ console.error('failed to resolve context', context, err);
207
+ this.clearCurrentContext();
208
+ }
209
+ }
210
+ throw Error('failed to validate provided context');
211
+ }
212
+
213
+ const onCurrentContextChange = await this.#event?.dispatchEvent('onCurrentContextChange', {
214
+ source: this,
215
+ canBubble: true,
216
+ cancelable: true,
217
+ detail: { context: context },
218
+ });
219
+
220
+ if (onCurrentContextChange?.canceled) {
221
+ throw Error('change of context was aborted');
222
+ }
223
+
224
+ this.#contextClient.setCurrentContext(context);
225
+
226
+ return context;
227
+ }
228
+
137
229
  public queryContext(search: string): Observable<Array<ContextItem>> {
138
230
  const query$ = this.queryClient
139
231
  .query(
@@ -151,8 +243,60 @@ export class ContextProvider implements IContextProvider {
151
243
  return lastValueFrom(this.queryContext(search));
152
244
  }
153
245
 
246
+ public validateContext(item: ContextItem<Record<string, unknown>>): boolean {
247
+ if (!this.#contextType) return true;
248
+ return this.#contextType.map((x) => x.toLowerCase()).includes(item.type.id.toLowerCase());
249
+ }
250
+
251
+ public resolveContext(
252
+ item: ContextItem<Record<string, unknown>>
253
+ ): Observable<ContextItem<Record<string, unknown>>> {
254
+ return this.relatedContexts({ item, filter: { type: this.#contextType } }).pipe(
255
+ map((x) => x.filter((item) => this.validateContext(item))),
256
+ map((values) => {
257
+ const value = values.shift();
258
+ if (!value) {
259
+ throw Error('failed to resolve context');
260
+ }
261
+ if (values.length) {
262
+ console.warn(
263
+ 'ContextProvider::relatedContext',
264
+ 'multiple items found 🤣',
265
+ values
266
+ );
267
+ }
268
+ return value;
269
+ })
270
+ );
271
+ }
272
+
273
+ public resolveContextAsync(
274
+ item: ContextItem<Record<string, unknown>>
275
+ ): Promise<ContextItem<Record<string, unknown>>> {
276
+ return lastValueFrom(this.resolveContext(item));
277
+ }
278
+
279
+ public relatedContexts(
280
+ args: RelatedContextParameters
281
+ ): Observable<Array<ContextItem<Record<string, unknown>>>> {
282
+ if (!this.#contextRelated) {
283
+ return throwError(() =>
284
+ Error(
285
+ 'ContextProvider::relatedContexts - no client defined for resolving related context'
286
+ )
287
+ );
288
+ }
289
+ return this.#contextRelated.query(args).pipe(map(({ value }) => value));
290
+ }
291
+
292
+ public relatedContextsAsync(
293
+ args: RelatedContextParameters
294
+ ): Promise<Array<ContextItem<Record<string, unknown>>>> {
295
+ return lastValueFrom(this.relatedContexts(args));
296
+ }
297
+
154
298
  public clearCurrentContext() {
155
- this.currentContext = undefined;
299
+ this.#contextClient.setCurrentContext(undefined);
156
300
  }
157
301
 
158
302
  dispose() {
@@ -183,5 +327,31 @@ declare module '@equinor/fusion-framework-module-event' {
183
327
  IContextProvider
184
328
  >
185
329
  >;
330
+ onParentContextChanged: FrameworkEvent<
331
+ FrameworkEventInit<
332
+ {
333
+ context: ContextItem | undefined;
334
+ },
335
+ IContextProvider
336
+ >
337
+ >;
338
+
339
+ onSetContextResolve: FrameworkEvent<
340
+ FrameworkEventInit<
341
+ {
342
+ context: ContextItem;
343
+ },
344
+ IContextProvider
345
+ >
346
+ >;
347
+ onSetContextResolved: FrameworkEvent<
348
+ FrameworkEventInit<
349
+ {
350
+ input: ContextItem;
351
+ result?: ContextItem | null;
352
+ },
353
+ IContextProvider
354
+ >
355
+ >;
186
356
  }
187
357
  }
@@ -1,15 +1,22 @@
1
1
  import { ModuleInitializerArgs, ModulesInstanceType } from '@equinor/fusion-framework-module';
2
2
  import { ServicesModule, IApiProvider } from '@equinor/fusion-framework-module-services';
3
- import { getContextSelector, queryContextSelector } from './selectors';
3
+ import { getContextSelector, queryContextSelector, relatedContextSelector } from './selectors';
4
4
  import { QueryCtorOptions } from '@equinor/fusion-query';
5
- import { ContextFilterFn, ContextItem, QueryContextParameters } from './types';
5
+ import {
6
+ ContextFilterFn,
7
+ ContextItem,
8
+ QueryContextParameters,
9
+ RelatedContextParameters,
10
+ } from './types';
6
11
  import { GetContextParameters } from './client/ContextClient';
7
12
  import { ContextConfigBuilder, ContextConfigBuilderCallback } from './ContextConfigBuilder';
13
+ import { IContextProvider } from 'ContextProvider';
8
14
 
9
15
  export interface ContextModuleConfig {
10
16
  client: {
11
17
  get: QueryCtorOptions<ContextItem, GetContextParameters>;
12
18
  query: QueryCtorOptions<ContextItem[], QueryContextParameters>;
19
+ related?: QueryCtorOptions<ContextItem[], RelatedContextParameters>;
13
20
  };
14
21
  contextType?: string[];
15
22
  contextFilter?: ContextFilterFn;
@@ -21,6 +28,16 @@ export interface ContextModuleConfig {
21
28
  search: string;
22
29
  type: ContextModuleConfig['contextType'];
23
30
  }) => string | QueryContextParameters;
31
+
32
+ resolveContext?: (
33
+ this: IContextProvider,
34
+ item: ContextItem | null
35
+ ) => ReturnType<IContextProvider['resolveContext']>;
36
+
37
+ validateContext?: (
38
+ this: IContextProvider,
39
+ item: ContextItem | null
40
+ ) => ReturnType<IContextProvider['validateContext']>;
24
41
  }
25
42
 
26
43
  export interface IContextModuleConfigurator {
@@ -87,6 +104,20 @@ export class ContextModuleConfigurator implements IContextModuleConfigurator {
87
104
  key: (args) => JSON.stringify(args),
88
105
  expire: this.defaultExpireTime,
89
106
  },
107
+ related: {
108
+ client: {
109
+ fn: (args) => {
110
+ return contextClient.related(
111
+ 'v1',
112
+ { id: args.item.id, query: { filter: args.filter } },
113
+ { selector: relatedContextSelector }
114
+ );
115
+ },
116
+ },
117
+ // TODO - might cast to checksum
118
+ key: (args) => JSON.stringify(args),
119
+ expire: this.defaultExpireTime,
120
+ },
90
121
  };
91
122
  })();
92
123
 
package/src/selectors.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { ApiVersion, ApiContextEntity } from '@equinor/fusion-framework-module-services/context';
2
2
  import type { GetContextResponse } from '@equinor/fusion-framework-module-services/context/get';
3
3
  import type { QueryContextResponse } from '@equinor/fusion-framework-module-services/context/query';
4
+ import type { RelatedContextResponse } from '@equinor/fusion-framework-module-services/context/related';
4
5
  import type { ContextItem, ContextItemType } from './types';
5
6
 
6
7
  const parseContextType = (type: GetContextResponse<'v1'>['type']): ContextItemType => ({
@@ -33,3 +34,8 @@ export const queryContextSelector = async (response: Response): Promise<ContextI
33
34
  const result = (await response.json()) as QueryContextResponse<'v1'>;
34
35
  return result.map(parseContextItem);
35
36
  };
37
+
38
+ export const relatedContextSelector = async (response: Response): Promise<ContextItem[]> => {
39
+ const result = (await response.json()) as RelatedContextResponse<'v1'>;
40
+ return result.map(parseContextItem);
41
+ };
package/src/types.ts CHANGED
@@ -26,4 +26,6 @@ export type QueryContextParameters = {
26
26
  };
27
27
  };
28
28
 
29
+ export type RelatedContextParameters = { item: ContextItem; filter?: { type?: string[] } };
30
+
29
31
  export type ContextFilterFn = (items: ContextItem[]) => ContextItem[];