iframe-pubsub 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -10,6 +10,21 @@ interface IMessage {
10
10
  to: string;
11
11
  payload: any;
12
12
  }
13
+ declare enum AIChatNameEnum {
14
+ AI_CHAT_CLIENT_ID = "aichat",
15
+ AI_CHAT_INTERNAL_COMM_TYPE = "pubsub",
16
+ SET_PARENT_NAME = "setParentName",
17
+ SET_USER_ID = "setUserId",
18
+ SET_CUSTOM_HEADERS = "setCustomHeaders",
19
+ SET_CUSTOM_PAYLOAD = "setCustomPayload",
20
+ SET_SUGGESTIONS = "setSuggestions",
21
+ SHOW_SUGGESTIONS = "showSuggestions",
22
+ SHOW_CHAT_MESSAGE = "showChatMessage",
23
+ CONFIRM_ACTION = "confirmAction",
24
+ SHOW_OPTIONS = "showOptions",
25
+ SEND_CHAT_PROMPT = "sendChatPrompt",
26
+ DEFAULT = "default"
27
+ }
13
28
  type MessageCallback = (message: IMessage) => void | Promise<void>;
14
29
  declare class PubSub {
15
30
  private static instance;
@@ -33,7 +48,22 @@ declare class PubSub {
33
48
  */
34
49
  unregister(pageId: string): void;
35
50
  sendMessage(message: IMessage): void;
51
+ /**
52
+ * Try to send a message to a client with retry logic.
53
+ * Will retry up to 3 times with 1 second delay between retries.
54
+ *
55
+ * @param message The message to send.
56
+ * @param retryCount The current retry count.
57
+ */
58
+ private trySendMessageWithRetry;
36
59
  private handleMessage;
60
+ /**
61
+ * Check if a client with the given ID exists in the PubSub system.
62
+ *
63
+ * @param clientId The ID of the client to check.
64
+ * @returns True if the client exists, false otherwise.
65
+ */
66
+ isClientExists(clientId: string): boolean;
37
67
  }
38
68
  declare class Client {
39
69
  private pageId;
@@ -46,6 +76,10 @@ declare class Client {
46
76
  * @param pageId The ID of the page or component to register to.
47
77
  */
48
78
  constructor(pageId: string);
79
+ /**
80
+ * Unregister the client from the pubsub.
81
+ */
82
+ unregister(): void;
49
83
  /**
50
84
  * Listen for messages from the parent page with a callback.
51
85
  *
@@ -59,7 +93,87 @@ declare class Client {
59
93
  * @param payload The payload of the message.
60
94
  */
61
95
  sendMessage(to: string, payload: any): void;
96
+ private sendAIChatMethod;
97
+ /**
98
+ * Set the parent name then the AI Chat can know who should it communicate with.
99
+ *
100
+ * @param parentName The name of the parent page.
101
+ */
102
+ setParentName(parentName: string): void;
103
+ /**
104
+ * Set the user ID for the AI Chat component.
105
+ *
106
+ * @param userId The user ID.
107
+ */
108
+ setUserId(userId: string): void;
109
+ /**
110
+ * Set custom headers for the AI Chat component.
111
+ *
112
+ * @param headers The custom headers.
113
+ */
114
+ setCustomHeaders(headers: Record<string, string>): void;
115
+ /**
116
+ * Set custom payload for the AI Chat component.
117
+ *
118
+ * @param payload The custom payload.
119
+ */
120
+ setCustomPayload(payload: Record<string, any>): void;
121
+ /**
122
+ * Set suggestions for the AI Chat component.
123
+ *
124
+ * @param suggestions The suggestions to set.
125
+ */
126
+ setSuggestions(suggestions: any[]): void;
127
+ /**
128
+ * Show suggestions in the AI Chat component.
129
+ *
130
+ * @param show Whether to show suggestions.
131
+ */
132
+ showSuggestions(show: boolean): void;
133
+ /**
134
+ * Show a chat message in the AI Chat component.
135
+ *
136
+ * @param message The message to show.
137
+ */
138
+ showChatMessage(message: string): void;
139
+ /**
140
+ * Confirm an action in the AI Chat component.
141
+ *
142
+ * @param action The action to confirm.
143
+ */
144
+ confirmAction(action: any): void;
145
+ /**
146
+ * Show options in the AI Chat component.
147
+ *
148
+ * @param options The options to show.
149
+ */
150
+ showOptions(options: any[]): void;
151
+ /**
152
+ * Send a chat prompt to the AI Chat component.
153
+ *
154
+ * @param prompt The prompt to send.
155
+ */
156
+ sendChatPrompt(prompt: string): void;
157
+ /**
158
+ * Check if a client with the given ID exists in the PubSub system.
159
+ *
160
+ * @param clientId The ID of the client to check.
161
+ * @param maxRetries Maximum number of retries. Default is 3.
162
+ * @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
163
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
164
+ */
165
+ checkClientExists(clientId: string, maxRetries?: number, retryInterval?: number): Promise<boolean>;
166
+ /**
167
+ * Check if a client with the given ID exists in the PubSub system with retry mechanism.
168
+ * Will retry up to 3 times with 1 second delay between retries.
169
+ *
170
+ * @param clientId The ID of the client to check.
171
+ * @param retryCount The current retry count.
172
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
173
+ * @private
174
+ */
175
+ private checkClientExistsWithRetry;
62
176
  private handleMessage;
63
177
  }
64
178
 
65
- export { Client, type IMessage, type MessageCallback, PubSub };
179
+ export { AIChatNameEnum, Client, type IMessage, type MessageCallback, PubSub };
package/dist/index.d.ts CHANGED
@@ -10,6 +10,21 @@ interface IMessage {
10
10
  to: string;
11
11
  payload: any;
12
12
  }
13
+ declare enum AIChatNameEnum {
14
+ AI_CHAT_CLIENT_ID = "aichat",
15
+ AI_CHAT_INTERNAL_COMM_TYPE = "pubsub",
16
+ SET_PARENT_NAME = "setParentName",
17
+ SET_USER_ID = "setUserId",
18
+ SET_CUSTOM_HEADERS = "setCustomHeaders",
19
+ SET_CUSTOM_PAYLOAD = "setCustomPayload",
20
+ SET_SUGGESTIONS = "setSuggestions",
21
+ SHOW_SUGGESTIONS = "showSuggestions",
22
+ SHOW_CHAT_MESSAGE = "showChatMessage",
23
+ CONFIRM_ACTION = "confirmAction",
24
+ SHOW_OPTIONS = "showOptions",
25
+ SEND_CHAT_PROMPT = "sendChatPrompt",
26
+ DEFAULT = "default"
27
+ }
13
28
  type MessageCallback = (message: IMessage) => void | Promise<void>;
14
29
  declare class PubSub {
15
30
  private static instance;
@@ -33,7 +48,22 @@ declare class PubSub {
33
48
  */
34
49
  unregister(pageId: string): void;
35
50
  sendMessage(message: IMessage): void;
51
+ /**
52
+ * Try to send a message to a client with retry logic.
53
+ * Will retry up to 3 times with 1 second delay between retries.
54
+ *
55
+ * @param message The message to send.
56
+ * @param retryCount The current retry count.
57
+ */
58
+ private trySendMessageWithRetry;
36
59
  private handleMessage;
60
+ /**
61
+ * Check if a client with the given ID exists in the PubSub system.
62
+ *
63
+ * @param clientId The ID of the client to check.
64
+ * @returns True if the client exists, false otherwise.
65
+ */
66
+ isClientExists(clientId: string): boolean;
37
67
  }
38
68
  declare class Client {
39
69
  private pageId;
@@ -46,6 +76,10 @@ declare class Client {
46
76
  * @param pageId The ID of the page or component to register to.
47
77
  */
48
78
  constructor(pageId: string);
79
+ /**
80
+ * Unregister the client from the pubsub.
81
+ */
82
+ unregister(): void;
49
83
  /**
50
84
  * Listen for messages from the parent page with a callback.
51
85
  *
@@ -59,7 +93,87 @@ declare class Client {
59
93
  * @param payload The payload of the message.
60
94
  */
61
95
  sendMessage(to: string, payload: any): void;
96
+ private sendAIChatMethod;
97
+ /**
98
+ * Set the parent name then the AI Chat can know who should it communicate with.
99
+ *
100
+ * @param parentName The name of the parent page.
101
+ */
102
+ setParentName(parentName: string): void;
103
+ /**
104
+ * Set the user ID for the AI Chat component.
105
+ *
106
+ * @param userId The user ID.
107
+ */
108
+ setUserId(userId: string): void;
109
+ /**
110
+ * Set custom headers for the AI Chat component.
111
+ *
112
+ * @param headers The custom headers.
113
+ */
114
+ setCustomHeaders(headers: Record<string, string>): void;
115
+ /**
116
+ * Set custom payload for the AI Chat component.
117
+ *
118
+ * @param payload The custom payload.
119
+ */
120
+ setCustomPayload(payload: Record<string, any>): void;
121
+ /**
122
+ * Set suggestions for the AI Chat component.
123
+ *
124
+ * @param suggestions The suggestions to set.
125
+ */
126
+ setSuggestions(suggestions: any[]): void;
127
+ /**
128
+ * Show suggestions in the AI Chat component.
129
+ *
130
+ * @param show Whether to show suggestions.
131
+ */
132
+ showSuggestions(show: boolean): void;
133
+ /**
134
+ * Show a chat message in the AI Chat component.
135
+ *
136
+ * @param message The message to show.
137
+ */
138
+ showChatMessage(message: string): void;
139
+ /**
140
+ * Confirm an action in the AI Chat component.
141
+ *
142
+ * @param action The action to confirm.
143
+ */
144
+ confirmAction(action: any): void;
145
+ /**
146
+ * Show options in the AI Chat component.
147
+ *
148
+ * @param options The options to show.
149
+ */
150
+ showOptions(options: any[]): void;
151
+ /**
152
+ * Send a chat prompt to the AI Chat component.
153
+ *
154
+ * @param prompt The prompt to send.
155
+ */
156
+ sendChatPrompt(prompt: string): void;
157
+ /**
158
+ * Check if a client with the given ID exists in the PubSub system.
159
+ *
160
+ * @param clientId The ID of the client to check.
161
+ * @param maxRetries Maximum number of retries. Default is 3.
162
+ * @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
163
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
164
+ */
165
+ checkClientExists(clientId: string, maxRetries?: number, retryInterval?: number): Promise<boolean>;
166
+ /**
167
+ * Check if a client with the given ID exists in the PubSub system with retry mechanism.
168
+ * Will retry up to 3 times with 1 second delay between retries.
169
+ *
170
+ * @param clientId The ID of the client to check.
171
+ * @param retryCount The current retry count.
172
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
173
+ * @private
174
+ */
175
+ private checkClientExistsWithRetry;
62
176
  private handleMessage;
63
177
  }
64
178
 
65
- export { Client, type IMessage, type MessageCallback, PubSub };
179
+ export { AIChatNameEnum, Client, type IMessage, type MessageCallback, PubSub };
package/dist/index.js CHANGED
@@ -22,10 +22,27 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
22
22
  // src/index.ts
23
23
  var index_exports = {};
24
24
  __export(index_exports, {
25
+ AIChatNameEnum: () => AIChatNameEnum,
25
26
  Client: () => Client,
26
27
  PubSub: () => PubSub
27
28
  });
28
29
  module.exports = __toCommonJS(index_exports);
30
+ var AIChatNameEnum = /* @__PURE__ */ ((AIChatNameEnum2) => {
31
+ AIChatNameEnum2["AI_CHAT_CLIENT_ID"] = "aichat";
32
+ AIChatNameEnum2["AI_CHAT_INTERNAL_COMM_TYPE"] = "pubsub";
33
+ AIChatNameEnum2["SET_PARENT_NAME"] = "setParentName";
34
+ AIChatNameEnum2["SET_USER_ID"] = "setUserId";
35
+ AIChatNameEnum2["SET_CUSTOM_HEADERS"] = "setCustomHeaders";
36
+ AIChatNameEnum2["SET_CUSTOM_PAYLOAD"] = "setCustomPayload";
37
+ AIChatNameEnum2["SET_SUGGESTIONS"] = "setSuggestions";
38
+ AIChatNameEnum2["SHOW_SUGGESTIONS"] = "showSuggestions";
39
+ AIChatNameEnum2["SHOW_CHAT_MESSAGE"] = "showChatMessage";
40
+ AIChatNameEnum2["CONFIRM_ACTION"] = "confirmAction";
41
+ AIChatNameEnum2["SHOW_OPTIONS"] = "showOptions";
42
+ AIChatNameEnum2["SEND_CHAT_PROMPT"] = "sendChatPrompt";
43
+ AIChatNameEnum2["DEFAULT"] = "default";
44
+ return AIChatNameEnum2;
45
+ })(AIChatNameEnum || {});
29
46
  var _PubSub = class _PubSub {
30
47
  constructor() {
31
48
  __publicField(this, "subscribers");
@@ -65,12 +82,31 @@ var _PubSub = class _PubSub {
65
82
  if (this.mainCallback) {
66
83
  this.mainCallback(message);
67
84
  }
85
+ this.trySendMessageWithRetry(message, 0);
86
+ }
87
+ /**
88
+ * Try to send a message to a client with retry logic.
89
+ * Will retry up to 3 times with 1 second delay between retries.
90
+ *
91
+ * @param message The message to send.
92
+ * @param retryCount The current retry count.
93
+ */
94
+ trySendMessageWithRetry(message, retryCount) {
68
95
  const subscriber = this.subscribers.get(message.to);
69
- if (!subscriber) return;
70
- if (subscriber.source) {
71
- subscriber.source.postMessage(message, "*");
96
+ if (subscriber) {
97
+ if (subscriber.source) {
98
+ subscriber.source.postMessage(message, "*");
99
+ } else {
100
+ subscriber.callback(message);
101
+ }
102
+ return;
103
+ }
104
+ if (retryCount < 10) {
105
+ setTimeout(() => {
106
+ this.trySendMessageWithRetry(message, retryCount + 1);
107
+ }, 1e3);
72
108
  } else {
73
- subscriber.callback(message);
109
+ console.warn(`Failed to send message to client ${message.to} after 10 retries`);
74
110
  }
75
111
  }
76
112
  async handleMessage(event) {
@@ -86,6 +122,19 @@ var _PubSub = class _PubSub {
86
122
  });
87
123
  return;
88
124
  }
125
+ if (data?.type === "UNREGISTER") {
126
+ const unregistration = data;
127
+ this.subscribers.delete(unregistration.pageId);
128
+ return;
129
+ }
130
+ if (data?.type === "CLIENT_EXISTS_CHECK") {
131
+ source.postMessage({
132
+ type: "CLIENT_EXISTS_RESPONSE",
133
+ requestId: data.requestId,
134
+ exists: this.subscribers.has(data.clientId)
135
+ }, "*");
136
+ return;
137
+ }
89
138
  if (!data || !data.from || !data.to) return;
90
139
  const message = data;
91
140
  if (this.mainCallback) {
@@ -99,6 +148,15 @@ var _PubSub = class _PubSub {
99
148
  await subscriber.callback(message);
100
149
  }
101
150
  }
151
+ /**
152
+ * Check if a client with the given ID exists in the PubSub system.
153
+ *
154
+ * @param clientId The ID of the client to check.
155
+ * @returns True if the client exists, false otherwise.
156
+ */
157
+ isClientExists(clientId) {
158
+ return this.subscribers.has(clientId);
159
+ }
102
160
  };
103
161
  __publicField(_PubSub, "instance");
104
162
  var PubSub = _PubSub;
@@ -126,6 +184,19 @@ var Client = class {
126
184
  this.pubsub.register(pageId, this.handleMessage.bind(this));
127
185
  }
128
186
  }
187
+ /**
188
+ * Unregister the client from the pubsub.
189
+ */
190
+ unregister() {
191
+ if (this.isIframe) {
192
+ window.parent.postMessage({
193
+ type: "UNREGISTER",
194
+ pageId: this.pageId
195
+ }, "*");
196
+ } else {
197
+ this.pubsub.unregister(this.pageId);
198
+ }
199
+ }
129
200
  /**
130
201
  * Listen for messages from the parent page with a callback.
131
202
  *
@@ -152,6 +223,163 @@ var Client = class {
152
223
  this.pubsub.sendMessage(message);
153
224
  }
154
225
  }
226
+ sendAIChatMethod(methodName, arg) {
227
+ this.sendMessage(
228
+ "aichat" /* AI_CHAT_CLIENT_ID */,
229
+ // This name is hardcode, do not change it
230
+ {
231
+ type: "pubsub" /* AI_CHAT_INTERNAL_COMM_TYPE */,
232
+ // This name is hardcode, do not change it
233
+ methodName,
234
+ arg
235
+ }
236
+ );
237
+ }
238
+ /**
239
+ * Set the parent name then the AI Chat can know who should it communicate with.
240
+ *
241
+ * @param parentName The name of the parent page.
242
+ */
243
+ setParentName(parentName) {
244
+ this.sendAIChatMethod("setParentName" /* SET_PARENT_NAME */, parentName);
245
+ }
246
+ /**
247
+ * Set the user ID for the AI Chat component.
248
+ *
249
+ * @param userId The user ID.
250
+ */
251
+ setUserId(userId) {
252
+ this.sendAIChatMethod("setUserId" /* SET_USER_ID */, userId);
253
+ }
254
+ /**
255
+ * Set custom headers for the AI Chat component.
256
+ *
257
+ * @param headers The custom headers.
258
+ */
259
+ setCustomHeaders(headers) {
260
+ this.sendAIChatMethod("setCustomHeaders" /* SET_CUSTOM_HEADERS */, headers);
261
+ }
262
+ /**
263
+ * Set custom payload for the AI Chat component.
264
+ *
265
+ * @param payload The custom payload.
266
+ */
267
+ setCustomPayload(payload) {
268
+ this.sendAIChatMethod("setCustomPayload" /* SET_CUSTOM_PAYLOAD */, payload);
269
+ }
270
+ /**
271
+ * Set suggestions for the AI Chat component.
272
+ *
273
+ * @param suggestions The suggestions to set.
274
+ */
275
+ setSuggestions(suggestions) {
276
+ this.sendAIChatMethod("setSuggestions" /* SET_SUGGESTIONS */, suggestions);
277
+ }
278
+ /**
279
+ * Show suggestions in the AI Chat component.
280
+ *
281
+ * @param show Whether to show suggestions.
282
+ */
283
+ showSuggestions(show) {
284
+ this.sendAIChatMethod("showSuggestions" /* SHOW_SUGGESTIONS */, show);
285
+ }
286
+ /**
287
+ * Show a chat message in the AI Chat component.
288
+ *
289
+ * @param message The message to show.
290
+ */
291
+ showChatMessage(message) {
292
+ this.sendAIChatMethod("showChatMessage" /* SHOW_CHAT_MESSAGE */, message);
293
+ }
294
+ /**
295
+ * Confirm an action in the AI Chat component.
296
+ *
297
+ * @param action The action to confirm.
298
+ */
299
+ confirmAction(action) {
300
+ this.sendAIChatMethod("confirmAction" /* CONFIRM_ACTION */, action);
301
+ }
302
+ /**
303
+ * Show options in the AI Chat component.
304
+ *
305
+ * @param options The options to show.
306
+ */
307
+ showOptions(options) {
308
+ this.sendAIChatMethod("showOptions" /* SHOW_OPTIONS */, options);
309
+ }
310
+ /**
311
+ * Send a chat prompt to the AI Chat component.
312
+ *
313
+ * @param prompt The prompt to send.
314
+ */
315
+ sendChatPrompt(prompt) {
316
+ this.sendAIChatMethod("sendChatPrompt" /* SEND_CHAT_PROMPT */, prompt);
317
+ }
318
+ /**
319
+ * Check if a client with the given ID exists in the PubSub system.
320
+ *
321
+ * @param clientId The ID of the client to check.
322
+ * @param maxRetries Maximum number of retries. Default is 3.
323
+ * @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
324
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
325
+ */
326
+ checkClientExists(clientId, maxRetries = 3, retryInterval = 1e3) {
327
+ return this.checkClientExistsWithRetry(clientId, 0, maxRetries, retryInterval);
328
+ }
329
+ /**
330
+ * Check if a client with the given ID exists in the PubSub system with retry mechanism.
331
+ * Will retry up to 3 times with 1 second delay between retries.
332
+ *
333
+ * @param clientId The ID of the client to check.
334
+ * @param retryCount The current retry count.
335
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
336
+ * @private
337
+ */
338
+ checkClientExistsWithRetry(clientId, retryCount, maxRetries, retryInterval) {
339
+ return new Promise((resolve) => {
340
+ if (this.isIframe) {
341
+ const requestId = `check-client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
342
+ const messageHandler = (event) => {
343
+ const data = event.data;
344
+ if (data && data.type === "CLIENT_EXISTS_RESPONSE" && data.requestId === requestId) {
345
+ window.removeEventListener("message", messageHandler);
346
+ clearTimeout(removeHandlerTimeout);
347
+ if (data.exists) {
348
+ resolve(true);
349
+ } else if (retryCount < maxRetries - 1) {
350
+ setTimeout(() => {
351
+ this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists) => resolve(exists));
352
+ }, retryInterval);
353
+ } else {
354
+ resolve(false);
355
+ }
356
+ }
357
+ };
358
+ window.addEventListener("message", messageHandler);
359
+ window.parent.postMessage({
360
+ type: "CLIENT_EXISTS_CHECK",
361
+ clientId,
362
+ requestId,
363
+ from: this.pageId
364
+ }, "*");
365
+ const removeHandlerTimeout = setTimeout(() => {
366
+ window.removeEventListener("message", messageHandler);
367
+ resolve(false);
368
+ }, retryInterval + 1e3);
369
+ } else {
370
+ const exists = this.pubsub.isClientExists(clientId);
371
+ if (exists) {
372
+ resolve(true);
373
+ } else if (retryCount < maxRetries - 1) {
374
+ setTimeout(() => {
375
+ this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists2) => resolve(exists2));
376
+ }, retryInterval);
377
+ } else {
378
+ resolve(false);
379
+ }
380
+ }
381
+ });
382
+ }
155
383
  async handleMessage(event) {
156
384
  let message;
157
385
  if (event.data) {
@@ -172,6 +400,7 @@ var Client = class {
172
400
  };
173
401
  // Annotate the CommonJS export names for ESM import in node:
174
402
  0 && (module.exports = {
403
+ AIChatNameEnum,
175
404
  Client,
176
405
  PubSub
177
406
  });
package/dist/index.mjs CHANGED
@@ -3,6 +3,22 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
 
5
5
  // src/index.ts
6
+ var AIChatNameEnum = /* @__PURE__ */ ((AIChatNameEnum2) => {
7
+ AIChatNameEnum2["AI_CHAT_CLIENT_ID"] = "aichat";
8
+ AIChatNameEnum2["AI_CHAT_INTERNAL_COMM_TYPE"] = "pubsub";
9
+ AIChatNameEnum2["SET_PARENT_NAME"] = "setParentName";
10
+ AIChatNameEnum2["SET_USER_ID"] = "setUserId";
11
+ AIChatNameEnum2["SET_CUSTOM_HEADERS"] = "setCustomHeaders";
12
+ AIChatNameEnum2["SET_CUSTOM_PAYLOAD"] = "setCustomPayload";
13
+ AIChatNameEnum2["SET_SUGGESTIONS"] = "setSuggestions";
14
+ AIChatNameEnum2["SHOW_SUGGESTIONS"] = "showSuggestions";
15
+ AIChatNameEnum2["SHOW_CHAT_MESSAGE"] = "showChatMessage";
16
+ AIChatNameEnum2["CONFIRM_ACTION"] = "confirmAction";
17
+ AIChatNameEnum2["SHOW_OPTIONS"] = "showOptions";
18
+ AIChatNameEnum2["SEND_CHAT_PROMPT"] = "sendChatPrompt";
19
+ AIChatNameEnum2["DEFAULT"] = "default";
20
+ return AIChatNameEnum2;
21
+ })(AIChatNameEnum || {});
6
22
  var _PubSub = class _PubSub {
7
23
  constructor() {
8
24
  __publicField(this, "subscribers");
@@ -42,12 +58,31 @@ var _PubSub = class _PubSub {
42
58
  if (this.mainCallback) {
43
59
  this.mainCallback(message);
44
60
  }
61
+ this.trySendMessageWithRetry(message, 0);
62
+ }
63
+ /**
64
+ * Try to send a message to a client with retry logic.
65
+ * Will retry up to 3 times with 1 second delay between retries.
66
+ *
67
+ * @param message The message to send.
68
+ * @param retryCount The current retry count.
69
+ */
70
+ trySendMessageWithRetry(message, retryCount) {
45
71
  const subscriber = this.subscribers.get(message.to);
46
- if (!subscriber) return;
47
- if (subscriber.source) {
48
- subscriber.source.postMessage(message, "*");
72
+ if (subscriber) {
73
+ if (subscriber.source) {
74
+ subscriber.source.postMessage(message, "*");
75
+ } else {
76
+ subscriber.callback(message);
77
+ }
78
+ return;
79
+ }
80
+ if (retryCount < 10) {
81
+ setTimeout(() => {
82
+ this.trySendMessageWithRetry(message, retryCount + 1);
83
+ }, 1e3);
49
84
  } else {
50
- subscriber.callback(message);
85
+ console.warn(`Failed to send message to client ${message.to} after 10 retries`);
51
86
  }
52
87
  }
53
88
  async handleMessage(event) {
@@ -63,6 +98,19 @@ var _PubSub = class _PubSub {
63
98
  });
64
99
  return;
65
100
  }
101
+ if (data?.type === "UNREGISTER") {
102
+ const unregistration = data;
103
+ this.subscribers.delete(unregistration.pageId);
104
+ return;
105
+ }
106
+ if (data?.type === "CLIENT_EXISTS_CHECK") {
107
+ source.postMessage({
108
+ type: "CLIENT_EXISTS_RESPONSE",
109
+ requestId: data.requestId,
110
+ exists: this.subscribers.has(data.clientId)
111
+ }, "*");
112
+ return;
113
+ }
66
114
  if (!data || !data.from || !data.to) return;
67
115
  const message = data;
68
116
  if (this.mainCallback) {
@@ -76,6 +124,15 @@ var _PubSub = class _PubSub {
76
124
  await subscriber.callback(message);
77
125
  }
78
126
  }
127
+ /**
128
+ * Check if a client with the given ID exists in the PubSub system.
129
+ *
130
+ * @param clientId The ID of the client to check.
131
+ * @returns True if the client exists, false otherwise.
132
+ */
133
+ isClientExists(clientId) {
134
+ return this.subscribers.has(clientId);
135
+ }
79
136
  };
80
137
  __publicField(_PubSub, "instance");
81
138
  var PubSub = _PubSub;
@@ -103,6 +160,19 @@ var Client = class {
103
160
  this.pubsub.register(pageId, this.handleMessage.bind(this));
104
161
  }
105
162
  }
163
+ /**
164
+ * Unregister the client from the pubsub.
165
+ */
166
+ unregister() {
167
+ if (this.isIframe) {
168
+ window.parent.postMessage({
169
+ type: "UNREGISTER",
170
+ pageId: this.pageId
171
+ }, "*");
172
+ } else {
173
+ this.pubsub.unregister(this.pageId);
174
+ }
175
+ }
106
176
  /**
107
177
  * Listen for messages from the parent page with a callback.
108
178
  *
@@ -129,6 +199,163 @@ var Client = class {
129
199
  this.pubsub.sendMessage(message);
130
200
  }
131
201
  }
202
+ sendAIChatMethod(methodName, arg) {
203
+ this.sendMessage(
204
+ "aichat" /* AI_CHAT_CLIENT_ID */,
205
+ // This name is hardcode, do not change it
206
+ {
207
+ type: "pubsub" /* AI_CHAT_INTERNAL_COMM_TYPE */,
208
+ // This name is hardcode, do not change it
209
+ methodName,
210
+ arg
211
+ }
212
+ );
213
+ }
214
+ /**
215
+ * Set the parent name then the AI Chat can know who should it communicate with.
216
+ *
217
+ * @param parentName The name of the parent page.
218
+ */
219
+ setParentName(parentName) {
220
+ this.sendAIChatMethod("setParentName" /* SET_PARENT_NAME */, parentName);
221
+ }
222
+ /**
223
+ * Set the user ID for the AI Chat component.
224
+ *
225
+ * @param userId The user ID.
226
+ */
227
+ setUserId(userId) {
228
+ this.sendAIChatMethod("setUserId" /* SET_USER_ID */, userId);
229
+ }
230
+ /**
231
+ * Set custom headers for the AI Chat component.
232
+ *
233
+ * @param headers The custom headers.
234
+ */
235
+ setCustomHeaders(headers) {
236
+ this.sendAIChatMethod("setCustomHeaders" /* SET_CUSTOM_HEADERS */, headers);
237
+ }
238
+ /**
239
+ * Set custom payload for the AI Chat component.
240
+ *
241
+ * @param payload The custom payload.
242
+ */
243
+ setCustomPayload(payload) {
244
+ this.sendAIChatMethod("setCustomPayload" /* SET_CUSTOM_PAYLOAD */, payload);
245
+ }
246
+ /**
247
+ * Set suggestions for the AI Chat component.
248
+ *
249
+ * @param suggestions The suggestions to set.
250
+ */
251
+ setSuggestions(suggestions) {
252
+ this.sendAIChatMethod("setSuggestions" /* SET_SUGGESTIONS */, suggestions);
253
+ }
254
+ /**
255
+ * Show suggestions in the AI Chat component.
256
+ *
257
+ * @param show Whether to show suggestions.
258
+ */
259
+ showSuggestions(show) {
260
+ this.sendAIChatMethod("showSuggestions" /* SHOW_SUGGESTIONS */, show);
261
+ }
262
+ /**
263
+ * Show a chat message in the AI Chat component.
264
+ *
265
+ * @param message The message to show.
266
+ */
267
+ showChatMessage(message) {
268
+ this.sendAIChatMethod("showChatMessage" /* SHOW_CHAT_MESSAGE */, message);
269
+ }
270
+ /**
271
+ * Confirm an action in the AI Chat component.
272
+ *
273
+ * @param action The action to confirm.
274
+ */
275
+ confirmAction(action) {
276
+ this.sendAIChatMethod("confirmAction" /* CONFIRM_ACTION */, action);
277
+ }
278
+ /**
279
+ * Show options in the AI Chat component.
280
+ *
281
+ * @param options The options to show.
282
+ */
283
+ showOptions(options) {
284
+ this.sendAIChatMethod("showOptions" /* SHOW_OPTIONS */, options);
285
+ }
286
+ /**
287
+ * Send a chat prompt to the AI Chat component.
288
+ *
289
+ * @param prompt The prompt to send.
290
+ */
291
+ sendChatPrompt(prompt) {
292
+ this.sendAIChatMethod("sendChatPrompt" /* SEND_CHAT_PROMPT */, prompt);
293
+ }
294
+ /**
295
+ * Check if a client with the given ID exists in the PubSub system.
296
+ *
297
+ * @param clientId The ID of the client to check.
298
+ * @param maxRetries Maximum number of retries. Default is 3.
299
+ * @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
300
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
301
+ */
302
+ checkClientExists(clientId, maxRetries = 3, retryInterval = 1e3) {
303
+ return this.checkClientExistsWithRetry(clientId, 0, maxRetries, retryInterval);
304
+ }
305
+ /**
306
+ * Check if a client with the given ID exists in the PubSub system with retry mechanism.
307
+ * Will retry up to 3 times with 1 second delay between retries.
308
+ *
309
+ * @param clientId The ID of the client to check.
310
+ * @param retryCount The current retry count.
311
+ * @returns A Promise that resolves to true if the client exists, false otherwise.
312
+ * @private
313
+ */
314
+ checkClientExistsWithRetry(clientId, retryCount, maxRetries, retryInterval) {
315
+ return new Promise((resolve) => {
316
+ if (this.isIframe) {
317
+ const requestId = `check-client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
318
+ const messageHandler = (event) => {
319
+ const data = event.data;
320
+ if (data && data.type === "CLIENT_EXISTS_RESPONSE" && data.requestId === requestId) {
321
+ window.removeEventListener("message", messageHandler);
322
+ clearTimeout(removeHandlerTimeout);
323
+ if (data.exists) {
324
+ resolve(true);
325
+ } else if (retryCount < maxRetries - 1) {
326
+ setTimeout(() => {
327
+ this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists) => resolve(exists));
328
+ }, retryInterval);
329
+ } else {
330
+ resolve(false);
331
+ }
332
+ }
333
+ };
334
+ window.addEventListener("message", messageHandler);
335
+ window.parent.postMessage({
336
+ type: "CLIENT_EXISTS_CHECK",
337
+ clientId,
338
+ requestId,
339
+ from: this.pageId
340
+ }, "*");
341
+ const removeHandlerTimeout = setTimeout(() => {
342
+ window.removeEventListener("message", messageHandler);
343
+ resolve(false);
344
+ }, retryInterval + 1e3);
345
+ } else {
346
+ const exists = this.pubsub.isClientExists(clientId);
347
+ if (exists) {
348
+ resolve(true);
349
+ } else if (retryCount < maxRetries - 1) {
350
+ setTimeout(() => {
351
+ this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists2) => resolve(exists2));
352
+ }, retryInterval);
353
+ } else {
354
+ resolve(false);
355
+ }
356
+ }
357
+ });
358
+ }
132
359
  async handleMessage(event) {
133
360
  let message;
134
361
  if (event.data) {
@@ -148,6 +375,7 @@ var Client = class {
148
375
  }
149
376
  };
150
377
  export {
378
+ AIChatNameEnum,
151
379
  Client,
152
380
  PubSub
153
381
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iframe-pubsub",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",