@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/index.cjs +57 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +57 -112
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +57 -112
- 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,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: [
|
|
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 =
|
|
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 ||
|
|
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:
|
|
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"
|
|
7630
|
+
methods: ["elysia-websocket", "fetch"],
|
|
7686
7631
|
fallbackDelay: 100,
|
|
7687
7632
|
maxRetries: 2,
|
|
7688
7633
|
debug: this.config.debug,
|