iframe.io 1.0.5 → 1.1.0
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/README.md +260 -324
- package/dist/index.d.ts +1 -1
- package/dist/index.js +52 -28
- package/package.json +1 -1
- package/src/index.ts +204 -165
package/dist/index.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export default class IOF {
|
|
|
75
75
|
once(_event: string, fn: Listener): this;
|
|
76
76
|
off(_event: string, fn?: Listener): this;
|
|
77
77
|
removeListeners(fn?: Listener): this;
|
|
78
|
-
emitAsync<T = any, R = any>(_event: string, payload?: T): Promise<R>;
|
|
78
|
+
emitAsync<T = any, R = any>(_event: string, payload?: T, timeout?: number): Promise<R>;
|
|
79
79
|
onceAsync<T = any>(_event: string): Promise<T>;
|
|
80
80
|
connectAsync(timeout?: number): Promise<void>;
|
|
81
81
|
private cleanup;
|
package/dist/index.js
CHANGED
|
@@ -35,18 +35,21 @@ function sanitizePayload(payload, maxSize) {
|
|
|
35
35
|
if (!payload)
|
|
36
36
|
return payload;
|
|
37
37
|
var size = getMessageSize(payload);
|
|
38
|
-
if (size > maxSize)
|
|
38
|
+
if (size > maxSize)
|
|
39
39
|
throw new Error("Message size ".concat(size, " exceeds limit ").concat(maxSize));
|
|
40
|
-
}
|
|
41
40
|
// Basic sanitization - remove functions and undefined values
|
|
42
41
|
return JSON.parse(JSON.stringify(payload));
|
|
43
42
|
}
|
|
44
43
|
var ackId = function () {
|
|
45
|
-
var rmin = 100000, rmax = 999999;
|
|
46
|
-
var timestamp = Date.now();
|
|
47
|
-
var random = Math.floor(Math.random() * (rmax - rmin + 1) + rmin);
|
|
44
|
+
var rmin = 100000, rmax = 999999, timestamp = Date.now(), random = Math.floor(Math.random() * (rmax - rmin + 1) + rmin);
|
|
48
45
|
return "".concat(timestamp, "_").concat(random);
|
|
49
46
|
};
|
|
47
|
+
var RESERVED_EVENTS = [
|
|
48
|
+
'ping',
|
|
49
|
+
'pong',
|
|
50
|
+
'__heartbeat',
|
|
51
|
+
'__heartbeat_response'
|
|
52
|
+
];
|
|
50
53
|
var IOF = /** @class */ (function () {
|
|
51
54
|
function IOF(options) {
|
|
52
55
|
if (options === void 0) { options = {}; }
|
|
@@ -81,7 +84,8 @@ var IOF = /** @class */ (function () {
|
|
|
81
84
|
if (_this.isConnected()) {
|
|
82
85
|
var now = Date.now();
|
|
83
86
|
// Check if peer is still responsive
|
|
84
|
-
if (_this.peer.lastHeartbeat
|
|
87
|
+
if (_this.peer.lastHeartbeat
|
|
88
|
+
&& (now - _this.peer.lastHeartbeat) > (_this.options.heartbeatInterval * 2)) {
|
|
85
89
|
_this.debug("[".concat(_this.peer.type, "] Heartbeat timeout detected"));
|
|
86
90
|
_this.handleConnectionLoss();
|
|
87
91
|
return;
|
|
@@ -132,11 +136,11 @@ var IOF = /** @class */ (function () {
|
|
|
132
136
|
// For IFRAME type, just wait for incoming connection
|
|
133
137
|
// Set timeout for this reconnection attempt
|
|
134
138
|
setTimeout(function () {
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
if (_this.peer.connected)
|
|
140
|
+
return;
|
|
141
|
+
_this.reconnectAttempts < _this.maxReconnectAttempts
|
|
142
|
+
? _this.attemptReconnection()
|
|
143
|
+
: _this.fire('reconnection_failed', { attempts: _this.reconnectAttempts });
|
|
140
144
|
}, _this.options.connectionTimeout);
|
|
141
145
|
}, delay);
|
|
142
146
|
};
|
|
@@ -238,7 +242,8 @@ var IOF = /** @class */ (function () {
|
|
|
238
242
|
_this.startHeartbeat();
|
|
239
243
|
_this.fire('connect');
|
|
240
244
|
_this.processMessageQueue();
|
|
241
|
-
|
|
245
|
+
_this.debug("[".concat(_this.peer.type, "] connected"));
|
|
246
|
+
return;
|
|
242
247
|
}
|
|
243
248
|
// Fire available event listeners
|
|
244
249
|
_this.fire(_event, payload, cid);
|
|
@@ -273,7 +278,11 @@ var IOF = /** @class */ (function () {
|
|
|
273
278
|
try {
|
|
274
279
|
// Enhanced security: check host origin where event must only come from
|
|
275
280
|
if (hostOrigin && hostOrigin !== origin) {
|
|
276
|
-
_this.fire('error', {
|
|
281
|
+
_this.fire('error', {
|
|
282
|
+
type: 'INVALID_ORIGIN',
|
|
283
|
+
expected: hostOrigin,
|
|
284
|
+
received: origin
|
|
285
|
+
});
|
|
277
286
|
return;
|
|
278
287
|
}
|
|
279
288
|
// Enhanced security: check valid message structure
|
|
@@ -288,7 +297,11 @@ var IOF = /** @class */ (function () {
|
|
|
288
297
|
}
|
|
289
298
|
// Origin different from handshaked source origin
|
|
290
299
|
else if (origin !== _this.peer.origin) {
|
|
291
|
-
_this.fire('error', {
|
|
300
|
+
_this.fire('error', {
|
|
301
|
+
type: 'ORIGIN_MISMATCH',
|
|
302
|
+
expected: _this.peer.origin,
|
|
303
|
+
received: origin
|
|
304
|
+
});
|
|
292
305
|
return;
|
|
293
306
|
}
|
|
294
307
|
var _event = data._event, payload = data.payload, cid = data.cid, timestamp = data.timestamp;
|
|
@@ -314,7 +327,8 @@ var IOF = /** @class */ (function () {
|
|
|
314
327
|
_this.startHeartbeat();
|
|
315
328
|
_this.fire('connect');
|
|
316
329
|
_this.processMessageQueue();
|
|
317
|
-
|
|
330
|
+
_this.debug("[".concat(_this.peer.type, "] connected"));
|
|
331
|
+
return;
|
|
318
332
|
}
|
|
319
333
|
// Fire available event listeners
|
|
320
334
|
_this.fire(_event, payload, cid);
|
|
@@ -334,9 +348,10 @@ var IOF = /** @class */ (function () {
|
|
|
334
348
|
IOF.prototype.fire = function (_event, payload, cid) {
|
|
335
349
|
var _this = this;
|
|
336
350
|
// Volatile event - check if any listeners exist
|
|
337
|
-
if (!this.Events[_event]
|
|
338
|
-
|
|
339
|
-
return
|
|
351
|
+
if (!this.Events[_event] && !this.Events[_event + '--@once']) {
|
|
352
|
+
this.debug("[".concat(this.peer.type, "] No <").concat(_event, "> listener defined"));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
340
355
|
var ackFn = cid
|
|
341
356
|
? function (error) {
|
|
342
357
|
var args = [];
|
|
@@ -376,8 +391,11 @@ var IOF = /** @class */ (function () {
|
|
|
376
391
|
// Check rate limiting
|
|
377
392
|
if (!this.checkRateLimit())
|
|
378
393
|
return this;
|
|
379
|
-
|
|
380
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Queue message if not connected: Except for
|
|
396
|
+
* connection-related events
|
|
397
|
+
*/
|
|
398
|
+
if (!this.isConnected() && !RESERVED_EVENTS.includes(_event)) {
|
|
381
399
|
this.queueMessage(_event, payload, fn);
|
|
382
400
|
return this;
|
|
383
401
|
}
|
|
@@ -391,7 +409,9 @@ var IOF = /** @class */ (function () {
|
|
|
391
409
|
}
|
|
392
410
|
try {
|
|
393
411
|
// Enhanced security: sanitize and validate payload
|
|
394
|
-
var sanitizedPayload = payload
|
|
412
|
+
var sanitizedPayload = payload
|
|
413
|
+
? sanitizePayload(payload, this.options.maxMessageSize)
|
|
414
|
+
: payload;
|
|
395
415
|
// Acknowledge event listener
|
|
396
416
|
var cid = void 0;
|
|
397
417
|
if (typeof fn === 'function') {
|
|
@@ -419,9 +439,8 @@ var IOF = /** @class */ (function () {
|
|
|
419
439
|
error: error instanceof Error ? error.message : String(error)
|
|
420
440
|
});
|
|
421
441
|
// Call acknowledgment with error if provided
|
|
422
|
-
|
|
423
|
-
fn(error instanceof Error ? error.message : String(error));
|
|
424
|
-
}
|
|
442
|
+
typeof fn === 'function'
|
|
443
|
+
&& fn(error instanceof Error ? error.message : String(error));
|
|
425
444
|
}
|
|
426
445
|
return this;
|
|
427
446
|
};
|
|
@@ -468,21 +487,27 @@ var IOF = /** @class */ (function () {
|
|
|
468
487
|
this.debug("[".concat(this.peer.type, "] All listeners removed"));
|
|
469
488
|
return this;
|
|
470
489
|
};
|
|
471
|
-
IOF.prototype.emitAsync = function (_event, payload) {
|
|
490
|
+
IOF.prototype.emitAsync = function (_event, payload, timeout) {
|
|
472
491
|
var _this = this;
|
|
492
|
+
if (timeout === void 0) { timeout = 5000; }
|
|
473
493
|
return new Promise(function (resolve, reject) {
|
|
494
|
+
var timeoutId = setTimeout(function () {
|
|
495
|
+
reject(new Error("Event '".concat(_event, "' acknowledgment timeout after ").concat(timeout, "ms")));
|
|
496
|
+
}, timeout);
|
|
474
497
|
try {
|
|
475
498
|
_this.emit(_event, payload, function (error) {
|
|
476
499
|
var args = [];
|
|
477
500
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
478
501
|
args[_i - 1] = arguments[_i];
|
|
479
502
|
}
|
|
503
|
+
clearTimeout(timeoutId);
|
|
480
504
|
error
|
|
481
505
|
? reject(new Error(typeof error === 'string' ? error : 'Ack error'))
|
|
482
506
|
: resolve(args.length === 0 ? undefined : args.length === 1 ? args[0] : args);
|
|
483
507
|
});
|
|
484
508
|
}
|
|
485
509
|
catch (error) {
|
|
510
|
+
clearTimeout(timeoutId);
|
|
486
511
|
reject(error);
|
|
487
512
|
}
|
|
488
513
|
});
|
|
@@ -493,14 +518,13 @@ var IOF = /** @class */ (function () {
|
|
|
493
518
|
};
|
|
494
519
|
IOF.prototype.connectAsync = function (timeout) {
|
|
495
520
|
var _this = this;
|
|
496
|
-
if (timeout === void 0) { timeout = 5000; }
|
|
497
521
|
return new Promise(function (resolve, reject) {
|
|
498
522
|
if (_this.isConnected())
|
|
499
523
|
return resolve();
|
|
500
524
|
var timeoutId = setTimeout(function () {
|
|
501
525
|
_this.off('connect', connectHandler);
|
|
502
526
|
reject(new Error('Connection timeout'));
|
|
503
|
-
}, timeout);
|
|
527
|
+
}, timeout || _this.options.connectionTimeout);
|
|
504
528
|
var connectHandler = function () {
|
|
505
529
|
clearTimeout(timeoutId);
|
|
506
530
|
resolve();
|
|
@@ -521,7 +545,7 @@ var IOF = /** @class */ (function () {
|
|
|
521
545
|
}
|
|
522
546
|
};
|
|
523
547
|
IOF.prototype.disconnect = function (fn) {
|
|
524
|
-
//
|
|
548
|
+
// Cleanup on disconnect
|
|
525
549
|
this.cleanup();
|
|
526
550
|
this.peer.connected = false;
|
|
527
551
|
this.peer.source = undefined;
|
package/package.json
CHANGED