@equinor/fusion-framework-module-app 2.1.6 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/esm/AppConfigBuilder.js +57 -0
  3. package/dist/esm/AppConfigBuilder.js.map +1 -0
  4. package/dist/esm/AppConfigurator.js +82 -0
  5. package/dist/esm/AppConfigurator.js.map +1 -0
  6. package/dist/esm/AppModuleProvider.js +91 -0
  7. package/dist/esm/AppModuleProvider.js.map +1 -0
  8. package/dist/esm/app/App.js +172 -0
  9. package/dist/esm/app/App.js.map +1 -0
  10. package/dist/esm/app/actions.js +17 -0
  11. package/dist/esm/app/actions.js.map +1 -0
  12. package/dist/esm/app/create-reducer.js +25 -0
  13. package/dist/esm/app/create-reducer.js.map +1 -0
  14. package/dist/esm/app/create-state.js +12 -0
  15. package/dist/esm/app/create-state.js.map +1 -0
  16. package/dist/esm/app/flows.js +17 -0
  17. package/dist/esm/app/flows.js.map +1 -0
  18. package/dist/esm/app/types.js +2 -0
  19. package/dist/esm/app/types.js.map +1 -0
  20. package/dist/esm/errors.js +37 -0
  21. package/dist/esm/errors.js.map +1 -0
  22. package/dist/esm/events.js +7 -0
  23. package/dist/esm/events.js.map +1 -0
  24. package/dist/esm/index.js +4 -2
  25. package/dist/esm/index.js.map +1 -1
  26. package/dist/esm/module.js +6 -3
  27. package/dist/esm/module.js.map +1 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/dist/types/AppConfigBuilder.d.ts +26 -0
  30. package/dist/types/AppConfigurator.d.ts +28 -0
  31. package/dist/types/AppModuleProvider.d.ts +26 -0
  32. package/dist/types/app/App.d.ts +34 -0
  33. package/dist/types/app/actions.d.ts +46 -0
  34. package/dist/types/app/create-reducer.d.ts +3 -0
  35. package/dist/types/app/create-state.d.ts +5 -0
  36. package/dist/types/app/flows.d.ts +7 -0
  37. package/dist/types/app/types.d.ts +9 -0
  38. package/dist/types/errors.d.ts +16 -0
  39. package/dist/types/events.d.ts +22 -0
  40. package/dist/types/index.d.ts +4 -2
  41. package/dist/types/module.d.ts +5 -4
  42. package/dist/types/types.d.ts +29 -1
  43. package/package.json +14 -6
  44. package/src/AppConfigBuilder.ts +86 -0
  45. package/src/AppConfigurator.ts +101 -0
  46. package/src/AppModuleProvider.ts +159 -0
  47. package/src/app/App.ts +243 -0
  48. package/src/app/actions.ts +51 -0
  49. package/src/app/create-reducer.ts +41 -0
  50. package/src/app/create-state.ts +21 -0
  51. package/src/app/flows.ts +61 -0
  52. package/src/app/types.ts +11 -0
  53. package/src/errors.ts +53 -0
  54. package/src/events.ts +34 -0
  55. package/src/index.ts +10 -2
  56. package/src/module.ts +11 -12
  57. package/src/types.ts +42 -1
  58. package/dist/esm/configurator.js +0 -62
  59. package/dist/esm/configurator.js.map +0 -1
  60. package/dist/esm/provider.js +0 -83
  61. package/dist/esm/provider.js.map +0 -1
  62. package/dist/types/configurator.d.ts +0 -24
  63. package/dist/types/provider.d.ts +0 -43
  64. package/src/configurator.ts +0 -81
  65. package/src/provider.ts +0 -181
package/src/index.ts CHANGED
@@ -1,6 +1,14 @@
1
- export { AppConfigurator, IAppConfigurator, IAppModuleConfig } from './configurator';
2
- export { AppProvider, IAppProvider } from './provider';
1
+ export {
2
+ AppModuleConfig,
3
+ AppConfigurator,
4
+ IAppConfigurator,
5
+ AppModuleConfig as IAppModuleConfig,
6
+ } from './AppConfigurator';
7
+ export { AppModuleProvider } from './AppModuleProvider';
3
8
 
9
+ export { App } from './app/App';
10
+
11
+ export * from './events';
4
12
  export * from './types';
5
13
 
6
14
  export { default, AppModule, module, moduleKey } from './module';
package/src/module.ts CHANGED
@@ -1,31 +1,30 @@
1
- import { Module } from '@equinor/fusion-framework-module';
1
+ import { IModulesConfigurator, Module } from '@equinor/fusion-framework-module';
2
2
  import { ModuleDeps } from './types';
3
3
 
4
- import { IAppConfigurator, AppConfigurator } from './configurator';
5
- import { AppProvider, IAppProvider } from './provider';
4
+ import { IAppConfigurator, AppConfigurator } from './AppConfigurator';
5
+ import { AppModuleProvider } from './AppModuleProvider';
6
6
 
7
7
  export const moduleKey = 'app';
8
8
 
9
- export type AppModule = Module<
10
- typeof moduleKey,
11
- IAppProvider,
12
- IAppConfigurator<ModuleDeps>,
13
- ModuleDeps
14
- >;
9
+ export type AppModule = Module<typeof moduleKey, AppModuleProvider, IAppConfigurator, ModuleDeps>;
15
10
 
16
11
  export const module: AppModule = {
17
12
  name: moduleKey,
18
13
  configure: () => new AppConfigurator(),
19
14
  initialize: async (args) => {
20
- const config = await args.config.createConfig(args);
15
+ const config = await (args.config as AppConfigurator).createConfig(args);
21
16
  const event = await args.requireInstance('event').catch(() => undefined);
22
- return new AppProvider({ config, event });
17
+ return new AppModuleProvider({ config, event });
23
18
  },
24
19
  dispose: (args) => {
25
- (args.instance as unknown as AppProvider).dispose();
20
+ (args.instance as unknown as AppModuleProvider).dispose();
26
21
  },
27
22
  };
28
23
 
24
+ export const enableAppModule = (configurator: IModulesConfigurator) => {
25
+ configurator.addConfig({ module });
26
+ };
27
+
29
28
  export default module;
30
29
 
31
30
  declare module '@equinor/fusion-framework-module' {
package/src/types.ts CHANGED
@@ -1,7 +1,20 @@
1
+ import { AnyModule, CombinedModules, ModulesInstance } from '@equinor/fusion-framework-module';
1
2
  import type { EventModule } from '@equinor/fusion-framework-module-event';
2
3
  import type { HttpModule } from '@equinor/fusion-framework-module-http';
4
+ import { MsalModule } from '@equinor/fusion-framework-module-msal';
3
5
  import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';
4
6
 
7
+ // TODO
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ type Fusion = any;
10
+
11
+ export type AppEnv<TConfig = unknown, TProps = unknown> = {
12
+ basename?: string;
13
+ manifest?: AppManifest;
14
+ config?: AppConfig<TConfig>;
15
+ props?: TProps;
16
+ };
17
+
5
18
  // TODO: change to module-services when new app service is created
6
19
  export type ModuleDeps = [HttpModule, ServiceDiscoveryModule, EventModule];
7
20
 
@@ -20,7 +33,7 @@ type AppCategory = {
20
33
  };
21
34
 
22
35
  export type AppManifest = {
23
- key: string;
36
+ appKey: string;
24
37
  name: string;
25
38
  shortName: string;
26
39
  version: string;
@@ -45,3 +58,31 @@ export type AppConfig<TEnvironment = unknown> = {
45
58
  environment: TEnvironment;
46
59
  endpoints: Record<string, string | Endpoint>;
47
60
  };
61
+
62
+ /**
63
+ * @template TEnvironment - name of hosted environment
64
+ * @template TModule - ES module type (import return type)
65
+ */
66
+ export type AppBundle<TEnvironment = unknown, TModule = unknown> = {
67
+ manifest: AppManifest;
68
+ config: AppConfig<TEnvironment>;
69
+ module: TModule;
70
+ };
71
+
72
+ export type AppModules<TModules extends Array<AnyModule> | unknown = unknown> = CombinedModules<
73
+ TModules,
74
+ [EventModule, HttpModule, MsalModule]
75
+ >;
76
+
77
+ export type ComponentRenderArgs<TFusion extends Fusion = Fusion, TEnv = AppEnv> = {
78
+ fusion: TFusion;
79
+ env: TEnv;
80
+ };
81
+
82
+ export type AppScriptModule = {
83
+ default: (el: HTMLElement, args: ComponentRenderArgs) => VoidFunction;
84
+ renderApp: (el: HTMLElement, args: ComponentRenderArgs) => VoidFunction;
85
+ };
86
+
87
+ export type AppModulesInstance<TModules extends Array<AnyModule> | unknown = unknown> =
88
+ ModulesInstance<AppModules<TModules>>;
@@ -1,62 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { moduleKey } from './module';
11
- export class AppConfigurator {
12
- constructor() {
13
- this.defaultExpireTime = 1 * 60 * 1000;
14
- }
15
- _createHttpClient(init) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- const http = yield init.requireInstance('http');
18
- if (http.hasClient(moduleKey)) {
19
- return http.createClient(moduleKey);
20
- }
21
- else {
22
- const serviceDiscovery = yield init.requireInstance('serviceDiscovery');
23
- try {
24
- return yield serviceDiscovery.createClient('app');
25
- }
26
- catch (_a) {
27
- return yield serviceDiscovery.createClient('portal');
28
- }
29
- }
30
- });
31
- }
32
- createConfig(args) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- const httpClient = yield this._createHttpClient(args);
35
- const config = {
36
- getApp: {
37
- client: {
38
- fn: ({ appKey }) => httpClient.json$(`/api/apps/${appKey}`),
39
- },
40
- key: ({ appKey }) => appKey,
41
- },
42
- getApps: {
43
- client: {
44
- fn: () => httpClient.json$(`/api/apps`),
45
- },
46
- key: () => 'apps',
47
- },
48
- getConfig: {
49
- client: {
50
- fn: ({ appKey, tag }) => httpClient.json$(`/api/apps/${appKey}/config${tag ? `?tag=${tag}` : ''}`),
51
- },
52
- key: (args) => JSON.stringify(args),
53
- },
54
- };
55
- return this.processConfig(config);
56
- });
57
- }
58
- processConfig(config) {
59
- return config;
60
- }
61
- }
62
- //# sourceMappingURL=configurator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"configurator.js","sourceRoot":"","sources":["../../src/configurator.ts"],"names":[],"mappings":";;;;;;;;;AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAiBrC,MAAM,OAAO,eAAe;IAA5B;QAGI,sBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAyDtC,CAAC;IApDmB,iBAAiB,CAC7B,IAA2D;;YAE3D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAEhD,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;gBAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;aACvC;iBAAM;gBAEH,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;gBAIxE,IAAI;oBACA,OAAO,MAAM,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;iBACrD;gBAAC,WAAM;oBACJ,OAAO,MAAM,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;iBACxD;aACJ;QACL,CAAC;KAAA;IAEY,YAAY,CACrB,IAA2D;;YAE3D,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,MAAM,GAAqB;gBAC7B,MAAM,EAAE;oBACJ,MAAM,EAAE;wBACJ,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,MAAM,EAAE,CAAC;qBAC9D;oBACD,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM;iBAC9B;gBACD,OAAO,EAAE;oBACL,MAAM,EAAE;wBACJ,EAAE,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;qBAC1C;oBACD,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM;iBACpB;gBACD,SAAS,EAAE;oBACP,MAAM,EAAE;wBACJ,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,CACpB,UAAU,CAAC,KAAK,CAAC,aAAa,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;qBAChF;oBACD,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;iBACtC;aACJ,CAAC;YACF,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;KAAA;IAEM,aAAa,CAAC,MAAwB;QACzC,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ"}
@@ -1,83 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
- if (kind === "m") throw new TypeError("Private method is not writable");
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
- };
12
- var _AppProvider_appClient, _AppProvider_appsClient, _AppProvider_configClient, _AppProvider_current$, _AppProvider_subscription;
13
- import { BehaviorSubject, catchError, distinctUntilChanged, filter, firstValueFrom, from, map, merge, Observable, pairwise, scan, Subscription, switchMap, takeWhile, throwIfEmpty, } from 'rxjs';
14
- import { Query } from '@equinor/fusion-query';
15
- import { compareAppManifest } from './helpers';
16
- export class AppProvider extends Observable {
17
- get current() {
18
- return __classPrivateFieldGet(this, _AppProvider_current$, "f").value;
19
- }
20
- get current$() {
21
- return __classPrivateFieldGet(this, _AppProvider_current$, "f").pipe(distinctUntilChanged(compareAppManifest));
22
- }
23
- constructor(args) {
24
- super((observer) => this.current$.subscribe(observer));
25
- _AppProvider_appClient.set(this, void 0);
26
- _AppProvider_appsClient.set(this, void 0);
27
- _AppProvider_configClient.set(this, void 0);
28
- _AppProvider_current$.set(this, void 0);
29
- _AppProvider_subscription.set(this, new Subscription());
30
- const { event, config } = args;
31
- __classPrivateFieldSet(this, _AppProvider_current$, new BehaviorSubject(undefined), "f");
32
- __classPrivateFieldSet(this, _AppProvider_appClient, new Query(config.getApp), "f");
33
- __classPrivateFieldSet(this, _AppProvider_appsClient, new Query(config.getApps), "f");
34
- __classPrivateFieldSet(this, _AppProvider_configClient, new Query(config.getConfig), "f");
35
- __classPrivateFieldGet(this, _AppProvider_subscription, "f").add(__classPrivateFieldGet(this, _AppProvider_appClient, "f").complete);
36
- __classPrivateFieldGet(this, _AppProvider_subscription, "f").add(__classPrivateFieldGet(this, _AppProvider_appsClient, "f").complete);
37
- __classPrivateFieldGet(this, _AppProvider_subscription, "f").add(__classPrivateFieldGet(this, _AppProvider_configClient, "f").complete);
38
- __classPrivateFieldGet(this, _AppProvider_subscription, "f").add(this.current$
39
- .pipe(pairwise(), takeWhile(() => !!event))
40
- .subscribe(([previous, next]) => {
41
- event === null || event === void 0 ? void 0 : event.dispatchEvent('onCurrentAppChanged', {
42
- source: this,
43
- detail: { previous, next },
44
- });
45
- }));
46
- }
47
- getApp(appKey) {
48
- return Query.extractQueryValue(__classPrivateFieldGet(this, _AppProvider_appClient, "f").query({ appKey }).pipe(catchError((cause) => {
49
- throw Error('failed to load manifest', { cause });
50
- })));
51
- }
52
- getAllApps() {
53
- return Query.extractQueryValue(__classPrivateFieldGet(this, _AppProvider_appsClient, "f").query());
54
- }
55
- getAppConfig(appKey, tag) {
56
- return Query.extractQueryValue(__classPrivateFieldGet(this, _AppProvider_configClient, "f").query({ appKey, tag }).pipe(catchError((cause) => {
57
- throw Error('failed to load config', { cause });
58
- })));
59
- }
60
- setCurrentApp(appKey) {
61
- return new Promise((complete, error) => {
62
- const query$ = __classPrivateFieldGet(this, _AppProvider_appClient, "f").query({ appKey });
63
- __classPrivateFieldGet(this, _AppProvider_subscription, "f").add(Query.extractQueryValue(query$).subscribe({
64
- next: (x) => __classPrivateFieldGet(this, _AppProvider_current$, "f").next(x),
65
- error,
66
- complete,
67
- }));
68
- });
69
- }
70
- loadApp(appKey) {
71
- const loadApp$ = this.getApp(appKey).pipe(switchMap((manifest) => {
72
- return firstValueFrom(from(import(manifest.entry)).pipe(map((module) => ({ manifest, module }))));
73
- }));
74
- const loadConfig$ = this.getAppConfig(appKey).pipe(map((config) => ({ config })));
75
- return merge(loadApp$, loadConfig$).pipe(scan((acc, next) => Object.assign({}, acc, next), {}), filter((x) => ['manifest', 'module', 'config'].every((key) => !!x[key])), throwIfEmpty(() => 'failed to load application'));
76
- }
77
- dispose() {
78
- __classPrivateFieldGet(this, _AppProvider_subscription, "f").unsubscribe();
79
- }
80
- }
81
- _AppProvider_appClient = new WeakMap(), _AppProvider_appsClient = new WeakMap(), _AppProvider_configClient = new WeakMap(), _AppProvider_current$ = new WeakMap(), _AppProvider_subscription = new WeakMap();
82
- export default AppProvider;
83
- //# sourceMappingURL=provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/provider.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACH,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,MAAM,EACN,cAAc,EACd,IAAI,EACJ,GAAG,EACH,KAAK,EACL,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,GACf,MAAM,MAAM,CAAC;AAId,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAS9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AA0B/C,MAAM,OAAO,WAAY,SAAQ,UAAmC;IAUhE,IAAI,OAAO;QACP,OAAO,uBAAA,IAAI,6BAAU,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,QAAQ;QACR,OAAO,uBAAA,IAAI,6BAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,YAAY,IAAmE;QAC3E,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAlB3D,yCAAmD;QACnD,0CAAwC;QAExC,4CAAuE;QAEvE,wCAAoD;QAEpD,oCAAgB,IAAI,YAAY,EAAE,EAAC;QAa/B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAE/B,uBAAA,IAAI,yBAAa,IAAI,eAAe,CAA0B,SAAS,CAAC,MAAA,CAAC;QAEzE,uBAAA,IAAI,0BAAc,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAA,CAAC;QAC3C,uBAAA,IAAI,2BAAe,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAA,CAAC;QAC7C,uBAAA,IAAI,6BAAiB,IAAI,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAA,CAAC;QAEjD,uBAAA,IAAI,iCAAc,CAAC,GAAG,CAAC,uBAAA,IAAI,8BAAW,CAAC,QAAQ,CAAC,CAAC;QACjD,uBAAA,IAAI,iCAAc,CAAC,GAAG,CAAC,uBAAA,IAAI,+BAAY,CAAC,QAAQ,CAAC,CAAC;QAClD,uBAAA,IAAI,iCAAc,CAAC,GAAG,CAAC,uBAAA,IAAI,iCAAc,CAAC,QAAQ,CAAC,CAAC;QACpD,uBAAA,IAAI,iCAAc,CAAC,GAAG,CAClB,IAAI,CAAC,QAAQ;aACR,IAAI,CACD,QAAQ,EAAE,EACV,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAC3B;aACA,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;YAC5B,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,aAAa,CAAC,qBAAqB,EAAE;gBACxC,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;aAC7B,CAAC,CAAC;QACP,CAAC,CAAC,CACT,CAAC;IACN,CAAC;IAEM,MAAM,CAAC,MAAc;QACxB,OAAO,KAAK,CAAC,iBAAiB,CAC1B,uBAAA,IAAI,8BAAW,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAClC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE;YACjB,MAAM,KAAK,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,CACL,CACJ,CAAC;IACN,CAAC;IAEM,UAAU;QACb,OAAO,KAAK,CAAC,iBAAiB,CAAC,uBAAA,IAAI,+BAAY,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAEM,YAAY,CACf,MAAc,EACd,GAAY;QAEZ,OAAO,KAAK,CAAC,iBAAiB,CAC1B,uBAAA,IAAI,iCAAc,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAC1C,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE;YACjB,MAAM,KAAK,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CACL,CACJ,CAAC;IACN,CAAC;IAEM,aAAa,CAAC,MAAc;QAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,uBAAA,IAAI,8BAAW,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YACjD,uBAAA,IAAI,iCAAc,CAAC,GAAG,CAClB,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;gBACtC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAA,IAAI,6BAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnC,KAAK;gBACL,QAAQ;aACX,CAAC,CACL,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,OAAO,CACV,MAAc;QAEd,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CACrC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE;YACnB,OAAO,cAAc,CAGjB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAC7E,CAAC;QACN,CAAC,CAAC,CACL,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QAElF,OAAO,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,IAAI,CACpC,IAAI,CAAC,CAAC,GAAuB,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAEzE,MAAM,CAAC,CAAC,CAAC,EAAyC,EAAE,CAChD,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAsB,CAAC,CAAC,CAC/E,EACD,YAAY,CAAC,GAAG,EAAE,CAAC,4BAA4B,CAAC,CACnD,CAAC;IACN,CAAC;IAEM,OAAO;QACV,uBAAA,IAAI,iCAAc,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;CACJ;;AAUD,eAAe,WAAW,CAAC"}
@@ -1,24 +0,0 @@
1
- import { AnyModule, ModuleInitializerArgs } from '@equinor/fusion-framework-module';
2
- import { IHttpClient } from '@equinor/fusion-framework-module-http';
3
- import { QueryCtorOptions } from '@equinor/fusion-query';
4
- import type { AppConfig, AppManifest, ModuleDeps } from './types';
5
- export interface IAppModuleConfig {
6
- getApp: QueryCtorOptions<AppManifest, {
7
- appKey: string;
8
- }>;
9
- getApps: QueryCtorOptions<AppManifest[], void>;
10
- getConfig: QueryCtorOptions<AppConfig, {
11
- appKey: string;
12
- tag?: string;
13
- }>;
14
- }
15
- export interface IAppConfigurator<TDeps extends Array<AnyModule>> {
16
- createConfig: (args: ModuleInitializerArgs<IAppConfigurator<TDeps>, TDeps>) => Promise<IAppModuleConfig>;
17
- processConfig: (config: IAppModuleConfig) => IAppModuleConfig;
18
- }
19
- export declare class AppConfigurator<TDeps extends ModuleDeps = ModuleDeps> implements IAppConfigurator<TDeps> {
20
- defaultExpireTime: number;
21
- protected _createHttpClient(init: ModuleInitializerArgs<IAppConfigurator<TDeps>, TDeps>): Promise<IHttpClient>;
22
- createConfig(args: ModuleInitializerArgs<IAppConfigurator<TDeps>, TDeps>): Promise<IAppModuleConfig>;
23
- processConfig(config: IAppModuleConfig): IAppModuleConfig;
24
- }
@@ -1,43 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { ModuleType } from '@equinor/fusion-framework-module';
3
- import { EventModule, FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framework-module-event';
4
- import { IAppModuleConfig } from './configurator';
5
- import type { AppConfig, AppManifest } from './types';
6
- export interface IAppProvider {
7
- getApp(appKey: string): Observable<AppManifest>;
8
- getAllApps(): Observable<AppManifest[]>;
9
- getAppConfig<TType = unknown>(appKey: string): Observable<AppConfig<TType>>;
10
- setCurrentApp(appKey: string): void;
11
- readonly current$: Observable<AppManifest | undefined>;
12
- current: AppManifest | undefined;
13
- loadApp<TEnvironment = unknown, TModule = any>(appKey: string): Observable<AppBundle<TEnvironment, TModule>>;
14
- }
15
- export type AppBundle<TEnvironment = unknown, TModule = unknown> = {
16
- manifest: AppManifest;
17
- config: AppConfig<TEnvironment>;
18
- module: TModule;
19
- };
20
- export declare class AppProvider extends Observable<AppManifest | undefined> implements IAppProvider {
21
- #private;
22
- get current(): AppManifest | undefined;
23
- get current$(): Observable<AppManifest | undefined>;
24
- constructor(args: {
25
- config: IAppModuleConfig;
26
- event?: ModuleType<EventModule>;
27
- });
28
- getApp(appKey: string): Observable<AppManifest>;
29
- getAllApps(): Observable<AppManifest[]>;
30
- getAppConfig<TType = unknown>(appKey: string, tag?: string): Observable<AppConfig<TType>>;
31
- setCurrentApp(appKey: string): Promise<void>;
32
- loadApp<TEnvironment = unknown, TModule = unknown>(appKey: string): Observable<AppBundle<TEnvironment, TModule>>;
33
- dispose(): void;
34
- }
35
- declare module '@equinor/fusion-framework-module-event' {
36
- interface FrameworkEventMap {
37
- onCurrentAppChanged: FrameworkEvent<FrameworkEventInit<{
38
- next?: AppManifest;
39
- previous?: AppManifest;
40
- }, IAppProvider>>;
41
- }
42
- }
43
- export default AppProvider;
@@ -1,81 +0,0 @@
1
- import { AnyModule, ModuleInitializerArgs } from '@equinor/fusion-framework-module';
2
- import { IHttpClient } from '@equinor/fusion-framework-module-http';
3
- import { QueryCtorOptions } from '@equinor/fusion-query';
4
- import { moduleKey } from './module';
5
- import type { AppConfig, AppManifest, ModuleDeps } from './types';
6
-
7
- export interface IAppModuleConfig {
8
- getApp: QueryCtorOptions<AppManifest, { appKey: string }>;
9
- // TODO: add filter
10
- getApps: QueryCtorOptions<AppManifest[], void>;
11
- getConfig: QueryCtorOptions<AppConfig, { appKey: string; tag?: string }>;
12
- }
13
-
14
- export interface IAppConfigurator<TDeps extends Array<AnyModule>> {
15
- createConfig: (
16
- args: ModuleInitializerArgs<IAppConfigurator<TDeps>, TDeps>
17
- ) => Promise<IAppModuleConfig>;
18
- processConfig: (config: IAppModuleConfig) => IAppModuleConfig;
19
- }
20
-
21
- export class AppConfigurator<TDeps extends ModuleDeps = ModuleDeps>
22
- implements IAppConfigurator<TDeps>
23
- {
24
- defaultExpireTime = 1 * 60 * 1000;
25
-
26
- /**
27
- * WARNING: this function will be remove in future
28
- */
29
- protected async _createHttpClient(
30
- init: ModuleInitializerArgs<IAppConfigurator<TDeps>, TDeps>
31
- ): Promise<IHttpClient> {
32
- const http = await init.requireInstance('http');
33
- /** check if the http provider has configure a client */
34
- if (http.hasClient(moduleKey)) {
35
- return http.createClient(moduleKey);
36
- } else {
37
- /** load service discovery module */
38
- const serviceDiscovery = await init.requireInstance('serviceDiscovery');
39
-
40
- // TODO - remove when refactor portal service!
41
- /** resolve and create a client from discovery */
42
- try {
43
- return await serviceDiscovery.createClient('app');
44
- } catch {
45
- return await serviceDiscovery.createClient('portal');
46
- }
47
- }
48
- }
49
-
50
- public async createConfig(
51
- args: ModuleInitializerArgs<IAppConfigurator<TDeps>, TDeps>
52
- ): Promise<IAppModuleConfig> {
53
- const httpClient = await this._createHttpClient(args);
54
- const config: IAppModuleConfig = {
55
- getApp: {
56
- client: {
57
- fn: ({ appKey }) => httpClient.json$(`/api/apps/${appKey}`),
58
- },
59
- key: ({ appKey }) => appKey,
60
- },
61
- getApps: {
62
- client: {
63
- fn: () => httpClient.json$(`/api/apps`),
64
- },
65
- key: () => 'apps',
66
- },
67
- getConfig: {
68
- client: {
69
- fn: ({ appKey, tag }) =>
70
- httpClient.json$(`/api/apps/${appKey}/config${tag ? `?tag=${tag}` : ''}`),
71
- },
72
- key: (args) => JSON.stringify(args),
73
- },
74
- };
75
- return this.processConfig(config);
76
- }
77
-
78
- public processConfig(config: IAppModuleConfig): IAppModuleConfig {
79
- return config;
80
- }
81
- }
package/src/provider.ts DELETED
@@ -1,181 +0,0 @@
1
- import {
2
- BehaviorSubject,
3
- catchError,
4
- distinctUntilChanged,
5
- filter,
6
- firstValueFrom,
7
- from,
8
- map,
9
- merge,
10
- Observable,
11
- pairwise,
12
- scan,
13
- Subscription,
14
- switchMap,
15
- takeWhile,
16
- throwIfEmpty,
17
- } from 'rxjs';
18
-
19
- import { ModuleType } from '@equinor/fusion-framework-module';
20
-
21
- import { Query } from '@equinor/fusion-query';
22
-
23
- import {
24
- EventModule,
25
- FrameworkEvent,
26
- FrameworkEventInit,
27
- } from '@equinor/fusion-framework-module-event';
28
-
29
- import { IAppModuleConfig } from './configurator';
30
- import { compareAppManifest } from './helpers';
31
-
32
- import type { AppConfig, AppManifest } from './types';
33
-
34
- export interface IAppProvider {
35
- getApp(appKey: string): Observable<AppManifest>;
36
- getAllApps(): Observable<AppManifest[]>;
37
- getAppConfig<TType = unknown>(appKey: string): Observable<AppConfig<TType>>;
38
- setCurrentApp(appKey: string): void;
39
- readonly current$: Observable<AppManifest | undefined>;
40
- current: AppManifest | undefined;
41
- loadApp<TEnvironment = unknown, TModule = any>(
42
- appKey: string
43
- ): Observable<AppBundle<TEnvironment, TModule>>;
44
- }
45
-
46
- /**
47
- * @template TModule - ES module type
48
- */
49
- export type AppBundle<TEnvironment = unknown, TModule = unknown> = {
50
- manifest: AppManifest;
51
- config: AppConfig<TEnvironment>;
52
- /** ES module instance */
53
- module: TModule;
54
- };
55
-
56
- export class AppProvider extends Observable<AppManifest | undefined> implements IAppProvider {
57
- #appClient: Query<AppManifest, { appKey: string }>;
58
- #appsClient: Query<AppManifest[], void>;
59
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
- #configClient: Query<AppConfig<any>, { appKey: string; tag?: string }>;
61
-
62
- #current$: BehaviorSubject<AppManifest | undefined>;
63
-
64
- #subscription = new Subscription();
65
-
66
- get current(): AppManifest | undefined {
67
- return this.#current$.value;
68
- }
69
-
70
- get current$(): Observable<AppManifest | undefined> {
71
- return this.#current$.pipe(distinctUntilChanged(compareAppManifest));
72
- }
73
-
74
- constructor(args: { config: IAppModuleConfig; event?: ModuleType<EventModule> }) {
75
- super((observer) => this.current$.subscribe(observer));
76
-
77
- const { event, config } = args;
78
-
79
- this.#current$ = new BehaviorSubject<AppManifest | undefined>(undefined);
80
-
81
- this.#appClient = new Query(config.getApp);
82
- this.#appsClient = new Query(config.getApps);
83
- this.#configClient = new Query(config.getConfig);
84
-
85
- this.#subscription.add(this.#appClient.complete);
86
- this.#subscription.add(this.#appsClient.complete);
87
- this.#subscription.add(this.#configClient.complete);
88
- this.#subscription.add(
89
- this.current$
90
- .pipe(
91
- pairwise(),
92
- takeWhile(() => !!event)
93
- )
94
- .subscribe(([previous, next]) => {
95
- event?.dispatchEvent('onCurrentAppChanged', {
96
- source: this,
97
- detail: { previous, next },
98
- });
99
- })
100
- );
101
- }
102
-
103
- public getApp(appKey: string): Observable<AppManifest> {
104
- return Query.extractQueryValue(
105
- this.#appClient.query({ appKey }).pipe(
106
- catchError((cause) => {
107
- throw Error('failed to load manifest', { cause });
108
- })
109
- )
110
- );
111
- }
112
-
113
- public getAllApps(): Observable<AppManifest[]> {
114
- return Query.extractQueryValue(this.#appsClient.query());
115
- }
116
-
117
- public getAppConfig<TType = unknown>(
118
- appKey: string,
119
- tag?: string
120
- ): Observable<AppConfig<TType>> {
121
- return Query.extractQueryValue(
122
- this.#configClient.query({ appKey, tag }).pipe(
123
- catchError((cause) => {
124
- throw Error('failed to load config', { cause });
125
- })
126
- )
127
- );
128
- }
129
-
130
- public setCurrentApp(appKey: string): Promise<void> {
131
- return new Promise((complete, error) => {
132
- const query$ = this.#appClient.query({ appKey });
133
- this.#subscription.add(
134
- Query.extractQueryValue(query$).subscribe({
135
- next: (x) => this.#current$.next(x),
136
- error,
137
- complete,
138
- })
139
- );
140
- });
141
- }
142
-
143
- public loadApp<TEnvironment = unknown, TModule = unknown>(
144
- appKey: string
145
- ): Observable<AppBundle<TEnvironment, TModule>> {
146
- const loadApp$ = this.getApp(appKey).pipe(
147
- switchMap((manifest) => {
148
- return firstValueFrom(
149
- // TODO: use source from manifest when service is ready!
150
- /* @vite-ignore */
151
- from(import(manifest.entry)).pipe(map((module) => ({ manifest, module })))
152
- );
153
- })
154
- );
155
-
156
- const loadConfig$ = this.getAppConfig(appKey).pipe(map((config) => ({ config })));
157
-
158
- return merge(loadApp$, loadConfig$).pipe(
159
- scan((acc: Partial<AppBundle>, next) => Object.assign({}, acc, next), {}),
160
- /** only output when all attributes are filled */
161
- filter((x): x is AppBundle<TEnvironment, TModule> =>
162
- ['manifest', 'module', 'config'].every((key) => !!x[key as keyof AppBundle])
163
- ),
164
- throwIfEmpty(() => 'failed to load application')
165
- );
166
- }
167
-
168
- public dispose() {
169
- this.#subscription.unsubscribe();
170
- }
171
- }
172
-
173
- declare module '@equinor/fusion-framework-module-event' {
174
- interface FrameworkEventMap {
175
- onCurrentAppChanged: FrameworkEvent<
176
- FrameworkEventInit<{ next?: AppManifest; previous?: AppManifest }, IAppProvider>
177
- >;
178
- }
179
- }
180
-
181
- export default AppProvider;