@equinor/fusion-framework-module-widget 14.0.2-next.0 → 15.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/CHANGELOG.md +37 -23
- package/README.md +171 -0
- package/dist/esm/Widget.js +91 -27
- package/dist/esm/Widget.js.map +1 -1
- package/dist/esm/WidgetModuleConfigurator.js +31 -15
- package/dist/esm/WidgetModuleConfigurator.js.map +1 -1
- package/dist/esm/WidgetModuleProvider.js +52 -20
- package/dist/esm/WidgetModuleProvider.js.map +1 -1
- package/dist/esm/enable-widget-module.js +16 -2
- package/dist/esm/enable-widget-module.js.map +1 -1
- package/dist/esm/errors.js +50 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/module.js +12 -0
- package/dist/esm/module.js.map +1 -1
- package/dist/esm/state/actions.js +18 -3
- package/dist/esm/state/actions.js.map +1 -1
- package/dist/esm/state/create-reducer.js +10 -0
- package/dist/esm/state/create-reducer.js.map +1 -1
- package/dist/esm/state/create-state.js +12 -0
- package/dist/esm/state/create-state.js.map +1 -1
- package/dist/esm/state/flows.js +22 -0
- package/dist/esm/state/flows.js.map +1 -1
- package/dist/esm/utils.js +29 -0
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/Widget.d.ts +91 -25
- package/dist/types/WidgetModuleConfigurator.d.ts +44 -10
- package/dist/types/WidgetModuleProvider.d.ts +80 -20
- package/dist/types/enable-widget-module.d.ts +16 -2
- package/dist/types/errors.d.ts +57 -0
- package/dist/types/events.d.ts +37 -17
- package/dist/types/index.d.ts +11 -2
- package/dist/types/module.d.ts +21 -0
- package/dist/types/state/actions.d.ts +29 -4
- package/dist/types/state/create-reducer.d.ts +10 -0
- package/dist/types/state/create-state.d.ts +12 -0
- package/dist/types/state/flows.d.ts +22 -0
- package/dist/types/types.d.ts +82 -15
- package/dist/types/utils.d.ts +29 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +13 -13
- package/src/Widget.ts +94 -27
- package/src/WidgetModuleConfigurator.ts +44 -17
- package/src/WidgetModuleProvider.ts +82 -20
- package/src/enable-widget-module.ts +16 -2
- package/src/errors.ts +57 -0
- package/src/events.ts +36 -17
- package/src/index.ts +12 -2
- package/src/module.ts +21 -0
- package/src/state/actions.ts +21 -3
- package/src/state/create-reducer.ts +10 -0
- package/src/state/create-state.ts +12 -0
- package/src/state/flows.ts +22 -0
- package/src/types.ts +88 -16
- package/src/utils.ts +29 -0
- package/src/version.ts +1 -1
|
@@ -3,34 +3,62 @@ import type { ConfigBuilderCallbackArgs } from '@equinor/fusion-framework-module
|
|
|
3
3
|
import { createDefaultClient } from './utils';
|
|
4
4
|
import type { IClient } from './types';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Resolved configuration produced by {@link WidgetModuleConfigurator}.
|
|
8
|
+
*
|
|
9
|
+
* Contains the {@link IClient} used to fetch widget manifests and configs
|
|
10
|
+
* from the backend API.
|
|
11
|
+
*/
|
|
7
12
|
export type WidgetModuleConfig = {
|
|
13
|
+
/** HTTP client abstraction for widget API calls. */
|
|
8
14
|
client: IClient;
|
|
9
15
|
};
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Callback signature accepted by {@link enableWidgetModule} for customizing
|
|
19
|
+
* the widget module configuration.
|
|
20
|
+
*
|
|
21
|
+
* @param builder - The {@link WidgetModuleConfigurator} instance to configure.
|
|
22
|
+
*/
|
|
12
23
|
export type WidgetModuleConfigBuilderCallback = (
|
|
13
24
|
builder: WidgetModuleConfigurator,
|
|
14
25
|
) => void | Promise<void>;
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Configuration builder for the widget module.
|
|
29
|
+
*
|
|
30
|
+
* Extends `BaseConfigBuilder` to produce a {@link WidgetModuleConfig}. If no
|
|
31
|
+
* custom client is provided via {@link setClient}, a default HTTP client is
|
|
32
|
+
* created from the `apps` service-discovery endpoint.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* enableWidgetModule(configurator, (builder) => {
|
|
37
|
+
* builder.setClient(async () => myCustomClient);
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
17
41
|
export class WidgetModuleConfigurator extends BaseConfigBuilder<WidgetModuleConfig> {
|
|
18
|
-
|
|
42
|
+
/** Default cache expiration time in milliseconds (1 minute). */
|
|
19
43
|
defaultExpireTime = 1 * 60 * 1000;
|
|
20
44
|
|
|
21
45
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
46
|
+
* Registers a custom {@link IClient} factory for the widget module.
|
|
47
|
+
*
|
|
48
|
+
* @param cb - Callback that receives config-builder args and returns an
|
|
49
|
+
* `IClient` instance (or a `Promise` thereof).
|
|
24
50
|
*/
|
|
25
51
|
public setClient(cb: ConfigBuilderCallback<IClient>) {
|
|
26
52
|
this._set('client', cb);
|
|
27
53
|
}
|
|
28
54
|
|
|
29
55
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* @
|
|
56
|
+
* Creates an HTTP client by resolving the `apps` client from the HTTP module
|
|
57
|
+
* or falling back to service discovery.
|
|
58
|
+
*
|
|
59
|
+
* @param clientId - Registered HTTP client identifier (typically `'apps'`).
|
|
60
|
+
* @param init - Framework config-builder callback args providing module instances.
|
|
61
|
+
* @returns An `IHttpClient` instance for widget API calls.
|
|
34
62
|
*/
|
|
35
63
|
private async _createHttpClient(clientId: string, init: ConfigBuilderCallbackArgs) {
|
|
36
64
|
const http = await init.requireInstance('http');
|
|
@@ -45,23 +73,22 @@ export class WidgetModuleConfigurator extends BaseConfigBuilder<WidgetModuleConf
|
|
|
45
73
|
}
|
|
46
74
|
|
|
47
75
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* @
|
|
76
|
+
* Finalizes the configuration by creating the default HTTP client when no
|
|
77
|
+
* custom client has been set.
|
|
78
|
+
*
|
|
79
|
+
* @param config - Partial configuration accumulated by builder callbacks.
|
|
80
|
+
* @param _init - Framework config-builder callback args.
|
|
81
|
+
* @returns The fully resolved {@link WidgetModuleConfig}.
|
|
52
82
|
*/
|
|
53
83
|
protected async _processConfig(
|
|
54
84
|
config: Partial<WidgetModuleConfig>,
|
|
55
85
|
_init: ConfigBuilderCallbackArgs,
|
|
56
86
|
) {
|
|
57
|
-
// Create an HTTP client using the specified client ID and initialization parameters
|
|
58
87
|
const httpClient = await this._createHttpClient('apps', _init);
|
|
59
88
|
|
|
60
|
-
// If the configuration does not have a client, use the default client
|
|
61
89
|
if (!config.client) {
|
|
62
90
|
config.client = createDefaultClient(httpClient);
|
|
63
91
|
}
|
|
64
|
-
// Return the processed configuration as a WidgetModuleConfig object
|
|
65
92
|
return config as WidgetModuleConfig;
|
|
66
93
|
}
|
|
67
94
|
}
|
|
@@ -12,15 +12,45 @@ import type { WidgetModuleConfig } from './WidgetModuleConfigurator';
|
|
|
12
12
|
import { WidgetManifestLoadError, WidgetConfigLoadError } from './errors';
|
|
13
13
|
import { Widget } from './Widget';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Public interface for the widget module provider.
|
|
17
|
+
*
|
|
18
|
+
* Consumers depend on this interface rather than the concrete
|
|
19
|
+
* {@link WidgetModuleProvider} class, enabling testability and
|
|
20
|
+
* alternative implementations.
|
|
21
|
+
*/
|
|
15
22
|
export interface IWidgetModuleProvider {
|
|
23
|
+
/**
|
|
24
|
+
* Creates a {@link Widget} instance for the given widget key.
|
|
25
|
+
*
|
|
26
|
+
* @param widgetKey - Unique identifier (name) of the widget.
|
|
27
|
+
* @param args - Optional version or tag selector.
|
|
28
|
+
* @returns A new `Widget` ready for initialization.
|
|
29
|
+
*/
|
|
16
30
|
getWidget(
|
|
17
31
|
widgetKey: GetWidgetParameters['widgetKey'],
|
|
18
32
|
args?: GetWidgetParameters['args'],
|
|
19
33
|
): Widget;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fetches the manifest for a widget as an observable stream.
|
|
37
|
+
*
|
|
38
|
+
* @param widgetKey - Unique identifier (name) of the widget.
|
|
39
|
+
* @param args - Optional version or tag selector.
|
|
40
|
+
* @returns Observable that emits the {@link WidgetManifest}.
|
|
41
|
+
*/
|
|
20
42
|
getWidgetManifest(
|
|
21
43
|
widgetKey: GetWidgetParameters['widgetKey'],
|
|
22
44
|
args?: GetWidgetParameters['args'],
|
|
23
45
|
): Observable<WidgetManifest>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Fetches the configuration for a widget as an observable stream.
|
|
49
|
+
*
|
|
50
|
+
* @param widgetKey - Unique identifier (name) of the widget.
|
|
51
|
+
* @param args - Optional version or tag selector.
|
|
52
|
+
* @returns Observable that emits the {@link WidgetConfig}.
|
|
53
|
+
*/
|
|
24
54
|
getWidgetConfig(
|
|
25
55
|
widgetKey: GetWidgetParameters['widgetKey'],
|
|
26
56
|
args?: GetWidgetParameters['args'],
|
|
@@ -28,7 +58,17 @@ export interface IWidgetModuleProvider {
|
|
|
28
58
|
}
|
|
29
59
|
|
|
30
60
|
/**
|
|
31
|
-
*
|
|
61
|
+
* Concrete provider that manages widget instances and performs API queries
|
|
62
|
+
* for widget manifests and configurations.
|
|
63
|
+
*
|
|
64
|
+
* Created automatically during module initialization; see {@link module} and
|
|
65
|
+
* {@link enableWidgetModule}.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const widget = provider.getWidget('my-widget');
|
|
70
|
+
* widget.initialize().subscribe(result => { ... });
|
|
71
|
+
* ```
|
|
32
72
|
*/
|
|
33
73
|
export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
34
74
|
// Private fields
|
|
@@ -37,8 +77,11 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
37
77
|
#event?: ModuleType<EventModule>;
|
|
38
78
|
|
|
39
79
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
80
|
+
* Creates a new `WidgetModuleProvider`.
|
|
81
|
+
*
|
|
82
|
+
* @param args - Provider dependencies.
|
|
83
|
+
* @param args.config - Resolved {@link WidgetModuleConfig} with HTTP client.
|
|
84
|
+
* @param args.event - Optional event module for dispatching lifecycle events.
|
|
42
85
|
*/
|
|
43
86
|
constructor(args: { config: WidgetModuleConfig; event?: ModuleType<EventModule> }) {
|
|
44
87
|
const { config, event } = args;
|
|
@@ -47,9 +90,13 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
47
90
|
}
|
|
48
91
|
|
|
49
92
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
93
|
+
* Creates a new {@link Widget} instance for the given name.
|
|
94
|
+
*
|
|
95
|
+
* The returned widget has not been initialized yet — call
|
|
96
|
+
* {@link Widget.initialize} to start the lifecycle.
|
|
97
|
+
*
|
|
98
|
+
* @param name - Unique widget name (used as lookup key).
|
|
99
|
+
* @param widgetPrams - Optional version or tag selector.
|
|
53
100
|
* @returns A new `Widget` instance.
|
|
54
101
|
*/
|
|
55
102
|
public getWidget(name: string, widgetPrams?: GetWidgetParameters['args']): Widget {
|
|
@@ -60,10 +107,12 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
60
107
|
}
|
|
61
108
|
|
|
62
109
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* @param
|
|
66
|
-
* @
|
|
110
|
+
* Fetches the manifest for a widget via the configured HTTP client.
|
|
111
|
+
*
|
|
112
|
+
* @param name - Unique widget name.
|
|
113
|
+
* @param widgetPrams - Optional version or tag selector.
|
|
114
|
+
* @returns Observable that emits the {@link WidgetManifest} and completes.
|
|
115
|
+
* @throws {WidgetManifestLoadError} When the manifest request fails.
|
|
67
116
|
*/
|
|
68
117
|
public getWidgetManifest(
|
|
69
118
|
name: string,
|
|
@@ -73,10 +122,12 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
73
122
|
}
|
|
74
123
|
|
|
75
124
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* @param
|
|
79
|
-
* @
|
|
125
|
+
* Fetches the configuration for a widget via the configured HTTP client.
|
|
126
|
+
*
|
|
127
|
+
* @param name - Unique widget name.
|
|
128
|
+
* @param widgetPrams - Optional version or tag selector.
|
|
129
|
+
* @returns Observable that emits the {@link WidgetConfig} and completes.
|
|
130
|
+
* @throws {WidgetConfigLoadError} When the config request fails.
|
|
80
131
|
*/
|
|
81
132
|
public getWidgetConfig(
|
|
82
133
|
name: string,
|
|
@@ -85,6 +136,14 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
85
136
|
return this._getWidgetConfig(name, widgetPrams);
|
|
86
137
|
}
|
|
87
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Internal: queries widget config from the API and maps HTTP errors to
|
|
141
|
+
* typed {@link WidgetConfigLoadError} instances.
|
|
142
|
+
*
|
|
143
|
+
* @param widgetKey - Widget identifier.
|
|
144
|
+
* @param args - Optional version or tag selector.
|
|
145
|
+
* @returns Observable emitting the {@link WidgetConfig}.
|
|
146
|
+
*/
|
|
88
147
|
protected _getWidgetConfig(
|
|
89
148
|
widgetKey: GetWidgetParameters['widgetKey'],
|
|
90
149
|
args?: GetWidgetParameters['args'],
|
|
@@ -116,11 +175,12 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
116
175
|
}
|
|
117
176
|
|
|
118
177
|
/**
|
|
119
|
-
*
|
|
120
|
-
* @
|
|
121
|
-
*
|
|
122
|
-
* @
|
|
123
|
-
* @
|
|
178
|
+
* Internal: queries widget manifest from the API and maps HTTP errors to
|
|
179
|
+
* typed {@link WidgetManifestLoadError} instances.
|
|
180
|
+
*
|
|
181
|
+
* @param widgetKey - Widget identifier.
|
|
182
|
+
* @param args - Optional version or tag selector.
|
|
183
|
+
* @returns Observable emitting the {@link WidgetManifest}.
|
|
124
184
|
*/
|
|
125
185
|
protected _getWidget(
|
|
126
186
|
widgetKey: GetWidgetParameters['widgetKey'],
|
|
@@ -154,7 +214,9 @@ export class WidgetModuleProvider implements IWidgetModuleProvider {
|
|
|
154
214
|
}
|
|
155
215
|
|
|
156
216
|
/**
|
|
157
|
-
* Disposes
|
|
217
|
+
* Disposes all internal query subscriptions.
|
|
218
|
+
*
|
|
219
|
+
* After disposal the provider should not be reused.
|
|
158
220
|
*/
|
|
159
221
|
public dispose() {
|
|
160
222
|
this.#subscription.unsubscribe();
|
|
@@ -4,8 +4,22 @@ import { module } from './module';
|
|
|
4
4
|
import type { WidgetModuleConfigBuilderCallback } from './WidgetModuleConfigurator';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Registers the widget module on a Fusion Framework configurator.
|
|
8
|
+
*
|
|
9
|
+
* Call this during framework setup to enable widget loading, manifest
|
|
10
|
+
* resolution, and script import capabilities.
|
|
11
|
+
*
|
|
12
|
+
* @param configurator - The framework modules configurator to register the
|
|
13
|
+
* widget module on.
|
|
14
|
+
* @param builder - Optional callback to customize the
|
|
15
|
+
* {@link WidgetModuleConfigurator} (e.g., set a custom HTTP client).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { enableWidgetModule } from '@equinor/fusion-framework-module-widget';
|
|
20
|
+
*
|
|
21
|
+
* enableWidgetModule(configurator);
|
|
22
|
+
* ```
|
|
9
23
|
*/
|
|
10
24
|
export const enableWidgetModule = (
|
|
11
25
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/src/errors.ts
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discriminator for categorizing widget HTTP errors.
|
|
3
|
+
*
|
|
4
|
+
* - `'not_found'` — HTTP 404
|
|
5
|
+
* - `'unauthorized'` — HTTP 401
|
|
6
|
+
* - `'unknown'` — any other error
|
|
7
|
+
*/
|
|
1
8
|
type WidgetErrorType = 'not_found' | 'unauthorized' | 'unknown';
|
|
2
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when a widget manifest cannot be loaded from the backend API.
|
|
12
|
+
*
|
|
13
|
+
* Use the static {@link fromHttpResponse} factory to create instances from
|
|
14
|
+
* HTTP responses with appropriate type mapping.
|
|
15
|
+
*/
|
|
3
16
|
export class WidgetManifestLoadError extends Error {
|
|
17
|
+
/**
|
|
18
|
+
* Creates a `WidgetManifestLoadError` from an HTTP `Response`.
|
|
19
|
+
*
|
|
20
|
+
* Maps HTTP 401 to `'unauthorized'`, 404 to `'not_found'`, and all other
|
|
21
|
+
* status codes to `'unknown'`.
|
|
22
|
+
*
|
|
23
|
+
* @param response - The failing HTTP response.
|
|
24
|
+
* @param options - Standard `ErrorOptions` (e.g., `cause`).
|
|
25
|
+
* @returns A typed `WidgetManifestLoadError`.
|
|
26
|
+
*/
|
|
4
27
|
static fromHttpResponse(response: Response, options?: ErrorOptions) {
|
|
5
28
|
switch (response.status) {
|
|
6
29
|
case 401:
|
|
@@ -18,6 +41,11 @@ export class WidgetManifestLoadError extends Error {
|
|
|
18
41
|
options,
|
|
19
42
|
);
|
|
20
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* @param type - Error category discriminator.
|
|
46
|
+
* @param message - Human-readable error description.
|
|
47
|
+
* @param options - Standard `ErrorOptions` (e.g., `cause`).
|
|
48
|
+
*/
|
|
21
49
|
constructor(
|
|
22
50
|
public readonly type: WidgetErrorType,
|
|
23
51
|
message?: string,
|
|
@@ -28,7 +56,23 @@ export class WidgetManifestLoadError extends Error {
|
|
|
28
56
|
}
|
|
29
57
|
}
|
|
30
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Error thrown when a widget configuration cannot be loaded from the backend API.
|
|
61
|
+
*
|
|
62
|
+
* Use the static {@link fromHttpResponse} factory to create instances from
|
|
63
|
+
* HTTP responses with appropriate type mapping.
|
|
64
|
+
*/
|
|
31
65
|
export class WidgetConfigLoadError extends Error {
|
|
66
|
+
/**
|
|
67
|
+
* Creates a `WidgetConfigLoadError` from an HTTP `Response`.
|
|
68
|
+
*
|
|
69
|
+
* Maps HTTP 401 to `'unauthorized'`, 404 to `'not_found'`, and all other
|
|
70
|
+
* status codes to `'unknown'`.
|
|
71
|
+
*
|
|
72
|
+
* @param response - The failing HTTP response.
|
|
73
|
+
* @param options - Standard `ErrorOptions` (e.g., `cause`).
|
|
74
|
+
* @returns A typed `WidgetConfigLoadError`.
|
|
75
|
+
*/
|
|
32
76
|
static fromHttpResponse(response: Response, options?: ErrorOptions) {
|
|
33
77
|
switch (response.status) {
|
|
34
78
|
case 401:
|
|
@@ -46,6 +90,11 @@ export class WidgetConfigLoadError extends Error {
|
|
|
46
90
|
options,
|
|
47
91
|
);
|
|
48
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* @param type - Error category discriminator.
|
|
95
|
+
* @param message - Human-readable error description.
|
|
96
|
+
* @param options - Standard `ErrorOptions` (e.g., `cause`).
|
|
97
|
+
*/
|
|
49
98
|
constructor(
|
|
50
99
|
public readonly type: WidgetErrorType,
|
|
51
100
|
message?: string,
|
|
@@ -56,7 +105,15 @@ export class WidgetConfigLoadError extends Error {
|
|
|
56
105
|
}
|
|
57
106
|
}
|
|
58
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Error thrown when a widget script module cannot be dynamically imported.
|
|
110
|
+
*/
|
|
59
111
|
export class WidgetScriptModuleError extends Error {
|
|
112
|
+
/**
|
|
113
|
+
* @param type - Error category discriminator.
|
|
114
|
+
* @param message - Human-readable error description.
|
|
115
|
+
* @param options - Standard `ErrorOptions` (e.g., `cause`).
|
|
116
|
+
*/
|
|
60
117
|
constructor(
|
|
61
118
|
public readonly type: WidgetErrorType,
|
|
62
119
|
message?: string,
|
package/src/events.ts
CHANGED
|
@@ -9,18 +9,31 @@ import type {
|
|
|
9
9
|
WidgetScriptModule,
|
|
10
10
|
} from './types';
|
|
11
11
|
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Base event-init shape for all widget lifecycle events.
|
|
14
|
+
*
|
|
15
|
+
* Extends `FrameworkEventInit` with a mandatory `name` field identifying
|
|
16
|
+
* the widget, and sets the event `source` to the originating {@link Widget}
|
|
17
|
+
* instance.
|
|
18
|
+
*
|
|
19
|
+
* @template TDetail - Additional detail properties merged with `{ name: string }`.
|
|
20
|
+
*/
|
|
13
21
|
export type WidgetEventInit<TDetail extends Record<string, unknown> | unknown = unknown> =
|
|
14
|
-
FrameworkEventInit<
|
|
15
|
-
/** additional event details and key of target event */
|
|
16
|
-
TDetail & { name: string },
|
|
17
|
-
/** source of the event */
|
|
18
|
-
Widget
|
|
19
|
-
>;
|
|
22
|
+
FrameworkEventInit<TDetail & { name: string }, Widget>;
|
|
20
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Concrete framework-event type for widget lifecycle events.
|
|
26
|
+
*
|
|
27
|
+
* @template TDetail - Additional detail properties.
|
|
28
|
+
*/
|
|
21
29
|
export type WidgetEvent<TDetail extends Record<string, unknown> | unknown = unknown> =
|
|
22
30
|
FrameworkEvent<WidgetEventInit<TDetail>>;
|
|
23
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Framework-event type for widget lifecycle failure events.
|
|
34
|
+
*
|
|
35
|
+
* Carries an `error` property in the event detail for error inspection.
|
|
36
|
+
*/
|
|
24
37
|
export type WidgetEventFailure = FrameworkEvent<
|
|
25
38
|
WidgetEventInit<{
|
|
26
39
|
error: WidgetConfig;
|
|
@@ -29,47 +42,53 @@ export type WidgetEventFailure = FrameworkEvent<
|
|
|
29
42
|
|
|
30
43
|
declare module '@equinor/fusion-framework-module-event' {
|
|
31
44
|
interface FrameworkEventMap {
|
|
32
|
-
/**
|
|
45
|
+
/** Fired when a widget has finished initializing its framework modules. */
|
|
33
46
|
onWidgetModulesLoaded: WidgetEvent<{
|
|
34
|
-
/**
|
|
47
|
+
/** The initialized module instances. */
|
|
35
48
|
modules: WidgetModulesInstance;
|
|
36
49
|
}>;
|
|
37
50
|
|
|
51
|
+
/** Fired when a widget manifest fetch starts. */
|
|
38
52
|
onWidgetManifestLoad: WidgetEvent;
|
|
39
|
-
/**
|
|
53
|
+
/** Fired when a widget manifest has been successfully loaded. */
|
|
40
54
|
onWidgetManifestLoaded: WidgetEvent<{
|
|
41
55
|
manifest: WidgetManifest;
|
|
42
56
|
}>;
|
|
57
|
+
/** Fired when a widget manifest fetch fails. */
|
|
43
58
|
onWidgetManifestFailure: WidgetEventFailure;
|
|
44
59
|
|
|
60
|
+
/** Fired when a widget config fetch starts. */
|
|
45
61
|
onWidgetConfigLoad: WidgetEvent;
|
|
46
|
-
/**
|
|
62
|
+
/** Fired when a widget config has been successfully loaded. */
|
|
47
63
|
onWidgetConfigLoaded: WidgetEvent<{
|
|
48
64
|
config: WidgetConfig;
|
|
49
65
|
}>;
|
|
66
|
+
/** Fired when a widget config fetch fails. */
|
|
50
67
|
onWidgetConfigFailure: WidgetEventFailure;
|
|
51
68
|
|
|
52
|
-
/**
|
|
69
|
+
/** Fired when a widget script import starts. */
|
|
53
70
|
onAWidgetScriptLoad: WidgetEvent;
|
|
71
|
+
/** Fired when a widget script has been successfully imported. */
|
|
54
72
|
onWidgetScriptLoaded: WidgetEvent<{
|
|
55
73
|
script: WidgetScriptModule;
|
|
56
74
|
}>;
|
|
75
|
+
/** Fired when a widget script import fails. */
|
|
57
76
|
onWidgetScriptFailure: WidgetEventFailure;
|
|
58
77
|
|
|
59
|
-
/**
|
|
78
|
+
/** Fired before the widget begins loading manifest, config, and script. */
|
|
60
79
|
onWidgetInitialize: WidgetEvent;
|
|
61
80
|
|
|
62
81
|
/**
|
|
63
|
-
*
|
|
82
|
+
* Fired after the widget has loaded manifest, config, and script.
|
|
64
83
|
*
|
|
65
|
-
*
|
|
84
|
+
* Not emitted until all loaders have settled (last emission).
|
|
66
85
|
*/
|
|
67
86
|
onWidgetInitialized: WidgetEvent;
|
|
68
87
|
|
|
69
|
-
/**
|
|
88
|
+
/** Fired when the widget fails to load manifest, config, or script. */
|
|
70
89
|
onWidgetInitializeFailure: WidgetEventFailure;
|
|
71
90
|
|
|
72
|
-
/**
|
|
91
|
+
/** Fired when the widget is disposed (unmounted from the DOM). */
|
|
73
92
|
onWidgetDispose: FrameworkEvent<WidgetEventInit>;
|
|
74
93
|
}
|
|
75
94
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Fusion Framework Widget Module
|
|
3
|
+
*
|
|
4
|
+
* Provides runtime loading, configuration, and lifecycle management for
|
|
5
|
+
* remote widget micro-frontends. Widgets are dynamically fetched, imported,
|
|
6
|
+
* and mounted into a host application.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export { WidgetModuleConfigurator, type WidgetModuleConfig } from './WidgetModuleConfigurator';
|
|
2
12
|
|
|
3
13
|
export { WidgetModuleProvider } from './WidgetModuleProvider';
|
|
4
14
|
|
|
@@ -8,4 +18,4 @@ export * from './types';
|
|
|
8
18
|
|
|
9
19
|
export { enableWidgetModule } from './enable-widget-module';
|
|
10
20
|
|
|
11
|
-
export { default, WidgetModule, module, moduleKey } from './module';
|
|
21
|
+
export { default, type WidgetModule, module, moduleKey } from './module';
|
package/src/module.ts
CHANGED
|
@@ -4,8 +4,14 @@ import type { ModuleDeps } from './types';
|
|
|
4
4
|
import { WidgetModuleConfigurator } from './WidgetModuleConfigurator';
|
|
5
5
|
import { type IWidgetModuleProvider, WidgetModuleProvider } from './WidgetModuleProvider';
|
|
6
6
|
|
|
7
|
+
/** Module registration key used in the Fusion Framework module map. */
|
|
7
8
|
export const moduleKey = 'widget';
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Module type definition binding the `'widget'` key to the
|
|
12
|
+
* {@link IWidgetModuleProvider} instance, {@link WidgetModuleConfigurator}
|
|
13
|
+
* configuration builder, and required {@link ModuleDeps}.
|
|
14
|
+
*/
|
|
9
15
|
export type WidgetModule = Module<
|
|
10
16
|
typeof moduleKey,
|
|
11
17
|
IWidgetModuleProvider,
|
|
@@ -13,6 +19,17 @@ export type WidgetModule = Module<
|
|
|
13
19
|
ModuleDeps
|
|
14
20
|
>;
|
|
15
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Widget module descriptor.
|
|
24
|
+
*
|
|
25
|
+
* Defines how the widget module is configured, initialized, and disposed
|
|
26
|
+
* within the Fusion Framework module system.
|
|
27
|
+
*
|
|
28
|
+
* - `configure` — creates a fresh {@link WidgetModuleConfigurator}
|
|
29
|
+
* - `initialize` — resolves the config, optionally acquires the event module,
|
|
30
|
+
* and returns a {@link WidgetModuleProvider}
|
|
31
|
+
* - `dispose` — cleans up provider subscriptions
|
|
32
|
+
*/
|
|
16
33
|
export const module: WidgetModule = {
|
|
17
34
|
name: moduleKey,
|
|
18
35
|
configure() {
|
|
@@ -31,6 +48,10 @@ export const module: WidgetModule = {
|
|
|
31
48
|
|
|
32
49
|
export default module;
|
|
33
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Augments the global Fusion Framework `Modules` interface so that
|
|
53
|
+
* `modules.widget` is typed as {@link WidgetModule}.
|
|
54
|
+
*/
|
|
34
55
|
declare module '@equinor/fusion-framework-module' {
|
|
35
56
|
interface Modules {
|
|
36
57
|
[moduleKey]: WidgetModule;
|
package/src/state/actions.ts
CHANGED
|
@@ -12,8 +12,17 @@ import type {
|
|
|
12
12
|
WidgetScriptModule,
|
|
13
13
|
} from '../types';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Factory that creates all widget state-machine actions.
|
|
17
|
+
*
|
|
18
|
+
* Each action (or async action triplet) drives a specific step in the
|
|
19
|
+
* widget lifecycle: manifest loading, config loading, script import,
|
|
20
|
+
* and initialization.
|
|
21
|
+
*
|
|
22
|
+
* @returns Action creators for the widget state machine.
|
|
23
|
+
*/
|
|
15
24
|
const createActions = () => ({
|
|
16
|
-
/**
|
|
25
|
+
/** Sets the manifest in state (optionally merging with existing). */
|
|
17
26
|
setManifest: createAction('set_manifest', (manifest: WidgetManifest, update?: boolean) => ({
|
|
18
27
|
payload: manifest,
|
|
19
28
|
meta: {
|
|
@@ -21,6 +30,7 @@ const createActions = () => ({
|
|
|
21
30
|
update,
|
|
22
31
|
},
|
|
23
32
|
})),
|
|
33
|
+
/** Async action triplet for fetching the widget manifest from the API. */
|
|
24
34
|
fetchManifest: createAsyncAction(
|
|
25
35
|
'fetch_manifest',
|
|
26
36
|
(payload: { key: string; args?: GetWidgetParameters['args'] }, update?: boolean) => ({
|
|
@@ -30,8 +40,9 @@ const createActions = () => ({
|
|
|
30
40
|
(manifest: WidgetManifest) => ({ payload: manifest }),
|
|
31
41
|
(error: unknown) => ({ payload: error }),
|
|
32
42
|
),
|
|
33
|
-
/**
|
|
43
|
+
/** Sets the widget config in state. */
|
|
34
44
|
setConfig: createAction('set_config', (config: WidgetConfig) => ({ payload: config })),
|
|
45
|
+
/** Async action triplet for fetching the widget config from the API. */
|
|
35
46
|
fetchConfig: createAsyncAction(
|
|
36
47
|
'fetch_config',
|
|
37
48
|
(payload: { key: string; args?: GetWidgetParameters['args'] }, update?: boolean) => ({
|
|
@@ -41,18 +52,21 @@ const createActions = () => ({
|
|
|
41
52
|
(config: WidgetConfig) => ({ payload: config }),
|
|
42
53
|
(error: unknown) => ({ payload: error }),
|
|
43
54
|
),
|
|
55
|
+
/** Sets the dynamically imported widget script module in state. */
|
|
44
56
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
57
|
setModule: createAction('set_module', (module: any) => ({ payload: module })),
|
|
58
|
+
/** Async action triplet for dynamically importing the widget script. */
|
|
46
59
|
importWidget: createAsyncAction(
|
|
47
60
|
'import_widget',
|
|
48
61
|
(entrypoint: string) => ({ payload: entrypoint }),
|
|
49
62
|
(module: WidgetScriptModule) => ({ payload: module }),
|
|
50
63
|
(error: unknown) => ({ payload: error }),
|
|
51
64
|
),
|
|
52
|
-
|
|
65
|
+
/** Sets the resolved widget framework-module instances in state. */
|
|
53
66
|
setInstance: createAction('set_instance', (instance: WidgetModulesInstance) => ({
|
|
54
67
|
payload: instance,
|
|
55
68
|
})),
|
|
69
|
+
/** Async action triplet for the overall widget initialization lifecycle. */
|
|
56
70
|
initialize: createAsyncAction(
|
|
57
71
|
'initialize_widget',
|
|
58
72
|
() => ({ payload: null }),
|
|
@@ -61,10 +75,14 @@ const createActions = () => ({
|
|
|
61
75
|
),
|
|
62
76
|
});
|
|
63
77
|
|
|
78
|
+
/** Singleton action creators used by the widget state machine. */
|
|
64
79
|
export const actions = createActions();
|
|
65
80
|
|
|
81
|
+
/** Map of action-creator names to their instance types. */
|
|
66
82
|
export type ActionBuilder = ReturnType<typeof createActions>;
|
|
67
83
|
|
|
84
|
+
/** Map of action types produced by the action builders. */
|
|
68
85
|
export type ActionMap = ActionInstanceMap<ActionBuilder>;
|
|
69
86
|
|
|
87
|
+
/** Union of all action types dispatched in the widget state machine. */
|
|
70
88
|
export type Actions = ActionTypes<typeof actions>;
|
|
@@ -12,6 +12,16 @@ enableMapSet();
|
|
|
12
12
|
import { type Actions, actions } from './actions';
|
|
13
13
|
import type { WidgetStateInitial, WidgetState } from '../types';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Creates an Immer-powered reducer for the widget state machine.
|
|
17
|
+
*
|
|
18
|
+
* Handles direct state setters (`setManifest`, `setConfig`, `setModule`,
|
|
19
|
+
* `setInstance`) and tracks in-flight async operations via the `status` set.
|
|
20
|
+
*
|
|
21
|
+
* @param value - Initial widget state (without `status`, which is added
|
|
22
|
+
* automatically as an empty `Set`).
|
|
23
|
+
* @returns A reducer function compatible with `FlowSubject`.
|
|
24
|
+
*/
|
|
15
25
|
export const createReducer = (value: WidgetStateInitial) =>
|
|
16
26
|
makeReducer<WidgetState, Actions>({ ...value, status: new Set() } as WidgetState, (builder) =>
|
|
17
27
|
builder
|
|
@@ -8,6 +8,18 @@ import type { Actions } from './actions';
|
|
|
8
8
|
import type { WidgetState, WidgetStateInitial } from '../types';
|
|
9
9
|
import type WidgetModuleProvider from '../WidgetModuleProvider';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Creates and wires the RxJS-based `FlowSubject` state machine for a single
|
|
13
|
+
* widget.
|
|
14
|
+
*
|
|
15
|
+
* Attaches the manifest-fetch, script-import, and config-fetch flows to the
|
|
16
|
+
* subject so that dispatched actions trigger the corresponding side effects.
|
|
17
|
+
*
|
|
18
|
+
* @param value - Initial widget state (name and optional pre-loaded data).
|
|
19
|
+
* @param provider - The {@link WidgetModuleProvider} used by flows to query
|
|
20
|
+
* the backend API.
|
|
21
|
+
* @returns A `FlowSubject` managing {@link WidgetState} via {@link Actions}.
|
|
22
|
+
*/
|
|
11
23
|
export const createState = (
|
|
12
24
|
value: WidgetStateInitial,
|
|
13
25
|
provider: WidgetModuleProvider,
|