@drivemetadata-ai/sdk 0.1.1-beta.1 → 0.1.1-beta.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/README.md +18 -15
- package/dist/angular/index.cjs +880 -191
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.d.cts +2 -2
- package/dist/angular/index.d.ts +2 -2
- package/dist/angular/index.js +880 -191
- package/dist/angular/index.js.map +1 -1
- package/dist/browser/index.cjs +881 -192
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.d.cts +5 -68
- package/dist/browser/index.d.ts +5 -68
- package/dist/browser/index.js +881 -192
- package/dist/browser/index.js.map +1 -1
- package/dist/next/index.cjs +881 -191
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +881 -191
- package/dist/next/index.js.map +1 -1
- package/dist/node/index.cjs +152 -7
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +7 -1
- package/dist/node/index.d.ts +7 -1
- package/dist/node/index.js +152 -7
- package/dist/node/index.js.map +1 -1
- package/dist/react/index.cjs +881 -191
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +881 -191
- package/dist/react/index.js.map +1 -1
- package/dist/{types-BwtS0ZDu.d.cts → types-mgbdL1V7.d.cts} +24 -7
- package/dist/{types-BwtS0ZDu.d.ts → types-mgbdL1V7.d.ts} +24 -7
- package/docs/angular-integration.md +6 -6
- package/docs/architecture.md +109 -0
- package/docs/index.md +5 -6
- package/docs/integration.md +348 -0
- package/docs/node-server-integration.md +16 -7
- package/docs/npm-browser-sdk.md +6 -6
- package/docs/react-next-integration.md +9 -9
- package/docs/security-privacy.md +11 -11
- package/package.json +6 -6
- package/docs/migration-cdn-to-npm.md +0 -99
package/dist/browser/index.cjs
CHANGED
|
@@ -37,58 +37,154 @@ __export(browser_exports, {
|
|
|
37
37
|
});
|
|
38
38
|
module.exports = __toCommonJS(browser_exports);
|
|
39
39
|
|
|
40
|
-
// src/core/config.ts
|
|
41
|
-
function
|
|
42
|
-
if (
|
|
43
|
-
|
|
40
|
+
// src/browser/core/browser-config.ts
|
|
41
|
+
function setIfDefined(target, key, value) {
|
|
42
|
+
if (value !== void 0) {
|
|
43
|
+
target[key] = value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function normalizeBrowserConfig(input) {
|
|
47
|
+
const normalized = {
|
|
48
|
+
...input,
|
|
49
|
+
clientId: input.clientId ?? "",
|
|
50
|
+
workspaceId: input.workspaceId ?? "",
|
|
51
|
+
appId: input.appId ?? ""
|
|
52
|
+
};
|
|
53
|
+
setIfDefined(normalized, "apiHost", input.apiHost);
|
|
54
|
+
setIfDefined(normalized, "capturePageview", input.capturePageview);
|
|
55
|
+
setIfDefined(normalized, "capturePageleave", input.capturePageleave);
|
|
56
|
+
setIfDefined(normalized, "captureDeadClicks", input.captureDeadClicks);
|
|
57
|
+
setIfDefined(normalized, "crossSubdomainCookie", input.crossSubdomainCookie);
|
|
58
|
+
setIfDefined(normalized, "sessionIdleTimeoutSeconds", input.sessionIdleTimeoutSeconds);
|
|
59
|
+
setIfDefined(normalized, "schemaValidation", input.schemaValidation);
|
|
60
|
+
setIfDefined(normalized, "beforeSend", input.beforeSend);
|
|
61
|
+
setIfDefined(normalized, "persistence", input.disablePersistence === true ? "none" : input.persistence);
|
|
62
|
+
return normalized;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/core/uuid.ts
|
|
66
|
+
function createUuid() {
|
|
67
|
+
const cryptoApi = globalThis.crypto;
|
|
68
|
+
if (typeof cryptoApi?.randomUUID === "function") {
|
|
69
|
+
return cryptoApi.randomUUID();
|
|
70
|
+
}
|
|
71
|
+
const bytes = new Uint8Array(16);
|
|
72
|
+
if (typeof cryptoApi?.getRandomValues === "function") {
|
|
73
|
+
cryptoApi.getRandomValues(bytes);
|
|
74
|
+
} else {
|
|
75
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
76
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
80
|
+
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
81
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
82
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
83
|
+
}
|
|
84
|
+
function isUuid(value) {
|
|
85
|
+
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
86
|
+
}
|
|
87
|
+
function ensureUuid(value) {
|
|
88
|
+
return isUuid(value) ? value : createUuid();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/core/backend-payload.ts
|
|
92
|
+
function formatUtcTimestamp(value) {
|
|
93
|
+
const date = typeof value === "string" || typeof value === "number" || value instanceof Date ? new Date(value) : /* @__PURE__ */ new Date();
|
|
94
|
+
const safeDate = Number.isNaN(date.getTime()) ? /* @__PURE__ */ new Date() : date;
|
|
95
|
+
return safeDate.toISOString().replace("T", " ").slice(0, 19);
|
|
96
|
+
}
|
|
97
|
+
function cleanObject(value) {
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
|
|
100
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
101
|
+
}
|
|
102
|
+
if (value && typeof value === "object") {
|
|
103
|
+
const cleaned = Object.fromEntries(
|
|
104
|
+
Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
|
|
105
|
+
if (item === null || item === void 0 || item === "") return false;
|
|
106
|
+
if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
|
|
107
|
+
return true;
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
return Object.keys(cleaned).length > 0 ? cleaned : void 0;
|
|
44
111
|
}
|
|
45
112
|
return value;
|
|
46
113
|
}
|
|
47
|
-
function
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
114
|
+
function createBackendCollectorPayload(input) {
|
|
115
|
+
const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
|
|
116
|
+
const page2 = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
|
|
117
|
+
const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
|
|
118
|
+
const normalizedEventData = {
|
|
119
|
+
...eventData,
|
|
120
|
+
timestamp,
|
|
121
|
+
requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
|
|
122
|
+
requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
|
|
54
123
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
if (config.beforeSend !== void 0) legacyConfig.before_send = config.beforeSend;
|
|
80
|
-
return legacyConfig;
|
|
124
|
+
const metaData = {
|
|
125
|
+
...normalizedEventData,
|
|
126
|
+
requestId: ensureUuid(typeof input.requestId === "string" ? input.requestId : void 0),
|
|
127
|
+
timestamp,
|
|
128
|
+
eventType: input.eventType,
|
|
129
|
+
requestFrom: input.requestFrom ?? "3",
|
|
130
|
+
clientId: input.clientId,
|
|
131
|
+
workspaceId: input.workspaceId,
|
|
132
|
+
token: input.token,
|
|
133
|
+
anonymousId: ensureUuid(
|
|
134
|
+
typeof eventData.anonymousId === "string" ? eventData.anonymousId : typeof input.anonymousId === "string" ? input.anonymousId : void 0
|
|
135
|
+
),
|
|
136
|
+
sessionId: ensureUuid(
|
|
137
|
+
typeof eventData.sessionId === "string" ? eventData.sessionId : typeof input.sessionId === "string" ? input.sessionId : void 0
|
|
138
|
+
),
|
|
139
|
+
ua: input.ua,
|
|
140
|
+
appDetails: { app_id: input.appId },
|
|
141
|
+
page: { ...page2, url: page2.url ?? input.pageUrl },
|
|
142
|
+
requestSentAt: normalizedEventData.requestSentAt,
|
|
143
|
+
requestReceivedAt: normalizedEventData.requestReceivedAt
|
|
144
|
+
};
|
|
145
|
+
const payload = { metaData };
|
|
146
|
+
return cleanObject(payload);
|
|
81
147
|
}
|
|
82
148
|
|
|
83
|
-
// src/core/
|
|
84
|
-
|
|
85
|
-
|
|
149
|
+
// src/core/backend-schema.ts
|
|
150
|
+
var requiredMetaDataFields = [
|
|
151
|
+
"requestId",
|
|
152
|
+
"timestamp",
|
|
153
|
+
"eventType",
|
|
154
|
+
"requestFrom",
|
|
155
|
+
"clientId",
|
|
156
|
+
"workspaceId",
|
|
157
|
+
"anonymousId",
|
|
158
|
+
"sessionId"
|
|
159
|
+
];
|
|
160
|
+
function isPresent(value) {
|
|
161
|
+
return value !== null && value !== void 0 && value !== "";
|
|
86
162
|
}
|
|
87
|
-
function
|
|
88
|
-
|
|
163
|
+
function validateBackendCollectorPayload(payload) {
|
|
164
|
+
const errors = [];
|
|
165
|
+
const metaData = payload.metaData;
|
|
166
|
+
if (!metaData || typeof metaData !== "object" || Array.isArray(metaData)) {
|
|
167
|
+
return {
|
|
168
|
+
ok: false,
|
|
169
|
+
errors: ["metaData is required"]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const metadataRecord = metaData;
|
|
173
|
+
for (const field of requiredMetaDataFields) {
|
|
174
|
+
if (!isPresent(metadataRecord[field])) {
|
|
175
|
+
errors.push(`metaData.${field} is required`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (isPresent(metadataRecord.eventType) && typeof metadataRecord.eventType !== "string") {
|
|
179
|
+
errors.push("metaData.eventType must be a string");
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
ok: errors.length === 0,
|
|
183
|
+
errors
|
|
184
|
+
};
|
|
89
185
|
}
|
|
90
186
|
|
|
91
|
-
// src/
|
|
187
|
+
// src/core/consent.ts
|
|
92
188
|
var purposes = [
|
|
93
189
|
"analytics",
|
|
94
190
|
"advertising",
|
|
@@ -128,6 +224,335 @@ function canCollectPurpose(consent2, purpose) {
|
|
|
128
224
|
return consent2[purpose] === "granted";
|
|
129
225
|
}
|
|
130
226
|
|
|
227
|
+
// src/core/event-schema.ts
|
|
228
|
+
var reservedKeys = /* @__PURE__ */ new Set(["messageId", "timestamp", "type", "event", "anonymousId", "userId", "context"]);
|
|
229
|
+
function validateEventEnvelope(envelope, options = {}) {
|
|
230
|
+
if (options.mode === "off") return { ok: true, errors: [] };
|
|
231
|
+
const errors = [];
|
|
232
|
+
if (typeof envelope.type !== "string") errors.push("type must be a string");
|
|
233
|
+
if (envelope.type === "track" && typeof envelope.event !== "string") {
|
|
234
|
+
errors.push("track event must include event name");
|
|
235
|
+
}
|
|
236
|
+
if (typeof envelope.messageId !== "string") errors.push("messageId must be a string");
|
|
237
|
+
if (typeof envelope.timestamp !== "string") errors.push("timestamp must be an ISO string");
|
|
238
|
+
for (const key of Object.keys(envelope.properties ?? {})) {
|
|
239
|
+
if (reservedKeys.has(key)) errors.push(`properties.${key} is reserved`);
|
|
240
|
+
}
|
|
241
|
+
return { ok: errors.length === 0, errors };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/core/environment.ts
|
|
245
|
+
function getBrowserWindow() {
|
|
246
|
+
return typeof window === "undefined" ? void 0 : window;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// src/core/privacy.ts
|
|
250
|
+
var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
251
|
+
"email",
|
|
252
|
+
"phone",
|
|
253
|
+
"mobile",
|
|
254
|
+
"address",
|
|
255
|
+
"address1",
|
|
256
|
+
"address2",
|
|
257
|
+
"first_name",
|
|
258
|
+
"last_name",
|
|
259
|
+
"name",
|
|
260
|
+
"token",
|
|
261
|
+
"secret",
|
|
262
|
+
"password",
|
|
263
|
+
"session",
|
|
264
|
+
"cookie"
|
|
265
|
+
]);
|
|
266
|
+
function sanitizeValue(value, allow, path = []) {
|
|
267
|
+
if (Array.isArray(value)) {
|
|
268
|
+
return value.map((item) => sanitizeValue(item, allow, path));
|
|
269
|
+
}
|
|
270
|
+
if (value && typeof value === "object") {
|
|
271
|
+
return Object.fromEntries(
|
|
272
|
+
Object.entries(value).filter(([key]) => {
|
|
273
|
+
const lowerKey = key.toLowerCase();
|
|
274
|
+
const lowerPath = path.map((item) => item.toLowerCase());
|
|
275
|
+
const isEcommerceItemName = lowerKey === "name" && lowerPath.includes("ecommerce") && lowerPath.includes("items");
|
|
276
|
+
return isEcommerceItemName || !sensitiveKeys.has(lowerKey) || allow.has(lowerKey);
|
|
277
|
+
}).map(([key, nestedValue]) => [key, sanitizeValue(nestedValue, allow, [...path, key])])
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
return value;
|
|
281
|
+
}
|
|
282
|
+
function sanitizeProperties(input, allowRawKeys = []) {
|
|
283
|
+
const allow = new Set(allowRawKeys.map((key) => key.toLowerCase()));
|
|
284
|
+
return sanitizeValue(input, allow);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// src/core/attribution.ts
|
|
288
|
+
var dmdUtmKeys = [
|
|
289
|
+
"utm_source",
|
|
290
|
+
"utm_medium",
|
|
291
|
+
"utm_campaign",
|
|
292
|
+
"utm_term",
|
|
293
|
+
"utm_content",
|
|
294
|
+
"utm_id"
|
|
295
|
+
];
|
|
296
|
+
var dmdCampaignKeys = ["campaign_id", "ad_id"];
|
|
297
|
+
var dmdClickIdSources = [
|
|
298
|
+
["gclid", 2],
|
|
299
|
+
["fbclid", 3],
|
|
300
|
+
["ScCid", 1],
|
|
301
|
+
["li_fat_id", 4]
|
|
302
|
+
];
|
|
303
|
+
function cleanAttributionRecord(record) {
|
|
304
|
+
const cleaned = Object.fromEntries(
|
|
305
|
+
Object.entries(record).filter(([, value]) => value !== null && value !== void 0 && value !== "")
|
|
306
|
+
);
|
|
307
|
+
return Object.keys(cleaned).length > 0 ? cleaned : void 0;
|
|
308
|
+
}
|
|
309
|
+
function objectValue(value) {
|
|
310
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
311
|
+
}
|
|
312
|
+
function mergeAttributionRecords(explicitProperties, stored) {
|
|
313
|
+
const attributionData = objectValue(explicitProperties.attributionData);
|
|
314
|
+
const utmParameter = objectValue(explicitProperties.utmParameter);
|
|
315
|
+
return {
|
|
316
|
+
...explicitProperties,
|
|
317
|
+
...stored.attributionData || attributionData ? { attributionData: { ...stored.attributionData ?? {}, ...attributionData ?? {} } } : {},
|
|
318
|
+
...stored.utmParameter || utmParameter ? { utmParameter: { ...stored.utmParameter ?? {}, ...utmParameter ?? {} } } : {}
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// src/browser/core/attribution.ts
|
|
323
|
+
function getCurrentUrl() {
|
|
324
|
+
return getBrowserWindow()?.location?.href;
|
|
325
|
+
}
|
|
326
|
+
function getCookie(name) {
|
|
327
|
+
const cookie = getBrowserWindow()?.document?.cookie;
|
|
328
|
+
if (!cookie) return void 0;
|
|
329
|
+
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
330
|
+
const match = new RegExp(`(?:^|; )${escapedName}=([^;]*)`).exec(cookie);
|
|
331
|
+
return match ? decodeURIComponent(match[1] ?? "") : void 0;
|
|
332
|
+
}
|
|
333
|
+
function getParams(url) {
|
|
334
|
+
return new URL(url, "https://placeholder.local").searchParams;
|
|
335
|
+
}
|
|
336
|
+
function setIfPresent(persistence, key, value) {
|
|
337
|
+
if (value !== null && value !== "") {
|
|
338
|
+
persistence.setItem(key, value);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function getStoredString(persistence, key) {
|
|
342
|
+
const value = persistence.getItem(key);
|
|
343
|
+
return value === null || value === "" ? void 0 : value;
|
|
344
|
+
}
|
|
345
|
+
function getStoredNumberOrString(persistence, key) {
|
|
346
|
+
const value = getStoredString(persistence, key);
|
|
347
|
+
if (value === void 0) return void 0;
|
|
348
|
+
const parsed = Number.parseInt(value, 10);
|
|
349
|
+
return Number.isNaN(parsed) ? value : parsed;
|
|
350
|
+
}
|
|
351
|
+
function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
352
|
+
if (!url) return;
|
|
353
|
+
const params = getParams(url);
|
|
354
|
+
for (const key of dmdUtmKeys) {
|
|
355
|
+
setIfPresent(persistence, key, params.get(key));
|
|
356
|
+
}
|
|
357
|
+
for (const key of dmdCampaignKeys) {
|
|
358
|
+
setIfPresent(persistence, key, params.get(key));
|
|
359
|
+
}
|
|
360
|
+
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
361
|
+
const value = params.get(param);
|
|
362
|
+
if (value) {
|
|
363
|
+
persistence.setItem("unique_id", value);
|
|
364
|
+
persistence.setItem("sdk_pub_id", String(sdkPubId));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function getStoredAttributionData(persistence) {
|
|
369
|
+
return cleanAttributionRecord({
|
|
370
|
+
unique_id: getStoredString(persistence, "unique_id"),
|
|
371
|
+
sdk_pub_id: getStoredNumberOrString(persistence, "sdk_pub_id"),
|
|
372
|
+
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
373
|
+
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
374
|
+
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
375
|
+
ad_id: getStoredString(persistence, "ad_id")
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
function getStoredUtmParameter(persistence) {
|
|
379
|
+
return cleanAttributionRecord(Object.fromEntries(dmdUtmKeys.map((key) => [key, getStoredString(persistence, key)])));
|
|
380
|
+
}
|
|
381
|
+
function mergeStoredAttribution(properties, persistence) {
|
|
382
|
+
const stored = {};
|
|
383
|
+
const attributionData = getStoredAttributionData(persistence);
|
|
384
|
+
const utmParameter = getStoredUtmParameter(persistence);
|
|
385
|
+
if (attributionData !== void 0) stored.attributionData = attributionData;
|
|
386
|
+
if (utmParameter !== void 0) stored.utmParameter = utmParameter;
|
|
387
|
+
return mergeAttributionRecords(properties, stored);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// src/browser/core/autocapture.ts
|
|
391
|
+
function installAutocapture(config) {
|
|
392
|
+
const trackedPageUrls = /* @__PURE__ */ new Set();
|
|
393
|
+
const timers = /* @__PURE__ */ new Set();
|
|
394
|
+
const pageviewDelayMs = config.pageviewDelayMs ?? 500;
|
|
395
|
+
const history = config.browserWindow.history;
|
|
396
|
+
const originalPushState = history?.pushState;
|
|
397
|
+
const originalReplaceState = history?.replaceState;
|
|
398
|
+
function clearTimer(timer) {
|
|
399
|
+
timers.delete(timer);
|
|
400
|
+
clearTimeout(timer);
|
|
401
|
+
}
|
|
402
|
+
function canonicalUrl() {
|
|
403
|
+
return config.browserWindow.location.href;
|
|
404
|
+
}
|
|
405
|
+
function trackCurrentPageview() {
|
|
406
|
+
if (!config.capturePageview) return;
|
|
407
|
+
const url = canonicalUrl();
|
|
408
|
+
if (trackedPageUrls.has(url)) return;
|
|
409
|
+
trackedPageUrls.add(url);
|
|
410
|
+
config.onPageView();
|
|
411
|
+
}
|
|
412
|
+
function schedulePageview(delayMs) {
|
|
413
|
+
if (!config.capturePageview) return;
|
|
414
|
+
const timer = setTimeout(() => {
|
|
415
|
+
timers.delete(timer);
|
|
416
|
+
trackCurrentPageview();
|
|
417
|
+
}, delayMs);
|
|
418
|
+
timers.add(timer);
|
|
419
|
+
}
|
|
420
|
+
function handleRouteChange() {
|
|
421
|
+
config.onRouteChange?.();
|
|
422
|
+
trackCurrentPageview();
|
|
423
|
+
}
|
|
424
|
+
function wrapHistoryMethod(method) {
|
|
425
|
+
if (!history) return;
|
|
426
|
+
const original = history[method];
|
|
427
|
+
if (typeof original !== "function") return;
|
|
428
|
+
history[method] = function wrappedHistoryMethod(...args) {
|
|
429
|
+
const result = original.apply(this, args);
|
|
430
|
+
const timer = setTimeout(() => {
|
|
431
|
+
timers.delete(timer);
|
|
432
|
+
handleRouteChange();
|
|
433
|
+
}, 0);
|
|
434
|
+
timers.add(timer);
|
|
435
|
+
return result;
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function handlePopOrHashChange() {
|
|
439
|
+
handleRouteChange();
|
|
440
|
+
}
|
|
441
|
+
function handlePageLeave() {
|
|
442
|
+
if (config.capturePageleave) {
|
|
443
|
+
config.onPageLeave();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
schedulePageview(pageviewDelayMs);
|
|
447
|
+
wrapHistoryMethod("pushState");
|
|
448
|
+
wrapHistoryMethod("replaceState");
|
|
449
|
+
const canListen = typeof config.browserWindow.addEventListener === "function" && typeof config.browserWindow.removeEventListener === "function";
|
|
450
|
+
if (canListen) {
|
|
451
|
+
config.browserWindow.addEventListener("popstate", handlePopOrHashChange);
|
|
452
|
+
config.browserWindow.addEventListener("hashchange", handlePopOrHashChange);
|
|
453
|
+
config.browserWindow.addEventListener("beforeunload", handlePageLeave);
|
|
454
|
+
}
|
|
455
|
+
return {
|
|
456
|
+
cleanup() {
|
|
457
|
+
for (const timer of Array.from(timers)) {
|
|
458
|
+
clearTimer(timer);
|
|
459
|
+
}
|
|
460
|
+
if (history && originalPushState) history.pushState = originalPushState;
|
|
461
|
+
if (history && originalReplaceState) history.replaceState = originalReplaceState;
|
|
462
|
+
if (canListen) {
|
|
463
|
+
config.browserWindow.removeEventListener("popstate", handlePopOrHashChange);
|
|
464
|
+
config.browserWindow.removeEventListener("hashchange", handlePopOrHashChange);
|
|
465
|
+
config.browserWindow.removeEventListener("beforeunload", handlePageLeave);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/core/payload-size.ts
|
|
472
|
+
var preserveStringKeys = /* @__PURE__ */ new Set([
|
|
473
|
+
"requestId",
|
|
474
|
+
"eventType",
|
|
475
|
+
"requestFrom",
|
|
476
|
+
"clientId",
|
|
477
|
+
"workspaceId",
|
|
478
|
+
"anonymousId",
|
|
479
|
+
"sessionId",
|
|
480
|
+
"token"
|
|
481
|
+
]);
|
|
482
|
+
function payloadByteLength(payload) {
|
|
483
|
+
const serialized = JSON.stringify(payload);
|
|
484
|
+
if (typeof TextEncoder !== "undefined") {
|
|
485
|
+
return new TextEncoder().encode(serialized).length;
|
|
486
|
+
}
|
|
487
|
+
return serialized.length;
|
|
488
|
+
}
|
|
489
|
+
function clonePayload(payload) {
|
|
490
|
+
try {
|
|
491
|
+
return JSON.parse(JSON.stringify(payload));
|
|
492
|
+
} catch {
|
|
493
|
+
return void 0;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function truncateValue(value, truncateStringLength, key) {
|
|
497
|
+
if (typeof value === "string") {
|
|
498
|
+
if (key && preserveStringKeys.has(key)) return value;
|
|
499
|
+
if (value.length <= truncateStringLength) return value;
|
|
500
|
+
return `${value.slice(0, truncateStringLength)}...[TRUNCATED]`;
|
|
501
|
+
}
|
|
502
|
+
if (Array.isArray(value)) {
|
|
503
|
+
return value.map((item) => truncateValue(item, truncateStringLength));
|
|
504
|
+
}
|
|
505
|
+
if (value && typeof value === "object") {
|
|
506
|
+
return Object.fromEntries(
|
|
507
|
+
Object.entries(value).map(([childKey, childValue]) => [
|
|
508
|
+
childKey,
|
|
509
|
+
truncateValue(childValue, truncateStringLength, childKey)
|
|
510
|
+
])
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
return value;
|
|
514
|
+
}
|
|
515
|
+
function markPayloadTruncated(payload) {
|
|
516
|
+
if (payload.metaData && typeof payload.metaData === "object" && !Array.isArray(payload.metaData)) {
|
|
517
|
+
return {
|
|
518
|
+
...payload,
|
|
519
|
+
metaData: {
|
|
520
|
+
...payload.metaData,
|
|
521
|
+
payloadTruncated: true
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
return {
|
|
526
|
+
...payload,
|
|
527
|
+
payloadTruncated: true
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
function truncatePayload(payload, truncateStringLength) {
|
|
531
|
+
const cloned = clonePayload(payload);
|
|
532
|
+
if (!cloned) return void 0;
|
|
533
|
+
return markPayloadTruncated(truncateValue(cloned, truncateStringLength));
|
|
534
|
+
}
|
|
535
|
+
function getPayloadMessageId(payload) {
|
|
536
|
+
const value = payload.metaData?.requestId ?? payload.messageId;
|
|
537
|
+
return value === void 0 ? void 0 : String(value);
|
|
538
|
+
}
|
|
539
|
+
function preparePayloadForSizePolicy(payload, options = {}) {
|
|
540
|
+
const maxPayloadBytes = options.maxPayloadBytes ?? 64e3;
|
|
541
|
+
const payloadSizePolicy = options.payloadSizePolicy ?? "drop";
|
|
542
|
+
const payloadTruncateStringLength = options.payloadTruncateStringLength ?? 1024;
|
|
543
|
+
if (payloadByteLength(payload) <= maxPayloadBytes) {
|
|
544
|
+
return { ok: true, payload, truncated: false };
|
|
545
|
+
}
|
|
546
|
+
if (payloadSizePolicy === "truncate") {
|
|
547
|
+
const truncatedPayload = truncatePayload(payload, payloadTruncateStringLength);
|
|
548
|
+
if (truncatedPayload && payloadByteLength(truncatedPayload) <= maxPayloadBytes) {
|
|
549
|
+
return { ok: true, payload: truncatedPayload, truncated: true };
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
const messageId = getPayloadMessageId(payload);
|
|
553
|
+
return messageId === void 0 ? { ok: false, reason: "payload_too_large" } : { ok: false, reason: "payload_too_large", messageId };
|
|
554
|
+
}
|
|
555
|
+
|
|
131
556
|
// src/browser/core/delivery.ts
|
|
132
557
|
function createId(prefix) {
|
|
133
558
|
return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
@@ -143,8 +568,9 @@ function stableStringify(value) {
|
|
|
143
568
|
);
|
|
144
569
|
}
|
|
145
570
|
function createIdempotencyKey(payload, messageId) {
|
|
146
|
-
const
|
|
147
|
-
const
|
|
571
|
+
const metaData = payload.metaData;
|
|
572
|
+
const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? "event");
|
|
573
|
+
const properties = metaData ?? payload.properties;
|
|
148
574
|
const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;
|
|
149
575
|
if (orderId !== void 0) return `${event}:${String(orderId)}`;
|
|
150
576
|
return `${event}:${stableStringify(properties ?? {}) || messageId}`;
|
|
@@ -158,7 +584,6 @@ function createDeliveryManager(config) {
|
|
|
158
584
|
const lockTtlMs = config.lockTtlMs ?? 5e3;
|
|
159
585
|
const tabId = config.tabId ?? createId("tab");
|
|
160
586
|
const batchSize = config.batchSize ?? 25;
|
|
161
|
-
const maxPayloadBytes = config.maxPayloadBytes ?? 64e3;
|
|
162
587
|
function recordDrop(event) {
|
|
163
588
|
diagnostics.dropped.push(event);
|
|
164
589
|
config.onDrop?.(event);
|
|
@@ -167,12 +592,22 @@ function createDeliveryManager(config) {
|
|
|
167
592
|
diagnostics.lastError = error.message;
|
|
168
593
|
config.onError?.(error);
|
|
169
594
|
}
|
|
170
|
-
function
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
173
|
-
|
|
595
|
+
function preparePayloadForSend(payload) {
|
|
596
|
+
const sizePolicyOptions = {};
|
|
597
|
+
if (config.maxPayloadBytes !== void 0) sizePolicyOptions.maxPayloadBytes = config.maxPayloadBytes;
|
|
598
|
+
if (config.payloadSizePolicy !== void 0) sizePolicyOptions.payloadSizePolicy = config.payloadSizePolicy;
|
|
599
|
+
if (config.payloadTruncateStringLength !== void 0) {
|
|
600
|
+
sizePolicyOptions.payloadTruncateStringLength = config.payloadTruncateStringLength;
|
|
174
601
|
}
|
|
175
|
-
|
|
602
|
+
const prepared = preparePayloadForSizePolicy(payload, sizePolicyOptions);
|
|
603
|
+
if (prepared.ok) return prepared.payload;
|
|
604
|
+
const diagnostic = {
|
|
605
|
+
reason: prepared.reason,
|
|
606
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
607
|
+
};
|
|
608
|
+
if (prepared.messageId !== void 0) diagnostic.messageId = prepared.messageId;
|
|
609
|
+
recordDrop(diagnostic);
|
|
610
|
+
return void 0;
|
|
176
611
|
}
|
|
177
612
|
function recordStorageUnavailable() {
|
|
178
613
|
recordDrop({
|
|
@@ -245,14 +680,36 @@ function createDeliveryManager(config) {
|
|
|
245
680
|
persistQueue();
|
|
246
681
|
}
|
|
247
682
|
function withEnvelope(payload) {
|
|
248
|
-
const
|
|
683
|
+
const metaData = payload.metaData;
|
|
684
|
+
const messageId = String(metaData?.requestId ?? payload.messageId ?? createId("msg"));
|
|
685
|
+
if (metaData) {
|
|
686
|
+
return {
|
|
687
|
+
...payload,
|
|
688
|
+
metaData: {
|
|
689
|
+
...metaData,
|
|
690
|
+
requestId: messageId
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
}
|
|
249
694
|
return {
|
|
250
695
|
...payload,
|
|
251
696
|
messageId,
|
|
252
697
|
idempotencyKey: String(payload.idempotencyKey ?? createIdempotencyKey(payload, messageId))
|
|
253
698
|
};
|
|
254
699
|
}
|
|
700
|
+
function tryBeacon(body) {
|
|
701
|
+
if (!config.useBeacon) return false;
|
|
702
|
+
const sendBeacon = globalThis.navigator?.sendBeacon;
|
|
703
|
+
if (typeof sendBeacon !== "function") return false;
|
|
704
|
+
try {
|
|
705
|
+
const blob = new Blob([JSON.stringify(body)], { type: "application/json" });
|
|
706
|
+
return sendBeacon.call(globalThis.navigator, config.endpoint, blob);
|
|
707
|
+
} catch {
|
|
708
|
+
return false;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
255
711
|
async function deliver(body) {
|
|
712
|
+
if (tryBeacon(body)) return;
|
|
256
713
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
257
714
|
if (typeof fetchImpl !== "function") {
|
|
258
715
|
throw new Error("fetch_unavailable");
|
|
@@ -269,26 +726,22 @@ function createDeliveryManager(config) {
|
|
|
269
726
|
return {
|
|
270
727
|
async send(payload) {
|
|
271
728
|
const body = withEnvelope(payload);
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
messageId: String(body.messageId),
|
|
275
|
-
reason: "payload_too_large",
|
|
276
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
277
|
-
});
|
|
729
|
+
const preparedBody = preparePayloadForSend(body);
|
|
730
|
+
if (!preparedBody) {
|
|
278
731
|
return;
|
|
279
732
|
}
|
|
280
733
|
diagnostics.inFlight += 1;
|
|
281
734
|
try {
|
|
282
|
-
await deliver(
|
|
735
|
+
await deliver(preparedBody);
|
|
283
736
|
} catch (error) {
|
|
284
737
|
const deliveryError = error instanceof Error ? error : new Error(String(error));
|
|
285
738
|
recordError(deliveryError);
|
|
286
739
|
enqueue({
|
|
287
|
-
messageId: String(body
|
|
740
|
+
messageId: String(getPayloadMessageId(body)),
|
|
288
741
|
savedAt: Date.now(),
|
|
289
742
|
attempts: 1,
|
|
290
743
|
lastError: deliveryError.message,
|
|
291
|
-
payload:
|
|
744
|
+
payload: preparedBody
|
|
292
745
|
});
|
|
293
746
|
} finally {
|
|
294
747
|
diagnostics.inFlight -= 1;
|
|
@@ -401,65 +854,109 @@ function createDeliveryManager(config) {
|
|
|
401
854
|
};
|
|
402
855
|
}
|
|
403
856
|
|
|
404
|
-
// src/browser/core/
|
|
405
|
-
var
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
"name",
|
|
415
|
-
"token",
|
|
416
|
-
"secret",
|
|
417
|
-
"password",
|
|
418
|
-
"session",
|
|
419
|
-
"cookie"
|
|
420
|
-
]);
|
|
421
|
-
function sanitizeValue(value, allow) {
|
|
422
|
-
if (Array.isArray(value)) {
|
|
423
|
-
return value.map((item) => sanitizeValue(item, allow));
|
|
857
|
+
// src/browser/core/identity.ts
|
|
858
|
+
var ANONYMOUS_ID_STORAGE_KEY = "dmd_anonymous_id";
|
|
859
|
+
var LEGACY_ANONYMOUS_ID_STORAGE_KEY = "anonymousId";
|
|
860
|
+
function getUrlParam(name) {
|
|
861
|
+
const href = getBrowserWindow()?.location?.href;
|
|
862
|
+
if (!href) return null;
|
|
863
|
+
try {
|
|
864
|
+
return new URL(href).searchParams.get(name);
|
|
865
|
+
} catch {
|
|
866
|
+
return null;
|
|
424
867
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
868
|
+
}
|
|
869
|
+
function resolveAnonymousId(persistence) {
|
|
870
|
+
const urlAnonymousId = getUrlParam("aid");
|
|
871
|
+
if (isUuid(urlAnonymousId)) {
|
|
872
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, urlAnonymousId);
|
|
873
|
+
return urlAnonymousId;
|
|
429
874
|
}
|
|
430
|
-
|
|
875
|
+
const storedAnonymousId = persistence.getItem(ANONYMOUS_ID_STORAGE_KEY);
|
|
876
|
+
if (isUuid(storedAnonymousId)) {
|
|
877
|
+
return storedAnonymousId;
|
|
878
|
+
}
|
|
879
|
+
const legacyAnonymousId = persistence.getItem(LEGACY_ANONYMOUS_ID_STORAGE_KEY);
|
|
880
|
+
if (isUuid(legacyAnonymousId)) {
|
|
881
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, legacyAnonymousId);
|
|
882
|
+
return legacyAnonymousId;
|
|
883
|
+
}
|
|
884
|
+
const anonymousId = createUuid();
|
|
885
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, anonymousId);
|
|
886
|
+
return anonymousId;
|
|
431
887
|
}
|
|
432
|
-
function
|
|
433
|
-
const
|
|
434
|
-
|
|
888
|
+
function resetAnonymousId(persistence) {
|
|
889
|
+
const anonymousId = createUuid();
|
|
890
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, anonymousId);
|
|
891
|
+
return anonymousId;
|
|
435
892
|
}
|
|
436
893
|
|
|
437
|
-
// src/browser/core/
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
894
|
+
// src/browser/core/persistence.ts
|
|
895
|
+
function createPersistenceHealth(requested) {
|
|
896
|
+
return {
|
|
897
|
+
requested,
|
|
898
|
+
cookieFallbackUsed: false,
|
|
899
|
+
memoryFallbackUsed: requested === "memory",
|
|
900
|
+
failures: []
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function recordFailure(health, backend, operation, error) {
|
|
904
|
+
health.failures.push({
|
|
905
|
+
backend,
|
|
906
|
+
operation,
|
|
907
|
+
message: error instanceof Error ? error.message : String(error)
|
|
908
|
+
});
|
|
909
|
+
if (health.failures.length > 25) {
|
|
910
|
+
health.failures.shift();
|
|
450
911
|
}
|
|
451
|
-
return { ok: errors.length === 0, errors };
|
|
452
912
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
913
|
+
function createMemoryPersistence(health = createPersistenceHealth("memory")) {
|
|
914
|
+
const memory = {};
|
|
915
|
+
return {
|
|
916
|
+
getItem(key) {
|
|
917
|
+
return Object.prototype.hasOwnProperty.call(memory, key) ? memory[key] ?? null : null;
|
|
918
|
+
},
|
|
919
|
+
setItem(key, value) {
|
|
920
|
+
memory[key] = value;
|
|
921
|
+
return true;
|
|
922
|
+
},
|
|
923
|
+
removeItem(key) {
|
|
924
|
+
delete memory[key];
|
|
925
|
+
},
|
|
926
|
+
getHealth() {
|
|
927
|
+
return {
|
|
928
|
+
...health,
|
|
929
|
+
failures: health.failures.map((failure) => ({ ...failure }))
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
};
|
|
457
933
|
}
|
|
458
|
-
function
|
|
459
|
-
const
|
|
460
|
-
|
|
934
|
+
function getCookie2(name) {
|
|
935
|
+
const browserWindow = getBrowserWindow();
|
|
936
|
+
const cookie = browserWindow?.document?.cookie;
|
|
937
|
+
if (!cookie) return null;
|
|
938
|
+
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
939
|
+
const match = new RegExp(`(?:^|; )${escapedName}=([^;]*)`).exec(cookie);
|
|
940
|
+
return match ? decodeURIComponent(match[1] ?? "") : null;
|
|
941
|
+
}
|
|
942
|
+
function setCookie(name, value) {
|
|
943
|
+
const browserWindow = getBrowserWindow();
|
|
944
|
+
if (!browserWindow?.document) return false;
|
|
945
|
+
try {
|
|
946
|
+
const expires = new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toUTCString();
|
|
947
|
+
const secure = browserWindow.location?.protocol === "https:" ? "; Secure" : "";
|
|
948
|
+
browserWindow.document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/${secure}; SameSite=Lax`;
|
|
949
|
+
return true;
|
|
950
|
+
} catch {
|
|
951
|
+
return false;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
function removeCookie(name) {
|
|
955
|
+
const browserWindow = getBrowserWindow();
|
|
956
|
+
if (!browserWindow?.document) return;
|
|
957
|
+
browserWindow.document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
|
|
461
958
|
}
|
|
462
|
-
function
|
|
959
|
+
function getLocalStorage() {
|
|
463
960
|
const browserWindow = getBrowserWindow();
|
|
464
961
|
try {
|
|
465
962
|
return browserWindow?.localStorage;
|
|
@@ -467,37 +964,209 @@ function getBrowserStorage() {
|
|
|
467
964
|
return void 0;
|
|
468
965
|
}
|
|
469
966
|
}
|
|
967
|
+
function getSessionStorage() {
|
|
968
|
+
const browserWindow = getBrowserWindow();
|
|
969
|
+
try {
|
|
970
|
+
return browserWindow?.sessionStorage;
|
|
971
|
+
} catch {
|
|
972
|
+
return void 0;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
976
|
+
const health = createPersistenceHealth(mode);
|
|
977
|
+
const memory = createMemoryPersistence(health);
|
|
978
|
+
if (mode === "none") {
|
|
979
|
+
return {
|
|
980
|
+
getItem() {
|
|
981
|
+
return null;
|
|
982
|
+
},
|
|
983
|
+
setItem() {
|
|
984
|
+
return false;
|
|
985
|
+
},
|
|
986
|
+
removeItem() {
|
|
987
|
+
},
|
|
988
|
+
getHealth() {
|
|
989
|
+
return {
|
|
990
|
+
...health,
|
|
991
|
+
failures: health.failures.map((failure) => ({ ...failure }))
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
if (mode === "memory") return memory;
|
|
997
|
+
const primary = mode === "sessionStorage" ? getSessionStorage() : getLocalStorage();
|
|
998
|
+
const useCookie = mode === "cookie" || mode === "localStorage+cookie" || !primary;
|
|
999
|
+
return {
|
|
1000
|
+
getItem(key) {
|
|
1001
|
+
try {
|
|
1002
|
+
const stored = primary?.getItem(key);
|
|
1003
|
+
if (stored) return stored;
|
|
1004
|
+
} catch (error) {
|
|
1005
|
+
recordFailure(health, mode === "sessionStorage" ? "sessionStorage" : "localStorage", "get", error);
|
|
1006
|
+
}
|
|
1007
|
+
if (useCookie) {
|
|
1008
|
+
const cookie = getCookie2(key);
|
|
1009
|
+
if (cookie) {
|
|
1010
|
+
health.cookieFallbackUsed = true;
|
|
1011
|
+
return cookie;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
const value = memory.getItem(key);
|
|
1015
|
+
if (value !== null) health.memoryFallbackUsed = true;
|
|
1016
|
+
return value;
|
|
1017
|
+
},
|
|
1018
|
+
setItem(key, value) {
|
|
1019
|
+
let wrote = false;
|
|
1020
|
+
try {
|
|
1021
|
+
primary?.setItem(key, value);
|
|
1022
|
+
wrote = primary !== void 0;
|
|
1023
|
+
} catch (error) {
|
|
1024
|
+
recordFailure(health, mode === "sessionStorage" ? "sessionStorage" : "localStorage", "set", error);
|
|
1025
|
+
wrote = false;
|
|
1026
|
+
}
|
|
1027
|
+
if (useCookie) {
|
|
1028
|
+
const cookieWrote = setCookie(key, value);
|
|
1029
|
+
if (cookieWrote) health.cookieFallbackUsed = true;
|
|
1030
|
+
wrote = cookieWrote || wrote;
|
|
1031
|
+
}
|
|
1032
|
+
if (!wrote) {
|
|
1033
|
+
health.memoryFallbackUsed = true;
|
|
1034
|
+
return memory.setItem(key, value);
|
|
1035
|
+
}
|
|
1036
|
+
if (mode === "localStorage+cookie") {
|
|
1037
|
+
memory.setItem(key, value);
|
|
1038
|
+
}
|
|
1039
|
+
return true;
|
|
1040
|
+
},
|
|
1041
|
+
removeItem(key) {
|
|
1042
|
+
try {
|
|
1043
|
+
primary?.removeItem(key);
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
recordFailure(health, mode === "sessionStorage" ? "sessionStorage" : "localStorage", "remove", error);
|
|
1046
|
+
}
|
|
1047
|
+
if (useCookie) removeCookie(key);
|
|
1048
|
+
memory.removeItem(key);
|
|
1049
|
+
},
|
|
1050
|
+
getHealth() {
|
|
1051
|
+
return {
|
|
1052
|
+
...health,
|
|
1053
|
+
failures: health.failures.map((failure) => ({ ...failure }))
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/browser/core/session.ts
|
|
1060
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
1061
|
+
function getUrlParam2(name) {
|
|
1062
|
+
const href = getBrowserWindow()?.location?.href;
|
|
1063
|
+
if (!href) return null;
|
|
1064
|
+
try {
|
|
1065
|
+
return new URL(href).searchParams.get(name);
|
|
1066
|
+
} catch {
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
function readStoredSession(persistence) {
|
|
1071
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY);
|
|
1072
|
+
if (!rawSession) return void 0;
|
|
1073
|
+
try {
|
|
1074
|
+
const parsed = JSON.parse(rawSession);
|
|
1075
|
+
if (isUuid(parsed.sessionId) && typeof parsed.timestamp === "number") {
|
|
1076
|
+
return {
|
|
1077
|
+
sessionId: parsed.sessionId,
|
|
1078
|
+
timestamp: parsed.timestamp
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
} catch {
|
|
1082
|
+
persistence.removeItem(SESSION_STORAGE_KEY);
|
|
1083
|
+
}
|
|
1084
|
+
return void 0;
|
|
1085
|
+
}
|
|
1086
|
+
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1087
|
+
persistence.setItem(SESSION_STORAGE_KEY, JSON.stringify({ sessionId, timestamp }));
|
|
1088
|
+
}
|
|
1089
|
+
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1090
|
+
function resolveSessionId() {
|
|
1091
|
+
const now = Date.now();
|
|
1092
|
+
const urlSessionId = getUrlParam2("sid") ?? getUrlParam2("session_id");
|
|
1093
|
+
if (isUuid(urlSessionId)) {
|
|
1094
|
+
writeStoredSession(persistence, urlSessionId, now);
|
|
1095
|
+
return urlSessionId;
|
|
1096
|
+
}
|
|
1097
|
+
const storedSession = readStoredSession(persistence);
|
|
1098
|
+
if (storedSession && now - storedSession.timestamp <= idleTimeoutSeconds * 1e3) {
|
|
1099
|
+
writeStoredSession(persistence, storedSession.sessionId, now);
|
|
1100
|
+
return storedSession.sessionId;
|
|
1101
|
+
}
|
|
1102
|
+
const sessionId = createUuid();
|
|
1103
|
+
writeStoredSession(persistence, sessionId, now);
|
|
1104
|
+
return sessionId;
|
|
1105
|
+
}
|
|
1106
|
+
return {
|
|
1107
|
+
getSessionId() {
|
|
1108
|
+
return resolveSessionId();
|
|
1109
|
+
},
|
|
1110
|
+
reset() {
|
|
1111
|
+
const sessionId = createUuid();
|
|
1112
|
+
writeStoredSession(persistence, sessionId, Date.now());
|
|
1113
|
+
return sessionId;
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
// src/browser/core/DriveMetaDataSDK.ts
|
|
1119
|
+
function endpointFromConfig(config) {
|
|
1120
|
+
const host = config.apiHost ?? "https://sdk.drivemetadata.com/v2";
|
|
1121
|
+
return `${host.replace(/\/$/, "")}/data-collector`;
|
|
1122
|
+
}
|
|
1123
|
+
function requireConfigString(value, field) {
|
|
1124
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
1125
|
+
throw new Error(`DMD SDK config ${field} is required`);
|
|
1126
|
+
}
|
|
1127
|
+
return value;
|
|
1128
|
+
}
|
|
470
1129
|
var DriveMetaDataSDK = class {
|
|
471
1130
|
constructor(config) {
|
|
472
1131
|
this.initialized = true;
|
|
473
1132
|
this.queue = [];
|
|
474
1133
|
this.offline = false;
|
|
475
1134
|
this.droppedEvents = 0;
|
|
1135
|
+
requireConfigString(config.clientId, "clientId");
|
|
1136
|
+
requireConfigString(config.workspaceId, "workspaceId");
|
|
1137
|
+
requireConfigString(config.appId, "appId");
|
|
1138
|
+
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
476
1139
|
this.config = config;
|
|
477
1140
|
this.endpoint = endpointFromConfig(config);
|
|
478
|
-
|
|
1141
|
+
this.persistence = createBrowserPersistence(config.persistence);
|
|
1142
|
+
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
479
1143
|
const deliveryConfig = {
|
|
480
|
-
endpoint: this.endpoint
|
|
1144
|
+
endpoint: this.endpoint,
|
|
1145
|
+
storage: this.persistence
|
|
481
1146
|
};
|
|
482
1147
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
483
1148
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
484
1149
|
if (config.delivery?.retryDelayMs !== void 0) deliveryConfig.retryDelayMs = config.delivery.retryDelayMs;
|
|
485
1150
|
if (config.delivery?.maxRetryDelayMs !== void 0) deliveryConfig.maxRetryDelayMs = config.delivery.maxRetryDelayMs;
|
|
486
1151
|
if (config.delivery?.maxPayloadBytes !== void 0) deliveryConfig.maxPayloadBytes = config.delivery.maxPayloadBytes;
|
|
1152
|
+
if (config.delivery?.payloadSizePolicy !== void 0) deliveryConfig.payloadSizePolicy = config.delivery.payloadSizePolicy;
|
|
1153
|
+
if (config.delivery?.payloadTruncateStringLength !== void 0) {
|
|
1154
|
+
deliveryConfig.payloadTruncateStringLength = config.delivery.payloadTruncateStringLength;
|
|
1155
|
+
}
|
|
1156
|
+
if (config.delivery?.useBeacon !== void 0) deliveryConfig.useBeacon = config.delivery.useBeacon;
|
|
487
1157
|
if (config.delivery?.batchSize !== void 0) deliveryConfig.batchSize = config.delivery.batchSize;
|
|
488
1158
|
if (config.onDrop !== void 0) deliveryConfig.onDrop = config.onDrop;
|
|
489
1159
|
if (config.onError !== void 0) deliveryConfig.onError = config.onError;
|
|
490
|
-
this.delivery = createDeliveryManager(
|
|
491
|
-
...deliveryConfig,
|
|
492
|
-
storage
|
|
493
|
-
} : deliveryConfig);
|
|
1160
|
+
this.delivery = createDeliveryManager(deliveryConfig);
|
|
494
1161
|
this.initialRetryDelayMs = config.delivery?.retryDelayMs ?? 1e3;
|
|
495
1162
|
this.retryDelayMs = this.initialRetryDelayMs;
|
|
496
1163
|
this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 3e4;
|
|
497
1164
|
this.writeKey = config.writeKey || config.token || "";
|
|
498
|
-
this.identity = { anonymousId:
|
|
1165
|
+
this.identity = { anonymousId: resolveAnonymousId(this.persistence) };
|
|
1166
|
+
captureAttributionFromUrl(this.persistence);
|
|
499
1167
|
this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);
|
|
500
1168
|
this.gdprConsent = this.consentState.analytics;
|
|
1169
|
+
this.installAutocapture();
|
|
501
1170
|
if (!config.delivery?.disableLifecycleFlush) {
|
|
502
1171
|
this.installLifecycleFlush();
|
|
503
1172
|
}
|
|
@@ -537,7 +1206,8 @@ var DriveMetaDataSDK = class {
|
|
|
537
1206
|
}
|
|
538
1207
|
}
|
|
539
1208
|
reset() {
|
|
540
|
-
this.identity = { anonymousId:
|
|
1209
|
+
this.identity = { anonymousId: resetAnonymousId(this.persistence) };
|
|
1210
|
+
this.session.reset();
|
|
541
1211
|
this.queue = [];
|
|
542
1212
|
this.offline = false;
|
|
543
1213
|
if (this.retryTimer !== void 0) {
|
|
@@ -546,8 +1216,20 @@ var DriveMetaDataSDK = class {
|
|
|
546
1216
|
}
|
|
547
1217
|
this.lifecycleCleanup?.();
|
|
548
1218
|
this.lifecycleCleanup = void 0;
|
|
1219
|
+
this.autocaptureCleanup?.();
|
|
1220
|
+
this.autocaptureCleanup = void 0;
|
|
549
1221
|
this.delivery.clearQueue("manual_clear");
|
|
550
1222
|
}
|
|
1223
|
+
disposeForTests() {
|
|
1224
|
+
if (this.retryTimer !== void 0) {
|
|
1225
|
+
clearTimeout(this.retryTimer);
|
|
1226
|
+
this.retryTimer = void 0;
|
|
1227
|
+
}
|
|
1228
|
+
this.lifecycleCleanup?.();
|
|
1229
|
+
this.lifecycleCleanup = void 0;
|
|
1230
|
+
this.autocaptureCleanup?.();
|
|
1231
|
+
this.autocaptureCleanup = void 0;
|
|
1232
|
+
}
|
|
551
1233
|
setConsent(consent2) {
|
|
552
1234
|
this.consentState = typeof consent2 === "object" ? mergeConsent(this.consentState, consent2) : normalizeConsent(consent2);
|
|
553
1235
|
this.gdprConsent = this.consentState.analytics;
|
|
@@ -562,6 +1244,7 @@ var DriveMetaDataSDK = class {
|
|
|
562
1244
|
initialized: this.initialized,
|
|
563
1245
|
consent: this.gdprConsent,
|
|
564
1246
|
consentPurposes: this.consentState,
|
|
1247
|
+
persistence: this.persistence.getHealth(),
|
|
565
1248
|
queueSize: deliveryDiagnostics.queued,
|
|
566
1249
|
offline: this.offline || deliveryDiagnostics.queued > 0,
|
|
567
1250
|
droppedEvents: this.droppedEvents + deliveryDiagnostics.dropped.length,
|
|
@@ -576,7 +1259,9 @@ var DriveMetaDataSDK = class {
|
|
|
576
1259
|
void this.delivery.send(payload).then(() => {
|
|
577
1260
|
const diagnostics = this.delivery.getDiagnostics();
|
|
578
1261
|
this.offline = diagnostics.queued > 0;
|
|
579
|
-
|
|
1262
|
+
if (diagnostics.lastError !== void 0) {
|
|
1263
|
+
this.lastError = diagnostics.lastError;
|
|
1264
|
+
}
|
|
580
1265
|
if (diagnostics.queued > 0) {
|
|
581
1266
|
this.scheduleRetryFlush();
|
|
582
1267
|
}
|
|
@@ -608,6 +1293,28 @@ var DriveMetaDataSDK = class {
|
|
|
608
1293
|
}
|
|
609
1294
|
};
|
|
610
1295
|
}
|
|
1296
|
+
installAutocapture() {
|
|
1297
|
+
const browserWindow = getBrowserWindow();
|
|
1298
|
+
if (!browserWindow) return;
|
|
1299
|
+
if (this.config.autocapture === false) return;
|
|
1300
|
+
const capturePageview = this.config.capturePageview !== false;
|
|
1301
|
+
const capturePageleave = this.config.capturePageleave !== false;
|
|
1302
|
+
const controller = installAutocapture({
|
|
1303
|
+
browserWindow,
|
|
1304
|
+
capturePageview,
|
|
1305
|
+
capturePageleave,
|
|
1306
|
+
onPageView: () => {
|
|
1307
|
+
this.page();
|
|
1308
|
+
},
|
|
1309
|
+
onPageLeave: () => {
|
|
1310
|
+
this.trackEvent("page_leave", { url: browserWindow.location.href });
|
|
1311
|
+
},
|
|
1312
|
+
onRouteChange: () => {
|
|
1313
|
+
captureAttributionFromUrl(this.persistence);
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
this.autocaptureCleanup = controller.cleanup;
|
|
1317
|
+
}
|
|
611
1318
|
scheduleRetryFlush() {
|
|
612
1319
|
if (this.retryTimer !== void 0) return;
|
|
613
1320
|
const delay = Math.min(this.retryDelayMs, this.maxRetryDelayMs);
|
|
@@ -633,7 +1340,7 @@ var DriveMetaDataSDK = class {
|
|
|
633
1340
|
type,
|
|
634
1341
|
event,
|
|
635
1342
|
properties: sanitizeProperties(properties),
|
|
636
|
-
messageId: options.messageId
|
|
1343
|
+
messageId: ensureUuid(options.messageId),
|
|
637
1344
|
timestamp: options.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
638
1345
|
context: options.context ?? {},
|
|
639
1346
|
anonymousId: this.identity.anonymousId,
|
|
@@ -641,7 +1348,8 @@ var DriveMetaDataSDK = class {
|
|
|
641
1348
|
workspaceId: this.config.workspaceId,
|
|
642
1349
|
appId: this.config.appId,
|
|
643
1350
|
writeKey: this.writeKey,
|
|
644
|
-
consent: this.consentState
|
|
1351
|
+
consent: this.consentState,
|
|
1352
|
+
sessionId: this.session.getSessionId()
|
|
645
1353
|
};
|
|
646
1354
|
if (this.identity.userId !== void 0) prepared.userId = this.identity.userId;
|
|
647
1355
|
if (this.identity.groupId !== void 0) prepared.groupId = this.identity.groupId;
|
|
@@ -665,7 +1373,41 @@ var DriveMetaDataSDK = class {
|
|
|
665
1373
|
if (!validation.ok) {
|
|
666
1374
|
this.lastError = `DMD SDK schema warning: ${validation.errors.join(", ")}`;
|
|
667
1375
|
}
|
|
668
|
-
this.
|
|
1376
|
+
const collectorPayload = this.toCollectorPayload(prepared);
|
|
1377
|
+
const backendValidation = validateBackendCollectorPayload(collectorPayload);
|
|
1378
|
+
if (!backendValidation.ok && this.config.schemaValidation === "strict") {
|
|
1379
|
+
this.lastError = `DMD SDK backend schema warning: ${backendValidation.errors.join(", ")}`;
|
|
1380
|
+
this.recordDrop(type, "invalid_payload", event);
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
if (!backendValidation.ok) {
|
|
1384
|
+
this.lastError = `DMD SDK backend schema warning: ${backendValidation.errors.join(", ")}`;
|
|
1385
|
+
}
|
|
1386
|
+
this.sendEvent(collectorPayload);
|
|
1387
|
+
}
|
|
1388
|
+
toCollectorPayload(prepared) {
|
|
1389
|
+
const browserWindow = getBrowserWindow();
|
|
1390
|
+
return createBackendCollectorPayload({
|
|
1391
|
+
requestId: prepared.messageId,
|
|
1392
|
+
timestamp: prepared.timestamp,
|
|
1393
|
+
eventType: prepared.event,
|
|
1394
|
+
clientId: prepared.clientId,
|
|
1395
|
+
workspaceId: prepared.workspaceId,
|
|
1396
|
+
token: prepared.writeKey,
|
|
1397
|
+
anonymousId: prepared.anonymousId,
|
|
1398
|
+
sessionId: prepared.sessionId,
|
|
1399
|
+
ua: browserWindow?.navigator?.userAgent,
|
|
1400
|
+
appId: prepared.appId,
|
|
1401
|
+
pageUrl: browserWindow?.location?.href,
|
|
1402
|
+
eventData: mergeStoredAttribution({
|
|
1403
|
+
...prepared.properties,
|
|
1404
|
+
anonymousId: prepared.anonymousId,
|
|
1405
|
+
sessionId: prepared.sessionId,
|
|
1406
|
+
timestamp: prepared.timestamp,
|
|
1407
|
+
requestSentAt: prepared.timestamp,
|
|
1408
|
+
requestReceivedAt: prepared.timestamp
|
|
1409
|
+
}, this.persistence)
|
|
1410
|
+
});
|
|
669
1411
|
}
|
|
670
1412
|
recordDrop(type, reason, event) {
|
|
671
1413
|
this.droppedEvents += 1;
|
|
@@ -679,22 +1421,6 @@ var DriveMetaDataSDK = class {
|
|
|
679
1421
|
}
|
|
680
1422
|
};
|
|
681
1423
|
|
|
682
|
-
// src/browser/legacy-loader.ts
|
|
683
|
-
function getLegacySdkInstanceFromWindow() {
|
|
684
|
-
const browserWindow = getBrowserWindow();
|
|
685
|
-
return browserWindow?.__DriveMetaDataSDKInstance;
|
|
686
|
-
}
|
|
687
|
-
function ensureLegacySdkLoaded() {
|
|
688
|
-
if (!isBrowserRuntime()) {
|
|
689
|
-
throw new Error("DMD legacy SDK is only available in a browser runtime");
|
|
690
|
-
}
|
|
691
|
-
const browserWindow = getBrowserWindow();
|
|
692
|
-
if (!browserWindow?.DriveMetaDataSDK) {
|
|
693
|
-
throw new Error("DMD legacy SDK constructor is missing from window.DriveMetaDataSDK");
|
|
694
|
-
}
|
|
695
|
-
return browserWindow.DriveMetaDataSDK;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
1424
|
// src/browser/client.ts
|
|
699
1425
|
var singleton;
|
|
700
1426
|
var publicSingleton;
|
|
@@ -703,56 +1429,34 @@ var lastError;
|
|
|
703
1429
|
var lastDroppedEvent;
|
|
704
1430
|
function createPublicClient(instance) {
|
|
705
1431
|
return {
|
|
706
|
-
__legacy: instance,
|
|
707
1432
|
track(event, properties, options) {
|
|
708
|
-
|
|
709
|
-
instance.trackEvent(event, properties, options);
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
instance.sendEvent?.({ eventName: event, event, properties, options });
|
|
1433
|
+
instance.trackEvent(event, properties, options);
|
|
713
1434
|
},
|
|
714
1435
|
identify(userId, traits, options) {
|
|
715
|
-
|
|
716
|
-
instance.identify(userId, traits, options);
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
instance.identifyUser?.(userId, traits);
|
|
1436
|
+
instance.identify(userId, traits, options);
|
|
720
1437
|
},
|
|
721
1438
|
page(name, properties, options) {
|
|
722
|
-
|
|
723
|
-
instance.page(name, properties, options);
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
instance.trackPageview?.();
|
|
1439
|
+
instance.page(name, properties, options);
|
|
727
1440
|
},
|
|
728
1441
|
group(groupId, traits, options) {
|
|
729
|
-
instance.group
|
|
1442
|
+
instance.group(groupId, traits, options);
|
|
730
1443
|
},
|
|
731
1444
|
alias(previousId, userId, options) {
|
|
732
|
-
instance.alias
|
|
1445
|
+
instance.alias(previousId, userId, options);
|
|
733
1446
|
},
|
|
734
1447
|
async flush() {
|
|
735
|
-
await instance.flush
|
|
1448
|
+
await instance.flush();
|
|
736
1449
|
},
|
|
737
1450
|
reset() {
|
|
738
|
-
instance.reset
|
|
1451
|
+
instance.reset();
|
|
739
1452
|
singleton = void 0;
|
|
740
1453
|
publicSingleton = void 0;
|
|
741
1454
|
},
|
|
742
1455
|
setConsent(consent2) {
|
|
743
|
-
|
|
744
|
-
instance.setConsent(consent2);
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
if (typeof consent2 === "string") {
|
|
748
|
-
instance.gdprConsent = consent2;
|
|
749
|
-
}
|
|
1456
|
+
instance.setConsent(consent2);
|
|
750
1457
|
},
|
|
751
1458
|
getHealth() {
|
|
752
|
-
|
|
753
|
-
return instance.getHealth();
|
|
754
|
-
}
|
|
755
|
-
return getDmdHealth();
|
|
1459
|
+
return instance.getHealth();
|
|
756
1460
|
}
|
|
757
1461
|
};
|
|
758
1462
|
}
|
|
@@ -777,23 +1481,8 @@ function initDmdSDK(config) {
|
|
|
777
1481
|
if (publicSingleton) {
|
|
778
1482
|
return publicSingleton;
|
|
779
1483
|
}
|
|
780
|
-
const legacyConfig = normalizeBrowserConfig(config);
|
|
781
|
-
const existingInstance = getLegacySdkInstanceFromWindow();
|
|
782
|
-
if (existingInstance) {
|
|
783
|
-
return setSingleton(existingInstance);
|
|
784
|
-
}
|
|
785
1484
|
try {
|
|
786
|
-
|
|
787
|
-
try {
|
|
788
|
-
const LegacySdk = ensureLegacySdkLoaded();
|
|
789
|
-
instance = new LegacySdk(legacyConfig);
|
|
790
|
-
} catch (error) {
|
|
791
|
-
if (error instanceof Error && error.message.includes("constructor is missing")) {
|
|
792
|
-
instance = new DriveMetaDataSDK(config);
|
|
793
|
-
} else {
|
|
794
|
-
throw error;
|
|
795
|
-
}
|
|
796
|
-
}
|
|
1485
|
+
const instance = new DriveMetaDataSDK(normalizeBrowserConfig(config));
|
|
797
1486
|
return setSingleton(instance);
|
|
798
1487
|
} catch (error) {
|
|
799
1488
|
lastError = error instanceof Error ? error.message : String(error);
|
|
@@ -868,14 +1557,14 @@ async function ready() {
|
|
|
868
1557
|
return getDmdSDK();
|
|
869
1558
|
}
|
|
870
1559
|
function getDmdHealth() {
|
|
871
|
-
if (singleton
|
|
1560
|
+
if (singleton) {
|
|
872
1561
|
return singleton.getHealth();
|
|
873
1562
|
}
|
|
874
1563
|
const health = {
|
|
875
|
-
initialized:
|
|
876
|
-
consent:
|
|
877
|
-
queueSize:
|
|
878
|
-
offline:
|
|
1564
|
+
initialized: false,
|
|
1565
|
+
consent: "pending",
|
|
1566
|
+
queueSize: 0,
|
|
1567
|
+
offline: false,
|
|
879
1568
|
droppedEvents
|
|
880
1569
|
};
|
|
881
1570
|
if (lastError !== void 0) {
|
|
@@ -887,7 +1576,7 @@ function getDmdHealth() {
|
|
|
887
1576
|
return health;
|
|
888
1577
|
}
|
|
889
1578
|
function resetDmdSDKForTests() {
|
|
890
|
-
singleton?.
|
|
1579
|
+
singleton?.disposeForTests();
|
|
891
1580
|
singleton = void 0;
|
|
892
1581
|
publicSingleton = void 0;
|
|
893
1582
|
droppedEvents = 0;
|