@equinor/roma-framework 6.0.1-beta.7 → 6.0.1-beta.9

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.
@@ -1,5 +1,5 @@
1
- import { c as createLocalStorage, T as THEME_PREFERENCE, P as PiPProvider, a as ThemeContext, D as Devtools, Q as QueryDevtoolsContext } from "./NITRNJ62--TsKJch6.mjs";
2
- import { g as getPreferredColorScheme, c as createMemo, a as createComponent } from "./index-BZgjGlgD.mjs";
1
+ import { c as createLocalStorage, T as THEME_PREFERENCE, P as PiPProvider, a as ThemeContext, D as Devtools, Q as QueryDevtoolsContext } from "./NITRNJ62-DUIbHypW.mjs";
2
+ import { g as getPreferredColorScheme, c as createMemo, a as createComponent } from "./index-DQWkf5T-.mjs";
3
3
  var DevtoolsComponent = (props) => {
4
4
  const [localStore, setLocalStore] = createLocalStorage({
5
5
  prefix: "TanstackQueryDevtools"
@@ -1,5 +1,5 @@
1
- import { c as createLocalStorage, T as THEME_PREFERENCE, P as PiPProvider, a as ThemeContext, b as ParentPanel, C as ContentView, Q as QueryDevtoolsContext } from "./NITRNJ62--TsKJch6.mjs";
2
- import { g as getPreferredColorScheme, c as createMemo, a as createComponent } from "./index-BZgjGlgD.mjs";
1
+ import { c as createLocalStorage, T as THEME_PREFERENCE, P as PiPProvider, a as ThemeContext, b as ParentPanel, C as ContentView, Q as QueryDevtoolsContext } from "./NITRNJ62-DUIbHypW.mjs";
2
+ import { g as getPreferredColorScheme, c as createMemo, a as createComponent } from "./index-DQWkf5T-.mjs";
3
3
  var DevtoolsPanelComponent = (props) => {
4
4
  const [localStore, setLocalStore] = createLocalStorage({
5
5
  prefix: "TanstackQueryDevtools"
@@ -1,4 +1,4 @@
1
- import { b as createSignal, d as createEffect, c as createMemo, a as createComponent, e as createContext, o as onMount, P as Portal, m as memo, S as Show, i as insert, f as createRenderEffect, h as className, j as clearDelegatedEvents, k as delegateEvents, u as useContext, l as onCleanup, s as sortFns, n as mutationSortFns, p as on, q as setAttribute, t as template, r as getSidedProp, v as use, w as convertRemToPixels, x as createUniqueId, y as batch, z as getQueryStatusLabel, A as getMutationStatusColor, B as getQueryStatusColor, C as getQueryStatusColorByLabel, D as displayValue, F as For, E as untrack, $ as $TRACK, G as spread, H as mergeProps, I as createRoot, J as serialize, K as Index, L as updateNestedDataByPath, M as useTransition, N as addEventListener, O as stringify, Q as Match, R as Switch, T as deleteNestedDataByPath, U as splitProps, V as Dynamic, W as createComputed } from "./index-BZgjGlgD.mjs";
1
+ import { b as createSignal, d as createEffect, c as createMemo, a as createComponent, e as createContext, o as onMount, P as Portal, m as memo, S as Show, i as insert, f as createRenderEffect, h as className, j as clearDelegatedEvents, k as delegateEvents, u as useContext, l as onCleanup, s as sortFns, n as mutationSortFns, p as on, q as setAttribute, t as template, r as getSidedProp, v as use, w as convertRemToPixels, x as createUniqueId, y as batch, z as getQueryStatusLabel, A as getMutationStatusColor, B as getQueryStatusColor, C as getQueryStatusColorByLabel, D as displayValue, F as For, E as untrack, $ as $TRACK, G as spread, H as mergeProps, I as createRoot, J as serialize, K as Index, L as updateNestedDataByPath, M as useTransition, N as addEventListener, O as stringify, Q as Match, R as Switch, T as deleteNestedDataByPath, U as splitProps, V as Dynamic, W as createComputed } from "./index-DQWkf5T-.mjs";
2
2
  var isNonNullable = (i2) => i2 != null;
3
3
  var filterNonNullable = (arr) => arr.filter(isNonNullable);
4
4
  function chain(callbacks) {
@@ -98384,6 +98384,44 @@ function getAppModule(app, framework) {
98384
98384
  const appModuleScript = appModule.initialize();
98385
98385
  return { appModule, appModuleScript };
98386
98386
  }
98387
+ async function loadCssAssets(app, container) {
98388
+ const assets = app.metadata?.assets;
98389
+ if (!assets || assets.length === 0)
98390
+ return () => {
98391
+ };
98392
+ const cssAssets = assets.filter((url2) => url2.split("?")[0].endsWith(".css"));
98393
+ const injectedStyles = [];
98394
+ const results = await Promise.allSettled(
98395
+ cssAssets.map(async (cssUrl) => {
98396
+ const filename = cssUrl.split("?")[0].split("/").pop() ?? cssUrl;
98397
+ const tag = `${app.appKey}-${filename}`;
98398
+ if (container.querySelector(`style[data-asset="${tag}"]`)) return;
98399
+ const response = await fetch(cssUrl);
98400
+ if (!response.ok) {
98401
+ console.warn(
98402
+ `Failed to load CSS asset: ${cssUrl} (${response.status})`
98403
+ );
98404
+ return;
98405
+ }
98406
+ const cssText = await response.text();
98407
+ const style2 = document.createElement("style");
98408
+ style2.setAttribute("data-asset", tag);
98409
+ style2.textContent = `@scope { ${cssText} }`;
98410
+ container.appendChild(style2);
98411
+ injectedStyles.push(style2);
98412
+ })
98413
+ );
98414
+ for (const result of results) {
98415
+ if (result.status === "rejected") {
98416
+ console.warn("Failed to load CSS asset:", result.reason);
98417
+ }
98418
+ }
98419
+ return () => {
98420
+ for (const style2 of injectedStyles) {
98421
+ style2.remove();
98422
+ }
98423
+ };
98424
+ }
98387
98425
  function AppLoader({
98388
98426
  app,
98389
98427
  kind,
@@ -98401,15 +98439,15 @@ function AppLoader({
98401
98439
  new CustomEvent(eventName, data)
98402
98440
  );
98403
98441
  };
98404
- function renderApplication(el) {
98442
+ async function renderApplication(el) {
98405
98443
  const { appModule, appModuleScript } = getAppModule(app, framework);
98406
98444
  const [basename] = window.location.pathname.match(
98407
98445
  /\/?apps\/[a-z|-]+(\/)?/g
98408
98446
  ) ?? [""];
98409
- lastValueFrom(appModuleScript).then((x2) => {
98447
+ const cleanup = await lastValueFrom(appModuleScript).then((x2) => {
98410
98448
  const script = x2.script;
98411
98449
  const render2 = script.renderApp ?? script.default;
98412
- render2(el, {
98450
+ const cleanup2 = render2(el, {
98413
98451
  query: queryClient,
98414
98452
  fusion: framework,
98415
98453
  env: {
@@ -98425,8 +98463,9 @@ function AppLoader({
98425
98463
  if (kind === "app") {
98426
98464
  setCurrentApp(app.appKey);
98427
98465
  }
98466
+ return cleanup2;
98428
98467
  });
98429
- return appModule;
98468
+ return { appModule, cleanup };
98430
98469
  }
98431
98470
  reactExports.useEffect(() => {
98432
98471
  setError(null);
@@ -98438,15 +98477,30 @@ function AppLoader({
98438
98477
  setLoading(true);
98439
98478
  const el = document.createElement("div");
98440
98479
  ref.current?.appendChild(el);
98441
- const appModule = renderApplication(el);
98480
+ let cleanupCss = () => {
98481
+ ref.current?.removeChild(
98482
+ document.querySelector("[data-asset]")
98483
+ );
98484
+ };
98485
+ loadCssAssets(app, ref.current).then((cleanup2) => {
98486
+ cleanupCss = cleanup2;
98487
+ });
98488
+ let appModule = null;
98489
+ let cleanup = null;
98490
+ renderApplication(el).then((r) => {
98491
+ appModule = r.appModule;
98492
+ cleanup = r.cleanup;
98493
+ });
98442
98494
  setLoading(false);
98443
98495
  const currentRef = ref.current;
98444
98496
  return () => {
98497
+ cleanupCss?.();
98445
98498
  try {
98446
98499
  currentRef?.removeChild(el);
98447
98500
  } catch {
98448
98501
  }
98449
- appModule.dispose();
98502
+ if (appModule) appModule.dispose();
98503
+ if (cleanup) cleanup();
98450
98504
  if (kind === "app") clearCurrentApp();
98451
98505
  };
98452
98506
  }, [app]);
@@ -101404,7 +101458,7 @@ var TanstackQueryDevtools = class {
101404
101458
  if (this.#Component) {
101405
101459
  Devtools = this.#Component;
101406
101460
  } else {
101407
- Devtools = lazy(() => import("./BAGVG3AX-CYB_E9ev.mjs"));
101461
+ Devtools = lazy(() => import("./BAGVG3AX-CofbVVV8.mjs"));
101408
101462
  this.#Component = Devtools;
101409
101463
  }
101410
101464
  setupStyleSheet(this.#styleNonce, this.#shadowDOMTarget);
@@ -101542,7 +101596,7 @@ var TanstackQueryDevtoolsPanel = class {
101542
101596
  if (this.#Component) {
101543
101597
  Devtools = this.#Component;
101544
101598
  } else {
101545
- Devtools = lazy(() => import("./KZB72KQG-BdryGQdW.mjs"));
101599
+ Devtools = lazy(() => import("./KZB72KQG-CFetK-yG.mjs"));
101546
101600
  this.#Component = Devtools;
101547
101601
  }
101548
101602
  setupStyleSheet(this.#styleNonce, this.#shadowDOMTarget);
@@ -30,7 +30,7 @@
30
30
 
31
31
  <meta name='viewport' content='width=device-width, initial-scale=1'/>
32
32
  <link rel='icon' type='image/x-icon' href='/favicon.ico'/>
33
- <script type="module" crossorigin src="/index-BZgjGlgD.mjs"></script>
33
+ <script type="module" crossorigin src="/index-DQWkf5T-.mjs"></script>
34
34
  <link rel="stylesheet" crossorigin href="/roma-framework.css">
35
35
  </head>
36
36
  <body>
@@ -1,4 +1,9 @@
1
1
  import { AppManifest } from '@equinor/fusion-framework-module-app';
2
+ type AppManifestWithMetadata = AppManifest & {
3
+ metadata?: {
4
+ assets?: Array<string>;
5
+ };
6
+ };
2
7
  /**
3
8
  * Component that will render a Fusion application
4
9
  *
@@ -8,7 +13,8 @@ import { AppManifest } from '@equinor/fusion-framework-module-app';
8
13
  * @constructor
9
14
  */
10
15
  export declare function AppLoader({ app, kind, props, }: {
11
- app: AppManifest | null;
16
+ app: AppManifestWithMetadata | null;
12
17
  kind?: 'app' | 'widget';
13
18
  props?: Record<string | number, any>;
14
19
  }): import("react/jsx-runtime").JSX.Element;
20
+ export {};
@@ -1,7 +1,12 @@
1
- import { AppBuildManifest, AppConfig, AppManifest, IAppClient } from '@equinor/fusion-framework-module-app';
1
+ import { AppBuildManifest, AppConfig, AppManifest as FusionAppManifest, IAppClient } from '@equinor/fusion-framework-module-app';
2
2
  import { Observable } from 'rxjs';
3
3
  import { IHttpClient } from '@equinor/fusion-framework-module-http';
4
4
  import { FetchRequest } from '@equinor/fusion-framework-module-http/client';
5
+ type AppManifest = FusionAppManifest & {
6
+ metadata?: {
7
+ assets?: Array<string>;
8
+ };
9
+ };
5
10
  export declare class CustomAppClient implements IAppClient {
6
11
  #private;
7
12
  private client;
@@ -59,6 +64,9 @@ export declare class CustomAppClient implements IAppClient {
59
64
  }[] | null | undefined;
60
65
  build?: (AppBuildManifest & import('../../api/roma').BuildDto) | undefined;
61
66
  routes?: import('@equinor/fusion-framework-module-app').RouteSchemaEntry[] | null | undefined;
67
+ metadata?: {
68
+ assets?: Array<string>;
69
+ };
62
70
  version: import('../../api/roma').VersionDto;
63
71
  shortName: string;
64
72
  entry: string;
@@ -82,3 +90,4 @@ export declare class CustomAppClient implements IAppClient {
82
90
  tag?: string;
83
91
  }): Observable<AppBuildManifest>;
84
92
  }
93
+ export {};
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/roma-framework",
3
- "version": "6.0.1-beta.7",
3
+ "version": "6.0.1-beta.9",
4
4
  "repository": "https://github.com/equinor/tops-roma",
5
5
  "types": "./index.d.ts",
6
6
  "private": false,
@@ -22,7 +22,7 @@
22
22
  "@equinor/fusion-framework-react-module": "^4.0.0",
23
23
  "@equinor/fusion-framework-react-module-http": "^11.0.0",
24
24
  "@equinor/fusion-framework-react-router": "^1.0.2",
25
- "@equinor/roma-sse-module": "1.0.0-beta.5",
25
+ "@equinor/roma-sse-module": "1.0.0-beta.6",
26
26
  "react": "^19.2.4",
27
27
  "react-dom": "^19.2.4",
28
28
  "react-router-dom": "^7.13.2",
@@ -1,4 +1,9 @@
1
1
  import { AppManifest } from '@equinor/fusion-framework-module-app';
2
+ type AppManifestWithMetadata = AppManifest & {
3
+ metadata?: {
4
+ assets?: Array<string>;
5
+ };
6
+ };
2
7
  /**
3
8
  * Component that will render a Fusion application
4
9
  *
@@ -8,7 +13,8 @@ import { AppManifest } from '@equinor/fusion-framework-module-app';
8
13
  * @constructor
9
14
  */
10
15
  export declare function AppLoader({ app, kind, props, }: {
11
- app: AppManifest | null;
16
+ app: AppManifestWithMetadata | null;
12
17
  kind?: 'app' | 'widget';
13
18
  props?: Record<string | number, any>;
14
19
  }): import("react/jsx-runtime").JSX.Element;
20
+ export {};
@@ -1,7 +1,12 @@
1
- import { AppBuildManifest, AppConfig, AppManifest, IAppClient } from '@equinor/fusion-framework-module-app';
1
+ import { AppBuildManifest, AppConfig, AppManifest as FusionAppManifest, IAppClient } from '@equinor/fusion-framework-module-app';
2
2
  import { Observable } from 'rxjs';
3
3
  import { IHttpClient } from '@equinor/fusion-framework-module-http';
4
4
  import { FetchRequest } from '@equinor/fusion-framework-module-http/client';
5
+ type AppManifest = FusionAppManifest & {
6
+ metadata?: {
7
+ assets?: Array<string>;
8
+ };
9
+ };
5
10
  export declare class CustomAppClient implements IAppClient {
6
11
  #private;
7
12
  private client;
@@ -59,6 +64,9 @@ export declare class CustomAppClient implements IAppClient {
59
64
  }[] | null | undefined;
60
65
  build?: (AppBuildManifest & import('../../api/roma').BuildDto) | undefined;
61
66
  routes?: import('@equinor/fusion-framework-module-app').RouteSchemaEntry[] | null | undefined;
67
+ metadata?: {
68
+ assets?: Array<string>;
69
+ };
62
70
  version: import('../../api/roma').VersionDto;
63
71
  shortName: string;
64
72
  entry: string;
@@ -82,3 +90,4 @@ export declare class CustomAppClient implements IAppClient {
82
90
  tag?: string;
83
91
  }): Observable<AppBuildManifest>;
84
92
  }
93
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/roma-framework",
3
- "version": "6.0.1-beta.7",
3
+ "version": "6.0.1-beta.9",
4
4
  "repository": "https://github.com/equinor/tops-roma",
5
5
  "types": "./index.d.ts",
6
6
  "private": false,
@@ -22,7 +22,7 @@
22
22
  "@equinor/fusion-framework-react-module": "^4.0.0",
23
23
  "@equinor/fusion-framework-react-module-http": "^11.0.0",
24
24
  "@equinor/fusion-framework-react-router": "^1.0.2",
25
- "@equinor/roma-sse-module": "1.0.0-beta.5",
25
+ "@equinor/roma-sse-module": "1.0.0-beta.6",
26
26
  "react": "^19.2.4",
27
27
  "react-dom": "^19.2.4",
28
28
  "react-router-dom": "^7.13.2",
@@ -197,7 +197,7 @@ const makeComponent = (Component, args, configure2) => lazy(async () => {
197
197
  source: Component
198
198
  });
199
199
  const queryClient = args.query ?? new QueryClient();
200
- const version2 = "6.0.1-beta.7";
200
+ const version2 = "6.0.1-beta.9";
201
201
  return {
202
202
  default: () => /* @__PURE__ */ jsx(FrameworkProvider, { value: fusion, children: /* @__PURE__ */ jsx(IntlProvider, { locale: navigator.language, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(StyleProvider, { scope: `roma-${appKey}`, version: version2, children: /* @__PURE__ */ jsx(
203
203
  EdsEventProvider,
@@ -282,6 +282,44 @@ function getAppModule(app, framework) {
282
282
  const appModuleScript = appModule.initialize();
283
283
  return { appModule, appModuleScript };
284
284
  }
285
+ async function loadCssAssets(app, container) {
286
+ const assets = app.metadata?.assets;
287
+ if (!assets || assets.length === 0)
288
+ return () => {
289
+ };
290
+ const cssAssets = assets.filter((url) => url.split("?")[0].endsWith(".css"));
291
+ const injectedStyles = [];
292
+ const results = await Promise.allSettled(
293
+ cssAssets.map(async (cssUrl) => {
294
+ const filename = cssUrl.split("?")[0].split("/").pop() ?? cssUrl;
295
+ const tag = `${app.appKey}-${filename}`;
296
+ if (container.querySelector(`style[data-asset="${tag}"]`)) return;
297
+ const response = await fetch(cssUrl);
298
+ if (!response.ok) {
299
+ console.warn(
300
+ `Failed to load CSS asset: ${cssUrl} (${response.status})`
301
+ );
302
+ return;
303
+ }
304
+ const cssText = await response.text();
305
+ const style = document.createElement("style");
306
+ style.setAttribute("data-asset", tag);
307
+ style.textContent = `@scope { ${cssText} }`;
308
+ container.appendChild(style);
309
+ injectedStyles.push(style);
310
+ })
311
+ );
312
+ for (const result of results) {
313
+ if (result.status === "rejected") {
314
+ console.warn("Failed to load CSS asset:", result.reason);
315
+ }
316
+ }
317
+ return () => {
318
+ for (const style of injectedStyles) {
319
+ style.remove();
320
+ }
321
+ };
322
+ }
285
323
  function AppLoader({
286
324
  app,
287
325
  kind,
@@ -299,15 +337,15 @@ function AppLoader({
299
337
  new CustomEvent(eventName, data)
300
338
  );
301
339
  };
302
- function renderApplication(el) {
340
+ async function renderApplication(el) {
303
341
  const { appModule, appModuleScript } = getAppModule(app, framework);
304
342
  const [basename] = window.location.pathname.match(
305
343
  /\/?apps\/[a-z|-]+(\/)?/g
306
344
  ) ?? [""];
307
- lastValueFrom(appModuleScript).then((x) => {
345
+ const cleanup = await lastValueFrom(appModuleScript).then((x) => {
308
346
  const script = x.script;
309
347
  const render = script.renderApp ?? script.default;
310
- render(el, {
348
+ const cleanup2 = render(el, {
311
349
  query: queryClient,
312
350
  fusion: framework,
313
351
  env: {
@@ -323,8 +361,9 @@ function AppLoader({
323
361
  if (kind === "app") {
324
362
  setCurrentApp(app.appKey);
325
363
  }
364
+ return cleanup2;
326
365
  });
327
- return appModule;
366
+ return { appModule, cleanup };
328
367
  }
329
368
  useEffect(() => {
330
369
  setError(null);
@@ -336,15 +375,30 @@ function AppLoader({
336
375
  setLoading(true);
337
376
  const el = document.createElement("div");
338
377
  ref.current?.appendChild(el);
339
- const appModule = renderApplication(el);
378
+ let cleanupCss = () => {
379
+ ref.current?.removeChild(
380
+ document.querySelector("[data-asset]")
381
+ );
382
+ };
383
+ loadCssAssets(app, ref.current).then((cleanup2) => {
384
+ cleanupCss = cleanup2;
385
+ });
386
+ let appModule = null;
387
+ let cleanup = null;
388
+ renderApplication(el).then((r) => {
389
+ appModule = r.appModule;
390
+ cleanup = r.cleanup;
391
+ });
340
392
  setLoading(false);
341
393
  const currentRef = ref.current;
342
394
  return () => {
395
+ cleanupCss?.();
343
396
  try {
344
397
  currentRef?.removeChild(el);
345
398
  } catch {
346
399
  }
347
- appModule.dispose();
400
+ if (appModule) appModule.dispose();
401
+ if (cleanup) cleanup();
348
402
  if (kind === "app") clearCurrentApp();
349
403
  };
350
404
  }, [app]);