@cross-deck/web 1.6.3 → 1.7.0
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/CHANGELOG.md +46 -29
- package/dist/contracts.json +12 -12
- package/dist/crossdeck.umd.min.js +2 -2
- package/dist/crossdeck.umd.min.js.map +1 -1
- package/dist/error-codes.json +1 -1
- package/dist/index.cjs +110 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +110 -23
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +99 -12
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +99 -12
- package/dist/react.mjs.map +1 -1
- package/dist/vue.cjs +99 -12
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.mjs +99 -12
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -67,7 +67,7 @@ function typeMapForStatus(status) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// src/_version.ts
|
|
70
|
-
var SDK_VERSION = "1.
|
|
70
|
+
var SDK_VERSION = "1.7.0";
|
|
71
71
|
var SDK_NAME = "@cross-deck/web";
|
|
72
72
|
|
|
73
73
|
// src/http.ts
|
|
@@ -983,9 +983,13 @@ var EventQueue = class {
|
|
|
983
983
|
const env = this.cfg.envelope();
|
|
984
984
|
const result = await this.cfg.http.request("POST", "/events", {
|
|
985
985
|
body: {
|
|
986
|
-
//
|
|
987
|
-
//
|
|
988
|
-
//
|
|
986
|
+
// Event Envelope v1 batch envelope (backend/docs/
|
|
987
|
+
// event-envelope-spec-v1.md §1). `envelopeVersion` is the
|
|
988
|
+
// schema/wire version the server parses against ("can I parse
|
|
989
|
+
// this?") and is DISTINCT from `sdk.version` ("which build is in
|
|
990
|
+
// the wild?") — two questions, two fields, never conflated. The
|
|
991
|
+
// backend refuses payloads with a missing/unknown envelopeVersion.
|
|
992
|
+
envelopeVersion: 1,
|
|
989
993
|
appId: env.appId,
|
|
990
994
|
environment: env.environment,
|
|
991
995
|
sdk: env.sdk,
|
|
@@ -1440,6 +1444,15 @@ var AutoTracker = class {
|
|
|
1440
1444
|
this.cleanups = [];
|
|
1441
1445
|
/** Last time we flushed lastActivityAt to storage (throttle gate). */
|
|
1442
1446
|
this.lastPersistAt = 0;
|
|
1447
|
+
/**
|
|
1448
|
+
* Event Envelope v1 §3 — per-session monotonic sequence counter.
|
|
1449
|
+
* The single owner of the seq counter lives here, alongside all other
|
|
1450
|
+
* session state. Incremented atomically at track() time (via nextSeq()),
|
|
1451
|
+
* reset to 0 whenever a new session boundary is crossed (startNewSession
|
|
1452
|
+
* path + resetSession). Persists across background/foreground within a
|
|
1453
|
+
* session — only a real session boundary (not a tab hide/show) resets it.
|
|
1454
|
+
*/
|
|
1455
|
+
this._sessionSeq = 0;
|
|
1443
1456
|
/**
|
|
1444
1457
|
* Stable per-page-view identifier. Minted at every `page.viewed`
|
|
1445
1458
|
* emission and attached to every subsequent event until the next
|
|
@@ -1524,6 +1537,20 @@ var AutoTracker = class {
|
|
|
1524
1537
|
get currentAcquisition() {
|
|
1525
1538
|
return this.session?.acquisition ?? EMPTY_ACQUISITION;
|
|
1526
1539
|
}
|
|
1540
|
+
/**
|
|
1541
|
+
* Event Envelope v1 §3 — return the next seq value for the current session
|
|
1542
|
+
* and advance the counter. Called SYNCHRONOUSLY at track() time, before any
|
|
1543
|
+
* async dispatch, so the seq assignment order is deterministic (call order,
|
|
1544
|
+
* not scheduler luck). The counter is reset to 0 at every session boundary;
|
|
1545
|
+
* it is NOT reset by tab hide/show (spec §3 clause 1: backgrounding does not
|
|
1546
|
+
* reset seq). When no session is active (Node, before init, after uninstall),
|
|
1547
|
+
* returns 0 and leaves the counter unchanged — fallback, not an error.
|
|
1548
|
+
*/
|
|
1549
|
+
nextSeq() {
|
|
1550
|
+
const seq = this._sessionSeq;
|
|
1551
|
+
this._sessionSeq += 1;
|
|
1552
|
+
return seq;
|
|
1553
|
+
}
|
|
1527
1554
|
// ---------- sessions ----------
|
|
1528
1555
|
installSessionTracking() {
|
|
1529
1556
|
const now = Date.now();
|
|
@@ -1575,6 +1602,7 @@ var AutoTracker = class {
|
|
|
1575
1602
|
}
|
|
1576
1603
|
startNewSession() {
|
|
1577
1604
|
const now = Date.now();
|
|
1605
|
+
this._sessionSeq = 0;
|
|
1578
1606
|
return {
|
|
1579
1607
|
sessionId: mintSessionId(),
|
|
1580
1608
|
startedAt: now,
|
|
@@ -2303,6 +2331,40 @@ function writeJson(storage, key, value) {
|
|
|
2303
2331
|
}
|
|
2304
2332
|
}
|
|
2305
2333
|
|
|
2334
|
+
// src/internal-opt-out.ts
|
|
2335
|
+
var INTERNAL_OPT_OUT_PROPERTY = "$crossdeck_internal";
|
|
2336
|
+
var STORAGE_KEY = "crossdeck.internalOptOut";
|
|
2337
|
+
function localStore() {
|
|
2338
|
+
try {
|
|
2339
|
+
return typeof localStorage !== "undefined" ? localStorage : null;
|
|
2340
|
+
} catch {
|
|
2341
|
+
return null;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
function processInternalOptOutUrl() {
|
|
2345
|
+
try {
|
|
2346
|
+
const search = typeof location !== "undefined" ? location.search : "";
|
|
2347
|
+
const params = new URLSearchParams(search || "");
|
|
2348
|
+
if (!params.has("crossdeck_internal")) return;
|
|
2349
|
+
const store = localStore();
|
|
2350
|
+
if (!store) return;
|
|
2351
|
+
const v = params.get("crossdeck_internal");
|
|
2352
|
+
if (v === "1" || v === "true") {
|
|
2353
|
+
store.setItem(STORAGE_KEY, "1");
|
|
2354
|
+
} else if (v === "0" || v === "false") {
|
|
2355
|
+
store.removeItem(STORAGE_KEY);
|
|
2356
|
+
}
|
|
2357
|
+
} catch {
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
function isInternalOptOut() {
|
|
2361
|
+
try {
|
|
2362
|
+
return localStore()?.getItem(STORAGE_KEY) === "1";
|
|
2363
|
+
} catch {
|
|
2364
|
+
return false;
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2306
2368
|
// src/web-vitals.ts
|
|
2307
2369
|
var WebVitalsTracker = class {
|
|
2308
2370
|
constructor(cfg, report) {
|
|
@@ -3663,18 +3725,18 @@ function isInAppFrame(filename) {
|
|
|
3663
3725
|
if (/\/crossdeck\.umd\.min\.js$/.test(filename)) return false;
|
|
3664
3726
|
return true;
|
|
3665
3727
|
}
|
|
3666
|
-
function fingerprintError(message, frames,
|
|
3728
|
+
function fingerprintError(message, frames, location2) {
|
|
3667
3729
|
const inAppFrames = frames.filter((f) => f.in_app).slice(0, 3);
|
|
3668
3730
|
const parts = [
|
|
3669
3731
|
(message || "").slice(0, 200),
|
|
3670
3732
|
...inAppFrames.map((f) => `${f.function}@${f.filename}:${f.lineno}`)
|
|
3671
3733
|
];
|
|
3672
|
-
if (inAppFrames.length === 0 &&
|
|
3734
|
+
if (inAppFrames.length === 0 && location2) {
|
|
3673
3735
|
const loc = [
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3736
|
+
location2.errorType ?? "",
|
|
3737
|
+
location2.filename ?? "",
|
|
3738
|
+
location2.lineno ?? "",
|
|
3739
|
+
location2.colno ?? ""
|
|
3678
3740
|
].join(":");
|
|
3679
3741
|
if (loc !== ":::") parts.push(loc);
|
|
3680
3742
|
}
|
|
@@ -4520,6 +4582,7 @@ var CrossdeckClient = class {
|
|
|
4520
4582
|
persistIdentity ? effectiveStorage : new MemoryStorage(),
|
|
4521
4583
|
opts.storagePrefix
|
|
4522
4584
|
);
|
|
4585
|
+
processInternalOptOutUrl();
|
|
4523
4586
|
const consent = new ConsentManager({ respectDnt: options.respectDnt === true });
|
|
4524
4587
|
if (consent.isDntDenied) {
|
|
4525
4588
|
debug.emit(
|
|
@@ -5173,8 +5236,27 @@ var CrossdeckClient = class {
|
|
|
5173
5236
|
);
|
|
5174
5237
|
}
|
|
5175
5238
|
}
|
|
5239
|
+
const seq = s.autoTracker?.nextSeq() ?? 0;
|
|
5240
|
+
const occurrenceTimestamp = Date.now();
|
|
5176
5241
|
s.autoTracker?.markActivity();
|
|
5177
|
-
const
|
|
5242
|
+
const wireContext = {};
|
|
5243
|
+
const di = s.deviceInfo;
|
|
5244
|
+
if (di.os) wireContext.os = di.os;
|
|
5245
|
+
if (di.osVersion) wireContext.osVersion = di.osVersion;
|
|
5246
|
+
const appVer = s.options.appVersion;
|
|
5247
|
+
if (appVer) wireContext.appVersion = appVer;
|
|
5248
|
+
wireContext.sdkName = SDK_NAME;
|
|
5249
|
+
wireContext.sdkVersion = s.options.sdkVersion;
|
|
5250
|
+
if (di.locale) wireContext.locale = di.locale;
|
|
5251
|
+
if (di.timezone) wireContext.timezone = di.timezone;
|
|
5252
|
+
if (di.browser) wireContext.browser = di.browser;
|
|
5253
|
+
if (di.browserVersion) wireContext.browserVersion = di.browserVersion;
|
|
5254
|
+
const enriched = {};
|
|
5255
|
+
if (di.screenWidth !== void 0) enriched.screenWidth = di.screenWidth;
|
|
5256
|
+
if (di.screenHeight !== void 0) enriched.screenHeight = di.screenHeight;
|
|
5257
|
+
if (di.viewportWidth !== void 0) enriched.viewportWidth = di.viewportWidth;
|
|
5258
|
+
if (di.viewportHeight !== void 0) enriched.viewportHeight = di.viewportHeight;
|
|
5259
|
+
if (di.devicePixelRatio !== void 0) enriched.devicePixelRatio = di.devicePixelRatio;
|
|
5178
5260
|
const sessionId = s.autoTracker?.currentSessionId;
|
|
5179
5261
|
if (sessionId) enriched.sessionId = sessionId;
|
|
5180
5262
|
const pageviewId = s.autoTracker?.currentPageviewId;
|
|
@@ -5205,11 +5287,16 @@ var CrossdeckClient = class {
|
|
|
5205
5287
|
enriched.$groups = groupIds;
|
|
5206
5288
|
}
|
|
5207
5289
|
Object.assign(enriched, validation.properties);
|
|
5290
|
+
if (isInternalOptOut()) {
|
|
5291
|
+
enriched[INTERNAL_OPT_OUT_PROPERTY] = true;
|
|
5292
|
+
}
|
|
5208
5293
|
const finalProperties = s.scrubPii ? scrubPiiFromProperties(enriched) : enriched;
|
|
5209
5294
|
const event = {
|
|
5210
5295
|
eventId: this.mintEventId(),
|
|
5211
5296
|
name,
|
|
5212
|
-
timestamp:
|
|
5297
|
+
timestamp: occurrenceTimestamp,
|
|
5298
|
+
seq,
|
|
5299
|
+
context: wireContext,
|
|
5213
5300
|
properties: finalProperties
|
|
5214
5301
|
};
|
|
5215
5302
|
Object.assign(event, this.identityHintForEvent());
|