@pulse-editor/shared-utils 0.1.1-beta.1 → 0.1.1-beta.56

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.
@@ -2,17 +2,28 @@ import { IMCMessageTypeEnum, ReceiverHandlerMap } from "../types/types";
2
2
  export declare class InterModuleCommunication {
3
3
  private thisWindow;
4
4
  private otherWindow;
5
- private thisPendingTasks;
6
- private otherPendingMessages;
7
5
  private receiver;
8
6
  private sender;
9
- private moduleName;
7
+ private thisWindowId;
8
+ private otherWindowId;
10
9
  private receiverHandlerMap;
11
10
  private listener;
12
- constructor(moduleName: string);
13
- initThisWindow(window: Window): void;
14
- initOtherWindow(window: Window): void;
11
+ private messageRecords;
12
+ intent: string | undefined;
13
+ channelId: string | undefined;
14
+ constructor(intent: string | undefined, channelId: string | undefined);
15
+ /**
16
+ * Initialize a receiver to receive message.
17
+ * @param window The current window.
18
+ * @param otherWindowId The ID of the other window. This is optional and can be undefined.
19
+ * When defined, the receiver will only receive messages from window with the ID.
20
+ */
21
+ initThisWindow(window: Window, otherWindowId?: string): void;
22
+ initOtherWindow(window: Window): Promise<void>;
15
23
  close(): void;
16
24
  sendMessage(type: IMCMessageTypeEnum, payload?: any, abortSignal?: AbortSignal): Promise<any>;
17
25
  updateReceiverHandlerMap(receiverHandlerMap: ReceiverHandlerMap): void;
26
+ getThisWindowId(): string;
27
+ getOtherWindowId(): string;
28
+ private setBaseHandler;
18
29
  }
@@ -2,10 +2,10 @@ import { IMCMessage, ReceiverHandlerMap } from "../types/types";
2
2
  export declare class MessageReceiver {
3
3
  private handlerMap;
4
4
  private pendingTasks;
5
- private moduleName;
6
- constructor(listenerMap: ReceiverHandlerMap, pendingTasks: Map<string, {
7
- controller: AbortController;
8
- }>, moduleInfo: string);
5
+ private windowId;
6
+ private intent;
7
+ constructor(listenerMap: ReceiverHandlerMap, windowId: string, intent: string | undefined);
9
8
  receiveMessage(senderWindow: Window, message: IMCMessage): void;
10
9
  private acknowledgeSender;
10
+ private ignoreSender;
11
11
  }
@@ -3,10 +3,12 @@ export declare class MessageSender {
3
3
  private targetWindow;
4
4
  private timeout;
5
5
  private pendingMessages;
6
- private moduleName;
7
- constructor(targetWindow: Window, timeout: number, pendingMessages: Map<string, {
8
- resolve: (result: any) => void;
9
- reject: () => void;
10
- }>, moduleInfo: string);
6
+ private moduleId;
7
+ private channelId;
8
+ constructor(targetWindow: Window, timeout: number, moduleId: string, channelId?: string);
11
9
  sendMessage(handlingType: IMCMessageTypeEnum, payload?: any, abortSignal?: AbortSignal): Promise<any>;
10
+ getPendingMessage(id: string): {
11
+ resolve: (value: any) => void;
12
+ reject: (reason: any) => void;
13
+ } | undefined;
12
14
  }
@@ -0,0 +1,44 @@
1
+ import { IMCMessage, IMCMessageTypeEnum, ReceiverHandlerMap } from "../types/types";
2
+ /**
3
+ * Poly IMC establishes two-way inter-module communication channels,
4
+ * where each channel consists of a sender and a receiver to send and
5
+ * receive messages between host window and the other module's window.
6
+ *
7
+ * This assumes the other window has IMC or Poly-IMC setup.
8
+ */
9
+ export declare class PolyIMC {
10
+ private channelsMap;
11
+ private baseReceiverHandlerMap;
12
+ private channelReceiverHandlerMapMap;
13
+ /**
14
+ *
15
+ * @param baseReceiverHandlerMap A base receiver handler map for universal handlers.
16
+ * E.g. Pulse Editor API handler
17
+ */
18
+ constructor(baseReceiverHandlerMap: ReceiverHandlerMap);
19
+ sendMessage(targetWindowId: string, handlingType: IMCMessageTypeEnum, payload?: any, abortSignal?: AbortSignal): Promise<any[]>;
20
+ updateBaseReceiverHandlerMap(handlerMap: ReceiverHandlerMap): void;
21
+ updateChannelReceiverHandlerMap(targetWindowId: string, handlerMap: ReceiverHandlerMap): void;
22
+ createChannel(targetWindow: Window, targetWindowId: string, intent: string, channelId?: string, receiverHandlerMap?: ReceiverHandlerMap): Promise<void>;
23
+ removeWindowChannels(targetWindowId: string): void;
24
+ hasChannel(targetWindowId: string): boolean;
25
+ close(): void;
26
+ private getCombinedHandlerMap;
27
+ }
28
+ export declare class ConnectionListener {
29
+ private polyIMC;
30
+ private newConnectionReceiverHandlerMap;
31
+ private onConnection?;
32
+ private listener;
33
+ /**
34
+ *
35
+ * @param polyIMC The polyIMC instance.
36
+ * @param newConnectionReceiverHandlerMap Receiver handler map for newly established poly-IMC channel.
37
+ * @param onConnection Callback function to be called when a new connection is established.
38
+ * @param expectedOtherWindowId Optional expected other window ID to validate incoming connections.
39
+ */
40
+ constructor(polyIMC: PolyIMC, newConnectionReceiverHandlerMap: ReceiverHandlerMap, onConnection?: (senderWindow: Window, message: IMCMessage) => void, expectedOtherWindowId?: string);
41
+ close(): void;
42
+ updateReceiverHandlerMap(newReceiverHandlerMap: ReceiverHandlerMap): void;
43
+ private handleExtReady;
44
+ }
package/dist/main.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- export * from "./imc/inter-module-communication";
2
- export * from "./imc/message-sender";
3
- export * from "./imc/message-receiver";
4
- export * from "./types/types";
1
+ import { InterModuleCommunication } from "./imc/inter-module-communication";
2
+ import { MessageReceiver } from "./imc/message-receiver";
3
+ import { MessageSender } from "./imc/message-sender";
4
+ import { ConnectionListener, PolyIMC } from "./imc/poly-imc";
5
5
  export * from "./types/constants";
6
+ export * from "./types/types";
7
+ export { ConnectionListener, InterModuleCommunication, MessageReceiver, MessageSender, PolyIMC, };
package/dist/main.js CHANGED
@@ -1 +1,652 @@
1
- export{InterModuleCommunication}from"./imc/inter-module-communication.js";export{MessageSender}from"./imc/message-sender.js";export{MessageReceiver}from"./imc/message-receiver.js";export{AccessEnum,ExtensionTypeEnum,IMCMessageTypeEnum,NotificationTypeEnum}from"./types/types.js";export{messageTimeout}from"./types/constants.js";
1
+ const messageTimeout = 300000;
2
+
3
+ // #region Inter-Module Communication
4
+ /* Inter Module Communication messages */
5
+ var IMCMessageTypeEnum;
6
+ (function (IMCMessageTypeEnum) {
7
+ // #region AI modality tools
8
+ IMCMessageTypeEnum["ModalityVAD"] = "modality-vad";
9
+ IMCMessageTypeEnum["ModalitySTT"] = "modality-stt";
10
+ IMCMessageTypeEnum["ModalityLLM"] = "modality-llm";
11
+ IMCMessageTypeEnum["ModalityTTS"] = "modality-tts";
12
+ IMCMessageTypeEnum["ModalitySpeech2Speech"] = "modality-speech-to-speech";
13
+ // TODO: Do not use UseX2Y or Use__Gen in the future.
14
+ // Instead, use a common AI IO adapter.
15
+ IMCMessageTypeEnum["ModalityImageGen"] = "modality-image-gen";
16
+ IMCMessageTypeEnum["ModalityVideoGen"] = "modality-video-gen";
17
+ IMCMessageTypeEnum["ModalityOCR"] = "modality-ocr";
18
+ IMCMessageTypeEnum["ModalityMusicGen"] = "modality-music-gen";
19
+ // #endregion
20
+ // #region App states
21
+ // Notify Pulse that app window is available
22
+ IMCMessageTypeEnum["AppReady"] = "app-ready";
23
+ // Notify Pulse that aoo is closing
24
+ IMCMessageTypeEnum["AppClose"] = "app-close";
25
+ // #endregion
26
+ // #region Editor states
27
+ // Notify editor that app is loading or loaded
28
+ IMCMessageTypeEnum["EditorLoadingApp"] = "editor-loading-app";
29
+ // App actions
30
+ IMCMessageTypeEnum["EditorRegisterAction"] = "editor-register-action";
31
+ IMCMessageTypeEnum["EditorRunAppAction"] = "editor-run-app-action";
32
+ // Execute agent method
33
+ IMCMessageTypeEnum["EditorRunAgentMethod"] = "editor-run-agent-method";
34
+ // Get theme
35
+ IMCMessageTypeEnum["EditorThemeUpdate"] = "editor-theme-update";
36
+ IMCMessageTypeEnum["EditorAppRequestTheme"] = "editor-app-request-theme";
37
+ // Send notification
38
+ IMCMessageTypeEnum["EditorShowNotification"] = "editor-show-notification";
39
+ // Get environment variables
40
+ IMCMessageTypeEnum["EditorGetEnv"] = "editor-get-env";
41
+ // App state snapshot upon importing & exporting
42
+ IMCMessageTypeEnum["EditorAppStateSnapshotRestore"] = "editor-app-state-snapshot-restore";
43
+ IMCMessageTypeEnum["EditorAppStateSnapshotSave"] = "editor-app-state-snapshot-save";
44
+ // Handle editor file selection or drop
45
+ IMCMessageTypeEnum["EditorAppReceiveFileUri"] = "editor-app-receive-file-uri";
46
+ // App uses owned app
47
+ IMCMessageTypeEnum["EditorAppUseOwnedApp"] = "editor-app-use-owned-app";
48
+ // App requests workspace info
49
+ IMCMessageTypeEnum["EditorAppRequestWorkspace"] = "editor-app-request-workspace";
50
+ // #endregion
51
+ // #region Platform API interaction messages (require OS-like environment)
52
+ /* Terminal */
53
+ IMCMessageTypeEnum["PlatformCreateTerminal"] = "platform-create-terminal";
54
+ // Update view file
55
+ IMCMessageTypeEnum["PlatformWriteFile"] = "platform-write-file";
56
+ // Request view file
57
+ IMCMessageTypeEnum["PlatformReadFile"] = "platform-read-file";
58
+ // File update (file watch notification from platform to view)
59
+ IMCMessageTypeEnum["PlatformFileUpdate"] = "platform-file-update";
60
+ // #endregion
61
+ // #region Signal messages
62
+ IMCMessageTypeEnum["SignalRequestOtherWindowId"] = "signal-request-other-window-id";
63
+ // A message to notify sender that the message
64
+ // has been received and finished processing
65
+ IMCMessageTypeEnum["SignalAcknowledge"] = "signal-acknowledge";
66
+ // Notify abort
67
+ IMCMessageTypeEnum["SignalAbort"] = "signal-abort";
68
+ // Error
69
+ IMCMessageTypeEnum["SignalError"] = "signal-error";
70
+ // Ignore
71
+ IMCMessageTypeEnum["SignalIgnore"] = "signal-ignore";
72
+ // #endregion
73
+ })(IMCMessageTypeEnum || (IMCMessageTypeEnum = {}));
74
+ var ViewModeEnum;
75
+ (function (ViewModeEnum) {
76
+ ViewModeEnum["App"] = "app";
77
+ ViewModeEnum["Canvas"] = "canvas";
78
+ ViewModeEnum["Home"] = "home";
79
+ })(ViewModeEnum || (ViewModeEnum = {}));
80
+ /* Notification */
81
+ var NotificationTypeEnum;
82
+ (function (NotificationTypeEnum) {
83
+ NotificationTypeEnum["Success"] = "success";
84
+ NotificationTypeEnum["Error"] = "error";
85
+ NotificationTypeEnum["Info"] = "info";
86
+ NotificationTypeEnum["Warning"] = "warning";
87
+ })(NotificationTypeEnum || (NotificationTypeEnum = {}));
88
+ // #region App settings
89
+ var AppTypeEnum;
90
+ (function (AppTypeEnum) {
91
+ AppTypeEnum["Generic"] = "generic";
92
+ AppTypeEnum["FileView"] = "file-view";
93
+ AppTypeEnum["ConsoleView"] = "console-view";
94
+ })(AppTypeEnum || (AppTypeEnum = {}));
95
+ function isArrayType(value) {
96
+ return Array.isArray(value) && value.length === 1;
97
+ }
98
+ function isObjectType(value) {
99
+ return typeof value === "object" && !Array.isArray(value);
100
+ }
101
+ var AccessEnum;
102
+ (function (AccessEnum) {
103
+ AccessEnum["public"] = "public";
104
+ AccessEnum["private"] = "private";
105
+ })(AccessEnum || (AccessEnum = {}));
106
+ // #endregion
107
+ // TODO: In the future, add a common AI IO adapter
108
+ // where the input and output types are arbitrary
109
+ // modalities. So we can plug in any AI model,
110
+ // or even a program, for either input or output.
111
+ // e.g. similar to how a function works.
112
+ // export type FuncAdapter = {
113
+ // input:
114
+ // output:
115
+ // }
116
+
117
+ class MessageReceiver {
118
+ constructor(listenerMap, windowId, intent) {
119
+ this.handlerMap = listenerMap;
120
+ this.pendingTasks = new Map();
121
+ this.windowId = windowId;
122
+ this.intent = intent;
123
+ }
124
+ receiveMessage(senderWindow, message) {
125
+ // Not handling messages from self
126
+ if (this.windowId === message.from)
127
+ return;
128
+ // Abort the task if the message type is Abort
129
+ if (message.type === IMCMessageTypeEnum.SignalAbort) {
130
+ const id = message.messageId;
131
+ const pendingTask = this.pendingTasks.get(id);
132
+ if (pendingTask) {
133
+ console.log("Aborting task", id);
134
+ pendingTask.controller.abort();
135
+ this.pendingTasks.delete(id);
136
+ }
137
+ return;
138
+ }
139
+ const handler = this.handlerMap.get(message.type);
140
+ if (!handler) {
141
+ if (this.intent === "connection-listener") {
142
+ // Ignore missing handler for connection listener,
143
+ // as it handles connection related messages only.
144
+ // There should be another channel created to handle other messages.
145
+ return;
146
+ }
147
+ console.warn(`No handler found for message type: ${message.type}`);
148
+ // Ignore the message if no handler is found
149
+ this.ignoreSender(senderWindow, message);
150
+ return;
151
+ }
152
+ // Create abort controller to listen for abort signal from sender.
153
+ // Then save the message id and abort controller to the pending tasks.
154
+ const controller = new AbortController();
155
+ const signal = controller.signal;
156
+ this.pendingTasks.set(message.messageId, {
157
+ controller,
158
+ });
159
+ const promise = handler(senderWindow, message, signal);
160
+ promise
161
+ .then((result) => {
162
+ // Don't send the result if the task has been aborted
163
+ if (signal.aborted)
164
+ return;
165
+ // Acknowledge the sender with the result if the message type is not Acknowledge
166
+ if (message.type !== IMCMessageTypeEnum.SignalAcknowledge) {
167
+ this.acknowledgeSender(senderWindow, message.messageId, message.channelId, result);
168
+ }
169
+ })
170
+ .catch((error) => {
171
+ if (error.message === "Message ignored by receiver") {
172
+ // Ignore the message if no handler is found
173
+ this.ignoreSender(senderWindow, message);
174
+ return;
175
+ }
176
+ // Send the error message to the sender
177
+ const errMsg = {
178
+ messageId: message.messageId,
179
+ channelId: message.channelId,
180
+ type: IMCMessageTypeEnum.SignalError,
181
+ payload: error.message,
182
+ from: this.windowId,
183
+ };
184
+ console.error("Error handling message:", error);
185
+ senderWindow.postMessage(errMsg, "*");
186
+ })
187
+ .finally(() => {
188
+ this.pendingTasks.delete(message.messageId);
189
+ });
190
+ }
191
+ acknowledgeSender(senderWindow, messageId, channelId, payload) {
192
+ const message = {
193
+ messageId: messageId,
194
+ channelId: channelId,
195
+ type: IMCMessageTypeEnum.SignalAcknowledge,
196
+ payload: payload,
197
+ from: this.windowId,
198
+ };
199
+ senderWindow.postMessage(message, "*");
200
+ }
201
+ ignoreSender(senderWindow, message) {
202
+ // Ignore the message if no handler is found
203
+ senderWindow.postMessage({
204
+ messageId: message.messageId,
205
+ channelId: message.channelId,
206
+ type: IMCMessageTypeEnum.SignalIgnore,
207
+ payload: `No handler for message type: ${message.type}`,
208
+ from: this.windowId,
209
+ }, "*");
210
+ }
211
+ }
212
+
213
+ var byteToHex = [];
214
+ for (var i = 0; i < 256; ++i) {
215
+ byteToHex.push((i + 0x100).toString(16).slice(1));
216
+ }
217
+ function unsafeStringify(arr) {
218
+ var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
219
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
220
+ }
221
+
222
+ var getRandomValues;
223
+ var rnds8 = new Uint8Array(16);
224
+ function rng() {
225
+ if (!getRandomValues) {
226
+ if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
227
+ throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
228
+ }
229
+ getRandomValues = crypto.getRandomValues.bind(crypto);
230
+ }
231
+ return getRandomValues(rnds8);
232
+ }
233
+
234
+ var randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
235
+ var _native = {
236
+ randomUUID: randomUUID
237
+ };
238
+
239
+ function _v4(options, buf, offset) {
240
+ var _ref, _options$random, _options$rng, _options;
241
+ options = options || {};
242
+ var rnds = (_ref = (_options$random = options.random) !== null && _options$random !== void 0 ? _options$random : (_options$rng = (_options = options).rng) === null || _options$rng === void 0 ? void 0 : _options$rng.call(_options)) !== null && _ref !== void 0 ? _ref : rng();
243
+ if (rnds.length < 16) {
244
+ throw new Error('Random bytes length must be >= 16');
245
+ }
246
+ rnds[6] = rnds[6] & 0x0f | 0x40;
247
+ rnds[8] = rnds[8] & 0x3f | 0x80;
248
+ return unsafeStringify(rnds);
249
+ }
250
+ function v4(options, buf, offset) {
251
+ if (_native.randomUUID && true && !options) {
252
+ return _native.randomUUID();
253
+ }
254
+ return _v4(options);
255
+ }
256
+
257
+ class MessageSender {
258
+ constructor(targetWindow, timeout, moduleId, channelId) {
259
+ this.targetWindow = targetWindow;
260
+ this.timeout = timeout;
261
+ this.pendingMessages = new Map();
262
+ this.moduleId = moduleId;
263
+ this.channelId = channelId;
264
+ }
265
+ async sendMessage(handlingType, payload, abortSignal) {
266
+ // Generate a unique id for the message using timestamp
267
+ const id = v4() + new Date().getTime().toString();
268
+ const message = {
269
+ messageId: id,
270
+ channelId: this.channelId,
271
+ type: handlingType,
272
+ payload: payload,
273
+ from: this.moduleId,
274
+ };
275
+ return new Promise((resolve, reject) => {
276
+ // If the signal is already aborted, reject immediately
277
+ if (abortSignal?.aborted) {
278
+ return reject(new Error("Request aborted"));
279
+ }
280
+ const abortHandler = () => {
281
+ this.pendingMessages.delete(id);
282
+ // Notify the target window that the request has been aborted
283
+ this.targetWindow.postMessage({
284
+ id,
285
+ type: IMCMessageTypeEnum.SignalAbort,
286
+ payload: JSON.stringify({
287
+ status: "Task aborted",
288
+ data: null,
289
+ }),
290
+ }, "*");
291
+ reject(new Error("Request aborted"));
292
+ };
293
+ // Attach abort listener
294
+ abortSignal?.addEventListener("abort", abortHandler);
295
+ // Check timeout
296
+ const timeoutId = setTimeout(() => {
297
+ this.pendingMessages.delete(id);
298
+ abortSignal?.removeEventListener("abort", abortHandler);
299
+ reject(new Error("Communication with Pulse Editor timeout."));
300
+ }, this.timeout);
301
+ // Ensure cleanup on resolution
302
+ const onResolve = (value) => {
303
+ clearTimeout(timeoutId);
304
+ abortSignal?.removeEventListener("abort", abortHandler);
305
+ this.pendingMessages.delete(id);
306
+ resolve(value);
307
+ };
308
+ const onReject = (reason) => {
309
+ clearTimeout(timeoutId);
310
+ abortSignal?.removeEventListener("abort", abortHandler);
311
+ this.pendingMessages.delete(id);
312
+ reject(reason);
313
+ };
314
+ this.pendingMessages.set(id, {
315
+ resolve: onResolve,
316
+ reject: onReject,
317
+ });
318
+ // Send message
319
+ this.targetWindow.postMessage(message, "*");
320
+ });
321
+ }
322
+ getPendingMessage(id) {
323
+ return this.pendingMessages.get(id);
324
+ }
325
+ }
326
+
327
+ class InterModuleCommunication {
328
+ constructor(intent, channelId) {
329
+ this.intent = intent;
330
+ this.channelId = channelId;
331
+ }
332
+ /**
333
+ * Initialize a receiver to receive message.
334
+ * @param window The current window.
335
+ * @param otherWindowId The ID of the other window. This is optional and can be undefined.
336
+ * When defined, the receiver will only receive messages from window with the ID.
337
+ */
338
+ initThisWindow(window, otherWindowId) {
339
+ this.thisWindow = window;
340
+ // @ts-expect-error viewId is injected by the browser
341
+ const thisWindowId = window.viewId;
342
+ if (!thisWindowId) {
343
+ throw new Error("Current window's ID is not defined.");
344
+ }
345
+ this.thisWindowId = thisWindowId;
346
+ this.receiverHandlerMap = new Map();
347
+ const receiver = new MessageReceiver(this.receiverHandlerMap, this.thisWindowId, this.intent);
348
+ this.receiver = receiver;
349
+ this.messageRecords = new Map();
350
+ this.listener = (event) => {
351
+ const message = event.data;
352
+ const messageId = message.messageId;
353
+ const channelId = message.channelId;
354
+ const type = message.type;
355
+ // Return if the channel ID exists but does not match the current channel ID
356
+ // (channel ID can be undefined during initial handshake)
357
+ if (this.channelId !== undefined &&
358
+ channelId !== undefined &&
359
+ channelId !== this.channelId) {
360
+ return;
361
+ }
362
+ if (this.messageRecords?.has(messageId) &&
363
+ type !== IMCMessageTypeEnum.SignalRequestOtherWindowId) {
364
+ console.warn(`[${this.thisWindowId}]: Duplicate message received with message ID: ${messageId}. Ignoring this message. Message: ${JSON.stringify(message)}`);
365
+ return;
366
+ }
367
+ this.messageRecords?.set(messageId, message);
368
+ if (!receiver) {
369
+ throw new Error("Receiver not initialized at module " + this.thisWindowId);
370
+ }
371
+ if (message.from !== undefined && message.type !== IMCMessageTypeEnum.SignalIgnore) {
372
+ console.log(`Module ${this.thisWindowId} received message from module ${message.from}:\n ${JSON.stringify(message)}`);
373
+ }
374
+ if (otherWindowId && message.from !== otherWindowId) {
375
+ return;
376
+ }
377
+ const win = event.source;
378
+ receiver.receiveMessage(win, message);
379
+ };
380
+ window.addEventListener("message", this.listener);
381
+ console.log("Adding IMC listener in " + this.thisWindowId);
382
+ // refresh the receiver handler map
383
+ this.setBaseHandler();
384
+ }
385
+ /* Initialize a sender to send message ot the other window. */
386
+ async initOtherWindow(window) {
387
+ return new Promise((resolve) => {
388
+ if (!this.thisWindow || !this.thisWindowId) {
389
+ throw new Error("You must initialize the current window first.");
390
+ }
391
+ const onReceiveWindowID = (event) => {
392
+ if (!this.thisWindow || !this.thisWindowId) {
393
+ throw new Error("You must initialize the current window first.");
394
+ }
395
+ const message = event.data;
396
+ const otherWindowId = message.payload;
397
+ this.otherWindowId = otherWindowId;
398
+ const sender = new MessageSender(window, messageTimeout, this.thisWindowId, this.channelId);
399
+ this.sender = sender;
400
+ if (!this.receiverHandlerMap) {
401
+ throw new Error("You must initialize the current window first.");
402
+ }
403
+ this.setBaseHandler();
404
+ resolve();
405
+ };
406
+ // Wait for the other window to send its ID.
407
+ this.thisWindow.addEventListener("message", onReceiveWindowID, {
408
+ once: true,
409
+ });
410
+ this.otherWindow = window;
411
+ this.otherWindow.postMessage({
412
+ type: IMCMessageTypeEnum.SignalRequestOtherWindowId,
413
+ from: this.thisWindowId,
414
+ }, "*");
415
+ });
416
+ }
417
+ close() {
418
+ if (this.listener) {
419
+ window.removeEventListener("message", this.listener);
420
+ }
421
+ }
422
+ async sendMessage(type, payload, abortSignal) {
423
+ const sender = this.sender;
424
+ if (!sender) {
425
+ throw new Error("Sender not initialized");
426
+ }
427
+ return await sender.sendMessage(type, payload, abortSignal);
428
+ }
429
+ updateReceiverHandlerMap(receiverHandlerMap) {
430
+ if (!this.receiver) {
431
+ throw new Error("Receiver not initialized");
432
+ }
433
+ // Clear all existing handlers except the acknowledgement handler.
434
+ this.receiverHandlerMap?.clear();
435
+ this.setBaseHandler();
436
+ receiverHandlerMap.forEach((value, key) => {
437
+ this.receiverHandlerMap?.set(key, value);
438
+ });
439
+ }
440
+ getThisWindowId() {
441
+ if (!this.thisWindowId) {
442
+ throw new Error("This window ID is not defined.");
443
+ }
444
+ return this.thisWindowId;
445
+ }
446
+ getOtherWindowId() {
447
+ if (!this.otherWindowId) {
448
+ throw new Error("Other window ID is not defined.");
449
+ }
450
+ return this.otherWindowId;
451
+ }
452
+ setBaseHandler() {
453
+ // Add an acknowledgement handler in current window's receiver for results of sent messages.
454
+ // This is to receive the acknowledgement from the other window, so that we know the other
455
+ // window has received the message and finished processing it.
456
+ // The current window must be initialized first. i.e. call initThisWindow() before initOtherWindow().
457
+ this.receiverHandlerMap?.set(IMCMessageTypeEnum.SignalAcknowledge, async (senderWindow, message) => {
458
+ const pendingMessage = this.sender?.getPendingMessage(message.messageId);
459
+ if (pendingMessage) {
460
+ pendingMessage.resolve(message.payload);
461
+ }
462
+ });
463
+ // Handle error message from the other window.
464
+ this.receiverHandlerMap?.set(IMCMessageTypeEnum.SignalError, async (senderWindow, message) => {
465
+ const pendingMessage = this.sender?.getPendingMessage(message.messageId);
466
+ if (pendingMessage) {
467
+ pendingMessage.reject(new Error(message.payload));
468
+ }
469
+ });
470
+ // Set get window ID handler in the receiver handler map.
471
+ this.receiverHandlerMap?.set(IMCMessageTypeEnum.SignalRequestOtherWindowId, async (senderWindow, message) => {
472
+ console.log("Received window ID request. Sending current window ID to other window: ");
473
+ const id = this.thisWindowId;
474
+ if (!id) {
475
+ throw new Error("This window ID is not defined.");
476
+ }
477
+ return id;
478
+ });
479
+ // Handle ignore signal
480
+ this.receiverHandlerMap?.set(IMCMessageTypeEnum.SignalIgnore, async (senderWindow, message) => {
481
+ console.warn(`Message ignored by receiver. Message ID: ${message.messageId}, Payload: ${message.payload}`);
482
+ const pendingMessage = this.sender?.getPendingMessage(message.messageId);
483
+ if (pendingMessage) {
484
+ pendingMessage.reject(new Error("Message ignored by receiver"));
485
+ }
486
+ });
487
+ }
488
+ }
489
+
490
+ /**
491
+ * Poly IMC establishes two-way inter-module communication channels,
492
+ * where each channel consists of a sender and a receiver to send and
493
+ * receive messages between host window and the other module's window.
494
+ *
495
+ * This assumes the other window has IMC or Poly-IMC setup.
496
+ */
497
+ class PolyIMC {
498
+ /**
499
+ *
500
+ * @param baseReceiverHandlerMap A base receiver handler map for universal handlers.
501
+ * E.g. Pulse Editor API handler
502
+ */
503
+ constructor(baseReceiverHandlerMap) {
504
+ this.channelsMap = new Map();
505
+ this.baseReceiverHandlerMap = baseReceiverHandlerMap;
506
+ this.channelReceiverHandlerMapMap = new Map();
507
+ }
508
+ async sendMessage(targetWindowId, handlingType, payload, abortSignal) {
509
+ const channels = this.channelsMap.get(targetWindowId);
510
+ if (!channels) {
511
+ throw new Error("Channel not found for window ID " + targetWindowId);
512
+ }
513
+ // - some channels here are not returning results
514
+ // - and the result now is an array instead of a single value
515
+ const results = [];
516
+ await Promise.all(channels.map(async (channel) => {
517
+ try {
518
+ const result = await channel.sendMessage(handlingType, payload, abortSignal);
519
+ results.push(result);
520
+ }
521
+ catch (error) {
522
+ // TODO: better ignore handling
523
+ if (error.message === "Message ignored by receiver") {
524
+ console.warn(`Message ignored by receiver (window ID ${targetWindowId})`, error);
525
+ // nothing returned, nothing pushed — completely skipped
526
+ return;
527
+ }
528
+ throw error; // rethrow real errors
529
+ }
530
+ }));
531
+ return results;
532
+ }
533
+ updateBaseReceiverHandlerMap(handlerMap) {
534
+ this.baseReceiverHandlerMap = handlerMap;
535
+ this.channelsMap.forEach((channels, key) => {
536
+ const combinedMap = this.getCombinedHandlerMap(this.baseReceiverHandlerMap, this.channelReceiverHandlerMapMap.get(key));
537
+ channels.forEach((channel) => {
538
+ channel.updateReceiverHandlerMap(combinedMap);
539
+ });
540
+ });
541
+ }
542
+ updateChannelReceiverHandlerMap(targetWindowId, handlerMap) {
543
+ const channels = this.channelsMap.get(targetWindowId);
544
+ if (!channels) {
545
+ throw new Error("Channel not found for window ID " + targetWindowId);
546
+ }
547
+ const combinedMap = this.getCombinedHandlerMap(this.baseReceiverHandlerMap, handlerMap);
548
+ channels.forEach((channel) => {
549
+ channel.updateReceiverHandlerMap(combinedMap);
550
+ });
551
+ this.channelReceiverHandlerMapMap.set(targetWindowId, handlerMap);
552
+ }
553
+ async createChannel(targetWindow, targetWindowId, intent, channelId, receiverHandlerMap) {
554
+ console.log("Creating channel for window ID: " + targetWindowId);
555
+ const channel = new InterModuleCommunication(intent, channelId);
556
+ channel.initThisWindow(window, targetWindowId);
557
+ await channel.initOtherWindow(targetWindow);
558
+ const newChannels = this.channelsMap.get(targetWindowId) ?? [];
559
+ // Add to existing channels
560
+ newChannels.push(channel);
561
+ this.channelsMap.set(targetWindowId, newChannels);
562
+ // If there is a channel specific receiver handler map,
563
+ // combine it with the base receiver handler map.
564
+ if (receiverHandlerMap) {
565
+ this.updateChannelReceiverHandlerMap(targetWindowId, receiverHandlerMap);
566
+ }
567
+ else {
568
+ channel.updateReceiverHandlerMap(this.baseReceiverHandlerMap);
569
+ }
570
+ }
571
+ removeWindowChannels(targetWindowId) {
572
+ const channels = this.channelsMap.get(targetWindowId);
573
+ if (!channels) {
574
+ throw new Error("Channel not found for window ID " + targetWindowId);
575
+ }
576
+ channels.forEach((channel) => {
577
+ channel.close();
578
+ });
579
+ this.channelsMap.delete(targetWindowId);
580
+ this.channelReceiverHandlerMapMap.delete(targetWindowId);
581
+ }
582
+ hasChannel(targetWindowId) {
583
+ return this.channelsMap.has(targetWindowId);
584
+ }
585
+ close() {
586
+ this.channelsMap.forEach((channels) => channels.forEach((channel) => channel.close()));
587
+ this.channelsMap.clear();
588
+ this.channelReceiverHandlerMapMap.clear();
589
+ }
590
+ getCombinedHandlerMap(map1, map2) {
591
+ if (map1 && map2) {
592
+ // Combine two maps
593
+ const combinedMap = new Map([...map1, ...map2]);
594
+ return combinedMap;
595
+ }
596
+ else if (map1) {
597
+ return map1;
598
+ }
599
+ else if (map2) {
600
+ return map2;
601
+ }
602
+ else {
603
+ return new Map();
604
+ }
605
+ }
606
+ }
607
+ class ConnectionListener {
608
+ /**
609
+ *
610
+ * @param polyIMC The polyIMC instance.
611
+ * @param newConnectionReceiverHandlerMap Receiver handler map for newly established poly-IMC channel.
612
+ * @param onConnection Callback function to be called when a new connection is established.
613
+ * @param expectedOtherWindowId Optional expected other window ID to validate incoming connections.
614
+ */
615
+ constructor(polyIMC, newConnectionReceiverHandlerMap, onConnection, expectedOtherWindowId) {
616
+ this.polyIMC = polyIMC;
617
+ this.newConnectionReceiverHandlerMap = newConnectionReceiverHandlerMap;
618
+ this.onConnection = onConnection;
619
+ const listener = new InterModuleCommunication("connection-listener", undefined);
620
+ this.listener = listener;
621
+ listener.initThisWindow(window, expectedOtherWindowId);
622
+ listener.updateReceiverHandlerMap(new Map([
623
+ [
624
+ IMCMessageTypeEnum.AppReady,
625
+ async (senderWindow, message, abortSignal) => {
626
+ await this.handleExtReady(senderWindow, message, abortSignal);
627
+ },
628
+ ],
629
+ ]));
630
+ }
631
+ close() {
632
+ this.listener?.close();
633
+ }
634
+ updateReceiverHandlerMap(newReceiverHandlerMap) {
635
+ this.newConnectionReceiverHandlerMap = newReceiverHandlerMap;
636
+ }
637
+ async handleExtReady(senderWindow, message, abortSignal) {
638
+ const targetWindowId = message.from;
639
+ const { intent, channelId } = message.payload;
640
+ if (!channelId) {
641
+ throw new Error("Channel ID is missing in AppReady message.");
642
+ }
643
+ // Create a new channel for the incoming connection
644
+ await this.polyIMC.createChannel(senderWindow, targetWindowId, intent, channelId, this.newConnectionReceiverHandlerMap);
645
+ if (this.onConnection) {
646
+ this.onConnection(senderWindow, message);
647
+ }
648
+ }
649
+ }
650
+
651
+ export { AccessEnum, AppTypeEnum, ConnectionListener, IMCMessageTypeEnum, InterModuleCommunication, MessageReceiver, MessageSender, NotificationTypeEnum, PolyIMC, ViewModeEnum, isArrayType, isObjectType, messageTimeout };
652
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sources":["../src/types/constants.ts","../src/types/types.ts","../src/imc/message-receiver.ts","../../../node_modules/uuid/dist/stringify.js","../../../node_modules/uuid/dist/rng.js","../../../node_modules/uuid/dist/native.js","../../../node_modules/uuid/dist/v4.js","../src/imc/message-sender.ts","../src/imc/inter-module-communication.ts","../src/imc/poly-imc.ts"],"sourcesContent":["export const messageTimeout = 300000;\r\n","// #region Inter-Module Communication\r\n/* Inter Module Communication messages */\r\nexport enum IMCMessageTypeEnum {\r\n // #region AI modality tools\r\n ModalityVAD = \"modality-vad\",\r\n ModalitySTT = \"modality-stt\",\r\n ModalityLLM = \"modality-llm\",\r\n ModalityTTS = \"modality-tts\",\r\n ModalitySpeech2Speech = \"modality-speech-to-speech\",\r\n // TODO: Do not use UseX2Y or Use__Gen in the future.\r\n // Instead, use a common AI IO adapter.\r\n ModalityImageGen = \"modality-image-gen\",\r\n ModalityVideoGen = \"modality-video-gen\",\r\n ModalityOCR = \"modality-ocr\",\r\n ModalityMusicGen = \"modality-music-gen\",\r\n // #endregion\r\n\r\n // #region App states\r\n // Notify Pulse that app window is available\r\n AppReady = \"app-ready\",\r\n // Notify Pulse that aoo is closing\r\n AppClose = \"app-close\",\r\n // #endregion\r\n\r\n // #region Editor states\r\n // Notify editor that app is loading or loaded\r\n EditorLoadingApp = \"editor-loading-app\",\r\n // App actions\r\n EditorRegisterAction = \"editor-register-action\",\r\n EditorRunAppAction = \"editor-run-app-action\",\r\n // Execute agent method\r\n EditorRunAgentMethod = \"editor-run-agent-method\",\r\n // Get theme\r\n EditorThemeUpdate = \"editor-theme-update\",\r\n EditorAppRequestTheme = \"editor-app-request-theme\",\r\n // Send notification\r\n EditorShowNotification = \"editor-show-notification\",\r\n // Get environment variables\r\n EditorGetEnv = \"editor-get-env\",\r\n // App state snapshot upon importing & exporting\r\n EditorAppStateSnapshotRestore = \"editor-app-state-snapshot-restore\",\r\n EditorAppStateSnapshotSave = \"editor-app-state-snapshot-save\",\r\n // Handle editor file selection or drop\r\n EditorAppReceiveFileUri = \"editor-app-receive-file-uri\",\r\n // App uses owned app\r\n EditorAppUseOwnedApp = \"editor-app-use-owned-app\",\r\n // App requests workspace info\r\n EditorAppRequestWorkspace = \"editor-app-request-workspace\",\r\n // #endregion\r\n\r\n // #region Platform API interaction messages (require OS-like environment)\r\n /* Terminal */\r\n PlatformCreateTerminal = \"platform-create-terminal\",\r\n // Update view file\r\n PlatformWriteFile = \"platform-write-file\",\r\n // Request view file\r\n PlatformReadFile = \"platform-read-file\",\r\n // File update (file watch notification from platform to view)\r\n PlatformFileUpdate = \"platform-file-update\",\r\n // #endregion\r\n\r\n // #region Signal messages\r\n SignalRequestOtherWindowId = \"signal-request-other-window-id\",\r\n // A message to notify sender that the message\r\n // has been received and finished processing\r\n SignalAcknowledge = \"signal-acknowledge\",\r\n // Notify abort\r\n SignalAbort = \"signal-abort\",\r\n // Error\r\n SignalError = \"signal-error\",\r\n // Ignore\r\n SignalIgnore = \"signal-ignore\",\r\n // #endregion\r\n}\r\n\r\nexport type IMCMessage = {\r\n messageId: string;\r\n channelId?: string;\r\n from: string;\r\n type: IMCMessageTypeEnum;\r\n payload?: any;\r\n};\r\n\r\nexport type ReceiverHandler = (\r\n senderWindow: Window,\r\n message: IMCMessage,\r\n abortSignal?: AbortSignal,\r\n) => Promise<any>;\r\n\r\n// IMC receiver handler map\r\nexport type ReceiverHandlerMap = Map<IMCMessageTypeEnum, ReceiverHandler>;\r\n// #endregion\r\n\r\n/* File view */\r\nexport type TextFileSelection = {\r\n lineStart: number;\r\n lineEnd: number;\r\n text: string;\r\n};\r\n\r\nexport type ViewModel = {\r\n viewId: string;\r\n appConfig: AppConfig;\r\n};\r\n\r\nexport enum ViewModeEnum {\r\n App = \"app\",\r\n Canvas = \"canvas\",\r\n Home = \"home\",\r\n}\r\n\r\n/* Fetch API */\r\nexport type FetchPayload = {\r\n uri: string;\r\n options?: RequestInit;\r\n};\r\n\r\n/* Notification */\r\nexport enum NotificationTypeEnum {\r\n Success = \"success\",\r\n Error = \"error\",\r\n Info = \"info\",\r\n Warning = \"warning\",\r\n}\r\n\r\n// #region App settings\r\nexport enum AppTypeEnum {\r\n Generic = \"generic\",\r\n FileView = \"file-view\",\r\n ConsoleView = \"console-view\",\r\n}\r\n\r\nexport type AppConfig = {\r\n id: string;\r\n version: string;\r\n libVersion?: string;\r\n visibility?: \"public\" | \"private\" | \"unlisted\";\r\n author?: string;\r\n displayName?: string;\r\n description?: string;\r\n materialIcon?: string;\r\n appType?: AppTypeEnum;\r\n fileTypes?: string[];\r\n thumbnail?: string;\r\n enabledPlatforms?: Record<string, boolean>;\r\n\r\n // App installed agents\r\n agents?: Agent[];\r\n // Exposed actions in the modular app\r\n preRegisteredActions?: Action[];\r\n // Recommended dimensions for app view in canvas\r\n recommendedHeight?: number;\r\n recommendedWidth?: number;\r\n};\r\n\r\nexport type Action = {\r\n name: string;\r\n description: string;\r\n parameters: Record<string, TypedVariable>;\r\n returns: Record<string, TypedVariable>;\r\n handler?: (args: any) => Promise<any>;\r\n};\r\n// #endregion\r\n\r\n// #region Agent config\r\nexport type Agent = {\r\n name: string;\r\n version: string;\r\n systemPrompt: string;\r\n availableMethods: AgentMethod[];\r\n description: string;\r\n tools?: AgentTool[];\r\n LLMConfig?: LLMConfig;\r\n};\r\n\r\n/**\r\n * An agent method is a sub task that an agent can perform.\r\n */\r\nexport type AgentMethod = {\r\n access: AccessEnum;\r\n name: string;\r\n parameters: Record<string, TypedVariable>;\r\n prompt: string;\r\n returns: Record<string, TypedVariable>;\r\n // If this config does not exist, use the class's LLMConfig\r\n LLMConfig?: LLMConfig;\r\n};\r\n\r\nexport type TypedVariable = {\r\n type: TypedVariableType;\r\n // Describe the variable for LLM to better understand it\r\n description: string;\r\n optional?: boolean;\r\n defaultValue?: any;\r\n};\r\n\r\n/**\r\n * A tool that agent can use during method execution.\r\n *\r\n *\r\n * The tool may optionally return a value to the agent.\r\n */\r\nexport type AgentTool = {\r\n access: AccessEnum;\r\n name: string;\r\n description: string;\r\n parameters: Record<string, TypedVariable>;\r\n returns: Record<string, TypedVariable>;\r\n};\r\n// #endregion\r\n\r\nexport type TypedVariableType =\r\n | \"string\"\r\n | \"number\"\r\n | \"boolean\"\r\n | \"any\"\r\n // An app instance is a reference to another app.\r\n // This instance could be possessed by the owner,\r\n // or it can be initialized by the caller.\r\n | \"app-instance\"\r\n | TypedVariableObjectType\r\n | TypedVariableArrayType;\r\n\r\nexport type TypedVariableObjectType = {\r\n [key: string]: TypedVariable;\r\n};\r\n\r\nexport type TypedVariableArrayType = [TypedVariableType];\r\n\r\nexport function isArrayType(\r\n value: TypedVariableType,\r\n): value is TypedVariableArrayType {\r\n return Array.isArray(value) && value.length === 1;\r\n}\r\n\r\nexport function isObjectType(\r\n value: TypedVariableType,\r\n): value is TypedVariableObjectType {\r\n return typeof value === \"object\" && !Array.isArray(value);\r\n}\r\n\r\nexport enum AccessEnum {\r\n public = \"public\",\r\n private = \"private\",\r\n}\r\n\r\n// #region AI settings\r\nexport type STTConfig = {\r\n provider: string;\r\n modelName: string;\r\n};\r\n\r\nexport type LLMConfig = {\r\n provider: string;\r\n modelName: string;\r\n temperature: number;\r\n};\r\n\r\nexport type TTSConfig = {\r\n provider: string;\r\n modelName: string;\r\n voice: string;\r\n};\r\n\r\nexport type ImageModelConfig = {\r\n provider: string;\r\n modelName: string;\r\n};\r\n\r\nexport type VideoModelConfig = {\r\n provider: string;\r\n modelName: string;\r\n};\r\n// #endregion\r\n\r\n// TODO: In the future, add a common AI IO adapter\r\n// where the input and output types are arbitrary\r\n// modalities. So we can plug in any AI model,\r\n// or even a program, for either input or output.\r\n// e.g. similar to how a function works.\r\n// export type FuncAdapter = {\r\n// input:\r\n// output:\r\n// }\r\n","import {\r\n IMCMessage,\r\n IMCMessageTypeEnum,\r\n ReceiverHandlerMap,\r\n} from \"../types/types\";\r\n\r\nexport class MessageReceiver {\r\n private handlerMap: ReceiverHandlerMap;\r\n private pendingTasks: Map<\r\n string,\r\n {\r\n controller: AbortController;\r\n }\r\n >;\r\n private windowId: string;\r\n private intent: string | undefined;\r\n\r\n constructor(\r\n listenerMap: ReceiverHandlerMap,\r\n windowId: string,\r\n intent: string | undefined\r\n ) {\r\n this.handlerMap = listenerMap;\r\n this.pendingTasks = new Map();\r\n this.windowId = windowId;\r\n this.intent = intent;\r\n }\r\n\r\n public receiveMessage(senderWindow: Window, message: IMCMessage) {\r\n // Not handling messages from self\r\n if (this.windowId === message.from) return;\r\n\r\n // Abort the task if the message type is Abort\r\n if (message.type === IMCMessageTypeEnum.SignalAbort) {\r\n const id = message.messageId;\r\n const pendingTask = this.pendingTasks.get(id);\r\n\r\n if (pendingTask) {\r\n console.log(\"Aborting task\", id);\r\n pendingTask.controller.abort();\r\n this.pendingTasks.delete(id);\r\n }\r\n\r\n return;\r\n }\r\n\r\n const handler = this.handlerMap.get(message.type);\r\n\r\n if (!handler) {\r\n if (this.intent === \"connection-listener\") {\r\n // Ignore missing handler for connection listener,\r\n // as it handles connection related messages only.\r\n // There should be another channel created to handle other messages.\r\n return;\r\n }\r\n\r\n console.warn(`No handler found for message type: ${message.type}`);\r\n\r\n // Ignore the message if no handler is found\r\n this.ignoreSender(senderWindow, message);\r\n\r\n return;\r\n }\r\n\r\n // Create abort controller to listen for abort signal from sender.\r\n // Then save the message id and abort controller to the pending tasks.\r\n const controller = new AbortController();\r\n const signal = controller.signal;\r\n this.pendingTasks.set(message.messageId, {\r\n controller,\r\n });\r\n\r\n const promise = handler(senderWindow, message, signal);\r\n promise\r\n .then((result) => {\r\n // Don't send the result if the task has been aborted\r\n if (signal.aborted) return;\r\n\r\n // Acknowledge the sender with the result if the message type is not Acknowledge\r\n if (message.type !== IMCMessageTypeEnum.SignalAcknowledge) {\r\n this.acknowledgeSender(\r\n senderWindow,\r\n message.messageId,\r\n message.channelId,\r\n result\r\n );\r\n }\r\n })\r\n .catch((error) => {\r\n if (error.message === \"Message ignored by receiver\") {\r\n // Ignore the message if no handler is found\r\n this.ignoreSender(senderWindow, message);\r\n return;\r\n }\r\n\r\n // Send the error message to the sender\r\n const errMsg: IMCMessage = {\r\n messageId: message.messageId,\r\n channelId: message.channelId,\r\n type: IMCMessageTypeEnum.SignalError,\r\n payload: error.message,\r\n from: this.windowId,\r\n };\r\n\r\n console.error(\"Error handling message:\", error);\r\n\r\n senderWindow.postMessage(errMsg, \"*\");\r\n })\r\n .finally(() => {\r\n this.pendingTasks.delete(message.messageId);\r\n });\r\n }\r\n\r\n private acknowledgeSender(\r\n senderWindow: Window,\r\n messageId: string,\r\n channelId: string | undefined,\r\n payload: any\r\n ): void {\r\n const message: IMCMessage = {\r\n messageId: messageId,\r\n channelId: channelId,\r\n type: IMCMessageTypeEnum.SignalAcknowledge,\r\n payload: payload,\r\n from: this.windowId,\r\n };\r\n senderWindow.postMessage(message, \"*\");\r\n }\r\n\r\n private ignoreSender(senderWindow: Window, message: IMCMessage) {\r\n // Ignore the message if no handler is found\r\n senderWindow.postMessage(\r\n {\r\n messageId: message.messageId,\r\n channelId: message.channelId,\r\n type: IMCMessageTypeEnum.SignalIgnore,\r\n payload: `No handler for message type: ${message.type}`,\r\n from: this.windowId,\r\n } as IMCMessage,\r\n \"*\"\r\n );\r\n }\r\n}\r\n","import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n","let getRandomValues;\nconst rnds8 = new Uint8Array(16);\nexport default function rng() {\n if (!getRandomValues) {\n if (typeof crypto === 'undefined' || !crypto.getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n getRandomValues = crypto.getRandomValues.bind(crypto);\n }\n return getRandomValues(rnds8);\n}\n","const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);\nexport default { randomUUID };\n","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction _v4(options, buf, offset) {\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n return _v4(options, buf, offset);\n}\nexport default v4;\n","import { v4 } from \"uuid\";\r\nimport { IMCMessage, IMCMessageTypeEnum } from \"../types/types\";\r\n\r\nexport class MessageSender {\r\n private targetWindow: Window;\r\n private timeout: number;\r\n\r\n private pendingMessages: Map<\r\n string,\r\n { resolve: (value: any) => void; reject: (reason: any) => void }\r\n >;\r\n\r\n private moduleId: string;\r\n private channelId: string | undefined;\r\n\r\n constructor(\r\n targetWindow: Window,\r\n timeout: number,\r\n moduleId: string,\r\n channelId?: string\r\n ) {\r\n this.targetWindow = targetWindow;\r\n this.timeout = timeout;\r\n\r\n this.pendingMessages = new Map();\r\n this.moduleId = moduleId;\r\n this.channelId = channelId;\r\n }\r\n\r\n public async sendMessage(\r\n handlingType: IMCMessageTypeEnum,\r\n payload?: any,\r\n abortSignal?: AbortSignal\r\n ): Promise<any> {\r\n // Generate a unique id for the message using timestamp\r\n const id = v4() + new Date().getTime().toString();\r\n const message: IMCMessage = {\r\n messageId: id,\r\n channelId: this.channelId,\r\n type: handlingType,\r\n payload: payload,\r\n from: this.moduleId,\r\n };\r\n\r\n return new Promise((resolve, reject) => {\r\n // If the signal is already aborted, reject immediately\r\n if (abortSignal?.aborted) {\r\n return reject(new Error(\"Request aborted\"));\r\n }\r\n\r\n const abortHandler = () => {\r\n this.pendingMessages.delete(id);\r\n // Notify the target window that the request has been aborted\r\n this.targetWindow.postMessage(\r\n {\r\n id,\r\n type: IMCMessageTypeEnum.SignalAbort,\r\n payload: JSON.stringify({\r\n status: \"Task aborted\",\r\n data: null,\r\n }),\r\n },\r\n \"*\"\r\n );\r\n reject(new Error(\"Request aborted\"));\r\n };\r\n // Attach abort listener\r\n abortSignal?.addEventListener(\"abort\", abortHandler);\r\n\r\n // Check timeout\r\n const timeoutId = setTimeout(() => {\r\n this.pendingMessages.delete(id);\r\n abortSignal?.removeEventListener(\"abort\", abortHandler);\r\n reject(new Error(\"Communication with Pulse Editor timeout.\"));\r\n }, this.timeout);\r\n // Ensure cleanup on resolution\r\n const onResolve = (value: any) => {\r\n clearTimeout(timeoutId);\r\n abortSignal?.removeEventListener(\"abort\", abortHandler);\r\n this.pendingMessages.delete(id);\r\n resolve(value);\r\n };\r\n\r\n const onReject = (reason: any) => {\r\n clearTimeout(timeoutId);\r\n abortSignal?.removeEventListener(\"abort\", abortHandler);\r\n this.pendingMessages.delete(id);\r\n reject(reason);\r\n };\r\n \r\n this.pendingMessages.set(id, {\r\n resolve: onResolve,\r\n reject: onReject,\r\n });\r\n\r\n // Send message\r\n this.targetWindow.postMessage(message, \"*\");\r\n });\r\n }\r\n\r\n public getPendingMessage(id: string) {\r\n return this.pendingMessages.get(id);\r\n }\r\n}\r\n","import { messageTimeout } from \"../types/constants\";\r\nimport {\r\n IMCMessage,\r\n IMCMessageTypeEnum,\r\n ReceiverHandlerMap,\r\n} from \"../types/types\";\r\nimport { MessageReceiver } from \"./message-receiver\";\r\nimport { MessageSender } from \"./message-sender\";\r\n\r\nexport class InterModuleCommunication {\r\n private thisWindow: Window | undefined;\r\n private otherWindow: Window | undefined;\r\n\r\n private receiver: MessageReceiver | undefined;\r\n private sender: MessageSender | undefined;\r\n\r\n private thisWindowId: string | undefined;\r\n private otherWindowId: string | undefined;\r\n\r\n private receiverHandlerMap: ReceiverHandlerMap | undefined;\r\n\r\n private listener: ((event: MessageEvent) => void) | undefined;\r\n\r\n private messageRecords: Map<string, IMCMessage> | undefined;\r\n\r\n public intent: string | undefined;\r\n public channelId: string | undefined;\r\n\r\n constructor(intent: string | undefined, channelId: string | undefined) {\r\n this.intent = intent;\r\n this.channelId = channelId;\r\n }\r\n\r\n /**\r\n * Initialize a receiver to receive message.\r\n * @param window The current window.\r\n * @param otherWindowId The ID of the other window. This is optional and can be undefined.\r\n * When defined, the receiver will only receive messages from window with the ID.\r\n */\r\n public initThisWindow(window: Window, otherWindowId?: string) {\r\n this.thisWindow = window;\r\n // @ts-expect-error viewId is injected by the browser\r\n const thisWindowId = window.viewId as string | undefined;\r\n if (!thisWindowId) {\r\n throw new Error(\"Current window's ID is not defined.\");\r\n }\r\n this.thisWindowId = thisWindowId;\r\n\r\n this.receiverHandlerMap = new Map();\r\n\r\n const receiver = new MessageReceiver(\r\n this.receiverHandlerMap,\r\n this.thisWindowId,\r\n this.intent\r\n );\r\n this.receiver = receiver;\r\n\r\n this.messageRecords = new Map<string, IMCMessage>();\r\n\r\n this.listener = (event: MessageEvent<IMCMessage>) => {\r\n const message = event.data;\r\n const messageId = message.messageId;\r\n const channelId = message.channelId;\r\n const type = message.type;\r\n\r\n // Return if the channel ID exists but does not match the current channel ID\r\n // (channel ID can be undefined during initial handshake)\r\n if (\r\n this.channelId !== undefined &&\r\n channelId !== undefined &&\r\n channelId !== this.channelId\r\n ) {\r\n return;\r\n }\r\n\r\n if (\r\n this.messageRecords?.has(messageId) &&\r\n type !== IMCMessageTypeEnum.SignalRequestOtherWindowId\r\n ) {\r\n console.warn(\r\n `[${\r\n this.thisWindowId\r\n }]: Duplicate message received with message ID: ${messageId}. Ignoring this message. Message: ${JSON.stringify(\r\n message\r\n )}`\r\n );\r\n return;\r\n }\r\n this.messageRecords?.set(messageId, message);\r\n\r\n if (!receiver) {\r\n throw new Error(\r\n \"Receiver not initialized at module \" + this.thisWindowId\r\n );\r\n }\r\n\r\n if (message.from !== undefined && message.type !== IMCMessageTypeEnum.SignalIgnore) {\r\n console.log(\r\n `Module ${this.thisWindowId} received message from module ${\r\n message.from\r\n }:\\n ${JSON.stringify(message)}`\r\n );\r\n }\r\n\r\n if (otherWindowId && message.from !== otherWindowId) {\r\n return;\r\n }\r\n const win = event.source as Window;\r\n receiver.receiveMessage(win, message);\r\n };\r\n window.addEventListener(\"message\", this.listener);\r\n console.log(\"Adding IMC listener in \" + this.thisWindowId);\r\n // refresh the receiver handler map\r\n this.setBaseHandler();\r\n }\r\n\r\n /* Initialize a sender to send message ot the other window. */\r\n public async initOtherWindow(window: Window) {\r\n return new Promise<void>((resolve) => {\r\n if (!this.thisWindow || !this.thisWindowId) {\r\n throw new Error(\"You must initialize the current window first.\");\r\n }\r\n\r\n const onReceiveWindowID = (event: MessageEvent) => {\r\n if (!this.thisWindow || !this.thisWindowId) {\r\n throw new Error(\"You must initialize the current window first.\");\r\n }\r\n\r\n const message = event.data;\r\n const otherWindowId = message.payload;\r\n this.otherWindowId = otherWindowId;\r\n\r\n const sender = new MessageSender(\r\n window,\r\n messageTimeout,\r\n this.thisWindowId,\r\n this.channelId\r\n );\r\n this.sender = sender;\r\n\r\n if (!this.receiverHandlerMap) {\r\n throw new Error(\"You must initialize the current window first.\");\r\n }\r\n\r\n this.setBaseHandler();\r\n resolve();\r\n };\r\n\r\n // Wait for the other window to send its ID.\r\n this.thisWindow.addEventListener(\"message\", onReceiveWindowID, {\r\n once: true,\r\n });\r\n\r\n this.otherWindow = window;\r\n this.otherWindow.postMessage(\r\n {\r\n type: IMCMessageTypeEnum.SignalRequestOtherWindowId,\r\n from: this.thisWindowId,\r\n },\r\n \"*\"\r\n );\r\n });\r\n }\r\n\r\n public close() {\r\n if (this.listener) {\r\n window.removeEventListener(\"message\", this.listener);\r\n }\r\n }\r\n\r\n public async sendMessage(\r\n type: IMCMessageTypeEnum,\r\n payload?: any,\r\n abortSignal?: AbortSignal\r\n ): Promise<any> {\r\n const sender = this.sender;\r\n if (!sender) {\r\n throw new Error(\"Sender not initialized\");\r\n }\r\n\r\n return await sender.sendMessage(type, payload, abortSignal);\r\n }\r\n\r\n public updateReceiverHandlerMap(\r\n receiverHandlerMap: ReceiverHandlerMap\r\n ): void {\r\n if (!this.receiver) {\r\n throw new Error(\"Receiver not initialized\");\r\n }\r\n\r\n // Clear all existing handlers except the acknowledgement handler.\r\n this.receiverHandlerMap?.clear();\r\n this.setBaseHandler();\r\n receiverHandlerMap.forEach((value, key) => {\r\n this.receiverHandlerMap?.set(key, value);\r\n });\r\n }\r\n\r\n public getThisWindowId(): string {\r\n if (!this.thisWindowId) {\r\n throw new Error(\"This window ID is not defined.\");\r\n }\r\n return this.thisWindowId;\r\n }\r\n\r\n public getOtherWindowId(): string {\r\n if (!this.otherWindowId) {\r\n throw new Error(\"Other window ID is not defined.\");\r\n }\r\n return this.otherWindowId;\r\n }\r\n\r\n private setBaseHandler() {\r\n // Add an acknowledgement handler in current window's receiver for results of sent messages.\r\n // This is to receive the acknowledgement from the other window, so that we know the other\r\n // window has received the message and finished processing it.\r\n // The current window must be initialized first. i.e. call initThisWindow() before initOtherWindow().\r\n this.receiverHandlerMap?.set(\r\n IMCMessageTypeEnum.SignalAcknowledge,\r\n async (senderWindow: Window, message: IMCMessage) => {\r\n const pendingMessage = this.sender?.getPendingMessage(\r\n message.messageId\r\n );\r\n if (pendingMessage) {\r\n pendingMessage.resolve(message.payload);\r\n }\r\n }\r\n );\r\n\r\n // Handle error message from the other window.\r\n this.receiverHandlerMap?.set(\r\n IMCMessageTypeEnum.SignalError,\r\n async (senderWindow: Window, message: IMCMessage) => {\r\n const pendingMessage = this.sender?.getPendingMessage(\r\n message.messageId\r\n );\r\n if (pendingMessage) {\r\n pendingMessage.reject(new Error(message.payload));\r\n }\r\n }\r\n );\r\n\r\n // Set get window ID handler in the receiver handler map.\r\n this.receiverHandlerMap?.set(\r\n IMCMessageTypeEnum.SignalRequestOtherWindowId,\r\n async (senderWindow: Window, message: IMCMessage) => {\r\n console.log(\r\n \"Received window ID request. Sending current window ID to other window: \"\r\n );\r\n const id = this.thisWindowId;\r\n if (!id) {\r\n throw new Error(\"This window ID is not defined.\");\r\n }\r\n\r\n return id;\r\n }\r\n );\r\n\r\n // Handle ignore signal\r\n this.receiverHandlerMap?.set(\r\n IMCMessageTypeEnum.SignalIgnore,\r\n async (senderWindow: Window, message: IMCMessage) => {\r\n console.warn(\r\n `Message ignored by receiver. Message ID: ${message.messageId}, Payload: ${message.payload}`\r\n );\r\n const pendingMessage = this.sender?.getPendingMessage(\r\n message.messageId\r\n );\r\n if (pendingMessage) {\r\n pendingMessage.reject(new Error(\"Message ignored by receiver\"));\r\n }\r\n }\r\n );\r\n }\r\n}\r\n","import {\r\n IMCMessage,\r\n IMCMessageTypeEnum,\r\n ReceiverHandler,\r\n ReceiverHandlerMap,\r\n} from \"../types/types\";\r\nimport { InterModuleCommunication } from \"./inter-module-communication\";\r\n\r\n/**\r\n * Poly IMC establishes two-way inter-module communication channels,\r\n * where each channel consists of a sender and a receiver to send and\r\n * receive messages between host window and the other module's window.\r\n *\r\n * This assumes the other window has IMC or Poly-IMC setup.\r\n */\r\nexport class PolyIMC {\r\n // A map that maps the other window ID,\r\n // and IMC between current window and the other window.\r\n private channelsMap: Map<string, InterModuleCommunication[]>;\r\n private baseReceiverHandlerMap: ReceiverHandlerMap;\r\n private channelReceiverHandlerMapMap: Map<string, ReceiverHandlerMap>;\r\n\r\n /**\r\n *\r\n * @param baseReceiverHandlerMap A base receiver handler map for universal handlers.\r\n * E.g. Pulse Editor API handler\r\n */\r\n constructor(baseReceiverHandlerMap: ReceiverHandlerMap) {\r\n this.channelsMap = new Map();\r\n this.baseReceiverHandlerMap = baseReceiverHandlerMap;\r\n this.channelReceiverHandlerMapMap = new Map();\r\n }\r\n\r\n public async sendMessage(\r\n targetWindowId: string,\r\n handlingType: IMCMessageTypeEnum,\r\n payload?: any,\r\n abortSignal?: AbortSignal\r\n ) {\r\n const channels = this.channelsMap.get(targetWindowId);\r\n if (!channels) {\r\n throw new Error(\"Channel not found for window ID \" + targetWindowId);\r\n }\r\n\r\n // - some channels here are not returning results\r\n // - and the result now is an array instead of a single value\r\n\r\n const results: any[] = [];\r\n\r\n await Promise.all(\r\n channels.map(async (channel) => {\r\n try {\r\n const result = await channel.sendMessage(\r\n handlingType,\r\n payload,\r\n abortSignal\r\n );\r\n results.push(result);\r\n } catch (error: any) {\r\n // TODO: better ignore handling\r\n if (error.message === \"Message ignored by receiver\") {\r\n console.warn(\r\n `Message ignored by receiver (window ID ${targetWindowId})`,\r\n error\r\n );\r\n // nothing returned, nothing pushed — completely skipped\r\n return;\r\n }\r\n throw error; // rethrow real errors\r\n }\r\n })\r\n );\r\n\r\n return results;\r\n }\r\n\r\n public updateBaseReceiverHandlerMap(handlerMap: ReceiverHandlerMap) {\r\n this.baseReceiverHandlerMap = handlerMap;\r\n this.channelsMap.forEach((channels, key) => {\r\n const combinedMap = this.getCombinedHandlerMap(\r\n this.baseReceiverHandlerMap,\r\n this.channelReceiverHandlerMapMap.get(key)\r\n );\r\n channels.forEach((channel) => {\r\n channel.updateReceiverHandlerMap(combinedMap);\r\n });\r\n });\r\n }\r\n\r\n public updateChannelReceiverHandlerMap(\r\n targetWindowId: string,\r\n handlerMap: ReceiverHandlerMap\r\n ) {\r\n const channels = this.channelsMap.get(targetWindowId);\r\n if (!channels) {\r\n throw new Error(\"Channel not found for window ID \" + targetWindowId);\r\n }\r\n\r\n const combinedMap = this.getCombinedHandlerMap(\r\n this.baseReceiverHandlerMap,\r\n handlerMap\r\n );\r\n\r\n channels.forEach((channel) => {\r\n channel.updateReceiverHandlerMap(combinedMap);\r\n });\r\n\r\n this.channelReceiverHandlerMapMap.set(targetWindowId, handlerMap);\r\n }\r\n\r\n public async createChannel(\r\n targetWindow: Window,\r\n targetWindowId: string,\r\n intent: string,\r\n channelId?: string,\r\n receiverHandlerMap?: ReceiverHandlerMap\r\n ) {\r\n console.log(\"Creating channel for window ID: \" + targetWindowId);\r\n const channel = new InterModuleCommunication(intent, channelId);\r\n channel.initThisWindow(window, targetWindowId);\r\n await channel.initOtherWindow(targetWindow);\r\n\r\n const newChannels = this.channelsMap.get(targetWindowId) ?? [];\r\n // Add to existing channels\r\n newChannels.push(channel);\r\n\r\n this.channelsMap.set(targetWindowId, newChannels);\r\n\r\n // If there is a channel specific receiver handler map,\r\n // combine it with the base receiver handler map.\r\n if (receiverHandlerMap) {\r\n this.updateChannelReceiverHandlerMap(targetWindowId, receiverHandlerMap);\r\n } else {\r\n channel.updateReceiverHandlerMap(this.baseReceiverHandlerMap);\r\n }\r\n }\r\n\r\n public removeWindowChannels(targetWindowId: string) {\r\n const channels = this.channelsMap.get(targetWindowId);\r\n if (!channels) {\r\n throw new Error(\"Channel not found for window ID \" + targetWindowId);\r\n }\r\n\r\n channels.forEach((channel) => {\r\n channel.close();\r\n });\r\n this.channelsMap.delete(targetWindowId);\r\n this.channelReceiverHandlerMapMap.delete(targetWindowId);\r\n }\r\n\r\n public hasChannel(targetWindowId: string): boolean {\r\n return this.channelsMap.has(targetWindowId);\r\n }\r\n\r\n public close() {\r\n this.channelsMap.forEach((channels) =>\r\n channels.forEach((channel) => channel.close())\r\n );\r\n this.channelsMap.clear();\r\n this.channelReceiverHandlerMapMap.clear();\r\n }\r\n\r\n private getCombinedHandlerMap(\r\n map1?: ReceiverHandlerMap,\r\n map2?: ReceiverHandlerMap\r\n ): ReceiverHandlerMap {\r\n if (map1 && map2) {\r\n // Combine two maps\r\n const combinedMap = new Map([...map1, ...map2]);\r\n\r\n return combinedMap;\r\n } else if (map1) {\r\n return map1;\r\n } else if (map2) {\r\n return map2;\r\n } else {\r\n return new Map();\r\n }\r\n }\r\n}\r\n\r\nexport class ConnectionListener {\r\n private polyIMC: PolyIMC;\r\n private newConnectionReceiverHandlerMap: ReceiverHandlerMap;\r\n private onConnection?: (senderWindow: Window, message: IMCMessage) => void;\r\n\r\n private listener: InterModuleCommunication;\r\n\r\n /**\r\n *\r\n * @param polyIMC The polyIMC instance.\r\n * @param newConnectionReceiverHandlerMap Receiver handler map for newly established poly-IMC channel.\r\n * @param onConnection Callback function to be called when a new connection is established.\r\n * @param expectedOtherWindowId Optional expected other window ID to validate incoming connections.\r\n */\r\n constructor(\r\n polyIMC: PolyIMC,\r\n newConnectionReceiverHandlerMap: ReceiverHandlerMap,\r\n onConnection?: (senderWindow: Window, message: IMCMessage) => void,\r\n expectedOtherWindowId?: string\r\n ) {\r\n this.polyIMC = polyIMC;\r\n this.newConnectionReceiverHandlerMap = newConnectionReceiverHandlerMap;\r\n this.onConnection = onConnection;\r\n\r\n const listener = new InterModuleCommunication(\r\n \"connection-listener\",\r\n undefined\r\n );\r\n this.listener = listener;\r\n listener.initThisWindow(window, expectedOtherWindowId);\r\n\r\n listener.updateReceiverHandlerMap(\r\n new Map<IMCMessageTypeEnum, ReceiverHandler>([\r\n [\r\n IMCMessageTypeEnum.AppReady,\r\n async (\r\n senderWindow: Window,\r\n message: IMCMessage,\r\n abortSignal?: AbortSignal\r\n ) => {\r\n await this.handleExtReady(senderWindow, message, abortSignal);\r\n },\r\n ],\r\n ])\r\n );\r\n }\r\n\r\n public close() {\r\n this.listener?.close();\r\n }\r\n\r\n public updateReceiverHandlerMap(\r\n newReceiverHandlerMap: ReceiverHandlerMap\r\n ): void {\r\n this.newConnectionReceiverHandlerMap = newReceiverHandlerMap;\r\n }\r\n\r\n private async handleExtReady(\r\n senderWindow: Window,\r\n message: IMCMessage,\r\n abortSignal?: AbortSignal\r\n ) {\r\n const targetWindowId = message.from;\r\n const { intent, channelId }: { intent: string; channelId?: string } =\r\n message.payload;\r\n\r\n if (!channelId) {\r\n throw new Error(\"Channel ID is missing in AppReady message.\");\r\n }\r\n\r\n // Create a new channel for the incoming connection\r\n await this.polyIMC.createChannel(\r\n senderWindow,\r\n targetWindowId,\r\n intent,\r\n channelId,\r\n this.newConnectionReceiverHandlerMap\r\n );\r\n\r\n if (this.onConnection) {\r\n this.onConnection(senderWindow, message);\r\n }\r\n }\r\n}\r\n"],"names":["byteToHex","i","push","toString","slice","unsafeStringify","arr","offset","arguments","length","undefined","toLowerCase","getRandomValues","rnds8","Uint8Array","rng","crypto","Error","bind","randomUUID","_v4","options","buf","_ref","_options$random","_options$rng","_options","rnds","random","call","v4","native"],"mappings":"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","x_google_ignoreList":[3,4,5,6]}
@@ -1,40 +1,61 @@
1
1
  export declare enum IMCMessageTypeEnum {
2
- WriteViewFile = "write-view-file",
3
- RequestViewFile = "request-view-file",
4
- Fetch = "fetch",
5
- Notification = "notification",
6
- ThemeChange = "theme-change",
7
- InstallAgent = "install-agent",
8
- RunAgentMethod = "run-agent-method",
9
- InstallAgentTool = "install-agent-tool",
10
- OCR = "ocr",
11
- RequestTerminal = "request-terminal",
12
- Ready = "ready",
13
- Loaded = "loaded",
14
- Acknowledge = "acknowledge",
15
- Abort = "abort",
16
- Error = "error"
2
+ ModalityVAD = "modality-vad",
3
+ ModalitySTT = "modality-stt",
4
+ ModalityLLM = "modality-llm",
5
+ ModalityTTS = "modality-tts",
6
+ ModalitySpeech2Speech = "modality-speech-to-speech",
7
+ ModalityImageGen = "modality-image-gen",
8
+ ModalityVideoGen = "modality-video-gen",
9
+ ModalityOCR = "modality-ocr",
10
+ ModalityMusicGen = "modality-music-gen",
11
+ AppReady = "app-ready",
12
+ AppClose = "app-close",
13
+ EditorLoadingApp = "editor-loading-app",
14
+ EditorRegisterAction = "editor-register-action",
15
+ EditorRunAppAction = "editor-run-app-action",
16
+ EditorRunAgentMethod = "editor-run-agent-method",
17
+ EditorThemeUpdate = "editor-theme-update",
18
+ EditorAppRequestTheme = "editor-app-request-theme",
19
+ EditorShowNotification = "editor-show-notification",
20
+ EditorGetEnv = "editor-get-env",
21
+ EditorAppStateSnapshotRestore = "editor-app-state-snapshot-restore",
22
+ EditorAppStateSnapshotSave = "editor-app-state-snapshot-save",
23
+ EditorAppReceiveFileUri = "editor-app-receive-file-uri",
24
+ EditorAppUseOwnedApp = "editor-app-use-owned-app",
25
+ EditorAppRequestWorkspace = "editor-app-request-workspace",
26
+ PlatformCreateTerminal = "platform-create-terminal",
27
+ PlatformWriteFile = "platform-write-file",
28
+ PlatformReadFile = "platform-read-file",
29
+ PlatformFileUpdate = "platform-file-update",
30
+ SignalRequestOtherWindowId = "signal-request-other-window-id",
31
+ SignalAcknowledge = "signal-acknowledge",
32
+ SignalAbort = "signal-abort",
33
+ SignalError = "signal-error",
34
+ SignalIgnore = "signal-ignore"
17
35
  }
18
36
  export type IMCMessage = {
19
- id: string;
37
+ messageId: string;
38
+ channelId?: string;
20
39
  from: string;
21
40
  type: IMCMessageTypeEnum;
22
41
  payload?: any;
23
42
  };
24
- export type ReceiverHandlerMap = Map<IMCMessageTypeEnum, {
25
- (senderWindow: Window, message: IMCMessage, abortSignal?: AbortSignal): Promise<any>;
26
- }>;
43
+ export type ReceiverHandler = (senderWindow: Window, message: IMCMessage, abortSignal?: AbortSignal) => Promise<any>;
44
+ export type ReceiverHandlerMap = Map<IMCMessageTypeEnum, ReceiverHandler>;
27
45
  export type TextFileSelection = {
28
46
  lineStart: number;
29
47
  lineEnd: number;
30
48
  text: string;
31
49
  };
32
- export type FileViewModel = {
33
- fileContent: string;
34
- filePath: string;
35
- selections?: TextFileSelection[];
36
- isActive: boolean;
50
+ export type ViewModel = {
51
+ viewId: string;
52
+ appConfig: AppConfig;
37
53
  };
54
+ export declare enum ViewModeEnum {
55
+ App = "app",
56
+ Canvas = "canvas",
57
+ Home = "home"
58
+ }
38
59
  export type FetchPayload = {
39
60
  uri: string;
40
61
  options?: RequestInit;
@@ -45,31 +66,44 @@ export declare enum NotificationTypeEnum {
45
66
  Info = "info",
46
67
  Warning = "warning"
47
68
  }
48
- export declare enum ExtensionTypeEnum {
69
+ export declare enum AppTypeEnum {
49
70
  Generic = "generic",
50
71
  FileView = "file-view",
51
72
  ConsoleView = "console-view"
52
73
  }
53
- export type ExtensionConfig = {
74
+ export type AppConfig = {
54
75
  id: string;
55
76
  version: string;
77
+ libVersion?: string;
78
+ visibility?: "public" | "private" | "unlisted";
56
79
  author?: string;
57
80
  displayName?: string;
58
81
  description?: string;
59
82
  materialIcon?: string;
60
- extensionType?: ExtensionTypeEnum;
83
+ appType?: AppTypeEnum;
61
84
  fileTypes?: string[];
62
- preview?: string;
85
+ thumbnail?: string;
63
86
  enabledPlatforms?: Record<string, boolean>;
87
+ agents?: Agent[];
88
+ preRegisteredActions?: Action[];
89
+ recommendedHeight?: number;
90
+ recommendedWidth?: number;
91
+ };
92
+ export type Action = {
93
+ name: string;
94
+ description: string;
95
+ parameters: Record<string, TypedVariable>;
96
+ returns: Record<string, TypedVariable>;
97
+ handler?: (args: any) => Promise<any>;
64
98
  };
65
99
  export type Agent = {
66
100
  name: string;
67
101
  version: string;
68
102
  systemPrompt: string;
69
103
  availableMethods: AgentMethod[];
70
- LLMConfig: LLMConfig;
71
104
  description: string;
72
105
  tools?: AgentTool[];
106
+ LLMConfig?: LLMConfig;
73
107
  };
74
108
  /**
75
109
  * An agent method is a sub task that an agent can perform.
@@ -77,43 +111,60 @@ export type Agent = {
77
111
  export type AgentMethod = {
78
112
  access: AccessEnum;
79
113
  name: string;
80
- parameters: Record<string, AgentVariable>;
114
+ parameters: Record<string, TypedVariable>;
81
115
  prompt: string;
82
- returns: Record<string, AgentVariable>;
116
+ returns: Record<string, TypedVariable>;
83
117
  LLMConfig?: LLMConfig;
84
118
  };
85
- export type AgentVariable = {
86
- type: AgentVariableType;
119
+ export type TypedVariable = {
120
+ type: TypedVariableType;
87
121
  description: string;
88
- };
89
- export type AgentVariableType = "string" | "number" | "boolean" | AgentVariableTypeArray;
90
- type AgentVariableTypeArray = {
91
- size: number;
92
- elementType: AgentVariableType;
122
+ optional?: boolean;
123
+ defaultValue?: any;
93
124
  };
94
125
  /**
95
126
  * A tool that agent can use during method execution.
96
127
  *
97
- * This is linked to a callback function created by user,
98
- * tool developer, or extension.
99
128
  *
100
- * The tool may optionally return a value to running
101
- * agent method.
129
+ * The tool may optionally return a value to the agent.
102
130
  */
103
131
  export type AgentTool = {
104
132
  access: AccessEnum;
105
133
  name: string;
106
134
  description: string;
107
- parameters: Record<string, AgentVariable>;
108
- returns: Record<string, AgentVariable>;
135
+ parameters: Record<string, TypedVariable>;
136
+ returns: Record<string, TypedVariable>;
109
137
  };
110
- export type LLMConfig = {
111
- provider: string;
112
- modelName: string;
113
- temperature: number;
138
+ export type TypedVariableType = "string" | "number" | "boolean" | "any" | "app-instance" | TypedVariableObjectType | TypedVariableArrayType;
139
+ export type TypedVariableObjectType = {
140
+ [key: string]: TypedVariable;
114
141
  };
142
+ export type TypedVariableArrayType = [TypedVariableType];
143
+ export declare function isArrayType(value: TypedVariableType): value is TypedVariableArrayType;
144
+ export declare function isObjectType(value: TypedVariableType): value is TypedVariableObjectType;
115
145
  export declare enum AccessEnum {
116
146
  public = "public",
117
147
  private = "private"
118
148
  }
119
- export {};
149
+ export type STTConfig = {
150
+ provider: string;
151
+ modelName: string;
152
+ };
153
+ export type LLMConfig = {
154
+ provider: string;
155
+ modelName: string;
156
+ temperature: number;
157
+ };
158
+ export type TTSConfig = {
159
+ provider: string;
160
+ modelName: string;
161
+ voice: string;
162
+ };
163
+ export type ImageModelConfig = {
164
+ provider: string;
165
+ modelName: string;
166
+ };
167
+ export type VideoModelConfig = {
168
+ provider: string;
169
+ modelName: string;
170
+ };
package/package.json CHANGED
@@ -1,30 +1,33 @@
1
1
  {
2
2
  "name": "@pulse-editor/shared-utils",
3
- "version": "0.1.1-beta.1",
3
+ "version": "0.1.1-beta.56",
4
4
  "main": "dist/main.js",
5
- "type": "module",
6
5
  "files": [
7
6
  "dist"
8
7
  ],
9
8
  "publishConfig": {
10
9
  "access": "public"
11
10
  },
11
+ "types": "dist/main.d.ts",
12
+ "type": "module",
12
13
  "scripts": {
13
- "build": "rollup -c",
14
- "lint": "eslint ."
14
+ "build": "npm run clean && rollup -c",
15
+ "lint": "eslint .",
16
+ "clean": "rimraf dist"
15
17
  },
16
18
  "devDependencies": {
17
19
  "@babel/core": "^7.26.10",
18
20
  "@babel/preset-env": "^7.26.9",
19
21
  "@eslint/js": "^9.25.0",
20
22
  "@rollup/plugin-babel": "^6.0.4",
23
+ "@rollup/plugin-json": "^6.1.0",
21
24
  "@rollup/plugin-node-resolve": "^16.0.1",
22
- "@rollup/plugin-terser": "^0.4.4",
23
25
  "@rollup/plugin-typescript": "^12.1.2",
24
26
  "@types/node": "^22.13.1",
25
27
  "eslint": "^9.25.0",
28
+ "rimraf": "^3.0.2",
26
29
  "rollup": "^4.40.0",
27
30
  "typescript": "^5.8.3",
28
31
  "typescript-eslint": "^8.30.1"
29
32
  }
30
- }
33
+ }
@@ -1 +0,0 @@
1
- import{IMCMessageTypeEnum as e}from"../types/types.js";import{messageTimeout as s}from"../types/constants.js";import{MessageReceiver as i}from"./message-receiver.js";import{MessageSender as t}from"./message-sender.js";class r{constructor(e){this.moduleName=e}initThisWindow(e){this.thisWindow=e,this.receiverHandlerMap=new Map,this.thisPendingTasks=new Map;const s=new i(this.receiverHandlerMap,this.thisPendingTasks,this.moduleName);this.receiver=s,this.listener=e=>{if(!s)throw new Error("Receiver not initialized at module "+this.moduleName);const i=e.data,t=e.source;s.receiveMessage(t,i)},e.addEventListener("message",this.listener),console.log("Adding IMC listener in "+this.moduleName)}initOtherWindow(i){this.otherWindow=i,this.otherPendingMessages=new Map;const r=new t(i,s,this.otherPendingMessages,this.moduleName);if(this.sender=r,!this.receiverHandlerMap)throw new Error("You must initialize the current window first.");this.receiverHandlerMap.set(e.Acknowledge,(async(e,s)=>{const i=this.otherPendingMessages?.get(s.id);i&&(i.resolve(s.payload),this.otherPendingMessages?.delete(s.id))}))}close(){this.listener&&window.removeEventListener("message",this.listener)}async sendMessage(e,s,i){if(!this.sender)throw new Error("Sender not initialized");return await this.sender.sendMessage(e,s,i)}updateReceiverHandlerMap(e){if(!this.receiver)throw new Error("Receiver not initialized");this.receiverHandlerMap?.clear(),e.forEach(((e,s)=>{this.receiverHandlerMap?.set(s,e)}))}}export{r as InterModuleCommunication};
@@ -1 +0,0 @@
1
- import{IMCMessageTypeEnum as e}from"../types/types.js";class s{constructor(e,s,o){this.handlerMap=e,this.pendingTasks=s,this.moduleName=o}receiveMessage(s,o){if(this.moduleName===o.from)return;if("development"===process.env.NODE_ENV&&console.log(`Module ${this.moduleName} received message from module ${o.from}:\n ${JSON.stringify(o)}`),o.type===e.Abort){const e=o.id,s=this.pendingTasks.get(e);return void(s&&(console.log("Aborting task",e),s.controller.abort(),this.pendingTasks.delete(e)))}const t=this.handlerMap.get(o.type);if(t){const n=new AbortController,i=n.signal;this.pendingTasks.set(o.id,{controller:n});t(s,o,i).then((t=>{i.aborted||o.type!==e.Acknowledge&&this.acknowledgeSender(s,o.id,t)})).catch((t=>{const n={id:o.id,type:e.Error,payload:t.message,from:this.moduleName};s.postMessage(n,"*")})).finally((()=>{this.pendingTasks.delete(o.id)}))}}acknowledgeSender(s,o,t){const n={id:o,type:e.Acknowledge,payload:t,from:this.moduleName};s.postMessage(n,"*")}}export{s as MessageReceiver};
@@ -1 +0,0 @@
1
- import{IMCMessageTypeEnum as e}from"../types/types.js";class t{constructor(e,t,s,r){this.targetWindow=e,this.timeout=t,this.pendingMessages=s,this.moduleName=r}async sendMessage(t,s,r){const o=(new Date).getTime().toString(),i={id:o,type:t,payload:s,from:this.moduleName};return new Promise(((t,s)=>{if(r?.aborted)return s(new Error("Request aborted"));const n=()=>{this.pendingMessages.delete(o),this.targetWindow.postMessage({id:o,type:e.Abort,payload:JSON.stringify({status:"Task aborted",data:null})},"*"),s(new Error("Request aborted"))};r?.addEventListener("abort",n),this.pendingMessages.set(o,{resolve:t,reject:s}),this.targetWindow.postMessage(i,"*");const a=setTimeout((()=>{this.pendingMessages.delete(o),r?.removeEventListener("abort",n),s(new Error("Communication with Pulse Editor timeout."))}),this.timeout),d=this.pendingMessages.get(o);d&&(d.resolve=e=>{clearTimeout(a),r?.removeEventListener("abort",n),t(e)},d.reject=()=>{clearTimeout(a),r?.removeEventListener("abort",n),s()})}))}}export{t as MessageSender};
@@ -1 +0,0 @@
1
- const e=3e5;export{e as messageTimeout};
@@ -1 +0,0 @@
1
- var e,i,n,t;!function(e){e.WriteViewFile="write-view-file",e.RequestViewFile="request-view-file",e.Fetch="fetch",e.Notification="notification",e.ThemeChange="theme-change",e.InstallAgent="install-agent",e.RunAgentMethod="run-agent-method",e.InstallAgentTool="install-agent-tool",e.OCR="ocr",e.RequestTerminal="request-terminal",e.Ready="ready",e.Loaded="loaded",e.Acknowledge="acknowledge",e.Abort="abort",e.Error="error"}(e||(e={})),function(e){e.Success="success",e.Error="error",e.Info="info",e.Warning="warning"}(i||(i={})),function(e){e.Generic="generic",e.FileView="file-view",e.ConsoleView="console-view"}(n||(n={})),function(e){e.public="public",e.private="private"}(t||(t={}));export{t as AccessEnum,n as ExtensionTypeEnum,e as IMCMessageTypeEnum,i as NotificationTypeEnum};