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