@equinor/fusion-framework-module-context 9.0.0-next.0 → 9.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.
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +13 -10
- package/CHANGELOG.md +0 -1095
- package/docs/data-model.md +0 -134
- package/docs/lifecycle.md +0 -163
- package/docs/recipes.md +0 -89
- package/src/ContextModuleConfig.ts +0 -147
- package/src/ContextModuleConfigurator.interface.ts +0 -145
- package/src/ContextModuleConfigurator.ts +0 -295
- package/src/ContextProvider.ts +0 -1158
- package/src/__tests__/ContextModuleConfigurator.test.ts +0 -412
- package/src/__tests__/mock/context-mock.test.ts +0 -137
- package/src/__tests__/mock/create-context-item-factory.test.ts +0 -60
- package/src/__tests__/mock/create-context-items.test.ts +0 -58
- package/src/client/ContextClient.ts +0 -149
- package/src/errors/FusionContextSearchError.ts +0 -56
- package/src/errors/index.ts +0 -1
- package/src/index.ts +0 -29
- package/src/mock/ContextMockConfigurator.ts +0 -244
- package/src/mock/fixtures/create-context-item-factory.ts +0 -62
- package/src/mock/fixtures/create-context-items.ts +0 -80
- package/src/mock/fixtures/index.ts +0 -28
- package/src/mock/fixtures/string-to-seed.ts +0 -18
- package/src/mock/index.ts +0 -33
- package/src/mock/module.ts +0 -54
- package/src/module.ts +0 -178
- package/src/selectors/get-context-selector.ts +0 -14
- package/src/selectors/index.ts +0 -12
- package/src/selectors/query-context-selector.ts +0 -15
- package/src/selectors/related-context-selector.ts +0 -15
- package/src/types.ts +0 -98
- package/src/utils/enable-context.ts +0 -40
- package/src/utils/extract-context-id-from-path.ts +0 -39
- package/src/utils/index.ts +0 -15
- package/src/utils/parse-context-item.ts +0 -39
- package/src/utils/resolve-context-from-path.ts +0 -118
- package/src/utils/resolve-initial-context.ts +0 -58
- package/src/version.ts +0 -2
- package/tsconfig.json +0 -33
- package/vitest.config.ts +0 -11
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
import { from, lastValueFrom } from 'rxjs';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
BaseConfigBuilder,
|
|
5
|
-
type ModuleInitializerArgs,
|
|
6
|
-
type ModulesInstanceType,
|
|
7
|
-
type Modules,
|
|
8
|
-
type ModuleType,
|
|
9
|
-
} from '@equinor/fusion-framework-module';
|
|
10
|
-
import type { ServicesModule, IApiProvider } from '@equinor/fusion-framework-module-services';
|
|
11
|
-
import type { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
12
|
-
import { getContextSelector, queryContextSelector, relatedContextSelector } from './selectors';
|
|
13
|
-
import type { QueryCtorOptions, QueryFn } from '@equinor/fusion-query';
|
|
14
|
-
import type { ContextItem, QueryContextParameters, RelatedContextParameters } from './types';
|
|
15
|
-
import type { GetContextParameters } from './client/ContextClient';
|
|
16
|
-
import resolveInitialContext from './utils/resolve-initial-context';
|
|
17
|
-
import type { ContextModuleConfig } from './ContextModuleConfig';
|
|
18
|
-
import type {
|
|
19
|
-
ContextConfigBuilderCallback,
|
|
20
|
-
IContextModuleConfigurator,
|
|
21
|
-
} from './ContextModuleConfigurator.interface';
|
|
22
|
-
|
|
23
|
-
export type { ContextModuleConfig } from './ContextModuleConfig';
|
|
24
|
-
export type {
|
|
25
|
-
ContextConfigBuilderCallback,
|
|
26
|
-
IContextModuleConfigurator,
|
|
27
|
-
} from './ContextModuleConfigurator.interface';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Default implementation of {@link IContextModuleConfigurator}.
|
|
31
|
-
*
|
|
32
|
-
* Collects {@link ContextConfigBuilderCallback} registrations and, when
|
|
33
|
-
* {@link createConfigAsync} is called, runs them in order — each callback
|
|
34
|
-
* receives this configurator itself and populates the config through its
|
|
35
|
-
* setter methods, which register into {@link BaseConfigBuilder._set} — to
|
|
36
|
-
* produce the final {@link ContextModuleConfig}.
|
|
37
|
-
*
|
|
38
|
-
* If no custom client is configured, the configurator falls back to
|
|
39
|
-
* creating one from the {@link ServicesModule} API provider.
|
|
40
|
-
*
|
|
41
|
-
* @remarks
|
|
42
|
-
* Extends {@link BaseConfigBuilder} and fully reuses its `_set`/`_buildConfig`
|
|
43
|
-
* machinery. Setters always pass an `async () => value` callback to `_set`,
|
|
44
|
-
* never the raw value directly — `_set` decides whether it received a value
|
|
45
|
-
* or a deferred callback by checking `typeof value_or_cb === 'function'`, so
|
|
46
|
-
* fields that are themselves functions (e.g. `validateContext`) would
|
|
47
|
-
* otherwise be misread as callbacks and invoked instead of stored.
|
|
48
|
-
*/
|
|
49
|
-
export class ContextModuleConfigurator
|
|
50
|
-
extends BaseConfigBuilder<ContextModuleConfig>
|
|
51
|
-
implements IContextModuleConfigurator
|
|
52
|
-
{
|
|
53
|
-
/** Default cache TTL (in ms) for context query results. */
|
|
54
|
-
defaultExpireTime = 1 * 60 * 1000;
|
|
55
|
-
|
|
56
|
-
#configBuilders: Array<ContextConfigBuilderCallback> = [];
|
|
57
|
-
#init?: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule, NavigationModule]>;
|
|
58
|
-
|
|
59
|
-
/** @inheritdoc */
|
|
60
|
-
addConfigBuilder(init: ContextConfigBuilderCallback): void {
|
|
61
|
-
this.#configBuilders.push(init);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** @inheritdoc */
|
|
65
|
-
requireInstance<TKey extends string = Extract<keyof Modules, string>>(
|
|
66
|
-
module: TKey,
|
|
67
|
-
): Promise<ModuleType<Modules[TKey]>>;
|
|
68
|
-
/** @inheritdoc */
|
|
69
|
-
requireInstance<T>(module: string): Promise<T>;
|
|
70
|
-
/** @inheritdoc */
|
|
71
|
-
requireInstance(
|
|
72
|
-
module: string,
|
|
73
|
-
// biome-ignore lint/suspicious/noExplicitAny: implementation signature must satisfy both overloads above (`Promise<ModuleType<...>>` and `Promise<T>`); `unknown` is not assignable to the generic `Promise<T>` overload
|
|
74
|
-
): Promise<any> {
|
|
75
|
-
// requireInstance is only meaningful once module initialization has begun and #init is set
|
|
76
|
-
if (!this.#init) {
|
|
77
|
-
throw Error('requireInstance can only be called during module configuration');
|
|
78
|
-
}
|
|
79
|
-
// #init's requireInstance is narrowed to this module's own declared deps; widen for the public any-module overload above
|
|
80
|
-
return this.#init.requireInstance(module as never);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** @inheritdoc */
|
|
84
|
-
setContextType(type: ContextModuleConfig['contextType']): void {
|
|
85
|
-
this._set('contextType', async () => type);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** @inheritdoc */
|
|
89
|
-
setContextFilter(filter: ContextModuleConfig['contextFilter']): void {
|
|
90
|
-
this._set('contextFilter', async () => filter);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** @inheritdoc */
|
|
94
|
-
connectParentContext(connect: ContextModuleConfig['connectParentContext']): void {
|
|
95
|
-
this._set('connectParentContext', async () => connect);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** @inheritdoc */
|
|
99
|
-
setContextParameterFn(fn: ContextModuleConfig['contextParameterFn']): void {
|
|
100
|
-
this._set('contextParameterFn', async () => fn);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** @inheritdoc */
|
|
104
|
-
setValidateContext(fn: ContextModuleConfig['validateContext']): void {
|
|
105
|
-
this._set('validateContext', async () => fn);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** @inheritdoc */
|
|
109
|
-
setResolveContext(fn: ContextModuleConfig['resolveContext']): void {
|
|
110
|
-
this._set('resolveContext', async () => fn);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** @inheritdoc */
|
|
114
|
-
setContextPathExtractor(fn: ContextModuleConfig['extractContextIdFromPath']): void {
|
|
115
|
-
this._set('extractContextIdFromPath', async () => fn);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** @inheritdoc */
|
|
119
|
-
setContextPathGenerator(fn: ContextModuleConfig['generatePathFromContext']): void {
|
|
120
|
-
this._set('generatePathFromContext', async () => fn);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** @inheritdoc */
|
|
124
|
-
setResolveInitialContext(fn: ContextModuleConfig['resolveInitialContext']): void {
|
|
125
|
-
this._set('resolveInitialContext', async () => fn);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** @inheritdoc */
|
|
129
|
-
setContextClient(
|
|
130
|
-
client: {
|
|
131
|
-
get:
|
|
132
|
-
| QueryFn<ContextItem, GetContextParameters>
|
|
133
|
-
| QueryCtorOptions<ContextItem, GetContextParameters>;
|
|
134
|
-
query:
|
|
135
|
-
| QueryFn<ContextItem[], QueryContextParameters>
|
|
136
|
-
| QueryCtorOptions<ContextItem[], QueryContextParameters>;
|
|
137
|
-
related?:
|
|
138
|
-
| QueryFn<ContextItem[], RelatedContextParameters>
|
|
139
|
-
| QueryCtorOptions<ContextItem[], RelatedContextParameters>;
|
|
140
|
-
},
|
|
141
|
-
expire = 1 * 60 * 1000,
|
|
142
|
-
): void {
|
|
143
|
-
const clientConfig: ContextModuleConfig['client'] = {
|
|
144
|
-
get:
|
|
145
|
-
typeof client.get === 'function'
|
|
146
|
-
? {
|
|
147
|
-
key: ({ id }) => id,
|
|
148
|
-
client: {
|
|
149
|
-
fn: client.get,
|
|
150
|
-
},
|
|
151
|
-
expire,
|
|
152
|
-
}
|
|
153
|
-
: client.get,
|
|
154
|
-
query:
|
|
155
|
-
typeof client.query === 'function'
|
|
156
|
-
? {
|
|
157
|
-
// TODO(#5118) - might cast to checksum
|
|
158
|
-
key: (args) => JSON.stringify(args),
|
|
159
|
-
client: {
|
|
160
|
-
fn: client.query,
|
|
161
|
-
},
|
|
162
|
-
expire,
|
|
163
|
-
}
|
|
164
|
-
: client.query,
|
|
165
|
-
};
|
|
166
|
-
// only override the related-context client config if one was provided
|
|
167
|
-
if (client.related) {
|
|
168
|
-
clientConfig.related =
|
|
169
|
-
typeof client.related === 'function'
|
|
170
|
-
? {
|
|
171
|
-
// TODO(#5118) - might cast to checksum
|
|
172
|
-
key: (args) => JSON.stringify(args),
|
|
173
|
-
client: {
|
|
174
|
-
fn: client.related,
|
|
175
|
-
},
|
|
176
|
-
expire,
|
|
177
|
-
}
|
|
178
|
-
: client.related;
|
|
179
|
-
}
|
|
180
|
-
this._set('client', async () => clientConfig);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Resolves the services API provider, preferring the local module
|
|
185
|
-
* instance and falling back to the parent module.
|
|
186
|
-
*
|
|
187
|
-
* @param init - Module initializer arguments.
|
|
188
|
-
* @returns The resolved API provider.
|
|
189
|
-
* @throws Error if no services module is available.
|
|
190
|
-
*/
|
|
191
|
-
protected async _getServiceProvider(
|
|
192
|
-
init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule]>,
|
|
193
|
-
): Promise<IApiProvider> {
|
|
194
|
-
// prefer the local services module instance if available
|
|
195
|
-
if (init.hasModule('services')) {
|
|
196
|
-
return init.requireInstance('services');
|
|
197
|
-
}
|
|
198
|
-
const parentServiceModule = (init.ref as ModulesInstanceType<[ServicesModule]>)?.services;
|
|
199
|
-
// fall back to the parent module's services instance
|
|
200
|
-
if (!parentServiceModule) {
|
|
201
|
-
throw Error('no service services provider configures [ServicesModule]');
|
|
202
|
-
}
|
|
203
|
-
return parentServiceModule;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Runs all registered config builders, then resolves the accumulated
|
|
208
|
-
* `_set` registrations into the final {@link ContextModuleConfig}.
|
|
209
|
-
*
|
|
210
|
-
* @param init - Module initializer arguments including dependency instances.
|
|
211
|
-
* @param initial - Optional partial config inherited from a parent module.
|
|
212
|
-
* @returns The fully resolved context module configuration.
|
|
213
|
-
*/
|
|
214
|
-
protected async _createConfig(
|
|
215
|
-
init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule, NavigationModule]>,
|
|
216
|
-
initial?: Partial<ContextModuleConfig>,
|
|
217
|
-
): Promise<ContextModuleConfig> {
|
|
218
|
-
// requireInstance resolves lazily against this init for the remainder of config building
|
|
219
|
-
this.#init = init;
|
|
220
|
-
|
|
221
|
-
// run each registered config builder in sequence; each calls setXxx(), registering into _set
|
|
222
|
-
await this.#configBuilders.reduce((prev, cb) => prev.then(() => cb(this)), Promise.resolve());
|
|
223
|
-
|
|
224
|
-
// resolve every registered _set callback into the actual config object
|
|
225
|
-
const config = await lastValueFrom(from(this._buildConfig(init, initial)));
|
|
226
|
-
|
|
227
|
-
// route through _processConfig, so a subclass overriding it (e.g. ContextMockConfigurator) still runs
|
|
228
|
-
return lastValueFrom(from(this._processConfig(config, init)));
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Defaults `resolveInitialContext` and `client` when a builder callback
|
|
233
|
-
* didn't set them.
|
|
234
|
-
*
|
|
235
|
-
* If no `resolveInitialContext` was set, the default path + parent
|
|
236
|
-
* resolver is used. If no `client` was set, one is created from the
|
|
237
|
-
* {@link ServicesModule} API provider.
|
|
238
|
-
*
|
|
239
|
-
* @param config - The config accumulated from registered builder callbacks.
|
|
240
|
-
* @param init - Module initializer arguments including dependency instances.
|
|
241
|
-
* @returns The fully resolved context module configuration.
|
|
242
|
-
*/
|
|
243
|
-
protected async _processConfig(
|
|
244
|
-
config: Partial<ContextModuleConfig>,
|
|
245
|
-
init: ModuleInitializerArgs<IContextModuleConfigurator, [ServicesModule, NavigationModule]>,
|
|
246
|
-
): Promise<ContextModuleConfig> {
|
|
247
|
-
config.resolveInitialContext ??= resolveInitialContext({
|
|
248
|
-
path: {
|
|
249
|
-
extract: config.extractContextIdFromPath,
|
|
250
|
-
validate: config.extractContextIdFromPath ? () => true : undefined,
|
|
251
|
-
},
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
// TODO(#5119) - make less lazy
|
|
255
|
-
config.client ??= await (async (): Promise<ContextModuleConfig['client']> => {
|
|
256
|
-
const apiProvider = await this._getServiceProvider(init);
|
|
257
|
-
const contextClient = await apiProvider.createContextClient('json$');
|
|
258
|
-
return {
|
|
259
|
-
get: {
|
|
260
|
-
client: {
|
|
261
|
-
fn: (args) => contextClient.get('v1', args, { selector: getContextSelector }),
|
|
262
|
-
},
|
|
263
|
-
key: ({ id }) => id,
|
|
264
|
-
expire: this.defaultExpireTime,
|
|
265
|
-
},
|
|
266
|
-
query: {
|
|
267
|
-
client: {
|
|
268
|
-
fn: (query) => contextClient.query('v1', { query }, { selector: queryContextSelector }),
|
|
269
|
-
},
|
|
270
|
-
// TODO(#5118) - might cast to checksum
|
|
271
|
-
key: (args) => JSON.stringify(args),
|
|
272
|
-
expire: this.defaultExpireTime,
|
|
273
|
-
},
|
|
274
|
-
related: {
|
|
275
|
-
client: {
|
|
276
|
-
fn: (args) => {
|
|
277
|
-
return contextClient.related(
|
|
278
|
-
'v1',
|
|
279
|
-
{ id: args.item.id, query: { filter: args.filter } },
|
|
280
|
-
{ selector: relatedContextSelector },
|
|
281
|
-
);
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
// TODO(#5118) - might cast to checksum
|
|
285
|
-
key: (args) => JSON.stringify(args),
|
|
286
|
-
expire: this.defaultExpireTime,
|
|
287
|
-
},
|
|
288
|
-
};
|
|
289
|
-
})();
|
|
290
|
-
|
|
291
|
-
return config as ContextModuleConfig;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export default ContextModuleConfigurator;
|