@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
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { type ActionInstanceMap, type ActionTypes } from '@equinor/fusion-observable';
|
|
2
2
|
import type { GetWidgetParameters, WidgetConfig, WidgetManifest, WidgetModulesInstance, WidgetScriptModule } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Factory that creates all widget state-machine actions.
|
|
5
|
+
*
|
|
6
|
+
* Each action (or async action triplet) drives a specific step in the
|
|
7
|
+
* widget lifecycle: manifest loading, config loading, script import,
|
|
8
|
+
* and initialization.
|
|
9
|
+
*
|
|
10
|
+
* @returns Action creators for the widget state machine.
|
|
11
|
+
*/
|
|
3
12
|
declare const createActions: () => {
|
|
4
|
-
/**
|
|
13
|
+
/** Sets the manifest in state (optionally merging with existing). */
|
|
5
14
|
setManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: WidgetManifest, update?: boolean | undefined], WidgetManifest, "set_manifest", never, {
|
|
6
15
|
created: number;
|
|
7
16
|
update: boolean | undefined;
|
|
8
17
|
}>;
|
|
18
|
+
/** Async action triplet for fetching the widget manifest from the API. */
|
|
9
19
|
fetchManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[payload: {
|
|
10
20
|
key: string;
|
|
11
21
|
args?: GetWidgetParameters["args"];
|
|
@@ -18,8 +28,9 @@ declare const createActions: () => {
|
|
|
18
28
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: WidgetManifest], WidgetManifest, "fetch_manifest::success", never, never>;
|
|
19
29
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_manifest::failure", never, never>;
|
|
20
30
|
};
|
|
21
|
-
/**
|
|
31
|
+
/** Sets the widget config in state. */
|
|
22
32
|
setConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: WidgetConfig], WidgetConfig, "set_config", never, never>;
|
|
33
|
+
/** Async action triplet for fetching the widget config from the API. */
|
|
23
34
|
fetchConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[payload: {
|
|
24
35
|
key: string;
|
|
25
36
|
args?: GetWidgetParameters["args"];
|
|
@@ -32,23 +43,29 @@ declare const createActions: () => {
|
|
|
32
43
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: WidgetConfig], WidgetConfig, "fetch_config::success", never, never>;
|
|
33
44
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_config::failure", never, never>;
|
|
34
45
|
};
|
|
46
|
+
/** Sets the dynamically imported widget script module in state. */
|
|
35
47
|
setModule: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[module: any], any, "set_module", never, never>;
|
|
48
|
+
/** Async action triplet for dynamically importing the widget script. */
|
|
36
49
|
importWidget: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[entrypoint: string], string, "import_widget::request", never, never> & {
|
|
37
50
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[module: WidgetScriptModule], WidgetScriptModule, "import_widget::success", never, never>;
|
|
38
51
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "import_widget::failure", never, never>;
|
|
39
52
|
};
|
|
53
|
+
/** Sets the resolved widget framework-module instances in state. */
|
|
40
54
|
setInstance: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[instance: WidgetModulesInstance], WidgetModulesInstance, "set_instance", never, never>;
|
|
55
|
+
/** Async action triplet for the overall widget initialization lifecycle. */
|
|
41
56
|
initialize: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[], null, "initialize_widget::request", never, never> & {
|
|
42
57
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[], null, "initialize_widget::success", never, never>;
|
|
43
58
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "initialize_widget::failure", never, never>;
|
|
44
59
|
};
|
|
45
60
|
};
|
|
61
|
+
/** Singleton action creators used by the widget state machine. */
|
|
46
62
|
export declare const actions: {
|
|
47
|
-
/**
|
|
63
|
+
/** Sets the manifest in state (optionally merging with existing). */
|
|
48
64
|
setManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: WidgetManifest, update?: boolean | undefined], WidgetManifest, "set_manifest", never, {
|
|
49
65
|
created: number;
|
|
50
66
|
update: boolean | undefined;
|
|
51
67
|
}>;
|
|
68
|
+
/** Async action triplet for fetching the widget manifest from the API. */
|
|
52
69
|
fetchManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[payload: {
|
|
53
70
|
key: string;
|
|
54
71
|
args?: GetWidgetParameters["args"];
|
|
@@ -61,8 +78,9 @@ export declare const actions: {
|
|
|
61
78
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: WidgetManifest], WidgetManifest, "fetch_manifest::success", never, never>;
|
|
62
79
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_manifest::failure", never, never>;
|
|
63
80
|
};
|
|
64
|
-
/**
|
|
81
|
+
/** Sets the widget config in state. */
|
|
65
82
|
setConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: WidgetConfig], WidgetConfig, "set_config", never, never>;
|
|
83
|
+
/** Async action triplet for fetching the widget config from the API. */
|
|
66
84
|
fetchConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[payload: {
|
|
67
85
|
key: string;
|
|
68
86
|
args?: GetWidgetParameters["args"];
|
|
@@ -75,18 +93,25 @@ export declare const actions: {
|
|
|
75
93
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: WidgetConfig], WidgetConfig, "fetch_config::success", never, never>;
|
|
76
94
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_config::failure", never, never>;
|
|
77
95
|
};
|
|
96
|
+
/** Sets the dynamically imported widget script module in state. */
|
|
78
97
|
setModule: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[module: any], any, "set_module", never, never>;
|
|
98
|
+
/** Async action triplet for dynamically importing the widget script. */
|
|
79
99
|
importWidget: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[entrypoint: string], string, "import_widget::request", never, never> & {
|
|
80
100
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[module: WidgetScriptModule], WidgetScriptModule, "import_widget::success", never, never>;
|
|
81
101
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "import_widget::failure", never, never>;
|
|
82
102
|
};
|
|
103
|
+
/** Sets the resolved widget framework-module instances in state. */
|
|
83
104
|
setInstance: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[instance: WidgetModulesInstance], WidgetModulesInstance, "set_instance", never, never>;
|
|
105
|
+
/** Async action triplet for the overall widget initialization lifecycle. */
|
|
84
106
|
initialize: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[], null, "initialize_widget::request", never, never> & {
|
|
85
107
|
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[], null, "initialize_widget::success", never, never>;
|
|
86
108
|
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "initialize_widget::failure", never, never>;
|
|
87
109
|
};
|
|
88
110
|
};
|
|
111
|
+
/** Map of action-creator names to their instance types. */
|
|
89
112
|
export type ActionBuilder = ReturnType<typeof createActions>;
|
|
113
|
+
/** Map of action types produced by the action builders. */
|
|
90
114
|
export type ActionMap = ActionInstanceMap<ActionBuilder>;
|
|
115
|
+
/** Union of all action types dispatched in the widget state machine. */
|
|
91
116
|
export type Actions = ActionTypes<typeof actions>;
|
|
92
117
|
export {};
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import type { WidgetStateInitial, WidgetState } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an Immer-powered reducer for the widget state machine.
|
|
4
|
+
*
|
|
5
|
+
* Handles direct state setters (`setManifest`, `setConfig`, `setModule`,
|
|
6
|
+
* `setInstance`) and tracks in-flight async operations via the `status` set.
|
|
7
|
+
*
|
|
8
|
+
* @param value - Initial widget state (without `status`, which is added
|
|
9
|
+
* automatically as an empty `Set`).
|
|
10
|
+
* @returns A reducer function compatible with `FlowSubject`.
|
|
11
|
+
*/
|
|
2
12
|
export declare const createReducer: (value: WidgetStateInitial) => import("@equinor/fusion-observable").ReducerWithInitialState<WidgetState, import("@equinor/fusion-observable").PayloadAction<import("..").WidgetManifest, "set_manifest", {
|
|
3
13
|
created: number;
|
|
4
14
|
update: boolean | undefined;
|
|
@@ -2,4 +2,16 @@ import { FlowSubject } from '@equinor/fusion-observable';
|
|
|
2
2
|
import type { Actions } from './actions';
|
|
3
3
|
import type { WidgetState, WidgetStateInitial } from '../types';
|
|
4
4
|
import type WidgetModuleProvider from '../WidgetModuleProvider';
|
|
5
|
+
/**
|
|
6
|
+
* Creates and wires the RxJS-based `FlowSubject` state machine for a single
|
|
7
|
+
* widget.
|
|
8
|
+
*
|
|
9
|
+
* Attaches the manifest-fetch, script-import, and config-fetch flows to the
|
|
10
|
+
* subject so that dispatched actions trigger the corresponding side effects.
|
|
11
|
+
*
|
|
12
|
+
* @param value - Initial widget state (name and optional pre-loaded data).
|
|
13
|
+
* @param provider - The {@link WidgetModuleProvider} used by flows to query
|
|
14
|
+
* the backend API.
|
|
15
|
+
* @returns A `FlowSubject` managing {@link WidgetState} via {@link Actions}.
|
|
16
|
+
*/
|
|
5
17
|
export declare const createState: (value: WidgetStateInitial, provider: WidgetModuleProvider) => FlowSubject<WidgetState, Actions>;
|
|
@@ -2,6 +2,28 @@ import type { Flow } from '@equinor/fusion-observable';
|
|
|
2
2
|
import type { Actions } from './actions';
|
|
3
3
|
import type { WidgetState } from '../types';
|
|
4
4
|
import type WidgetModuleProvider from '../WidgetModuleProvider';
|
|
5
|
+
/**
|
|
6
|
+
* RxJS flow that reacts to `fetchManifest` actions by querying the
|
|
7
|
+
* {@link WidgetModuleProvider} for the manifest, emitting intermediate
|
|
8
|
+
* `setManifest` actions, and completing with a success or failure action.
|
|
9
|
+
*
|
|
10
|
+
* @param provider - The widget module provider used for API queries.
|
|
11
|
+
* @returns A `Flow` function for the widget state machine.
|
|
12
|
+
*/
|
|
5
13
|
export declare const handleFetchManifest: (provider: WidgetModuleProvider) => Flow<Actions, WidgetState>;
|
|
14
|
+
/**
|
|
15
|
+
* RxJS flow that reacts to `fetchConfig` actions by querying the
|
|
16
|
+
* {@link WidgetModuleProvider} for the widget config, emitting intermediate
|
|
17
|
+
* `setConfig` actions, and completing with a success or failure action.
|
|
18
|
+
*
|
|
19
|
+
* @param provider - The widget module provider used for API queries.
|
|
20
|
+
* @returns A `Flow` function for the widget state machine.
|
|
21
|
+
*/
|
|
6
22
|
export declare const handleFetchConfig: (provider: WidgetModuleProvider) => Flow<Actions, WidgetState>;
|
|
23
|
+
/**
|
|
24
|
+
* RxJS flow that reacts to `importWidget` actions by dynamically importing
|
|
25
|
+
* the widget’s JavaScript entry point URL and emitting success or failure.
|
|
26
|
+
*
|
|
27
|
+
* @returns A `Flow` function for the widget state machine.
|
|
28
|
+
*/
|
|
7
29
|
export declare const handleImportWidget: () => Flow<Actions, WidgetState>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -5,80 +5,121 @@ import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-se
|
|
|
5
5
|
import type { QueryCtorOptions } from '@equinor/fusion-query';
|
|
6
6
|
type Fusion = any;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Environment descriptor passed to widget render functions.
|
|
9
|
+
*
|
|
10
|
+
* @template TProps - Custom props type forwarded to the widget.
|
|
9
11
|
*/
|
|
10
12
|
export type WidgetEnv<TProps = unknown> = {
|
|
13
|
+
/** Base URL path the widget should use for routing (if applicable). */
|
|
11
14
|
basename?: string;
|
|
15
|
+
/** The resolved widget manifest. */
|
|
12
16
|
manifest?: WidgetManifest;
|
|
17
|
+
/** Arbitrary props forwarded from the host application. */
|
|
13
18
|
props?: TProps;
|
|
14
19
|
};
|
|
15
20
|
/**
|
|
16
|
-
*
|
|
21
|
+
* HTTP client abstraction used by the widget module to fetch manifests
|
|
22
|
+
* and configurations from the backend API.
|
|
17
23
|
*/
|
|
18
24
|
export type IClient = {
|
|
25
|
+
/** API version string appended as a query parameter to widget endpoints. */
|
|
19
26
|
apiVersion: string;
|
|
27
|
+
/** Base URL used to construct full import URLs for widget scripts. */
|
|
20
28
|
baseImportUrl: string;
|
|
29
|
+
/** Query constructor options for fetching a {@link WidgetManifest}. */
|
|
21
30
|
getWidgetManifest: QueryCtorOptions<WidgetManifest, GetWidgetParameters>;
|
|
31
|
+
/** Query constructor options for fetching a {@link WidgetConfig}. */
|
|
22
32
|
getWidgetConfig: QueryCtorOptions<WidgetConfig, GetWidgetParameters>;
|
|
23
33
|
};
|
|
24
34
|
/**
|
|
25
|
-
*
|
|
35
|
+
* Peer-dependency module tuple required by the widget module.
|
|
36
|
+
*
|
|
37
|
+
* Includes {@link HttpModule}, {@link ServiceDiscoveryModule}, and
|
|
38
|
+
* {@link EventModule} (the latter two are optional at runtime).
|
|
26
39
|
*/
|
|
27
40
|
export type ModuleDeps = [HttpModule, ServiceDiscoveryModule, EventModule];
|
|
28
41
|
/**
|
|
29
|
-
*
|
|
42
|
+
* Parameters for fetching a widget manifest or configuration.
|
|
30
43
|
*/
|
|
31
44
|
export type GetWidgetParameters = {
|
|
45
|
+
/** Unique key (name) identifying the widget. */
|
|
32
46
|
widgetKey: string;
|
|
47
|
+
/** Optional version or tag selector for the widget. */
|
|
33
48
|
args?: {
|
|
34
49
|
type: 'version' | 'tag';
|
|
35
50
|
value: string;
|
|
36
51
|
};
|
|
37
52
|
};
|
|
38
53
|
/**
|
|
39
|
-
*
|
|
54
|
+
* Function that builds a widget API endpoint URL from {@link GetWidgetParameters}.
|
|
40
55
|
*/
|
|
41
56
|
export type WidgetEndpointBuilder = (args: GetWidgetParameters) => string;
|
|
42
57
|
/**
|
|
43
|
-
*
|
|
58
|
+
* Metadata manifest describing a widget’s identity, version, and entry point.
|
|
59
|
+
*
|
|
60
|
+
* Fetched from the backend API during widget initialization.
|
|
44
61
|
*/
|
|
45
62
|
export type WidgetManifest = {
|
|
63
|
+
/** Unique backend identifier for the widget. */
|
|
46
64
|
id: string;
|
|
65
|
+
/** Human-readable widget name (also used as lookup key). */
|
|
47
66
|
name: string;
|
|
67
|
+
/** Semantic version of the widget. */
|
|
48
68
|
version: string;
|
|
69
|
+
/** Brief description of the widget’s purpose. */
|
|
49
70
|
description: string;
|
|
71
|
+
/** Optional list of maintainer identifiers. */
|
|
50
72
|
maintainers?: string[];
|
|
73
|
+
/** Relative path to the JavaScript entry point (e.g., `index.js`). */
|
|
51
74
|
entryPoint: string;
|
|
75
|
+
/** Base path for widget assets (combined with `entryPoint` to build the import URL). */
|
|
52
76
|
assetPath: string;
|
|
53
77
|
};
|
|
54
78
|
/**
|
|
55
|
-
*
|
|
79
|
+
* Describes a named endpoint with a URI and optional OAuth scopes.
|
|
56
80
|
*/
|
|
57
81
|
export type Endpoint = {
|
|
82
|
+
/** Endpoint name. */
|
|
58
83
|
name: string;
|
|
84
|
+
/** Endpoint URI. */
|
|
59
85
|
uri: string;
|
|
86
|
+
/** Optional OAuth scopes required for the endpoint. */
|
|
60
87
|
scopes?: string[];
|
|
61
88
|
};
|
|
62
89
|
/**
|
|
63
|
-
*
|
|
90
|
+
* Runtime configuration for a widget, including environment variables and
|
|
91
|
+
* backend endpoint mappings.
|
|
92
|
+
*
|
|
93
|
+
* @template TEnvironment - Custom environment shape.
|
|
64
94
|
*/
|
|
65
95
|
export type WidgetConfig<TEnvironment = unknown> = {
|
|
96
|
+
/** Widget-specific environment variables. */
|
|
66
97
|
environment: TEnvironment;
|
|
98
|
+
/** Map of endpoint names to URIs or structured {@link Endpoint} objects. */
|
|
67
99
|
endpoints: Record<string, string | Endpoint>;
|
|
68
100
|
};
|
|
69
101
|
/**
|
|
70
|
-
*
|
|
102
|
+
* Combined module set available inside a widget, merging custom modules with
|
|
103
|
+
* the standard {@link EventModule} and {@link ServiceDiscoveryModule}.
|
|
104
|
+
*
|
|
105
|
+
* @template TModules - Additional modules to combine.
|
|
71
106
|
*/
|
|
72
107
|
export type WidgetModules<TModules extends Array<AnyModule> | unknown = unknown> = CombinedModules<TModules, [
|
|
73
108
|
EventModule,
|
|
74
109
|
ServiceDiscoveryModule
|
|
75
110
|
]>;
|
|
76
111
|
/**
|
|
77
|
-
*
|
|
112
|
+
* Generic property bag passed from the host application to a widget render
|
|
113
|
+
* function.
|
|
78
114
|
*/
|
|
79
115
|
export type WidgetProps = Record<PropertyKey, unknown>;
|
|
80
116
|
/**
|
|
81
|
-
*
|
|
117
|
+
* Arguments passed to a widget’s render functions (`renderWidget`, `render`,
|
|
118
|
+
* `renderIcon`, and the default export).
|
|
119
|
+
*
|
|
120
|
+
* @template TFusion - Fusion instance type.
|
|
121
|
+
* @template TEnv - Environment descriptor type.
|
|
122
|
+
* @template TProps - Custom props type.
|
|
82
123
|
*/
|
|
83
124
|
export type WidgetRenderArgs<TFusion extends Fusion = Fusion, TEnv = WidgetEnv, TProps extends WidgetProps = WidgetProps> = {
|
|
84
125
|
fusion: TFusion;
|
|
@@ -86,31 +127,57 @@ export type WidgetRenderArgs<TFusion extends Fusion = Fusion, TEnv = WidgetEnv,
|
|
|
86
127
|
props?: TProps;
|
|
87
128
|
};
|
|
88
129
|
/**
|
|
89
|
-
*
|
|
130
|
+
* Describes the interface a widget script module must export.
|
|
131
|
+
*
|
|
132
|
+
* A dynamically imported widget entry point is expected to expose render
|
|
133
|
+
* functions that mount the widget into a given DOM element and return a
|
|
134
|
+
* cleanup function.
|
|
135
|
+
*
|
|
136
|
+
* @template TProps - Custom props type.
|
|
90
137
|
*/
|
|
91
138
|
export type WidgetScriptModule<TProps extends WidgetProps = WidgetProps> = {
|
|
139
|
+
/** Default render function (fallback entry point). */
|
|
92
140
|
default: (el: HTMLElement, args: WidgetRenderArgs, props?: TProps) => VoidFunction;
|
|
141
|
+
/** Primary render function for the widget body. */
|
|
93
142
|
renderWidget: (el: HTMLElement, args: WidgetRenderArgs, props?: TProps) => VoidFunction;
|
|
143
|
+
/** Render function for the widget’s icon representation. */
|
|
94
144
|
renderIcon: (el: HTMLElement, args: WidgetRenderArgs, props?: TProps) => VoidFunction;
|
|
145
|
+
/** Generic render function. */
|
|
95
146
|
render: (el: HTMLElement, args: WidgetRenderArgs, props?: TProps) => VoidFunction;
|
|
96
147
|
};
|
|
97
148
|
/**
|
|
98
|
-
*
|
|
149
|
+
* Resolved module instances available inside a running widget.
|
|
150
|
+
*
|
|
151
|
+
* @template TModules - Additional custom modules.
|
|
99
152
|
*/
|
|
100
153
|
export type WidgetModulesInstance<TModules extends Array<AnyModule> | unknown = unknown> = ModulesInstance<WidgetModules<TModules>>;
|
|
101
154
|
/**
|
|
102
|
-
*
|
|
155
|
+
* Internal state managed by a {@link Widget}’s `FlowSubject` state machine.
|
|
156
|
+
*
|
|
157
|
+
* Tracks manifest, config, imported script, framework module instances, and
|
|
158
|
+
* a set of in-flight status markers.
|
|
159
|
+
*
|
|
160
|
+
* @template TModules - Custom module types.
|
|
103
161
|
*/
|
|
104
162
|
export type WidgetState<TModules = any> = {
|
|
163
|
+
/** Widget name (lookup key). */
|
|
105
164
|
name: string;
|
|
165
|
+
/** Set of in-flight action base types (e.g., `'fetch_manifest'`). */
|
|
106
166
|
status: Set<string>;
|
|
167
|
+
/** Resolved widget configuration (when loaded). */
|
|
107
168
|
config?: WidgetConfig;
|
|
169
|
+
/** Resolved widget manifest (when loaded). */
|
|
108
170
|
manifest?: WidgetManifest;
|
|
171
|
+
/** Imported widget script module (when loaded). */
|
|
109
172
|
modules?: WidgetScriptModule;
|
|
173
|
+
/** Framework module instances created for the widget. */
|
|
110
174
|
instance?: WidgetModulesInstance<TModules>;
|
|
111
175
|
};
|
|
112
176
|
/**
|
|
113
|
-
*
|
|
177
|
+
* Initial widget state shape passed to the `Widget` constructor.
|
|
178
|
+
*
|
|
179
|
+
* Same as {@link WidgetState} but without the `status` set, which is
|
|
180
|
+
* initialized internally by the reducer.
|
|
114
181
|
*/
|
|
115
182
|
export type WidgetStateInitial = Omit<WidgetState, 'status'>;
|
|
116
183
|
export {};
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
import type { IClient, WidgetEndpointBuilder } from './types';
|
|
2
2
|
import type { IHttpClient } from '@equinor/fusion-framework-module-http';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a {@link WidgetEndpointBuilder} that produces manifest endpoint URLs.
|
|
5
|
+
*
|
|
6
|
+
* Routes versioned or tagged lookups to `/widgets/{key}/versions/{value}` and
|
|
7
|
+
* unversioned lookups to `/widgets/{key}`.
|
|
8
|
+
*
|
|
9
|
+
* @param apiVersion - API version string appended as a query parameter.
|
|
10
|
+
* @returns A function that maps {@link GetWidgetParameters} to a URL path.
|
|
11
|
+
*/
|
|
3
12
|
export declare const defaultManifestEndpointBuilder: (apiVersion: string) => WidgetEndpointBuilder;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a {@link WidgetEndpointBuilder} that produces config endpoint URLs.
|
|
15
|
+
*
|
|
16
|
+
* Routes versioned or tagged lookups to `/widgets/{key}/versions/{value}/config`
|
|
17
|
+
* and unversioned lookups to `/widgets/{key}/config`.
|
|
18
|
+
*
|
|
19
|
+
* @param apiVersion - API version string appended as a query parameter.
|
|
20
|
+
* @returns A function that maps {@link GetWidgetParameters} to a URL path.
|
|
21
|
+
*/
|
|
4
22
|
export declare const defaultConfigEndpointBuilder: (apiVersion: string) => WidgetEndpointBuilder;
|
|
23
|
+
/**
|
|
24
|
+
* Creates the default {@link IClient} that uses the given HTTP client to
|
|
25
|
+
* fetch widget manifests and configurations.
|
|
26
|
+
*
|
|
27
|
+
* Uses `api-version=1.0-preview` and the default manifest/config endpoint
|
|
28
|
+
* builders.
|
|
29
|
+
*
|
|
30
|
+
* @param httpClient - An `IHttpClient` instance (typically resolved from the
|
|
31
|
+
* `apps` service-discovery key).
|
|
32
|
+
* @returns A fully configured `IClient`.
|
|
33
|
+
*/
|
|
5
34
|
export declare const createDefaultClient: (httpClient: IHttpClient) => IClient;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "
|
|
1
|
+
export declare const version = "15.0.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-module-widget",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "15.0.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -38,22 +38,22 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"immer": "^11.0.0",
|
|
40
40
|
"rxjs": "^7.8.1",
|
|
41
|
-
"@equinor/fusion-observable": "
|
|
42
|
-
"@equinor/fusion-query": "
|
|
41
|
+
"@equinor/fusion-observable": "9.0.1",
|
|
42
|
+
"@equinor/fusion-query": "7.0.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"typescript": "^5.
|
|
46
|
-
"@equinor/fusion-framework-module-
|
|
47
|
-
"@equinor/fusion-framework-module": "^
|
|
48
|
-
"@equinor/fusion-framework-module
|
|
49
|
-
"@equinor/fusion-
|
|
50
|
-
"@equinor/fusion-
|
|
45
|
+
"typescript": "^5.9.3",
|
|
46
|
+
"@equinor/fusion-framework-module-event": "^6.0.0",
|
|
47
|
+
"@equinor/fusion-framework-module-http": "^8.0.0",
|
|
48
|
+
"@equinor/fusion-framework-module": "^6.0.0",
|
|
49
|
+
"@equinor/fusion-framework-module-service-discovery": "^10.0.0",
|
|
50
|
+
"@equinor/fusion-query": "^7.0.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@equinor/fusion-framework-module": "
|
|
54
|
-
"@equinor/fusion-framework-module-
|
|
55
|
-
"@equinor/fusion-framework-module-
|
|
56
|
-
"@equinor/fusion-framework-module-service-discovery": "
|
|
53
|
+
"@equinor/fusion-framework-module": "6.0.0",
|
|
54
|
+
"@equinor/fusion-framework-module-event": "6.0.0",
|
|
55
|
+
"@equinor/fusion-framework-module-http": "8.0.0",
|
|
56
|
+
"@equinor/fusion-framework-module-service-discovery": "10.0.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependenciesMeta": {
|
|
59
59
|
"@equinor/fusion-framework-module-event": {
|
package/src/Widget.ts
CHANGED
|
@@ -18,24 +18,56 @@ import type { WidgetModuleConfig } from './WidgetModuleConfigurator';
|
|
|
18
18
|
|
|
19
19
|
import './events';
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Manages the full lifecycle of a single Fusion widget.
|
|
23
|
+
*
|
|
24
|
+
* A `Widget` encapsulates fetching its manifest, dynamically importing its
|
|
25
|
+
* script entry point, loading configuration, and emitting lifecycle events.
|
|
26
|
+
* Internally it uses an RxJS-based `FlowSubject` state machine driven by
|
|
27
|
+
* actions and flows defined in the `state/` directory.
|
|
28
|
+
*
|
|
29
|
+
* Create instances via {@link WidgetModuleProvider.getWidget} rather than
|
|
30
|
+
* constructing directly.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const widget = provider.getWidget('my-widget');
|
|
35
|
+
* widget.initialize().subscribe(({ manifest, script }) => {
|
|
36
|
+
* script.renderWidget(el, { fusion, env: { manifest } });
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
22
40
|
export class Widget {
|
|
23
41
|
#state: FlowSubject<WidgetState, Actions>;
|
|
42
|
+
|
|
43
|
+
/** Human-readable widget name used as the lookup key for manifest and config. */
|
|
24
44
|
name: string;
|
|
45
|
+
|
|
46
|
+
/** Module-level HTTP client configuration used to resolve asset URLs. */
|
|
25
47
|
config?: WidgetModuleConfig;
|
|
48
|
+
|
|
49
|
+
/** Optional version or tag parameters forwarded to manifest/config endpoints. */
|
|
26
50
|
widgetPrams?: GetWidgetParameters['args'];
|
|
27
51
|
|
|
28
52
|
#subscription = new Subscription();
|
|
29
53
|
|
|
30
|
-
|
|
54
|
+
/** Current snapshot of the widget's internal state (manifest, config, modules, status). */
|
|
31
55
|
get state(): WidgetState {
|
|
32
56
|
return this.#state.value;
|
|
33
57
|
}
|
|
34
58
|
|
|
35
59
|
/**
|
|
36
|
-
* Constructs a new Widget instance.
|
|
37
|
-
*
|
|
38
|
-
*
|
|
60
|
+
* Constructs a new `Widget` instance.
|
|
61
|
+
*
|
|
62
|
+
* Prefer using {@link WidgetModuleProvider.getWidget} instead of calling
|
|
63
|
+
* this constructor directly.
|
|
64
|
+
*
|
|
65
|
+
* @param value - Initial widget state (at minimum, the widget `name`).
|
|
66
|
+
* @param args - Dependencies required by the widget.
|
|
67
|
+
* @param args.provider - The owning {@link WidgetModuleProvider}.
|
|
68
|
+
* @param args.config - Optional module-level HTTP client configuration.
|
|
69
|
+
* @param args.event - Optional event module for dispatching lifecycle events.
|
|
70
|
+
* @param args.widgetPrams - Optional version/tag selector for the widget.
|
|
39
71
|
*/
|
|
40
72
|
constructor(
|
|
41
73
|
value: WidgetStateInitial,
|
|
@@ -121,9 +153,15 @@ export class Widget {
|
|
|
121
153
|
}
|
|
122
154
|
|
|
123
155
|
/**
|
|
124
|
-
* Retrieves the manifest
|
|
125
|
-
*
|
|
126
|
-
*
|
|
156
|
+
* Retrieves the widget manifest as an observable stream.
|
|
157
|
+
*
|
|
158
|
+
* If the manifest is already cached in state it is emitted immediately.
|
|
159
|
+
* When `force_refresh` is `true`, a new fetch is dispatched regardless of
|
|
160
|
+
* cache status.
|
|
161
|
+
*
|
|
162
|
+
* @param force_refresh - When `true`, re-fetches the manifest even if cached.
|
|
163
|
+
* @returns Observable that emits the {@link WidgetManifest} and completes.
|
|
164
|
+
* @throws {Error} When the manifest fetch fails (wraps the underlying cause).
|
|
127
165
|
*/
|
|
128
166
|
public getManifest(force_refresh = false): Observable<WidgetManifest> {
|
|
129
167
|
return new Observable((subscriber) => {
|
|
@@ -159,9 +197,14 @@ export class Widget {
|
|
|
159
197
|
}
|
|
160
198
|
|
|
161
199
|
/**
|
|
162
|
-
* Retrieves the configuration
|
|
163
|
-
*
|
|
164
|
-
*
|
|
200
|
+
* Retrieves the widget configuration as an observable stream.
|
|
201
|
+
*
|
|
202
|
+
* Returns the cached config immediately when available. Set `force_refresh`
|
|
203
|
+
* to `true` to force a new fetch from the backend API.
|
|
204
|
+
*
|
|
205
|
+
* @param force_refresh - When `true`, re-fetches the config even if cached.
|
|
206
|
+
* @returns Observable that emits the {@link WidgetConfig} and completes.
|
|
207
|
+
* @throws {Error} When the config fetch fails (wraps the underlying cause).
|
|
165
208
|
*/
|
|
166
209
|
public getConfig(force_refresh = false): Observable<WidgetConfig> {
|
|
167
210
|
return new Observable((subscriber) => {
|
|
@@ -198,25 +241,35 @@ export class Widget {
|
|
|
198
241
|
}
|
|
199
242
|
|
|
200
243
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
244
|
+
* Dispatches a config fetch action into the state machine.
|
|
245
|
+
*
|
|
246
|
+
* @param update - When `true`, merges the fetched config with existing state
|
|
247
|
+
* instead of replacing it.
|
|
203
248
|
*/
|
|
204
249
|
public loadConfig(update?: boolean) {
|
|
205
250
|
this.#state.next(actions.fetchConfig({ key: this.name, ...this.widgetPrams }, update));
|
|
206
251
|
}
|
|
207
252
|
|
|
208
253
|
/**
|
|
209
|
-
*
|
|
210
|
-
*
|
|
254
|
+
* Dispatches a manifest fetch action into the state machine.
|
|
255
|
+
*
|
|
256
|
+
* @param update - When `true`, merges the fetched manifest with existing
|
|
257
|
+
* state instead of replacing it.
|
|
211
258
|
*/
|
|
212
259
|
public loadManifest(update?: boolean) {
|
|
213
260
|
this.#state.next(actions.fetchManifest({ key: this.name, ...this.widgetPrams }, update));
|
|
214
261
|
}
|
|
215
262
|
|
|
216
263
|
/**
|
|
217
|
-
* Retrieves the widget module as an observable stream.
|
|
218
|
-
*
|
|
219
|
-
*
|
|
264
|
+
* Retrieves the widget's script module as an observable stream.
|
|
265
|
+
*
|
|
266
|
+
* Resolves the manifest first, builds the full import URL from the asset
|
|
267
|
+
* path and entry point, then dynamically imports the script. The imported
|
|
268
|
+
* module is cached in state for subsequent calls.
|
|
269
|
+
*
|
|
270
|
+
* @param force_refresh - When `true`, re-imports the script even if cached.
|
|
271
|
+
* @returns Observable that emits the {@link WidgetScriptModule} and completes.
|
|
272
|
+
* @throws {Error} When the script import fails (wraps the underlying cause).
|
|
220
273
|
*/
|
|
221
274
|
public getWidgetModule(force_refresh = false): Observable<WidgetScriptModule> {
|
|
222
275
|
return new Observable((subscriber) => {
|
|
@@ -261,8 +314,12 @@ export class Widget {
|
|
|
261
314
|
});
|
|
262
315
|
}
|
|
263
316
|
/**
|
|
264
|
-
* Initializes the widget
|
|
265
|
-
*
|
|
317
|
+
* Initializes the widget by loading the manifest, importing the script, and
|
|
318
|
+
* preparing configuration. Emits a combined result when all resources are ready.
|
|
319
|
+
*
|
|
320
|
+
* @returns Observable that emits `{ manifest, script, config }` and completes
|
|
321
|
+
* once all resources have been resolved.
|
|
322
|
+
* @throws {Error} When any initialization step fails.
|
|
266
323
|
*/
|
|
267
324
|
public initialize(): Observable<{
|
|
268
325
|
manifest: WidgetManifest;
|
|
@@ -299,25 +356,35 @@ export class Widget {
|
|
|
299
356
|
});
|
|
300
357
|
}
|
|
301
358
|
/**
|
|
302
|
-
* Retrieves the widget module
|
|
303
|
-
*
|
|
304
|
-
*
|
|
359
|
+
* Retrieves the widget script module as a `Promise`.
|
|
360
|
+
*
|
|
361
|
+
* When `allow_cache` is `true` (default), resolves with the first emitted
|
|
362
|
+
* value (which may be cached). When `false`, waits for the last emission
|
|
363
|
+
* after a forced refresh.
|
|
364
|
+
*
|
|
365
|
+
* @param allow_cache - When `true`, uses `firstValueFrom`; when `false`,
|
|
366
|
+
* uses `lastValueFrom` after forcing a re-import.
|
|
367
|
+
* @returns Promise that resolves with the {@link WidgetScriptModule}.
|
|
305
368
|
*/
|
|
306
369
|
public getWidgetModuleAsync(allow_cache = true): Promise<WidgetScriptModule> {
|
|
307
370
|
const operator = allow_cache ? firstValueFrom : lastValueFrom;
|
|
308
371
|
return operator(this.getWidgetModule(!allow_cache));
|
|
309
372
|
}
|
|
310
373
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
* @param
|
|
374
|
+
* Replaces or merges the widget manifest in state.
|
|
375
|
+
*
|
|
376
|
+
* @param manifest - The new or partial manifest to set.
|
|
377
|
+
* @param replace - When `false` (default), the new manifest is merged with
|
|
378
|
+
* the existing one. Pass explicit `false` to merge, or omit to merge.
|
|
314
379
|
*/
|
|
315
380
|
public updateManifest(manifest: WidgetManifest, replace?: false) {
|
|
316
381
|
this.#state.next(actions.setManifest(manifest, !replace));
|
|
317
382
|
}
|
|
318
383
|
|
|
319
384
|
/**
|
|
320
|
-
* Disposes of the widget by unsubscribing from
|
|
385
|
+
* Disposes of the widget by unsubscribing from all internal subscriptions.
|
|
386
|
+
*
|
|
387
|
+
* After disposal the widget instance should not be reused.
|
|
321
388
|
*/
|
|
322
389
|
public dispose() {
|
|
323
390
|
this.#subscription.unsubscribe();
|