@equinor/fusion-framework-react-app 6.0.0 → 6.0.2

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 (70) hide show
  1. package/CHANGELOG.md +457 -433
  2. package/dist/esm/ag-grid/useTheme.js.map +1 -1
  3. package/dist/esm/bookmark/useBookmark.js.map +1 -1
  4. package/dist/esm/bookmark/useCurrentBookmark.js.map +1 -1
  5. package/dist/esm/create-component.js.map +1 -1
  6. package/dist/esm/create-legacy-app.js +1 -0
  7. package/dist/esm/create-legacy-app.js.map +1 -1
  8. package/dist/esm/feature-flag/enable-feature-flag.js.map +1 -1
  9. package/dist/esm/feature-flag/useFeature.js.map +1 -1
  10. package/dist/esm/framework/index.js.map +1 -1
  11. package/dist/esm/make-component.js.map +1 -1
  12. package/dist/esm/msal/useAccessToken.js.map +1 -1
  13. package/dist/esm/msal/useCurrentAccount.js.map +1 -1
  14. package/dist/esm/msal/useToken.js.map +1 -1
  15. package/dist/esm/navigation/useRouter.js.map +1 -1
  16. package/dist/esm/render-app.js.map +1 -1
  17. package/dist/esm/render-component.js.map +1 -1
  18. package/dist/esm/settings/useAppSetting.js +1 -2
  19. package/dist/esm/settings/useAppSetting.js.map +1 -1
  20. package/dist/esm/settings/useAppSettings.js +1 -2
  21. package/dist/esm/settings/useAppSettings.js.map +1 -1
  22. package/dist/esm/settings/useAppSettingsStatus.js.map +1 -1
  23. package/dist/esm/useAppEnvironmentVariables.js.map +1 -1
  24. package/dist/esm/useAppModule.js.map +1 -1
  25. package/dist/esm/version.js +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/dist/types/ag-grid/useTheme.d.ts +1 -1
  28. package/dist/types/bookmark/useCurrentBookmark.d.ts +1 -1
  29. package/dist/types/create-component.d.ts +2 -2
  30. package/dist/types/create-legacy-app.d.ts +2 -1
  31. package/dist/types/feature-flag/enable-feature-flag.d.ts +5 -17
  32. package/dist/types/feature-flag/useFeature.d.ts +1 -1
  33. package/dist/types/make-component.d.ts +2 -2
  34. package/dist/types/msal/useCurrentAccount.d.ts +1 -1
  35. package/dist/types/msal/useToken.d.ts +1 -1
  36. package/dist/types/navigation/useNavigationModule.d.ts +1 -1
  37. package/dist/types/navigation/useRouter.d.ts +1 -1
  38. package/dist/types/render-app.d.ts +2 -1
  39. package/dist/types/settings/useAppSettings.d.ts +1 -1
  40. package/dist/types/useAppEnvironmentVariables.d.ts +1 -1
  41. package/dist/types/version.d.ts +1 -1
  42. package/package.json +18 -18
  43. package/src/ag-grid/useTheme.ts +7 -7
  44. package/src/bookmark/index.ts +5 -5
  45. package/src/bookmark/useBookmark.ts +2 -2
  46. package/src/bookmark/useCurrentBookmark.ts +17 -17
  47. package/src/context/useContextProvider.ts +1 -1
  48. package/src/create-component.tsx +40 -39
  49. package/src/create-legacy-app.tsx +25 -24
  50. package/src/feature-flag/enable-feature-flag.ts +42 -43
  51. package/src/feature-flag/index.ts +3 -3
  52. package/src/feature-flag/useFeature.ts +40 -40
  53. package/src/framework/index.ts +2 -2
  54. package/src/index.ts +7 -7
  55. package/src/make-component.tsx +34 -33
  56. package/src/msal/useAccessToken.ts +3 -3
  57. package/src/msal/useCurrentAccount.ts +3 -3
  58. package/src/msal/useToken.ts +16 -16
  59. package/src/navigation/useNavigationModule.ts +1 -1
  60. package/src/navigation/useRouter.ts +4 -4
  61. package/src/render-app.ts +5 -5
  62. package/src/render-component.tsx +16 -16
  63. package/src/settings/useAppSetting.ts +49 -50
  64. package/src/settings/useAppSettings.ts +38 -39
  65. package/src/settings/useAppSettingsStatus.ts +19 -19
  66. package/src/useAppEnvironmentVariables.ts +20 -20
  67. package/src/useAppModule.ts +15 -15
  68. package/src/useAppModules.ts +1 -1
  69. package/src/version.ts +1 -1
  70. package/src/widget/index.ts +4 -4
@@ -4,9 +4,9 @@ import { EMPTY, combineLatest, map } from 'rxjs';
4
4
 
5
5
  import { useFrameworkModule } from '@equinor/fusion-framework-react';
6
6
  import { useObservableState } from '@equinor/fusion-observable/react';
7
- import {
8
- type FeatureFlagModule,
9
- type IFeatureFlag,
7
+ import type {
8
+ FeatureFlagModule,
9
+ IFeatureFlag,
10
10
  } from '@equinor/fusion-framework-module-feature-flag';
11
11
  import { findFeature } from '@equinor/fusion-framework-module-feature-flag/selectors';
12
12
 
@@ -19,48 +19,48 @@ import { useAppModule } from '../useAppModule';
19
19
  * @returns An object containing the feature flag, toggle function, and error (if any).
20
20
  */
21
21
  export const useFeature = <T = unknown>(
22
- key: string,
22
+ key: string,
23
23
  ): {
24
- feature?: IFeatureFlag<T>;
25
- toggleFeature: (enabled?: boolean) => void;
26
- error?: unknown;
24
+ feature?: IFeatureFlag<T>;
25
+ toggleFeature: (enabled?: boolean) => void;
26
+ error?: unknown;
27
27
  } => {
28
- const appProvider = useAppModule<FeatureFlagModule>('featureFlag');
29
- const frameworkProvider = useFrameworkModule<FeatureFlagModule>('featureFlag');
28
+ const appProvider = useAppModule<FeatureFlagModule>('featureFlag');
29
+ const frameworkProvider = useFrameworkModule<FeatureFlagModule>('featureFlag');
30
30
 
31
- /** get all available feature flags */
32
- const features$ = useMemo(() => {
33
- /** the framework does not have the feature flag module */
34
- if (!frameworkProvider) {
35
- return appProvider.features$;
36
- }
37
- /** merge feature flags from framework and application */
38
- return combineLatest({
39
- framework: frameworkProvider.features$,
40
- app: appProvider.features$,
41
- }).pipe(
42
- map(({ framework, app }) => {
43
- return { ...framework, ...app };
44
- }),
45
- );
46
- }, [appProvider, frameworkProvider]);
31
+ /** get all available feature flags */
32
+ const features$ = useMemo(() => {
33
+ /** the framework does not have the feature flag module */
34
+ if (!frameworkProvider) {
35
+ return appProvider.features$;
36
+ }
37
+ /** merge feature flags from framework and application */
38
+ return combineLatest({
39
+ framework: frameworkProvider.features$,
40
+ app: appProvider.features$,
41
+ }).pipe(
42
+ map(({ framework, app }) => {
43
+ return { ...framework, ...app };
44
+ }),
45
+ );
46
+ }, [appProvider, frameworkProvider]);
47
47
 
48
- /** find feature flag by the provided key */
49
- const feature$ = useMemo(() => features$.pipe(findFeature<T>(key)), [features$, key]);
48
+ /** find feature flag by the provided key */
49
+ const feature$ = useMemo(() => features$.pipe(findFeature<T>(key)), [features$, key]);
50
50
 
51
- const { value: feature, error } = useObservableState(feature$ ?? EMPTY);
51
+ const { value: feature, error } = useObservableState(feature$ ?? EMPTY);
52
52
 
53
- const toggleFeature = useCallback(
54
- (enable?: boolean) => {
55
- /** if no value provided, invert the current value */
56
- const enabled = enable === undefined ? !appProvider.getFeature(key)?.enabled : enable;
57
- appProvider.toggleFeature({
58
- key,
59
- enabled,
60
- });
61
- },
62
- [appProvider, key],
63
- );
53
+ const toggleFeature = useCallback(
54
+ (enable?: boolean) => {
55
+ /** if no value provided, invert the current value */
56
+ const enabled = enable === undefined ? !appProvider.getFeature(key)?.enabled : enable;
57
+ appProvider.toggleFeature({
58
+ key,
59
+ enabled,
60
+ });
61
+ },
62
+ [appProvider, key],
63
+ );
64
64
 
65
- return { feature, toggleFeature, error };
65
+ return { feature, toggleFeature, error };
66
66
  };
@@ -2,6 +2,6 @@ export { useFramework } from '@equinor/fusion-framework-react';
2
2
 
3
3
  // TODO
4
4
  export {
5
- useCurrentUser,
6
- useHttpClient as useFrameworkHttpClient,
5
+ useCurrentUser,
6
+ useHttpClient as useFrameworkHttpClient,
7
7
  } from '@equinor/fusion-framework-react/hooks';
package/src/index.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  export type {
2
- AppConfig,
3
- AppEnv,
4
- AppModuleInitiator,
5
- AppModules,
6
- AppModulesInstance,
7
- AppRenderFn,
8
- IAppConfigurator,
2
+ AppConfig,
3
+ AppEnv,
4
+ AppModuleInitiator,
5
+ AppModules,
6
+ AppModulesInstance,
7
+ AppRenderFn,
8
+ IAppConfigurator,
9
9
  } from '@equinor/fusion-framework-app';
10
10
 
11
11
  export { AppManifest } from '@equinor/fusion-framework-module-app';
@@ -1,9 +1,10 @@
1
- import React, { lazy } from 'react';
1
+ import type React from 'react';
2
+ import { lazy } from 'react';
2
3
 
3
4
  import { FrameworkProvider } from '@equinor/fusion-framework-react';
4
5
  import type { Fusion } from '@equinor/fusion-framework-react';
5
6
 
6
- import { AppEnv, configureModules } from '@equinor/fusion-framework-app';
7
+ import { type AppEnv, configureModules } from '@equinor/fusion-framework-app';
7
8
  import type { AppModuleInitiator, AppModulesInstance } from '@equinor/fusion-framework-app';
8
9
 
9
10
  import type { AnyModule } from '@equinor/fusion-framework-module';
@@ -13,13 +14,13 @@ import type { FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framewo
13
14
  import { ModuleProvider as AppModuleProvider } from '@equinor/fusion-framework-react-module';
14
15
 
15
16
  export type ComponentRenderArgs<TFusion extends Fusion = Fusion, TEnv = AppEnv> = {
16
- fusion: TFusion;
17
- env: TEnv;
17
+ fusion: TFusion;
18
+ env: TEnv;
18
19
  };
19
20
 
20
21
  export type ComponentRenderer<TFusion extends Fusion = Fusion, TEnv = AppEnv> = (
21
- fusion: TFusion,
22
- env: TEnv,
22
+ fusion: TFusion,
23
+ env: TEnv,
23
24
  ) => React.LazyExoticComponent<React.ComponentType>;
24
25
 
25
26
  /**
@@ -44,40 +45,40 @@ export type ComponentRenderer<TFusion extends Fusion = Fusion, TEnv = AppEnv> =
44
45
  * initializes the specified modules and provides the necessary Fusion and module context.
45
46
  */
46
47
  export const makeComponent = <
47
- TModules extends Array<AnyModule>,
48
- TRef extends Fusion = Fusion,
49
- TEnv extends AppEnv = AppEnv,
48
+ TModules extends Array<AnyModule>,
49
+ TRef extends Fusion = Fusion,
50
+ TEnv extends AppEnv = AppEnv,
50
51
  >(
51
- Component: React.ReactNode,
52
- args: { fusion: TRef; env: TEnv },
53
- configure?: AppModuleInitiator<TModules, TRef, TEnv>,
52
+ Component: React.ReactNode,
53
+ args: { fusion: TRef; env: TEnv },
54
+ configure?: AppModuleInitiator<TModules, TRef, TEnv>,
54
55
  ): React.LazyExoticComponent<React.ComponentType> =>
55
- lazy(async () => {
56
- const init = configureModules<TModules, TRef, TEnv>(configure);
57
- const modules = (await init(args)) as unknown as AppModulesInstance;
56
+ lazy(async () => {
57
+ const init = configureModules<TModules, TRef, TEnv>(configure);
58
+ const modules = (await init(args)) as unknown as AppModulesInstance;
58
59
 
59
- const { fusion } = args;
60
+ const { fusion } = args;
60
61
 
61
- modules.event.dispatchEvent('onReactAppLoaded', {
62
- detail: { modules, fusion },
63
- source: Component,
64
- });
65
-
66
- return {
67
- default: () => (
68
- <FrameworkProvider value={fusion}>
69
- <AppModuleProvider value={modules}>{Component}</AppModuleProvider>
70
- </FrameworkProvider>
71
- ),
72
- };
62
+ modules.event.dispatchEvent('onReactAppLoaded', {
63
+ detail: { modules, fusion },
64
+ source: Component,
73
65
  });
74
66
 
67
+ return {
68
+ default: () => (
69
+ <FrameworkProvider value={fusion}>
70
+ <AppModuleProvider value={modules}>{Component}</AppModuleProvider>
71
+ </FrameworkProvider>
72
+ ),
73
+ };
74
+ });
75
+
75
76
  declare module '@equinor/fusion-framework-module-event' {
76
- interface FrameworkEventMap {
77
- onReactAppLoaded: FrameworkEvent<
78
- FrameworkEventInit<{ modules: AppModulesInstance; fusion: Fusion }, React.ComponentType>
79
- >;
80
- }
77
+ interface FrameworkEventMap {
78
+ onReactAppLoaded: FrameworkEvent<
79
+ FrameworkEventInit<{ modules: AppModulesInstance; fusion: Fusion }, React.ComponentType>
80
+ >;
81
+ }
81
82
  }
82
83
 
83
84
  export default makeComponent;
@@ -7,8 +7,8 @@ import { useToken } from './useToken';
7
7
  * @returns An object containing the access token, pending state, and error.
8
8
  */
9
9
  export const useAccessToken = (req: {
10
- scopes: string[];
10
+ scopes: string[];
11
11
  }): { token?: string; pending: boolean; error: unknown } => {
12
- const { token, error, pending } = useToken(req);
13
- return { token: token?.accessToken, pending, error };
12
+ const { token, error, pending } = useToken(req);
13
+ return { token: token?.accessToken, pending, error };
14
14
  };
@@ -1,4 +1,4 @@
1
- import { AccountInfo } from '@equinor/fusion-framework-module-msal';
1
+ import type { AccountInfo } from '@equinor/fusion-framework-module-msal';
2
2
  import useAppModule from '../useAppModule';
3
3
 
4
4
  /**
@@ -6,6 +6,6 @@ import useAppModule from '../useAppModule';
6
6
  * @returns The current account information or undefined if no account is available.
7
7
  */
8
8
  export const useCurrentAccount = (): AccountInfo | undefined => {
9
- const msalProvider = useAppModule('auth');
10
- return msalProvider.defaultAccount;
9
+ const msalProvider = useAppModule('auth');
10
+ return msalProvider.defaultAccount;
11
11
  };
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
 
3
- import { type AuthenticationResult } from '@equinor/fusion-framework-module-msal';
3
+ import type { AuthenticationResult } from '@equinor/fusion-framework-module-msal';
4
4
 
5
5
  import useAppModule from '../useAppModule';
6
6
 
@@ -10,22 +10,22 @@ import useAppModule from '../useAppModule';
10
10
  * @returns An object containing the acquired token, pending state, and error.
11
11
  */
12
12
  export const useToken = (req: {
13
- scopes: string[];
13
+ scopes: string[];
14
14
  }): { token?: AuthenticationResult; pending: boolean; error: unknown } => {
15
- const msalProvider = useAppModule('auth');
16
- const [token, setToken] = useState<AuthenticationResult | undefined>(undefined);
17
- const [pending, setPending] = useState<boolean>(false);
18
- const [error, setError] = useState<unknown>(null);
19
- useEffect(() => {
20
- setPending(true);
21
- setToken(undefined);
22
- msalProvider
23
- .acquireToken(req)
24
- .then((token) => token && setToken(token))
25
- .catch(setError)
26
- .finally(() => setPending(false));
27
- }, [msalProvider, req]);
28
- return { token, pending, error };
15
+ const msalProvider = useAppModule('auth');
16
+ const [token, setToken] = useState<AuthenticationResult | undefined>(undefined);
17
+ const [pending, setPending] = useState<boolean>(false);
18
+ const [error, setError] = useState<unknown>(null);
19
+ useEffect(() => {
20
+ setPending(true);
21
+ setToken(undefined);
22
+ msalProvider
23
+ .acquireToken(req)
24
+ .then((token) => token && setToken(token))
25
+ .catch(setError)
26
+ .finally(() => setPending(false));
27
+ }, [msalProvider, req]);
28
+ return { token, pending, error };
29
29
  };
30
30
 
31
31
  export default useToken;
@@ -1,5 +1,5 @@
1
1
  import useAppModule from '../useAppModule';
2
- import { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
2
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
3
3
 
4
4
  /** hook for getting the navigation provider (if enabled!) */
5
5
  export const useNavigationModule = (): INavigationProvider => useAppModule('navigation');
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useNavigationModule } from './useNavigationModule';
3
- import { type INavigationProvider } from '@equinor/fusion-framework-module-navigation';
3
+ import type { INavigationProvider } from '@equinor/fusion-framework-module-navigation';
4
4
 
5
5
  /**
6
6
  * create a router for react routing
@@ -9,8 +9,8 @@ import { type INavigationProvider } from '@equinor/fusion-framework-module-navig
9
9
  * @param routes router objects __(must be static | memorized)__
10
10
  */
11
11
  export const useRouter = (
12
- routes: Parameters<INavigationProvider['createRouter']>[0],
12
+ routes: Parameters<INavigationProvider['createRouter']>[0],
13
13
  ): ReturnType<INavigationProvider['createRouter']> => {
14
- const provider = useNavigationModule();
15
- return useMemo(() => provider.createRouter(routes), [provider, routes]);
14
+ const provider = useNavigationModule();
15
+ return useMemo(() => provider.createRouter(routes), [provider, routes]);
16
16
  };
package/src/render-app.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { createComponent } from './create-component';
2
- import { renderComponent, RenderTeardown } from './render-component';
2
+ import { renderComponent, type RenderTeardown } from './render-component';
3
3
 
4
4
  import type { ComponentRenderArgs } from './create-component';
5
5
 
6
6
  /** @deprecated */
7
7
  export const renderApp = (...componentArgs: Parameters<typeof createComponent>) => {
8
- const renderer = renderComponent(createComponent(...componentArgs));
9
- return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
10
- return renderer(el, args);
11
- };
8
+ const renderer = renderComponent(createComponent(...componentArgs));
9
+ return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
10
+ return renderer(el, args);
11
+ };
12
12
  };
13
13
 
14
14
  export default renderApp;
@@ -7,26 +7,26 @@ export type RenderTeardown = VoidFunction;
7
7
 
8
8
  /** @deprecated */
9
9
  export const renderComponent = (renderer: ComponentRenderer) => {
10
- return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
11
- const Component = renderer(args.fusion, args.env);
12
- return render(el, Component);
13
- };
10
+ return (el: HTMLElement, args: ComponentRenderArgs): RenderTeardown => {
11
+ const Component = renderer(args.fusion, args.env);
12
+ return render(el, Component);
13
+ };
14
14
  };
15
15
 
16
16
  const render = (el: Element, Component: FunctionComponent): RenderTeardown => {
17
+ // eslint-disable-next-line react/no-deprecated
18
+ ReactDOM.render(
19
+ <StrictMode>
20
+ <Suspense fallback={<p>loading app</p>}>
21
+ <Component />
22
+ </Suspense>
23
+ </StrictMode>,
24
+ el,
25
+ );
26
+ return () => {
17
27
  // eslint-disable-next-line react/no-deprecated
18
- ReactDOM.render(
19
- <StrictMode>
20
- <Suspense fallback={<p>loading app</p>}>
21
- <Component />
22
- </Suspense>
23
- </StrictMode>,
24
- el,
25
- );
26
- return () => {
27
- // eslint-disable-next-line react/no-deprecated
28
- ReactDOM.unmountComponentAtNode(el);
29
- };
28
+ ReactDOM.unmountComponentAtNode(el);
29
+ };
30
30
  };
31
31
 
32
32
  // const render = (el: Element, Component: FunctionComponent): RenderTeardown => {
@@ -45,68 +45,67 @@ type UpdateSettingFunction<T, O = T> = (currentSetting: T | undefined) => O;
45
45
  * });
46
46
  */
47
47
  export const useAppSetting = <
48
- TSettings extends Record<string, unknown> = AppSettings,
49
- TProp extends keyof TSettings = keyof TSettings,
48
+ TSettings extends Record<string, unknown> = AppSettings,
49
+ TProp extends keyof TSettings = keyof TSettings,
50
50
  >(
51
- prop: TProp,
52
- defaultValue?: TSettings[TProp],
53
- hooks?: AppSettingsStatusHooks & {
54
- onError?: (error: Error | null) => void;
55
- onUpdated?: () => void;
56
- },
51
+ prop: TProp,
52
+ defaultValue?: TSettings[TProp],
53
+ hooks?: AppSettingsStatusHooks & {
54
+ onError?: (error: Error | null) => void;
55
+ onUpdated?: () => void;
56
+ },
57
57
  ): [
58
- TSettings[TProp] | undefined,
59
- (update: TSettings[TProp] | UpdateSettingFunction<TSettings[TProp]>) => void,
58
+ TSettings[TProp] | undefined,
59
+ (update: TSettings[TProp] | UpdateSettingFunction<TSettings[TProp]>) => void,
60
60
  ] => {
61
- const [{ onError, onUpdated, onLoading, onUpdating }] = useState(() => hooks ?? {});
61
+ const [{ onError, onUpdated, onLoading, onUpdating }] = useState(() => hooks ?? {});
62
62
 
63
- const { currentApp = null } = useCurrentApp();
63
+ const { currentApp = null } = useCurrentApp();
64
64
 
65
- // create a subject to manage the setting value
66
- const subject = useMemo(() => {
67
- return new BehaviorSubject<TSettings[TProp] | undefined>(defaultValue);
68
- // Only create a new subject when the current app changes
69
- // eslint-disable-next-line react-hooks/exhaustive-deps
70
- }, [currentApp]);
65
+ // create a subject to manage the setting value
66
+ // biome-ignore lint/correctness/useExhaustiveDependencies: new subject when app changes
67
+ const subject = useMemo(() => {
68
+ return new BehaviorSubject<TSettings[TProp] | undefined>(defaultValue);
69
+ }, [currentApp]);
71
70
 
72
- useLayoutEffect(() => {
73
- const sub = currentApp?.settings$
74
- .pipe(map((settings) => (settings as TSettings)[prop]))
75
- .subscribe(subject);
76
- return () => sub?.unsubscribe();
77
- }, [currentApp, subject, prop]);
71
+ useLayoutEffect(() => {
72
+ const sub = currentApp?.settings$
73
+ .pipe(map((settings) => (settings as TSettings)[prop]))
74
+ .subscribe(subject);
75
+ return () => sub?.unsubscribe();
76
+ }, [currentApp, subject, prop]);
78
77
 
79
- // subscribe to the setting value
80
- const { value: setting } = useObservableState(subject);
78
+ // subscribe to the setting value
79
+ const { value: setting } = useObservableState(subject);
81
80
 
82
- // update function
83
- const setSetting = useCallback(
84
- (update: TSettings[TProp] | UpdateSettingFunction<TSettings[TProp]>) => {
85
- if (!currentApp) {
86
- return onError?.(new Error('App is not available'));
87
- }
81
+ // update function
82
+ const setSetting = useCallback(
83
+ (update: TSettings[TProp] | UpdateSettingFunction<TSettings[TProp]>) => {
84
+ if (!currentApp) {
85
+ return onError?.(new Error('App is not available'));
86
+ }
88
87
 
89
- // resolve setting value with the provided value or function
90
- const value =
91
- typeof update === 'function'
92
- ? (update as UpdateSettingFunction<TSettings[TProp]>)(subject.value)
93
- : update;
88
+ // resolve setting value with the provided value or function
89
+ const value =
90
+ typeof update === 'function'
91
+ ? (update as UpdateSettingFunction<TSettings[TProp]>)(subject.value)
92
+ : update;
94
93
 
95
- currentApp.updateSetting<TSettings, TProp>(prop, value).subscribe({
96
- error: onError,
97
- complete: onUpdated,
98
- });
99
- },
100
- [currentApp, subject, prop, onError, onUpdated],
101
- );
94
+ currentApp.updateSetting<TSettings, TProp>(prop, value).subscribe({
95
+ error: onError,
96
+ complete: onUpdated,
97
+ });
98
+ },
99
+ [currentApp, subject, prop, onError, onUpdated],
100
+ );
102
101
 
103
- // status hooks
104
- useAppSettingsStatus(currentApp, {
105
- onLoading,
106
- onUpdating,
107
- });
102
+ // status hooks
103
+ useAppSettingsStatus(currentApp, {
104
+ onLoading,
105
+ onUpdating,
106
+ });
108
107
 
109
- return [setting, setSetting];
108
+ return [setting, setSetting];
110
109
  };
111
110
 
112
111
  export default useAppSetting;
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useLayoutEffect, useMemo } from 'react';
2
- import { BehaviorSubject, Observable } from 'rxjs';
2
+ import { BehaviorSubject, type Observable } from 'rxjs';
3
3
 
4
- import { type AppSettings } from '@equinor/fusion-framework-module-app';
4
+ import type { AppSettings } from '@equinor/fusion-framework-module-app';
5
5
 
6
6
  import { useCurrentApp } from '@equinor/fusion-framework-react/app';
7
7
  import { useObservableState } from '@equinor/fusion-observable/react';
@@ -47,53 +47,52 @@ type UpdateSettingsFunction<T, O = T> = (currentSettings: T | undefined) => O;
47
47
  * });
48
48
  */
49
49
  export const useAppSettings = <TSettings extends Record<string, unknown> = AppSettings>(
50
- defaultValue?: TSettings,
51
- hooks?: AppSettingsStatusHooks & {
52
- onError?: (error: Error | null) => void;
53
- onUpdated?: () => void;
54
- },
50
+ defaultValue?: TSettings,
51
+ hooks?: AppSettingsStatusHooks & {
52
+ onError?: (error: Error | null) => void;
53
+ onUpdated?: () => void;
54
+ },
55
55
  ): [TSettings, (settings: TSettings | UpdateSettingsFunction<TSettings>) => void] => {
56
- const { onError, onUpdated, onLoading, onUpdating } = hooks ?? {};
57
- const { currentApp = null } = useCurrentApp();
56
+ const { onError, onUpdated, onLoading, onUpdating } = hooks ?? {};
57
+ const { currentApp = null } = useCurrentApp();
58
58
 
59
- const subject = useMemo(() => {
60
- return new BehaviorSubject<TSettings>(defaultValue ?? ({} as TSettings));
61
- // Only create a new subject when the current app changes
62
- // eslint-disable-next-line react-hooks/exhaustive-deps
63
- }, [currentApp]);
59
+ // biome-ignore lint/correctness/useExhaustiveDependencies: create new subject when app changes
60
+ const subject = useMemo(() => {
61
+ return new BehaviorSubject<TSettings>(defaultValue ?? ({} as TSettings));
62
+ }, [currentApp]);
64
63
 
65
- // connect the subject to the current app settings stream
66
- useLayoutEffect(() => {
67
- const sub = (currentApp?.settings$ as Observable<TSettings>).subscribe(subject);
68
- return () => sub?.unsubscribe();
69
- }, [currentApp, subject]);
64
+ // connect the subject to the current app settings stream
65
+ useLayoutEffect(() => {
66
+ const sub = (currentApp?.settings$ as Observable<TSettings>).subscribe(subject);
67
+ return () => sub?.unsubscribe();
68
+ }, [currentApp, subject]);
70
69
 
71
- // subscribe to the subject to get the latest settings
72
- const { value: settings } = useObservableState(subject, { initial: defaultValue });
70
+ // subscribe to the subject to get the latest settings
71
+ const { value: settings } = useObservableState(subject, { initial: defaultValue });
73
72
 
74
- const setSettings = useCallback(
75
- (update: TSettings | UpdateSettingsFunction<TSettings>) => {
76
- if (!currentApp) {
77
- return onError?.(new Error('App is not available'));
78
- }
73
+ const setSettings = useCallback(
74
+ (update: TSettings | UpdateSettingsFunction<TSettings>) => {
75
+ if (!currentApp) {
76
+ return onError?.(new Error('App is not available'));
77
+ }
79
78
 
80
- // resolve settings with the provided value or function
81
- const settings = typeof update === 'function' ? update(subject.value) : update;
79
+ // resolve settings with the provided value or function
80
+ const settings = typeof update === 'function' ? update(subject.value) : update;
82
81
 
83
- currentApp.updateSettings(settings).subscribe({
84
- next: () => {
85
- onUpdated?.();
86
- onError?.(null);
87
- },
88
- error: onError,
89
- });
82
+ currentApp.updateSettings(settings).subscribe({
83
+ next: () => {
84
+ onUpdated?.();
85
+ onError?.(null);
90
86
  },
91
- [currentApp, subject, onError, onUpdated],
92
- );
87
+ error: onError,
88
+ });
89
+ },
90
+ [currentApp, subject, onError, onUpdated],
91
+ );
93
92
 
94
- useAppSettingsStatus(currentApp, { onLoading, onUpdating });
93
+ useAppSettingsStatus(currentApp, { onLoading, onUpdating });
95
94
 
96
- return [settings, setSettings];
95
+ return [settings, setSettings];
97
96
  };
98
97
 
99
98
  export default useAppSettings;