@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/sdk.js
CHANGED
|
@@ -6123,16 +6123,16 @@
|
|
|
6123
6123
|
*/
|
|
6124
6124
|
class FetchTransport {
|
|
6125
6125
|
constructor() {
|
|
6126
|
-
this.name =
|
|
6127
|
-
this.available = typeof fetch !==
|
|
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:
|
|
6134
|
-
headers: {
|
|
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 =
|
|
6224
|
-
this.available = typeof WebSocket !==
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
6252
|
-
reject(new Error(
|
|
6189
|
+
this.ws?.removeEventListener("message", messageHandler);
|
|
6190
|
+
reject(new Error("Failed to parse WebSocket response"));
|
|
6253
6191
|
}
|
|
6254
6192
|
};
|
|
6255
|
-
this.ws?.addEventListener(
|
|
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 ||
|
|
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(
|
|
6276
|
-
reject(new Error(
|
|
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 ===
|
|
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(
|
|
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(
|
|
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 =
|
|
6337
|
-
this.available = typeof globalThis.RTCPeerConnection !==
|
|
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 {
|
|
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:
|
|
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:
|
|
6319
|
+
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
|
6378
6320
|
});
|
|
6379
|
-
this.dataChannel = this.pc.createDataChannel(
|
|
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,45 +6357,51 @@
|
|
|
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: [
|
|
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
|
-
|
|
6376
|
+
"elysia-websocket": () => new ElysiaWebSocketTransport(this.baseUrl, this.token),
|
|
6435
6377
|
fetch: () => new FetchTransport(),
|
|
6436
|
-
|
|
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(
|
|
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 =
|
|
6390
|
+
async send(data, endpoint = "/tracking/event") {
|
|
6450
6391
|
this.stats.totalRequests++;
|
|
6451
6392
|
if (!this.config.enabled || this.transports.length === 0) {
|
|
6452
|
-
return {
|
|
6393
|
+
return {
|
|
6394
|
+
success: false,
|
|
6395
|
+
method: "none",
|
|
6396
|
+
error: "No transports available",
|
|
6397
|
+
};
|
|
6453
6398
|
}
|
|
6454
|
-
let lastError =
|
|
6455
|
-
// Try each transport in order
|
|
6399
|
+
let lastError = "";
|
|
6400
|
+
// Try each transport in order (sequential, not parallel)
|
|
6456
6401
|
for (const transport of this.transports) {
|
|
6402
|
+
if (this.config.debug) {
|
|
6403
|
+
console.log(`[Zaplier] Trying transport: ${transport.name}`);
|
|
6404
|
+
}
|
|
6457
6405
|
try {
|
|
6458
6406
|
const result = await transport.send(data, `${this.baseUrl}${endpoint}`);
|
|
6459
6407
|
// Update stats
|
|
@@ -6461,15 +6409,15 @@
|
|
|
6461
6409
|
this.stats.successfulRequests++;
|
|
6462
6410
|
this.updateMethodStats(transport.name, true);
|
|
6463
6411
|
if (this.config.debug) {
|
|
6464
|
-
console.log(`[Zaplier] Data sent successfully via ${transport.name}`, result);
|
|
6412
|
+
console.log(`[Zaplier] ✅ Data sent successfully via ${transport.name} - STOPPING fallback chain`, result);
|
|
6465
6413
|
}
|
|
6466
|
-
return result;
|
|
6414
|
+
return result; // SUCCESS - stop trying other transports
|
|
6467
6415
|
}
|
|
6468
6416
|
else {
|
|
6469
6417
|
this.updateMethodStats(transport.name, false);
|
|
6470
|
-
lastError = result.error ||
|
|
6418
|
+
lastError = result.error || "Unknown error";
|
|
6471
6419
|
if (this.config.debug) {
|
|
6472
|
-
console.warn(`[Zaplier] Transport ${transport.name} failed:`, result.error);
|
|
6420
|
+
console.warn(`[Zaplier] ❌ Transport ${transport.name} failed:`, result.error);
|
|
6473
6421
|
}
|
|
6474
6422
|
}
|
|
6475
6423
|
}
|
|
@@ -6477,18 +6425,18 @@
|
|
|
6477
6425
|
lastError = error instanceof Error ? error.message : String(error);
|
|
6478
6426
|
this.updateMethodStats(transport.name, false);
|
|
6479
6427
|
if (this.config.debug) {
|
|
6480
|
-
console.warn(`[Zaplier] Transport ${transport.name} threw error:`, error);
|
|
6428
|
+
console.warn(`[Zaplier] ❌ Transport ${transport.name} threw error:`, error);
|
|
6481
6429
|
}
|
|
6482
6430
|
}
|
|
6483
6431
|
// Wait before trying next transport
|
|
6484
6432
|
if (this.config.fallbackDelay > 0) {
|
|
6485
|
-
await new Promise(resolve => setTimeout(resolve, this.config.fallbackDelay));
|
|
6433
|
+
await new Promise((resolve) => setTimeout(resolve, this.config.fallbackDelay));
|
|
6486
6434
|
}
|
|
6487
6435
|
}
|
|
6488
6436
|
return {
|
|
6489
6437
|
success: false,
|
|
6490
|
-
method:
|
|
6491
|
-
error: `All transports failed. Last error: ${lastError}
|
|
6438
|
+
method: "all_failed",
|
|
6439
|
+
error: `All transports failed. Last error: ${lastError}`,
|
|
6492
6440
|
};
|
|
6493
6441
|
}
|
|
6494
6442
|
updateMethodStats(method, success) {
|
|
@@ -6522,7 +6470,7 @@
|
|
|
6522
6470
|
* Destroy all transports
|
|
6523
6471
|
*/
|
|
6524
6472
|
destroy() {
|
|
6525
|
-
this.transports.forEach(transport => {
|
|
6473
|
+
this.transports.forEach((transport) => {
|
|
6526
6474
|
if (transport.destroy) {
|
|
6527
6475
|
transport.destroy();
|
|
6528
6476
|
}
|
|
@@ -6543,7 +6491,7 @@
|
|
|
6543
6491
|
results[transport.name] = {
|
|
6544
6492
|
success: false,
|
|
6545
6493
|
method: transport.name,
|
|
6546
|
-
error: error instanceof Error ? error.message : String(error)
|
|
6494
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6547
6495
|
};
|
|
6548
6496
|
}
|
|
6549
6497
|
}
|
|
@@ -7679,7 +7627,7 @@
|
|
|
7679
7627
|
this.antiAdblockManager = new AntiAdblockManager(this.config.apiEndpoint, this.config.token, // Pass token to anti-adblock manager
|
|
7680
7628
|
{
|
|
7681
7629
|
enabled: true,
|
|
7682
|
-
methods: ["elysia-websocket", "fetch"
|
|
7630
|
+
methods: ["elysia-websocket", "fetch"],
|
|
7683
7631
|
fallbackDelay: 100,
|
|
7684
7632
|
maxRetries: 2,
|
|
7685
7633
|
debug: this.config.debug,
|