@zaplier/sdk 1.2.3 → 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/sdk.js CHANGED
@@ -6123,16 +6123,16 @@
6123
6123
  */
6124
6124
  class FetchTransport {
6125
6125
  constructor() {
6126
- this.name = 'fetch';
6127
- this.available = typeof fetch !== 'undefined';
6126
+ this.name = "fetch";
6127
+ this.available = typeof fetch !== "undefined";
6128
6128
  }
6129
6129
  async send(data, endpoint) {
6130
6130
  const start = Date.now();
6131
6131
  try {
6132
6132
  const response = await fetch(endpoint, {
6133
- method: 'POST',
6134
- headers: { 'Content-Type': 'application/json' },
6135
- body: JSON.stringify(data)
6133
+ method: "POST",
6134
+ headers: { "Content-Type": "application/json" },
6135
+ body: JSON.stringify(data),
6136
6136
  });
6137
6137
  if (!response.ok) {
6138
6138
  throw new Error(`HTTP ${response.status}`);
@@ -6140,56 +6140,7 @@
6140
6140
  return {
6141
6141
  success: true,
6142
6142
  method: this.name,
6143
- latency: Date.now() - start
6144
- };
6145
- }
6146
- catch (error) {
6147
- return {
6148
- success: false,
6149
- method: this.name,
6150
6143
  latency: Date.now() - start,
6151
- error: error instanceof Error ? error.message : String(error)
6152
- };
6153
- }
6154
- }
6155
- }
6156
- /**
6157
- * Resource Spoofing Transport (GET requests disguised as assets)
6158
- */
6159
- class ResourceSpoofTransport {
6160
- constructor(baseUrl) {
6161
- this.name = 'resource';
6162
- this.available = typeof fetch !== 'undefined';
6163
- this.baseUrl = baseUrl;
6164
- }
6165
- async send(data, endpoint) {
6166
- const start = Date.now();
6167
- try {
6168
- // Compress and encode data
6169
- const encoded = this.encodeData(data);
6170
- // Try different resource types
6171
- const resourceTypes = [
6172
- { path: '/assets/styles.css', type: 'text/css' },
6173
- { path: '/images/pixel.gif', type: 'image/gif' },
6174
- { path: '/fonts/roboto.woff2', type: 'font/woff2' },
6175
- { path: '/js/analytics.js', type: 'application/javascript' }
6176
- ];
6177
- const randomType = resourceTypes[Math.floor(Math.random() * resourceTypes.length)];
6178
- const url = `${this.baseUrl}${randomType.path}?d=${encoded}&t=${Date.now()}`;
6179
- const response = await fetch(url, {
6180
- method: 'GET',
6181
- headers: {
6182
- 'Accept': randomType.type,
6183
- 'Cache-Control': 'no-cache',
6184
- 'User-Agent': navigator.userAgent
6185
- }
6186
- });
6187
- // Even if status is not OK, adblockers might have blocked it
6188
- // But the data might still reach the server
6189
- return {
6190
- success: true, // Optimistic success
6191
- method: this.name,
6192
- latency: Date.now() - start
6193
6144
  };
6194
6145
  }
6195
6146
  catch (error) {
@@ -6197,31 +6148,18 @@
6197
6148
  success: false,
6198
6149
  method: this.name,
6199
6150
  latency: Date.now() - start,
6200
- error: error instanceof Error ? error.message : String(error)
6151
+ error: error instanceof Error ? error.message : String(error),
6201
6152
  };
6202
6153
  }
6203
6154
  }
6204
- encodeData(data) {
6205
- try {
6206
- const json = JSON.stringify(data);
6207
- return btoa(encodeURIComponent(json)).replace(/[+/=]/g, (match) => ({
6208
- '+': '-',
6209
- '/': '_',
6210
- '=': ''
6211
- }[match] || match));
6212
- }
6213
- catch (error) {
6214
- return '';
6215
- }
6216
- }
6217
6155
  }
6218
6156
  /**
6219
6157
  * Elysia WebSocket Transport (Native WebSocket for anti-adblock)
6220
6158
  */
6221
6159
  class ElysiaWebSocketTransport {
6222
6160
  constructor(baseUrl, token) {
6223
- this.name = 'elysia-websocket';
6224
- this.available = typeof WebSocket !== 'undefined';
6161
+ this.name = "elysia-websocket";
6162
+ this.available = typeof WebSocket !== "undefined";
6225
6163
  this.connected = false;
6226
6164
  this.baseUrl = baseUrl;
6227
6165
  this.token = token;
@@ -6230,29 +6168,29 @@
6230
6168
  const start = Date.now();
6231
6169
  try {
6232
6170
  if (!this.token) {
6233
- throw new Error('Missing token for WebSocket connection');
6171
+ throw new Error("Missing token for WebSocket connection");
6234
6172
  }
6235
6173
  await this.connect();
6236
6174
  if (!this.ws || !this.connected) {
6237
- throw new Error('WebSocket not connected');
6175
+ throw new Error("WebSocket not connected");
6238
6176
  }
6239
6177
  return new Promise((resolve, reject) => {
6240
6178
  const messageHandler = (event) => {
6241
6179
  try {
6242
6180
  const response = JSON.parse(event.data);
6243
- this.ws?.removeEventListener('message', messageHandler);
6181
+ this.ws?.removeEventListener("message", messageHandler);
6244
6182
  resolve({
6245
6183
  success: response.success || false,
6246
6184
  method: this.name,
6247
- latency: Date.now() - start
6185
+ latency: Date.now() - start,
6248
6186
  });
6249
6187
  }
6250
6188
  catch (error) {
6251
- this.ws?.removeEventListener('message', messageHandler);
6252
- reject(new Error('Failed to parse WebSocket response'));
6189
+ this.ws?.removeEventListener("message", messageHandler);
6190
+ reject(new Error("Failed to parse WebSocket response"));
6253
6191
  }
6254
6192
  };
6255
- this.ws?.addEventListener('message', messageHandler);
6193
+ this.ws?.addEventListener("message", messageHandler);
6256
6194
  // Send the complete tracking data payload (includes fingerprintHash, stableCoreHash, etc.)
6257
6195
  this.ws?.send(JSON.stringify({
6258
6196
  // Include all data from the SDK payload
@@ -6260,7 +6198,7 @@
6260
6198
  // Override/ensure essential fields for WebSocket transport
6261
6199
  eventId: data.eventId || crypto.randomUUID(),
6262
6200
  sessionId: data.sessionId || data.s,
6263
- eventType: data.eventType || data.type || 'websocket_event',
6201
+ eventType: data.eventType || data.type || "websocket_event",
6264
6202
  eventName: data.eventName || data.name,
6265
6203
  url: data.url,
6266
6204
  userAgent: data.userAgent || navigator.userAgent,
@@ -6268,12 +6206,12 @@
6268
6206
  // Ensure these critical fields are included for identity resolution
6269
6207
  fingerprintHash: data.fingerprintHash,
6270
6208
  stableCoreHash: data.stableCoreHash,
6271
- stableCoreVector: data.stableCoreVector
6209
+ stableCoreVector: data.stableCoreVector,
6272
6210
  }));
6273
6211
  // Timeout after 5 seconds
6274
6212
  setTimeout(() => {
6275
- this.ws?.removeEventListener('message', messageHandler);
6276
- reject(new Error('WebSocket response timeout'));
6213
+ this.ws?.removeEventListener("message", messageHandler);
6214
+ reject(new Error("WebSocket response timeout"));
6277
6215
  }, 5000);
6278
6216
  });
6279
6217
  }
@@ -6282,7 +6220,7 @@
6282
6220
  success: false,
6283
6221
  method: this.name,
6284
6222
  latency: Date.now() - start,
6285
- error: error instanceof Error ? error.message : String(error)
6223
+ error: error instanceof Error ? error.message : String(error),
6286
6224
  };
6287
6225
  }
6288
6226
  }
@@ -6294,7 +6232,7 @@
6294
6232
  try {
6295
6233
  // Convert HTTP/HTTPS to WS/WSS
6296
6234
  const url = new URL(this.baseUrl);
6297
- const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
6235
+ const protocol = url.protocol === "https:" ? "wss:" : "ws:";
6298
6236
  const wsUrl = `${protocol}//${url.host}/ws/track?token=${encodeURIComponent(this.token)}`;
6299
6237
  this.ws = new WebSocket(wsUrl);
6300
6238
  this.ws.onopen = () => {
@@ -6303,7 +6241,7 @@
6303
6241
  };
6304
6242
  this.ws.onerror = () => {
6305
6243
  this.connected = false;
6306
- reject(new Error('WebSocket connection failed'));
6244
+ reject(new Error("WebSocket connection failed"));
6307
6245
  };
6308
6246
  this.ws.onclose = () => {
6309
6247
  this.connected = false;
@@ -6312,7 +6250,7 @@
6312
6250
  setTimeout(() => {
6313
6251
  if (!this.connected) {
6314
6252
  this.ws?.close();
6315
- reject(new Error('WebSocket connection timeout'));
6253
+ reject(new Error("WebSocket connection timeout"));
6316
6254
  }
6317
6255
  }, 5000);
6318
6256
  }
@@ -6333,14 +6271,18 @@
6333
6271
  */
6334
6272
  class WebRTCTransport {
6335
6273
  constructor() {
6336
- this.name = 'webrtc';
6337
- this.available = typeof globalThis.RTCPeerConnection !== 'undefined';
6274
+ this.name = "webrtc";
6275
+ this.available = typeof globalThis.RTCPeerConnection !== "undefined";
6338
6276
  this.connected = false;
6339
6277
  }
6340
6278
  async send(data, _endpoint) {
6341
6279
  const start = Date.now();
6342
6280
  if (!this.available) {
6343
- return { success: false, method: this.name, error: 'WebRTC not available' };
6281
+ return {
6282
+ success: false,
6283
+ method: this.name,
6284
+ error: "WebRTC not available",
6285
+ };
6344
6286
  }
6345
6287
  try {
6346
6288
  await this.setupConnection();
@@ -6349,14 +6291,14 @@
6349
6291
  return {
6350
6292
  success: true,
6351
6293
  method: this.name,
6352
- latency: Date.now() - start
6294
+ latency: Date.now() - start,
6353
6295
  };
6354
6296
  }
6355
6297
  else {
6356
6298
  return {
6357
6299
  success: false,
6358
6300
  method: this.name,
6359
- error: 'DataChannel not ready'
6301
+ error: "DataChannel not ready",
6360
6302
  };
6361
6303
  }
6362
6304
  }
@@ -6364,7 +6306,7 @@
6364
6306
  return {
6365
6307
  success: false,
6366
6308
  method: this.name,
6367
- error: error instanceof Error ? error.message : String(error)
6309
+ error: error instanceof Error ? error.message : String(error),
6368
6310
  };
6369
6311
  }
6370
6312
  }
@@ -6374,11 +6316,11 @@
6374
6316
  return new Promise((resolve, reject) => {
6375
6317
  try {
6376
6318
  this.pc = new globalThis.RTCPeerConnection({
6377
- iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
6319
+ iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
6378
6320
  });
6379
- this.dataChannel = this.pc.createDataChannel('tracking', {
6321
+ this.dataChannel = this.pc.createDataChannel("tracking", {
6380
6322
  ordered: false,
6381
- maxRetransmits: 0
6323
+ maxRetransmits: 0,
6382
6324
  });
6383
6325
  this.dataChannel.onopen = () => {
6384
6326
  this.connected = true;
@@ -6415,43 +6357,46 @@
6415
6357
  totalRequests: 0,
6416
6358
  successfulRequests: 0,
6417
6359
  methodSuccess: new Map(),
6418
- methodFailures: new Map()
6360
+ methodFailures: new Map(),
6419
6361
  };
6420
6362
  this.baseUrl = baseUrl;
6421
6363
  this.token = token;
6422
6364
  this.config = {
6423
6365
  enabled: true,
6424
- methods: ['elysia-websocket', 'fetch', 'resource'], // Elysia WebSocket as primary
6366
+ methods: ["elysia-websocket", "fetch"],
6425
6367
  fallbackDelay: 100,
6426
6368
  maxRetries: 2,
6427
6369
  debug: false,
6428
- ...config
6370
+ ...config,
6429
6371
  };
6430
6372
  this.initializeTransports();
6431
6373
  }
6432
6374
  initializeTransports() {
6433
6375
  const transportMap = {
6434
- 'elysia-websocket': () => new ElysiaWebSocketTransport(this.baseUrl, this.token),
6376
+ "elysia-websocket": () => new ElysiaWebSocketTransport(this.baseUrl, this.token),
6435
6377
  fetch: () => new FetchTransport(),
6436
- resource: () => new ResourceSpoofTransport(this.baseUrl),
6437
- webrtc: () => new WebRTCTransport()
6378
+ webrtc: () => new WebRTCTransport(),
6438
6379
  };
6439
6380
  this.transports = this.config.methods
6440
- .map(method => transportMap[method]?.())
6381
+ .map((method) => transportMap[method]?.())
6441
6382
  .filter((transport) => transport !== undefined && transport.available);
6442
6383
  if (this.config.debug) {
6443
- console.log('[Zaplier] Anti-adblock initialized with transports:', this.transports.map(t => t.name));
6384
+ console.log("[Zaplier] Anti-adblock initialized with transports:", this.transports.map((t) => t.name));
6444
6385
  }
6445
6386
  }
6446
6387
  /**
6447
6388
  * Send data using the best available transport
6448
6389
  */
6449
- async send(data, endpoint = '/tracking/event') {
6390
+ async send(data, endpoint = "/tracking/event") {
6450
6391
  this.stats.totalRequests++;
6451
6392
  if (!this.config.enabled || this.transports.length === 0) {
6452
- return { success: false, method: 'none', error: 'No transports available' };
6393
+ return {
6394
+ success: false,
6395
+ method: "none",
6396
+ error: "No transports available",
6397
+ };
6453
6398
  }
6454
- let lastError = '';
6399
+ let lastError = "";
6455
6400
  // Try each transport in order (sequential, not parallel)
6456
6401
  for (const transport of this.transports) {
6457
6402
  if (this.config.debug) {
@@ -6470,7 +6415,7 @@
6470
6415
  }
6471
6416
  else {
6472
6417
  this.updateMethodStats(transport.name, false);
6473
- lastError = result.error || 'Unknown error';
6418
+ lastError = result.error || "Unknown error";
6474
6419
  if (this.config.debug) {
6475
6420
  console.warn(`[Zaplier] ❌ Transport ${transport.name} failed:`, result.error);
6476
6421
  }
@@ -6485,13 +6430,13 @@
6485
6430
  }
6486
6431
  // Wait before trying next transport
6487
6432
  if (this.config.fallbackDelay > 0) {
6488
- await new Promise(resolve => setTimeout(resolve, this.config.fallbackDelay));
6433
+ await new Promise((resolve) => setTimeout(resolve, this.config.fallbackDelay));
6489
6434
  }
6490
6435
  }
6491
6436
  return {
6492
6437
  success: false,
6493
- method: 'all_failed',
6494
- error: `All transports failed. Last error: ${lastError}`
6438
+ method: "all_failed",
6439
+ error: `All transports failed. Last error: ${lastError}`,
6495
6440
  };
6496
6441
  }
6497
6442
  updateMethodStats(method, success) {
@@ -6525,7 +6470,7 @@
6525
6470
  * Destroy all transports
6526
6471
  */
6527
6472
  destroy() {
6528
- this.transports.forEach(transport => {
6473
+ this.transports.forEach((transport) => {
6529
6474
  if (transport.destroy) {
6530
6475
  transport.destroy();
6531
6476
  }
@@ -6546,7 +6491,7 @@
6546
6491
  results[transport.name] = {
6547
6492
  success: false,
6548
6493
  method: transport.name,
6549
- error: error instanceof Error ? error.message : String(error)
6494
+ error: error instanceof Error ? error.message : String(error),
6550
6495
  };
6551
6496
  }
6552
6497
  }
@@ -7682,7 +7627,7 @@
7682
7627
  this.antiAdblockManager = new AntiAdblockManager(this.config.apiEndpoint, this.config.token, // Pass token to anti-adblock manager
7683
7628
  {
7684
7629
  enabled: true,
7685
- methods: ["elysia-websocket", "fetch", "resource"], // Elysia WebSocket as primary
7630
+ methods: ["elysia-websocket", "fetch"],
7686
7631
  fallbackDelay: 100,
7687
7632
  maxRetries: 2,
7688
7633
  debug: this.config.debug,