@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.esm.js
CHANGED
|
@@ -6117,16 +6117,16 @@ function getAvailableComponents() {
|
|
|
6117
6117
|
*/
|
|
6118
6118
|
class FetchTransport {
|
|
6119
6119
|
constructor() {
|
|
6120
|
-
this.name =
|
|
6121
|
-
this.available = typeof fetch !==
|
|
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:
|
|
6128
|
-
headers: {
|
|
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 =
|
|
6218
|
-
this.available = typeof WebSocket !==
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
6246
|
-
reject(new Error(
|
|
6183
|
+
this.ws?.removeEventListener("message", messageHandler);
|
|
6184
|
+
reject(new Error("Failed to parse WebSocket response"));
|
|
6247
6185
|
}
|
|
6248
6186
|
};
|
|
6249
|
-
this.ws?.addEventListener(
|
|
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 ||
|
|
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(
|
|
6270
|
-
reject(new Error(
|
|
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 ===
|
|
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(
|
|
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(
|
|
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 =
|
|
6331
|
-
this.available = typeof globalThis.RTCPeerConnection !==
|
|
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 {
|
|
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:
|
|
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:
|
|
6313
|
+
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
|
6372
6314
|
});
|
|
6373
|
-
this.dataChannel = this.pc.createDataChannel(
|
|
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: [
|
|
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
|
-
|
|
6370
|
+
"elysia-websocket": () => new ElysiaWebSocketTransport(this.baseUrl, this.token),
|
|
6429
6371
|
fetch: () => new FetchTransport(),
|
|
6430
|
-
|
|
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(
|
|
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 =
|
|
6384
|
+
async send(data, endpoint = "/tracking/event") {
|
|
6444
6385
|
this.stats.totalRequests++;
|
|
6445
6386
|
if (!this.config.enabled || this.transports.length === 0) {
|
|
6446
|
-
return {
|
|
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 ||
|
|
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:
|
|
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"
|
|
7624
|
+
methods: ["elysia-websocket", "fetch"],
|
|
7677
7625
|
fallbackDelay: 100,
|
|
7678
7626
|
maxRetries: 2,
|
|
7679
7627
|
debug: this.config.debug,
|