@equinor/fusion-framework-module-signalr 10.0.1 → 11.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +28 -2
  2. package/README.md +133 -0
  3. package/dist/esm/SignalRModule.js +16 -0
  4. package/dist/esm/SignalRModule.js.map +1 -1
  5. package/dist/esm/SignalRModuleConfigurator.js +35 -7
  6. package/dist/esm/SignalRModuleConfigurator.js.map +1 -1
  7. package/dist/esm/SignalRModuleProvider.js +33 -1
  8. package/dist/esm/SignalRModuleProvider.js.map +1 -1
  9. package/dist/esm/index.js +13 -0
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/lib/Topic.js +40 -0
  12. package/dist/esm/lib/Topic.js.map +1 -1
  13. package/dist/esm/lib/utils/configure-from-framework.js +12 -0
  14. package/dist/esm/lib/utils/configure-from-framework.js.map +1 -1
  15. package/dist/esm/lib/utils/enable-signalr.js +29 -24
  16. package/dist/esm/lib/utils/enable-signalr.js.map +1 -1
  17. package/dist/esm/version.js +1 -1
  18. package/dist/tsconfig.tsbuildinfo +1 -1
  19. package/dist/types/SignalRModule.d.ts +25 -0
  20. package/dist/types/SignalRModuleConfigurator.d.ts +91 -15
  21. package/dist/types/SignalRModuleProvider.d.ts +56 -3
  22. package/dist/types/index.d.ts +13 -0
  23. package/dist/types/lib/Topic.d.ts +40 -0
  24. package/dist/types/lib/utils/configure-from-framework.d.ts +1 -8
  25. package/dist/types/lib/utils/enable-signalr.d.ts +46 -24
  26. package/dist/types/version.d.ts +1 -1
  27. package/package.json +8 -7
  28. package/src/SignalRModule.ts +25 -0
  29. package/src/SignalRModuleConfigurator.ts +92 -15
  30. package/src/SignalRModuleProvider.ts +58 -4
  31. package/src/index.ts +14 -0
  32. package/src/lib/Topic.ts +40 -0
  33. package/src/lib/utils/configure-from-framework.ts +12 -0
  34. package/src/lib/utils/enable-signalr.ts +47 -24
  35. package/src/version.ts +1 -1
@@ -1,11 +1,36 @@
1
1
  import type { Module } from '@equinor/fusion-framework-module';
2
2
  import { type ISignalRConfigurator } from './SignalRModuleConfigurator';
3
3
  import { type ISignalRProvider } from './SignalRModuleProvider';
4
+ /** String literal key used to register the SignalR module in the Fusion Framework module system. */
4
5
  export type SignalRModuleKey = 'signalR';
6
+ /** Module registration key for the SignalR module (`'signalR'`). */
5
7
  export declare const moduleKey: SignalRModuleKey;
8
+ /**
9
+ * Module type definition for the SignalR module.
10
+ *
11
+ * Binds the module key, provider interface ({@link ISignalRProvider}), and
12
+ * configurator interface ({@link ISignalRConfigurator}) together for the
13
+ * Fusion Framework module system.
14
+ */
6
15
  export type SignalRModule = Module<SignalRModuleKey, ISignalRProvider, ISignalRConfigurator>;
16
+ /**
17
+ * SignalR module instance that can be registered with a Fusion Framework configurator.
18
+ *
19
+ * During the `configure` phase, a {@link SignalRConfigurator} is created.
20
+ * During the `initialize` phase, the configurator builds its {@link SignalRConfig}
21
+ * and produces a {@link SignalRModuleProvider}.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { ModuleConfigurator } from '@equinor/fusion-framework-module';
26
+ * import signalR from '@equinor/fusion-framework-module-signalr';
27
+ *
28
+ * configurator.addConfig({ module: signalR });
29
+ * ```
30
+ */
7
31
  export declare const module: SignalRModule;
8
32
  export default module;
33
+ /** Augments the global `Modules` interface so that `'signalR'` is a known module key. */
9
34
  declare module '@equinor/fusion-framework-module' {
10
35
  interface Modules {
11
36
  signalR: SignalRModule;
@@ -1,53 +1,129 @@
1
1
  import { type AnyModule, ModuleConfigBuilder, type ModuleInitializerArgs } from '@equinor/fusion-framework-module';
2
2
  import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';
3
3
  import type { IHttpConnectionOptions, LogLevel } from '@microsoft/signalr';
4
+ /**
5
+ * Public configuration interface for the SignalR module.
6
+ *
7
+ * Consumers use this interface to register hub connections and configuration
8
+ * callbacks during the module `configure` phase.
9
+ */
4
10
  export interface ISignalRConfigurator {
5
- /** add configuration for hub connection */
11
+ /**
12
+ * Register a named SignalR hub connection.
13
+ *
14
+ * @param name - Unique identifier for the hub (used later with {@link ISignalRProvider.connect})
15
+ * @param config - Hub connection configuration or a promise that resolves to one
16
+ */
6
17
  addHub(name: string, config: SignalRHubConfig | Promise<SignalRHubConfig>): void;
7
- /** add callback for building config on init */
18
+ /**
19
+ * Register a callback that will run during the module initialization phase
20
+ * to build configuration using a {@link SignalRModuleConfigBuilder}.
21
+ *
22
+ * Use this when hub configuration depends on resolved module dependencies
23
+ * such as service-discovery or authentication.
24
+ *
25
+ * @param cb - Callback that receives a {@link SignalRModuleConfigBuilder}
26
+ */
8
27
  onCreateConfig(cb: SignalRModuleConfigBuilderCallback): void;
9
28
  }
10
- /** configuration callback */
29
+ /**
30
+ * Callback invoked during module initialization to configure SignalR hubs.
31
+ *
32
+ * Receives a {@link SignalRModuleConfigBuilder} that provides access to
33
+ * resolved module dependencies, allowing dynamic hub registration.
34
+ *
35
+ * @template TDeps - Tuple of module dependencies available through the builder
36
+ */
11
37
  export type SignalRModuleConfigBuilderCallback<TDeps = unknown> = (builder: SignalRModuleConfigBuilder<TDeps>) => void | Promise<void>;
12
38
  /**
13
- * Configuration for hub connection
39
+ * Configuration for a single SignalR hub connection.
40
+ *
41
+ * Defines the endpoint URL, transport options, reconnection behavior,
42
+ * and logging level for a `@microsoft/signalr` `HubConnection`.
14
43
  */
15
44
  export type SignalRHubConfig = {
16
- /** connection endpoint */
45
+ /** Absolute URL of the SignalR hub endpoint. */
17
46
  url: string;
18
- /** connection options */
47
+ /**
48
+ * Transport and authentication options forwarded to the underlying
49
+ * `HubConnectionBuilder.withUrl()` call.
50
+ *
51
+ * The `httpClient` option is excluded because the module manages the
52
+ * HTTP client internally.
53
+ */
19
54
  options: Omit<IHttpConnectionOptions, 'httpClient'>;
20
- /** reconnect when connection lost */
55
+ /**
56
+ * When `true`, the connection will automatically attempt to reconnect
57
+ * after an unintentional disconnection.
58
+ *
59
+ * @defaultValue `undefined` (no automatic reconnect)
60
+ */
21
61
  automaticReconnect?: boolean;
62
+ /**
63
+ * Minimum log level for the SignalR connection logger.
64
+ *
65
+ * @defaultValue `LogLevel.Critical` (5) when omitted
66
+ */
22
67
  logLevel?: LogLevel;
23
68
  };
24
69
  /**
25
- * Configuration for creating SignalR provider
70
+ * Resolved configuration used to create a {@link SignalRModuleProvider}.
71
+ *
72
+ * Contains all registered hub configurations keyed by hub name.
26
73
  */
27
74
  export type SignalRConfig = {
75
+ /** Map of hub name to its {@link SignalRHubConfig}. */
28
76
  hubs: Record<string, SignalRHubConfig>;
29
77
  };
30
78
  /**
31
- * builder utility class for generating configuration
79
+ * Builder utility for registering SignalR hub configurations during
80
+ * module initialization.
81
+ *
82
+ * Extends {@link ModuleConfigBuilder} to provide access to resolved
83
+ * module dependencies (e.g., service-discovery, authentication) so that
84
+ * hub URLs and access-token factories can be built dynamically.
85
+ *
86
+ * @template TDeps - Tuple of module dependencies available through the builder
32
87
  */
33
88
  export declare class SignalRModuleConfigBuilder<TDeps extends AnyModule[] | unknown = unknown> extends ModuleConfigBuilder<TDeps, ISignalRConfigurator> {
89
+ /**
90
+ * Register a named hub connection through the underlying configurator.
91
+ *
92
+ * @param name - Unique hub identifier
93
+ * @param config - Hub connection configuration
94
+ */
34
95
  addHub(name: string, config: SignalRHubConfig): Promise<void>;
35
96
  }
97
+ /**
98
+ * Default {@link ISignalRConfigurator} implementation.
99
+ *
100
+ * Collects hub registrations and builder callbacks, then produces a
101
+ * {@link SignalRConfig} during the module initialization phase.
102
+ */
36
103
  export declare class SignalRConfigurator implements ISignalRConfigurator {
37
104
  #private;
38
105
  /**
39
- * register SignalR hub configuration.
106
+ * Register a named SignalR hub connection.
107
+ *
108
+ * @param name - Unique identifier for the hub
109
+ * @param config - Hub connection configuration
40
110
  */
41
111
  addHub(name: string, config: SignalRHubConfig): void;
42
112
  /**
43
- * add callback for building config on when configurator is creating config.
44
- * {@link SignalRConfigurator.createConfig}
113
+ * Register a configuration builder callback that will run during
114
+ * {@link SignalRConfigurator.createConfig}.
115
+ *
116
+ * @param cb - Callback receiving a {@link SignalRModuleConfigBuilder}
45
117
  */
46
118
  onCreateConfig<T>(cb: SignalRModuleConfigBuilderCallback<T>): void;
47
119
  /**
48
- * normally executed in `init` phase of module, which creates configuration to the module provider.
49
- * cycles threw all registered configuration builders.
50
- * await all registered hub configurations.
120
+ * Build the final {@link SignalRConfig} by executing all registered
121
+ * builder callbacks and collecting hub configurations.
122
+ *
123
+ * Normally called during the module `initialize` phase.
124
+ *
125
+ * @param init - Module initializer arguments providing access to resolved dependencies
126
+ * @returns Resolved configuration containing all registered hubs
51
127
  */
52
128
  createConfig(init: ModuleInitializerArgs<ISignalRConfigurator, [ServiceDiscoveryModule]>): Promise<SignalRConfig>;
53
129
  }
@@ -2,17 +2,70 @@ import { type HubConnection } from '@microsoft/signalr';
2
2
  import { Observable } from 'rxjs';
3
3
  import type { SignalRConfig } from './SignalRModuleConfigurator';
4
4
  import { Topic } from './lib/Topic';
5
+ /**
6
+ * Public interface for the SignalR module provider.
7
+ *
8
+ * Use {@link ISignalRProvider.connect} to subscribe to a named hub method
9
+ * through an RxJS-based {@link Topic}. Connections are reference-counted
10
+ * and automatically torn down when all subscribers unsubscribe.
11
+ */
5
12
  export interface ISignalRProvider {
6
13
  /**
7
- * connect to SignalR hub
8
- * re-use existing connections and close connection when nobody is listening
14
+ * Connect to a SignalR hub method and return an observable {@link Topic}.
15
+ *
16
+ * Existing hub connections are reused (shared via `shareReplay` with
17
+ * `refCount`). When the last subscriber unsubscribes, the underlying
18
+ * `HubConnection` is stopped automatically.
19
+ *
20
+ * @template T - Type of messages received from the hub method
21
+ * @param hubId - Name of the hub as registered in the configurator
22
+ * @param methodName - Server-side method name to listen on
23
+ * @returns A {@link Topic} observable that emits messages from the hub method
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const provider = modules.signalR;
28
+ * const topic = provider.connect<MyMessage>('notifications', 'OnNewMessage');
29
+ * topic.subscribe((msg) => console.log('Received:', msg));
30
+ * ```
9
31
  */
10
- connect<T>(ubId: string, methodName: string): Topic<T>;
32
+ connect<T>(hubId: string, methodName: string): Topic<T>;
11
33
  }
34
+ /**
35
+ * Default {@link ISignalRProvider} implementation.
36
+ *
37
+ * Creates and manages `@microsoft/signalr` `HubConnection` instances based on
38
+ * the resolved {@link SignalRConfig}. Hub connections are lazily created on
39
+ * first subscription and shared across all callers via `shareReplay`.
40
+ */
12
41
  export declare class SignalRModuleProvider implements ISignalRProvider {
13
42
  #private;
43
+ /**
44
+ * @param config - Resolved SignalR configuration containing all registered hubs
45
+ */
14
46
  constructor(config: SignalRConfig);
47
+ /**
48
+ * Connect to a named hub method and return an observable {@link Topic}.
49
+ *
50
+ * @template T - Type of messages received from the hub method
51
+ * @param hubId - Name of the hub as registered in the configurator
52
+ * @param methodName - Server-side method name to listen on
53
+ * @returns A {@link Topic} observable emitting hub messages
54
+ * @throws {Error} When no hub configuration exists for `hubId`
55
+ */
15
56
  connect<T>(hubId: string, methodName: string): Topic<T>;
57
+ /**
58
+ * Create or retrieve a shared `HubConnection` observable for the given hub.
59
+ *
60
+ * The connection is lazily built using `HubConnectionBuilder` and shared
61
+ * with `shareReplay({ bufferSize: 1, refCount: true })` so that:
62
+ * - New subscribers immediately receive the current connection.
63
+ * - The connection is stopped when the last subscriber unsubscribes.
64
+ *
65
+ * @param hubId - Name of the hub as registered in the configurator
66
+ * @returns Observable that emits the active `HubConnection`
67
+ * @throws {Error} When no hub configuration exists for `hubId`
68
+ */
16
69
  protected _createHubConnection(hubId: string): Observable<HubConnection>;
17
70
  }
18
71
  export default SignalRModuleProvider;
@@ -1,3 +1,16 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Fusion Framework module for real-time communication via
5
+ * [SignalR](https://learn.microsoft.com/aspnet/core/signalr/introduction).
6
+ *
7
+ * Provides an RxJS-based API for connecting to SignalR hubs, subscribing to
8
+ * server-side methods, and sending messages. Hub connections are reference-counted
9
+ * and automatically stopped when no subscribers remain.
10
+ *
11
+ * @see {@link enableSignalR} for the quickest way to register the module.
12
+ * @see {@link ISignalRProvider.connect} for subscribing to hub methods at runtime.
13
+ */
1
14
  export { ISignalRConfigurator, SignalRConfigurator, SignalRConfig, SignalRHubConfig, SignalRModuleConfigBuilder, SignalRModuleConfigBuilderCallback, } from './SignalRModuleConfigurator';
2
15
  export { ISignalRProvider, SignalRModuleProvider } from './SignalRModuleProvider';
3
16
  export { Topic } from './lib/Topic';
@@ -1,10 +1,50 @@
1
1
  import type { HubConnection } from '@microsoft/signalr';
2
2
  import { Observable } from 'rxjs';
3
+ /**
4
+ * RxJS Observable wrapper around a SignalR hub method.
5
+ *
6
+ * A `Topic` subscribes to a named method on a `HubConnection` and emits
7
+ * incoming messages as observable values. It also exposes {@link Topic.send}
8
+ * and {@link Topic.invoke} for sending messages back to the server.
9
+ *
10
+ * Created by {@link SignalRModuleProvider.connect} — consumers typically
11
+ * do not instantiate `Topic` directly.
12
+ *
13
+ * @template T - Type of messages received from the hub method
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const topic = provider.connect<ChatMessage>('chat', 'ReceiveMessage');
18
+ * topic.subscribe((msg) => console.log(msg.text));
19
+ *
20
+ * // Send a message to the server on the same method
21
+ * topic.send('Hello, world!');
22
+ * ```
23
+ */
3
24
  export declare class Topic<T> extends Observable<T> {
4
25
  topic: string;
5
26
  hubConnection: Observable<HubConnection>;
27
+ /** The active hub connection, set once the connection observable emits. */
6
28
  connection: HubConnection | undefined;
29
+ /**
30
+ * @param topic - Server-side method name to listen on and send to
31
+ * @param hubConnection - Observable that emits the active `HubConnection`
32
+ */
7
33
  constructor(topic: string, hubConnection: Observable<HubConnection>);
34
+ /**
35
+ * Send a fire-and-forget message to the server on this topic.
36
+ *
37
+ * @param args - Arguments forwarded to `HubConnection.send()`
38
+ * @throws {Error} When the hub connection has not been established yet
39
+ */
8
40
  send(...args: any[]): void;
41
+ /**
42
+ * Invoke a server method on this topic and wait for a response.
43
+ *
44
+ * @template T - Expected return type from the server method
45
+ * @param args - Arguments forwarded to `HubConnection.invoke()`
46
+ * @returns Promise resolving with the server's response
47
+ * @throws {Error} When the hub connection has not been established yet
48
+ */
9
49
  invoke<T>(...args: any[]): Promise<T>;
10
50
  }
@@ -1,8 +1 @@
1
- import type { MsalModule } from '@equinor/fusion-framework-module-msal';
2
- import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';
3
- import type { SignalRModuleConfigBuilder } from '../../SignalRModuleConfigurator';
4
- export declare const configureFromFramework: (args: {
5
- name: string;
6
- service: string;
7
- path: string;
8
- }, builder: SignalRModuleConfigBuilder<[MsalModule, ServiceDiscoveryModule]>) => Promise<void>;
1
+ export {};
@@ -1,38 +1,60 @@
1
1
  import type { IModulesConfigurator } from '@equinor/fusion-framework-module';
2
2
  import type { SignalRModuleConfigBuilderCallback } from '../../SignalRModuleConfigurator';
3
+ /**
4
+ * Call-signature overloads for {@link enableSignalR}.
5
+ */
3
6
  export interface enableSignalR {
7
+ /**
8
+ * Enable SignalR with a custom configuration builder callback.
9
+ *
10
+ * @param configurator - The module configurator instance
11
+ * @param name - Hub name identifier
12
+ * @param cb - Builder callback for manual hub configuration
13
+ */
4
14
  (configurator: IModulesConfigurator<any, any>, name: string, cb: SignalRModuleConfigBuilderCallback): void;
15
+ /**
16
+ * Enable SignalR using service-discovery to resolve the hub URL automatically.
17
+ *
18
+ * @param configurator - The module configurator instance
19
+ * @param name - Hub name identifier
20
+ * @param options - Service name and path used to resolve the hub endpoint
21
+ */
5
22
  (configurator: IModulesConfigurator<any, any>, name: string, options: {
6
23
  service: string;
7
24
  path: string;
8
25
  }): void;
9
26
  }
10
27
  /**
28
+ * Register the SignalR module on a Fusion Framework configurator and add hub
29
+ * configuration in a single call.
30
+ *
31
+ * Accepts either a manual builder callback or a service-discovery shorthand.
32
+ * When the shorthand form is used, the hub URL and authentication token are
33
+ * resolved automatically via the service-discovery and MSAL modules.
34
+ *
35
+ * @param configurator - The module configurator to register the SignalR module on
36
+ * @param name - Hub name identifier (used as key in the hub registry)
37
+ * @param optionsOrCallback - A builder callback for custom configuration, or
38
+ * `{ service, path }` to resolve the hub endpoint through service-discovery
39
+ *
11
40
  * @example
12
- ```ts
13
- import {
14
- enableSignalR,
15
- configurePortalHub,
16
- configureNotificationHub
17
- } from '@equinor/fusion-framework-module-signalr';
18
-
19
- export const configure = (configurator) => {
20
- enableSignalR(configurator, {
21
- name: 'portal',
22
- service: 'portal',
23
- path: '/signalr/hubs/service-message'
24
- });
25
- enableSignalR(configurator, 'notifications');
26
- // custom
27
- enableSignalR(configurator, builder => {
28
- builder.addHub('myHub', {
29
- uri: 'https://foo.bar',
30
- path: '/my_messages'
31
- accessTokenFactory: () => makeToken(),
32
- })
33
- });
34
- }
35
- ```
41
+ * ```ts
42
+ * import { enableSignalR } from '@equinor/fusion-framework-module-signalr';
43
+ *
44
+ * // Using service-discovery shorthand
45
+ * enableSignalR(configurator, 'portal', {
46
+ * service: 'portal',
47
+ * path: '/signalr/hubs/service-message',
48
+ * });
49
+ *
50
+ * // Using a custom builder callback
51
+ * enableSignalR(configurator, 'custom', (builder) => {
52
+ * builder.addHub('custom', {
53
+ * url: 'https://my-service.example.com/hub',
54
+ * options: { accessTokenFactory: () => getToken() },
55
+ * });
56
+ * });
57
+ * ```
36
58
  */
37
59
  export declare function enableSignalR(configurator: IModulesConfigurator<any, any>, name: string, optionsOrCallback: SignalRModuleConfigBuilderCallback | {
38
60
  service: string;
@@ -1 +1 @@
1
- export declare const version = "10.0.1";
1
+ export declare const version = "11.0.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/fusion-framework-module-signalr",
3
- "version": "10.0.1",
3
+ "version": "11.0.0",
4
4
  "description": "",
5
5
  "sideEffects": false,
6
6
  "main": "dist/esm/index.js",
@@ -27,14 +27,15 @@
27
27
  "rxjs": "^7.8.1"
28
28
  },
29
29
  "devDependencies": {
30
- "typescript": "^5.8.2",
31
- "@equinor/fusion-framework-module-msal": "^7.3.1",
32
- "@equinor/fusion-framework-module": "^5.0.6"
30
+ "typescript": "^5.9.3",
31
+ "@equinor/fusion-framework-module-msal": "^8.0.0",
32
+ "@equinor/fusion-framework-module": "^6.0.0",
33
+ "@equinor/fusion-framework-module-service-discovery": "^10.0.0"
33
34
  },
34
35
  "peerDependencies": {
35
- "@equinor/fusion-framework-module": "^5.0.6",
36
- "@equinor/fusion-framework-module-msal": "^7.3.1",
37
- "@equinor/fusion-framework-module-service-discovery": "^9.1.1"
36
+ "@equinor/fusion-framework-module": "^6.0.0",
37
+ "@equinor/fusion-framework-module-msal": "^8.0.0",
38
+ "@equinor/fusion-framework-module-service-discovery": "^10.0.0"
38
39
  },
39
40
  "peerDependenciesMeta": {
40
41
  "@equinor/fusion-framework-module-service-discovery": {
@@ -3,12 +3,36 @@ import { type ISignalRConfigurator, SignalRConfigurator } from './SignalRModuleC
3
3
 
4
4
  import { type ISignalRProvider, SignalRModuleProvider } from './SignalRModuleProvider';
5
5
 
6
+ /** String literal key used to register the SignalR module in the Fusion Framework module system. */
6
7
  export type SignalRModuleKey = 'signalR';
7
8
 
9
+ /** Module registration key for the SignalR module (`'signalR'`). */
8
10
  export const moduleKey: SignalRModuleKey = 'signalR';
9
11
 
12
+ /**
13
+ * Module type definition for the SignalR module.
14
+ *
15
+ * Binds the module key, provider interface ({@link ISignalRProvider}), and
16
+ * configurator interface ({@link ISignalRConfigurator}) together for the
17
+ * Fusion Framework module system.
18
+ */
10
19
  export type SignalRModule = Module<SignalRModuleKey, ISignalRProvider, ISignalRConfigurator>;
11
20
 
21
+ /**
22
+ * SignalR module instance that can be registered with a Fusion Framework configurator.
23
+ *
24
+ * During the `configure` phase, a {@link SignalRConfigurator} is created.
25
+ * During the `initialize` phase, the configurator builds its {@link SignalRConfig}
26
+ * and produces a {@link SignalRModuleProvider}.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { ModuleConfigurator } from '@equinor/fusion-framework-module';
31
+ * import signalR from '@equinor/fusion-framework-module-signalr';
32
+ *
33
+ * configurator.addConfig({ module: signalR });
34
+ * ```
35
+ */
12
36
  export const module: SignalRModule = {
13
37
  name: moduleKey,
14
38
  configure: () => new SignalRConfigurator(),
@@ -20,6 +44,7 @@ export const module: SignalRModule = {
20
44
 
21
45
  export default module;
22
46
 
47
+ /** Augments the global `Modules` interface so that `'signalR'` is a known module key. */
23
48
  declare module '@equinor/fusion-framework-module' {
24
49
  interface Modules {
25
50
  signalR: SignalRModule;
@@ -7,77 +7,154 @@ import {
7
7
  import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';
8
8
  import type { IHttpConnectionOptions, LogLevel } from '@microsoft/signalr';
9
9
 
10
+ /**
11
+ * Public configuration interface for the SignalR module.
12
+ *
13
+ * Consumers use this interface to register hub connections and configuration
14
+ * callbacks during the module `configure` phase.
15
+ */
10
16
  export interface ISignalRConfigurator {
11
- /** add configuration for hub connection */
17
+ /**
18
+ * Register a named SignalR hub connection.
19
+ *
20
+ * @param name - Unique identifier for the hub (used later with {@link ISignalRProvider.connect})
21
+ * @param config - Hub connection configuration or a promise that resolves to one
22
+ */
12
23
  addHub(name: string, config: SignalRHubConfig | Promise<SignalRHubConfig>): void;
13
24
 
14
- /** add callback for building config on init */
25
+ /**
26
+ * Register a callback that will run during the module initialization phase
27
+ * to build configuration using a {@link SignalRModuleConfigBuilder}.
28
+ *
29
+ * Use this when hub configuration depends on resolved module dependencies
30
+ * such as service-discovery or authentication.
31
+ *
32
+ * @param cb - Callback that receives a {@link SignalRModuleConfigBuilder}
33
+ */
15
34
  onCreateConfig(cb: SignalRModuleConfigBuilderCallback): void;
16
35
  }
17
36
 
18
- /** configuration callback */
37
+ /**
38
+ * Callback invoked during module initialization to configure SignalR hubs.
39
+ *
40
+ * Receives a {@link SignalRModuleConfigBuilder} that provides access to
41
+ * resolved module dependencies, allowing dynamic hub registration.
42
+ *
43
+ * @template TDeps - Tuple of module dependencies available through the builder
44
+ */
19
45
  export type SignalRModuleConfigBuilderCallback<TDeps = unknown> = (
20
46
  builder: SignalRModuleConfigBuilder<TDeps>,
21
47
  ) => void | Promise<void>;
22
48
 
23
49
  /**
24
- * Configuration for hub connection
50
+ * Configuration for a single SignalR hub connection.
51
+ *
52
+ * Defines the endpoint URL, transport options, reconnection behavior,
53
+ * and logging level for a `@microsoft/signalr` `HubConnection`.
25
54
  */
26
55
  export type SignalRHubConfig = {
27
- /** connection endpoint */
56
+ /** Absolute URL of the SignalR hub endpoint. */
28
57
  url: string;
29
58
 
30
- /** connection options */
59
+ /**
60
+ * Transport and authentication options forwarded to the underlying
61
+ * `HubConnectionBuilder.withUrl()` call.
62
+ *
63
+ * The `httpClient` option is excluded because the module manages the
64
+ * HTTP client internally.
65
+ */
31
66
  options: Omit<IHttpConnectionOptions, 'httpClient'>;
32
67
 
33
- /** reconnect when connection lost */
68
+ /**
69
+ * When `true`, the connection will automatically attempt to reconnect
70
+ * after an unintentional disconnection.
71
+ *
72
+ * @defaultValue `undefined` (no automatic reconnect)
73
+ */
34
74
  automaticReconnect?: boolean;
75
+
76
+ /**
77
+ * Minimum log level for the SignalR connection logger.
78
+ *
79
+ * @defaultValue `LogLevel.Critical` (5) when omitted
80
+ */
35
81
  logLevel?: LogLevel;
36
82
  };
37
83
 
38
84
  /**
39
- * Configuration for creating SignalR provider
85
+ * Resolved configuration used to create a {@link SignalRModuleProvider}.
86
+ *
87
+ * Contains all registered hub configurations keyed by hub name.
40
88
  */
41
89
  export type SignalRConfig = {
90
+ /** Map of hub name to its {@link SignalRHubConfig}. */
42
91
  hubs: Record<string, SignalRHubConfig>;
43
92
  };
44
93
 
45
94
  /**
46
- * builder utility class for generating configuration
95
+ * Builder utility for registering SignalR hub configurations during
96
+ * module initialization.
97
+ *
98
+ * Extends {@link ModuleConfigBuilder} to provide access to resolved
99
+ * module dependencies (e.g., service-discovery, authentication) so that
100
+ * hub URLs and access-token factories can be built dynamically.
101
+ *
102
+ * @template TDeps - Tuple of module dependencies available through the builder
47
103
  */
48
104
  export class SignalRModuleConfigBuilder<
49
105
  TDeps extends AnyModule[] | unknown = unknown,
50
106
  // TODO - use BaseConfigBuilder
51
107
  > extends ModuleConfigBuilder<TDeps, ISignalRConfigurator> {
108
+ /**
109
+ * Register a named hub connection through the underlying configurator.
110
+ *
111
+ * @param name - Unique hub identifier
112
+ * @param config - Hub connection configuration
113
+ */
52
114
  async addHub(name: string, config: SignalRHubConfig) {
53
115
  this._config.addHub(name, config);
54
116
  }
55
117
  }
56
118
 
119
+ /**
120
+ * Default {@link ISignalRConfigurator} implementation.
121
+ *
122
+ * Collects hub registrations and builder callbacks, then produces a
123
+ * {@link SignalRConfig} during the module initialization phase.
124
+ */
57
125
  export class SignalRConfigurator implements ISignalRConfigurator {
58
126
  #builderCallbacks: Array<SignalRModuleConfigBuilderCallback> = [];
59
127
 
60
128
  #hubs: Record<string, SignalRHubConfig> = {};
61
129
 
62
130
  /**
63
- * register SignalR hub configuration.
131
+ * Register a named SignalR hub connection.
132
+ *
133
+ * @param name - Unique identifier for the hub
134
+ * @param config - Hub connection configuration
64
135
  */
65
136
  public addHub(name: string, config: SignalRHubConfig) {
66
137
  this.#hubs[name] = config;
67
138
  }
68
139
 
69
140
  /**
70
- * add callback for building config on when configurator is creating config.
71
- * {@link SignalRConfigurator.createConfig}
141
+ * Register a configuration builder callback that will run during
142
+ * {@link SignalRConfigurator.createConfig}.
143
+ *
144
+ * @param cb - Callback receiving a {@link SignalRModuleConfigBuilder}
72
145
  */
73
146
  public onCreateConfig<T>(cb: SignalRModuleConfigBuilderCallback<T>): void {
74
147
  this.#builderCallbacks.push(cb);
75
148
  }
76
149
 
77
150
  /**
78
- * normally executed in `init` phase of module, which creates configuration to the module provider.
79
- * cycles threw all registered configuration builders.
80
- * await all registered hub configurations.
151
+ * Build the final {@link SignalRConfig} by executing all registered
152
+ * builder callbacks and collecting hub configurations.
153
+ *
154
+ * Normally called during the module `initialize` phase.
155
+ *
156
+ * @param init - Module initializer arguments providing access to resolved dependencies
157
+ * @returns Resolved configuration containing all registered hubs
81
158
  */
82
159
  public async createConfig(
83
160
  init: ModuleInitializerArgs<ISignalRConfigurator, [ServiceDiscoveryModule]>,