@softarc/native-federation-orchestrator 4.9.0 → 4.10.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.
Files changed (42) hide show
  1. package/README.md +12 -12
  2. package/fesm2022/@softarc/native-federation-orchestrator.mjs +490 -123
  3. package/fesm2022/@softarc/native-federation-orchestrator.mjs.map +4 -4
  4. package/fesm2022/module-federation.mjs.map +2 -2
  5. package/fesm2022/node.mjs +495 -123
  6. package/fesm2022/node.mjs.map +4 -4
  7. package/fesm2022/options.mjs +25 -2
  8. package/fesm2022/options.mjs.map +3 -3
  9. package/fesm2022/registry.mjs.map +2 -2
  10. package/package.json +3 -3
  11. package/quickstart.mjs +15 -13
  12. package/types/lib/core/1.domain/externals/basis.d.ts +2 -2
  13. package/types/lib/core/1.domain/externals/version.contract.d.ts +3 -0
  14. package/types/lib/core/1.domain/import-map/eager-preloads.d.ts +10 -0
  15. package/types/lib/core/1.domain/pooling/builds.d.ts +7 -1
  16. package/types/lib/core/1.domain/remote/remote-module.contract.d.ts +1 -0
  17. package/types/lib/core/1.domain/remote-entry/remote-entry.contract.d.ts +2 -2
  18. package/types/lib/core/2.app/config/import-map.contract.d.ts +4 -7
  19. package/types/lib/core/2.app/config/index.d.ts +2 -2
  20. package/types/lib/core/2.app/config/mode.contract.d.ts +1 -0
  21. package/types/lib/core/2.app/driver-ports/init/flow.contract.d.ts +2 -4
  22. package/types/lib/core/2.app/driver-ports/init/for-exposing-module-loader.port.d.ts +6 -2
  23. package/types/lib/core/2.app/driving-ports/for-browser-tasks.d.ts +1 -0
  24. package/types/lib/core/2.app/driving-ports/for-remote-info-storage.port.d.ts +1 -0
  25. package/types/lib/core/2.app/steps/collect-eager-preloads.d.ts +4 -0
  26. package/types/lib/core/2.app/steps/preload-hint.d.ts +4 -0
  27. package/types/lib/core/2.app/steps/store-remote-entry.d.ts +0 -14
  28. package/types/lib/core/4.config/import-map/index.d.ts +2 -0
  29. package/types/lib/core/4.config/import-map/no-preload.d.ts +2 -0
  30. package/types/lib/core/4.config/import-map/preload-in-dom.d.ts +2 -0
  31. package/types/lib/core/5.di/federation-result.factory.d.ts +3 -2
  32. package/types/lib/core/init-federation.contract.d.ts +2 -0
  33. package/types/lib/index.d.ts +1 -1
  34. package/types/lib/node/init-federation.node.d.ts +2 -7
  35. package/types/lib/node.index.d.ts +1 -1
  36. package/types/lib/registry/event-registry.contract.d.ts +1 -0
  37. package/types/lib/registry/event.contract.d.ts +6 -0
  38. package/types/lib/registry/for-managing-events.port.d.ts +1 -0
  39. package/types/lib/registry/registry.contract.d.ts +2 -0
  40. package/types/lib/registry/setup-registry.d.ts +1 -0
  41. package/types/scripts/announce-init-ready.d.ts +2 -0
  42. package/types/scripts/init-registry.d.ts +1 -0
@@ -187,6 +187,18 @@ var replaceInDOM = (mapType, trustedTypesPolicyName = "nfo") => (importMap, opts
187
187
  return Promise.resolve(importMap);
188
188
  };
189
189
 
190
+ // src/lib/core/4.config/import-map/preload-in-dom.ts
191
+ var preloadInDOM = (rel) => {
192
+ const preloaded = /* @__PURE__ */ new Set();
193
+ return (urls) => {
194
+ for (const href of urls) {
195
+ if (preloaded.has(href)) continue;
196
+ preloaded.add(href);
197
+ document.head.appendChild(Object.assign(document.createElement("link"), { rel, href }));
198
+ }
199
+ };
200
+ };
201
+
190
202
  // src/lib/core/4.config/import-map/use-import-shim.ts
191
203
  var useShimImportMap = (cfg = { shimMode: false }, trustedTypesPolicyName = "nfo") => ({
192
204
  loadModuleFn: (url) => {
@@ -197,6 +209,8 @@ var useShimImportMap = (cfg = { shimMode: false }, trustedTypesPolicyName = "nfo
197
209
  cfg.shimMode ? "importmap-shim" : "importmap",
198
210
  trustedTypesPolicyName
199
211
  ),
212
+ // es-module-shims reuses only the fetches of the link type that matches its mode.
213
+ preloadModulesFn: preloadInDOM(cfg.shimMode ? "modulepreload-shim" : "modulepreload"),
200
214
  reloadBrowserFn: () => {
201
215
  window.location.reload();
202
216
  }
@@ -212,18 +226,24 @@ var useDefaultImportMap = (trustedTypesPolicyName = "nfo") => ({
212
226
  );
213
227
  },
214
228
  setImportMapFn: replaceInDOM("importmap", trustedTypesPolicyName),
229
+ preloadModulesFn: preloadInDOM("modulepreload"),
215
230
  reloadBrowserFn: () => {
216
231
  window.location.reload();
217
232
  }
218
233
  });
219
234
 
235
+ // src/lib/core/4.config/import-map/no-preload.ts
236
+ var noPreload = () => {
237
+ };
238
+
220
239
  // src/lib/core/4.config/mode/default.profile.ts
221
240
  var defaultProfile = {
222
241
  latestSharedExternal: false,
223
242
  skipInvalidExternalVersions: false,
224
243
  overrideCachedRemotes: "init-only",
225
244
  overrideCachedRemotesIfURLMatches: false,
226
- mergeManifests: true
245
+ mergeManifests: true,
246
+ enableDebugging: false
227
247
  };
228
248
 
229
249
  // src/lib/core/4.config/mode/caching.profile.ts
@@ -232,7 +252,8 @@ var cachingProfile = {
232
252
  skipInvalidExternalVersions: false,
233
253
  overrideCachedRemotes: "never",
234
254
  overrideCachedRemotesIfURLMatches: false,
235
- mergeManifests: true
255
+ mergeManifests: true,
256
+ enableDebugging: false
236
257
  };
237
258
  export {
238
259
  LogLevel,
@@ -241,7 +262,9 @@ export {
241
262
  defaultProfile,
242
263
  globalThisStorageEntry,
243
264
  localStorageEntry,
265
+ noPreload,
244
266
  noopLogger,
267
+ preloadInDOM,
245
268
  replaceInDOM,
246
269
  sessionStorageEntry,
247
270
  useDefaultImportMap,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/lib/core/2.app/config/log.contract.ts", "../../src/lib/core/4.config/logging/console.logger.ts", "../../src/lib/core/4.config/logging/noop.logger.ts", "../../src/lib/core/native-federation.error.ts", "../../src/lib/utils/clone-entry.ts", "../../src/lib/core/4.config/storage/global-this.storage.ts", "../../src/lib/core/4.config/storage/local.storage.ts", "../../src/lib/core/4.config/storage/session.storage.ts", "../../src/lib/core/4.config/import-map/trusted-types.ts", "../../src/lib/core/4.config/import-map/replace-in-dom.ts", "../../src/lib/core/4.config/import-map/use-import-shim.ts", "../../src/lib/core/4.config/import-map/use-default.ts", "../../src/lib/core/4.config/mode/default.profile.ts", "../../src/lib/core/4.config/mode/caching.profile.ts"],
4
- "sourcesContent": ["export const LogLevel = {\n debug: 0,\n warn: 1,\n error: 2,\n};\n\nexport type LogType = keyof typeof LogLevel;\n\nexport type Logger = {\n error: (step: number, msg: string, details?: unknown) => void;\n warn: (step: number, msg: string, details?: unknown) => void;\n debug: (step: number, msg: string, details?: unknown) => void;\n};\n\nexport type LogHandler = Logger & {\n level: LogType;\n};\n\nexport type LoggingConfig = {\n log: LogHandler;\n sse: boolean;\n};\n\nexport type LoggingOptions = {\n logger?: Logger;\n logLevel?: LogType;\n sse?: boolean;\n};\n", "import type { Logger } from 'lib/core/2.app/config/log.contract';\n\nconst consoleLogger: Logger = {\n /* eslint no-console: \"off\", curly: \"error\" */\n debug: (step: number, msg: string, err) =>\n !!err ? console.log(`[DEBUG][${step}]: ${msg}`, err) : console.log(`[DEBUG][${step}]: ${msg}`),\n error: (step: number, msg: string, err) =>\n !!err ? console.error(`[NF][${step}]: ${msg}`, err) : console.error(`[NF][${step}]: ${msg}`),\n warn: (step: number, msg: string, err) =>\n !!err ? console.warn(`[NF][${step}]: ${msg}`, err) : console.warn(`[NF][${step}]: ${msg}`),\n};\n\nexport { consoleLogger };\n", "import type { Logger } from 'lib/core/2.app/config/log.contract';\n\nconst noopLogger: Logger = {\n debug: () => {},\n error: () => {},\n warn: () => {},\n};\n\nexport { noopLogger };\n", "class NFError extends Error {\n constructor(message: string, cause?: Error) {\n super(message, cause ? { cause } : undefined);\n this.name = 'NFError';\n }\n}\n\nexport { NFError };\n", "import type { StorageEntryKey } from 'lib/core/2.app/config/storage.contract';\nimport { NFError } from 'lib/core/native-federation.error';\n\ntype CloneEntry = <T>(name: StorageEntryKey, raw: T) => T;\n\nconst cloneEntry: CloneEntry = <T>(name: StorageEntryKey, raw: T) => {\n try {\n if (typeof structuredClone === 'function') {\n return structuredClone(raw);\n }\n } catch {\n /* structured clone is unavailable */\n }\n try {\n return JSON.parse(JSON.stringify(raw));\n } catch {\n /* object is not stringifyable */\n }\n throw new NFError(`Could not clone entry '${String(name)}'`);\n};\n\nexport { CloneEntry, cloneEntry };\n", "import { cloneEntry } from 'lib/utils/clone-entry';\nimport {\n type StorageEntryCreator,\n type StorageEntry,\n} from 'lib/core/2.app/config/storage.contract';\n\nconst globalThisStorageEntry: StorageEntryCreator =\n (namespace: string) =>\n <TValue>(key: string, initialValue: TValue) => {\n if (!(globalThis as unknown as { [namespace]: unknown })[namespace]) {\n (globalThis as unknown as { [namespace]: unknown })[namespace] = {};\n }\n\n const storage = (globalThis as unknown as { [namespace]: { [P in typeof key]: TValue } })[\n namespace\n ]!;\n\n const entry: StorageEntry<TValue> = {\n get(): TValue {\n return cloneEntry(key, key in storage ? storage[key] : initialValue)!;\n },\n set(value: TValue): StorageEntry<TValue> {\n storage[key] = cloneEntry(key, value);\n return entry;\n },\n clear(): StorageEntry<TValue> {\n storage[key] = cloneEntry(key, initialValue);\n return this;\n },\n };\n\n return entry;\n };\n\nglobalThisStorageEntry.type = 'globalThis';\nObject.freeze(globalThisStorageEntry);\n\nexport { globalThisStorageEntry };\n", "import type { StorageEntryCreator, StorageEntry } from 'lib/core/2.app/config/storage.contract';\nimport { cloneEntry } from 'lib/utils/clone-entry';\n\nconst localStorageEntry: StorageEntryCreator =\n (namespace: string) =>\n <TValue>(key: string, initialValue: TValue) => {\n const entry: StorageEntry<TValue> = {\n get() {\n const fromCache = localStorage.getItem(`${namespace}.${String(key)}`);\n if (!fromCache) return cloneEntry(key, initialValue);\n return JSON.parse(fromCache);\n },\n set(value: TValue): StorageEntry<TValue> {\n localStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(value));\n return entry;\n },\n clear(): StorageEntry<TValue> {\n localStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(initialValue));\n return this;\n },\n };\n return entry;\n };\n\nlocalStorageEntry.type = 'localStorage';\nObject.freeze(localStorageEntry);\n\nexport { localStorageEntry };\n", "import type { StorageEntryCreator, StorageEntry } from 'lib/core/2.app/config/storage.contract';\nimport { cloneEntry } from 'lib/utils/clone-entry';\n\nconst sessionStorageEntry: StorageEntryCreator =\n (namespace: string) =>\n <TValue>(key: string, initialValue: TValue) => {\n const entry: StorageEntry<TValue> = {\n get() {\n const fromCache = sessionStorage.getItem(`${namespace}.${String(key)}`);\n if (!fromCache) return cloneEntry(key, initialValue);\n return JSON.parse(fromCache);\n },\n set(value: TValue): StorageEntry<TValue> {\n sessionStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(value));\n return entry;\n },\n clear(): StorageEntry<TValue> {\n sessionStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(initialValue));\n return this;\n },\n };\n return entry;\n };\n\nsessionStorageEntry.type = 'sessionStorage';\nObject.freeze(sessionStorageEntry);\n\nexport { sessionStorageEntry };\n", "type TTCreateScript = (input: string) => string;\ntype TTCreateScriptURL = (input: string) => string;\n\ntype TTPolicyRules = {\n createScript?: TTCreateScript;\n createScriptURL?: TTCreateScriptURL;\n};\n\ntype TrustedValue = { toString(): string };\n\ntype TTPolicy = {\n createScript: (input: string) => TrustedValue;\n createScriptURL: (input: string) => TrustedValue;\n};\n\ntype TTFactory = {\n createPolicy: (name: string, rules: TTPolicyRules) => TTPolicy;\n};\n\nexport type NFTrustedTypesPolicy = {\n // `script.text` is a TrustedScript sink, so this must stay the genuine object.\n createScript: (input: string) => TrustedValue;\n createScriptURL: (input: string) => string;\n};\n\nconst IMPORT_MAP_KEYS = new Set(['imports', 'scopes', 'integrity']);\n\nconst validateImportMapJSON = (input: string): string => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(input);\n } catch {\n throw new TypeError('[nf-orchestrator] trusted-types: import map is not valid JSON');\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new TypeError('[nf-orchestrator] trusted-types: import map must be a plain object');\n }\n for (const key of Object.keys(parsed as Record<string, unknown>)) {\n if (!IMPORT_MAP_KEYS.has(key)) {\n throw new TypeError(`[nf-orchestrator] trusted-types: unexpected key \"${key}\" in import map`);\n }\n }\n return input;\n};\n\nconst validateScriptURL = (input: string): string => {\n const base = typeof location !== 'undefined' ? location.href : 'http://localhost/';\n let url: URL;\n try {\n url = new URL(input, base);\n } catch {\n throw new TypeError(`[nf-orchestrator] trusted-types: invalid script URL \"${input}\"`);\n }\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n throw new TypeError(\n `[nf-orchestrator] trusted-types: disallowed protocol \"${url.protocol}\" for script URL`\n );\n }\n return input;\n};\n\nconst passThroughPolicy: NFTrustedTypesPolicy = {\n createScript: input => input,\n createScriptURL: input => input,\n};\n\nlet cachedPolicy: NFTrustedTypesPolicy | null = null;\n\nexport const getTrustedTypesPolicy = (\n name: string | false = 'nfo'\n): NFTrustedTypesPolicy => {\n if (name === false) return passThroughPolicy;\n if (cachedPolicy) return cachedPolicy;\n\n const factory = (globalThis as { trustedTypes?: TTFactory }).trustedTypes;\n if (!factory) {\n cachedPolicy = passThroughPolicy;\n return cachedPolicy;\n }\n\n const native = factory.createPolicy(name, {\n createScript: validateImportMapJSON,\n createScriptURL: validateScriptURL,\n });\n\n cachedPolicy = {\n createScript: input => native.createScript(input),\n createScriptURL: input => String(native.createScriptURL(input)),\n };\n return cachedPolicy;\n};\n\nexport const __resetTrustedTypesPolicyForTests = (): void => {\n cachedPolicy = null;\n};\n", "import type { ImportMap } from 'lib/core/1.domain';\nimport type { SetImportMap } from 'lib/core/2.app/config/import-map.contract';\nimport { getTrustedTypesPolicy } from './trusted-types';\n\nexport const replaceInDOM =\n (mapType: string, trustedTypesPolicyName: string | false = 'nfo'): SetImportMap =>\n (importMap: ImportMap, opts = {}) => {\n if (opts?.override) {\n document.head\n .querySelectorAll(`script[type=\"${mapType}\"]`)\n .forEach(importMap => importMap.remove());\n }\n\n const policy = getTrustedTypesPolicy(trustedTypesPolicyName);\n document.head.appendChild(\n Object.assign(document.createElement('script'), {\n type: mapType,\n text: policy.createScript(JSON.stringify(importMap)),\n })\n );\n return Promise.resolve(importMap);\n };\n", "import type { ImportMapConfig } from 'lib/core/2.app/config/import-map.contract';\nimport { replaceInDOM } from './replace-in-dom';\nimport { getTrustedTypesPolicy } from './trusted-types';\n\ndeclare function importShim<T>(url: string): T;\n\nconst useShimImportMap = (\n cfg: { shimMode: boolean } = { shimMode: false },\n trustedTypesPolicyName: string | false = 'nfo'\n): ImportMapConfig => ({\n loadModuleFn: url => {\n const trusted = getTrustedTypesPolicy(trustedTypesPolicyName).createScriptURL(url);\n return importShim(trusted);\n },\n setImportMapFn: replaceInDOM(\n cfg.shimMode ? 'importmap-shim' : 'importmap',\n trustedTypesPolicyName\n ),\n reloadBrowserFn: () => {\n window.location.reload();\n },\n});\n\nexport { useShimImportMap };\n", "import type { ImportMapConfig } from 'lib/core/2.app/config/import-map.contract';\nimport { replaceInDOM } from './replace-in-dom';\nimport { getTrustedTypesPolicy } from './trusted-types';\n\nconst useDefaultImportMap = (trustedTypesPolicyName: string | false = 'nfo'): ImportMapConfig => ({\n loadModuleFn: url => {\n const trusted = getTrustedTypesPolicy(trustedTypesPolicyName).createScriptURL(url);\n return import(/* @vite-ignore */ trusted);\n },\n setImportMapFn: replaceInDOM('importmap', trustedTypesPolicyName),\n reloadBrowserFn: () => {\n window.location.reload();\n },\n});\n\nexport { useDefaultImportMap };\n", "import type { ModeProfileConfig } from 'lib/core/2.app/config/mode.contract';\n\nexport const defaultProfile: ModeProfileConfig = {\n latestSharedExternal: false,\n skipInvalidExternalVersions: false,\n overrideCachedRemotes: 'init-only',\n overrideCachedRemotesIfURLMatches: false,\n mergeManifests: true,\n};\n", "import type { ModeProfileConfig } from 'lib/core/2.app/config/mode.contract';\n\nexport const cachingProfile: ModeProfileConfig = {\n latestSharedExternal: false,\n skipInvalidExternalVersions: false,\n overrideCachedRemotes: 'never',\n overrideCachedRemotesIfURLMatches: false,\n mergeManifests: true,\n};\n"],
5
- "mappings": "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",
3
+ "sources": ["../../src/lib/core/2.app/config/log.contract.ts", "../../src/lib/core/4.config/logging/console.logger.ts", "../../src/lib/core/4.config/logging/noop.logger.ts", "../../src/lib/core/native-federation.error.ts", "../../src/lib/utils/clone-entry.ts", "../../src/lib/core/4.config/storage/global-this.storage.ts", "../../src/lib/core/4.config/storage/local.storage.ts", "../../src/lib/core/4.config/storage/session.storage.ts", "../../src/lib/core/4.config/import-map/trusted-types.ts", "../../src/lib/core/4.config/import-map/replace-in-dom.ts", "../../src/lib/core/4.config/import-map/preload-in-dom.ts", "../../src/lib/core/4.config/import-map/use-import-shim.ts", "../../src/lib/core/4.config/import-map/use-default.ts", "../../src/lib/core/4.config/import-map/no-preload.ts", "../../src/lib/core/4.config/mode/default.profile.ts", "../../src/lib/core/4.config/mode/caching.profile.ts"],
4
+ "sourcesContent": ["export const LogLevel = {\n debug: 0,\n warn: 1,\n error: 2,\n};\n\nexport type LogType = keyof typeof LogLevel;\n\nexport type Logger = {\n error: (step: number, msg: string, details?: unknown) => void;\n warn: (step: number, msg: string, details?: unknown) => void;\n debug: (step: number, msg: string, details?: unknown) => void;\n};\n\nexport type LogHandler = Logger & {\n level: LogType;\n};\n\nexport type LoggingConfig = {\n log: LogHandler;\n sse: boolean;\n};\n\nexport type LoggingOptions = {\n logger?: Logger;\n logLevel?: LogType;\n sse?: boolean;\n};\n", "import type { Logger } from 'lib/core/2.app/config/log.contract';\n\nconst consoleLogger: Logger = {\n /* eslint no-console: \"off\", curly: \"error\" */\n debug: (step: number, msg: string, err) =>\n !!err ? console.log(`[DEBUG][${step}]: ${msg}`, err) : console.log(`[DEBUG][${step}]: ${msg}`),\n error: (step: number, msg: string, err) =>\n !!err ? console.error(`[NF][${step}]: ${msg}`, err) : console.error(`[NF][${step}]: ${msg}`),\n warn: (step: number, msg: string, err) =>\n !!err ? console.warn(`[NF][${step}]: ${msg}`, err) : console.warn(`[NF][${step}]: ${msg}`),\n};\n\nexport { consoleLogger };\n", "import type { Logger } from 'lib/core/2.app/config/log.contract';\n\nconst noopLogger: Logger = {\n debug: () => {},\n error: () => {},\n warn: () => {},\n};\n\nexport { noopLogger };\n", "class NFError extends Error {\n constructor(message: string, cause?: Error) {\n super(message, cause ? { cause } : undefined);\n this.name = 'NFError';\n }\n}\n\nexport { NFError };\n", "import type { StorageEntryKey } from 'lib/core/2.app/config/storage.contract';\nimport { NFError } from 'lib/core/native-federation.error';\n\ntype CloneEntry = <T>(name: StorageEntryKey, raw: T) => T;\n\nconst cloneEntry: CloneEntry = <T>(name: StorageEntryKey, raw: T) => {\n try {\n if (typeof structuredClone === 'function') {\n return structuredClone(raw);\n }\n } catch {\n /* structured clone is unavailable */\n }\n try {\n return JSON.parse(JSON.stringify(raw));\n } catch {\n /* object is not stringifyable */\n }\n throw new NFError(`Could not clone entry '${String(name)}'`);\n};\n\nexport { CloneEntry, cloneEntry };\n", "import { cloneEntry } from 'lib/utils/clone-entry';\nimport {\n type StorageEntryCreator,\n type StorageEntry,\n} from 'lib/core/2.app/config/storage.contract';\n\nconst globalThisStorageEntry: StorageEntryCreator =\n (namespace: string) =>\n <TValue>(key: string, initialValue: TValue) => {\n if (!(globalThis as unknown as { [namespace]: unknown })[namespace]) {\n (globalThis as unknown as { [namespace]: unknown })[namespace] = {};\n }\n\n const storage = (globalThis as unknown as { [namespace]: { [P in typeof key]: TValue } })[\n namespace\n ]!;\n\n const entry: StorageEntry<TValue> = {\n get(): TValue {\n return cloneEntry(key, key in storage ? storage[key] : initialValue)!;\n },\n set(value: TValue): StorageEntry<TValue> {\n storage[key] = cloneEntry(key, value);\n return entry;\n },\n clear(): StorageEntry<TValue> {\n storage[key] = cloneEntry(key, initialValue);\n return this;\n },\n };\n\n return entry;\n };\n\nglobalThisStorageEntry.type = 'globalThis';\nObject.freeze(globalThisStorageEntry);\n\nexport { globalThisStorageEntry };\n", "import type { StorageEntryCreator, StorageEntry } from 'lib/core/2.app/config/storage.contract';\nimport { cloneEntry } from 'lib/utils/clone-entry';\n\nconst localStorageEntry: StorageEntryCreator =\n (namespace: string) =>\n <TValue>(key: string, initialValue: TValue) => {\n const entry: StorageEntry<TValue> = {\n get() {\n const fromCache = localStorage.getItem(`${namespace}.${String(key)}`);\n if (!fromCache) return cloneEntry(key, initialValue);\n return JSON.parse(fromCache);\n },\n set(value: TValue): StorageEntry<TValue> {\n localStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(value));\n return entry;\n },\n clear(): StorageEntry<TValue> {\n localStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(initialValue));\n return this;\n },\n };\n return entry;\n };\n\nlocalStorageEntry.type = 'localStorage';\nObject.freeze(localStorageEntry);\n\nexport { localStorageEntry };\n", "import type { StorageEntryCreator, StorageEntry } from 'lib/core/2.app/config/storage.contract';\nimport { cloneEntry } from 'lib/utils/clone-entry';\n\nconst sessionStorageEntry: StorageEntryCreator =\n (namespace: string) =>\n <TValue>(key: string, initialValue: TValue) => {\n const entry: StorageEntry<TValue> = {\n get() {\n const fromCache = sessionStorage.getItem(`${namespace}.${String(key)}`);\n if (!fromCache) return cloneEntry(key, initialValue);\n return JSON.parse(fromCache);\n },\n set(value: TValue): StorageEntry<TValue> {\n sessionStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(value));\n return entry;\n },\n clear(): StorageEntry<TValue> {\n sessionStorage.setItem(`${namespace}.${String(key)}`, JSON.stringify(initialValue));\n return this;\n },\n };\n return entry;\n };\n\nsessionStorageEntry.type = 'sessionStorage';\nObject.freeze(sessionStorageEntry);\n\nexport { sessionStorageEntry };\n", "type TTCreateScript = (input: string) => string;\ntype TTCreateScriptURL = (input: string) => string;\n\ntype TTPolicyRules = {\n createScript?: TTCreateScript;\n createScriptURL?: TTCreateScriptURL;\n};\n\ntype TrustedValue = { toString(): string };\n\ntype TTPolicy = {\n createScript: (input: string) => TrustedValue;\n createScriptURL: (input: string) => TrustedValue;\n};\n\ntype TTFactory = {\n createPolicy: (name: string, rules: TTPolicyRules) => TTPolicy;\n};\n\nexport type NFTrustedTypesPolicy = {\n // `script.text` is a TrustedScript sink, so this must stay the genuine object.\n createScript: (input: string) => TrustedValue;\n createScriptURL: (input: string) => string;\n};\n\nconst IMPORT_MAP_KEYS = new Set(['imports', 'scopes', 'integrity']);\n\nconst validateImportMapJSON = (input: string): string => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(input);\n } catch {\n throw new TypeError('[nf-orchestrator] trusted-types: import map is not valid JSON');\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new TypeError('[nf-orchestrator] trusted-types: import map must be a plain object');\n }\n for (const key of Object.keys(parsed as Record<string, unknown>)) {\n if (!IMPORT_MAP_KEYS.has(key)) {\n throw new TypeError(`[nf-orchestrator] trusted-types: unexpected key \"${key}\" in import map`);\n }\n }\n return input;\n};\n\nconst validateScriptURL = (input: string): string => {\n const base = typeof location !== 'undefined' ? location.href : 'http://localhost/';\n let url: URL;\n try {\n url = new URL(input, base);\n } catch {\n throw new TypeError(`[nf-orchestrator] trusted-types: invalid script URL \"${input}\"`);\n }\n if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n throw new TypeError(\n `[nf-orchestrator] trusted-types: disallowed protocol \"${url.protocol}\" for script URL`\n );\n }\n return input;\n};\n\nconst passThroughPolicy: NFTrustedTypesPolicy = {\n createScript: input => input,\n createScriptURL: input => input,\n};\n\nlet cachedPolicy: NFTrustedTypesPolicy | null = null;\n\nexport const getTrustedTypesPolicy = (\n name: string | false = 'nfo'\n): NFTrustedTypesPolicy => {\n if (name === false) return passThroughPolicy;\n if (cachedPolicy) return cachedPolicy;\n\n const factory = (globalThis as { trustedTypes?: TTFactory }).trustedTypes;\n if (!factory) {\n cachedPolicy = passThroughPolicy;\n return cachedPolicy;\n }\n\n const native = factory.createPolicy(name, {\n createScript: validateImportMapJSON,\n createScriptURL: validateScriptURL,\n });\n\n cachedPolicy = {\n createScript: input => native.createScript(input),\n createScriptURL: input => String(native.createScriptURL(input)),\n };\n return cachedPolicy;\n};\n\nexport const __resetTrustedTypesPolicyForTests = (): void => {\n cachedPolicy = null;\n};\n", "import type { ImportMap } from 'lib/core/1.domain';\nimport type { SetImportMap } from 'lib/core/2.app/config/import-map.contract';\nimport { getTrustedTypesPolicy } from './trusted-types';\n\nexport const replaceInDOM =\n (mapType: string, trustedTypesPolicyName: string | false = 'nfo'): SetImportMap =>\n (importMap: ImportMap, opts = {}) => {\n if (opts?.override) {\n document.head\n .querySelectorAll(`script[type=\"${mapType}\"]`)\n .forEach(importMap => importMap.remove());\n }\n\n const policy = getTrustedTypesPolicy(trustedTypesPolicyName);\n document.head.appendChild(\n Object.assign(document.createElement('script'), {\n type: mapType,\n text: policy.createScript(JSON.stringify(importMap)),\n })\n );\n return Promise.resolve(importMap);\n };\n", "import type { PreloadModules } from 'lib/core/2.app/config/import-map.contract';\n\n// No crossorigin or integrity: the attributes must match the import's own request, and the import map's\n// integrity already applies to a link without one. Only document.head, the one place es-module-shims watches.\nexport const preloadInDOM = (rel: 'modulepreload' | 'modulepreload-shim'): PreloadModules => {\n // A module is loaded again on every visit to its route; without this the head grows a link per visit.\n const preloaded = new Set<string>();\n return urls => {\n for (const href of urls) {\n if (preloaded.has(href)) continue;\n preloaded.add(href);\n document.head.appendChild(Object.assign(document.createElement('link'), { rel, href }));\n }\n };\n};\n", "import type { ImportMapConfig } from 'lib/core/2.app/config/import-map.contract';\nimport { replaceInDOM } from './replace-in-dom';\nimport { preloadInDOM } from './preload-in-dom';\nimport { getTrustedTypesPolicy } from './trusted-types';\n\ndeclare function importShim<T>(url: string): T;\n\nconst useShimImportMap = (\n cfg: { shimMode: boolean } = { shimMode: false },\n trustedTypesPolicyName: string | false = 'nfo'\n): ImportMapConfig => ({\n loadModuleFn: url => {\n const trusted = getTrustedTypesPolicy(trustedTypesPolicyName).createScriptURL(url);\n return importShim(trusted);\n },\n setImportMapFn: replaceInDOM(\n cfg.shimMode ? 'importmap-shim' : 'importmap',\n trustedTypesPolicyName\n ),\n // es-module-shims reuses only the fetches of the link type that matches its mode.\n preloadModulesFn: preloadInDOM(cfg.shimMode ? 'modulepreload-shim' : 'modulepreload'),\n reloadBrowserFn: () => {\n window.location.reload();\n },\n});\n\nexport { useShimImportMap };\n", "import type { ImportMapConfig } from 'lib/core/2.app/config/import-map.contract';\nimport { replaceInDOM } from './replace-in-dom';\nimport { preloadInDOM } from './preload-in-dom';\nimport { getTrustedTypesPolicy } from './trusted-types';\n\nconst useDefaultImportMap = (trustedTypesPolicyName: string | false = 'nfo'): ImportMapConfig => ({\n loadModuleFn: url => {\n const trusted = getTrustedTypesPolicy(trustedTypesPolicyName).createScriptURL(url);\n return import(/* @vite-ignore */ trusted);\n },\n setImportMapFn: replaceInDOM('importmap', trustedTypesPolicyName),\n preloadModulesFn: preloadInDOM('modulepreload'),\n reloadBrowserFn: () => {\n window.location.reload();\n },\n});\n\nexport { useDefaultImportMap };\n", "import type { PreloadModules } from 'lib/core/2.app/config/import-map.contract';\n\nexport const noPreload: PreloadModules = () => {};\n", "import type { ModeProfileConfig } from 'lib/core/2.app/config/mode.contract';\n\nexport const defaultProfile: ModeProfileConfig = {\n latestSharedExternal: false,\n skipInvalidExternalVersions: false,\n overrideCachedRemotes: 'init-only',\n overrideCachedRemotesIfURLMatches: false,\n mergeManifests: true,\n enableDebugging: false,\n};\n", "import type { ModeProfileConfig } from 'lib/core/2.app/config/mode.contract';\n\nexport const cachingProfile: ModeProfileConfig = {\n latestSharedExternal: false,\n skipInvalidExternalVersions: false,\n overrideCachedRemotes: 'never',\n overrideCachedRemotesIfURLMatches: false,\n mergeManifests: true,\n enableDebugging: false,\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["importMap"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/core/native-federation.error.ts", "../../src/lib/utils/clone-entry.ts", "../../src/lib/registry/setup-registry.ts"],
4
- "sourcesContent": ["class NFError extends Error {\n constructor(message: string, cause?: Error) {\n super(message, cause ? { cause } : undefined);\n this.name = 'NFError';\n }\n}\n\nexport { NFError };\n", "import type { StorageEntryKey } from 'lib/core/2.app/config/storage.contract';\nimport { NFError } from 'lib/core/native-federation.error';\n\ntype CloneEntry = <T>(name: StorageEntryKey, raw: T) => T;\n\nconst cloneEntry: CloneEntry = <T>(name: StorageEntryKey, raw: T) => {\n try {\n if (typeof structuredClone === 'function') {\n return structuredClone(raw);\n }\n } catch {\n /* structured clone is unavailable */\n }\n try {\n return JSON.parse(JSON.stringify(raw));\n } catch {\n /* object is not stringifyable */\n }\n throw new NFError(`Could not clone entry '${String(name)}'`);\n};\n\nexport { CloneEntry, cloneEntry };\n", "import type {\n NFEventConsumer,\n NFEventData,\n NFEventProvider,\n NFEventUnsubscribe,\n} from './event.contract';\nimport type { ForManagingEvents } from './for-managing-events.port';\nimport type { NFEventRegistryConfig, NFEventRegistryOptions } from './registry.contract';\nimport { cloneEntry } from 'lib/utils/clone-entry';\n\nexport function createRegistry(opts: NFEventRegistryOptions): ForManagingEvents {\n const cfg: NFEventRegistryConfig = {\n maxStreams: opts.maxStreams,\n maxEvents: opts.maxEvents ?? 1,\n removePercentage: opts.removePercentage,\n };\n\n // resources\n const resources = new Map<string, unknown>();\n const pending = new Map<string, Set<NFEventConsumer<any>>>();\n\n // events\n const events = new Map<string, NFEventData[]>();\n const listeners = new Map<string, Set<NFEventConsumer<NFEventData<any>>>>();\n const recentlyUsedStreams = new Set<string>();\n\n // Clamp to (maxEvents - 1) so at least one event always survives the trim.\n // Without this, maxEvents=1 (or any config where REMOVE_EVENTS == maxEvents)\n // would compute slice(-0), which returns the whole array and never trims.\n const REMOVE_EVENTS = Math.min(\n cfg.maxEvents - 1,\n cfg.removePercentage ? Math.ceil(cfg.maxEvents * cfg.removePercentage) : 1\n );\n\n /**\n * Mark `type` as the most-recently-used stream. When `maxStreams` is set and\n * the LRU set grows past that bound, the oldest stream (and its history) is\n * dropped. No-op when `maxStreams` is undefined \u2014 streams are then unbounded.\n */\n const touchStream = (type: string): void => {\n if (!cfg.maxStreams) return;\n recentlyUsedStreams.delete(type);\n recentlyUsedStreams.add(type);\n\n if (recentlyUsedStreams.size > cfg.maxStreams) {\n const oldest = recentlyUsedStreams.values().next().value;\n if (oldest) {\n recentlyUsedStreams.delete(oldest);\n events.delete(oldest);\n }\n }\n };\n\n /**\n * Append an event to `type`'s history, trim the history if it exceeds\n * `maxEvents`, and synchronously notify all current listeners. Trimming is\n * batched: when the history overflows, it is sliced down to\n * `(maxEvents - REMOVE_EVENTS)` items so subsequent emits don't slice on\n * every call.\n */\n const appendAndNotify = <T>(type: string, event: NFEventData<T>): void => {\n let history = events.get(type) ?? [];\n history.push(event);\n\n if (history.length > cfg.maxEvents) {\n history = history.slice(-(cfg.maxEvents - REMOVE_EVENTS));\n }\n\n events.set(type, history);\n\n const typeListeners = listeners.get(type);\n if (typeListeners && typeListeners.size > 0) {\n typeListeners.forEach(listener => listener(event));\n }\n };\n\n /**\n * RESOURCE: Register a resource by name. If the resource is a provider function, it is\n * invoked to obtain the actual resource. All callbacks waiting for this\n * resource via `onReady` are invoked once the resource is registered.\n */\n const register = async <T>(type: string, resource: T | NFEventProvider<T>): Promise<void> => {\n const value =\n typeof resource === 'function' ? await (resource as NFEventProvider<T>)() : resource;\n\n resources.set(type, value);\n\n const callbacks = pending.get(type);\n if (callbacks) {\n pending.delete(type);\n callbacks.forEach(cb => cb(value));\n }\n };\n\n /**\n * RESOURCE: Subscribe to the readiness of a resource. If the resource is already\n * registered, the callback is invoked immediately. Otherwise, the callback\n * is invoked once the resource is registered.\n */\n const onReady = <T>(type: string, callback: NFEventConsumer<T>): NFEventUnsubscribe => {\n const existing = resources.get(type);\n if (existing !== undefined) {\n callback(existing as T);\n return () => {};\n }\n\n let callbacks = pending.get(type);\n if (!callbacks) {\n callbacks = new Set();\n pending.set(type, callbacks);\n }\n callbacks.add(callback);\n\n return () => {\n callbacks!.delete(callback);\n if (callbacks!.size === 0) {\n pending.delete(type);\n }\n };\n };\n\n /**\n * EVENT: Subscribe to events of a specific type. The callback is invoked for\n * all future events of that type, and \u2014 when `opts.replay > 0` \u2014 for the\n * most recent `opts.replay` events already in history. Replay deliveries are\n * scheduled via `queueMicrotask`, so the unsubscribe handle is returned\n * synchronously and the callback fires after the current task completes.\n *\n * @param type Stream identifier.\n * @param callback Listener invoked with each event (replay + future).\n * @param opts.replay Number of buffered events to replay on subscribe, taken\n * from the tail of history (most recent first, delivered\n * in chronological order). Defaults to `1`, matching the\n * BehaviorSubject pattern: a fresh subscriber receives\n * the latest state. Pass `0` to suppress replay; pass a\n * larger value (capped by `maxEvents`) to receive more\n * history.\n * @returns Function that unsubscribes the listener.\n */\n const on = <T>(\n type: string,\n callback: NFEventConsumer<NFEventData<T>>,\n opts: { replay?: number } = {}\n ): NFEventUnsubscribe => {\n const replay = opts.replay ?? 1;\n const history = events.get(type);\n\n let typeListeners = listeners.get(type);\n if (!typeListeners) {\n typeListeners = new Set();\n listeners.set(type, typeListeners);\n }\n typeListeners.add(callback);\n\n if (history && history.length > 0 && replay > 0) {\n queueMicrotask(() => {\n const start = Math.max(0, history.length - replay);\n for (let i = start; i < history.length; i++) {\n callback(cloneEntry('event channel ' + type, history[i]!));\n }\n });\n }\n\n return () => {\n typeListeners!.delete(callback);\n if (typeListeners!.size === 0) {\n listeners.delete(type);\n }\n };\n };\n\n /**\n * EVENT: Publish a new event on `type`. The event is appended to the stream's\n * history and delivered synchronously to every current listener. When\n * `maxEvents` is exceeded the history is batch-trimmed; when `maxStreams` is\n * set, emitting to a new type may evict the least-recently-used stream.\n */\n const emit = <T>(type: string, data: T): void => {\n touchStream(type);\n appendAndNotify(type, { data, timestamp: Date.now() });\n };\n\n /**\n * EVENT: Publish a new event on `type` derived from the previous value, in\n * the style of a state reducer. `updateFn` receives a structured clone of\n * the last event's data (or `undefined` if the stream is empty), and its\n * return value becomes the next event. The clone protects historical events\n * from accidental mutation inside `updateFn`.\n *\n * Use this instead of `emit` when the new state depends on the old one \u2014 it\n * collapses the read-modify-write into a single, race-free call. Requires\n * `data` to be structured-clone-able when the stream is non-empty.\n *\n * @param type Stream identifier.\n * @param updateFn Reducer: `(current | undefined) => next`. Called with a\n * cloned snapshot of the last value (or `undefined` on\n * first emit).\n */\n const update = <T>(type: string, updateFn: (current: T | undefined) => T): void => {\n touchStream(type);\n\n const history = events.get(type) ?? [];\n const lastEvent = history[history.length - 1];\n const current =\n lastEvent === undefined ? undefined : cloneEntry('event channel ' + type, lastEvent.data);\n\n appendAndNotify(type, {\n data: updateFn(current),\n timestamp: Date.now(),\n });\n };\n\n const clear = (type?: string): void => {\n if (type) {\n // Clear event-related data\n events.delete(type);\n listeners.delete(type);\n\n // Clear resource-related data\n resources.delete(type);\n pending.delete(type);\n\n recentlyUsedStreams.delete(type);\n } else {\n // Clear all data\n events.clear();\n listeners.clear();\n pending.clear();\n resources.clear();\n recentlyUsedStreams.clear();\n }\n };\n\n return () => ({\n register,\n onReady,\n emit,\n update,\n on,\n clear,\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["class NFError extends Error {\n constructor(message: string, cause?: Error) {\n super(message, cause ? { cause } : undefined);\n this.name = 'NFError';\n }\n}\n\nexport { NFError };\n", "import type { StorageEntryKey } from 'lib/core/2.app/config/storage.contract';\nimport { NFError } from 'lib/core/native-federation.error';\n\ntype CloneEntry = <T>(name: StorageEntryKey, raw: T) => T;\n\nconst cloneEntry: CloneEntry = <T>(name: StorageEntryKey, raw: T) => {\n try {\n if (typeof structuredClone === 'function') {\n return structuredClone(raw);\n }\n } catch {\n /* structured clone is unavailable */\n }\n try {\n return JSON.parse(JSON.stringify(raw));\n } catch {\n /* object is not stringifyable */\n }\n throw new NFError(`Could not clone entry '${String(name)}'`);\n};\n\nexport { CloneEntry, cloneEntry };\n", "import type {\n NFEventConsumer,\n NFEventData,\n NFEventProvider,\n NFEventUnsubscribe,\n} from './event.contract';\nimport type { ForManagingEvents } from './for-managing-events.port';\nimport type { NFEventRegistryConfig, NFEventRegistryOptions } from './registry.contract';\nimport { cloneEntry } from 'lib/utils/clone-entry';\n\n/** @deprecated Use @softarc/native-federation-communication. Removed in v5. */\nexport function createRegistry(opts: NFEventRegistryOptions): ForManagingEvents {\n const cfg: NFEventRegistryConfig = {\n maxStreams: opts.maxStreams,\n maxEvents: opts.maxEvents ?? 1,\n removePercentage: opts.removePercentage,\n };\n\n // resources\n const resources = new Map<string, unknown>();\n const pending = new Map<string, Set<NFEventConsumer<any>>>();\n\n // events\n const events = new Map<string, NFEventData[]>();\n const listeners = new Map<string, Set<NFEventConsumer<NFEventData<any>>>>();\n const recentlyUsedStreams = new Set<string>();\n\n // Clamp to (maxEvents - 1) so at least one event always survives the trim.\n // Without this, maxEvents=1 (or any config where REMOVE_EVENTS == maxEvents)\n // would compute slice(-0), which returns the whole array and never trims.\n const REMOVE_EVENTS = Math.min(\n cfg.maxEvents - 1,\n cfg.removePercentage ? Math.ceil(cfg.maxEvents * cfg.removePercentage) : 1\n );\n\n /**\n * Mark `type` as the most-recently-used stream. When `maxStreams` is set and\n * the LRU set grows past that bound, the oldest stream (and its history) is\n * dropped. No-op when `maxStreams` is undefined \u2014 streams are then unbounded.\n */\n const touchStream = (type: string): void => {\n if (!cfg.maxStreams) return;\n recentlyUsedStreams.delete(type);\n recentlyUsedStreams.add(type);\n\n if (recentlyUsedStreams.size > cfg.maxStreams) {\n const oldest = recentlyUsedStreams.values().next().value;\n if (oldest) {\n recentlyUsedStreams.delete(oldest);\n events.delete(oldest);\n }\n }\n };\n\n /**\n * Append an event to `type`'s history, trim the history if it exceeds\n * `maxEvents`, and synchronously notify all current listeners. Trimming is\n * batched: when the history overflows, it is sliced down to\n * `(maxEvents - REMOVE_EVENTS)` items so subsequent emits don't slice on\n * every call.\n */\n const appendAndNotify = <T>(type: string, event: NFEventData<T>): void => {\n let history = events.get(type) ?? [];\n history.push(event);\n\n if (history.length > cfg.maxEvents) {\n history = history.slice(-(cfg.maxEvents - REMOVE_EVENTS));\n }\n\n events.set(type, history);\n\n const typeListeners = listeners.get(type);\n if (typeListeners && typeListeners.size > 0) {\n typeListeners.forEach(listener => listener(event));\n }\n };\n\n /**\n * RESOURCE: Register a resource by name. If the resource is a provider function, it is\n * invoked to obtain the actual resource. All callbacks waiting for this\n * resource via `onReady` are invoked once the resource is registered.\n */\n const register = async <T>(type: string, resource: T | NFEventProvider<T>): Promise<void> => {\n const value =\n typeof resource === 'function' ? await (resource as NFEventProvider<T>)() : resource;\n\n resources.set(type, value);\n\n const callbacks = pending.get(type);\n if (callbacks) {\n pending.delete(type);\n callbacks.forEach(cb => cb(value));\n }\n };\n\n /**\n * RESOURCE: Subscribe to the readiness of a resource. If the resource is already\n * registered, the callback is invoked immediately. Otherwise, the callback\n * is invoked once the resource is registered.\n */\n const onReady = <T>(type: string, callback: NFEventConsumer<T>): NFEventUnsubscribe => {\n const existing = resources.get(type);\n if (existing !== undefined) {\n callback(existing as T);\n return () => {};\n }\n\n let callbacks = pending.get(type);\n if (!callbacks) {\n callbacks = new Set();\n pending.set(type, callbacks);\n }\n callbacks.add(callback);\n\n return () => {\n callbacks!.delete(callback);\n if (callbacks!.size === 0) {\n pending.delete(type);\n }\n };\n };\n\n /**\n * EVENT: Subscribe to events of a specific type. The callback is invoked for\n * all future events of that type, and \u2014 when `opts.replay > 0` \u2014 for the\n * most recent `opts.replay` events already in history. Replay deliveries are\n * scheduled via `queueMicrotask`, so the unsubscribe handle is returned\n * synchronously and the callback fires after the current task completes.\n *\n * @param type Stream identifier.\n * @param callback Listener invoked with each event (replay + future).\n * @param opts.replay Number of buffered events to replay on subscribe, taken\n * from the tail of history (most recent first, delivered\n * in chronological order). Defaults to `1`, matching the\n * BehaviorSubject pattern: a fresh subscriber receives\n * the latest state. Pass `0` to suppress replay; pass a\n * larger value (capped by `maxEvents`) to receive more\n * history.\n * @returns Function that unsubscribes the listener.\n */\n const on = <T>(\n type: string,\n callback: NFEventConsumer<NFEventData<T>>,\n opts: { replay?: number } = {}\n ): NFEventUnsubscribe => {\n const replay = opts.replay ?? 1;\n const history = events.get(type);\n\n let typeListeners = listeners.get(type);\n if (!typeListeners) {\n typeListeners = new Set();\n listeners.set(type, typeListeners);\n }\n typeListeners.add(callback);\n\n if (history && history.length > 0 && replay > 0) {\n queueMicrotask(() => {\n const start = Math.max(0, history.length - replay);\n for (let i = start; i < history.length; i++) {\n callback(cloneEntry('event channel ' + type, history[i]!));\n }\n });\n }\n\n return () => {\n typeListeners!.delete(callback);\n if (typeListeners!.size === 0) {\n listeners.delete(type);\n }\n };\n };\n\n /**\n * EVENT: Publish a new event on `type`. The event is appended to the stream's\n * history and delivered synchronously to every current listener. When\n * `maxEvents` is exceeded the history is batch-trimmed; when `maxStreams` is\n * set, emitting to a new type may evict the least-recently-used stream.\n */\n const emit = <T>(type: string, data: T): void => {\n touchStream(type);\n appendAndNotify(type, { data, timestamp: Date.now() });\n };\n\n /**\n * EVENT: Publish a new event on `type` derived from the previous value, in\n * the style of a state reducer. `updateFn` receives a structured clone of\n * the last event's data (or `undefined` if the stream is empty), and its\n * return value becomes the next event. The clone protects historical events\n * from accidental mutation inside `updateFn`.\n *\n * Use this instead of `emit` when the new state depends on the old one \u2014 it\n * collapses the read-modify-write into a single, race-free call. Requires\n * `data` to be structured-clone-able when the stream is non-empty.\n *\n * @param type Stream identifier.\n * @param updateFn Reducer: `(current | undefined) => next`. Called with a\n * cloned snapshot of the last value (or `undefined` on\n * first emit).\n */\n const update = <T>(type: string, updateFn: (current: T | undefined) => T): void => {\n touchStream(type);\n\n const history = events.get(type) ?? [];\n const lastEvent = history[history.length - 1];\n const current =\n lastEvent === undefined ? undefined : cloneEntry('event channel ' + type, lastEvent.data);\n\n appendAndNotify(type, {\n data: updateFn(current),\n timestamp: Date.now(),\n });\n };\n\n const clear = (type?: string): void => {\n if (type) {\n // Clear event-related data\n events.delete(type);\n listeners.delete(type);\n\n // Clear resource-related data\n resources.delete(type);\n pending.delete(type);\n\n recentlyUsedStreams.delete(type);\n } else {\n // Clear all data\n events.clear();\n listeners.clear();\n pending.clear();\n resources.clear();\n recentlyUsedStreams.clear();\n }\n };\n\n return () => ({\n register,\n onReady,\n emit,\n update,\n on,\n clear,\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["opts"]
7
7
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.9.0",
2
+ "version": "4.10.1",
3
3
  "name": "@softarc/native-federation-orchestrator",
4
4
  "author": "Aukevanoost",
5
5
  "keywords": [
@@ -13,14 +13,14 @@
13
13
  },
14
14
  "license": "MIT",
15
15
  "engines": {
16
- "node": ">=24.16.0"
16
+ "node": ">=20.6.0"
17
17
  },
18
18
  "sideEffects": false,
19
19
  "dependencies": {
20
20
  "semver": "^7.7.1"
21
21
  },
22
22
  "peerDependencies": {
23
- "@softarc/native-federation": "^4.8.0"
23
+ "@softarc/native-federation": "^4.10.0"
24
24
  },
25
25
  "peerDependenciesMeta": {
26
26
  "@softarc/native-federation": {