iframe-pubsub 1.0.21 → 1.0.24
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 +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +110 -55
- package/dist/index.mjs +110 -55
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -26,8 +26,9 @@ declare class Client {
|
|
|
26
26
|
protected targetAIChatClientId: string;
|
|
27
27
|
private pageId;
|
|
28
28
|
private callback?;
|
|
29
|
-
private pubsub
|
|
29
|
+
private pubsub?;
|
|
30
30
|
private isIframe;
|
|
31
|
+
private isMainApp;
|
|
31
32
|
private boundHandleMessage;
|
|
32
33
|
/**
|
|
33
34
|
* Create a new client instance.
|
|
@@ -39,11 +40,6 @@ declare class Client {
|
|
|
39
40
|
* Unregister the client from the pubsub.
|
|
40
41
|
*/
|
|
41
42
|
unregister(): void;
|
|
42
|
-
/**
|
|
43
|
-
* Clean up the aichat registration if the iframe is removed.
|
|
44
|
-
*
|
|
45
|
-
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
|
46
|
-
*/
|
|
47
43
|
cleanAIChat(): boolean;
|
|
48
44
|
/**
|
|
49
45
|
* Listen for messages from the parent page with a callback.
|
|
@@ -74,10 +70,15 @@ declare class Client {
|
|
|
74
70
|
* @param clientId The ID of the client to check.
|
|
75
71
|
* @param retryCount The current retry count.
|
|
76
72
|
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
|
77
|
-
* @private
|
|
78
73
|
*/
|
|
79
74
|
private checkClientExistsWithRetry;
|
|
80
75
|
private handleMessage;
|
|
76
|
+
getDebugInfo(): {
|
|
77
|
+
pageId: string;
|
|
78
|
+
isMainApp: boolean;
|
|
79
|
+
isIframe: boolean;
|
|
80
|
+
windowLevel: string;
|
|
81
|
+
};
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
declare enum AIChatNameEnum {
|
package/dist/index.d.ts
CHANGED
|
@@ -26,8 +26,9 @@ declare class Client {
|
|
|
26
26
|
protected targetAIChatClientId: string;
|
|
27
27
|
private pageId;
|
|
28
28
|
private callback?;
|
|
29
|
-
private pubsub
|
|
29
|
+
private pubsub?;
|
|
30
30
|
private isIframe;
|
|
31
|
+
private isMainApp;
|
|
31
32
|
private boundHandleMessage;
|
|
32
33
|
/**
|
|
33
34
|
* Create a new client instance.
|
|
@@ -39,11 +40,6 @@ declare class Client {
|
|
|
39
40
|
* Unregister the client from the pubsub.
|
|
40
41
|
*/
|
|
41
42
|
unregister(): void;
|
|
42
|
-
/**
|
|
43
|
-
* Clean up the aichat registration if the iframe is removed.
|
|
44
|
-
*
|
|
45
|
-
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
|
46
|
-
*/
|
|
47
43
|
cleanAIChat(): boolean;
|
|
48
44
|
/**
|
|
49
45
|
* Listen for messages from the parent page with a callback.
|
|
@@ -74,10 +70,15 @@ declare class Client {
|
|
|
74
70
|
* @param clientId The ID of the client to check.
|
|
75
71
|
* @param retryCount The current retry count.
|
|
76
72
|
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
|
77
|
-
* @private
|
|
78
73
|
*/
|
|
79
74
|
private checkClientExistsWithRetry;
|
|
80
75
|
private handleMessage;
|
|
76
|
+
getDebugInfo(): {
|
|
77
|
+
pageId: string;
|
|
78
|
+
isMainApp: boolean;
|
|
79
|
+
isIframe: boolean;
|
|
80
|
+
windowLevel: string;
|
|
81
|
+
};
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
declare enum AIChatNameEnum {
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,11 @@ __export(index_exports, {
|
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(index_exports);
|
|
31
31
|
|
|
32
|
+
// src/cors.ts
|
|
33
|
+
function isAllowedOrigin(origin) {
|
|
34
|
+
return origin === "null" || origin.startsWith("http://localhost") || origin.endsWith(".bkpi.co") || origin.endsWith(".bookipi.com");
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
// src/PubSub.ts
|
|
33
38
|
var _PubSub = class _PubSub {
|
|
34
39
|
constructor() {
|
|
@@ -83,7 +88,7 @@ var _PubSub = class _PubSub {
|
|
|
83
88
|
const subscriber = this.subscribers.get(message.to);
|
|
84
89
|
if (subscriber) {
|
|
85
90
|
if (subscriber.source) {
|
|
86
|
-
subscriber.source.postMessage(message, "*");
|
|
91
|
+
subscriber.source.postMessage(message, subscriber.origin || "*");
|
|
87
92
|
} else {
|
|
88
93
|
subscriber.callback(message);
|
|
89
94
|
}
|
|
@@ -100,12 +105,15 @@ var _PubSub = class _PubSub {
|
|
|
100
105
|
handleMessage(event) {
|
|
101
106
|
const data = event.data;
|
|
102
107
|
const source = event.source;
|
|
108
|
+
const origin = event.origin;
|
|
109
|
+
if (!isAllowedOrigin(origin)) return;
|
|
103
110
|
if (data?.type === "REGISTER") {
|
|
104
111
|
const registration = data;
|
|
105
112
|
this.subscribers.set(registration.pageId, {
|
|
106
113
|
source,
|
|
114
|
+
origin: registration.origin,
|
|
107
115
|
callback: (message2) => {
|
|
108
|
-
source.postMessage(message2, "*");
|
|
116
|
+
source.postMessage(message2, registration.origin || "*");
|
|
109
117
|
}
|
|
110
118
|
});
|
|
111
119
|
return;
|
|
@@ -120,7 +128,7 @@ var _PubSub = class _PubSub {
|
|
|
120
128
|
type: "CLIENT_EXISTS_RESPONSE",
|
|
121
129
|
requestId: data.requestId,
|
|
122
130
|
exists: this.subscribers.has(data.clientId)
|
|
123
|
-
}, "*");
|
|
131
|
+
}, data.origin || "*");
|
|
124
132
|
return;
|
|
125
133
|
}
|
|
126
134
|
if (!data || !data.from || !data.to) return;
|
|
@@ -130,8 +138,8 @@ var _PubSub = class _PubSub {
|
|
|
130
138
|
}
|
|
131
139
|
const subscriber = this.subscribers.get(message.to);
|
|
132
140
|
if (!subscriber) return;
|
|
133
|
-
if (subscriber
|
|
134
|
-
subscriber.source.postMessage(message, "*");
|
|
141
|
+
if (subscriber?.source) {
|
|
142
|
+
subscriber.source.postMessage(message, subscriber.origin || "*");
|
|
135
143
|
} else {
|
|
136
144
|
subscriber.callback(message);
|
|
137
145
|
}
|
|
@@ -162,46 +170,55 @@ var Client = class {
|
|
|
162
170
|
__publicField(this, "callback");
|
|
163
171
|
__publicField(this, "pubsub");
|
|
164
172
|
__publicField(this, "isIframe");
|
|
173
|
+
__publicField(this, "isMainApp");
|
|
165
174
|
__publicField(this, "boundHandleMessage");
|
|
166
175
|
this.targetAIChatClientId = targetAIChatClientId;
|
|
167
176
|
this.pageId = pageId;
|
|
168
|
-
this.pubsub = PubSub.getInstance();
|
|
169
177
|
this.isIframe = window !== window.parent;
|
|
178
|
+
this.isMainApp = window === window.top;
|
|
170
179
|
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
171
|
-
if (this.
|
|
172
|
-
|
|
173
|
-
type: "REGISTER",
|
|
174
|
-
pageId: this.pageId
|
|
175
|
-
}, "*");
|
|
176
|
-
window.addEventListener("message", this.boundHandleMessage);
|
|
177
|
-
} else {
|
|
180
|
+
if (this.isMainApp) {
|
|
181
|
+
this.pubsub = PubSub.getInstance();
|
|
178
182
|
this.pubsub.register(pageId, this.boundHandleMessage);
|
|
183
|
+
console.info(`\u2705 Client ${pageId} registered with main PubSub`);
|
|
184
|
+
} else {
|
|
185
|
+
console.info(
|
|
186
|
+
`\u{1F4E1} Client ${pageId} from iframe is registering with top window PubSub`
|
|
187
|
+
);
|
|
188
|
+
window.top.postMessage(
|
|
189
|
+
{
|
|
190
|
+
type: "REGISTER",
|
|
191
|
+
pageId: this.pageId,
|
|
192
|
+
origin: window.location.origin
|
|
193
|
+
},
|
|
194
|
+
"*"
|
|
195
|
+
);
|
|
196
|
+
window.addEventListener("message", this.boundHandleMessage);
|
|
179
197
|
}
|
|
180
198
|
}
|
|
181
199
|
/**
|
|
182
200
|
* Unregister the client from the pubsub.
|
|
183
201
|
*/
|
|
184
202
|
unregister() {
|
|
185
|
-
if (this.
|
|
186
|
-
window.parent.postMessage({
|
|
187
|
-
type: "UNREGISTER",
|
|
188
|
-
pageId: this.pageId
|
|
189
|
-
}, "*");
|
|
190
|
-
} else {
|
|
203
|
+
if (this.isMainApp && this.pubsub) {
|
|
191
204
|
this.pubsub.unregister(this.pageId);
|
|
205
|
+
} else {
|
|
206
|
+
window.top.postMessage(
|
|
207
|
+
{
|
|
208
|
+
type: "UNREGISTER",
|
|
209
|
+
pageId: this.pageId,
|
|
210
|
+
origin: window.location.origin
|
|
211
|
+
},
|
|
212
|
+
"*"
|
|
213
|
+
);
|
|
214
|
+
window.removeEventListener("message", this.boundHandleMessage);
|
|
192
215
|
}
|
|
216
|
+
console.info(`\u274C Client ${this.pageId} unregistered from PubSub`);
|
|
193
217
|
}
|
|
194
|
-
|
|
195
|
-
* Clean up the aichat registration if the iframe is removed.
|
|
196
|
-
*
|
|
197
|
-
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
|
198
|
-
*/
|
|
218
|
+
// Will not support this method anymore.
|
|
199
219
|
cleanAIChat() {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
window.removeEventListener("message", this.boundHandleMessage);
|
|
204
|
-
return this.pubsub.unregister(this.targetAIChatClientId);
|
|
220
|
+
console.warn(`\u203C\uFE0F Unsupported operation cleanAIChat has been called from ${this.pageId}.`);
|
|
221
|
+
return false;
|
|
205
222
|
}
|
|
206
223
|
/**
|
|
207
224
|
* Listen for messages from the parent page with a callback.
|
|
@@ -223,10 +240,10 @@ var Client = class {
|
|
|
223
240
|
to,
|
|
224
241
|
payload
|
|
225
242
|
};
|
|
226
|
-
if (this.
|
|
227
|
-
window.parent.postMessage(message, "*");
|
|
228
|
-
} else {
|
|
243
|
+
if (this.isMainApp && this.pubsub) {
|
|
229
244
|
this.pubsub.sendMessage(message);
|
|
245
|
+
} else {
|
|
246
|
+
window.top.postMessage(message, "*");
|
|
230
247
|
}
|
|
231
248
|
}
|
|
232
249
|
/**
|
|
@@ -238,7 +255,12 @@ var Client = class {
|
|
|
238
255
|
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
|
239
256
|
*/
|
|
240
257
|
checkClientExists(clientId, maxRetries = 3, retryInterval = 1e3) {
|
|
241
|
-
return this.checkClientExistsWithRetry(
|
|
258
|
+
return this.checkClientExistsWithRetry(
|
|
259
|
+
clientId,
|
|
260
|
+
0,
|
|
261
|
+
maxRetries,
|
|
262
|
+
retryInterval
|
|
263
|
+
);
|
|
242
264
|
}
|
|
243
265
|
/**
|
|
244
266
|
* Check if a client with the given ID exists in the PubSub system with retry mechanism.
|
|
@@ -247,13 +269,29 @@ var Client = class {
|
|
|
247
269
|
* @param clientId The ID of the client to check.
|
|
248
270
|
* @param retryCount The current retry count.
|
|
249
271
|
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
|
250
|
-
* @private
|
|
251
272
|
*/
|
|
252
273
|
checkClientExistsWithRetry(clientId, retryCount, maxRetries, retryInterval) {
|
|
253
274
|
return new Promise((resolve) => {
|
|
254
|
-
if (this.
|
|
275
|
+
if (this.isMainApp && this.pubsub) {
|
|
276
|
+
const exists = this.pubsub.isClientExists(clientId);
|
|
277
|
+
if (exists) {
|
|
278
|
+
resolve(true);
|
|
279
|
+
} else if (retryCount < maxRetries - 1) {
|
|
280
|
+
setTimeout(() => {
|
|
281
|
+
this.checkClientExistsWithRetry(
|
|
282
|
+
clientId,
|
|
283
|
+
retryCount + 1,
|
|
284
|
+
maxRetries,
|
|
285
|
+
retryInterval
|
|
286
|
+
).then((exists2) => resolve(exists2));
|
|
287
|
+
}, retryInterval);
|
|
288
|
+
} else {
|
|
289
|
+
resolve(false);
|
|
290
|
+
}
|
|
291
|
+
} else {
|
|
255
292
|
const requestId = `check-client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
256
293
|
const messageHandler = (event) => {
|
|
294
|
+
if (!isAllowedOrigin(event.origin)) return;
|
|
257
295
|
const data = event.data;
|
|
258
296
|
if (data && data.type === "CLIENT_EXISTS_RESPONSE" && data.requestId === requestId) {
|
|
259
297
|
window.removeEventListener("message", messageHandler);
|
|
@@ -262,7 +300,12 @@ var Client = class {
|
|
|
262
300
|
resolve(true);
|
|
263
301
|
} else if (retryCount < maxRetries - 1) {
|
|
264
302
|
setTimeout(() => {
|
|
265
|
-
this.checkClientExistsWithRetry(
|
|
303
|
+
this.checkClientExistsWithRetry(
|
|
304
|
+
clientId,
|
|
305
|
+
retryCount + 1,
|
|
306
|
+
maxRetries,
|
|
307
|
+
retryInterval
|
|
308
|
+
).then((exists) => resolve(exists));
|
|
266
309
|
}, retryInterval);
|
|
267
310
|
} else {
|
|
268
311
|
resolve(false);
|
|
@@ -270,27 +313,19 @@ var Client = class {
|
|
|
270
313
|
}
|
|
271
314
|
};
|
|
272
315
|
window.addEventListener("message", messageHandler);
|
|
273
|
-
window.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
316
|
+
window.top.postMessage(
|
|
317
|
+
{
|
|
318
|
+
type: "CLIENT_EXISTS_CHECK",
|
|
319
|
+
clientId,
|
|
320
|
+
requestId,
|
|
321
|
+
from: this.pageId
|
|
322
|
+
},
|
|
323
|
+
"*"
|
|
324
|
+
);
|
|
279
325
|
const removeHandlerTimeout = setTimeout(() => {
|
|
280
326
|
window.removeEventListener("message", messageHandler);
|
|
281
327
|
resolve(false);
|
|
282
328
|
}, retryInterval + 1e3);
|
|
283
|
-
} else {
|
|
284
|
-
const exists = this.pubsub.isClientExists(clientId);
|
|
285
|
-
if (exists) {
|
|
286
|
-
resolve(true);
|
|
287
|
-
} else if (retryCount < maxRetries - 1) {
|
|
288
|
-
setTimeout(() => {
|
|
289
|
-
this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists2) => resolve(exists2));
|
|
290
|
-
}, retryInterval);
|
|
291
|
-
} else {
|
|
292
|
-
resolve(false);
|
|
293
|
-
}
|
|
294
329
|
}
|
|
295
330
|
});
|
|
296
331
|
}
|
|
@@ -302,15 +337,35 @@ var Client = class {
|
|
|
302
337
|
} else {
|
|
303
338
|
message = event;
|
|
304
339
|
}
|
|
305
|
-
if (!message || !message.from || !message.to || message.to !== this.pageId)
|
|
340
|
+
if (!message || !message.from || !message.to || message.to !== this.pageId)
|
|
341
|
+
return;
|
|
306
342
|
if (this.callback) {
|
|
307
343
|
try {
|
|
308
344
|
this.callback(message);
|
|
309
345
|
} catch (error) {
|
|
310
|
-
console.error(
|
|
346
|
+
console.error(
|
|
347
|
+
`Client ${this.pageId} failed to process message:`,
|
|
348
|
+
error
|
|
349
|
+
);
|
|
311
350
|
}
|
|
312
351
|
}
|
|
313
352
|
}
|
|
353
|
+
getDebugInfo() {
|
|
354
|
+
let windowLevel = "main";
|
|
355
|
+
if (window !== window.top) {
|
|
356
|
+
if (window.parent === window.top) {
|
|
357
|
+
windowLevel = "first-level-iframe";
|
|
358
|
+
} else {
|
|
359
|
+
windowLevel = "nested-iframe";
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
pageId: this.pageId,
|
|
364
|
+
isMainApp: this.isMainApp,
|
|
365
|
+
isIframe: this.isIframe,
|
|
366
|
+
windowLevel
|
|
367
|
+
};
|
|
368
|
+
}
|
|
314
369
|
};
|
|
315
370
|
|
|
316
371
|
// src/aichat/AIChatClient.ts
|
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,11 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
|
|
5
|
+
// src/cors.ts
|
|
6
|
+
function isAllowedOrigin(origin) {
|
|
7
|
+
return origin === "null" || origin.startsWith("http://localhost") || origin.endsWith(".bkpi.co") || origin.endsWith(".bookipi.com");
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
// src/PubSub.ts
|
|
6
11
|
var _PubSub = class _PubSub {
|
|
7
12
|
constructor() {
|
|
@@ -56,7 +61,7 @@ var _PubSub = class _PubSub {
|
|
|
56
61
|
const subscriber = this.subscribers.get(message.to);
|
|
57
62
|
if (subscriber) {
|
|
58
63
|
if (subscriber.source) {
|
|
59
|
-
subscriber.source.postMessage(message, "*");
|
|
64
|
+
subscriber.source.postMessage(message, subscriber.origin || "*");
|
|
60
65
|
} else {
|
|
61
66
|
subscriber.callback(message);
|
|
62
67
|
}
|
|
@@ -73,12 +78,15 @@ var _PubSub = class _PubSub {
|
|
|
73
78
|
handleMessage(event) {
|
|
74
79
|
const data = event.data;
|
|
75
80
|
const source = event.source;
|
|
81
|
+
const origin = event.origin;
|
|
82
|
+
if (!isAllowedOrigin(origin)) return;
|
|
76
83
|
if (data?.type === "REGISTER") {
|
|
77
84
|
const registration = data;
|
|
78
85
|
this.subscribers.set(registration.pageId, {
|
|
79
86
|
source,
|
|
87
|
+
origin: registration.origin,
|
|
80
88
|
callback: (message2) => {
|
|
81
|
-
source.postMessage(message2, "*");
|
|
89
|
+
source.postMessage(message2, registration.origin || "*");
|
|
82
90
|
}
|
|
83
91
|
});
|
|
84
92
|
return;
|
|
@@ -93,7 +101,7 @@ var _PubSub = class _PubSub {
|
|
|
93
101
|
type: "CLIENT_EXISTS_RESPONSE",
|
|
94
102
|
requestId: data.requestId,
|
|
95
103
|
exists: this.subscribers.has(data.clientId)
|
|
96
|
-
}, "*");
|
|
104
|
+
}, data.origin || "*");
|
|
97
105
|
return;
|
|
98
106
|
}
|
|
99
107
|
if (!data || !data.from || !data.to) return;
|
|
@@ -103,8 +111,8 @@ var _PubSub = class _PubSub {
|
|
|
103
111
|
}
|
|
104
112
|
const subscriber = this.subscribers.get(message.to);
|
|
105
113
|
if (!subscriber) return;
|
|
106
|
-
if (subscriber
|
|
107
|
-
subscriber.source.postMessage(message, "*");
|
|
114
|
+
if (subscriber?.source) {
|
|
115
|
+
subscriber.source.postMessage(message, subscriber.origin || "*");
|
|
108
116
|
} else {
|
|
109
117
|
subscriber.callback(message);
|
|
110
118
|
}
|
|
@@ -135,46 +143,55 @@ var Client = class {
|
|
|
135
143
|
__publicField(this, "callback");
|
|
136
144
|
__publicField(this, "pubsub");
|
|
137
145
|
__publicField(this, "isIframe");
|
|
146
|
+
__publicField(this, "isMainApp");
|
|
138
147
|
__publicField(this, "boundHandleMessage");
|
|
139
148
|
this.targetAIChatClientId = targetAIChatClientId;
|
|
140
149
|
this.pageId = pageId;
|
|
141
|
-
this.pubsub = PubSub.getInstance();
|
|
142
150
|
this.isIframe = window !== window.parent;
|
|
151
|
+
this.isMainApp = window === window.top;
|
|
143
152
|
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
144
|
-
if (this.
|
|
145
|
-
|
|
146
|
-
type: "REGISTER",
|
|
147
|
-
pageId: this.pageId
|
|
148
|
-
}, "*");
|
|
149
|
-
window.addEventListener("message", this.boundHandleMessage);
|
|
150
|
-
} else {
|
|
153
|
+
if (this.isMainApp) {
|
|
154
|
+
this.pubsub = PubSub.getInstance();
|
|
151
155
|
this.pubsub.register(pageId, this.boundHandleMessage);
|
|
156
|
+
console.info(`\u2705 Client ${pageId} registered with main PubSub`);
|
|
157
|
+
} else {
|
|
158
|
+
console.info(
|
|
159
|
+
`\u{1F4E1} Client ${pageId} from iframe is registering with top window PubSub`
|
|
160
|
+
);
|
|
161
|
+
window.top.postMessage(
|
|
162
|
+
{
|
|
163
|
+
type: "REGISTER",
|
|
164
|
+
pageId: this.pageId,
|
|
165
|
+
origin: window.location.origin
|
|
166
|
+
},
|
|
167
|
+
"*"
|
|
168
|
+
);
|
|
169
|
+
window.addEventListener("message", this.boundHandleMessage);
|
|
152
170
|
}
|
|
153
171
|
}
|
|
154
172
|
/**
|
|
155
173
|
* Unregister the client from the pubsub.
|
|
156
174
|
*/
|
|
157
175
|
unregister() {
|
|
158
|
-
if (this.
|
|
159
|
-
window.parent.postMessage({
|
|
160
|
-
type: "UNREGISTER",
|
|
161
|
-
pageId: this.pageId
|
|
162
|
-
}, "*");
|
|
163
|
-
} else {
|
|
176
|
+
if (this.isMainApp && this.pubsub) {
|
|
164
177
|
this.pubsub.unregister(this.pageId);
|
|
178
|
+
} else {
|
|
179
|
+
window.top.postMessage(
|
|
180
|
+
{
|
|
181
|
+
type: "UNREGISTER",
|
|
182
|
+
pageId: this.pageId,
|
|
183
|
+
origin: window.location.origin
|
|
184
|
+
},
|
|
185
|
+
"*"
|
|
186
|
+
);
|
|
187
|
+
window.removeEventListener("message", this.boundHandleMessage);
|
|
165
188
|
}
|
|
189
|
+
console.info(`\u274C Client ${this.pageId} unregistered from PubSub`);
|
|
166
190
|
}
|
|
167
|
-
|
|
168
|
-
* Clean up the aichat registration if the iframe is removed.
|
|
169
|
-
*
|
|
170
|
-
* Note: aichat itself does not know the iframe is removed then we have to clean up from parent
|
|
171
|
-
*/
|
|
191
|
+
// Will not support this method anymore.
|
|
172
192
|
cleanAIChat() {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
window.removeEventListener("message", this.boundHandleMessage);
|
|
177
|
-
return this.pubsub.unregister(this.targetAIChatClientId);
|
|
193
|
+
console.warn(`\u203C\uFE0F Unsupported operation cleanAIChat has been called from ${this.pageId}.`);
|
|
194
|
+
return false;
|
|
178
195
|
}
|
|
179
196
|
/**
|
|
180
197
|
* Listen for messages from the parent page with a callback.
|
|
@@ -196,10 +213,10 @@ var Client = class {
|
|
|
196
213
|
to,
|
|
197
214
|
payload
|
|
198
215
|
};
|
|
199
|
-
if (this.
|
|
200
|
-
window.parent.postMessage(message, "*");
|
|
201
|
-
} else {
|
|
216
|
+
if (this.isMainApp && this.pubsub) {
|
|
202
217
|
this.pubsub.sendMessage(message);
|
|
218
|
+
} else {
|
|
219
|
+
window.top.postMessage(message, "*");
|
|
203
220
|
}
|
|
204
221
|
}
|
|
205
222
|
/**
|
|
@@ -211,7 +228,12 @@ var Client = class {
|
|
|
211
228
|
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
|
212
229
|
*/
|
|
213
230
|
checkClientExists(clientId, maxRetries = 3, retryInterval = 1e3) {
|
|
214
|
-
return this.checkClientExistsWithRetry(
|
|
231
|
+
return this.checkClientExistsWithRetry(
|
|
232
|
+
clientId,
|
|
233
|
+
0,
|
|
234
|
+
maxRetries,
|
|
235
|
+
retryInterval
|
|
236
|
+
);
|
|
215
237
|
}
|
|
216
238
|
/**
|
|
217
239
|
* Check if a client with the given ID exists in the PubSub system with retry mechanism.
|
|
@@ -220,13 +242,29 @@ var Client = class {
|
|
|
220
242
|
* @param clientId The ID of the client to check.
|
|
221
243
|
* @param retryCount The current retry count.
|
|
222
244
|
* @returns A Promise that resolves to true if the client exists, false otherwise.
|
|
223
|
-
* @private
|
|
224
245
|
*/
|
|
225
246
|
checkClientExistsWithRetry(clientId, retryCount, maxRetries, retryInterval) {
|
|
226
247
|
return new Promise((resolve) => {
|
|
227
|
-
if (this.
|
|
248
|
+
if (this.isMainApp && this.pubsub) {
|
|
249
|
+
const exists = this.pubsub.isClientExists(clientId);
|
|
250
|
+
if (exists) {
|
|
251
|
+
resolve(true);
|
|
252
|
+
} else if (retryCount < maxRetries - 1) {
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
this.checkClientExistsWithRetry(
|
|
255
|
+
clientId,
|
|
256
|
+
retryCount + 1,
|
|
257
|
+
maxRetries,
|
|
258
|
+
retryInterval
|
|
259
|
+
).then((exists2) => resolve(exists2));
|
|
260
|
+
}, retryInterval);
|
|
261
|
+
} else {
|
|
262
|
+
resolve(false);
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
228
265
|
const requestId = `check-client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
229
266
|
const messageHandler = (event) => {
|
|
267
|
+
if (!isAllowedOrigin(event.origin)) return;
|
|
230
268
|
const data = event.data;
|
|
231
269
|
if (data && data.type === "CLIENT_EXISTS_RESPONSE" && data.requestId === requestId) {
|
|
232
270
|
window.removeEventListener("message", messageHandler);
|
|
@@ -235,7 +273,12 @@ var Client = class {
|
|
|
235
273
|
resolve(true);
|
|
236
274
|
} else if (retryCount < maxRetries - 1) {
|
|
237
275
|
setTimeout(() => {
|
|
238
|
-
this.checkClientExistsWithRetry(
|
|
276
|
+
this.checkClientExistsWithRetry(
|
|
277
|
+
clientId,
|
|
278
|
+
retryCount + 1,
|
|
279
|
+
maxRetries,
|
|
280
|
+
retryInterval
|
|
281
|
+
).then((exists) => resolve(exists));
|
|
239
282
|
}, retryInterval);
|
|
240
283
|
} else {
|
|
241
284
|
resolve(false);
|
|
@@ -243,27 +286,19 @@ var Client = class {
|
|
|
243
286
|
}
|
|
244
287
|
};
|
|
245
288
|
window.addEventListener("message", messageHandler);
|
|
246
|
-
window.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
289
|
+
window.top.postMessage(
|
|
290
|
+
{
|
|
291
|
+
type: "CLIENT_EXISTS_CHECK",
|
|
292
|
+
clientId,
|
|
293
|
+
requestId,
|
|
294
|
+
from: this.pageId
|
|
295
|
+
},
|
|
296
|
+
"*"
|
|
297
|
+
);
|
|
252
298
|
const removeHandlerTimeout = setTimeout(() => {
|
|
253
299
|
window.removeEventListener("message", messageHandler);
|
|
254
300
|
resolve(false);
|
|
255
301
|
}, retryInterval + 1e3);
|
|
256
|
-
} else {
|
|
257
|
-
const exists = this.pubsub.isClientExists(clientId);
|
|
258
|
-
if (exists) {
|
|
259
|
-
resolve(true);
|
|
260
|
-
} else if (retryCount < maxRetries - 1) {
|
|
261
|
-
setTimeout(() => {
|
|
262
|
-
this.checkClientExistsWithRetry(clientId, retryCount + 1, maxRetries, retryInterval).then((exists2) => resolve(exists2));
|
|
263
|
-
}, retryInterval);
|
|
264
|
-
} else {
|
|
265
|
-
resolve(false);
|
|
266
|
-
}
|
|
267
302
|
}
|
|
268
303
|
});
|
|
269
304
|
}
|
|
@@ -275,15 +310,35 @@ var Client = class {
|
|
|
275
310
|
} else {
|
|
276
311
|
message = event;
|
|
277
312
|
}
|
|
278
|
-
if (!message || !message.from || !message.to || message.to !== this.pageId)
|
|
313
|
+
if (!message || !message.from || !message.to || message.to !== this.pageId)
|
|
314
|
+
return;
|
|
279
315
|
if (this.callback) {
|
|
280
316
|
try {
|
|
281
317
|
this.callback(message);
|
|
282
318
|
} catch (error) {
|
|
283
|
-
console.error(
|
|
319
|
+
console.error(
|
|
320
|
+
`Client ${this.pageId} failed to process message:`,
|
|
321
|
+
error
|
|
322
|
+
);
|
|
284
323
|
}
|
|
285
324
|
}
|
|
286
325
|
}
|
|
326
|
+
getDebugInfo() {
|
|
327
|
+
let windowLevel = "main";
|
|
328
|
+
if (window !== window.top) {
|
|
329
|
+
if (window.parent === window.top) {
|
|
330
|
+
windowLevel = "first-level-iframe";
|
|
331
|
+
} else {
|
|
332
|
+
windowLevel = "nested-iframe";
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
pageId: this.pageId,
|
|
337
|
+
isMainApp: this.isMainApp,
|
|
338
|
+
isIframe: this.isIframe,
|
|
339
|
+
windowLevel
|
|
340
|
+
};
|
|
341
|
+
}
|
|
287
342
|
};
|
|
288
343
|
|
|
289
344
|
// src/aichat/AIChatClient.ts
|