@zaplier/sdk 1.2.2 → 1.2.4

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.esm.js CHANGED
@@ -6117,16 +6117,16 @@ function getAvailableComponents() {
6117
6117
  */
6118
6118
  class FetchTransport {
6119
6119
  constructor() {
6120
- this.name = 'fetch';
6121
- this.available = typeof fetch !== 'undefined';
6120
+ this.name = "fetch";
6121
+ this.available = typeof fetch !== "undefined";
6122
6122
  }
6123
6123
  async send(data, endpoint) {
6124
6124
  const start = Date.now();
6125
6125
  try {
6126
6126
  const response = await fetch(endpoint, {
6127
- method: 'POST',
6128
- headers: { 'Content-Type': 'application/json' },
6129
- body: JSON.stringify(data)
6127
+ method: "POST",
6128
+ headers: { "Content-Type": "application/json" },
6129
+ body: JSON.stringify(data),
6130
6130
  });
6131
6131
  if (!response.ok) {
6132
6132
  throw new Error(`HTTP ${response.status}`);
@@ -6134,56 +6134,7 @@ class FetchTransport {
6134
6134
  return {
6135
6135
  success: true,
6136
6136
  method: this.name,
6137
- latency: Date.now() - start
6138
- };
6139
- }
6140
- catch (error) {
6141
- return {
6142
- success: false,
6143
- method: this.name,
6144
6137
  latency: Date.now() - start,
6145
- error: error instanceof Error ? error.message : String(error)
6146
- };
6147
- }
6148
- }
6149
- }
6150
- /**
6151
- * Resource Spoofing Transport (GET requests disguised as assets)
6152
- */
6153
- class ResourceSpoofTransport {
6154
- constructor(baseUrl) {
6155
- this.name = 'resource';
6156
- this.available = typeof fetch !== 'undefined';
6157
- this.baseUrl = baseUrl;
6158
- }
6159
- async send(data, endpoint) {
6160
- const start = Date.now();
6161
- try {
6162
- // Compress and encode data
6163
- const encoded = this.encodeData(data);
6164
- // Try different resource types
6165
- const resourceTypes = [
6166
- { path: '/assets/styles.css', type: 'text/css' },
6167
- { path: '/images/pixel.gif', type: 'image/gif' },
6168
- { path: '/fonts/roboto.woff2', type: 'font/woff2' },
6169
- { path: '/js/analytics.js', type: 'application/javascript' }
6170
- ];
6171
- const randomType = resourceTypes[Math.floor(Math.random() * resourceTypes.length)];
6172
- const url = `${this.baseUrl}${randomType.path}?d=${encoded}&t=${Date.now()}`;
6173
- const response = await fetch(url, {
6174
- method: 'GET',
6175
- headers: {
6176
- 'Accept': randomType.type,
6177
- 'Cache-Control': 'no-cache',
6178
- 'User-Agent': navigator.userAgent
6179
- }
6180
- });
6181
- // Even if status is not OK, adblockers might have blocked it
6182
- // But the data might still reach the server
6183
- return {
6184
- success: true, // Optimistic success
6185
- method: this.name,
6186
- latency: Date.now() - start
6187
6138
  };
6188
6139
  }
6189
6140
  catch (error) {
@@ -6191,31 +6142,18 @@ class ResourceSpoofTransport {
6191
6142
  success: false,
6192
6143
  method: this.name,
6193
6144
  latency: Date.now() - start,
6194
- error: error instanceof Error ? error.message : String(error)
6145
+ error: error instanceof Error ? error.message : String(error),
6195
6146
  };
6196
6147
  }
6197
6148
  }
6198
- encodeData(data) {
6199
- try {
6200
- const json = JSON.stringify(data);
6201
- return btoa(encodeURIComponent(json)).replace(/[+/=]/g, (match) => ({
6202
- '+': '-',
6203
- '/': '_',
6204
- '=': ''
6205
- }[match] || match));
6206
- }
6207
- catch (error) {
6208
- return '';
6209
- }
6210
- }
6211
6149
  }
6212
6150
  /**
6213
6151
  * Elysia WebSocket Transport (Native WebSocket for anti-adblock)
6214
6152
  */
6215
6153
  class ElysiaWebSocketTransport {
6216
6154
  constructor(baseUrl, token) {
6217
- this.name = 'elysia-websocket';
6218
- this.available = typeof WebSocket !== 'undefined';
6155
+ this.name = "elysia-websocket";
6156
+ this.available = typeof WebSocket !== "undefined";
6219
6157
  this.connected = false;
6220
6158
  this.baseUrl = baseUrl;
6221
6159
  this.token = token;
@@ -6224,29 +6162,29 @@ class ElysiaWebSocketTransport {
6224
6162
  const start = Date.now();
6225
6163
  try {
6226
6164
  if (!this.token) {
6227
- throw new Error('Missing token for WebSocket connection');
6165
+ throw new Error("Missing token for WebSocket connection");
6228
6166
  }
6229
6167
  await this.connect();
6230
6168
  if (!this.ws || !this.connected) {
6231
- throw new Error('WebSocket not connected');
6169
+ throw new Error("WebSocket not connected");
6232
6170
  }
6233
6171
  return new Promise((resolve, reject) => {
6234
6172
  const messageHandler = (event) => {
6235
6173
  try {
6236
6174
  const response = JSON.parse(event.data);
6237
- this.ws?.removeEventListener('message', messageHandler);
6175
+ this.ws?.removeEventListener("message", messageHandler);
6238
6176
  resolve({
6239
6177
  success: response.success || false,
6240
6178
  method: this.name,
6241
- latency: Date.now() - start
6179
+ latency: Date.now() - start,
6242
6180
  });
6243
6181
  }
6244
6182
  catch (error) {
6245
- this.ws?.removeEventListener('message', messageHandler);
6246
- reject(new Error('Failed to parse WebSocket response'));
6183
+ this.ws?.removeEventListener("message", messageHandler);
6184
+ reject(new Error("Failed to parse WebSocket response"));
6247
6185
  }
6248
6186
  };
6249
- this.ws?.addEventListener('message', messageHandler);
6187
+ this.ws?.addEventListener("message", messageHandler);
6250
6188
  // Send the complete tracking data payload (includes fingerprintHash, stableCoreHash, etc.)
6251
6189
  this.ws?.send(JSON.stringify({
6252
6190
  // Include all data from the SDK payload
@@ -6254,7 +6192,7 @@ class ElysiaWebSocketTransport {
6254
6192
  // Override/ensure essential fields for WebSocket transport
6255
6193
  eventId: data.eventId || crypto.randomUUID(),
6256
6194
  sessionId: data.sessionId || data.s,
6257
- eventType: data.eventType || data.type || 'websocket_event',
6195
+ eventType: data.eventType || data.type || "websocket_event",
6258
6196
  eventName: data.eventName || data.name,
6259
6197
  url: data.url,
6260
6198
  userAgent: data.userAgent || navigator.userAgent,
@@ -6262,12 +6200,12 @@ class ElysiaWebSocketTransport {
6262
6200
  // Ensure these critical fields are included for identity resolution
6263
6201
  fingerprintHash: data.fingerprintHash,
6264
6202
  stableCoreHash: data.stableCoreHash,
6265
- stableCoreVector: data.stableCoreVector
6203
+ stableCoreVector: data.stableCoreVector,
6266
6204
  }));
6267
6205
  // Timeout after 5 seconds
6268
6206
  setTimeout(() => {
6269
- this.ws?.removeEventListener('message', messageHandler);
6270
- reject(new Error('WebSocket response timeout'));
6207
+ this.ws?.removeEventListener("message", messageHandler);
6208
+ reject(new Error("WebSocket response timeout"));
6271
6209
  }, 5000);
6272
6210
  });
6273
6211
  }
@@ -6276,7 +6214,7 @@ class ElysiaWebSocketTransport {
6276
6214
  success: false,
6277
6215
  method: this.name,
6278
6216
  latency: Date.now() - start,
6279
- error: error instanceof Error ? error.message : String(error)
6217
+ error: error instanceof Error ? error.message : String(error),
6280
6218
  };
6281
6219
  }
6282
6220
  }
@@ -6288,7 +6226,7 @@ class ElysiaWebSocketTransport {
6288
6226
  try {
6289
6227
  // Convert HTTP/HTTPS to WS/WSS
6290
6228
  const url = new URL(this.baseUrl);
6291
- const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
6229
+ const protocol = url.protocol === "https:" ? "wss:" : "ws:";
6292
6230
  const wsUrl = `${protocol}//${url.host}/ws/track?token=${encodeURIComponent(this.token)}`;
6293
6231
  this.ws = new WebSocket(wsUrl);
6294
6232
  this.ws.onopen = () => {
@@ -6297,7 +6235,7 @@ class ElysiaWebSocketTransport {
6297
6235
  };
6298
6236
  this.ws.onerror = () => {
6299
6237
  this.connected = false;
6300
- reject(new Error('WebSocket connection failed'));
6238
+ reject(new Error("WebSocket connection failed"));
6301
6239
  };
6302
6240
  this.ws.onclose = () => {
6303
6241
  this.connected = false;
@@ -6306,7 +6244,7 @@ class ElysiaWebSocketTransport {
6306
6244
  setTimeout(() => {
6307
6245
  if (!this.connected) {
6308
6246
  this.ws?.close();
6309
- reject(new Error('WebSocket connection timeout'));
6247
+ reject(new Error("WebSocket connection timeout"));
6310
6248
  }
6311
6249
  }, 5000);
6312
6250
  }
@@ -6327,14 +6265,18 @@ class ElysiaWebSocketTransport {
6327
6265
  */
6328
6266
  class WebRTCTransport {
6329
6267
  constructor() {
6330
- this.name = 'webrtc';
6331
- this.available = typeof globalThis.RTCPeerConnection !== 'undefined';
6268
+ this.name = "webrtc";
6269
+ this.available = typeof globalThis.RTCPeerConnection !== "undefined";
6332
6270
  this.connected = false;
6333
6271
  }
6334
6272
  async send(data, _endpoint) {
6335
6273
  const start = Date.now();
6336
6274
  if (!this.available) {
6337
- return { success: false, method: this.name, error: 'WebRTC not available' };
6275
+ return {
6276
+ success: false,
6277
+ method: this.name,
6278
+ error: "WebRTC not available",
6279
+ };
6338
6280
  }
6339
6281
  try {
6340
6282
  await this.setupConnection();
@@ -6343,14 +6285,14 @@ class WebRTCTransport {
6343
6285
  return {
6344
6286
  success: true,
6345
6287
  method: this.name,
6346
- latency: Date.now() - start
6288
+ latency: Date.now() - start,
6347
6289
  };
6348
6290
  }
6349
6291
  else {
6350
6292
  return {
6351
6293
  success: false,
6352
6294
  method: this.name,
6353
- error: 'DataChannel not ready'
6295
+ error: "DataChannel not ready",
6354
6296
  };
6355
6297
  }
6356
6298
  }
@@ -6358,7 +6300,7 @@ class WebRTCTransport {
6358
6300
  return {
6359
6301
  success: false,
6360
6302
  method: this.name,
6361
- error: error instanceof Error ? error.message : String(error)
6303
+ error: error instanceof Error ? error.message : String(error),
6362
6304
  };
6363
6305
  }
6364
6306
  }
@@ -6368,11 +6310,11 @@ class WebRTCTransport {
6368
6310
  return new Promise((resolve, reject) => {
6369
6311
  try {
6370
6312
  this.pc = new globalThis.RTCPeerConnection({
6371
- iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
6313
+ iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
6372
6314
  });
6373
- this.dataChannel = this.pc.createDataChannel('tracking', {
6315
+ this.dataChannel = this.pc.createDataChannel("tracking", {
6374
6316
  ordered: false,
6375
- maxRetransmits: 0
6317
+ maxRetransmits: 0,
6376
6318
  });
6377
6319
  this.dataChannel.onopen = () => {
6378
6320
  this.connected = true;
@@ -6409,45 +6351,51 @@ class AntiAdblockManager {
6409
6351
  totalRequests: 0,
6410
6352
  successfulRequests: 0,
6411
6353
  methodSuccess: new Map(),
6412
- methodFailures: new Map()
6354
+ methodFailures: new Map(),
6413
6355
  };
6414
6356
  this.baseUrl = baseUrl;
6415
6357
  this.token = token;
6416
6358
  this.config = {
6417
6359
  enabled: true,
6418
- methods: ['elysia-websocket', 'fetch', 'resource'], // Elysia WebSocket as primary
6360
+ methods: ["elysia-websocket", "fetch"],
6419
6361
  fallbackDelay: 100,
6420
6362
  maxRetries: 2,
6421
6363
  debug: false,
6422
- ...config
6364
+ ...config,
6423
6365
  };
6424
6366
  this.initializeTransports();
6425
6367
  }
6426
6368
  initializeTransports() {
6427
6369
  const transportMap = {
6428
- 'elysia-websocket': () => new ElysiaWebSocketTransport(this.baseUrl, this.token),
6370
+ "elysia-websocket": () => new ElysiaWebSocketTransport(this.baseUrl, this.token),
6429
6371
  fetch: () => new FetchTransport(),
6430
- resource: () => new ResourceSpoofTransport(this.baseUrl),
6431
- webrtc: () => new WebRTCTransport()
6372
+ webrtc: () => new WebRTCTransport(),
6432
6373
  };
6433
6374
  this.transports = this.config.methods
6434
- .map(method => transportMap[method]?.())
6375
+ .map((method) => transportMap[method]?.())
6435
6376
  .filter((transport) => transport !== undefined && transport.available);
6436
6377
  if (this.config.debug) {
6437
- console.log('[Zaplier] Anti-adblock initialized with transports:', this.transports.map(t => t.name));
6378
+ console.log("[Zaplier] Anti-adblock initialized with transports:", this.transports.map((t) => t.name));
6438
6379
  }
6439
6380
  }
6440
6381
  /**
6441
6382
  * Send data using the best available transport
6442
6383
  */
6443
- async send(data, endpoint = '/tracking/event') {
6384
+ async send(data, endpoint = "/tracking/event") {
6444
6385
  this.stats.totalRequests++;
6445
6386
  if (!this.config.enabled || this.transports.length === 0) {
6446
- return { success: false, method: 'none', error: 'No transports available' };
6387
+ return {
6388
+ success: false,
6389
+ method: "none",
6390
+ error: "No transports available",
6391
+ };
6447
6392
  }
6448
- let lastError = '';
6449
- // Try each transport in order
6393
+ let lastError = "";
6394
+ // Try each transport in order (sequential, not parallel)
6450
6395
  for (const transport of this.transports) {
6396
+ if (this.config.debug) {
6397
+ console.log(`[Zaplier] Trying transport: ${transport.name}`);
6398
+ }
6451
6399
  try {
6452
6400
  const result = await transport.send(data, `${this.baseUrl}${endpoint}`);
6453
6401
  // Update stats
@@ -6455,15 +6403,15 @@ class AntiAdblockManager {
6455
6403
  this.stats.successfulRequests++;
6456
6404
  this.updateMethodStats(transport.name, true);
6457
6405
  if (this.config.debug) {
6458
- console.log(`[Zaplier] Data sent successfully via ${transport.name}`, result);
6406
+ console.log(`[Zaplier] Data sent successfully via ${transport.name} - STOPPING fallback chain`, result);
6459
6407
  }
6460
- return result;
6408
+ return result; // SUCCESS - stop trying other transports
6461
6409
  }
6462
6410
  else {
6463
6411
  this.updateMethodStats(transport.name, false);
6464
- lastError = result.error || 'Unknown error';
6412
+ lastError = result.error || "Unknown error";
6465
6413
  if (this.config.debug) {
6466
- console.warn(`[Zaplier] Transport ${transport.name} failed:`, result.error);
6414
+ console.warn(`[Zaplier] Transport ${transport.name} failed:`, result.error);
6467
6415
  }
6468
6416
  }
6469
6417
  }
@@ -6471,18 +6419,18 @@ class AntiAdblockManager {
6471
6419
  lastError = error instanceof Error ? error.message : String(error);
6472
6420
  this.updateMethodStats(transport.name, false);
6473
6421
  if (this.config.debug) {
6474
- console.warn(`[Zaplier] Transport ${transport.name} threw error:`, error);
6422
+ console.warn(`[Zaplier] Transport ${transport.name} threw error:`, error);
6475
6423
  }
6476
6424
  }
6477
6425
  // Wait before trying next transport
6478
6426
  if (this.config.fallbackDelay > 0) {
6479
- await new Promise(resolve => setTimeout(resolve, this.config.fallbackDelay));
6427
+ await new Promise((resolve) => setTimeout(resolve, this.config.fallbackDelay));
6480
6428
  }
6481
6429
  }
6482
6430
  return {
6483
6431
  success: false,
6484
- method: 'all_failed',
6485
- error: `All transports failed. Last error: ${lastError}`
6432
+ method: "all_failed",
6433
+ error: `All transports failed. Last error: ${lastError}`,
6486
6434
  };
6487
6435
  }
6488
6436
  updateMethodStats(method, success) {
@@ -6516,7 +6464,7 @@ class AntiAdblockManager {
6516
6464
  * Destroy all transports
6517
6465
  */
6518
6466
  destroy() {
6519
- this.transports.forEach(transport => {
6467
+ this.transports.forEach((transport) => {
6520
6468
  if (transport.destroy) {
6521
6469
  transport.destroy();
6522
6470
  }
@@ -6537,7 +6485,7 @@ class AntiAdblockManager {
6537
6485
  results[transport.name] = {
6538
6486
  success: false,
6539
6487
  method: transport.name,
6540
- error: error instanceof Error ? error.message : String(error)
6488
+ error: error instanceof Error ? error.message : String(error),
6541
6489
  };
6542
6490
  }
6543
6491
  }
@@ -7673,7 +7621,7 @@ class ZaplierSDK {
7673
7621
  this.antiAdblockManager = new AntiAdblockManager(this.config.apiEndpoint, this.config.token, // Pass token to anti-adblock manager
7674
7622
  {
7675
7623
  enabled: true,
7676
- methods: ["elysia-websocket", "fetch", "resource"], // Elysia WebSocket as primary
7624
+ methods: ["elysia-websocket", "fetch"],
7677
7625
  fallbackDelay: 100,
7678
7626
  maxRetries: 2,
7679
7627
  debug: this.config.debug,