iframe-pubsub 1.0.10 → 1.0.12
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 +31 -8
- package/dist/index.d.ts +31 -8
- package/dist/index.js +116 -80
- package/dist/index.mjs +116 -80
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
@@ -37,6 +37,12 @@ declare class Client {
|
|
37
37
|
* Unregister the client from the pubsub.
|
38
38
|
*/
|
39
39
|
unregister(): void;
|
40
|
+
/**
|
41
|
+
* Clean up the aichat registration if the iframe is removed.
|
42
|
+
*
|
43
|
+
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
44
|
+
*/
|
45
|
+
cleanAIChat(): boolean;
|
40
46
|
/**
|
41
47
|
* Listen for messages from the parent page with a callback.
|
42
48
|
*
|
@@ -50,6 +56,25 @@ declare class Client {
|
|
50
56
|
* @param payload The payload of the message.
|
51
57
|
*/
|
52
58
|
sendMessage(to: string, payload: any): void;
|
59
|
+
/**
|
60
|
+
* Check if a client with the given ID exists in the PubSub system.
|
61
|
+
*
|
62
|
+
* @param clientId The ID of the client to check.
|
63
|
+
* @param maxRetries Maximum number of retries. Default is 3.
|
64
|
+
* @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
|
65
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
66
|
+
*/
|
67
|
+
checkClientExists(clientId: string, maxRetries?: number, retryInterval?: number): Promise<boolean>;
|
68
|
+
/**
|
69
|
+
* Check if a client with the given ID exists in the PubSub system with retry mechanism.
|
70
|
+
* Will retry up to 3 times with 1 second delay between retries.
|
71
|
+
*
|
72
|
+
* @param clientId The ID of the client to check.
|
73
|
+
* @param retryCount The current retry count.
|
74
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
75
|
+
* @private
|
76
|
+
*/
|
77
|
+
private checkClientExistsWithRetry;
|
53
78
|
private handleMessage;
|
54
79
|
}
|
55
80
|
|
@@ -172,26 +197,24 @@ declare class PubSub {
|
|
172
197
|
*
|
173
198
|
* @param pageId The ID of the page or component to unregister from.
|
174
199
|
*/
|
175
|
-
unregister(pageId: string):
|
176
|
-
sendMessage(message: IMessage):
|
200
|
+
unregister(pageId: string): boolean;
|
201
|
+
sendMessage(message: IMessage): void;
|
177
202
|
/**
|
178
203
|
* Try to send a message to a client with retry logic.
|
179
204
|
* Will retry up to 3 times with 1 second delay between retries.
|
180
|
-
* If client exists, will check if it's still available with PING/PONG.
|
181
205
|
*
|
182
206
|
* @param message The message to send.
|
183
207
|
* @param retryCount The current retry count.
|
184
208
|
*/
|
185
209
|
private trySendMessageWithRetry;
|
210
|
+
private handleMessage;
|
186
211
|
/**
|
187
|
-
* Check if a client
|
212
|
+
* Check if a client with the given ID exists in the PubSub system.
|
188
213
|
*
|
189
214
|
* @param clientId The ID of the client to check.
|
190
|
-
* @
|
191
|
-
* @returns A Promise that resolves to true if the client is pingable, false otherwise.
|
215
|
+
* @returns True if the client exists, false otherwise.
|
192
216
|
*/
|
193
|
-
|
194
|
-
private handleMessage;
|
217
|
+
isClientExists(clientId: string): boolean;
|
195
218
|
}
|
196
219
|
|
197
220
|
export { AIChatClient, AIChatNameEnum, Client, type IMessage, type IRegistrationMessage, type MessageCallback, PubSub };
|
package/dist/index.d.ts
CHANGED
@@ -37,6 +37,12 @@ declare class Client {
|
|
37
37
|
* Unregister the client from the pubsub.
|
38
38
|
*/
|
39
39
|
unregister(): void;
|
40
|
+
/**
|
41
|
+
* Clean up the aichat registration if the iframe is removed.
|
42
|
+
*
|
43
|
+
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
44
|
+
*/
|
45
|
+
cleanAIChat(): boolean;
|
40
46
|
/**
|
41
47
|
* Listen for messages from the parent page with a callback.
|
42
48
|
*
|
@@ -50,6 +56,25 @@ declare class Client {
|
|
50
56
|
* @param payload The payload of the message.
|
51
57
|
*/
|
52
58
|
sendMessage(to: string, payload: any): void;
|
59
|
+
/**
|
60
|
+
* Check if a client with the given ID exists in the PubSub system.
|
61
|
+
*
|
62
|
+
* @param clientId The ID of the client to check.
|
63
|
+
* @param maxRetries Maximum number of retries. Default is 3.
|
64
|
+
* @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
|
65
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
66
|
+
*/
|
67
|
+
checkClientExists(clientId: string, maxRetries?: number, retryInterval?: number): Promise<boolean>;
|
68
|
+
/**
|
69
|
+
* Check if a client with the given ID exists in the PubSub system with retry mechanism.
|
70
|
+
* Will retry up to 3 times with 1 second delay between retries.
|
71
|
+
*
|
72
|
+
* @param clientId The ID of the client to check.
|
73
|
+
* @param retryCount The current retry count.
|
74
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
75
|
+
* @private
|
76
|
+
*/
|
77
|
+
private checkClientExistsWithRetry;
|
53
78
|
private handleMessage;
|
54
79
|
}
|
55
80
|
|
@@ -172,26 +197,24 @@ declare class PubSub {
|
|
172
197
|
*
|
173
198
|
* @param pageId The ID of the page or component to unregister from.
|
174
199
|
*/
|
175
|
-
unregister(pageId: string):
|
176
|
-
sendMessage(message: IMessage):
|
200
|
+
unregister(pageId: string): boolean;
|
201
|
+
sendMessage(message: IMessage): void;
|
177
202
|
/**
|
178
203
|
* Try to send a message to a client with retry logic.
|
179
204
|
* Will retry up to 3 times with 1 second delay between retries.
|
180
|
-
* If client exists, will check if it's still available with PING/PONG.
|
181
205
|
*
|
182
206
|
* @param message The message to send.
|
183
207
|
* @param retryCount The current retry count.
|
184
208
|
*/
|
185
209
|
private trySendMessageWithRetry;
|
210
|
+
private handleMessage;
|
186
211
|
/**
|
187
|
-
* Check if a client
|
212
|
+
* Check if a client with the given ID exists in the PubSub system.
|
188
213
|
*
|
189
214
|
* @param clientId The ID of the client to check.
|
190
|
-
* @
|
191
|
-
* @returns A Promise that resolves to true if the client is pingable, false otherwise.
|
215
|
+
* @returns True if the client exists, false otherwise.
|
192
216
|
*/
|
193
|
-
|
194
|
-
private handleMessage;
|
217
|
+
isClientExists(clientId: string): boolean;
|
195
218
|
}
|
196
219
|
|
197
220
|
export { AIChatClient, AIChatNameEnum, Client, type IMessage, type IRegistrationMessage, type MessageCallback, PubSub };
|
package/dist/index.js
CHANGED
@@ -63,91 +63,39 @@ var _PubSub = class _PubSub {
|
|
63
63
|
* @param pageId The ID of the page or component to unregister from.
|
64
64
|
*/
|
65
65
|
unregister(pageId) {
|
66
|
-
this.subscribers.delete(pageId);
|
66
|
+
return this.subscribers.delete(pageId);
|
67
67
|
}
|
68
68
|
sendMessage(message) {
|
69
69
|
if (this.mainCallback) {
|
70
70
|
this.mainCallback(message);
|
71
71
|
}
|
72
|
-
|
72
|
+
this.trySendMessageWithRetry(message, 0);
|
73
73
|
}
|
74
74
|
/**
|
75
75
|
* Try to send a message to a client with retry logic.
|
76
76
|
* Will retry up to 3 times with 1 second delay between retries.
|
77
|
-
*
|
78
|
-
*
|
77
|
+
*
|
79
78
|
* @param message The message to send.
|
80
79
|
* @param retryCount The current retry count.
|
81
80
|
*/
|
82
|
-
|
81
|
+
trySendMessageWithRetry(message, retryCount) {
|
83
82
|
const subscriber = this.subscribers.get(message.to);
|
84
83
|
if (subscriber) {
|
85
84
|
if (subscriber.source) {
|
86
|
-
|
87
|
-
const isPingable = await this.checkClientPingable(
|
88
|
-
message.to,
|
89
|
-
subscriber.source
|
90
|
-
);
|
91
|
-
if (isPingable) {
|
92
|
-
subscriber.source.postMessage(message, "*");
|
93
|
-
return;
|
94
|
-
} else {
|
95
|
-
this.subscribers.delete(message.to);
|
96
|
-
}
|
97
|
-
} catch (error) {
|
98
|
-
console.warn(`Failed to ping client ${message.to}:`, error);
|
99
|
-
this.subscribers.delete(message.to);
|
100
|
-
}
|
85
|
+
subscriber.source.postMessage(message, "*");
|
101
86
|
} else {
|
102
87
|
subscriber.callback(message);
|
103
|
-
return;
|
104
88
|
}
|
89
|
+
return;
|
105
90
|
}
|
106
|
-
if (retryCount <
|
107
|
-
|
108
|
-
|
91
|
+
if (retryCount < 10) {
|
92
|
+
setTimeout(() => {
|
93
|
+
this.trySendMessageWithRetry(message, retryCount + 1);
|
94
|
+
}, 1e3);
|
109
95
|
} else {
|
110
|
-
console.warn(
|
111
|
-
`Failed to send message to client ${message.to} after 3 retries`
|
112
|
-
);
|
96
|
+
console.warn(`Failed to send message to client ${message.to} after 10 retries`);
|
113
97
|
}
|
114
98
|
}
|
115
|
-
/**
|
116
|
-
* Check if a client is pingable (still available).
|
117
|
-
*
|
118
|
-
* @param clientId The ID of the client to check.
|
119
|
-
* @param source The window object of the client.
|
120
|
-
* @returns A Promise that resolves to true if the client is pingable, false otherwise.
|
121
|
-
*/
|
122
|
-
checkClientPingable(clientId, source) {
|
123
|
-
return new Promise((resolve) => {
|
124
|
-
const pingId = `ping-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
125
|
-
const messageHandler = (event) => {
|
126
|
-
const data = event.data;
|
127
|
-
if (data && data.from === clientId && data.to === "pubsub" && data.payload?.type === "PONG" && data.payload.pingId === pingId) {
|
128
|
-
console.info("Received pong from client:", clientId, data);
|
129
|
-
window.removeEventListener("message", messageHandler);
|
130
|
-
clearTimeout(timeoutId);
|
131
|
-
resolve(true);
|
132
|
-
}
|
133
|
-
};
|
134
|
-
window.addEventListener("message", messageHandler);
|
135
|
-
const pingMessage = {
|
136
|
-
from: "pubsub",
|
137
|
-
to: clientId,
|
138
|
-
payload: {
|
139
|
-
type: "PING",
|
140
|
-
pingId
|
141
|
-
}
|
142
|
-
};
|
143
|
-
console.info("Sending ping to client:", clientId, pingMessage);
|
144
|
-
source.postMessage(pingMessage, "*");
|
145
|
-
const timeoutId = setTimeout(() => {
|
146
|
-
window.removeEventListener("message", messageHandler);
|
147
|
-
resolve(false);
|
148
|
-
}, 1e3);
|
149
|
-
});
|
150
|
-
}
|
151
99
|
async handleMessage(event) {
|
152
100
|
const data = event.data;
|
153
101
|
const source = event.source;
|
@@ -166,9 +114,35 @@ var _PubSub = class _PubSub {
|
|
166
114
|
this.subscribers.delete(unregistration.pageId);
|
167
115
|
return;
|
168
116
|
}
|
117
|
+
if (data?.type === "CLIENT_EXISTS_CHECK") {
|
118
|
+
source.postMessage({
|
119
|
+
type: "CLIENT_EXISTS_RESPONSE",
|
120
|
+
requestId: data.requestId,
|
121
|
+
exists: this.subscribers.has(data.clientId)
|
122
|
+
}, "*");
|
123
|
+
return;
|
124
|
+
}
|
169
125
|
if (!data || !data.from || !data.to) return;
|
170
126
|
const message = data;
|
171
|
-
this.
|
127
|
+
if (this.mainCallback) {
|
128
|
+
await this.mainCallback(message);
|
129
|
+
}
|
130
|
+
const subscriber = this.subscribers.get(message.to);
|
131
|
+
if (!subscriber) return;
|
132
|
+
if (subscriber.source) {
|
133
|
+
subscriber.source.postMessage(message, "*");
|
134
|
+
} else {
|
135
|
+
await subscriber.callback(message);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
/**
|
139
|
+
* Check if a client with the given ID exists in the PubSub system.
|
140
|
+
*
|
141
|
+
* @param clientId The ID of the client to check.
|
142
|
+
* @returns True if the client exists, false otherwise.
|
143
|
+
*/
|
144
|
+
isClientExists(clientId) {
|
145
|
+
return this.subscribers.has(clientId);
|
172
146
|
}
|
173
147
|
};
|
174
148
|
__publicField(_PubSub, "instance");
|
@@ -212,12 +186,25 @@ var Client = class {
|
|
212
186
|
this.pubsub.unregister(this.pageId);
|
213
187
|
}
|
214
188
|
}
|
189
|
+
/**
|
190
|
+
* Clean up the aichat registration if the iframe is removed.
|
191
|
+
*
|
192
|
+
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
193
|
+
*/
|
194
|
+
cleanAIChat() {
|
195
|
+
if (this.isIframe) {
|
196
|
+
throw new Error("You are not allowed to clean up aichat from iframe.");
|
197
|
+
}
|
198
|
+
window.removeEventListener("message", this.handleMessage.bind(this));
|
199
|
+
return this.pubsub.unregister("aichat" /* AI_CHAT_CLIENT_ID */);
|
200
|
+
}
|
215
201
|
/**
|
216
202
|
* Listen for messages from the parent page with a callback.
|
217
203
|
*
|
218
204
|
* @param callback The callback function to register.
|
219
205
|
*/
|
220
206
|
onMessage(callback) {
|
207
|
+
console.info("Register new onMessage callback for", this.pageId, callback);
|
221
208
|
this.callback = callback;
|
222
209
|
}
|
223
210
|
/**
|
@@ -238,6 +225,71 @@ var Client = class {
|
|
238
225
|
this.pubsub.sendMessage(message);
|
239
226
|
}
|
240
227
|
}
|
228
|
+
/**
|
229
|
+
* Check if a client with the given ID exists in the PubSub system.
|
230
|
+
*
|
231
|
+
* @param clientId The ID of the client to check.
|
232
|
+
* @param maxRetries Maximum number of retries. Default is 3.
|
233
|
+
* @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
|
234
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
235
|
+
*/
|
236
|
+
checkClientExists(clientId, maxRetries = 3, retryInterval = 1e3) {
|
237
|
+
return this.checkClientExistsWithRetry(clientId, 0, maxRetries, retryInterval);
|
238
|
+
}
|
239
|
+
/**
|
240
|
+
* Check if a client with the given ID exists in the PubSub system with retry mechanism.
|
241
|
+
* Will retry up to 3 times with 1 second delay between retries.
|
242
|
+
*
|
243
|
+
* @param clientId The ID of the client to check.
|
244
|
+
* @param retryCount The current retry count.
|
245
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
246
|
+
* @private
|
247
|
+
*/
|
248
|
+
checkClientExistsWithRetry(clientId, retryCount, maxRetries, retryInterval) {
|
249
|
+
return new Promise((resolve) => {
|
250
|
+
if (this.isIframe) {
|
251
|
+
const requestId = `check-client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
252
|
+
const messageHandler = (event) => {
|
253
|
+
const data = event.data;
|
254
|
+
if (data && data.type === "CLIENT_EXISTS_RESPONSE" && data.requestId === requestId) {
|
255
|
+
window.removeEventListener("message", messageHandler);
|
256
|
+
clearTimeout(removeHandlerTimeout);
|
257
|
+
if (data.exists) {
|
258
|
+
resolve(true);
|
259
|
+
} else if (retryCount < maxRetries - 1) {
|
260
|
+
setTimeout(() => {
|
261
|
+
this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists) => resolve(exists));
|
262
|
+
}, retryInterval);
|
263
|
+
} else {
|
264
|
+
resolve(false);
|
265
|
+
}
|
266
|
+
}
|
267
|
+
};
|
268
|
+
window.addEventListener("message", messageHandler);
|
269
|
+
window.parent.postMessage({
|
270
|
+
type: "CLIENT_EXISTS_CHECK",
|
271
|
+
clientId,
|
272
|
+
requestId,
|
273
|
+
from: this.pageId
|
274
|
+
}, "*");
|
275
|
+
const removeHandlerTimeout = setTimeout(() => {
|
276
|
+
window.removeEventListener("message", messageHandler);
|
277
|
+
resolve(false);
|
278
|
+
}, retryInterval + 1e3);
|
279
|
+
} else {
|
280
|
+
const exists = this.pubsub.isClientExists(clientId);
|
281
|
+
if (exists) {
|
282
|
+
resolve(true);
|
283
|
+
} else if (retryCount < maxRetries - 1) {
|
284
|
+
setTimeout(() => {
|
285
|
+
this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists2) => resolve(exists2));
|
286
|
+
}, retryInterval);
|
287
|
+
} else {
|
288
|
+
resolve(false);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
});
|
292
|
+
}
|
241
293
|
async handleMessage(event) {
|
242
294
|
let message;
|
243
295
|
if (event.data) {
|
@@ -247,22 +299,6 @@ var Client = class {
|
|
247
299
|
message = event;
|
248
300
|
}
|
249
301
|
if (!message || !message.from || !message.to || message.to !== this.pageId) return;
|
250
|
-
if (message.payload?.type === "PING") {
|
251
|
-
const pongMsg = {
|
252
|
-
from: this.pageId,
|
253
|
-
to: message.from,
|
254
|
-
payload: {
|
255
|
-
type: "PONG",
|
256
|
-
pingId: message.payload.pingId
|
257
|
-
}
|
258
|
-
};
|
259
|
-
if (this.isIframe) {
|
260
|
-
window.parent.postMessage(pongMsg, "*");
|
261
|
-
} else {
|
262
|
-
this.pubsub.sendMessage(pongMsg);
|
263
|
-
}
|
264
|
-
return;
|
265
|
-
}
|
266
302
|
if (this.callback) {
|
267
303
|
try {
|
268
304
|
await this.callback(message);
|
package/dist/index.mjs
CHANGED
@@ -36,91 +36,39 @@ var _PubSub = class _PubSub {
|
|
36
36
|
* @param pageId The ID of the page or component to unregister from.
|
37
37
|
*/
|
38
38
|
unregister(pageId) {
|
39
|
-
this.subscribers.delete(pageId);
|
39
|
+
return this.subscribers.delete(pageId);
|
40
40
|
}
|
41
41
|
sendMessage(message) {
|
42
42
|
if (this.mainCallback) {
|
43
43
|
this.mainCallback(message);
|
44
44
|
}
|
45
|
-
|
45
|
+
this.trySendMessageWithRetry(message, 0);
|
46
46
|
}
|
47
47
|
/**
|
48
48
|
* Try to send a message to a client with retry logic.
|
49
49
|
* Will retry up to 3 times with 1 second delay between retries.
|
50
|
-
*
|
51
|
-
*
|
50
|
+
*
|
52
51
|
* @param message The message to send.
|
53
52
|
* @param retryCount The current retry count.
|
54
53
|
*/
|
55
|
-
|
54
|
+
trySendMessageWithRetry(message, retryCount) {
|
56
55
|
const subscriber = this.subscribers.get(message.to);
|
57
56
|
if (subscriber) {
|
58
57
|
if (subscriber.source) {
|
59
|
-
|
60
|
-
const isPingable = await this.checkClientPingable(
|
61
|
-
message.to,
|
62
|
-
subscriber.source
|
63
|
-
);
|
64
|
-
if (isPingable) {
|
65
|
-
subscriber.source.postMessage(message, "*");
|
66
|
-
return;
|
67
|
-
} else {
|
68
|
-
this.subscribers.delete(message.to);
|
69
|
-
}
|
70
|
-
} catch (error) {
|
71
|
-
console.warn(`Failed to ping client ${message.to}:`, error);
|
72
|
-
this.subscribers.delete(message.to);
|
73
|
-
}
|
58
|
+
subscriber.source.postMessage(message, "*");
|
74
59
|
} else {
|
75
60
|
subscriber.callback(message);
|
76
|
-
return;
|
77
61
|
}
|
62
|
+
return;
|
78
63
|
}
|
79
|
-
if (retryCount <
|
80
|
-
|
81
|
-
|
64
|
+
if (retryCount < 10) {
|
65
|
+
setTimeout(() => {
|
66
|
+
this.trySendMessageWithRetry(message, retryCount + 1);
|
67
|
+
}, 1e3);
|
82
68
|
} else {
|
83
|
-
console.warn(
|
84
|
-
`Failed to send message to client ${message.to} after 3 retries`
|
85
|
-
);
|
69
|
+
console.warn(`Failed to send message to client ${message.to} after 10 retries`);
|
86
70
|
}
|
87
71
|
}
|
88
|
-
/**
|
89
|
-
* Check if a client is pingable (still available).
|
90
|
-
*
|
91
|
-
* @param clientId The ID of the client to check.
|
92
|
-
* @param source The window object of the client.
|
93
|
-
* @returns A Promise that resolves to true if the client is pingable, false otherwise.
|
94
|
-
*/
|
95
|
-
checkClientPingable(clientId, source) {
|
96
|
-
return new Promise((resolve) => {
|
97
|
-
const pingId = `ping-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
98
|
-
const messageHandler = (event) => {
|
99
|
-
const data = event.data;
|
100
|
-
if (data && data.from === clientId && data.to === "pubsub" && data.payload?.type === "PONG" && data.payload.pingId === pingId) {
|
101
|
-
console.info("Received pong from client:", clientId, data);
|
102
|
-
window.removeEventListener("message", messageHandler);
|
103
|
-
clearTimeout(timeoutId);
|
104
|
-
resolve(true);
|
105
|
-
}
|
106
|
-
};
|
107
|
-
window.addEventListener("message", messageHandler);
|
108
|
-
const pingMessage = {
|
109
|
-
from: "pubsub",
|
110
|
-
to: clientId,
|
111
|
-
payload: {
|
112
|
-
type: "PING",
|
113
|
-
pingId
|
114
|
-
}
|
115
|
-
};
|
116
|
-
console.info("Sending ping to client:", clientId, pingMessage);
|
117
|
-
source.postMessage(pingMessage, "*");
|
118
|
-
const timeoutId = setTimeout(() => {
|
119
|
-
window.removeEventListener("message", messageHandler);
|
120
|
-
resolve(false);
|
121
|
-
}, 1e3);
|
122
|
-
});
|
123
|
-
}
|
124
72
|
async handleMessage(event) {
|
125
73
|
const data = event.data;
|
126
74
|
const source = event.source;
|
@@ -139,9 +87,35 @@ var _PubSub = class _PubSub {
|
|
139
87
|
this.subscribers.delete(unregistration.pageId);
|
140
88
|
return;
|
141
89
|
}
|
90
|
+
if (data?.type === "CLIENT_EXISTS_CHECK") {
|
91
|
+
source.postMessage({
|
92
|
+
type: "CLIENT_EXISTS_RESPONSE",
|
93
|
+
requestId: data.requestId,
|
94
|
+
exists: this.subscribers.has(data.clientId)
|
95
|
+
}, "*");
|
96
|
+
return;
|
97
|
+
}
|
142
98
|
if (!data || !data.from || !data.to) return;
|
143
99
|
const message = data;
|
144
|
-
this.
|
100
|
+
if (this.mainCallback) {
|
101
|
+
await this.mainCallback(message);
|
102
|
+
}
|
103
|
+
const subscriber = this.subscribers.get(message.to);
|
104
|
+
if (!subscriber) return;
|
105
|
+
if (subscriber.source) {
|
106
|
+
subscriber.source.postMessage(message, "*");
|
107
|
+
} else {
|
108
|
+
await subscriber.callback(message);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
/**
|
112
|
+
* Check if a client with the given ID exists in the PubSub system.
|
113
|
+
*
|
114
|
+
* @param clientId The ID of the client to check.
|
115
|
+
* @returns True if the client exists, false otherwise.
|
116
|
+
*/
|
117
|
+
isClientExists(clientId) {
|
118
|
+
return this.subscribers.has(clientId);
|
145
119
|
}
|
146
120
|
};
|
147
121
|
__publicField(_PubSub, "instance");
|
@@ -185,12 +159,25 @@ var Client = class {
|
|
185
159
|
this.pubsub.unregister(this.pageId);
|
186
160
|
}
|
187
161
|
}
|
162
|
+
/**
|
163
|
+
* Clean up the aichat registration if the iframe is removed.
|
164
|
+
*
|
165
|
+
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
166
|
+
*/
|
167
|
+
cleanAIChat() {
|
168
|
+
if (this.isIframe) {
|
169
|
+
throw new Error("You are not allowed to clean up aichat from iframe.");
|
170
|
+
}
|
171
|
+
window.removeEventListener("message", this.handleMessage.bind(this));
|
172
|
+
return this.pubsub.unregister("aichat" /* AI_CHAT_CLIENT_ID */);
|
173
|
+
}
|
188
174
|
/**
|
189
175
|
* Listen for messages from the parent page with a callback.
|
190
176
|
*
|
191
177
|
* @param callback The callback function to register.
|
192
178
|
*/
|
193
179
|
onMessage(callback) {
|
180
|
+
console.info("Register new onMessage callback for", this.pageId, callback);
|
194
181
|
this.callback = callback;
|
195
182
|
}
|
196
183
|
/**
|
@@ -211,6 +198,71 @@ var Client = class {
|
|
211
198
|
this.pubsub.sendMessage(message);
|
212
199
|
}
|
213
200
|
}
|
201
|
+
/**
|
202
|
+
* Check if a client with the given ID exists in the PubSub system.
|
203
|
+
*
|
204
|
+
* @param clientId The ID of the client to check.
|
205
|
+
* @param maxRetries Maximum number of retries. Default is 3.
|
206
|
+
* @param retryInterval Interval between retries in milliseconds. Default is 1000ms.
|
207
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
208
|
+
*/
|
209
|
+
checkClientExists(clientId, maxRetries = 3, retryInterval = 1e3) {
|
210
|
+
return this.checkClientExistsWithRetry(clientId, 0, maxRetries, retryInterval);
|
211
|
+
}
|
212
|
+
/**
|
213
|
+
* Check if a client with the given ID exists in the PubSub system with retry mechanism.
|
214
|
+
* Will retry up to 3 times with 1 second delay between retries.
|
215
|
+
*
|
216
|
+
* @param clientId The ID of the client to check.
|
217
|
+
* @param retryCount The current retry count.
|
218
|
+
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
219
|
+
* @private
|
220
|
+
*/
|
221
|
+
checkClientExistsWithRetry(clientId, retryCount, maxRetries, retryInterval) {
|
222
|
+
return new Promise((resolve) => {
|
223
|
+
if (this.isIframe) {
|
224
|
+
const requestId = `check-client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
225
|
+
const messageHandler = (event) => {
|
226
|
+
const data = event.data;
|
227
|
+
if (data && data.type === "CLIENT_EXISTS_RESPONSE" && data.requestId === requestId) {
|
228
|
+
window.removeEventListener("message", messageHandler);
|
229
|
+
clearTimeout(removeHandlerTimeout);
|
230
|
+
if (data.exists) {
|
231
|
+
resolve(true);
|
232
|
+
} else if (retryCount < maxRetries - 1) {
|
233
|
+
setTimeout(() => {
|
234
|
+
this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists) => resolve(exists));
|
235
|
+
}, retryInterval);
|
236
|
+
} else {
|
237
|
+
resolve(false);
|
238
|
+
}
|
239
|
+
}
|
240
|
+
};
|
241
|
+
window.addEventListener("message", messageHandler);
|
242
|
+
window.parent.postMessage({
|
243
|
+
type: "CLIENT_EXISTS_CHECK",
|
244
|
+
clientId,
|
245
|
+
requestId,
|
246
|
+
from: this.pageId
|
247
|
+
}, "*");
|
248
|
+
const removeHandlerTimeout = setTimeout(() => {
|
249
|
+
window.removeEventListener("message", messageHandler);
|
250
|
+
resolve(false);
|
251
|
+
}, retryInterval + 1e3);
|
252
|
+
} else {
|
253
|
+
const exists = this.pubsub.isClientExists(clientId);
|
254
|
+
if (exists) {
|
255
|
+
resolve(true);
|
256
|
+
} else if (retryCount < maxRetries - 1) {
|
257
|
+
setTimeout(() => {
|
258
|
+
this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists2) => resolve(exists2));
|
259
|
+
}, retryInterval);
|
260
|
+
} else {
|
261
|
+
resolve(false);
|
262
|
+
}
|
263
|
+
}
|
264
|
+
});
|
265
|
+
}
|
214
266
|
async handleMessage(event) {
|
215
267
|
let message;
|
216
268
|
if (event.data) {
|
@@ -220,22 +272,6 @@ var Client = class {
|
|
220
272
|
message = event;
|
221
273
|
}
|
222
274
|
if (!message || !message.from || !message.to || message.to !== this.pageId) return;
|
223
|
-
if (message.payload?.type === "PING") {
|
224
|
-
const pongMsg = {
|
225
|
-
from: this.pageId,
|
226
|
-
to: message.from,
|
227
|
-
payload: {
|
228
|
-
type: "PONG",
|
229
|
-
pingId: message.payload.pingId
|
230
|
-
}
|
231
|
-
};
|
232
|
-
if (this.isIframe) {
|
233
|
-
window.parent.postMessage(pongMsg, "*");
|
234
|
-
} else {
|
235
|
-
this.pubsub.sendMessage(pongMsg);
|
236
|
-
}
|
237
|
-
return;
|
238
|
-
}
|
239
275
|
if (this.callback) {
|
240
276
|
try {
|
241
277
|
await this.callback(message);
|