@morgan-stanley/composeui-messaging-client 0.1.0-alpha.10

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 (48) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +152 -0
  3. package/dist/EndpointDescriptor.d.ts +3 -0
  4. package/dist/ErrorNames.d.ts +12 -0
  5. package/dist/InvokeOptions.d.ts +3 -0
  6. package/dist/MessageBuffer.d.ts +1 -0
  7. package/dist/MessageContext.d.ts +4 -0
  8. package/dist/MessageHandler.d.ts +3 -0
  9. package/dist/MessageRouter.d.ts +30 -0
  10. package/dist/MessageRouterError.d.ts +5 -0
  11. package/dist/PublishOptions.d.ts +3 -0
  12. package/dist/TopicMessage.d.ts +7 -0
  13. package/dist/TopicSubscriber.d.ts +3 -0
  14. package/dist/client/Connection.d.ts +12 -0
  15. package/dist/client/Deferred.d.ts +9 -0
  16. package/dist/client/MessageRouterClient.d.ts +58 -0
  17. package/dist/client/MessageRouterOptions.d.ts +3 -0
  18. package/dist/client/index.d.ts +4 -0
  19. package/dist/client/websocket/WebSocketConnection.d.ts +20 -0
  20. package/dist/client/websocket/WebSocketOptions.d.ts +3 -0
  21. package/dist/client/websocket/index.d.ts +2 -0
  22. package/dist/exceptions/ThrowHelper.d.ts +11 -0
  23. package/dist/exceptions/index.d.ts +1 -0
  24. package/dist/index.d.ts +11 -0
  25. package/dist/index.js +756 -0
  26. package/dist/protocol/Error.d.ts +5 -0
  27. package/dist/protocol/index.d.ts +1 -0
  28. package/dist/protocol/messages/AbstractRequest.d.ts +4 -0
  29. package/dist/protocol/messages/AbstractResponse.d.ts +7 -0
  30. package/dist/protocol/messages/ConnectRequest.d.ts +6 -0
  31. package/dist/protocol/messages/ConnectResponse.d.ts +8 -0
  32. package/dist/protocol/messages/InvokeRequest.d.ts +12 -0
  33. package/dist/protocol/messages/InvokeResponse.d.ts +8 -0
  34. package/dist/protocol/messages/Message.d.ts +4 -0
  35. package/dist/protocol/messages/MessageType.d.ts +1 -0
  36. package/dist/protocol/messages/PublishMessage.d.ts +11 -0
  37. package/dist/protocol/messages/PublishResponse.d.ts +4 -0
  38. package/dist/protocol/messages/RegisterServiceRequest.d.ts +10 -0
  39. package/dist/protocol/messages/RegisterServiceResponse.d.ts +6 -0
  40. package/dist/protocol/messages/SubscribeMessage.d.ts +8 -0
  41. package/dist/protocol/messages/SubscribeResponse.d.ts +4 -0
  42. package/dist/protocol/messages/TopicMessage.d.ts +10 -0
  43. package/dist/protocol/messages/UnregisterServiceRequest.d.ts +8 -0
  44. package/dist/protocol/messages/UnregisterServiceResponse.d.ts +6 -0
  45. package/dist/protocol/messages/UnsubscribeMessage.d.ts +8 -0
  46. package/dist/protocol/messages/UnsubscribeResponse.d.ts +4 -0
  47. package/dist/protocol/messages/index.d.ts +19 -0
  48. package/package.json +50 -0
package/dist/index.js ADDED
@@ -0,0 +1,756 @@
1
+
2
+ /**
3
+ * @license
4
+ * author: Morgan Stanley
5
+ * composeui-messaging-client.js v0.1.0-alpha.10
6
+ * Released under the Apache-2.0 license.
7
+ */
8
+
9
+ /*
10
+ * Morgan Stanley makes this available to you under the Apache License,
11
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
12
+ * http://www.apache.org/licenses/LICENSE-2.0.
13
+ * See the NOTICE file distributed with this work for additional information
14
+ * regarding copyright ownership. Unless required by applicable law or agreed
15
+ * to in writing, software distributed under the License is distributed on an
16
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
+ * or implied. See the License for the specific language governing permissions
18
+ * and limitations under the License.
19
+ *
20
+ */
21
+ const ErrorNames = {
22
+ duplicateEndpoint: "DuplicateEndpoint",
23
+ duplicateRequestId: "DuplicateRequestId",
24
+ invalidEndpoint: "InvalidEndpoint",
25
+ invalidTopic: "InvalidTopic",
26
+ unknownEndpoint: "UnknownEndpoint",
27
+ unknownClient: "UnknownClient",
28
+ connectionClosed: "ConnectionClosed",
29
+ connectionAborted: "ConnectionAborted",
30
+ invalidAccessToken: "InvalidAccessToken",
31
+ connectionFailed: "ConnectionFailed",
32
+ };
33
+
34
+ /*
35
+ * Morgan Stanley makes this available to you under the Apache License,
36
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
37
+ * http://www.apache.org/licenses/LICENSE-2.0.
38
+ * See the NOTICE file distributed with this work for additional information
39
+ * regarding copyright ownership. Unless required by applicable law or agreed
40
+ * to in writing, software distributed under the License is distributed on an
41
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
42
+ * or implied. See the License for the specific language governing permissions
43
+ * and limitations under the License.
44
+ *
45
+ */
46
+ class WebSocketConnection {
47
+ options;
48
+ constructor(options) {
49
+ this.options = options;
50
+ }
51
+ connect() {
52
+ return new Promise((resolve, reject) => {
53
+ this.websocket = new WebSocket(this.options.url);
54
+ this.websocket.addEventListener('open', () => {
55
+ this.isConnected = true;
56
+ resolve();
57
+ });
58
+ this.websocket.addEventListener('message', ev => {
59
+ const message = WebSocketConnection.deserializeMessage(ev.data);
60
+ this._onMessage?.call(undefined, message);
61
+ });
62
+ this.websocket.addEventListener('error', ev => {
63
+ if (!this.isConnected) {
64
+ reject();
65
+ }
66
+ else {
67
+ this.isConnected = false;
68
+ this._onError?.call(undefined, new Error());
69
+ }
70
+ });
71
+ this.websocket.addEventListener('close', () => {
72
+ this.isConnected = false;
73
+ delete this.websocket;
74
+ this._onClose?.call(undefined);
75
+ });
76
+ });
77
+ }
78
+ send(message) {
79
+ if (!this.websocket) {
80
+ return Promise.reject();
81
+ }
82
+ this.websocket.send(JSON.stringify(message));
83
+ return Promise.resolve();
84
+ }
85
+ close() {
86
+ if (this.isConnected) {
87
+ this.websocket?.close(1000, "Closed by client");
88
+ this.isConnected = false;
89
+ delete this.websocket;
90
+ }
91
+ return Promise.resolve();
92
+ }
93
+ onMessage(callback) {
94
+ this._onMessage = callback;
95
+ }
96
+ onError(callback) {
97
+ this._onError = callback;
98
+ }
99
+ onClose(callback) {
100
+ this._onClose = callback;
101
+ }
102
+ static deserializeMessage(data) {
103
+ const msg = JSON.parse(data);
104
+ return msg;
105
+ }
106
+ websocket;
107
+ isConnected = false;
108
+ messageQueue = [];
109
+ _onMessage;
110
+ _onError;
111
+ _onClose;
112
+ }
113
+
114
+ /*
115
+ * Morgan Stanley makes this available to you under the Apache License,
116
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
117
+ * http://www.apache.org/licenses/LICENSE-2.0.
118
+ * See the NOTICE file distributed with this work for additional information
119
+ * regarding copyright ownership. Unless required by applicable law or agreed
120
+ * to in writing, software distributed under the License is distributed on an
121
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
122
+ * or implied. See the License for the specific language governing permissions
123
+ * and limitations under the License.
124
+ *
125
+ */
126
+ class Deferred {
127
+ constructor() {
128
+ this.promise = new Promise((resolve, reject) => {
129
+ this.resolve =
130
+ (value) => {
131
+ this.settle();
132
+ resolve(value);
133
+ };
134
+ this.reject =
135
+ (reason) => {
136
+ this.settle();
137
+ reject(reason);
138
+ };
139
+ });
140
+ }
141
+ resolve = () => { };
142
+ reject = () => { };
143
+ promise;
144
+ settle() {
145
+ const noop = () => { };
146
+ this.resolve = noop;
147
+ this.reject = noop;
148
+ }
149
+ }
150
+
151
+ /*
152
+ * Morgan Stanley makes this available to you under the Apache License,
153
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
154
+ * http://www.apache.org/licenses/LICENSE-2.0.
155
+ * See the NOTICE file distributed with this work for additional information
156
+ * regarding copyright ownership. Unless required by applicable law or agreed
157
+ * to in writing, software distributed under the License is distributed on an
158
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
159
+ * or implied. See the License for the specific language governing permissions
160
+ * and limitations under the License.
161
+ *
162
+ */
163
+ function isProtocolError(err) {
164
+ return (typeof err === "object") && ("name" in err);
165
+ }
166
+
167
+ /*
168
+ * Morgan Stanley makes this available to you under the Apache License,
169
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
170
+ * http://www.apache.org/licenses/LICENSE-2.0.
171
+ * See the NOTICE file distributed with this work for additional information
172
+ * regarding copyright ownership. Unless required by applicable law or agreed
173
+ * to in writing, software distributed under the License is distributed on an
174
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
175
+ * or implied. See the License for the specific language governing permissions
176
+ * and limitations under the License.
177
+ *
178
+ */
179
+ class MessageRouterError extends Error {
180
+ constructor(err, message, stack) {
181
+ let [name, msg] = isProtocolError(err) ? [err.name, err.message] : [err, message];
182
+ super(msg);
183
+ this.name = name;
184
+ if (stack) {
185
+ this.stack = stack;
186
+ }
187
+ }
188
+ }
189
+ function createProtocolError(err) {
190
+ if (typeof err === "string")
191
+ return {
192
+ name: "Error",
193
+ message: err
194
+ };
195
+ return {
196
+ name: err.name ?? "Error",
197
+ message: err.message ?? `Unknown error (${err})`
198
+ };
199
+ }
200
+
201
+ /*
202
+ * Morgan Stanley makes this available to you under the Apache License,
203
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
204
+ * http://www.apache.org/licenses/LICENSE-2.0.
205
+ * See the NOTICE file distributed with this work for additional information
206
+ * regarding copyright ownership. Unless required by applicable law or agreed
207
+ * to in writing, software distributed under the License is distributed on an
208
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
209
+ * or implied. See the License for the specific language governing permissions
210
+ * and limitations under the License.
211
+ *
212
+ */
213
+ class ThrowHelper {
214
+ static duplicateEndpoint(endpoint) {
215
+ return new MessageRouterError({ name: ErrorNames.duplicateEndpoint, message: `Duplicate endpoint registration: '${endpoint}'` });
216
+ }
217
+ static duplicateRequestId() {
218
+ return new MessageRouterError({ name: ErrorNames.duplicateRequestId, message: "Duplicate request ID" });
219
+ }
220
+ static invalidEndpoint(endpoint) {
221
+ return new MessageRouterError({ name: ErrorNames.invalidEndpoint, message: `Invalid endpoint: '${endpoint}'` });
222
+ }
223
+ static invalidTopic(topic) {
224
+ return new MessageRouterError({ name: ErrorNames.invalidTopic, message: `Invalid topic: '${topic}'` });
225
+ }
226
+ static unknownEndpoint(endpoint) {
227
+ return new MessageRouterError({ name: ErrorNames.unknownEndpoint, message: `Unknown endpoint: ${endpoint}` });
228
+ }
229
+ static connectionClosed() {
230
+ return new MessageRouterError({ name: ErrorNames.connectionClosed, message: "The connection has been closed" });
231
+ }
232
+ static connectionFailed(message) {
233
+ return new MessageRouterError({ name: ErrorNames.connectionFailed, message: `Connection failed with message ${message}` });
234
+ }
235
+ static connectionAborted() {
236
+ return new MessageRouterError({ name: ErrorNames.connectionAborted, message: "The connection dropped unexpectedly" });
237
+ }
238
+ }
239
+
240
+ /*
241
+ * Morgan Stanley makes this available to you under the Apache License,
242
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
243
+ * http://www.apache.org/licenses/LICENSE-2.0.
244
+ * See the NOTICE file distributed with this work for additional information
245
+ * regarding copyright ownership. Unless required by applicable law or agreed
246
+ * to in writing, software distributed under the License is distributed on an
247
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
248
+ * or implied. See the License for the specific language governing permissions
249
+ * and limitations under the License.
250
+ *
251
+ */
252
+ function isResponse(message) {
253
+ return (message.type === "InvokeResponse"
254
+ || message.type === "RegisterServiceResponse"
255
+ || message.type === "UnregisterServiceResponse"
256
+ || message.type === "SubscribeResponse"
257
+ || message.type === "UnsubscribeResponse"
258
+ || message.type === "PublishResponse");
259
+ }
260
+
261
+ /*
262
+ * Morgan Stanley makes this available to you under the Apache License,
263
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
264
+ * http://www.apache.org/licenses/LICENSE-2.0.
265
+ * See the NOTICE file distributed with this work for additional information
266
+ * regarding copyright ownership. Unless required by applicable law or agreed
267
+ * to in writing, software distributed under the License is distributed on an
268
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
269
+ * or implied. See the License for the specific language governing permissions
270
+ * and limitations under the License.
271
+ *
272
+ */
273
+ function isConnectResponse(message) {
274
+ return message.type == "ConnectResponse";
275
+ }
276
+
277
+ /*
278
+ * Morgan Stanley makes this available to you under the Apache License,
279
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
280
+ * http://www.apache.org/licenses/LICENSE-2.0.
281
+ * See the NOTICE file distributed with this work for additional information
282
+ * regarding copyright ownership. Unless required by applicable law or agreed
283
+ * to in writing, software distributed under the License is distributed on an
284
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
285
+ * or implied. See the License for the specific language governing permissions
286
+ * and limitations under the License.
287
+ *
288
+ */
289
+ function isInvokeRequest(message) {
290
+ return message.type == "Invoke";
291
+ }
292
+
293
+ /*
294
+ * Morgan Stanley makes this available to you under the Apache License,
295
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
296
+ * http://www.apache.org/licenses/LICENSE-2.0.
297
+ * See the NOTICE file distributed with this work for additional information
298
+ * regarding copyright ownership. Unless required by applicable law or agreed
299
+ * to in writing, software distributed under the License is distributed on an
300
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
301
+ * or implied. See the License for the specific language governing permissions
302
+ * and limitations under the License.
303
+ *
304
+ */
305
+ function isTopicMessage(message) {
306
+ return message.type == "Topic";
307
+ }
308
+
309
+ /*
310
+ * Morgan Stanley makes this available to you under the Apache License,
311
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
312
+ * http://www.apache.org/licenses/LICENSE-2.0.
313
+ * See the NOTICE file distributed with this work for additional information
314
+ * regarding copyright ownership. Unless required by applicable law or agreed
315
+ * to in writing, software distributed under the License is distributed on an
316
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
317
+ * or implied. See the License for the specific language governing permissions
318
+ * and limitations under the License.
319
+ *
320
+ */
321
+ var ClientState;
322
+ (function (ClientState) {
323
+ ClientState[ClientState["Created"] = 0] = "Created";
324
+ ClientState[ClientState["Connecting"] = 1] = "Connecting";
325
+ ClientState[ClientState["Connected"] = 2] = "Connected";
326
+ ClientState[ClientState["Closing"] = 3] = "Closing";
327
+ ClientState[ClientState["Closed"] = 4] = "Closed";
328
+ })(ClientState || (ClientState = {}));
329
+ class MessageRouterClient {
330
+ connection;
331
+ options;
332
+ constructor(connection, options) {
333
+ this.connection = connection;
334
+ this.options = options;
335
+ this.options = options ?? {};
336
+ }
337
+ _clientId;
338
+ get clientId() {
339
+ return this._clientId;
340
+ }
341
+ connect() {
342
+ switch (this._state) {
343
+ case ClientState.Connected:
344
+ return Promise.resolve();
345
+ case ClientState.Created:
346
+ return this.connectCore();
347
+ case ClientState.Connecting:
348
+ return this.connected.promise;
349
+ }
350
+ return Promise.reject(ThrowHelper.connectionClosed());
351
+ }
352
+ close() {
353
+ return this.closeCore();
354
+ }
355
+ async subscribe(topicName, subscriber) {
356
+ this.checkState();
357
+ if (this.pendingUnsubscriptions[topicName]) {
358
+ await this.pendingUnsubscriptions[topicName];
359
+ }
360
+ let needsSubscription = false;
361
+ let topic = this.topics[topicName];
362
+ if (!topic) {
363
+ this.topics[topicName] = topic = new Topic(() => this.unsubscribe(topicName));
364
+ needsSubscription = true;
365
+ }
366
+ if (typeof subscriber === "function") {
367
+ subscriber = { next: subscriber };
368
+ }
369
+ const subscription = topic.subscribe(subscriber);
370
+ if (needsSubscription) {
371
+ try {
372
+ await this.sendRequest({
373
+ requestId: this.getRequestId(),
374
+ type: "Subscribe",
375
+ topic: topicName
376
+ });
377
+ }
378
+ catch (error) {
379
+ delete this.topics[topicName];
380
+ throw error;
381
+ }
382
+ }
383
+ return subscription;
384
+ }
385
+ async publish(topic, payload, options) {
386
+ this.checkState();
387
+ await this.sendRequest({
388
+ type: "Publish",
389
+ requestId: this.getRequestId(),
390
+ topic,
391
+ payload,
392
+ correlationId: options?.correlationId
393
+ });
394
+ }
395
+ async invoke(endpoint, payload, options) {
396
+ this.checkState();
397
+ const response = await this.sendRequest({
398
+ type: "Invoke",
399
+ requestId: this.getRequestId(),
400
+ endpoint,
401
+ payload,
402
+ correlationId: options?.correlationId
403
+ });
404
+ return response.payload;
405
+ }
406
+ async registerService(endpoint, handler, descriptor) {
407
+ this.checkState();
408
+ if (this.endpointHandlers[endpoint])
409
+ throw ThrowHelper.duplicateEndpoint(endpoint);
410
+ this.endpointHandlers[endpoint] = handler;
411
+ try {
412
+ await this.sendRequest({
413
+ type: "RegisterService",
414
+ requestId: this.getRequestId(),
415
+ endpoint,
416
+ descriptor
417
+ });
418
+ }
419
+ catch (error) {
420
+ delete this.endpointHandlers[endpoint];
421
+ throw error;
422
+ }
423
+ }
424
+ async unregisterService(endpoint) {
425
+ this.checkState();
426
+ if (!this.endpointHandlers[endpoint])
427
+ return;
428
+ await this.sendRequest({
429
+ type: "UnregisterService",
430
+ requestId: this.getRequestId(),
431
+ endpoint
432
+ });
433
+ delete this.endpointHandlers[endpoint];
434
+ }
435
+ registerEndpoint(endpoint, handler, descriptor) {
436
+ this.checkState();
437
+ if (this.endpointHandlers[endpoint])
438
+ throw ThrowHelper.duplicateEndpoint(endpoint);
439
+ this.endpointHandlers[endpoint] = handler;
440
+ return Promise.resolve();
441
+ }
442
+ unregisterEndpoint(endpoint) {
443
+ this.checkState();
444
+ delete this.endpointHandlers[endpoint];
445
+ return Promise.resolve();
446
+ }
447
+ get state() {
448
+ return this._state;
449
+ }
450
+ _state = ClientState.Created;
451
+ lastRequestId = 0;
452
+ topics = {};
453
+ connected = new Deferred();
454
+ closed = new Deferred();
455
+ pendingRequests = {};
456
+ endpointHandlers = {};
457
+ pendingUnsubscriptions = {};
458
+ async connectCore() {
459
+ this._state = ClientState.Connecting;
460
+ try {
461
+ this.connection.onMessage(this.handleMessage.bind(this));
462
+ this.connection.onError(this.handleError.bind(this));
463
+ this.connection.onClose(this.handleClose.bind(this));
464
+ await this.connection.connect();
465
+ const req = {
466
+ type: "Connect",
467
+ accessToken: this.options.accessToken
468
+ };
469
+ await this.connection.send(req);
470
+ // This must be the last statement before catch so that awaiting `connected`
471
+ // has the same effect as awaiting `connect()`. `close()` also rejects this promise.
472
+ await this.connected.promise;
473
+ }
474
+ catch (error) {
475
+ if (error instanceof MessageRouterError) {
476
+ throw error;
477
+ }
478
+ else {
479
+ await this.closeCore(error);
480
+ throw ThrowHelper.connectionFailed(error.message || error);
481
+ }
482
+ }
483
+ }
484
+ async closeCore(error) {
485
+ error ??= ThrowHelper.connectionClosed();
486
+ switch (this._state) {
487
+ case ClientState.Created:
488
+ {
489
+ this._state = ClientState.Closed;
490
+ return;
491
+ }
492
+ case ClientState.Closed:
493
+ return;
494
+ case ClientState.Closing:
495
+ await this.closed.promise;
496
+ return;
497
+ case ClientState.Connecting:
498
+ {
499
+ this._state = ClientState.Closed;
500
+ this.connected.reject(ThrowHelper.connectionClosed());
501
+ return;
502
+ }
503
+ }
504
+ this._state = ClientState.Closing;
505
+ this.failPendingRequests(error);
506
+ this.failSubscribers(error);
507
+ try {
508
+ await this.connection.close();
509
+ }
510
+ catch (e) {
511
+ console.error(e);
512
+ }
513
+ this._state = ClientState.Closed;
514
+ this.closed.resolve();
515
+ }
516
+ failPendingRequests(error) {
517
+ for (let requestId in this.pendingRequests) {
518
+ this.pendingRequests[requestId].reject(error);
519
+ delete this.pendingRequests[requestId];
520
+ }
521
+ }
522
+ async failSubscribers(error) {
523
+ for (let topicName in this.topics) {
524
+ const topic = this.topics[topicName];
525
+ topic.error(error);
526
+ }
527
+ }
528
+ async sendMessage(message) {
529
+ await this.connect();
530
+ await this.connection.send(message);
531
+ }
532
+ async sendRequest(request) {
533
+ const deferred = this.pendingRequests[request.requestId] = new Deferred();
534
+ try {
535
+ await this.sendMessage(request);
536
+ }
537
+ catch (error) {
538
+ delete this.pendingRequests[request.requestId];
539
+ throw error;
540
+ }
541
+ return await deferred.promise;
542
+ }
543
+ handleMessage(message) {
544
+ if (isTopicMessage(message)) {
545
+ this.handleTopicMessage(message);
546
+ return;
547
+ }
548
+ if (isResponse(message)) {
549
+ this.handleResponse(message);
550
+ return;
551
+ }
552
+ if (isInvokeRequest(message)) {
553
+ this.handleInvokeRequest(message);
554
+ return;
555
+ }
556
+ if (isConnectResponse(message)) {
557
+ this.handleConnectResponse(message);
558
+ return;
559
+ }
560
+ }
561
+ handleTopicMessage(message) {
562
+ const topic = this.topics[message.topic];
563
+ if (!topic)
564
+ return;
565
+ topic.next({
566
+ topic: message.topic,
567
+ payload: message.payload,
568
+ context: {
569
+ sourceId: message.sourceId,
570
+ correlationId: message.correlationId
571
+ }
572
+ });
573
+ }
574
+ handleResponse(message) {
575
+ const request = this.pendingRequests[message.requestId];
576
+ if (!request)
577
+ return;
578
+ if (message.error) {
579
+ request.reject(new MessageRouterError(message.error));
580
+ }
581
+ else {
582
+ request.resolve(message);
583
+ }
584
+ }
585
+ async handleInvokeRequest(message) {
586
+ try {
587
+ const handler = this.endpointHandlers[message.endpoint];
588
+ if (!handler)
589
+ throw ThrowHelper.unknownEndpoint(message.endpoint);
590
+ const result = await handler(message.endpoint, message.payload, {
591
+ sourceId: message.sourceId,
592
+ correlationId: message.correlationId
593
+ });
594
+ await this.sendMessage({
595
+ type: "InvokeResponse",
596
+ requestId: message.requestId,
597
+ payload: typeof result === "string" ? result : undefined
598
+ });
599
+ }
600
+ catch (error) {
601
+ await this.sendMessage({
602
+ type: "InvokeResponse",
603
+ requestId: message.requestId,
604
+ error: createProtocolError(error)
605
+ });
606
+ }
607
+ }
608
+ handleConnectResponse(message) {
609
+ if (message.error) {
610
+ this._state = ClientState.Closed;
611
+ this.connected.reject(new MessageRouterError(message.error));
612
+ }
613
+ else {
614
+ this._clientId = message.clientId;
615
+ this._state = ClientState.Connected;
616
+ this.connected.resolve();
617
+ }
618
+ }
619
+ checkState() {
620
+ if (this._state == ClientState.Closed || this._state == ClientState.Closing) {
621
+ throw ThrowHelper.connectionClosed();
622
+ }
623
+ }
624
+ handleError(error) {
625
+ switch (this._state) {
626
+ case ClientState.Closing:
627
+ case ClientState.Closed:
628
+ return;
629
+ }
630
+ this.closeCore(error);
631
+ }
632
+ handleClose() {
633
+ this.handleError(ThrowHelper.connectionAborted());
634
+ }
635
+ async unsubscribe(topicName) {
636
+ let topic = this.topics[topicName];
637
+ if (!topic)
638
+ return;
639
+ if (this.pendingUnsubscriptions[topicName]) {
640
+ await this.pendingUnsubscriptions[topicName];
641
+ }
642
+ this.pendingUnsubscriptions[topicName] = this.sendRequest({
643
+ requestId: this.getRequestId(),
644
+ type: "Unsubscribe",
645
+ topic: topicName
646
+ })
647
+ .then(() => {
648
+ delete this.topics[topicName];
649
+ })
650
+ .catch(error => {
651
+ console.error("Exception thrown while unsubscribing.", error);
652
+ throw error;
653
+ })
654
+ .finally(() => {
655
+ delete this.pendingUnsubscriptions[topicName];
656
+ });
657
+ await this.pendingUnsubscriptions[topicName];
658
+ }
659
+ getRequestId() {
660
+ return '' + (++this.lastRequestId);
661
+ }
662
+ }
663
+ class Topic {
664
+ constructor(onUnsubscribe) {
665
+ this.onUnsubscribe = onUnsubscribe;
666
+ }
667
+ subscribe(subscriber) {
668
+ if (this.isCompleted)
669
+ return {
670
+ unsubscribe: () => { }
671
+ };
672
+ this.subscribers.push(subscriber);
673
+ return {
674
+ unsubscribe: () => this.unsubscribe(subscriber)
675
+ };
676
+ }
677
+ unsubscribe(subscriber) {
678
+ if (this.isCompleted)
679
+ return;
680
+ const idx = this.subscribers.lastIndexOf(subscriber);
681
+ if (idx < 0)
682
+ return;
683
+ this.subscribers.splice(idx, 1);
684
+ if (this.subscribers.length == 0) {
685
+ this.onUnsubscribe();
686
+ }
687
+ }
688
+ next(message) {
689
+ if (this.isCompleted) {
690
+ return;
691
+ }
692
+ for (let subscriber of this.subscribers) {
693
+ try {
694
+ subscriber.next?.call(subscriber, message);
695
+ }
696
+ catch (error) {
697
+ console.error(error);
698
+ }
699
+ }
700
+ }
701
+ error(error) {
702
+ if (this.isCompleted)
703
+ return;
704
+ this.isCompleted = true;
705
+ for (let subscriber of this.subscribers) {
706
+ try {
707
+ subscriber.error?.call(subscriber, error);
708
+ }
709
+ catch (e) {
710
+ console.error(e);
711
+ }
712
+ }
713
+ }
714
+ complete() {
715
+ if (this.isCompleted)
716
+ return;
717
+ for (let subscriber of this.subscribers) {
718
+ try {
719
+ subscriber.complete?.call(subscriber);
720
+ }
721
+ catch (e) {
722
+ console.error(e);
723
+ }
724
+ }
725
+ }
726
+ isCompleted = false;
727
+ onUnsubscribe;
728
+ subscribers = [];
729
+ }
730
+
731
+ /*
732
+ * Morgan Stanley makes this available to you under the Apache License,
733
+ * Version 2.0 (the "License"). You may obtain a copy of the License at
734
+ * http://www.apache.org/licenses/LICENSE-2.0.
735
+ * See the NOTICE file distributed with this work for additional information
736
+ * regarding copyright ownership. Unless required by applicable law or agreed
737
+ * to in writing, software distributed under the License is distributed on an
738
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
739
+ * or implied. See the License for the specific language governing permissions
740
+ * and limitations under the License.
741
+ *
742
+ */
743
+ function createMessageRouter(config) {
744
+ config ??= window.composeui?.messageRouterConfig;
745
+ if (config?.webSocket) {
746
+ const connection = new WebSocketConnection(config.webSocket);
747
+ return new MessageRouterClient(connection, config);
748
+ }
749
+ throw ConfigNotFound();
750
+ function ConfigNotFound() {
751
+ return new Error("Unable to create the MessageRouter client, configuration is missing.");
752
+ }
753
+ }
754
+
755
+ export { ErrorNames, MessageRouterError, createMessageRouter, createProtocolError };
756
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi4uL3NyYy9FcnJvck5hbWVzLnRzIiwiLi4vc3JjL2NsaWVudC93ZWJzb2NrZXQvV2ViU29ja2V0Q29ubmVjdGlvbi50cyIsIi4uL3NyYy9jbGllbnQvRGVmZXJyZWQudHMiLCIuLi9zcmMvcHJvdG9jb2wvRXJyb3IudHMiLCIuLi9zcmMvTWVzc2FnZVJvdXRlckVycm9yLnRzIiwiLi4vc3JjL2V4Y2VwdGlvbnMvVGhyb3dIZWxwZXIudHMiLCIuLi9zcmMvcHJvdG9jb2wvbWVzc2FnZXMvQWJzdHJhY3RSZXNwb25zZS50cyIsIi4uL3NyYy9wcm90b2NvbC9tZXNzYWdlcy9Db25uZWN0UmVzcG9uc2UudHMiLCIuLi9zcmMvcHJvdG9jb2wvbWVzc2FnZXMvSW52b2tlUmVxdWVzdC50cyIsIi4uL3NyYy9wcm90b2NvbC9tZXNzYWdlcy9Ub3BpY01lc3NhZ2UudHMiLCIuLi9zcmMvY2xpZW50L01lc3NhZ2VSb3V0ZXJDbGllbnQudHMiLCIuLi9zcmMvTWVzc2FnZVJvdXRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6W251bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSwibmFtZXMiOlsibWVzc2FnZXMuaXNUb3BpY01lc3NhZ2UiLCJtZXNzYWdlcy5pc1Jlc3BvbnNlIiwibWVzc2FnZXMuaXNJbnZva2VSZXF1ZXN0IiwibWVzc2FnZXMuaXNDb25uZWN0UmVzcG9uc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7Ozs7Ozs7O0FBV0c7QUFFSSxNQUFNLFVBQVUsR0FBRztBQUN0QixJQUFBLGlCQUFpQixFQUFFLG1CQUFtQjtBQUN0QyxJQUFBLGtCQUFrQixFQUFFLG9CQUFvQjtBQUN4QyxJQUFBLGVBQWUsRUFBRSxpQkFBaUI7QUFDbEMsSUFBQSxZQUFZLEVBQUUsY0FBYztBQUM1QixJQUFBLGVBQWUsRUFBRSxpQkFBaUI7QUFDbEMsSUFBQSxhQUFhLEVBQUUsZUFB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