iframe.io 1.0.6 → 1.2.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/dist/index.js CHANGED
@@ -1,24 +1,4 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
- if (ar || !(i in from)) {
16
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
- ar[i] = from[i];
18
- }
19
- }
20
- return to.concat(ar || Array.prototype.slice.call(from));
21
- };
22
2
  Object.defineProperty(exports, "__esModule", { value: true });
23
3
  function newObject(data) {
24
4
  return JSON.parse(JSON.stringify(data));
@@ -27,88 +7,107 @@ function getMessageSize(data) {
27
7
  try {
28
8
  return JSON.stringify(data).length;
29
9
  }
30
- catch (_a) {
10
+ catch {
31
11
  return 0;
32
12
  }
33
13
  }
34
14
  function sanitizePayload(payload, maxSize) {
35
15
  if (!payload)
36
16
  return payload;
37
- var size = getMessageSize(payload);
17
+ const size = getMessageSize(payload);
38
18
  if (size > maxSize)
39
- throw new Error("Message size ".concat(size, " exceeds limit ").concat(maxSize));
19
+ throw new Error(`Message size ${size} exceeds limit ${maxSize}`);
40
20
  // Basic sanitization - remove functions and undefined values
41
21
  return JSON.parse(JSON.stringify(payload));
42
22
  }
43
- var ackId = function () {
44
- var rmin = 100000, rmax = 999999, timestamp = Date.now(), random = Math.floor(Math.random() * (rmax - rmin + 1) + rmin);
45
- return "".concat(timestamp, "_").concat(random);
23
+ const ackId = () => {
24
+ // Prefer cryptographically strong randomness when available
25
+ try {
26
+ const globalCrypto = (typeof crypto !== 'undefined'
27
+ ? crypto
28
+ : (typeof window !== 'undefined' && window.crypto)
29
+ || (typeof globalThis !== 'undefined' && globalThis.crypto));
30
+ if (globalCrypto && typeof globalCrypto.getRandomValues === 'function') {
31
+ const buffer = new Uint32Array(4);
32
+ globalCrypto.getRandomValues(buffer);
33
+ const randomPart = Array.from(buffer).map(n => n.toString(16)).join('');
34
+ return `${Date.now()}_${randomPart}`;
35
+ }
36
+ }
37
+ catch {
38
+ // Fall back to Math.random-based implementation below
39
+ }
40
+ const rmin = 100000, rmax = 999999, timestampFallback = Date.now(), randomFallback = Math.floor(Math.random() * (rmax - rmin + 1) + rmin);
41
+ return `${timestampFallback}_${randomFallback}`;
46
42
  };
47
- var RESERVED_EVENTS = [
43
+ const RESERVED_EVENTS = [
48
44
  'ping',
49
45
  'pong',
50
46
  '__heartbeat',
51
47
  '__heartbeat_response'
52
48
  ];
53
- var IOF = /** @class */ (function () {
54
- function IOF(options) {
55
- if (options === void 0) { options = {}; }
49
+ class IOF {
50
+ constructor(options = {}) {
56
51
  this.messageQueue = [];
57
52
  this.messageRateTracker = [];
58
53
  this.reconnectAttempts = 0;
59
54
  this.maxReconnectAttempts = 5;
60
55
  if (options && typeof options !== 'object')
61
56
  throw new Error('Invalid Options');
62
- this.options = __assign({ debug: false, heartbeatInterval: 30000, connectionTimeout: 10000, maxMessageSize: 1024 * 1024, maxMessagesPerSecond: 100, autoReconnect: true, messageQueueSize: 50 }, options);
57
+ this.options = {
58
+ debug: false,
59
+ heartbeatInterval: 30000,
60
+ connectionTimeout: 10000,
61
+ maxMessageSize: 1024 * 1024,
62
+ maxMessagesPerSecond: 100,
63
+ autoReconnect: true,
64
+ messageQueueSize: 50,
65
+ ...options
66
+ };
63
67
  this.Events = {};
64
68
  this.peer = { type: 'IFRAME', connected: false };
65
69
  if (options.type)
66
70
  this.peer.type = options.type.toUpperCase();
67
71
  }
68
- IOF.prototype.debug = function () {
69
- var args = [];
70
- for (var _i = 0; _i < arguments.length; _i++) {
71
- args[_i] = arguments[_i];
72
- }
73
- this.options.debug && console.debug.apply(console, args);
74
- };
75
- IOF.prototype.isConnected = function () {
72
+ debug(...args) {
73
+ this.options.debug && console.debug(...args);
74
+ }
75
+ isConnected() {
76
76
  return !!this.peer.connected && !!this.peer.source;
77
- };
77
+ }
78
78
  // Enhanced connection health monitoring
79
- IOF.prototype.startHeartbeat = function () {
80
- var _this = this;
79
+ startHeartbeat() {
81
80
  if (!this.options.heartbeatInterval)
82
81
  return;
83
- this.heartbeatTimer = setInterval(function () {
84
- if (_this.isConnected()) {
85
- var now = Date.now();
82
+ this.heartbeatTimer = setInterval(() => {
83
+ if (this.isConnected()) {
84
+ const now = Date.now();
86
85
  // Check if peer is still responsive
87
- if (_this.peer.lastHeartbeat
88
- && (now - _this.peer.lastHeartbeat) > (_this.options.heartbeatInterval * 2)) {
89
- _this.debug("[".concat(_this.peer.type, "] Heartbeat timeout detected"));
90
- _this.handleConnectionLoss();
86
+ if (this.peer.lastHeartbeat
87
+ && (now - this.peer.lastHeartbeat) > (this.options.heartbeatInterval * 2)) {
88
+ this.debug(`[${this.peer.type}] Heartbeat timeout detected`);
89
+ this.handleConnectionLoss();
91
90
  return;
92
91
  }
93
92
  // Send heartbeat
94
93
  try {
95
- _this.emit('__heartbeat', { timestamp: now });
94
+ this.emit('__heartbeat', { timestamp: now });
96
95
  }
97
96
  catch (error) {
98
- _this.debug("[".concat(_this.peer.type, "] Heartbeat send failed:"), error);
99
- _this.handleConnectionLoss();
97
+ this.debug(`[${this.peer.type}] Heartbeat send failed:`, error);
98
+ this.handleConnectionLoss();
100
99
  }
101
100
  }
102
101
  }, this.options.heartbeatInterval);
103
- };
104
- IOF.prototype.stopHeartbeat = function () {
102
+ }
103
+ stopHeartbeat() {
105
104
  if (!this.heartbeatTimer)
106
105
  return;
107
106
  clearInterval(this.heartbeatTimer);
108
107
  this.heartbeatTimer = undefined;
109
- };
108
+ }
110
109
  // Handle connection loss and potential reconnection
111
- IOF.prototype.handleConnectionLoss = function () {
110
+ handleConnectionLoss() {
112
111
  if (!this.peer.connected)
113
112
  return;
114
113
  this.peer.connected = false;
@@ -117,40 +116,39 @@ var IOF = /** @class */ (function () {
117
116
  this.options.autoReconnect
118
117
  && this.reconnectAttempts < this.maxReconnectAttempts
119
118
  && this.attemptReconnection();
120
- };
121
- IOF.prototype.attemptReconnection = function () {
122
- var _this = this;
119
+ }
120
+ attemptReconnection() {
123
121
  if (this.reconnectTimer)
124
122
  return;
125
123
  this.reconnectAttempts++;
126
- var delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30000); // Exponential backoff, max 30s
127
- this.debug("[".concat(this.peer.type, "] Attempting reconnection ").concat(this.reconnectAttempts, "/").concat(this.maxReconnectAttempts, " in ").concat(delay, "ms"));
128
- this.fire('reconnecting', { attempt: this.reconnectAttempts, delay: delay });
129
- this.reconnectTimer = setTimeout(function () {
130
- _this.reconnectTimer = undefined;
124
+ const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30000); // Exponential backoff, max 30s
125
+ this.debug(`[${this.peer.type}] Attempting reconnection ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`);
126
+ this.fire('reconnecting', { attempt: this.reconnectAttempts, delay });
127
+ this.reconnectTimer = setTimeout(() => {
128
+ this.reconnectTimer = undefined;
131
129
  // Re-initiate connection for WINDOW type
132
- _this.peer.type === 'WINDOW'
133
- && _this.peer.source
134
- && _this.peer.origin
135
- && _this.emit('ping');
130
+ this.peer.type === 'WINDOW'
131
+ && this.peer.source
132
+ && this.peer.origin
133
+ && this.emit('ping');
136
134
  // For IFRAME type, just wait for incoming connection
137
135
  // Set timeout for this reconnection attempt
138
- setTimeout(function () {
139
- if (_this.peer.connected)
136
+ setTimeout(() => {
137
+ if (this.peer.connected)
140
138
  return;
141
- _this.reconnectAttempts < _this.maxReconnectAttempts
142
- ? _this.attemptReconnection()
143
- : _this.fire('reconnection_failed', { attempts: _this.reconnectAttempts });
144
- }, _this.options.connectionTimeout);
139
+ this.reconnectAttempts < this.maxReconnectAttempts
140
+ ? this.attemptReconnection()
141
+ : this.fire('reconnection_failed', { attempts: this.reconnectAttempts });
142
+ }, this.options.connectionTimeout);
145
143
  }, delay);
146
- };
144
+ }
147
145
  // Message rate limiting
148
- IOF.prototype.checkRateLimit = function () {
146
+ checkRateLimit() {
149
147
  if (!this.options.maxMessagesPerSecond)
150
148
  return true;
151
- var now = Date.now(), aSecondAgo = now - 1000;
149
+ const now = Date.now(), aSecondAgo = now - 1000;
152
150
  // Clean old entries
153
- this.messageRateTracker = this.messageRateTracker.filter(function (timestamp) { return timestamp > aSecondAgo; });
151
+ this.messageRateTracker = this.messageRateTracker.filter(timestamp => timestamp > aSecondAgo);
154
152
  // Check if limit exceeded
155
153
  if (this.messageRateTracker.length >= this.options.maxMessagesPerSecond) {
156
154
  this.fire('error', {
@@ -162,45 +160,43 @@ var IOF = /** @class */ (function () {
162
160
  }
163
161
  this.messageRateTracker.push(now);
164
162
  return true;
165
- };
163
+ }
166
164
  // Queue messages when not connected
167
- IOF.prototype.queueMessage = function (_event, payload, fn) {
165
+ queueMessage(_event, payload, fn) {
168
166
  if (this.messageQueue.length >= this.options.messageQueueSize) {
169
167
  // Remove oldest message
170
- var removed = this.messageQueue.shift();
171
- this.debug("[".concat(this.peer.type, "] Message queue full, removed oldest message:"), removed === null || removed === void 0 ? void 0 : removed._event);
168
+ const removed = this.messageQueue.shift();
169
+ this.debug(`[${this.peer.type}] Message queue full, removed oldest message:`, removed?._event);
172
170
  }
173
171
  this.messageQueue.push({
174
- _event: _event,
175
- payload: payload,
176
- fn: fn,
172
+ _event,
173
+ payload,
174
+ fn,
177
175
  timestamp: Date.now()
178
176
  });
179
- this.debug("[".concat(this.peer.type, "] Queued message: ").concat(_event, " (queue size: ").concat(this.messageQueue.length, ")"));
180
- };
177
+ this.debug(`[${this.peer.type}] Queued message: ${_event} (queue size: ${this.messageQueue.length})`);
178
+ }
181
179
  // Process queued messages when connection is established
182
- IOF.prototype.processMessageQueue = function () {
183
- var _this = this;
180
+ processMessageQueue() {
184
181
  if (!this.isConnected() || this.messageQueue.length === 0)
185
182
  return;
186
- this.debug("[".concat(this.peer.type, "] Processing ").concat(this.messageQueue.length, " queued messages"));
187
- var queue = __spreadArray([], this.messageQueue, true);
183
+ this.debug(`[${this.peer.type}] Processing ${this.messageQueue.length} queued messages`);
184
+ const queue = [...this.messageQueue];
188
185
  this.messageQueue = [];
189
- queue.forEach(function (message) {
186
+ queue.forEach(message => {
190
187
  try {
191
- _this.emit(message._event, message.payload, message.fn);
188
+ this.emit(message._event, message.payload, message.fn);
192
189
  }
193
190
  catch (error) {
194
- _this.debug("[".concat(_this.peer.type, "] Failed to send queued message:"), error);
191
+ this.debug(`[${this.peer.type}] Failed to send queued message:`, error);
195
192
  }
196
193
  });
197
- };
194
+ }
198
195
  /**
199
196
  * Establish a connection with an iframe containing
200
197
  * in the current window
201
198
  */
202
- IOF.prototype.initiate = function (contentWindow, iframeOrigin) {
203
- var _this = this;
199
+ initiate(contentWindow, iframeOrigin) {
204
200
  if (!contentWindow || !iframeOrigin)
205
201
  throw new Error('Invalid Connection initiation arguments');
206
202
  if (this.peer.type === 'IFRAME')
@@ -211,73 +207,94 @@ var IOF = /** @class */ (function () {
211
207
  this.peer.origin = iframeOrigin;
212
208
  this.peer.connected = false;
213
209
  this.reconnectAttempts = 0;
214
- this.messageListener = function (_a) {
215
- var origin = _a.origin, data = _a.data, source = _a.source;
210
+ this.messageListener = ({ origin, data, source }) => {
216
211
  try {
217
212
  // Enhanced security: check valid message structure
218
- if (origin !== _this.peer.origin
213
+ if (origin !== this.peer.origin
219
214
  || !source
220
215
  || typeof data !== 'object'
221
216
  || !data.hasOwnProperty('_event'))
222
217
  return;
223
- var _b = data, _event = _b._event, payload = _b.payload, cid = _b.cid, timestamp = _b.timestamp;
218
+ const { _event, payload, cid, timestamp } = data;
224
219
  // Handle heartbeat responses
225
220
  if (_event === '__heartbeat_response') {
226
- _this.peer.lastHeartbeat = Date.now();
221
+ this.peer.lastHeartbeat = Date.now();
227
222
  return;
228
223
  }
229
224
  // Handle heartbeat requests
230
225
  if (_event === '__heartbeat') {
231
- _this.emit('__heartbeat_response', { timestamp: Date.now() });
232
- _this.peer.lastHeartbeat = Date.now();
226
+ this.emit('__heartbeat_response', { timestamp: Date.now() });
227
+ this.peer.lastHeartbeat = Date.now();
233
228
  return;
234
229
  }
235
- _this.debug("[".concat(_this.peer.type, "] Message: ").concat(_event), payload || '');
230
+ this.debug(`[${this.peer.type}] Message: ${_event}`, payload || '');
236
231
  // Handshake or availability check events
237
232
  if (_event == 'pong') {
238
233
  // Content Window is connected to iframe
239
- _this.peer.connected = true;
240
- _this.reconnectAttempts = 0;
241
- _this.peer.lastHeartbeat = Date.now();
242
- _this.startHeartbeat();
243
- _this.fire('connect');
244
- _this.processMessageQueue();
245
- return _this.debug("[".concat(_this.peer.type, "] connected"));
234
+ this.peer.connected = true;
235
+ this.reconnectAttempts = 0;
236
+ this.peer.lastHeartbeat = Date.now();
237
+ this.startHeartbeat();
238
+ this.fire('connect');
239
+ this.processMessageQueue();
240
+ this.debug(`[${this.peer.type}] connected`);
241
+ return;
242
+ }
243
+ // Optional application-level incoming validation (non-reserved events only)
244
+ if (!RESERVED_EVENTS.includes(_event)) {
245
+ if (this.options.allowedIncomingEvents
246
+ && !this.options.allowedIncomingEvents.includes(_event)) {
247
+ this.fire('error', {
248
+ type: 'DISALLOWED_EVENT',
249
+ direction: 'incoming',
250
+ event: _event,
251
+ origin
252
+ });
253
+ return;
254
+ }
255
+ if (this.options.validateIncoming
256
+ && !this.options.validateIncoming(_event, payload, origin)) {
257
+ this.fire('error', {
258
+ type: 'INVALID_MESSAGE',
259
+ direction: 'incoming',
260
+ event: _event,
261
+ origin
262
+ });
263
+ return;
264
+ }
246
265
  }
247
266
  // Fire available event listeners
248
- _this.fire(_event, payload, cid);
267
+ this.fire(_event, payload, cid);
249
268
  }
250
269
  catch (error) {
251
- _this.debug("[".concat(_this.peer.type, "] Message handling error:"), error);
252
- _this.fire('error', {
270
+ this.debug(`[${this.peer.type}] Message handling error:`, error);
271
+ this.fire('error', {
253
272
  type: 'MESSAGE_HANDLING_ERROR',
254
273
  error: error instanceof Error ? error.message : String(error),
255
- origin: origin
274
+ origin
256
275
  });
257
276
  }
258
277
  };
259
278
  window.addEventListener('message', this.messageListener, false);
260
- this.debug("[".concat(this.peer.type, "] Initiate connection: IFrame origin <").concat(iframeOrigin, ">"));
279
+ this.debug(`[${this.peer.type}] Initiate connection: IFrame origin <${iframeOrigin}>`);
261
280
  this.emit('ping');
262
281
  return this;
263
- };
282
+ }
264
283
  /**
265
284
  * Listening to connection from the content window
266
285
  */
267
- IOF.prototype.listen = function (hostOrigin) {
268
- var _this = this;
286
+ listen(hostOrigin) {
269
287
  this.peer.type = 'IFRAME'; // iframe.io connection listener is automatically set as IFRAME
270
288
  this.peer.connected = false;
271
289
  this.reconnectAttempts = 0;
272
- this.debug("[".concat(this.peer.type, "] Listening to connect").concat(hostOrigin ? ": Host <".concat(hostOrigin, ">") : ''));
290
+ this.debug(`[${this.peer.type}] Listening to connect${hostOrigin ? `: Host <${hostOrigin}>` : ''}`);
273
291
  // Clean up existing listener if any
274
292
  this.cleanup();
275
- this.messageListener = function (_a) {
276
- var origin = _a.origin, data = _a.data, source = _a.source;
293
+ this.messageListener = ({ origin, data, source }) => {
277
294
  try {
278
295
  // Enhanced security: check host origin where event must only come from
279
296
  if (hostOrigin && hostOrigin !== origin) {
280
- _this.fire('error', {
297
+ this.fire('error', {
281
298
  type: 'INVALID_ORIGIN',
282
299
  expected: hostOrigin,
283
300
  received: origin
@@ -290,75 +307,73 @@ var IOF = /** @class */ (function () {
290
307
  || !data.hasOwnProperty('_event'))
291
308
  return;
292
309
  // Define peer source window and origin
293
- if (!_this.peer.source) {
294
- _this.peer = __assign(__assign({}, _this.peer), { source: source, origin: origin });
295
- _this.debug("[".concat(_this.peer.type, "] Connect to ").concat(origin));
310
+ if (!this.peer.source) {
311
+ this.peer = { ...this.peer, source: source, origin };
312
+ this.debug(`[${this.peer.type}] Connect to ${origin}`);
296
313
  }
297
314
  // Origin different from handshaked source origin
298
- else if (origin !== _this.peer.origin) {
299
- _this.fire('error', {
315
+ else if (origin !== this.peer.origin) {
316
+ this.fire('error', {
300
317
  type: 'ORIGIN_MISMATCH',
301
- expected: _this.peer.origin,
318
+ expected: this.peer.origin,
302
319
  received: origin
303
320
  });
304
321
  return;
305
322
  }
306
- var _event = data._event, payload = data.payload, cid = data.cid, timestamp = data.timestamp;
323
+ const { _event, payload, cid, timestamp } = data;
307
324
  // Handle heartbeat responses
308
325
  if (_event === '__heartbeat_response') {
309
- _this.peer.lastHeartbeat = Date.now();
326
+ this.peer.lastHeartbeat = Date.now();
310
327
  return;
311
328
  }
312
329
  // Handle heartbeat requests
313
330
  if (_event === '__heartbeat') {
314
- _this.emit('__heartbeat_response', { timestamp: Date.now() });
315
- _this.peer.lastHeartbeat = Date.now();
331
+ this.emit('__heartbeat_response', { timestamp: Date.now() });
332
+ this.peer.lastHeartbeat = Date.now();
316
333
  return;
317
334
  }
318
- _this.debug("[".concat(_this.peer.type, "] Message: ").concat(_event), payload || '');
335
+ this.debug(`[${this.peer.type}] Message: ${_event}`, payload || '');
319
336
  // Handshake or availability check events
320
337
  if (_event == 'ping') {
321
- _this.emit('pong');
338
+ this.emit('pong');
322
339
  // Iframe is connected to content window
323
- _this.peer.connected = true;
324
- _this.reconnectAttempts = 0;
325
- _this.peer.lastHeartbeat = Date.now();
326
- _this.startHeartbeat();
327
- _this.fire('connect');
328
- _this.processMessageQueue();
329
- return _this.debug("[".concat(_this.peer.type, "] connected"));
340
+ this.peer.connected = true;
341
+ this.reconnectAttempts = 0;
342
+ this.peer.lastHeartbeat = Date.now();
343
+ this.startHeartbeat();
344
+ this.fire('connect');
345
+ this.processMessageQueue();
346
+ this.debug(`[${this.peer.type}] connected`);
347
+ return;
330
348
  }
331
349
  // Fire available event listeners
332
- _this.fire(_event, payload, cid);
350
+ this.fire(_event, payload, cid);
333
351
  }
334
352
  catch (error) {
335
- _this.debug("[".concat(_this.peer.type, "] Message handling error:"), error);
336
- _this.fire('error', {
353
+ this.debug(`[${this.peer.type}] Message handling error:`, error);
354
+ this.fire('error', {
337
355
  type: 'MESSAGE_HANDLING_ERROR',
338
356
  error: error instanceof Error ? error.message : String(error),
339
- origin: origin
357
+ origin
340
358
  });
341
359
  }
342
360
  };
343
361
  window.addEventListener('message', this.messageListener, false);
344
362
  return this;
345
- };
346
- IOF.prototype.fire = function (_event, payload, cid) {
347
- var _this = this;
363
+ }
364
+ fire(_event, payload, cid) {
348
365
  // Volatile event - check if any listeners exist
349
- if (!this.Events[_event] && !this.Events[_event + '--@once'])
350
- return this.debug("[".concat(this.peer.type, "] No <").concat(_event, "> listener defined"));
351
- var ackFn = cid
352
- ? function (error) {
353
- var args = [];
354
- for (var _i = 1; _i < arguments.length; _i++) {
355
- args[_i - 1] = arguments[_i];
356
- }
357
- _this.emit("".concat(_event, "--").concat(cid, "--@ack"), { error: error || false, args: args });
366
+ if (!this.Events[_event] && !this.Events[_event + '--@once']) {
367
+ this.debug(`[${this.peer.type}] No <${_event}> listener defined`);
368
+ return;
369
+ }
370
+ const ackFn = cid
371
+ ? (error, ...args) => {
372
+ this.emit(`${_event}--${cid}--@ack`, { error: error || false, args });
358
373
  return;
359
374
  }
360
375
  : undefined;
361
- var listeners = [];
376
+ let listeners = [];
362
377
  if (this.Events[_event + '--@once']) {
363
378
  // Once triggable event
364
379
  _event += '--@once';
@@ -369,21 +384,21 @@ var IOF = /** @class */ (function () {
369
384
  else
370
385
  listeners = this.Events[_event];
371
386
  // Fire listeners with error handling
372
- listeners.forEach(function (fn) {
387
+ listeners.forEach(fn => {
373
388
  try {
374
389
  payload !== undefined ? fn(payload, ackFn) : fn(ackFn);
375
390
  }
376
391
  catch (error) {
377
- _this.debug("[".concat(_this.peer.type, "] Listener error for ").concat(_event, ":"), error);
378
- _this.fire('error', {
392
+ this.debug(`[${this.peer.type}] Listener error for ${_event}:`, error);
393
+ this.fire('error', {
379
394
  type: 'LISTENER_ERROR',
380
395
  event: _event,
381
396
  error: error instanceof Error ? error.message : String(error)
382
397
  });
383
398
  }
384
399
  });
385
- };
386
- IOF.prototype.emit = function (_event, payload, fn) {
400
+ }
401
+ emit(_event, payload, fn) {
387
402
  // Check rate limiting
388
403
  if (!this.checkRateLimit())
389
404
  return this;
@@ -405,30 +420,27 @@ var IOF = /** @class */ (function () {
405
420
  }
406
421
  try {
407
422
  // Enhanced security: sanitize and validate payload
408
- var sanitizedPayload = payload
423
+ const sanitizedPayload = payload
409
424
  ? sanitizePayload(payload, this.options.maxMessageSize)
410
425
  : payload;
411
426
  // Acknowledge event listener
412
- var cid = void 0;
427
+ let cid;
413
428
  if (typeof fn === 'function') {
414
- var ackFunction_1 = fn;
429
+ const ackFunction = fn;
415
430
  cid = ackId();
416
- this.once("".concat(_event, "--").concat(cid, "--@ack"), function (_a) {
417
- var error = _a.error, args = _a.args;
418
- return ackFunction_1.apply(void 0, __spreadArray([error], args, false));
419
- });
431
+ this.once(`${_event}--${cid}--@ack`, ({ error, args }) => ackFunction(error, ...args));
420
432
  }
421
- var messageData = {
422
- _event: _event,
433
+ const messageData = {
434
+ _event,
423
435
  payload: sanitizedPayload,
424
- cid: cid,
436
+ cid,
425
437
  timestamp: Date.now(),
426
438
  size: getMessageSize(sanitizedPayload)
427
439
  };
428
440
  this.peer.source.postMessage(newObject(messageData), this.peer.origin);
429
441
  }
430
442
  catch (error) {
431
- this.debug("[".concat(this.peer.type, "] Emit error:"), error);
443
+ this.debug(`[${this.peer.type}] Emit error:`, error);
432
444
  this.fire('error', {
433
445
  type: 'EMIT_ERROR',
434
446
  event: _event,
@@ -439,29 +451,29 @@ var IOF = /** @class */ (function () {
439
451
  && fn(error instanceof Error ? error.message : String(error));
440
452
  }
441
453
  return this;
442
- };
443
- IOF.prototype.on = function (_event, fn) {
454
+ }
455
+ on(_event, fn) {
444
456
  // Add Event listener
445
457
  if (!this.Events[_event])
446
458
  this.Events[_event] = [];
447
459
  this.Events[_event].push(fn);
448
- this.debug("[".concat(this.peer.type, "] New <").concat(_event, "> listener on"));
460
+ this.debug(`[${this.peer.type}] New <${_event}> listener on`);
449
461
  return this;
450
- };
451
- IOF.prototype.once = function (_event, fn) {
462
+ }
463
+ once(_event, fn) {
452
464
  // Add Once Event listener
453
465
  _event += '--@once';
454
466
  if (!this.Events[_event])
455
467
  this.Events[_event] = [];
456
468
  this.Events[_event].push(fn);
457
- this.debug("[".concat(this.peer.type, "] New <").concat(_event, " once> listener on"));
469
+ this.debug(`[${this.peer.type}] New <${_event} once> listener on`);
458
470
  return this;
459
- };
460
- IOF.prototype.off = function (_event, fn) {
471
+ }
472
+ off(_event, fn) {
461
473
  // Remove Event listener
462
474
  if (fn && this.Events[_event]) {
463
475
  // Remove specific listener if provided
464
- var index = this.Events[_event].indexOf(fn);
476
+ const index = this.Events[_event].indexOf(fn);
465
477
  if (index > -1) {
466
478
  this.Events[_event].splice(index, 1);
467
479
  // Remove event array if empty
@@ -473,29 +485,23 @@ var IOF = /** @class */ (function () {
473
485
  else
474
486
  delete this.Events[_event];
475
487
  typeof fn == 'function' && fn();
476
- this.debug("[".concat(this.peer.type, "] <").concat(_event, "> listener off"));
488
+ this.debug(`[${this.peer.type}] <${_event}> listener off`);
477
489
  return this;
478
- };
479
- IOF.prototype.removeListeners = function (fn) {
490
+ }
491
+ removeListeners(fn) {
480
492
  // Clear all event listeners
481
493
  this.Events = {};
482
494
  typeof fn == 'function' && fn();
483
- this.debug("[".concat(this.peer.type, "] All listeners removed"));
495
+ this.debug(`[${this.peer.type}] All listeners removed`);
484
496
  return this;
485
- };
486
- IOF.prototype.emitAsync = function (_event, payload, timeout) {
487
- var _this = this;
488
- if (timeout === void 0) { timeout = 5000; }
489
- return new Promise(function (resolve, reject) {
490
- var timeoutId = setTimeout(function () {
491
- reject(new Error("Event '".concat(_event, "' acknowledgment timeout after ").concat(timeout, "ms")));
497
+ }
498
+ emitAsync(_event, payload, timeout = 5000) {
499
+ return new Promise((resolve, reject) => {
500
+ const timeoutId = setTimeout(() => {
501
+ reject(new Error(`Event '${_event}' acknowledgment timeout after ${timeout}ms`));
492
502
  }, timeout);
493
503
  try {
494
- _this.emit(_event, payload, function (error) {
495
- var args = [];
496
- for (var _i = 1; _i < arguments.length; _i++) {
497
- args[_i - 1] = arguments[_i];
498
- }
504
+ this.emit(_event, payload, (error, ...args) => {
499
505
  clearTimeout(timeoutId);
500
506
  error
501
507
  ? reject(new Error(typeof error === 'string' ? error : 'Ack error'))
@@ -507,29 +513,27 @@ var IOF = /** @class */ (function () {
507
513
  reject(error);
508
514
  }
509
515
  });
510
- };
511
- IOF.prototype.onceAsync = function (_event) {
512
- var _this = this;
513
- return new Promise(function (resolve) { return _this.once(_event, resolve); });
514
- };
515
- IOF.prototype.connectAsync = function (timeout) {
516
- var _this = this;
517
- return new Promise(function (resolve, reject) {
518
- if (_this.isConnected())
516
+ }
517
+ onceAsync(_event) {
518
+ return new Promise(resolve => this.once(_event, resolve));
519
+ }
520
+ connectAsync(timeout) {
521
+ return new Promise((resolve, reject) => {
522
+ if (this.isConnected())
519
523
  return resolve();
520
- var timeoutId = setTimeout(function () {
521
- _this.off('connect', connectHandler);
524
+ const timeoutId = setTimeout(() => {
525
+ this.off('connect', connectHandler);
522
526
  reject(new Error('Connection timeout'));
523
- }, timeout || _this.options.connectionTimeout);
524
- var connectHandler = function () {
527
+ }, timeout || this.options.connectionTimeout);
528
+ const connectHandler = () => {
525
529
  clearTimeout(timeoutId);
526
530
  resolve();
527
531
  };
528
- _this.once('connect', connectHandler);
532
+ this.once('connect', connectHandler);
529
533
  });
530
- };
534
+ }
531
535
  // Clean up all resources
532
- IOF.prototype.cleanup = function () {
536
+ cleanup() {
533
537
  if (this.messageListener) {
534
538
  window.removeEventListener('message', this.messageListener);
535
539
  this.messageListener = undefined;
@@ -539,9 +543,9 @@ var IOF = /** @class */ (function () {
539
543
  clearTimeout(this.reconnectTimer);
540
544
  this.reconnectTimer = undefined;
541
545
  }
542
- };
543
- IOF.prototype.disconnect = function (fn) {
544
- // Clean disconnect method
546
+ }
547
+ disconnect(fn) {
548
+ // Cleanup on disconnect
545
549
  this.cleanup();
546
550
  this.peer.connected = false;
547
551
  this.peer.source = undefined;
@@ -552,11 +556,11 @@ var IOF = /** @class */ (function () {
552
556
  this.reconnectAttempts = 0;
553
557
  this.removeListeners();
554
558
  typeof fn == 'function' && fn();
555
- this.debug("[".concat(this.peer.type, "] Disconnected"));
559
+ this.debug(`[${this.peer.type}] Disconnected`);
556
560
  return this;
557
- };
561
+ }
558
562
  // Get connection statistics
559
- IOF.prototype.getStats = function () {
563
+ getStats() {
560
564
  return {
561
565
  connected: this.isConnected(),
562
566
  peerType: this.peer.type,
@@ -567,14 +571,13 @@ var IOF = /** @class */ (function () {
567
571
  activeListeners: Object.keys(this.Events).length,
568
572
  messageRate: this.messageRateTracker.length
569
573
  };
570
- };
574
+ }
571
575
  // Clear message queue manually
572
- IOF.prototype.clearQueue = function () {
573
- var queueSize = this.messageQueue.length;
576
+ clearQueue() {
577
+ const queueSize = this.messageQueue.length;
574
578
  this.messageQueue = [];
575
- this.debug("[".concat(this.peer.type, "] Cleared ").concat(queueSize, " queued messages"));
579
+ this.debug(`[${this.peer.type}] Cleared ${queueSize} queued messages`);
576
580
  return this;
577
- };
578
- return IOF;
579
- }());
581
+ }
582
+ }
580
583
  exports.default = IOF;