@equinor/fusion-framework-vite-plugin-spa 3.1.11 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5239,9 +5239,31 @@ var ModuleEventLevel;
5239
5239
  })(ModuleEventLevel || (ModuleEventLevel = {}));
5240
5240
 
5241
5241
  /**
5242
- * Base class for creating module provider
5242
+ * Abstract base class for Fusion Framework module providers.
5243
5243
  *
5244
- * this is the interface which is returned after enabling a module
5244
+ * Extend `BaseModuleProvider` to create the runtime instance that a module’s
5245
+ * {@link Module.initialize | initialize} method returns. The base class
5246
+ * handles version parsing, subscription lifecycle management, and duck-typed
5247
+ * `instanceof` checks.
5248
+ *
5249
+ * Subclasses should register teardown callbacks via {@link _addTeardown} so
5250
+ * that resources (subscriptions, timers, event listeners) are automatically
5251
+ * cleaned up when the framework calls {@link dispose}.
5252
+ *
5253
+ * @template TConfig - The resolved configuration type for the module.
5254
+ *
5255
+ * @example
5256
+ * ```typescript
5257
+ * class MyProvider extends BaseModuleProvider<MyConfig> {
5258
+ * constructor(args: BaseModuleProviderCtorArgs<MyConfig>) {
5259
+ * super(args);
5260
+ * const sub = someObservable$.subscribe();
5261
+ * this._addTeardown(sub);
5262
+ * }
5263
+ * }
5264
+ * ```
5265
+ *
5266
+ * @see IModuleProvider
5245
5267
  */
5246
5268
  class BaseModuleProvider {
5247
5269
  /**
@@ -5273,6 +5295,11 @@ class BaseModuleProvider {
5273
5295
  get version() {
5274
5296
  return this.#version;
5275
5297
  }
5298
+ /**
5299
+ * Creates a new module provider.
5300
+ *
5301
+ * @param args - Version and resolved configuration for the module.
5302
+ */
5276
5303
  constructor(args) {
5277
5304
  const { version } = args;
5278
5305
  this.#version = new SemanticVersion(version);
@@ -5288,13 +5315,18 @@ class BaseModuleProvider {
5288
5315
  this.#subscriptions.add(teardown);
5289
5316
  return () => this.#subscriptions.remove(teardown);
5290
5317
  }
5318
+ /**
5319
+ * Unsubscribes all registered teardowns and releases held resources.
5320
+ *
5321
+ * Called automatically by the framework during module disposal.
5322
+ */
5291
5323
  dispose() {
5292
5324
  this.#subscriptions.unsubscribe();
5293
5325
  }
5294
5326
  }
5295
5327
 
5296
5328
  // Generated by genversion.
5297
- const version$8 = '5.0.6';
5329
+ const version$8 = '6.0.0';
5298
5330
 
5299
5331
  /* eslint-disable @typescript-eslint/no-explicit-any */
5300
5332
  /**
@@ -5310,9 +5342,37 @@ class RequiredModuleTimeoutError extends Error {
5310
5342
  }
5311
5343
  }
5312
5344
  /**
5313
- * Configurator class for modules.
5314
- * @template TModules - Array of modules.
5315
- * @template TRef - Reference type.
5345
+ * Core orchestrator that drives the module lifecycle in Fusion Framework.
5346
+ *
5347
+ * `ModulesConfigurator` manages the full configure → initialize → dispose pipeline
5348
+ * for a set of modules. Consumers register modules via {@link addConfig} or
5349
+ * {@link configure}, then call {@link initialize} to produce a sealed
5350
+ * {@link ModulesInstance} whose properties are the initialized module providers.
5351
+ *
5352
+ * The lifecycle phases executed during {@link initialize} are:
5353
+ *
5354
+ * 1. **Configure** – each module’s `configure()` factory creates a config builder;
5355
+ * registered callbacks mutate it; `postConfigure()` hooks run.
5356
+ * 2. **Initialize** – modules are initialized concurrently via `initialize()`;
5357
+ * cross-module dependencies are resolved through `requireInstance()`.
5358
+ * 3. **Post-initialize** – `postInitialize()` hooks and `onInitialized` callbacks run.
5359
+ *
5360
+ * All lifecycle transitions emit {@link ModuleEvent} entries on the {@link event$}
5361
+ * observable for telemetry and debugging.
5362
+ *
5363
+ * @template TModules - Tuple of module types managed by this configurator.
5364
+ * @template TRef - Reference type passed through configuration (usually a parent instance).
5365
+ *
5366
+ * @example
5367
+ * ```typescript
5368
+ * const configurator = new ModulesConfigurator([httpModule, authModule]);
5369
+ * configurator.addConfig({
5370
+ * module: httpModule,
5371
+ * configure: (cfg) => cfg.setBaseUrl('https://api.example.com'),
5372
+ * });
5373
+ * const modules = await configurator.initialize();
5374
+ * // modules.http, modules.auth are now available
5375
+ * ```
5316
5376
  */
5317
5377
  class ModulesConfigurator {
5318
5378
  /**
@@ -5984,6 +6044,8 @@ class ModulesConfigurator {
5984
6044
  },
5985
6045
  });
5986
6046
  }
6047
+ /**
6048
+ * Disposes all modules managed by this configurator.\n *\n * Calls each module\u2019s `dispose` hook (if defined) and completes the\n * internal event stream. After disposal the configurator should not be reused.\n *\n * @param instance - The initialized modules instance to tear down.\n * @param ref - Optional reference object forwarded to module dispose hooks.\n */
5987
6049
  async dispose(instance, ref) {
5988
6050
  this._registerEvent({
5989
6051
  level: ModuleEventLevel.Debug,
@@ -20674,218 +20736,6 @@ const requestValidationOperator = (options) => (request) => {
20674
20736
  }
20675
20737
  };
20676
20738
 
20677
- /** @inheritdoc */
20678
- class HttpClientConfigurator {
20679
- _clients = {};
20680
- /** Get a clone of all configured clients */
20681
- get clients() {
20682
- return { ...this._clients };
20683
- }
20684
- /** default class for creation of http clients */
20685
- defaultHttpClientCtor;
20686
- /** default request handler for http clients, applied on creation */
20687
- defaultHttpRequestHandler = new HttpRequestHandler({
20688
- // convert all request methods to uppercase
20689
- 'capitalize-method': capitalizeRequestMethodOperator(),
20690
- // validate the request object
20691
- 'request-validation': requestValidationOperator(),
20692
- });
20693
- /**
20694
- * Create a instance of http configuration
20695
- * @param client defaultHttpRequestHandler
20696
- */
20697
- constructor(client) {
20698
- this.defaultHttpClientCtor = client;
20699
- }
20700
- /** @inheritdoc */
20701
- hasClient(name) {
20702
- return Object.keys(this._clients).includes(name);
20703
- }
20704
- /** @inheritdoc */
20705
- configureClient(name, args) {
20706
- const argFn = typeof args === 'string' ? { baseUri: args } : args;
20707
- const options = typeof argFn === 'function' ? { onCreate: argFn } : argFn;
20708
- this._clients[name] = {
20709
- ...this._clients[name],
20710
- ...options,
20711
- };
20712
- return this;
20713
- }
20714
- }
20715
-
20716
- // Generated by genversion.
20717
- const version$6 = '7.0.8';
20718
-
20719
- /**
20720
- * Exception thrown when a client cannot be found.
20721
- *
20722
- * This error is typically used to indicate that a requested client instance
20723
- * does not exist or cannot be located within the current context.
20724
- *
20725
- * @extends {Error}
20726
- */
20727
- class ClientNotFoundException extends Error {
20728
- }
20729
- /**
20730
- * Checks if a given string is a valid URL.
20731
- * @param url - The string to check for a valid URL.
20732
- * @returns `true` if the input string is a valid URL, `false` otherwise.
20733
- */
20734
- const isURL = (url) => {
20735
- const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
20736
- '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name
20737
- '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
20738
- '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
20739
- '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
20740
- '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
20741
- return pattern.test(url);
20742
- };
20743
- /**
20744
- * The `HttpClientProvider` class is responsible for managing HTTP client instances and their configuration.
20745
- * It provides methods to check if a client is configured, create new client instances, and create custom client instances.
20746
- */
20747
- class HttpClientProvider extends BaseModuleProvider {
20748
- config;
20749
- /**
20750
- * Gets the default HTTP request handler for the HTTP client provider.
20751
- * @returns The default HTTP request handler.
20752
- */
20753
- get defaultHttpRequestHandler() {
20754
- return this.config.defaultHttpRequestHandler;
20755
- }
20756
- constructor(config) {
20757
- super({
20758
- version: version$6,
20759
- config,
20760
- });
20761
- this.config = config;
20762
- }
20763
- /**
20764
- * Checks if a client with the given key is configured in the `HttpClientProvider`.
20765
- * @param key - The key of the HTTP client to check.
20766
- * @returns `true` if a client with the given key is configured, `false` otherwise.
20767
- */
20768
- hasClient(key) {
20769
- return Object.keys(this.config.clients).includes(key);
20770
- }
20771
- /**
20772
- * Creates a new HTTP client instance with the specified configuration.
20773
- *
20774
- * @param keyOrConfig - The key or configuration object for the HTTP client.
20775
- * @returns The created HTTP client instance.
20776
- *
20777
- * @remarks
20778
- * This method resolves the configuration for the HTTP client based on the provided `keyOrConfig` parameter.
20779
- * If a string is provided, it is treated as the key for a pre-configured client in the `HttpClientProvider`.
20780
- * If an `HttpClientOptions` object is provided, it is used as the configuration for the new client instance.
20781
- *
20782
- * The method sets up the HTTP client with the following options:
20783
- * - `baseUri`: The base URI for the HTTP client.
20784
- * - `defaultScopes`: The default scopes to be used for authentication.
20785
- * - `onCreate`: An optional callback function that is called when the client instance is created.
20786
- * - `ctor`: The constructor function for the HTTP client, defaulting to the configured `defaultHttpClientCtor`.
20787
- * - `requestHandler`: The HTTP request handler to be used by the client, defaulting to the `defaultHttpRequestHandler`.
20788
- *
20789
- * The created HTTP client instance is returned.
20790
- */
20791
- createClient(keyOrConfig) {
20792
- const config = this._resolveConfig(keyOrConfig);
20793
- const { baseUri, defaultScopes = [], onCreate, ctor = this.config.defaultHttpClientCtor, requestHandler = this.defaultHttpRequestHandler, } = config;
20794
- const options = { requestHandler };
20795
- const instance = new ctor(baseUri || '', options);
20796
- Object.assign(instance, { defaultScopes });
20797
- onCreate?.(instance);
20798
- return instance;
20799
- }
20800
- /**
20801
- * Creates a new HTTP client instance with the specified configuration.
20802
- *
20803
- * @param key - The key of the pre-configured HTTP client to create.
20804
- * @returns The created HTTP client instance, cast to the specified type `T`.
20805
- *
20806
- * @remarks
20807
- * This method delegates to the `createClient` method, but casts the returned
20808
- * instance to the specified type `T`. This can be useful when you need to
20809
- * work with a specific HTTP client implementation, but the `HttpClientProvider`
20810
- * is configured to use a different implementation.
20811
- */
20812
- createCustomClient(key) {
20813
- return this.createClient(key);
20814
- }
20815
- /**
20816
- * Resolves the configuration for an HTTP client based on the provided `keyOrConfig` parameter.
20817
- *
20818
- * If a string is provided, it is treated as the key for a pre-configured client in the `HttpClientProvider`.
20819
- * If an `HttpClientOptions` object is provided, it is used as the configuration for the new client instance.
20820
- *
20821
- * @param keyOrConfig - The key or configuration object for the HTTP client.
20822
- * @returns The resolved HTTP client configuration.
20823
- */
20824
- _resolveConfig(keyOrConfig) {
20825
- if (typeof keyOrConfig === 'string') {
20826
- const config = this.config.clients[keyOrConfig];
20827
- if (!config && isURL(keyOrConfig)) {
20828
- return { baseUri: keyOrConfig };
20829
- }
20830
- else if (!config) {
20831
- throw new ClientNotFoundException(`No registered http client for key [${keyOrConfig}]`);
20832
- }
20833
- return config;
20834
- }
20835
- return keyOrConfig;
20836
- }
20837
- }
20838
-
20839
- function fromFetch(input, initWithSelector) {
20840
- if (initWithSelector === void 0) { initWithSelector = {}; }
20841
- var selector = initWithSelector.selector, init = __rest(initWithSelector, ["selector"]);
20842
- return new Observable(function (subscriber) {
20843
- var controller = new AbortController();
20844
- var signal = controller.signal;
20845
- var abortable = true;
20846
- var outerSignal = init.signal;
20847
- if (outerSignal) {
20848
- if (outerSignal.aborted) {
20849
- controller.abort();
20850
- }
20851
- else {
20852
- var outerSignalHandler_1 = function () {
20853
- if (!signal.aborted) {
20854
- controller.abort();
20855
- }
20856
- };
20857
- outerSignal.addEventListener('abort', outerSignalHandler_1);
20858
- subscriber.add(function () { return outerSignal.removeEventListener('abort', outerSignalHandler_1); });
20859
- }
20860
- }
20861
- var perSubscriberInit = __assign(__assign({}, init), { signal: signal });
20862
- var handleError = function (err) {
20863
- abortable = false;
20864
- subscriber.error(err);
20865
- };
20866
- fetch(input, perSubscriberInit)
20867
- .then(function (response) {
20868
- if (selector) {
20869
- innerFrom(selector(response)).subscribe(createOperatorSubscriber(subscriber, undefined, function () {
20870
- abortable = false;
20871
- subscriber.complete();
20872
- }, handleError));
20873
- }
20874
- else {
20875
- abortable = false;
20876
- subscriber.next(response);
20877
- subscriber.complete();
20878
- }
20879
- })
20880
- .catch(handleError);
20881
- return function () {
20882
- if (abortable) {
20883
- controller.abort();
20884
- }
20885
- };
20886
- });
20887
- }
20888
-
20889
20739
  /**
20890
20740
  * Represents an error that occurs when handling an HTTP response.
20891
20741
  * @template TResponse The type of the HTTP response.
@@ -20944,80 +20794,6 @@ class ServerSentEventResponseError extends HttpResponseError {
20944
20794
  }
20945
20795
  }
20946
20796
 
20947
- /**
20948
- * Asynchronously parses the JSON data from a given HTTP response.
20949
- *
20950
- * If the response has a status code of 204 (No Content), this function will resolve with `undefined`.
20951
- *
20952
- * If the response is not successful (i.e. `response.ok` is `false`), this function will throw an `HttpJsonResponseError` with the response details and the parsed data (if any).
20953
- *
20954
- * If there is an error parsing the JSON data, this function will throw an `HttpJsonResponseError` with the parsing error and the original response.
20955
- *
20956
- * @template TType - The expected type of the parsed JSON data.
20957
- * @template TResponse - The type of the HTTP response object.
20958
- * @param response - The HTTP response to parse.
20959
- * @returns A promise that resolves with the parsed JSON data, or rejects with an `HttpJsonResponseError`.
20960
- */
20961
- const jsonSelector = async (response) => {
20962
- /** Status code 204 indicates no content in the response */
20963
- if (response.status === 204) {
20964
- return Promise.resolve();
20965
- }
20966
- try {
20967
- // Parse the response JSON data
20968
- const data = await response.json();
20969
- // Check if the response was successful
20970
- if (!response.ok) {
20971
- // Throw an error with the response details
20972
- throw new HttpJsonResponseError('network response was not OK', response, { data });
20973
- }
20974
- // Return the parsed data
20975
- return data;
20976
- }
20977
- catch (cause) {
20978
- // If the cause is an HttpJsonResponseError, rethrow it
20979
- if (cause instanceof HttpJsonResponseError) {
20980
- throw cause;
20981
- }
20982
- // Otherwise, throw a new HttpJsonResponseError with the parsing error
20983
- throw new HttpJsonResponseError('failed to parse response', response, { cause });
20984
- }
20985
- };
20986
-
20987
- /**
20988
- * Extracts a blob and filename from a successful HTTP response.
20989
- *
20990
- * @param response - The HTTP response to extract the blob and filename from.
20991
- * @returns A promise that resolves to an object containing the extracted blob and filename.
20992
- * @throws {Error} If the response is not successful or if there is an error parsing the response.
20993
- */
20994
- const blobSelector = async (response) => {
20995
- if (!response.ok) {
20996
- // Throw an error if the network response is not successful
20997
- throw new Error('network response was not OK');
20998
- }
20999
- // Status code 204 indicates no content, so throw an error
21000
- if (response.status === 204) {
21001
- throw new Error('no content');
21002
- }
21003
- // Extract the filename from the 'content-disposition' header
21004
- const filename = response.headers
21005
- .get('content-disposition')
21006
- ?.split(';')
21007
- .find((n) => n.includes('filename='))
21008
- ?.replace('filename=', '')
21009
- ?.trim();
21010
- try {
21011
- // Convert the response to a Blob and return the filename and Blob
21012
- const blob = await response.blob();
21013
- return { filename, blob };
21014
- }
21015
- catch (err) {
21016
- // Throw an error if there's a problem parsing the response
21017
- throw Error('failed to parse response');
21018
- }
21019
- };
21020
-
21021
20797
  const defaultDataParser = (data) => {
21022
20798
  try {
21023
20799
  return JSON.parse(data);
@@ -21178,6 +20954,303 @@ const createSseSelector = (options) => {
21178
20954
  };
21179
20955
  };
21180
20956
 
20957
+ /** @inheritdoc */
20958
+ class HttpClientConfigurator {
20959
+ _clients = {};
20960
+ /** Gets a shallow clone of all named client configurations. */
20961
+ get clients() {
20962
+ return { ...this._clients };
20963
+ }
20964
+ /** Default constructor used when a client configuration does not provide `ctor`. */
20965
+ defaultHttpClientCtor;
20966
+ /** Default request handler pipeline cloned into each created client instance. */
20967
+ defaultHttpRequestHandler = new HttpRequestHandler({
20968
+ // convert all request methods to uppercase
20969
+ 'capitalize-method': capitalizeRequestMethodOperator(),
20970
+ // validate the request object
20971
+ 'request-validation': requestValidationOperator(),
20972
+ });
20973
+ /**
20974
+ * Creates a configurator with the default client constructor.
20975
+ * @param client - The default client constructor used when `ctor` is not configured per client.
20976
+ */
20977
+ constructor(client) {
20978
+ this.defaultHttpClientCtor = client;
20979
+ }
20980
+ /** @inheritdoc */
20981
+ hasClient(name) {
20982
+ return Object.keys(this._clients).includes(name);
20983
+ }
20984
+ /** @inheritdoc */
20985
+ configureClient(name, args) {
20986
+ const argFn = typeof args === 'string' ? { baseUri: args } : args;
20987
+ const options = typeof argFn === 'function' ? { onCreate: argFn } : argFn;
20988
+ this._clients[name] = {
20989
+ ...this._clients[name],
20990
+ ...options,
20991
+ };
20992
+ return this;
20993
+ }
20994
+ }
20995
+
20996
+ // Generated by genversion.
20997
+ const version$6 = '8.0.0';
20998
+
20999
+ /**
21000
+ * Thrown when `createClient(name)` is called with an unknown client key.
21001
+ *
21002
+ * This is only used when the provided string is neither a registered client name
21003
+ * nor an absolute `http:` or `https:` URL.
21004
+ */
21005
+ class ClientNotFoundException extends Error {
21006
+ }
21007
+ /** URL protocols accepted as valid ad-hoc base URIs. */
21008
+ const SUPPORTED_PROTOCOLS = ['http:', 'https:', 'ws:', 'wss:'];
21009
+ /**
21010
+ * Checks if a given string is a valid absolute URL with a supported protocol.
21011
+ * @param url - The string to check.
21012
+ * @returns `true` when the string uses one of {@link SUPPORTED_PROTOCOLS}.
21013
+ */
21014
+ const isURL = (url) => {
21015
+ try {
21016
+ const parsed = new URL(url);
21017
+ return SUPPORTED_PROTOCOLS.includes(parsed.protocol);
21018
+ }
21019
+ catch {
21020
+ return false;
21021
+ }
21022
+ };
21023
+ /**
21024
+ * Heuristic check for strings that look like a bare hostname or URL without a
21025
+ * protocol prefix (e.g. `api.example.com` or `api.example.com/v1`).
21026
+ *
21027
+ * Used to emit a deprecation warning when callers rely on the old (pre-patch)
21028
+ * behaviour that accepted protocol-less URLs.
21029
+ */
21030
+ const looksLikeURL = (value) => !value.includes(' ') && /^[a-z\d]([a-z\d-]*\.)+[a-z]{2,}/i.test(value);
21031
+ /**
21032
+ * The `HttpClientProvider` class is responsible for managing HTTP client instances and their configuration.
21033
+ * It provides methods to check if a client is configured, create new client instances, and create custom client instances.
21034
+ */
21035
+ class HttpClientProvider extends BaseModuleProvider {
21036
+ config;
21037
+ /**
21038
+ * Gets the default HTTP request handler for the HTTP client provider.
21039
+ * @returns The default HTTP request handler.
21040
+ */
21041
+ get defaultHttpRequestHandler() {
21042
+ return this.config.defaultHttpRequestHandler;
21043
+ }
21044
+ constructor(config) {
21045
+ super({
21046
+ version: version$6,
21047
+ config,
21048
+ });
21049
+ this.config = config;
21050
+ }
21051
+ /**
21052
+ * Checks if a client with the given key is configured in the `HttpClientProvider`.
21053
+ * @param key - The key of the HTTP client to check.
21054
+ * @returns `true` if a client with the given key is configured, `false` otherwise.
21055
+ */
21056
+ hasClient(key) {
21057
+ return Object.keys(this.config.clients).includes(key);
21058
+ }
21059
+ /**
21060
+ * Creates a fresh HTTP client instance from a named or ad-hoc configuration.
21061
+ *
21062
+ * @param keyOrConfig - The key or configuration object for the HTTP client.
21063
+ * @returns The created HTTP client instance.
21064
+ *
21065
+ * @remarks
21066
+ * This method resolves the configuration for the HTTP client based on the provided `keyOrConfig` parameter.
21067
+ * If a string is provided, it is treated as the key for a pre-configured client in the `HttpClientProvider`.
21068
+ * If an `HttpClientOptions` object is provided, it is used as the configuration for the new client instance.
21069
+ *
21070
+ * The method applies `baseUri`, `defaultScopes`, `requestHandler`, `responseHandler`,
21071
+ * a custom `ctor` when configured, and finally runs `onCreate` for the newly created instance.
21072
+ *
21073
+ * The created HTTP client instance is returned.
21074
+ */
21075
+ createClient(keyOrConfig) {
21076
+ const config = this._resolveConfig(keyOrConfig);
21077
+ const { baseUri, defaultScopes = [], onCreate, ctor = this.config.defaultHttpClientCtor, requestHandler = this.defaultHttpRequestHandler, responseHandler, } = config;
21078
+ const options = { requestHandler, responseHandler };
21079
+ const instance = new ctor(baseUri || '', options);
21080
+ Object.assign(instance, { defaultScopes });
21081
+ onCreate?.(instance);
21082
+ return instance;
21083
+ }
21084
+ /**
21085
+ * Creates a client instance and returns it as the requested custom client type.
21086
+ *
21087
+ * @param key - The key of the pre-configured HTTP client to create.
21088
+ * @returns The created HTTP client instance, cast to the specified type `T`.
21089
+ *
21090
+ * @remarks
21091
+ * This method delegates to the `createClient` method, but casts the returned
21092
+ * instance to the specified type `T`. This can be useful when you need to
21093
+ * work with a specific HTTP client implementation, but the `HttpClientProvider`
21094
+ * is configured to use a different implementation.
21095
+ */
21096
+ createCustomClient(key) {
21097
+ return this.createClient(key);
21098
+ }
21099
+ /**
21100
+ * Resolves the configuration for an HTTP client based on the provided `keyOrConfig` parameter.
21101
+ *
21102
+ * If a string is provided, it is treated as either a pre-configured client key or,
21103
+ * when it is an absolute `http:` or `https:` URL, as an ad-hoc `baseUri`.
21104
+ * If an `HttpClientOptions` object is provided, it is used directly as the configuration for the new client instance.
21105
+ *
21106
+ * @param keyOrConfig - The key or configuration object for the HTTP client.
21107
+ * @returns The resolved HTTP client configuration.
21108
+ */
21109
+ _resolveConfig(keyOrConfig) {
21110
+ if (typeof keyOrConfig === 'string') {
21111
+ const config = this.config.clients[keyOrConfig];
21112
+ if (!config && isURL(keyOrConfig)) {
21113
+ return { baseUri: keyOrConfig };
21114
+ }
21115
+ else if (!config && looksLikeURL(keyOrConfig)) {
21116
+ console.warn(`[HttpClientProvider] "${keyOrConfig}" looks like a URL but is missing the http:// or https:// protocol. ` +
21117
+ `Treating it as "https://${keyOrConfig}". ` +
21118
+ `Pass a fully-qualified URL to silence this warning.`);
21119
+ return { baseUri: `https://${keyOrConfig}` };
21120
+ }
21121
+ else if (!config) {
21122
+ throw new ClientNotFoundException(`No registered http client for key [${keyOrConfig}]`);
21123
+ }
21124
+ return config;
21125
+ }
21126
+ return keyOrConfig;
21127
+ }
21128
+ }
21129
+
21130
+ function fromFetch(input, initWithSelector) {
21131
+ if (initWithSelector === void 0) { initWithSelector = {}; }
21132
+ var selector = initWithSelector.selector, init = __rest(initWithSelector, ["selector"]);
21133
+ return new Observable(function (subscriber) {
21134
+ var controller = new AbortController();
21135
+ var signal = controller.signal;
21136
+ var abortable = true;
21137
+ var outerSignal = init.signal;
21138
+ if (outerSignal) {
21139
+ if (outerSignal.aborted) {
21140
+ controller.abort();
21141
+ }
21142
+ else {
21143
+ var outerSignalHandler_1 = function () {
21144
+ if (!signal.aborted) {
21145
+ controller.abort();
21146
+ }
21147
+ };
21148
+ outerSignal.addEventListener('abort', outerSignalHandler_1);
21149
+ subscriber.add(function () { return outerSignal.removeEventListener('abort', outerSignalHandler_1); });
21150
+ }
21151
+ }
21152
+ var perSubscriberInit = __assign(__assign({}, init), { signal: signal });
21153
+ var handleError = function (err) {
21154
+ abortable = false;
21155
+ subscriber.error(err);
21156
+ };
21157
+ fetch(input, perSubscriberInit)
21158
+ .then(function (response) {
21159
+ if (selector) {
21160
+ innerFrom(selector(response)).subscribe(createOperatorSubscriber(subscriber, undefined, function () {
21161
+ abortable = false;
21162
+ subscriber.complete();
21163
+ }, handleError));
21164
+ }
21165
+ else {
21166
+ abortable = false;
21167
+ subscriber.next(response);
21168
+ subscriber.complete();
21169
+ }
21170
+ })
21171
+ .catch(handleError);
21172
+ return function () {
21173
+ if (abortable) {
21174
+ controller.abort();
21175
+ }
21176
+ };
21177
+ });
21178
+ }
21179
+
21180
+ /**
21181
+ * Asynchronously parses the JSON data from a given HTTP response.
21182
+ *
21183
+ * If the response has a status code of 204 (No Content), this function will resolve with `undefined`.
21184
+ *
21185
+ * If the response is not successful (i.e. `response.ok` is `false`), this function will throw an `HttpJsonResponseError` with the response details and the parsed data (if any).
21186
+ *
21187
+ * If there is an error parsing the JSON data, this function will throw an `HttpJsonResponseError` with the parsing error and the original response.
21188
+ *
21189
+ * @template TType - The expected type of the parsed JSON data.
21190
+ * @template TResponse - The type of the HTTP response object.
21191
+ * @param response - The HTTP response to parse.
21192
+ * @returns A promise that resolves with the parsed JSON data, or rejects with an `HttpJsonResponseError`.
21193
+ */
21194
+ const jsonSelector = async (response) => {
21195
+ /** Status code 204 indicates no content in the response */
21196
+ if (response.status === 204) {
21197
+ return Promise.resolve();
21198
+ }
21199
+ try {
21200
+ // Parse the response JSON data
21201
+ const data = await response.json();
21202
+ // Check if the response was successful
21203
+ if (!response.ok) {
21204
+ // Throw an error with the response details
21205
+ throw new HttpJsonResponseError('network response was not OK', response, { data });
21206
+ }
21207
+ // Return the parsed data
21208
+ return data;
21209
+ }
21210
+ catch (cause) {
21211
+ // If the cause is an HttpJsonResponseError, rethrow it
21212
+ if (cause instanceof HttpJsonResponseError) {
21213
+ throw cause;
21214
+ }
21215
+ // Otherwise, throw a new HttpJsonResponseError with the parsing error
21216
+ throw new HttpJsonResponseError('failed to parse response', response, { cause });
21217
+ }
21218
+ };
21219
+
21220
+ /**
21221
+ * Extracts a blob and filename from a successful HTTP response.
21222
+ *
21223
+ * @param response - The HTTP response to extract the blob and filename from.
21224
+ * @returns A promise that resolves to an object containing the extracted blob and filename.
21225
+ * @throws {Error} If the response is not successful or if there is an error parsing the response.
21226
+ */
21227
+ const blobSelector = async (response) => {
21228
+ if (!response.ok) {
21229
+ // Throw an error if the network response is not successful
21230
+ throw new Error('network response was not OK');
21231
+ }
21232
+ // Status code 204 indicates no content, so throw an error
21233
+ if (response.status === 204) {
21234
+ throw new Error('no content');
21235
+ }
21236
+ // Extract the filename from the 'content-disposition' header
21237
+ const filename = response.headers
21238
+ .get('content-disposition')
21239
+ ?.split(';')
21240
+ .find((n) => n.includes('filename='))
21241
+ ?.replace('filename=', '')
21242
+ ?.trim();
21243
+ try {
21244
+ // Convert the response to a Blob and return the filename and Blob
21245
+ const blob = await response.blob();
21246
+ return { filename, blob };
21247
+ }
21248
+ catch (err) {
21249
+ // Throw an error if there's a problem parsing the response
21250
+ throw Error('failed to parse response');
21251
+ }
21252
+ };
21253
+
21181
21254
  /** Base http client for executing requests */
21182
21255
  class HttpClient {
21183
21256
  uri;
@@ -21332,15 +21405,15 @@ class HttpClient {
21332
21405
  * @returns A `StreamResponse` that emits `ServerSentEvent<T>` objects as they are received from the server.
21333
21406
  *
21334
21407
  * @example
21335
- * const sse$ = httpClient.sse(
21336
- * '/events',
21337
- * { method: 'POST', body: JSON.stringify({ prompt: 'tell me a joke' }) },
21338
- * { eventFilter: ['message'] }
21408
+ * const sse$ = httpClient.sse$(
21409
+ * '/events',
21410
+ * { method: 'POST', body: JSON.stringify({ prompt: 'tell me a joke' }) },
21411
+ * { eventFilter: ['message'] },
21339
21412
  * );
21340
21413
  * sse$.subscribe({
21341
- * next: (event) => console.log(event),
21342
- * error: (err) => console.error(err),
21343
- * complete: () => console.log('Completed'),
21414
+ * next: (event) => console.log(event),
21415
+ * error: (err) => console.error(err),
21416
+ * complete: () => console.log('Completed'),
21344
21417
  * });
21345
21418
  */
21346
21419
  sse$(path, args, options) {
@@ -21397,6 +21470,7 @@ class HttpClient {
21397
21470
  const { selector, ...options } = args || {};
21398
21471
  const response$ = of({
21399
21472
  ...options,
21473
+ path,
21400
21474
  uri: this._resolveUrl(path),
21401
21475
  }).pipe(
21402
21476
  /** prepare request, allow extensions to modify request */
@@ -21503,16 +21577,21 @@ class HttpClientMsal extends HttpClient {
21503
21577
  * Merges the default scopes defined in the `HttpClientMsal` class with the scopes provided in the `init` parameter, if any.
21504
21578
  * This ensures that the request includes the necessary scopes for MSAL authentication.
21505
21579
  */
21506
- const args = Object.assign(init || {}, {
21580
+ const args = {
21581
+ ...init,
21507
21582
  scopes: this.defaultScopes.concat(init?.scopes || []),
21508
- });
21583
+ };
21509
21584
  return super._fetch$(path, args);
21510
21585
  }
21511
21586
  }
21512
21587
 
21513
21588
  /* eslint-disable @typescript-eslint/no-explicit-any */
21514
21589
  /**
21515
- * HTTP module with MSAL authentication.
21590
+ * Default HTTP module definition for Fusion Framework applications.
21591
+ *
21592
+ * The module uses `HttpClientMsal` as the default client implementation and,
21593
+ * when the auth module is available, installs a request handler that can acquire
21594
+ * bearer tokens for scoped requests.
21516
21595
  */
21517
21596
  const module$4 = {
21518
21597
  name: 'http',
@@ -21561,15 +21640,14 @@ const module$4 = {
21561
21640
  },
21562
21641
  };
21563
21642
  /**
21564
- * Configures the HTTP client with MSAL authentication.
21643
+ * Creates a module configurator that registers one named HTTP client.
21565
21644
  *
21566
- * This function creates a module configurator that can be used to configure the HTTP module
21567
- * with MSAL authentication. The configurator takes a name and a set of HTTP client options,
21568
- * and returns a module configurator that can be used to configure the HTTP module.
21645
+ * This is the convenience API for the common case where a setup step only needs to
21646
+ * register one client with `baseUri`, `defaultScopes`, handlers, or a custom constructor.
21569
21647
  *
21570
- * @param name - The name of the HTTP client configuration.
21571
- * @param args - The HTTP client options, including the MSAL configuration.
21572
- * @returns A module configurator that can be used to configure the HTTP module.
21648
+ * @param name - The client key used later with `createClient(name)`.
21649
+ * @param args - The named client configuration.
21650
+ * @returns A module configurator that registers the named client.
21573
21651
  */
21574
21652
  const configureHttpClient = (name, args) => ({
21575
21653
  module: module$4,
@@ -22437,12 +22515,58 @@ var immer = new Immer2();
22437
22515
  var produce = immer.produce;
22438
22516
  var castDraft = (value) => value;
22439
22517
 
22518
+ /**
22519
+ * RxJS operator that filters an action stream to only emit actions matching
22520
+ * one or more specified action types.
22521
+ *
22522
+ * @template TAction - The union of possible action types in the stream.
22523
+ * @template TType - The specific action type constant(s) to filter for.
22524
+ * @param types - One or more action type strings to filter by.
22525
+ * @returns An `OperatorFunction` that narrows the stream to matching actions.
22526
+ *
22527
+ * @example
22528
+ * ```ts
22529
+ * import { filterAction } from '@equinor/fusion-observable/operators';
22530
+ *
22531
+ * action$.pipe(
22532
+ * filterAction('increment', 'decrement'),
22533
+ * ).subscribe((action) => {
22534
+ * // action is narrowed to increment | decrement
22535
+ * });
22536
+ * ```
22537
+ */
22440
22538
  const filterAction = (...types) => filter((x) => types.includes(x.type));
22441
22539
 
22442
22540
  /**
22443
- * A specialized Observable that maintains internal state, which can be mutated by dispatching actions.
22541
+ * A specialized Observable that maintains internal state mutated by dispatching actions.
22542
+ *
22444
22543
  * Actions are processed sequentially by a reducer function to produce new state values.
22445
- * This class extends from Observable to allow subscribers to react to state changes over time.
22544
+ * Extends `Observable` so subscribers react to state changes over time.
22545
+ *
22546
+ * Inspired by Redux-style state management but built on top of RxJS, `FlowSubject`
22547
+ * combines a `BehaviorSubject` for state with a `Subject` for actions, providing
22548
+ * a reactive, observable state container.
22549
+ *
22550
+ * @template S - The state type managed by this subject.
22551
+ * @template A - The action type dispatched to this subject.
22552
+ *
22553
+ * @example
22554
+ * ```ts
22555
+ * import { FlowSubject, createReducer } from '@equinor/fusion-observable';
22556
+ *
22557
+ * type State = { count: number };
22558
+ * type Action = { type: 'increment' } | { type: 'decrement' };
22559
+ *
22560
+ * const reducer = createReducer<State, Action>({ count: 0 }, (builder) =>
22561
+ * builder
22562
+ * .addCase('increment', (state) => { state.count += 1; })
22563
+ * .addCase('decrement', (state) => { state.count -= 1; }),
22564
+ * );
22565
+ *
22566
+ * const subject = new FlowSubject(reducer);
22567
+ * subject.subscribe((state) => console.log(state.count));
22568
+ * subject.next({ type: 'increment' }); // logs: 1
22569
+ * ```
22446
22570
  */
22447
22571
  class FlowSubject extends Observable {
22448
22572
  /**
@@ -22539,21 +22663,38 @@ class FlowSubject extends Observable {
22539
22663
  .subscribe(this.#action);
22540
22664
  }
22541
22665
  /**
22542
- * Deprecated. Use `addFlow` instead.
22666
+ * @deprecated Use {@link FlowSubject.addFlow} instead.
22543
22667
  *
22544
- * @deprecated use `addFlow`
22545
- *
22546
- * @param fn The flow function to execute.
22668
+ * @param fn - The flow function to execute.
22547
22669
  * @returns A subscription to the flow.
22548
22670
  */
22549
22671
  addEpic(fn) {
22550
22672
  return this.addFlow(fn);
22551
22673
  }
22552
22674
  /**
22553
- * Adds a flow that listens for actions and performs side effects.
22675
+ * Adds a flow (epic-style) that transforms the action stream and optionally
22676
+ * reads state, then emits new actions back into the subject.
22554
22677
  *
22555
- * @param fn The flow function to execute.
22556
- * @returns A subscription to the flow.
22678
+ * Flows receive the full `action$` stream and the state observable, and must
22679
+ * return an `Observable<A>`. This is useful for complex async orchestration.
22680
+ *
22681
+ * @param fn - The flow function that receives `(action$, state$)` and returns an action observable.
22682
+ * @returns A subscription to the flow. Unsubscribe to remove the flow.
22683
+ * @throws {TypeError} If the flow function does not return an observable.
22684
+ *
22685
+ * @example
22686
+ * ```ts
22687
+ * subject.addFlow((action$) =>
22688
+ * action$.pipe(
22689
+ * filterAction('fetchData'),
22690
+ * switchMap((action) =>
22691
+ * fetchApi(action.payload).pipe(
22692
+ * map((data) => ({ type: 'fetchSuccess', payload: data })),
22693
+ * ),
22694
+ * ),
22695
+ * ),
22696
+ * );
22697
+ * ```
22557
22698
  */
22558
22699
  addFlow(fn) {
22559
22700
  const epic$ = fn(this.action$, this);
@@ -22568,23 +22709,27 @@ class FlowSubject extends Observable {
22568
22709
  .subscribe(this.#action);
22569
22710
  }
22570
22711
  /**
22571
- * Unsubscribes from actions and removes subscribers.
22712
+ * Tears down the subject by unsubscribing both the action and state subjects.
22713
+ *
22714
+ * After calling this method, the subject is no longer usable.
22572
22715
  */
22573
22716
  unsubscribe() {
22574
22717
  this.#action.unsubscribe();
22575
22718
  this.#state.unsubscribe();
22576
22719
  }
22577
22720
  /**
22578
- * Finalizes the subject and completes observers.
22721
+ * Completes both the action and state subjects, signalling to all
22722
+ * subscribers that no further values will be emitted.
22579
22723
  */
22580
22724
  complete() {
22581
22725
  this.#action.complete();
22582
22726
  this.#state.complete();
22583
22727
  }
22584
22728
  /**
22585
- * Clones the subject to a simple observable.
22729
+ * Returns a plain `Observable` of the state, hiding the subject's
22730
+ * `next`, `complete`, and other mutation methods.
22586
22731
  *
22587
- * @returns An observable of the state.
22732
+ * @returns A read-only observable of the state.
22588
22733
  */
22589
22734
  asObservable() {
22590
22735
  return this.#state.asObservable();
@@ -23158,7 +23303,7 @@ class TelemetryConfigurator extends BaseConfigBuilder {
23158
23303
  }
23159
23304
 
23160
23305
  // Generated by genversion.
23161
- const version$5 = '4.6.4';
23306
+ const version$5 = '5.0.0';
23162
23307
 
23163
23308
  /**
23164
23309
  * Enum representing the severity levels of telemetry items.
@@ -23310,6 +23455,12 @@ class FrameworkEvent {
23310
23455
  #cancelable;
23311
23456
  #canBubble;
23312
23457
  #created = Date.now();
23458
+ /**
23459
+ * Creates a new framework event.
23460
+ *
23461
+ * @param __type - The event name used for listener matching.
23462
+ * @param args - Initialization options including detail payload, source, and flags.
23463
+ */
23313
23464
  constructor(__type, args) {
23314
23465
  this.__type = __type;
23315
23466
  this.#detail = args.detail;
@@ -23568,6 +23719,16 @@ class Measurement {
23568
23719
  }
23569
23720
  }
23570
23721
 
23722
+ /**
23723
+ * Resolves metadata from a {@link MetadataExtractor} into an observable stream.
23724
+ *
23725
+ * Converts the extractor (which may be a static value, promise, function, or observable)
23726
+ * into a normalised `Observable` that emits the resolved metadata record.
23727
+ *
23728
+ * @param metadata - The metadata extractor to resolve.
23729
+ * @param args - Context passed to the extractor, including the telemetry item and optional module instances.
23730
+ * @returns An `Observable` emitting the resolved metadata record.
23731
+ */
23571
23732
  const resolveMetadata = (metadata, args) => {
23572
23733
  return toObservable(metadata, args);
23573
23734
  };
@@ -24043,6 +24204,21 @@ configurator) => {
24043
24204
  * `attachConfiguratorEvents` allows for the automatic attachment of configurator events to the telemetry builder,
24044
24205
  * ensuring that relevant events are captured and processed. __NOTE__ if the configurator crashes before the telemetry
24045
24206
  * builder is fully initialized, some events may be missed.
24207
+ *
24208
+ * @example
24209
+ * ```typescript
24210
+ * import { enableTelemetry } from '@equinor/fusion-framework-module-telemetry';
24211
+ *
24212
+ * const configure = (configurator) => {
24213
+ * enableTelemetry(configurator, {
24214
+ * attachConfiguratorEvents: true,
24215
+ * configure: (builder) => {
24216
+ * builder.setAdapter('console', new ConsoleAdapter());
24217
+ * builder.setMetadata(() => ({ appVersion: '1.0.0' }));
24218
+ * },
24219
+ * });
24220
+ * };
24221
+ * ```
24046
24222
  */
24047
24223
  const enableTelemetry = (
24048
24224
  // biome-ignore lint/suspicious/noExplicitAny: must be any to support all module types
@@ -40555,7 +40731,7 @@ const createClientLogCallback = (provider, metadata, scope) => {
40555
40731
  };
40556
40732
 
40557
40733
  // Generated by genversion.
40558
- const version$2 = '7.3.1';
40734
+ const version$2 = '8.0.0';
40559
40735
 
40560
40736
  /**
40561
40737
  * Zod schema for telemetry configuration validation.
@@ -40727,7 +40903,12 @@ class MsalConfigurator extends BaseConfigBuilder {
40727
40903
  return this;
40728
40904
  }
40729
40905
  /**
40730
- * @deprecated - since version 5.1.0, use setClient instead
40906
+ * Sets a pre-configured MSAL provider instance directly.
40907
+ *
40908
+ * @deprecated Since version 5.1.0. Use {@link MsalConfigurator.setClient | setClient} instead.
40909
+ *
40910
+ * @param provider - Pre-configured provider instance, or undefined to clear
40911
+ * @returns The configurator instance for method chaining
40731
40912
  */
40732
40913
  setProvider(provider) {
40733
40914
  this._set('provider', async () => provider);
@@ -40769,7 +40950,11 @@ class MsalConfigurator extends BaseConfigBuilder {
40769
40950
  }
40770
40951
  /**
40771
40952
  * Sets optional metadata to be included on all MSAL telemetry events.
40772
- * @deprecated Use setTelemetry({ metadata }) instead
40953
+ *
40954
+ * @deprecated Use {@link MsalConfigurator.setTelemetry | setTelemetry} instead.
40955
+ *
40956
+ * @param metadata - Key-value metadata to attach to telemetry events, or undefined to clear
40957
+ * @returns The configurator instance for method chaining
40773
40958
  */
40774
40959
  setTelemetryMetadata(metadata) {
40775
40960
  this._set('telemetry.metadata', async () => metadata);
@@ -41062,10 +41247,13 @@ function resolveVersion(version) {
41062
41247
  }
41063
41248
 
41064
41249
  /**
41065
- * Maps current AccountInfo to v2 AccountInfo format.
41250
+ * Maps a current (v4/v5) `AccountInfo` object to the v2-compatible `AccountInfo` format.
41251
+ *
41252
+ * Strips properties that don't exist in v2, ensuring backward-compatible serialization
41253
+ * and type safety when passing account data through the v2 proxy layer.
41066
41254
  *
41067
- * @param account - The current AccountInfo to convert
41068
- * @returns The v2 AccountInfo format
41255
+ * @param account - The current MSAL v4/v5 `AccountInfo` to convert
41256
+ * @returns A v2-compatible `AccountInfo` containing only fields recognised by MSAL v2 consumers
41069
41257
  */
41070
41258
  function mapAccountInfo(account) {
41071
41259
  return {
@@ -41080,10 +41268,14 @@ function mapAccountInfo(account) {
41080
41268
  }
41081
41269
 
41082
41270
  /**
41083
- * Maps current AuthenticationResult to v2 AuthenticationResult format.
41271
+ * Maps a current (v4/v5) `AuthenticationResult` to the v2-compatible format.
41084
41272
  *
41085
- * @param result - The current AuthenticationResult to convert
41086
- * @returns The v2 AuthenticationResult format
41273
+ * Converts the full authentication result including the nested account object —
41274
+ * to the subset of fields that MSAL v2 consumers expect. This enables the v2 proxy
41275
+ * layer to return type-safe results without exposing v4/v5-only properties.
41276
+ *
41277
+ * @param result - The current MSAL v4/v5 `AuthenticationResult` to convert
41278
+ * @returns A v2-compatible `AuthenticationResult` with mapped account and token fields
41087
41279
  */
41088
41280
  function mapAuthenticationResult(result) {
41089
41281
  return {
@@ -41101,22 +41293,24 @@ function mapAuthenticationResult(result) {
41101
41293
  }
41102
41294
 
41103
41295
  /**
41104
- * Creates a v2-compatible proxy for MSAL PublicClientApplication.
41296
+ * Creates a v2-compatible proxy wrapper around an MSAL v4 client.
41105
41297
  *
41106
- * This function creates a proxy that wraps the MSAL v4 PublicClientApplication
41107
- * and provides v2-compatible method signatures and return types.
41298
+ * The proxy intercepts property access on the v4 `IMsalClient` and adapts method
41299
+ * signatures, return types, and account data to match the v2 `IAuthClient` interface.
41300
+ * This allows consumer code written against MSAL v2 to continue working unchanged
41301
+ * while the underlying implementation uses MSAL v4/v5.
41108
41302
  *
41109
- * @param client - The MSAL v4 PublicClientApplication instance
41110
- * @returns A proxy client with v2-compatible interface
41303
+ * @param client - The MSAL v4 `IMsalClient` instance to wrap
41304
+ * @returns A proxy implementing the v2-compatible `IAuthClient` interface
41111
41305
  *
41112
41306
  * @example
41113
41307
  * ```typescript
41114
- * const v4Client = new PublicClientApplication(config);
41115
- * const v2Client = createProxyClient_v2(v4Client);
41308
+ * const v4Client = new MsalClient(config);
41309
+ * const v2Client = createProxyClient(v4Client);
41116
41310
  *
41117
41311
  * // Use v2-compatible methods
41118
41312
  * const accounts = v2Client.getAllAccounts();
41119
- * const token = await v2Client.acquireTokenSilent({ scopes: ['User.Read'], account });
41313
+ * const result = await v2Client.acquireTokenSilent({ scopes: ['User.Read'], account });
41120
41314
  * ```
41121
41315
  */
41122
41316
  function createProxyClient(client) {
@@ -41691,6 +41885,19 @@ class MsalProvider extends BaseModuleProvider {
41691
41885
  * Apps should call acquireToken with actual scopes after initialization completes.
41692
41886
  */
41693
41887
  async initialize() {
41888
+ // Guard: skip authentication when running inside MSAL's hidden iframe.
41889
+ // MSAL uses a hidden iframe for silent token renewal (acquireTokenSilent).
41890
+ // The iframe loads the app URL, which would re-initialize MSAL and attempt
41891
+ // loginRedirect(), causing the "block_iframe_reload" error. Detect this
41892
+ // by checking if we're in an iframe and the URL contains MSAL's hash params.
41893
+ if (typeof window !== 'undefined' && window !== window.parent) {
41894
+ // Running inside an iframe — let the parent handle authentication.
41895
+ // Still initialize the client so handleRedirectPromise can process
41896
+ // the auth response and post it back to the parent frame.
41897
+ await this.#client.initialize();
41898
+ await this.#client.handleRedirectPromise();
41899
+ return;
41900
+ }
41694
41901
  const measurement = this._trackMeasurement('initialize', TelemetryLevel.Debug);
41695
41902
  // Initialize the underlying MSAL client first
41696
41903
  await this.#client.initialize();
@@ -41826,10 +42033,14 @@ class MsalProvider extends BaseModuleProvider {
41826
42033
  * ```
41827
42034
  */
41828
42035
  async acquireToken(options) {
42036
+ // Guard: when running inside MSAL's hidden iframe, only attempt silent
42037
+ // acquisition. Interactive flows (redirect/popup) must never be triggered
42038
+ // from an iframe — MSAL will throw "block_iframe_reload".
42039
+ const inIframe = typeof window !== 'undefined' && window !== window.parent;
41829
42040
  // Determine behavior and silent options, with defaults (redirect and true respectively)
41830
- const behavior = options?.behavior ?? 'redirect';
41831
- // Silent mode defaults to true, meaning the provider will attempt silent token acquisition first
41832
- const silent = options?.silent ?? true;
42041
+ const behavior = inIframe ? 'redirect' : (options?.behavior ?? 'redirect');
42042
+ // When in an iframe, force silent-only to prevent interactive fallback
42043
+ const silent = inIframe ? true : (options?.silent ?? true);
41833
42044
  const defaultScopes = this.defaultScopes;
41834
42045
  const inputRequest = options?.request;
41835
42046
  // Determine the account to use for token acquisition, prioritizing request-specific account, then active account
@@ -41877,6 +42088,15 @@ class MsalProvider extends BaseModuleProvider {
41877
42088
  return result;
41878
42089
  }
41879
42090
  catch (error) {
42091
+ // Inside MSAL's hidden iframe, silent acquisition may fail and the client
42092
+ // would fall back to acquireTokenRedirect which throws "block_iframe_reload".
42093
+ // Suppress this — the parent frame handles interactive auth.
42094
+ if (inIframe) {
42095
+ this._trackEvent('acquireToken.suppressed-in-iframe', TelemetryLevel.Debug, {
42096
+ properties: telemetryProperties,
42097
+ });
42098
+ return undefined;
42099
+ }
41880
42100
  this._trackException('acquireToken-failed', TelemetryLevel.Error, {
41881
42101
  exception: error,
41882
42102
  properties: telemetryProperties,
@@ -41932,6 +42152,10 @@ class MsalProvider extends BaseModuleProvider {
41932
42152
  * ```
41933
42153
  */
41934
42154
  async login(options) {
42155
+ // Guard: never attempt interactive login inside MSAL's hidden iframe.
42156
+ if (typeof window !== 'undefined' && window !== window.parent) {
42157
+ return undefined;
42158
+ }
41935
42159
  const { behavior = 'redirect', silent = true, request } = options;
41936
42160
  request.loginHint ??=
41937
42161
  this.#loginHint ?? this.account?.username ?? this.account?.loginHint ?? undefined;
@@ -42309,11 +42533,26 @@ const mergeQueue = (...args) => (source$) => source$.pipe(mergeMap(...args));
42309
42533
  */
42310
42534
  const switchQueue = (...args) => (source$) => source$.pipe(switchMap(...args));
42311
42535
  /**
42312
- * Transforms an Observable stream of `QueryTaskValue<TType>` into an Observable stream of `TType`.
42313
- * It extracts the `value` property from each `QueryTaskValue<TType>` in the stream.
42536
+ * Transforms a query result Observable into a plain value Observable by extracting the `value` property.
42537
+ *
42538
+ * Use this operator to strip query metadata (status, transaction, timestamps) from
42539
+ * the result stream when only the raw data is needed.
42314
42540
  *
42315
- * @param source$ - An Observable stream of `QueryTaskValue<TType>`.
42316
- * @returns An Observable stream of `TType` where each emitted item is the `value` property from the input stream.
42541
+ * @template TType - The type of the data value extracted from the query result.
42542
+ * @template TArgs - The type of the query arguments.
42543
+ *
42544
+ * @param source$ - An Observable stream of query task results (cached or completed).
42545
+ * @returns An Observable stream of `TType` where each emission is the extracted value.
42546
+ *
42547
+ * @example
42548
+ * ```typescript
42549
+ * import { Query, operators } from '@equinor/fusion-query';
42550
+ *
42551
+ * const query = new Query({ client: { fn: fetchUser }, key: (args) => args.id });
42552
+ * query.query({ id: '123' }).pipe(operators.queryValue).subscribe(user => {
42553
+ * console.log(user.name);
42554
+ * });
42555
+ * ```
42317
42556
  */
42318
42557
  const queryValue = (source$) => source$.pipe(map$1((entry) => entry.value));
42319
42558
 
@@ -43175,6 +43414,12 @@ class QueryClient extends Observable {
43175
43414
  getRequest(transaction) {
43176
43415
  return this.#state.value[transaction];
43177
43416
  }
43417
+ /**
43418
+ * Retrieves the request associated with the specified reference string.
43419
+ *
43420
+ * @param ref - The reference identifier to search for.
43421
+ * @returns The request matching the reference, or `undefined` if not found.
43422
+ */
43178
43423
  getRequestByRef(ref) {
43179
43424
  return Object.values(this.#state.value).find((x) => x.ref === ref);
43180
43425
  }
@@ -43715,7 +43960,13 @@ class QueryTask extends Subject {
43715
43960
  }
43716
43961
 
43717
43962
  /**
43718
- * Base class for Query events
43963
+ * Concrete event class emitted by the {@link Query} instance itself.
43964
+ *
43965
+ * Represents lifecycle events for query creation, completion, caching, and job management.
43966
+ * Subscribers can use `instanceof QueryEvent` to filter for query-level events
43967
+ * when the aggregated `event$` stream also contains client and cache events.
43968
+ *
43969
+ * @template TData - The type of data payload carried by this event.
43719
43970
  */
43720
43971
  class QueryEvent {
43721
43972
  type;
@@ -43835,8 +44086,12 @@ const getQueueOperator = (type = 'switch') => {
43835
44086
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
43836
44087
  class Query {
43837
44088
  /**
43838
- * A static method that extracts the value from a query task.
43839
- * It is a utility function that can be used externally to access the result of a task.
44089
+ * Static utility that extracts the raw value from a query result Observable.
44090
+ *
44091
+ * Transforms a stream of `QueryTaskValue<TType>` into a plain `Observable<TType>`,
44092
+ * stripping away query metadata such as status, transaction, and timestamps.
44093
+ *
44094
+ * @see {@link queryValue} for the standalone operator function.
43840
44095
  */
43841
44096
  static extractQueryValue = queryValue;
43842
44097
  /**
@@ -44109,6 +44364,21 @@ class Query {
44109
44364
  fn(this._query(payload, args).pipe(throwIfEmpty())).then(resolve, reject);
44110
44365
  });
44111
44366
  }
44367
+ /**
44368
+ * Executes a query that remains subscribed to cache mutations after the initial fetch completes.
44369
+ *
44370
+ * Unlike {@link Query.query}, which completes after emitting the result, `persistentQuery`
44371
+ * continues to emit whenever the underlying cache entry is updated or mutated.
44372
+ * This is useful for scenarios where the UI must reflect optimistic updates,
44373
+ * background refetches, or external cache mutations in real time.
44374
+ *
44375
+ * The returned Observable deduplicates emissions based on the transaction identifier
44376
+ * and mutation timestamp, so subscribers only receive meaningful state changes.
44377
+ *
44378
+ * @param args - The arguments to pass to the query function.
44379
+ * @param options - Optional query options including signal, retry, and cache validation overrides.
44380
+ * @returns An Observable that emits cached and completed results, and continues emitting on cache mutations.
44381
+ */
44112
44382
  persistentQuery(args, options) {
44113
44383
  const key = this.#generateCacheKey(args);
44114
44384
  const original = this._query(args, options);
@@ -44340,7 +44610,12 @@ class Query {
44340
44610
  }
44341
44611
 
44342
44612
  /**
44343
- * Represents a service from the service discovery API.
44613
+ * Zod schema for a single service object returned by the service
44614
+ * discovery API.
44615
+ *
44616
+ * Validates required fields (`key`, `uri`) and optional metadata, then
44617
+ * transforms the result to include a backward-compatible `defaultScopes`
44618
+ * accessor.
44344
44619
  */
44345
44620
  const ApiService = z
44346
44621
  .object({
@@ -44361,26 +44636,29 @@ const ApiService = z
44361
44636
  },
44362
44637
  }));
44363
44638
  /**
44364
- * Represents a list of services from the service discovery API.
44365
- *
44366
- * This constant is an array of `ApiService` objects, which are defined
44367
- * elsewhere in the codebase. It uses the `z.array` method from the Zod
44368
- * library to enforce that the array contains only `ApiService` objects.
44639
+ * Zod schema for the service list returned by the service discovery API.
44369
44640
  *
44370
- * @constant
44371
- * @description A list of services from the service discovery API.
44641
+ * Parses and validates an array of service objects, each conforming to the
44642
+ * `ApiService` schema above. Used internally by
44643
+ * {@link ServiceDiscoveryClient} to validate API responses.
44372
44644
  */
44373
44645
  const ApiServices = z
44374
44646
  .array(ApiService)
44375
44647
  .describe('A list of services from the service discovery API');
44376
44648
 
44649
+ /** Cache key used by the internal {@link Query} instance. */
44377
44650
  const queryKey = 'services';
44378
44651
  /**
44379
- * Transforms a Response object into an ObservableInput of Service arrays.
44652
+ * Transforms a fetch {@link Response} into an observable that emits a
44653
+ * validated array of {@link Service} objects.
44654
+ *
44655
+ * The response body is parsed as JSON, validated against the
44656
+ * {@link ApiServices} Zod schema, and optionally piped through a
44657
+ * `postProcess` operator (used for session overrides).
44380
44658
  *
44381
- * @param response - The Response object to be transformed.
44382
- * @param postProcess - Optional callback to process the value.
44383
- * @returns An ObservableInput that emits an array of Service objects.
44659
+ * @param response - Raw fetch response from the service discovery API.
44660
+ * @param postProcess - Optional RxJS operator to transform the parsed list.
44661
+ * @returns An `ObservableInput` emitting the final `Service[]`.
44384
44662
  */
44385
44663
  const serviceResponseSelector = (response, postProcess) => {
44386
44664
  // parse response by using the jsonSelector
@@ -44392,12 +44670,26 @@ const serviceResponseSelector = (response, postProcess) => {
44392
44670
  }
44393
44671
  return result$;
44394
44672
  };
44673
+ /**
44674
+ * Default service discovery client that fetches endpoints from a remote API,
44675
+ * validates the response with Zod, caches results via {@link Query}, and
44676
+ * supports `sessionStorage`-based overrides.
44677
+ *
44678
+ * @remarks
44679
+ * Results are cached for 5 minutes. When `allow_cache` is `true`,
44680
+ * {@link resolveServices} returns the first cached value immediately;
44681
+ * otherwise it waits for the latest API response.
44682
+ */
44395
44683
  class ServiceDiscoveryClient {
44396
44684
  #query;
44397
- /** Endpoint for fetching services from API */
44685
+ /** Sub-path appended to the HTTP client's base URI when fetching services. */
44398
44686
  endpoint;
44399
- /** HTTP client for fetching services */
44687
+ /** HTTP client used to call the service discovery API. */
44400
44688
  http;
44689
+ /**
44690
+ * @param options - Construction options including the HTTP client,
44691
+ * optional endpoint path, and optional post-processing operator.
44692
+ */
44401
44693
  constructor(options) {
44402
44694
  this.http = options.http;
44403
44695
  this.endpoint = options.endpoint;
@@ -44414,10 +44706,14 @@ class ServiceDiscoveryClient {
44414
44706
  expire: 5 * 60 * 1000,
44415
44707
  });
44416
44708
  }
44709
+ /** {@inheritDoc IServiceDiscoveryClient.resolveServices} */
44417
44710
  resolveServices(allow_cache) {
44711
+ // firstValueFrom returns the cached snapshot; lastValueFrom waits for
44712
+ // the freshest value from the query
44418
44713
  const fn = allow_cache ? firstValueFrom : lastValueFrom;
44419
44714
  return fn(Query.extractQueryValue(this.#query.query()));
44420
44715
  }
44716
+ /** {@inheritDoc IServiceDiscoveryClient.resolveService} */
44421
44717
  async resolveService(key, allow_cache) {
44422
44718
  const services = await this.resolveServices(allow_cache);
44423
44719
  const service = services.find((s) => s.key === key);
@@ -44428,7 +44724,38 @@ class ServiceDiscoveryClient {
44428
44724
  }
44429
44725
  }
44430
44726
 
44727
+ /**
44728
+ * Configuration builder for the Service Discovery module.
44729
+ *
44730
+ * Provides a fluent API to set up how service endpoints are resolved.
44731
+ * The simplest path is to call
44732
+ * {@link ServiceDiscoveryConfigurator.configureServiceDiscoveryClientByClientKey | configureServiceDiscoveryClientByClientKey}
44733
+ * with the HTTP client key that points to the service discovery backend.
44734
+ *
44735
+ * For full control, use
44736
+ * {@link ServiceDiscoveryConfigurator.setServiceDiscoveryClient | setServiceDiscoveryClient}
44737
+ * to supply a custom {@link IServiceDiscoveryClient} implementation.
44738
+ *
44739
+ * @example
44740
+ * ```typescript
44741
+ * enableServiceDiscovery(configurator, async (builder) => {
44742
+ * builder.configureServiceDiscoveryClientByClientKey('sd_custom', '/services/v2');
44743
+ * });
44744
+ * ```
44745
+ */
44431
44746
  class ServiceDiscoveryConfigurator extends BaseConfigBuilder {
44747
+ /**
44748
+ * Creates the final {@link ServiceDiscoveryConfig}.
44749
+ *
44750
+ * When no explicit discovery client has been registered, this method
44751
+ * auto-detects an HTTP client with key `"service_discovery"` and uses it
44752
+ * as the default transport.
44753
+ *
44754
+ * @param init - Builder callback arguments providing module accessors.
44755
+ * @param initial - Optional partial config inherited from a parent module.
44756
+ * @returns The fully resolved configuration.
44757
+ * @throws {Error} When the HTTP module is not registered.
44758
+ */
44432
44759
  async _createConfig(init, initial) {
44433
44760
  if (!init.hasModule('http')) {
44434
44761
  throw new Error('http module is required');
@@ -44445,12 +44772,12 @@ class ServiceDiscoveryConfigurator extends BaseConfigBuilder {
44445
44772
  return lastValueFrom(from(super._createConfig(init, initial)));
44446
44773
  }
44447
44774
  /**
44448
- * Processes the service discovery configuration.
44775
+ * Validates and finalizes the service discovery configuration.
44449
44776
  *
44450
- * @param config - A partial configuration object for service discovery.
44451
- * @param init - Initialization arguments for the configuration builder callback.
44452
- * @returns An observable input of the complete service discovery configuration.
44453
- * @throws Will throw an error if `discoveryClient` is not configured.
44777
+ * @param config - Partial configuration assembled by the builder.
44778
+ * @param init - Builder callback arguments.
44779
+ * @returns An observable that emits the complete {@link ServiceDiscoveryConfig}.
44780
+ * @throws {Error} When `discoveryClient` has not been configured.
44454
44781
  */
44455
44782
  _processConfig(config, init) {
44456
44783
  if (!config.discoveryClient) {
@@ -44459,22 +44786,50 @@ class ServiceDiscoveryConfigurator extends BaseConfigBuilder {
44459
44786
  return super._processConfig(config, init);
44460
44787
  }
44461
44788
  /**
44462
- * Sets the service discovery client.
44789
+ * Sets the service discovery client directly.
44790
+ *
44791
+ * Accepts either a ready-made {@link IServiceDiscoveryClient} instance or a
44792
+ * {@link ConfigBuilderCallback} that will be invoked during module
44793
+ * initialization to produce one.
44463
44794
  *
44464
- * @param discoveryClient - An instance of `IServiceDiscoveryClient` or a callback function that returns an instance of `IServiceDiscoveryClient`.
44795
+ * Use this method when you need full control over service resolution
44796
+ * (e.g. a mock client for testing or a static service list).
44465
44797
  *
44466
- * This method configures the service discovery client by either directly setting the provided instance or by invoking the provided callback function to obtain the instance.
44798
+ * @param discoveryClient - A client instance or an async factory function.
44799
+ *
44800
+ * @example
44801
+ * ```typescript
44802
+ * // Static / mock client
44803
+ * builder.setServiceDiscoveryClient({
44804
+ * resolveServices: async () => [{ key: 'api', uri: 'https://localhost:5000', defaultScopes: [] }],
44805
+ * resolveService: async (key) => ({ key, uri: 'https://localhost:5000', defaultScopes: [] }),
44806
+ * });
44807
+ * ```
44467
44808
  */
44468
44809
  setServiceDiscoveryClient(discoveryClient) {
44469
44810
  this._set('discoveryClient', typeof discoveryClient === 'function' ? discoveryClient : async () => discoveryClient);
44470
44811
  }
44471
44812
  /**
44472
- * Configures the Service Discovery Client with the provided configuration callback.
44813
+ * Configures a {@link ServiceDiscoveryClient} with a custom HTTP client and
44814
+ * optional endpoint path.
44815
+ *
44816
+ * This is the mid-level configuration path: you supply the transport
44817
+ * details and the module constructs a standard
44818
+ * {@link ServiceDiscoveryClient} with built-in caching, response parsing,
44819
+ * and `sessionStorage` override support.
44473
44820
  *
44474
- * @param configCallback - A callback function that takes an argument of type `{ httpClient: IHttpClient; endpoint?: string }`
44475
- * and returns a configuration object. The `httpClient` is required, while the `endpoint` is optional.
44821
+ * @param configCallback - Async factory that must return
44822
+ * `{ httpClient, endpoint? }`. The `httpClient` is used to call the
44823
+ * service discovery API at the given `endpoint` (defaults to `""`).
44824
+ * @throws {Error} When the factory does not return an `httpClient`.
44476
44825
  *
44477
- * @throws {Error} Throws an error if `httpClient` is not provided in the configuration.
44826
+ * @example
44827
+ * ```typescript
44828
+ * builder.configureServiceDiscoveryClient(async ({ requireInstance }) => {
44829
+ * const http = await requireInstance('http');
44830
+ * return { httpClient: http.createClient('sd'), endpoint: '/services/v2' };
44831
+ * });
44832
+ * ```
44478
44833
  */
44479
44834
  configureServiceDiscoveryClient(configCallback) {
44480
44835
  this.setServiceDiscoveryClient(async (args) => {
@@ -44484,9 +44839,16 @@ class ServiceDiscoveryConfigurator extends BaseConfigBuilder {
44484
44839
  http: httpClient,
44485
44840
  endpoint,
44486
44841
  postProcess: map$1((input) => {
44842
+ // Get a reference to sessionStorage from globalThis
44843
+ const storage = typeof globalThis !== 'undefined' ? globalThis.sessionStorage : undefined;
44844
+ // Check if sessionStorage is available before attempting to access it.
44845
+ // If sessionStorage is not available, return the input as is without attempting to apply any overrides.
44846
+ if (!storage) {
44847
+ return input;
44848
+ }
44487
44849
  // Check if there are any session overrides in session storage.
44488
44850
  try {
44489
- const sessionOverrides = JSON.parse(sessionStorage.getItem('overriddenServiceDiscoveryUrls') || '{}');
44851
+ const sessionOverrides = JSON.parse(storage.getItem('overriddenServiceDiscoveryUrls') || '{}');
44490
44852
  for (const [key, { url, scopes }] of Object.entries(sessionOverrides)) {
44491
44853
  const service = input.find((service) => service.key === key);
44492
44854
  // If the service can be found, override the values with the values
@@ -44509,17 +44871,24 @@ class ServiceDiscoveryConfigurator extends BaseConfigBuilder {
44509
44871
  });
44510
44872
  }
44511
44873
  /**
44512
- * Configures a service discovery client using the provided client key and optional endpoint.
44874
+ * Configures service discovery using a named HTTP client key.
44513
44875
  *
44514
- * @param clientKey - The key used to identify the client.
44515
- * @param endpoint - An optional endpoint to be used by the service discovery client.
44876
+ * This is the simplest configuration path. The HTTP module must already
44877
+ * have a client registered under `clientKey`. If `endpoint` is omitted
44878
+ * the client calls the root path of the HTTP client's base URI.
44516
44879
  *
44517
- * @remarks
44518
- * The http module must have a configured client which match provided `clientKey`.
44880
+ * @param clientKey - Key of the HTTP client to use for service discovery
44881
+ * requests (must match an entry in the HTTP module configuration).
44882
+ * @param endpoint - Optional sub-path appended to the client's base URI
44883
+ * when fetching the service list.
44519
44884
  *
44520
- * This method sets up the service discovery client by requiring an HTTP provider instance,
44521
- * creating an HTTP client with the given client key, and returning an object containing
44522
- * the HTTP client and the optional endpoint.
44885
+ * @example
44886
+ * ```typescript
44887
+ * builder.configureServiceDiscoveryClientByClientKey(
44888
+ * 'service_discovery',
44889
+ * '/custom/services',
44890
+ * );
44891
+ * ```
44523
44892
  */
44524
44893
  configureServiceDiscoveryClientByClientKey(clientKey, endpoint) {
44525
44894
  this.configureServiceDiscoveryClient(async ({ requireInstance }) => {
@@ -44534,11 +44903,22 @@ class ServiceDiscoveryConfigurator extends BaseConfigBuilder {
44534
44903
  }
44535
44904
 
44536
44905
  // Generated by genversion.
44537
- const version$1 = '9.1.1';
44906
+ const version$1 = '10.0.0';
44538
44907
 
44908
+ /**
44909
+ * Default implementation of {@link IServiceDiscoveryProvider}.
44910
+ *
44911
+ * Created during module initialization and delegates service resolution to
44912
+ * the underlying {@link IServiceDiscoveryClient} while using the
44913
+ * {@link HttpModule} to construct pre-configured HTTP clients.
44914
+ */
44539
44915
  class ServiceDiscoveryProvider extends BaseModuleProvider {
44540
44916
  config;
44541
44917
  _http;
44918
+ /**
44919
+ * @param config - Resolved service discovery configuration.
44920
+ * @param _http - HTTP module instance used to create clients.
44921
+ */
44542
44922
  constructor(config, _http) {
44543
44923
  super({
44544
44924
  version: version$1,
@@ -44547,12 +44927,15 @@ class ServiceDiscoveryProvider extends BaseModuleProvider {
44547
44927
  this.config = config;
44548
44928
  this._http = _http;
44549
44929
  }
44930
+ /** {@inheritDoc IServiceDiscoveryProvider.resolveServices} */
44550
44931
  resolveServices() {
44551
44932
  return this.config.discoveryClient.resolveServices();
44552
44933
  }
44934
+ /** {@inheritDoc IServiceDiscoveryProvider.resolveService} */
44553
44935
  async resolveService(key) {
44554
44936
  return this.config.discoveryClient.resolveService(key);
44555
44937
  }
44938
+ /** {@inheritDoc IServiceDiscoveryProvider.createClient} */
44556
44939
  async createClient(name, opt) {
44557
44940
  const service = await this.resolveService(name);
44558
44941
  if (!service) {
@@ -44564,6 +44947,7 @@ class ServiceDiscoveryProvider extends BaseModuleProvider {
44564
44947
  defaultScopes: service.scopes,
44565
44948
  });
44566
44949
  }
44950
+ /** {@inheritDoc IServiceDiscoveryProvider.configureClient} */
44567
44951
  async configureClient(serviceName, config) {
44568
44952
  const { key, alias } = typeof serviceName === 'string' ? { key: serviceName, alias: serviceName } : serviceName;
44569
44953
  const { uri: baseUri, scopes: defaultScopes } = await this.resolveService(key);
@@ -44571,25 +44955,27 @@ class ServiceDiscoveryProvider extends BaseModuleProvider {
44571
44955
  }
44572
44956
  }
44573
44957
 
44958
+ /**
44959
+ * Module identifier used to register and look up the Service Discovery module
44960
+ * within the Fusion Framework module system.
44961
+ */
44574
44962
  const moduleName = 'serviceDiscovery';
44575
44963
  /**
44576
- * Represents the Service Discovery module configuration.
44964
+ * Service Discovery module definition.
44577
44965
  *
44578
- * @remarks
44579
- * This module is responsible for configuring and initializing the service discovery mechanism.
44580
- * It ensures that the service discovery configuration is created and the necessary dependencies
44581
- * are initialized before providing the service discovery provider.
44966
+ * Configures and initializes the service discovery mechanism within the
44967
+ * Fusion Framework module system. During initialization the module:
44582
44968
  *
44583
- * @returns {Promise<ServiceDiscoveryProvider>} - Returns a promise that resolves to the service discovery provider.
44969
+ * 1. Creates the {@link ServiceDiscoveryConfig} (optionally inheriting the
44970
+ * parent module's discovery client so sub-modules share cache).
44971
+ * 2. Resolves the required {@link HttpModule} instance.
44972
+ * 3. Returns a {@link ServiceDiscoveryProvider} ready to resolve endpoints.
44584
44973
  *
44585
44974
  * @remarks
44586
- * The initialization process involves creating the service discovery configuration, which may include
44587
- * inheriting configurations from a parent module. This pattern, while allowing reuse of cache and ensuring
44588
- * up-to-date configurations, can be risky as it exposes the child module to potential breaking changes
44589
- * from the parent module's client.
44590
- *
44591
- * Additionally, the service discovery module requires the HTTP module to be initialized before it can
44592
- * function properly.
44975
+ * When a parent module exposes its own `serviceDiscovery` config, the child
44976
+ * module reuses that configuration by default. This enables shared caching
44977
+ * and consistent service resolution but means breaking changes in the
44978
+ * parent's client can affect child modules.
44593
44979
  */
44594
44980
  const module$1 = {
44595
44981
  name: moduleName,
@@ -44613,20 +44999,31 @@ const module$1 = {
44613
44999
  },
44614
45000
  };
44615
45001
  /**
44616
- * Configures the Service Discovery module.
45002
+ * Creates a module configurator object for the Service Discovery module.
45003
+ *
45004
+ * Use this when you need to add service discovery to a
45005
+ * {@link ModulesConfigurator} via `addConfig` and want full control over
45006
+ * the configuration callback.
44617
45007
  *
44618
- * @template TRef - The type reference for the module configurator.
44619
- * @param callback - A function that takes a `ServiceDiscoveryConfigurator` and returns a promise that resolves when the configuration is complete.
44620
- * @returns An object implementing `IModuleConfigurator` for the `ServiceDiscoveryModule` with the provided configuration.
45008
+ * For the simpler "just enable it" path, prefer {@link enableServiceDiscovery}.
45009
+ *
45010
+ * @template TRef - Module reference type forwarded to the configurator.
45011
+ * @param callback - Receives a {@link ServiceDiscoveryConfigurator} and must
45012
+ * return a `Promise` that resolves when configuration is complete.
45013
+ * @returns An `IModuleConfigurator` that can be passed to
45014
+ * `ModulesConfigurator.addConfig`.
44621
45015
  *
44622
45016
  * @example
44623
45017
  * ```typescript
44624
45018
  * import { configureServiceDiscovery } from '@equinor/fusion-framework-module-service-discovery';
44625
45019
  *
44626
- * const config = (configurator: ModuleConfigurator) => {
44627
- * configurator.addConfig(configureServiceDiscovery(async (config) => {
44628
- * // custom configuration
44629
- * });
45020
+ * const configure = (configurator: ModulesConfigurator) => {
45021
+ * configurator.addConfig(
45022
+ * configureServiceDiscovery(async (builder) => {
45023
+ * builder.configureServiceDiscoveryClientByClientKey('my_sd_key');
45024
+ * }),
45025
+ * );
45026
+ * };
44630
45027
  * ```
44631
45028
  */
44632
45029
  const configureServiceDiscovery = (callback) => ({
@@ -44634,24 +45031,29 @@ const configureServiceDiscovery = (callback) => ({
44634
45031
  configure: (config) => callback(config),
44635
45032
  });
44636
45033
  /**
44637
- * Enables the service discovery module by adding its configuration to the provided configurator.
45034
+ * Enables the Service Discovery module on a {@link ModulesConfigurator}.
44638
45035
  *
44639
- * @param configurator - The configurator to which the service discovery configuration will be added.
44640
- * @param callback - An optional callback function that can be used to customize the service discovery configuration.
45036
+ * This is the recommended entry point for most consumers. When called
45037
+ * without a callback the module auto-detects an HTTP client registered
45038
+ * under the key `"service_discovery"`. Pass a callback to override the
45039
+ * client key, endpoint, or provide a fully custom discovery client.
45040
+ *
45041
+ * @param configurator - The modules configurator to register the module on.
45042
+ * Must already include {@link HttpModule}.
45043
+ * @param callback - Optional async callback receiving a
45044
+ * {@link ServiceDiscoveryConfigurator} for advanced setup.
44641
45045
  *
44642
45046
  * @example
44643
45047
  * ```typescript
44644
45048
  * import { enableServiceDiscovery } from '@equinor/fusion-framework-module-service-discovery';
44645
45049
  *
44646
- * const config = (configurator: ModuleConfigurator) => {
44647
- * // simple
44648
- * enableServiceDiscovery(configurator);
45050
+ * // Simplest usage auto-detects the 'service_discovery' HTTP client
45051
+ * enableServiceDiscovery(configurator);
44649
45052
  *
44650
- * // with custom configuration
44651
- * enableServiceDiscovery(configurator, async (config) => {
44652
- * config.configureServiceDiscoveryClientByClientKey('service-discovery-custom');
44653
- * });
44654
- * };
45053
+ * // Custom HTTP client key
45054
+ * enableServiceDiscovery(configurator, async (builder) => {
45055
+ * builder.configureServiceDiscoveryClientByClientKey('sd_custom');
45056
+ * });
44655
45057
  * ```
44656
45058
  */
44657
45059
  const enableServiceDiscovery = (configurator, callback) => {
@@ -44749,7 +45151,20 @@ class BaseTelemetryAdapter {
44749
45151
 
44750
45152
  /**
44751
45153
  * Telemetry adapter that outputs telemetry data to the browser console
44752
- * with formatted titles and color-coded log levels
45154
+ * with formatted titles and colour-coded log levels.
45155
+ *
45156
+ * Each telemetry item is logged using the console method that matches its
45157
+ * {@link TelemetryLevel} (e.g. `console.error` for `Error` / `Critical`,
45158
+ * `console.warn` for `Warning`). Event names are prefixed with a styled
45159
+ * application title badge.
45160
+ *
45161
+ * @example
45162
+ * ```typescript
45163
+ * import { ConsoleAdapter } from '@equinor/fusion-framework-module-telemetry/console-adapter';
45164
+ *
45165
+ * const adapter = new ConsoleAdapter({ title: 'MyApp' });
45166
+ * configurator.setAdapter(ConsoleAdapter.Identifier, adapter);
45167
+ * ```
44753
45168
  */
44754
45169
  class ConsoleAdapter extends BaseTelemetryAdapter {
44755
45170
  /** Default identifier for console adapter instances */
@@ -44893,6 +45308,36 @@ class ConsoleAdapter extends BaseTelemetryAdapter {
44893
45308
  }
44894
45309
  }
44895
45310
 
45311
+ /**
45312
+ * Registers the Fusion SPA service worker and wires token acquisition.
45313
+ *
45314
+ * @remarks
45315
+ * The service worker intercepts outgoing fetch requests that match
45316
+ * the configured {@link ResourceConfiguration | resource patterns},
45317
+ * rewrites URLs, and injects Bearer tokens obtained from the MSAL
45318
+ * module. This function:
45319
+ *
45320
+ * 1. Registers `/@fusion-spa-sw.js` as a module service worker.
45321
+ * 2. Listens for `GET_TOKEN` messages from the worker and responds
45322
+ * with MSAL access tokens.
45323
+ * 3. Sends the `INIT_CONFIG` message containing resource configurations
45324
+ * to the active worker once it is ready and controlling the page.
45325
+ *
45326
+ * @param framework - An initialized Fusion Framework instance that
45327
+ * includes the {@link MsalModule} (for token acquisition) and
45328
+ * {@link TelemetryModule} (for structured logging).
45329
+ * @throws {Error} When service workers are not supported by the browser.
45330
+ * @throws {Error} When the `FUSION_SPA_SERVICE_WORKER_RESOURCES`
45331
+ * environment variable is not defined.
45332
+ *
45333
+ * @example
45334
+ * ```ts
45335
+ * import { registerServiceWorker } from '@equinor/fusion-framework-vite-plugin-spa/html';
45336
+ *
45337
+ * const framework = await configurator.initialize();
45338
+ * await registerServiceWorker(framework);
45339
+ * ```
45340
+ */
44896
45341
  async function registerServiceWorker(framework) {
44897
45342
  const telemetry = framework.telemetry;
44898
45343
  if ('serviceWorker' in navigator === false) {
@@ -45053,7 +45498,7 @@ async function registerServiceWorker(framework) {
45053
45498
  }
45054
45499
 
45055
45500
  // Generated by genversion.
45056
- const version = '3.1.11';
45501
+ const version = '4.0.0';
45057
45502
 
45058
45503
  // Allow dynamic import without vite
45059
45504
  const importWithoutVite = (path) => import(/* @vite-ignore */ path);