@thalesrc/hermes 7.0.1 → 7.2.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019 Thales Rocks
3
+ Copyright (c) 2019 Thalesrc
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -231,6 +231,28 @@ mainService.sendDataToWorker([1, 2, 3, 4, 5]).subscribe(result => {
231
231
  });
232
232
  ```
233
233
 
234
+ ##### Async Worker Initialization
235
+
236
+ The worker parameter supports flexible initialization patterns:
237
+
238
+ ```typescript
239
+ // Direct Worker instance
240
+ const service1 = new MainThread(new Worker('./worker.js'));
241
+
242
+ // Promise that resolves to a Worker (for async initialization)
243
+ const workerPromise = import('./worker.js').then(m => new Worker(m.default));
244
+ const service2 = new MainThread(workerPromise);
245
+
246
+ // Function that returns a Worker (for lazy initialization)
247
+ const service3 = new MainThread(() => new Worker('./worker.js'));
248
+
249
+ // Function that returns a Promise<Worker> (for async lazy initialization)
250
+ const service4 = new MainThread(async () => {
251
+ const module = await import('./worker.js');
252
+ return new Worker(module.default);
253
+ });
254
+ ```
255
+
234
256
  #### Worker Thread
235
257
 
236
258
  ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thalesrc/hermes",
3
- "version": "7.0.1",
3
+ "version": "7.2.0",
4
4
  "description": "Javascript messaging library",
5
5
  "keywords": [
6
6
  "javascript",
@@ -48,6 +48,111 @@
48
48
  "node": "./index.cjs",
49
49
  "require": "./index.cjs",
50
50
  "types": "./index.d.ts"
51
+ },
52
+ "./broadcast": {
53
+ "default": "./broadcast/index.cjs",
54
+ "import": "./broadcast/index.js",
55
+ "node": "./broadcast/index.cjs",
56
+ "require": "./broadcast/index.cjs",
57
+ "types": "./broadcast/index.d.ts"
58
+ },
59
+ "./broadcast/message-client": {
60
+ "default": "./broadcast/message-client.cjs",
61
+ "import": "./broadcast/message-client.js",
62
+ "node": "./broadcast/message-client.cjs",
63
+ "require": "./broadcast/message-client.cjs",
64
+ "types": "./broadcast/message-client.d.ts"
65
+ },
66
+ "./broadcast/message-host": {
67
+ "default": "./broadcast/message-host.cjs",
68
+ "import": "./broadcast/message-host.js",
69
+ "node": "./broadcast/message-host.cjs",
70
+ "require": "./broadcast/message-host.cjs",
71
+ "types": "./broadcast/message-host.d.ts"
72
+ },
73
+ "./broadcast/message-service": {
74
+ "default": "./broadcast/message-service.cjs",
75
+ "import": "./broadcast/message-service.js",
76
+ "node": "./broadcast/message-service.cjs",
77
+ "require": "./broadcast/message-service.cjs",
78
+ "types": "./broadcast/message-service.d.ts"
79
+ },
80
+ "./chrome": {
81
+ "default": "./chrome/index.cjs",
82
+ "import": "./chrome/index.js",
83
+ "node": "./chrome/index.cjs",
84
+ "require": "./chrome/index.cjs",
85
+ "types": "./chrome/index.d.ts"
86
+ },
87
+ "./chrome/message-client": {
88
+ "default": "./chrome/message-client.cjs",
89
+ "import": "./chrome/message-client.js",
90
+ "node": "./chrome/message-client.cjs",
91
+ "require": "./chrome/message-client.cjs",
92
+ "types": "./chrome/message-client.d.ts"
93
+ },
94
+ "./chrome/message-host": {
95
+ "default": "./chrome/message-host.cjs",
96
+ "import": "./chrome/message-host.js",
97
+ "node": "./chrome/message-host.cjs",
98
+ "require": "./chrome/message-host.cjs",
99
+ "types": "./chrome/message-host.d.ts"
100
+ },
101
+ "./iframe": {
102
+ "default": "./iframe/index.cjs",
103
+ "import": "./iframe/index.js",
104
+ "node": "./iframe/index.cjs",
105
+ "require": "./iframe/index.cjs",
106
+ "types": "./iframe/index.d.ts"
107
+ },
108
+ "./iframe/message-client": {
109
+ "default": "./iframe/message-client.cjs",
110
+ "import": "./iframe/message-client.js",
111
+ "node": "./iframe/message-client.cjs",
112
+ "require": "./iframe/message-client.cjs",
113
+ "types": "./iframe/message-client.d.ts"
114
+ },
115
+ "./iframe/message-host": {
116
+ "default": "./iframe/message-host.cjs",
117
+ "import": "./iframe/message-host.js",
118
+ "node": "./iframe/message-host.cjs",
119
+ "require": "./iframe/message-host.cjs",
120
+ "types": "./iframe/message-host.d.ts"
121
+ },
122
+ "./iframe/message-service": {
123
+ "default": "./iframe/message-service.cjs",
124
+ "import": "./iframe/message-service.js",
125
+ "node": "./iframe/message-service.cjs",
126
+ "require": "./iframe/message-service.cjs",
127
+ "types": "./iframe/message-service.d.ts"
128
+ },
129
+ "./worker": {
130
+ "default": "./worker/index.cjs",
131
+ "import": "./worker/index.js",
132
+ "node": "./worker/index.cjs",
133
+ "require": "./worker/index.cjs",
134
+ "types": "./worker/index.d.ts"
135
+ },
136
+ "./worker/message-client": {
137
+ "default": "./worker/message-client.cjs",
138
+ "import": "./worker/message-client.js",
139
+ "node": "./worker/message-client.cjs",
140
+ "require": "./worker/message-client.cjs",
141
+ "types": "./worker/message-client.d.ts"
142
+ },
143
+ "./worker/message-host": {
144
+ "default": "./worker/message-host.cjs",
145
+ "import": "./worker/message-host.js",
146
+ "node": "./worker/message-host.cjs",
147
+ "require": "./worker/message-host.cjs",
148
+ "types": "./worker/message-host.d.ts"
149
+ },
150
+ "./worker/message-service": {
151
+ "default": "./worker/message-service.cjs",
152
+ "import": "./worker/message-service.js",
153
+ "node": "./worker/message-service.cjs",
154
+ "require": "./worker/message-service.cjs",
155
+ "types": "./worker/message-service.d.ts"
51
156
  }
52
157
  }
53
158
  }
package/worker/index.cjs CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Listen = exports.Request = exports.WorkerMessageService = void 0;
3
+ exports.Listen = exports.Request = exports.WorkerMessageHost = exports.WorkerMessageClient = exports.WorkerMessageService = void 0;
4
4
  var message_service_1 = require("./message-service");
5
5
  Object.defineProperty(exports, "WorkerMessageService", { enumerable: true, get: function () { return message_service_1.WorkerMessageService; } });
6
+ var message_client_1 = require("./message-client");
7
+ Object.defineProperty(exports, "WorkerMessageClient", { enumerable: true, get: function () { return message_client_1.WorkerMessageClient; } });
8
+ var message_host_1 = require("./message-host");
9
+ Object.defineProperty(exports, "WorkerMessageHost", { enumerable: true, get: function () { return message_host_1.WorkerMessageHost; } });
6
10
  var request_decorator_1 = require("../request.decorator");
7
11
  Object.defineProperty(exports, "Request", { enumerable: true, get: function () { return request_decorator_1.Request; } });
8
12
  var listen_decorator_1 = require("../listen.decorator");
package/worker/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { WorkerMessageService } from './message-service';
2
+ export { WorkerMessageClient } from './message-client';
3
+ export { WorkerMessageHost } from './message-host';
2
4
  export { Request } from '../request.decorator';
3
5
  export { Listen } from '../listen.decorator';
package/worker/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export { WorkerMessageService } from './message-service';
2
+ export { WorkerMessageClient } from './message-client';
3
+ export { WorkerMessageHost } from './message-host';
2
4
  export { Request } from '../request.decorator';
3
5
  export { Listen } from '../listen.decorator';
4
6
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../libs/hermes/src/worker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC","file":"index.js","sourcesContent":["export { WorkerMessageService } from './message-service';\nexport { Request } from '../request.decorator';\nexport { Listen } from '../listen.decorator';\n"]}
1
+ {"version":3,"sources":["../../../../../libs/hermes/src/worker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC","file":"index.js","sourcesContent":["export { WorkerMessageService } from './message-service';\nexport { WorkerMessageClient } from './message-client';\nexport { WorkerMessageHost } from './message-host';\nexport { Request } from '../request.decorator';\nexport { Listen } from '../listen.decorator';\n"]}
@@ -1,40 +1,125 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WorkerMessageClient = void 0;
4
- const js_utils_1 = require("@thalesrc/js-utils");
4
+ const unique_id_1 = require("@thalesrc/js-utils/unique-id");
5
+ const noop_1 = require("@thalesrc/js-utils/function/noop");
6
+ const promisify_1 = require("@thalesrc/js-utils/promise/promisify");
5
7
  const rxjs_1 = require("rxjs");
6
8
  const message_client_1 = require("../message-client");
7
9
  const selectors_1 = require("../selectors");
8
- const WORKER = Symbol('Worker');
9
- const HANDLER = Symbol('Handler');
10
- const INSTANCE_ID = Symbol('Instance Id');
10
+ /**
11
+ * WorkerMessageClient
12
+ *
13
+ * Client implementation for Web Worker communication. Sends messages to and receives
14
+ * responses from Web Workers using the Worker postMessage API.
15
+ *
16
+ * This class can be used in two contexts:
17
+ * - **Main thread**: Provide a Worker instance to communicate with that specific worker
18
+ * - **Worker thread**: Omit the worker parameter to communicate with the main thread via self
19
+ *
20
+ * The worker parameter supports multiple types for flexibility:
21
+ * - Direct Worker instance
22
+ * - Promise that resolves to a Worker (for async worker initialization)
23
+ * - Function that returns a Worker (for lazy initialization)
24
+ * - Function that returns a Promise<Worker> (for async lazy initialization)
25
+ *
26
+ * @example
27
+ * // In main thread - communicate with a specific worker
28
+ * const worker = new Worker('./worker.js');
29
+ * const client = new WorkerMessageClient(worker);
30
+ *
31
+ * @example
32
+ * // In worker thread - communicate with main thread
33
+ * const client = new WorkerMessageClient();
34
+ *
35
+ * @example
36
+ * // With async worker initialization
37
+ * const workerPromise = import('./worker.js').then(m => new m.MyWorker());
38
+ * const client = new WorkerMessageClient(workerPromise);
39
+ *
40
+ * @example
41
+ * // With lazy initialization
42
+ * const client = new WorkerMessageClient(() =>
43
+ * document.querySelector('[data-worker]') ? new Worker('./worker.js') : undefined
44
+ * );
45
+ */
11
46
  class WorkerMessageClient extends message_client_1.MessageClient {
47
+ /**
48
+ * Promise resolving to the Worker instance or undefined if running in worker context
49
+ * @private
50
+ */
51
+ #worker = null;
52
+ /**
53
+ * Unique identifier for this client instance to prevent ID collisions
54
+ * @private
55
+ */
56
+ #instanceId = Date.now();
57
+ /**
58
+ * Observable stream of message responses from the worker or main thread
59
+ */
12
60
  [selectors_1.RESPONSES$] = new rxjs_1.Subject();
13
- [WORKER];
14
- [INSTANCE_ID] = Date.now();
61
+ /**
62
+ * Creates a new WorkerMessageClient instance
63
+ *
64
+ * @param worker - Optional worker configuration:
65
+ * - Worker: Direct worker instance (main thread)
66
+ * - Promise<Worker>: Promise resolving to worker (async initialization)
67
+ * - () => Worker: Function returning worker (lazy initialization)
68
+ * - () => Promise<Worker>: Function returning promise (async lazy initialization)
69
+ * - undefined: Omit for worker thread context (uses self)
70
+ */
15
71
  constructor(worker) {
16
72
  super();
17
- this[WORKER] = worker;
18
- if (worker) {
19
- worker.addEventListener('message', this[HANDLER]);
20
- }
21
- else {
22
- addEventListener('message', this[HANDLER]);
23
- }
73
+ // Resolve worker parameter: execute function if provided, otherwise use value directly
74
+ const _worker = typeof worker === 'function' ? worker() : worker;
75
+ // Ensure worker is wrapped in a promise for consistent async handling
76
+ this.#worker = (0, promisify_1.promisify)(_worker);
77
+ // Set up message listener once worker is resolved
78
+ this.#worker.then(worker => {
79
+ if (worker) {
80
+ // Main thread context: listen to specific worker
81
+ worker.addEventListener('message', this.#handler);
82
+ }
83
+ else {
84
+ // Worker thread context: listen to messages from main thread
85
+ addEventListener('message', this.#handler);
86
+ }
87
+ }).catch(noop_1.noop);
24
88
  }
89
+ /**
90
+ * Sends a message to the worker or main thread
91
+ *
92
+ * @param message - The message to send
93
+ * @template T - Type of the message body
94
+ * @internal Used by @Request decorator
95
+ */
25
96
  [selectors_1.SEND](message) {
26
- if (this[WORKER]) {
27
- this[WORKER].postMessage(message);
28
- }
29
- else {
30
- postMessage(message);
31
- }
97
+ this.#worker.then(worker => {
98
+ if (worker) {
99
+ // Main thread: send to worker
100
+ worker.postMessage(message);
101
+ }
102
+ else {
103
+ // Worker thread: send to main thread
104
+ postMessage(message);
105
+ }
106
+ }).catch(noop_1.noop);
32
107
  }
33
- [HANDLER] = (event) => {
108
+ /**
109
+ * Handles incoming messages and forwards them to the responses stream
110
+ * @private
111
+ */
112
+ #handler = (event) => {
34
113
  this[selectors_1.RESPONSES$].next(event.data);
35
114
  };
115
+ /**
116
+ * Generates a unique message ID for tracking request-response pairs
117
+ *
118
+ * @returns Unique message identifier
119
+ * @internal Used by @Request decorator
120
+ */
36
121
  [selectors_1.GET_NEW_ID]() {
37
- return (0, js_utils_1.uniqueId)('hermes-worker-message-' + this[INSTANCE_ID]);
122
+ return (0, unique_id_1.uniqueId)('hermes-worker-message-' + this.#instanceId);
38
123
  }
39
124
  }
40
125
  exports.WorkerMessageClient = WorkerMessageClient;
@@ -3,19 +3,72 @@ import { MessageClient } from "../message-client";
3
3
  import { MessageResponse } from "../message-response.type";
4
4
  import { Message } from "../message.interface";
5
5
  import { GET_NEW_ID, RESPONSES$, SEND } from "../selectors";
6
- interface MessageEvent<T> {
7
- data: T;
8
- }
9
- declare const WORKER: unique symbol;
10
- declare const HANDLER: unique symbol;
11
- declare const INSTANCE_ID: unique symbol;
6
+ /**
7
+ * WorkerMessageClient
8
+ *
9
+ * Client implementation for Web Worker communication. Sends messages to and receives
10
+ * responses from Web Workers using the Worker postMessage API.
11
+ *
12
+ * This class can be used in two contexts:
13
+ * - **Main thread**: Provide a Worker instance to communicate with that specific worker
14
+ * - **Worker thread**: Omit the worker parameter to communicate with the main thread via self
15
+ *
16
+ * The worker parameter supports multiple types for flexibility:
17
+ * - Direct Worker instance
18
+ * - Promise that resolves to a Worker (for async worker initialization)
19
+ * - Function that returns a Worker (for lazy initialization)
20
+ * - Function that returns a Promise<Worker> (for async lazy initialization)
21
+ *
22
+ * @example
23
+ * // In main thread - communicate with a specific worker
24
+ * const worker = new Worker('./worker.js');
25
+ * const client = new WorkerMessageClient(worker);
26
+ *
27
+ * @example
28
+ * // In worker thread - communicate with main thread
29
+ * const client = new WorkerMessageClient();
30
+ *
31
+ * @example
32
+ * // With async worker initialization
33
+ * const workerPromise = import('./worker.js').then(m => new m.MyWorker());
34
+ * const client = new WorkerMessageClient(workerPromise);
35
+ *
36
+ * @example
37
+ * // With lazy initialization
38
+ * const client = new WorkerMessageClient(() =>
39
+ * document.querySelector('[data-worker]') ? new Worker('./worker.js') : undefined
40
+ * );
41
+ */
12
42
  export declare class WorkerMessageClient extends MessageClient {
43
+ #private;
44
+ /**
45
+ * Observable stream of message responses from the worker or main thread
46
+ */
13
47
  [RESPONSES$]: Subject<MessageResponse>;
14
- protected [WORKER]: Worker | undefined;
15
- private [INSTANCE_ID];
16
- constructor(worker?: Worker);
48
+ /**
49
+ * Creates a new WorkerMessageClient instance
50
+ *
51
+ * @param worker - Optional worker configuration:
52
+ * - Worker: Direct worker instance (main thread)
53
+ * - Promise<Worker>: Promise resolving to worker (async initialization)
54
+ * - () => Worker: Function returning worker (lazy initialization)
55
+ * - () => Promise<Worker>: Function returning promise (async lazy initialization)
56
+ * - undefined: Omit for worker thread context (uses self)
57
+ */
58
+ constructor(worker?: Worker | Promise<Worker | undefined> | (() => Worker | undefined) | (() => Promise<Worker | undefined>));
59
+ /**
60
+ * Sends a message to the worker or main thread
61
+ *
62
+ * @param message - The message to send
63
+ * @template T - Type of the message body
64
+ * @internal Used by @Request decorator
65
+ */
17
66
  [SEND]<T>(message: Message<T>): void;
18
- protected [HANDLER]: (event: MessageEvent<MessageResponse>) => void;
67
+ /**
68
+ * Generates a unique message ID for tracking request-response pairs
69
+ *
70
+ * @returns Unique message identifier
71
+ * @internal Used by @Request decorator
72
+ */
19
73
  protected [GET_NEW_ID](): string;
20
74
  }
21
- export {};
@@ -1,37 +1,122 @@
1
- import { uniqueId } from "@thalesrc/js-utils";
1
+ import { uniqueId } from "@thalesrc/js-utils/unique-id";
2
+ import { noop } from "@thalesrc/js-utils/function/noop";
3
+ import { promisify } from '@thalesrc/js-utils/promise/promisify';
2
4
  import { Subject } from "rxjs";
3
5
  import { MessageClient } from "../message-client";
4
6
  import { GET_NEW_ID, RESPONSES$, SEND } from "../selectors";
5
- const WORKER = Symbol('Worker');
6
- const HANDLER = Symbol('Handler');
7
- const INSTANCE_ID = Symbol('Instance Id');
7
+ /**
8
+ * WorkerMessageClient
9
+ *
10
+ * Client implementation for Web Worker communication. Sends messages to and receives
11
+ * responses from Web Workers using the Worker postMessage API.
12
+ *
13
+ * This class can be used in two contexts:
14
+ * - **Main thread**: Provide a Worker instance to communicate with that specific worker
15
+ * - **Worker thread**: Omit the worker parameter to communicate with the main thread via self
16
+ *
17
+ * The worker parameter supports multiple types for flexibility:
18
+ * - Direct Worker instance
19
+ * - Promise that resolves to a Worker (for async worker initialization)
20
+ * - Function that returns a Worker (for lazy initialization)
21
+ * - Function that returns a Promise<Worker> (for async lazy initialization)
22
+ *
23
+ * @example
24
+ * // In main thread - communicate with a specific worker
25
+ * const worker = new Worker('./worker.js');
26
+ * const client = new WorkerMessageClient(worker);
27
+ *
28
+ * @example
29
+ * // In worker thread - communicate with main thread
30
+ * const client = new WorkerMessageClient();
31
+ *
32
+ * @example
33
+ * // With async worker initialization
34
+ * const workerPromise = import('./worker.js').then(m => new m.MyWorker());
35
+ * const client = new WorkerMessageClient(workerPromise);
36
+ *
37
+ * @example
38
+ * // With lazy initialization
39
+ * const client = new WorkerMessageClient(() =>
40
+ * document.querySelector('[data-worker]') ? new Worker('./worker.js') : undefined
41
+ * );
42
+ */
8
43
  export class WorkerMessageClient extends MessageClient {
44
+ /**
45
+ * Promise resolving to the Worker instance or undefined if running in worker context
46
+ * @private
47
+ */
48
+ #worker = null;
49
+ /**
50
+ * Unique identifier for this client instance to prevent ID collisions
51
+ * @private
52
+ */
53
+ #instanceId = Date.now();
54
+ /**
55
+ * Observable stream of message responses from the worker or main thread
56
+ */
9
57
  [RESPONSES$] = new Subject();
10
- [WORKER];
11
- [INSTANCE_ID] = Date.now();
58
+ /**
59
+ * Creates a new WorkerMessageClient instance
60
+ *
61
+ * @param worker - Optional worker configuration:
62
+ * - Worker: Direct worker instance (main thread)
63
+ * - Promise<Worker>: Promise resolving to worker (async initialization)
64
+ * - () => Worker: Function returning worker (lazy initialization)
65
+ * - () => Promise<Worker>: Function returning promise (async lazy initialization)
66
+ * - undefined: Omit for worker thread context (uses self)
67
+ */
12
68
  constructor(worker) {
13
69
  super();
14
- this[WORKER] = worker;
15
- if (worker) {
16
- worker.addEventListener('message', this[HANDLER]);
17
- }
18
- else {
19
- addEventListener('message', this[HANDLER]);
20
- }
70
+ // Resolve worker parameter: execute function if provided, otherwise use value directly
71
+ const _worker = typeof worker === 'function' ? worker() : worker;
72
+ // Ensure worker is wrapped in a promise for consistent async handling
73
+ this.#worker = promisify(_worker);
74
+ // Set up message listener once worker is resolved
75
+ this.#worker.then(worker => {
76
+ if (worker) {
77
+ // Main thread context: listen to specific worker
78
+ worker.addEventListener('message', this.#handler);
79
+ }
80
+ else {
81
+ // Worker thread context: listen to messages from main thread
82
+ addEventListener('message', this.#handler);
83
+ }
84
+ }).catch(noop);
21
85
  }
86
+ /**
87
+ * Sends a message to the worker or main thread
88
+ *
89
+ * @param message - The message to send
90
+ * @template T - Type of the message body
91
+ * @internal Used by @Request decorator
92
+ */
22
93
  [SEND](message) {
23
- if (this[WORKER]) {
24
- this[WORKER].postMessage(message);
25
- }
26
- else {
27
- postMessage(message);
28
- }
94
+ this.#worker.then(worker => {
95
+ if (worker) {
96
+ // Main thread: send to worker
97
+ worker.postMessage(message);
98
+ }
99
+ else {
100
+ // Worker thread: send to main thread
101
+ postMessage(message);
102
+ }
103
+ }).catch(noop);
29
104
  }
30
- [HANDLER] = (event) => {
105
+ /**
106
+ * Handles incoming messages and forwards them to the responses stream
107
+ * @private
108
+ */
109
+ #handler = (event) => {
31
110
  this[RESPONSES$].next(event.data);
32
111
  };
112
+ /**
113
+ * Generates a unique message ID for tracking request-response pairs
114
+ *
115
+ * @returns Unique message identifier
116
+ * @internal Used by @Request decorator
117
+ */
33
118
  [GET_NEW_ID]() {
34
- return uniqueId('hermes-worker-message-' + this[INSTANCE_ID]);
119
+ return uniqueId('hermes-worker-message-' + this.#instanceId);
35
120
  }
36
121
  }
37
122
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../libs/hermes/src/worker/message-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAM5D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAChC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAClC,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAE1C,MAAM,OAAO,mBAAoB,SAAQ,aAAa;IAC7C,CAAC,UAAU,CAAC,GAAG,IAAI,OAAO,EAAmB,CAAC;IAC3C,CAAC,MAAM,CAAC,CAAqB;IAC/B,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEnC,YAAY,MAAe;QACzB,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;QAEtB,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAEM,CAAC,IAAI,CAAC,CAAI,OAAmB;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACL,WAAmB,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAES,CAAC,OAAO,CAAC,GAAG,CAAC,KAAoC,EAAE,EAAE;QAC7D,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAA;IAES,CAAC,UAAU,CAAC;QACpB,OAAO,QAAQ,CAAC,wBAAwB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAW,CAAC;IAC1E,CAAC;CACF","file":"message-client.js","sourcesContent":["import { uniqueId } from \"@thalesrc/js-utils\";\nimport { Subject } from \"rxjs\";\nimport { MessageClient } from \"../message-client\";\nimport { MessageResponse } from \"../message-response.type\";\nimport { Message } from \"../message.interface\";\nimport { GET_NEW_ID, RESPONSES$, SEND } from \"../selectors\";\n\ninterface MessageEvent<T> {\n data: T;\n}\n\nconst WORKER = Symbol('Worker');\nconst HANDLER = Symbol('Handler');\nconst INSTANCE_ID = Symbol('Instance Id');\n\nexport class WorkerMessageClient extends MessageClient {\n public [RESPONSES$] = new Subject<MessageResponse>();\n protected [WORKER]: Worker | undefined;\n private [INSTANCE_ID] = Date.now();\n\n constructor(worker?: Worker) {\n super();\n\n this[WORKER] = worker;\n\n if (worker) {\n worker.addEventListener('message', this[HANDLER]);\n } else {\n addEventListener('message', this[HANDLER]);\n }\n }\n\n public [SEND]<T>(message: Message<T>) {\n if (this[WORKER]) {\n this[WORKER].postMessage(message);\n } else {\n (postMessage as any)(message);\n }\n }\n\n protected [HANDLER] = (event: MessageEvent<MessageResponse>) => {\n this[RESPONSES$].next(event.data);\n }\n\n protected [GET_NEW_ID](): string {\n return uniqueId('hermes-worker-message-' + this[INSTANCE_ID]) as string;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../../../libs/hermes/src/worker/message-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,kCAAkC,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,OAAO,mBAAoB,SAAQ,aAAa;IACpD;;;OAGG;IACH,OAAO,GAAgC,IAAK,CAAC;IAE7C;;;OAGG;IACH,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB;;OAEG;IACI,CAAC,UAAU,CAAC,GAAG,IAAI,OAAO,EAAmB,CAAC;IAErD;;;;;;;;;OASG;IACH,YAAY,MAAgH;QAC1H,KAAK,EAAE,CAAC;QAER,uFAAuF;QACvF,MAAM,OAAO,GAAqD,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAEnH,sEAAsE;QACtE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAElC,kDAAkD;QAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACzB,IAAI,MAAM,EAAE,CAAC;gBACX,iDAAiD;gBACjD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,6DAA6D;gBAC7D,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACI,CAAC,IAAI,CAAC,CAAI,OAAmB;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACzB,IAAI,MAAM,EAAE,CAAC;gBACX,8BAA8B;gBAC9B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,qCAAqC;gBACpC,WAAmB,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC;QACH,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,QAAQ,GAAG,CAAC,KAAoC,EAAE,EAAE;QAClD,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAA;IAED;;;;;OAKG;IACO,CAAC,UAAU,CAAC;QACpB,OAAO,QAAQ,CAAC,wBAAwB,GAAG,IAAI,CAAC,WAAW,CAAW,CAAC;IACzE,CAAC;CACF","file":"message-client.js","sourcesContent":["import { uniqueId } from \"@thalesrc/js-utils/unique-id\";\nimport { noop } from \"@thalesrc/js-utils/function/noop\";\nimport { promisify } from '@thalesrc/js-utils/promise/promisify';\nimport { Subject } from \"rxjs\";\nimport { MessageClient } from \"../message-client\";\nimport { MessageResponse } from \"../message-response.type\";\nimport { Message } from \"../message.interface\";\nimport { GET_NEW_ID, RESPONSES$, SEND } from \"../selectors\";\n\n/**\n * WorkerMessageClient\n *\n * Client implementation for Web Worker communication. Sends messages to and receives\n * responses from Web Workers using the Worker postMessage API.\n *\n * This class can be used in two contexts:\n * - **Main thread**: Provide a Worker instance to communicate with that specific worker\n * - **Worker thread**: Omit the worker parameter to communicate with the main thread via self\n *\n * The worker parameter supports multiple types for flexibility:\n * - Direct Worker instance\n * - Promise that resolves to a Worker (for async worker initialization)\n * - Function that returns a Worker (for lazy initialization)\n * - Function that returns a Promise<Worker> (for async lazy initialization)\n *\n * @example\n * // In main thread - communicate with a specific worker\n * const worker = new Worker('./worker.js');\n * const client = new WorkerMessageClient(worker);\n *\n * @example\n * // In worker thread - communicate with main thread\n * const client = new WorkerMessageClient();\n *\n * @example\n * // With async worker initialization\n * const workerPromise = import('./worker.js').then(m => new m.MyWorker());\n * const client = new WorkerMessageClient(workerPromise);\n *\n * @example\n * // With lazy initialization\n * const client = new WorkerMessageClient(() =>\n * document.querySelector('[data-worker]') ? new Worker('./worker.js') : undefined\n * );\n */\nexport class WorkerMessageClient extends MessageClient {\n /**\n * Promise resolving to the Worker instance or undefined if running in worker context\n * @private\n */\n #worker: Promise<Worker | undefined> = null!;\n\n /**\n * Unique identifier for this client instance to prevent ID collisions\n * @private\n */\n #instanceId = Date.now();\n\n /**\n * Observable stream of message responses from the worker or main thread\n */\n public [RESPONSES$] = new Subject<MessageResponse>();\n\n /**\n * Creates a new WorkerMessageClient instance\n *\n * @param worker - Optional worker configuration:\n * - Worker: Direct worker instance (main thread)\n * - Promise<Worker>: Promise resolving to worker (async initialization)\n * - () => Worker: Function returning worker (lazy initialization)\n * - () => Promise<Worker>: Function returning promise (async lazy initialization)\n * - undefined: Omit for worker thread context (uses self)\n */\n constructor(worker?: Worker | Promise<Worker | undefined> | (() => Worker | undefined) | (() => Promise<Worker | undefined>)) {\n super();\n\n // Resolve worker parameter: execute function if provided, otherwise use value directly\n const _worker: Worker | Promise<Worker | undefined> | undefined = typeof worker === 'function' ? worker() : worker;\n\n // Ensure worker is wrapped in a promise for consistent async handling\n this.#worker = promisify(_worker);\n\n // Set up message listener once worker is resolved\n this.#worker.then(worker => {\n if (worker) {\n // Main thread context: listen to specific worker\n worker.addEventListener('message', this.#handler);\n } else {\n // Worker thread context: listen to messages from main thread\n addEventListener('message', this.#handler);\n }\n }).catch(noop);\n }\n\n /**\n * Sends a message to the worker or main thread\n *\n * @param message - The message to send\n * @template T - Type of the message body\n * @internal Used by @Request decorator\n */\n public [SEND]<T>(message: Message<T>) {\n this.#worker.then(worker => {\n if (worker) {\n // Main thread: send to worker\n worker.postMessage(message);\n } else {\n // Worker thread: send to main thread\n (postMessage as any)(message);\n }\n }).catch(noop);\n }\n\n /**\n * Handles incoming messages and forwards them to the responses stream\n * @private\n */\n #handler = (event: MessageEvent<MessageResponse>) => {\n this[RESPONSES$].next(event.data);\n }\n\n /**\n * Generates a unique message ID for tracking request-response pairs\n *\n * @returns Unique message identifier\n * @internal Used by @Request decorator\n */\n protected [GET_NEW_ID](): string {\n return uniqueId('hermes-worker-message-' + this.#instanceId) as string;\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { WorkerMessageClient } from "./message-client";
2
- declare const WorkerMessageService_base: new (args_0: [worker?: Worker | undefined], args_1: [worker?: Worker | undefined]) => {
2
+ declare const WorkerMessageService_base: new (args_0: [worker?: Worker | undefined], args_1: [worker?: Worker | Promise<Worker | undefined> | (() => Worker | undefined) | (() => Promise<Worker | undefined>) | undefined]) => {
3
3
  terminate: () => void;
4
4
  } & WorkerMessageClient;
5
5
  export declare class WorkerMessageService extends WorkerMessageService_base {