@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/angular/index.js
CHANGED
|
@@ -13,58 +13,154 @@ var __decorateParam = (index, decorator) => (target, key) => decorator(target, k
|
|
|
13
13
|
// src/angular/dmd-analytics.service.ts
|
|
14
14
|
import { Inject, Injectable, Optional } from "@angular/core";
|
|
15
15
|
|
|
16
|
-
// src/core/config.ts
|
|
17
|
-
function
|
|
18
|
-
if (
|
|
19
|
-
|
|
16
|
+
// src/browser/core/browser-config.ts
|
|
17
|
+
function setIfDefined(target, key, value) {
|
|
18
|
+
if (value !== void 0) {
|
|
19
|
+
target[key] = value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function normalizeBrowserConfig(input) {
|
|
23
|
+
const normalized = {
|
|
24
|
+
...input,
|
|
25
|
+
clientId: input.clientId ?? "",
|
|
26
|
+
workspaceId: input.workspaceId ?? "",
|
|
27
|
+
appId: input.appId ?? ""
|
|
28
|
+
};
|
|
29
|
+
setIfDefined(normalized, "apiHost", input.apiHost);
|
|
30
|
+
setIfDefined(normalized, "capturePageview", input.capturePageview);
|
|
31
|
+
setIfDefined(normalized, "capturePageleave", input.capturePageleave);
|
|
32
|
+
setIfDefined(normalized, "captureDeadClicks", input.captureDeadClicks);
|
|
33
|
+
setIfDefined(normalized, "crossSubdomainCookie", input.crossSubdomainCookie);
|
|
34
|
+
setIfDefined(normalized, "sessionIdleTimeoutSeconds", input.sessionIdleTimeoutSeconds);
|
|
35
|
+
setIfDefined(normalized, "schemaValidation", input.schemaValidation);
|
|
36
|
+
setIfDefined(normalized, "beforeSend", input.beforeSend);
|
|
37
|
+
setIfDefined(normalized, "persistence", input.disablePersistence === true ? "none" : input.persistence);
|
|
38
|
+
return normalized;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/core/uuid.ts
|
|
42
|
+
function createUuid() {
|
|
43
|
+
const cryptoApi = globalThis.crypto;
|
|
44
|
+
if (typeof cryptoApi?.randomUUID === "function") {
|
|
45
|
+
return cryptoApi.randomUUID();
|
|
46
|
+
}
|
|
47
|
+
const bytes = new Uint8Array(16);
|
|
48
|
+
if (typeof cryptoApi?.getRandomValues === "function") {
|
|
49
|
+
cryptoApi.getRandomValues(bytes);
|
|
50
|
+
} else {
|
|
51
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
52
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
56
|
+
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
57
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
58
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
59
|
+
}
|
|
60
|
+
function isUuid(value) {
|
|
61
|
+
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);
|
|
62
|
+
}
|
|
63
|
+
function ensureUuid(value) {
|
|
64
|
+
return isUuid(value) ? value : createUuid();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/core/backend-payload.ts
|
|
68
|
+
function formatUtcTimestamp(value) {
|
|
69
|
+
const date = typeof value === "string" || typeof value === "number" || value instanceof Date ? new Date(value) : /* @__PURE__ */ new Date();
|
|
70
|
+
const safeDate = Number.isNaN(date.getTime()) ? /* @__PURE__ */ new Date() : date;
|
|
71
|
+
return safeDate.toISOString().replace("T", " ").slice(0, 19);
|
|
72
|
+
}
|
|
73
|
+
function cleanObject(value) {
|
|
74
|
+
if (Array.isArray(value)) {
|
|
75
|
+
const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
|
|
76
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
77
|
+
}
|
|
78
|
+
if (value && typeof value === "object") {
|
|
79
|
+
const cleaned = Object.fromEntries(
|
|
80
|
+
Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
|
|
81
|
+
if (item === null || item === void 0 || item === "") return false;
|
|
82
|
+
if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
|
|
83
|
+
return true;
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
return Object.keys(cleaned).length > 0 ? cleaned : void 0;
|
|
20
87
|
}
|
|
21
88
|
return value;
|
|
22
89
|
}
|
|
23
|
-
function
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
90
|
+
function createBackendCollectorPayload(input) {
|
|
91
|
+
const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
|
|
92
|
+
const page2 = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
|
|
93
|
+
const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
|
|
94
|
+
const normalizedEventData = {
|
|
95
|
+
...eventData,
|
|
96
|
+
timestamp,
|
|
97
|
+
requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
|
|
98
|
+
requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
|
|
99
|
+
};
|
|
100
|
+
const metaData = {
|
|
101
|
+
...normalizedEventData,
|
|
102
|
+
requestId: ensureUuid(typeof input.requestId === "string" ? input.requestId : void 0),
|
|
103
|
+
timestamp,
|
|
104
|
+
eventType: input.eventType,
|
|
105
|
+
requestFrom: input.requestFrom ?? "3",
|
|
106
|
+
clientId: input.clientId,
|
|
107
|
+
workspaceId: input.workspaceId,
|
|
108
|
+
token: input.token,
|
|
109
|
+
anonymousId: ensureUuid(
|
|
110
|
+
typeof eventData.anonymousId === "string" ? eventData.anonymousId : typeof input.anonymousId === "string" ? input.anonymousId : void 0
|
|
111
|
+
),
|
|
112
|
+
sessionId: ensureUuid(
|
|
113
|
+
typeof eventData.sessionId === "string" ? eventData.sessionId : typeof input.sessionId === "string" ? input.sessionId : void 0
|
|
114
|
+
),
|
|
115
|
+
ua: input.ua,
|
|
116
|
+
appDetails: { app_id: input.appId },
|
|
117
|
+
page: { ...page2, url: page2.url ?? input.pageUrl },
|
|
118
|
+
requestSentAt: normalizedEventData.requestSentAt,
|
|
119
|
+
requestReceivedAt: normalizedEventData.requestReceivedAt
|
|
30
120
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (config.deeplink !== void 0) legacyConfig.deeplink = config.deeplink;
|
|
34
|
-
if (config.debug !== void 0) legacyConfig.debug = config.debug;
|
|
35
|
-
if (config.consent !== void 0) legacyConfig.consent = config.consent;
|
|
36
|
-
if (config.gdprConsent !== void 0) legacyConfig.gdprConsent = config.gdprConsent;
|
|
37
|
-
if (config.autocapture !== void 0) legacyConfig.autocapture = config.autocapture;
|
|
38
|
-
if (config.capturePageview !== void 0) legacyConfig.capture_pageview = config.capturePageview;
|
|
39
|
-
if (config.capturePageleave !== void 0) legacyConfig.capture_pageleave = config.capturePageleave;
|
|
40
|
-
if (config.captureDeadClicks !== void 0) legacyConfig.capture_dead_clicks = config.captureDeadClicks;
|
|
41
|
-
if (config.crossSubdomainCookie !== void 0) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;
|
|
42
|
-
if (config.disablePersistence !== void 0) legacyConfig.disable_persistence = config.disablePersistence;
|
|
43
|
-
if (config.disableSurveys !== void 0) legacyConfig.disable_surveys = config.disableSurveys;
|
|
44
|
-
if (config.disableSessionRecording !== void 0) legacyConfig.disable_session_recording = config.disableSessionRecording;
|
|
45
|
-
if (config.enableHeatmaps !== void 0) legacyConfig.enable_heatmaps = config.enableHeatmaps;
|
|
46
|
-
if (config.maskAllText !== void 0) legacyConfig.mask_all_text = config.maskAllText;
|
|
47
|
-
if (config.maskAllElementAttributes !== void 0) {
|
|
48
|
-
legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;
|
|
49
|
-
}
|
|
50
|
-
if (config.persistence !== void 0) legacyConfig.persistence = config.persistence;
|
|
51
|
-
if (config.propertyDenylist !== void 0) legacyConfig.property_denylist = config.propertyDenylist;
|
|
52
|
-
if (config.sessionIdleTimeoutSeconds !== void 0) {
|
|
53
|
-
legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;
|
|
54
|
-
}
|
|
55
|
-
if (config.beforeSend !== void 0) legacyConfig.before_send = config.beforeSend;
|
|
56
|
-
return legacyConfig;
|
|
121
|
+
const payload = { metaData };
|
|
122
|
+
return cleanObject(payload);
|
|
57
123
|
}
|
|
58
124
|
|
|
59
|
-
// src/core/
|
|
60
|
-
|
|
61
|
-
|
|
125
|
+
// src/core/backend-schema.ts
|
|
126
|
+
var requiredMetaDataFields = [
|
|
127
|
+
"requestId",
|
|
128
|
+
"timestamp",
|
|
129
|
+
"eventType",
|
|
130
|
+
"requestFrom",
|
|
131
|
+
"clientId",
|
|
132
|
+
"workspaceId",
|
|
133
|
+
"anonymousId",
|
|
134
|
+
"sessionId"
|
|
135
|
+
];
|
|
136
|
+
function isPresent(value) {
|
|
137
|
+
return value !== null && value !== void 0 && value !== "";
|
|
62
138
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
139
|
+
function validateBackendCollectorPayload(payload) {
|
|
140
|
+
const errors = [];
|
|
141
|
+
const metaData = payload.metaData;
|
|
142
|
+
if (!metaData || typeof metaData !== "object" || Array.isArray(metaData)) {
|
|
143
|
+
return {
|
|
144
|
+
ok: false,
|
|
145
|
+
errors: ["metaData is required"]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const metadataRecord = metaData;
|
|
149
|
+
for (const field of requiredMetaDataFields) {
|
|
150
|
+
if (!isPresent(metadataRecord[field])) {
|
|
151
|
+
errors.push(`metaData.${field} is required`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (isPresent(metadataRecord.eventType) && typeof metadataRecord.eventType !== "string") {
|
|
155
|
+
errors.push("metaData.eventType must be a string");
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
ok: errors.length === 0,
|
|
159
|
+
errors
|
|
160
|
+
};
|
|
65
161
|
}
|
|
66
162
|
|
|
67
|
-
// src/
|
|
163
|
+
// src/core/consent.ts
|
|
68
164
|
var purposes = [
|
|
69
165
|
"analytics",
|
|
70
166
|
"advertising",
|
|
@@ -104,6 +200,335 @@ function canCollectPurpose(consent, purpose) {
|
|
|
104
200
|
return consent[purpose] === "granted";
|
|
105
201
|
}
|
|
106
202
|
|
|
203
|
+
// src/core/event-schema.ts
|
|
204
|
+
var reservedKeys = /* @__PURE__ */ new Set(["messageId", "timestamp", "type", "event", "anonymousId", "userId", "context"]);
|
|
205
|
+
function validateEventEnvelope(envelope, options = {}) {
|
|
206
|
+
if (options.mode === "off") return { ok: true, errors: [] };
|
|
207
|
+
const errors = [];
|
|
208
|
+
if (typeof envelope.type !== "string") errors.push("type must be a string");
|
|
209
|
+
if (envelope.type === "track" && typeof envelope.event !== "string") {
|
|
210
|
+
errors.push("track event must include event name");
|
|
211
|
+
}
|
|
212
|
+
if (typeof envelope.messageId !== "string") errors.push("messageId must be a string");
|
|
213
|
+
if (typeof envelope.timestamp !== "string") errors.push("timestamp must be an ISO string");
|
|
214
|
+
for (const key of Object.keys(envelope.properties ?? {})) {
|
|
215
|
+
if (reservedKeys.has(key)) errors.push(`properties.${key} is reserved`);
|
|
216
|
+
}
|
|
217
|
+
return { ok: errors.length === 0, errors };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/core/environment.ts
|
|
221
|
+
function getBrowserWindow() {
|
|
222
|
+
return typeof window === "undefined" ? void 0 : window;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/core/privacy.ts
|
|
226
|
+
var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
227
|
+
"email",
|
|
228
|
+
"phone",
|
|
229
|
+
"mobile",
|
|
230
|
+
"address",
|
|
231
|
+
"address1",
|
|
232
|
+
"address2",
|
|
233
|
+
"first_name",
|
|
234
|
+
"last_name",
|
|
235
|
+
"name",
|
|
236
|
+
"token",
|
|
237
|
+
"secret",
|
|
238
|
+
"password",
|
|
239
|
+
"session",
|
|
240
|
+
"cookie"
|
|
241
|
+
]);
|
|
242
|
+
function sanitizeValue(value, allow, path = []) {
|
|
243
|
+
if (Array.isArray(value)) {
|
|
244
|
+
return value.map((item) => sanitizeValue(item, allow, path));
|
|
245
|
+
}
|
|
246
|
+
if (value && typeof value === "object") {
|
|
247
|
+
return Object.fromEntries(
|
|
248
|
+
Object.entries(value).filter(([key]) => {
|
|
249
|
+
const lowerKey = key.toLowerCase();
|
|
250
|
+
const lowerPath = path.map((item) => item.toLowerCase());
|
|
251
|
+
const isEcommerceItemName = lowerKey === "name" && lowerPath.includes("ecommerce") && lowerPath.includes("items");
|
|
252
|
+
return isEcommerceItemName || !sensitiveKeys.has(lowerKey) || allow.has(lowerKey);
|
|
253
|
+
}).map(([key, nestedValue]) => [key, sanitizeValue(nestedValue, allow, [...path, key])])
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
258
|
+
function sanitizeProperties(input, allowRawKeys = []) {
|
|
259
|
+
const allow = new Set(allowRawKeys.map((key) => key.toLowerCase()));
|
|
260
|
+
return sanitizeValue(input, allow);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/core/attribution.ts
|
|
264
|
+
var dmdUtmKeys = [
|
|
265
|
+
"utm_source",
|
|
266
|
+
"utm_medium",
|
|
267
|
+
"utm_campaign",
|
|
268
|
+
"utm_term",
|
|
269
|
+
"utm_content",
|
|
270
|
+
"utm_id"
|
|
271
|
+
];
|
|
272
|
+
var dmdCampaignKeys = ["campaign_id", "ad_id"];
|
|
273
|
+
var dmdClickIdSources = [
|
|
274
|
+
["gclid", 2],
|
|
275
|
+
["fbclid", 3],
|
|
276
|
+
["ScCid", 1],
|
|
277
|
+
["li_fat_id", 4]
|
|
278
|
+
];
|
|
279
|
+
function cleanAttributionRecord(record) {
|
|
280
|
+
const cleaned = Object.fromEntries(
|
|
281
|
+
Object.entries(record).filter(([, value]) => value !== null && value !== void 0 && value !== "")
|
|
282
|
+
);
|
|
283
|
+
return Object.keys(cleaned).length > 0 ? cleaned : void 0;
|
|
284
|
+
}
|
|
285
|
+
function objectValue(value) {
|
|
286
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
287
|
+
}
|
|
288
|
+
function mergeAttributionRecords(explicitProperties, stored) {
|
|
289
|
+
const attributionData = objectValue(explicitProperties.attributionData);
|
|
290
|
+
const utmParameter = objectValue(explicitProperties.utmParameter);
|
|
291
|
+
return {
|
|
292
|
+
...explicitProperties,
|
|
293
|
+
...stored.attributionData || attributionData ? { attributionData: { ...stored.attributionData ?? {}, ...attributionData ?? {} } } : {},
|
|
294
|
+
...stored.utmParameter || utmParameter ? { utmParameter: { ...stored.utmParameter ?? {}, ...utmParameter ?? {} } } : {}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/browser/core/attribution.ts
|
|
299
|
+
function getCurrentUrl() {
|
|
300
|
+
return getBrowserWindow()?.location?.href;
|
|
301
|
+
}
|
|
302
|
+
function getCookie(name) {
|
|
303
|
+
const cookie = getBrowserWindow()?.document?.cookie;
|
|
304
|
+
if (!cookie) return void 0;
|
|
305
|
+
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
306
|
+
const match = new RegExp(`(?:^|; )${escapedName}=([^;]*)`).exec(cookie);
|
|
307
|
+
return match ? decodeURIComponent(match[1] ?? "") : void 0;
|
|
308
|
+
}
|
|
309
|
+
function getParams(url) {
|
|
310
|
+
return new URL(url, "https://placeholder.local").searchParams;
|
|
311
|
+
}
|
|
312
|
+
function setIfPresent(persistence, key, value) {
|
|
313
|
+
if (value !== null && value !== "") {
|
|
314
|
+
persistence.setItem(key, value);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function getStoredString(persistence, key) {
|
|
318
|
+
const value = persistence.getItem(key);
|
|
319
|
+
return value === null || value === "" ? void 0 : value;
|
|
320
|
+
}
|
|
321
|
+
function getStoredNumberOrString(persistence, key) {
|
|
322
|
+
const value = getStoredString(persistence, key);
|
|
323
|
+
if (value === void 0) return void 0;
|
|
324
|
+
const parsed = Number.parseInt(value, 10);
|
|
325
|
+
return Number.isNaN(parsed) ? value : parsed;
|
|
326
|
+
}
|
|
327
|
+
function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
328
|
+
if (!url) return;
|
|
329
|
+
const params = getParams(url);
|
|
330
|
+
for (const key of dmdUtmKeys) {
|
|
331
|
+
setIfPresent(persistence, key, params.get(key));
|
|
332
|
+
}
|
|
333
|
+
for (const key of dmdCampaignKeys) {
|
|
334
|
+
setIfPresent(persistence, key, params.get(key));
|
|
335
|
+
}
|
|
336
|
+
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
337
|
+
const value = params.get(param);
|
|
338
|
+
if (value) {
|
|
339
|
+
persistence.setItem("unique_id", value);
|
|
340
|
+
persistence.setItem("sdk_pub_id", String(sdkPubId));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function getStoredAttributionData(persistence) {
|
|
345
|
+
return cleanAttributionRecord({
|
|
346
|
+
unique_id: getStoredString(persistence, "unique_id"),
|
|
347
|
+
sdk_pub_id: getStoredNumberOrString(persistence, "sdk_pub_id"),
|
|
348
|
+
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
349
|
+
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
350
|
+
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
351
|
+
ad_id: getStoredString(persistence, "ad_id")
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
function getStoredUtmParameter(persistence) {
|
|
355
|
+
return cleanAttributionRecord(Object.fromEntries(dmdUtmKeys.map((key) => [key, getStoredString(persistence, key)])));
|
|
356
|
+
}
|
|
357
|
+
function mergeStoredAttribution(properties, persistence) {
|
|
358
|
+
const stored = {};
|
|
359
|
+
const attributionData = getStoredAttributionData(persistence);
|
|
360
|
+
const utmParameter = getStoredUtmParameter(persistence);
|
|
361
|
+
if (attributionData !== void 0) stored.attributionData = attributionData;
|
|
362
|
+
if (utmParameter !== void 0) stored.utmParameter = utmParameter;
|
|
363
|
+
return mergeAttributionRecords(properties, stored);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// src/browser/core/autocapture.ts
|
|
367
|
+
function installAutocapture(config) {
|
|
368
|
+
const trackedPageUrls = /* @__PURE__ */ new Set();
|
|
369
|
+
const timers = /* @__PURE__ */ new Set();
|
|
370
|
+
const pageviewDelayMs = config.pageviewDelayMs ?? 500;
|
|
371
|
+
const history = config.browserWindow.history;
|
|
372
|
+
const originalPushState = history?.pushState;
|
|
373
|
+
const originalReplaceState = history?.replaceState;
|
|
374
|
+
function clearTimer(timer) {
|
|
375
|
+
timers.delete(timer);
|
|
376
|
+
clearTimeout(timer);
|
|
377
|
+
}
|
|
378
|
+
function canonicalUrl() {
|
|
379
|
+
return config.browserWindow.location.href;
|
|
380
|
+
}
|
|
381
|
+
function trackCurrentPageview() {
|
|
382
|
+
if (!config.capturePageview) return;
|
|
383
|
+
const url = canonicalUrl();
|
|
384
|
+
if (trackedPageUrls.has(url)) return;
|
|
385
|
+
trackedPageUrls.add(url);
|
|
386
|
+
config.onPageView();
|
|
387
|
+
}
|
|
388
|
+
function schedulePageview(delayMs) {
|
|
389
|
+
if (!config.capturePageview) return;
|
|
390
|
+
const timer = setTimeout(() => {
|
|
391
|
+
timers.delete(timer);
|
|
392
|
+
trackCurrentPageview();
|
|
393
|
+
}, delayMs);
|
|
394
|
+
timers.add(timer);
|
|
395
|
+
}
|
|
396
|
+
function handleRouteChange() {
|
|
397
|
+
config.onRouteChange?.();
|
|
398
|
+
trackCurrentPageview();
|
|
399
|
+
}
|
|
400
|
+
function wrapHistoryMethod(method) {
|
|
401
|
+
if (!history) return;
|
|
402
|
+
const original = history[method];
|
|
403
|
+
if (typeof original !== "function") return;
|
|
404
|
+
history[method] = function wrappedHistoryMethod(...args) {
|
|
405
|
+
const result = original.apply(this, args);
|
|
406
|
+
const timer = setTimeout(() => {
|
|
407
|
+
timers.delete(timer);
|
|
408
|
+
handleRouteChange();
|
|
409
|
+
}, 0);
|
|
410
|
+
timers.add(timer);
|
|
411
|
+
return result;
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function handlePopOrHashChange() {
|
|
415
|
+
handleRouteChange();
|
|
416
|
+
}
|
|
417
|
+
function handlePageLeave() {
|
|
418
|
+
if (config.capturePageleave) {
|
|
419
|
+
config.onPageLeave();
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
schedulePageview(pageviewDelayMs);
|
|
423
|
+
wrapHistoryMethod("pushState");
|
|
424
|
+
wrapHistoryMethod("replaceState");
|
|
425
|
+
const canListen = typeof config.browserWindow.addEventListener === "function" && typeof config.browserWindow.removeEventListener === "function";
|
|
426
|
+
if (canListen) {
|
|
427
|
+
config.browserWindow.addEventListener("popstate", handlePopOrHashChange);
|
|
428
|
+
config.browserWindow.addEventListener("hashchange", handlePopOrHashChange);
|
|
429
|
+
config.browserWindow.addEventListener("beforeunload", handlePageLeave);
|
|
430
|
+
}
|
|
431
|
+
return {
|
|
432
|
+
cleanup() {
|
|
433
|
+
for (const timer of Array.from(timers)) {
|
|
434
|
+
clearTimer(timer);
|
|
435
|
+
}
|
|
436
|
+
if (history && originalPushState) history.pushState = originalPushState;
|
|
437
|
+
if (history && originalReplaceState) history.replaceState = originalReplaceState;
|
|
438
|
+
if (canListen) {
|
|
439
|
+
config.browserWindow.removeEventListener("popstate", handlePopOrHashChange);
|
|
440
|
+
config.browserWindow.removeEventListener("hashchange", handlePopOrHashChange);
|
|
441
|
+
config.browserWindow.removeEventListener("beforeunload", handlePageLeave);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// src/core/payload-size.ts
|
|
448
|
+
var preserveStringKeys = /* @__PURE__ */ new Set([
|
|
449
|
+
"requestId",
|
|
450
|
+
"eventType",
|
|
451
|
+
"requestFrom",
|
|
452
|
+
"clientId",
|
|
453
|
+
"workspaceId",
|
|
454
|
+
"anonymousId",
|
|
455
|
+
"sessionId",
|
|
456
|
+
"token"
|
|
457
|
+
]);
|
|
458
|
+
function payloadByteLength(payload) {
|
|
459
|
+
const serialized = JSON.stringify(payload);
|
|
460
|
+
if (typeof TextEncoder !== "undefined") {
|
|
461
|
+
return new TextEncoder().encode(serialized).length;
|
|
462
|
+
}
|
|
463
|
+
return serialized.length;
|
|
464
|
+
}
|
|
465
|
+
function clonePayload(payload) {
|
|
466
|
+
try {
|
|
467
|
+
return JSON.parse(JSON.stringify(payload));
|
|
468
|
+
} catch {
|
|
469
|
+
return void 0;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function truncateValue(value, truncateStringLength, key) {
|
|
473
|
+
if (typeof value === "string") {
|
|
474
|
+
if (key && preserveStringKeys.has(key)) return value;
|
|
475
|
+
if (value.length <= truncateStringLength) return value;
|
|
476
|
+
return `${value.slice(0, truncateStringLength)}...[TRUNCATED]`;
|
|
477
|
+
}
|
|
478
|
+
if (Array.isArray(value)) {
|
|
479
|
+
return value.map((item) => truncateValue(item, truncateStringLength));
|
|
480
|
+
}
|
|
481
|
+
if (value && typeof value === "object") {
|
|
482
|
+
return Object.fromEntries(
|
|
483
|
+
Object.entries(value).map(([childKey, childValue]) => [
|
|
484
|
+
childKey,
|
|
485
|
+
truncateValue(childValue, truncateStringLength, childKey)
|
|
486
|
+
])
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
return value;
|
|
490
|
+
}
|
|
491
|
+
function markPayloadTruncated(payload) {
|
|
492
|
+
if (payload.metaData && typeof payload.metaData === "object" && !Array.isArray(payload.metaData)) {
|
|
493
|
+
return {
|
|
494
|
+
...payload,
|
|
495
|
+
metaData: {
|
|
496
|
+
...payload.metaData,
|
|
497
|
+
payloadTruncated: true
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
...payload,
|
|
503
|
+
payloadTruncated: true
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
function truncatePayload(payload, truncateStringLength) {
|
|
507
|
+
const cloned = clonePayload(payload);
|
|
508
|
+
if (!cloned) return void 0;
|
|
509
|
+
return markPayloadTruncated(truncateValue(cloned, truncateStringLength));
|
|
510
|
+
}
|
|
511
|
+
function getPayloadMessageId(payload) {
|
|
512
|
+
const value = payload.metaData?.requestId ?? payload.messageId;
|
|
513
|
+
return value === void 0 ? void 0 : String(value);
|
|
514
|
+
}
|
|
515
|
+
function preparePayloadForSizePolicy(payload, options = {}) {
|
|
516
|
+
const maxPayloadBytes = options.maxPayloadBytes ?? 64e3;
|
|
517
|
+
const payloadSizePolicy = options.payloadSizePolicy ?? "drop";
|
|
518
|
+
const payloadTruncateStringLength = options.payloadTruncateStringLength ?? 1024;
|
|
519
|
+
if (payloadByteLength(payload) <= maxPayloadBytes) {
|
|
520
|
+
return { ok: true, payload, truncated: false };
|
|
521
|
+
}
|
|
522
|
+
if (payloadSizePolicy === "truncate") {
|
|
523
|
+
const truncatedPayload = truncatePayload(payload, payloadTruncateStringLength);
|
|
524
|
+
if (truncatedPayload && payloadByteLength(truncatedPayload) <= maxPayloadBytes) {
|
|
525
|
+
return { ok: true, payload: truncatedPayload, truncated: true };
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
const messageId = getPayloadMessageId(payload);
|
|
529
|
+
return messageId === void 0 ? { ok: false, reason: "payload_too_large" } : { ok: false, reason: "payload_too_large", messageId };
|
|
530
|
+
}
|
|
531
|
+
|
|
107
532
|
// src/browser/core/delivery.ts
|
|
108
533
|
function createId(prefix) {
|
|
109
534
|
return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
@@ -119,8 +544,9 @@ function stableStringify(value) {
|
|
|
119
544
|
);
|
|
120
545
|
}
|
|
121
546
|
function createIdempotencyKey(payload, messageId) {
|
|
122
|
-
const
|
|
123
|
-
const
|
|
547
|
+
const metaData = payload.metaData;
|
|
548
|
+
const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? "event");
|
|
549
|
+
const properties = metaData ?? payload.properties;
|
|
124
550
|
const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;
|
|
125
551
|
if (orderId !== void 0) return `${event}:${String(orderId)}`;
|
|
126
552
|
return `${event}:${stableStringify(properties ?? {}) || messageId}`;
|
|
@@ -134,7 +560,6 @@ function createDeliveryManager(config) {
|
|
|
134
560
|
const lockTtlMs = config.lockTtlMs ?? 5e3;
|
|
135
561
|
const tabId = config.tabId ?? createId("tab");
|
|
136
562
|
const batchSize = config.batchSize ?? 25;
|
|
137
|
-
const maxPayloadBytes = config.maxPayloadBytes ?? 64e3;
|
|
138
563
|
function recordDrop(event) {
|
|
139
564
|
diagnostics.dropped.push(event);
|
|
140
565
|
config.onDrop?.(event);
|
|
@@ -143,12 +568,22 @@ function createDeliveryManager(config) {
|
|
|
143
568
|
diagnostics.lastError = error.message;
|
|
144
569
|
config.onError?.(error);
|
|
145
570
|
}
|
|
146
|
-
function
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
149
|
-
|
|
571
|
+
function preparePayloadForSend(payload) {
|
|
572
|
+
const sizePolicyOptions = {};
|
|
573
|
+
if (config.maxPayloadBytes !== void 0) sizePolicyOptions.maxPayloadBytes = config.maxPayloadBytes;
|
|
574
|
+
if (config.payloadSizePolicy !== void 0) sizePolicyOptions.payloadSizePolicy = config.payloadSizePolicy;
|
|
575
|
+
if (config.payloadTruncateStringLength !== void 0) {
|
|
576
|
+
sizePolicyOptions.payloadTruncateStringLength = config.payloadTruncateStringLength;
|
|
150
577
|
}
|
|
151
|
-
|
|
578
|
+
const prepared = preparePayloadForSizePolicy(payload, sizePolicyOptions);
|
|
579
|
+
if (prepared.ok) return prepared.payload;
|
|
580
|
+
const diagnostic = {
|
|
581
|
+
reason: prepared.reason,
|
|
582
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
583
|
+
};
|
|
584
|
+
if (prepared.messageId !== void 0) diagnostic.messageId = prepared.messageId;
|
|
585
|
+
recordDrop(diagnostic);
|
|
586
|
+
return void 0;
|
|
152
587
|
}
|
|
153
588
|
function recordStorageUnavailable() {
|
|
154
589
|
recordDrop({
|
|
@@ -221,14 +656,36 @@ function createDeliveryManager(config) {
|
|
|
221
656
|
persistQueue();
|
|
222
657
|
}
|
|
223
658
|
function withEnvelope(payload) {
|
|
224
|
-
const
|
|
659
|
+
const metaData = payload.metaData;
|
|
660
|
+
const messageId = String(metaData?.requestId ?? payload.messageId ?? createId("msg"));
|
|
661
|
+
if (metaData) {
|
|
662
|
+
return {
|
|
663
|
+
...payload,
|
|
664
|
+
metaData: {
|
|
665
|
+
...metaData,
|
|
666
|
+
requestId: messageId
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
}
|
|
225
670
|
return {
|
|
226
671
|
...payload,
|
|
227
672
|
messageId,
|
|
228
673
|
idempotencyKey: String(payload.idempotencyKey ?? createIdempotencyKey(payload, messageId))
|
|
229
674
|
};
|
|
230
675
|
}
|
|
676
|
+
function tryBeacon(body) {
|
|
677
|
+
if (!config.useBeacon) return false;
|
|
678
|
+
const sendBeacon = globalThis.navigator?.sendBeacon;
|
|
679
|
+
if (typeof sendBeacon !== "function") return false;
|
|
680
|
+
try {
|
|
681
|
+
const blob = new Blob([JSON.stringify(body)], { type: "application/json" });
|
|
682
|
+
return sendBeacon.call(globalThis.navigator, config.endpoint, blob);
|
|
683
|
+
} catch {
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
231
687
|
async function deliver(body) {
|
|
688
|
+
if (tryBeacon(body)) return;
|
|
232
689
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
233
690
|
if (typeof fetchImpl !== "function") {
|
|
234
691
|
throw new Error("fetch_unavailable");
|
|
@@ -245,26 +702,22 @@ function createDeliveryManager(config) {
|
|
|
245
702
|
return {
|
|
246
703
|
async send(payload) {
|
|
247
704
|
const body = withEnvelope(payload);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
messageId: String(body.messageId),
|
|
251
|
-
reason: "payload_too_large",
|
|
252
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
253
|
-
});
|
|
705
|
+
const preparedBody = preparePayloadForSend(body);
|
|
706
|
+
if (!preparedBody) {
|
|
254
707
|
return;
|
|
255
708
|
}
|
|
256
709
|
diagnostics.inFlight += 1;
|
|
257
710
|
try {
|
|
258
|
-
await deliver(
|
|
711
|
+
await deliver(preparedBody);
|
|
259
712
|
} catch (error) {
|
|
260
713
|
const deliveryError = error instanceof Error ? error : new Error(String(error));
|
|
261
714
|
recordError(deliveryError);
|
|
262
715
|
enqueue({
|
|
263
|
-
messageId: String(body
|
|
716
|
+
messageId: String(getPayloadMessageId(body)),
|
|
264
717
|
savedAt: Date.now(),
|
|
265
718
|
attempts: 1,
|
|
266
719
|
lastError: deliveryError.message,
|
|
267
|
-
payload:
|
|
720
|
+
payload: preparedBody
|
|
268
721
|
});
|
|
269
722
|
} finally {
|
|
270
723
|
diagnostics.inFlight -= 1;
|
|
@@ -377,71 +830,277 @@ function createDeliveryManager(config) {
|
|
|
377
830
|
};
|
|
378
831
|
}
|
|
379
832
|
|
|
380
|
-
// src/browser/core/
|
|
381
|
-
var
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
"name",
|
|
391
|
-
"token",
|
|
392
|
-
"secret",
|
|
393
|
-
"password",
|
|
394
|
-
"session",
|
|
395
|
-
"cookie"
|
|
396
|
-
]);
|
|
397
|
-
function sanitizeValue(value, allow) {
|
|
398
|
-
if (Array.isArray(value)) {
|
|
399
|
-
return value.map((item) => sanitizeValue(item, allow));
|
|
833
|
+
// src/browser/core/identity.ts
|
|
834
|
+
var ANONYMOUS_ID_STORAGE_KEY = "dmd_anonymous_id";
|
|
835
|
+
var LEGACY_ANONYMOUS_ID_STORAGE_KEY = "anonymousId";
|
|
836
|
+
function getUrlParam(name) {
|
|
837
|
+
const href = getBrowserWindow()?.location?.href;
|
|
838
|
+
if (!href) return null;
|
|
839
|
+
try {
|
|
840
|
+
return new URL(href).searchParams.get(name);
|
|
841
|
+
} catch {
|
|
842
|
+
return null;
|
|
400
843
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
844
|
+
}
|
|
845
|
+
function resolveAnonymousId(persistence) {
|
|
846
|
+
const urlAnonymousId = getUrlParam("aid");
|
|
847
|
+
if (isUuid(urlAnonymousId)) {
|
|
848
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, urlAnonymousId);
|
|
849
|
+
return urlAnonymousId;
|
|
850
|
+
}
|
|
851
|
+
const storedAnonymousId = persistence.getItem(ANONYMOUS_ID_STORAGE_KEY);
|
|
852
|
+
if (isUuid(storedAnonymousId)) {
|
|
853
|
+
return storedAnonymousId;
|
|
854
|
+
}
|
|
855
|
+
const legacyAnonymousId = persistence.getItem(LEGACY_ANONYMOUS_ID_STORAGE_KEY);
|
|
856
|
+
if (isUuid(legacyAnonymousId)) {
|
|
857
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, legacyAnonymousId);
|
|
858
|
+
return legacyAnonymousId;
|
|
859
|
+
}
|
|
860
|
+
const anonymousId = createUuid();
|
|
861
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, anonymousId);
|
|
862
|
+
return anonymousId;
|
|
863
|
+
}
|
|
864
|
+
function resetAnonymousId(persistence) {
|
|
865
|
+
const anonymousId = createUuid();
|
|
866
|
+
persistence.setItem(ANONYMOUS_ID_STORAGE_KEY, anonymousId);
|
|
867
|
+
return anonymousId;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// src/browser/core/persistence.ts
|
|
871
|
+
function createPersistenceHealth(requested) {
|
|
872
|
+
return {
|
|
873
|
+
requested,
|
|
874
|
+
cookieFallbackUsed: false,
|
|
875
|
+
memoryFallbackUsed: requested === "memory",
|
|
876
|
+
failures: []
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
function recordFailure(health, backend, operation, error) {
|
|
880
|
+
health.failures.push({
|
|
881
|
+
backend,
|
|
882
|
+
operation,
|
|
883
|
+
message: error instanceof Error ? error.message : String(error)
|
|
884
|
+
});
|
|
885
|
+
if (health.failures.length > 25) {
|
|
886
|
+
health.failures.shift();
|
|
405
887
|
}
|
|
406
|
-
return value;
|
|
407
888
|
}
|
|
408
|
-
function
|
|
409
|
-
const
|
|
410
|
-
return
|
|
889
|
+
function createMemoryPersistence(health = createPersistenceHealth("memory")) {
|
|
890
|
+
const memory = {};
|
|
891
|
+
return {
|
|
892
|
+
getItem(key) {
|
|
893
|
+
return Object.prototype.hasOwnProperty.call(memory, key) ? memory[key] ?? null : null;
|
|
894
|
+
},
|
|
895
|
+
setItem(key, value) {
|
|
896
|
+
memory[key] = value;
|
|
897
|
+
return true;
|
|
898
|
+
},
|
|
899
|
+
removeItem(key) {
|
|
900
|
+
delete memory[key];
|
|
901
|
+
},
|
|
902
|
+
getHealth() {
|
|
903
|
+
return {
|
|
904
|
+
...health,
|
|
905
|
+
failures: health.failures.map((failure) => ({ ...failure }))
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
function getCookie2(name) {
|
|
911
|
+
const browserWindow = getBrowserWindow();
|
|
912
|
+
const cookie = browserWindow?.document?.cookie;
|
|
913
|
+
if (!cookie) return null;
|
|
914
|
+
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
915
|
+
const match = new RegExp(`(?:^|; )${escapedName}=([^;]*)`).exec(cookie);
|
|
916
|
+
return match ? decodeURIComponent(match[1] ?? "") : null;
|
|
917
|
+
}
|
|
918
|
+
function setCookie(name, value) {
|
|
919
|
+
const browserWindow = getBrowserWindow();
|
|
920
|
+
if (!browserWindow?.document) return false;
|
|
921
|
+
try {
|
|
922
|
+
const expires = new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toUTCString();
|
|
923
|
+
const secure = browserWindow.location?.protocol === "https:" ? "; Secure" : "";
|
|
924
|
+
browserWindow.document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/${secure}; SameSite=Lax`;
|
|
925
|
+
return true;
|
|
926
|
+
} catch {
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
function removeCookie(name) {
|
|
931
|
+
const browserWindow = getBrowserWindow();
|
|
932
|
+
if (!browserWindow?.document) return;
|
|
933
|
+
browserWindow.document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
|
|
934
|
+
}
|
|
935
|
+
function getLocalStorage() {
|
|
936
|
+
const browserWindow = getBrowserWindow();
|
|
937
|
+
try {
|
|
938
|
+
return browserWindow?.localStorage;
|
|
939
|
+
} catch {
|
|
940
|
+
return void 0;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
function getSessionStorage() {
|
|
944
|
+
const browserWindow = getBrowserWindow();
|
|
945
|
+
try {
|
|
946
|
+
return browserWindow?.sessionStorage;
|
|
947
|
+
} catch {
|
|
948
|
+
return void 0;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
952
|
+
const health = createPersistenceHealth(mode);
|
|
953
|
+
const memory = createMemoryPersistence(health);
|
|
954
|
+
if (mode === "none") {
|
|
955
|
+
return {
|
|
956
|
+
getItem() {
|
|
957
|
+
return null;
|
|
958
|
+
},
|
|
959
|
+
setItem() {
|
|
960
|
+
return false;
|
|
961
|
+
},
|
|
962
|
+
removeItem() {
|
|
963
|
+
},
|
|
964
|
+
getHealth() {
|
|
965
|
+
return {
|
|
966
|
+
...health,
|
|
967
|
+
failures: health.failures.map((failure) => ({ ...failure }))
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
if (mode === "memory") return memory;
|
|
973
|
+
const primary = mode === "sessionStorage" ? getSessionStorage() : getLocalStorage();
|
|
974
|
+
const useCookie = mode === "cookie" || mode === "localStorage+cookie" || !primary;
|
|
975
|
+
return {
|
|
976
|
+
getItem(key) {
|
|
977
|
+
try {
|
|
978
|
+
const stored = primary?.getItem(key);
|
|
979
|
+
if (stored) return stored;
|
|
980
|
+
} catch (error) {
|
|
981
|
+
recordFailure(health, mode === "sessionStorage" ? "sessionStorage" : "localStorage", "get", error);
|
|
982
|
+
}
|
|
983
|
+
if (useCookie) {
|
|
984
|
+
const cookie = getCookie2(key);
|
|
985
|
+
if (cookie) {
|
|
986
|
+
health.cookieFallbackUsed = true;
|
|
987
|
+
return cookie;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
const value = memory.getItem(key);
|
|
991
|
+
if (value !== null) health.memoryFallbackUsed = true;
|
|
992
|
+
return value;
|
|
993
|
+
},
|
|
994
|
+
setItem(key, value) {
|
|
995
|
+
let wrote = false;
|
|
996
|
+
try {
|
|
997
|
+
primary?.setItem(key, value);
|
|
998
|
+
wrote = primary !== void 0;
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
recordFailure(health, mode === "sessionStorage" ? "sessionStorage" : "localStorage", "set", error);
|
|
1001
|
+
wrote = false;
|
|
1002
|
+
}
|
|
1003
|
+
if (useCookie) {
|
|
1004
|
+
const cookieWrote = setCookie(key, value);
|
|
1005
|
+
if (cookieWrote) health.cookieFallbackUsed = true;
|
|
1006
|
+
wrote = cookieWrote || wrote;
|
|
1007
|
+
}
|
|
1008
|
+
if (!wrote) {
|
|
1009
|
+
health.memoryFallbackUsed = true;
|
|
1010
|
+
return memory.setItem(key, value);
|
|
1011
|
+
}
|
|
1012
|
+
if (mode === "localStorage+cookie") {
|
|
1013
|
+
memory.setItem(key, value);
|
|
1014
|
+
}
|
|
1015
|
+
return true;
|
|
1016
|
+
},
|
|
1017
|
+
removeItem(key) {
|
|
1018
|
+
try {
|
|
1019
|
+
primary?.removeItem(key);
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
recordFailure(health, mode === "sessionStorage" ? "sessionStorage" : "localStorage", "remove", error);
|
|
1022
|
+
}
|
|
1023
|
+
if (useCookie) removeCookie(key);
|
|
1024
|
+
memory.removeItem(key);
|
|
1025
|
+
},
|
|
1026
|
+
getHealth() {
|
|
1027
|
+
return {
|
|
1028
|
+
...health,
|
|
1029
|
+
failures: health.failures.map((failure) => ({ ...failure }))
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
411
1033
|
}
|
|
412
1034
|
|
|
413
|
-
// src/browser/core/
|
|
414
|
-
var
|
|
415
|
-
function
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
1035
|
+
// src/browser/core/session.ts
|
|
1036
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
1037
|
+
function getUrlParam2(name) {
|
|
1038
|
+
const href = getBrowserWindow()?.location?.href;
|
|
1039
|
+
if (!href) return null;
|
|
1040
|
+
try {
|
|
1041
|
+
return new URL(href).searchParams.get(name);
|
|
1042
|
+
} catch {
|
|
1043
|
+
return null;
|
|
421
1044
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
1045
|
+
}
|
|
1046
|
+
function readStoredSession(persistence) {
|
|
1047
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY);
|
|
1048
|
+
if (!rawSession) return void 0;
|
|
1049
|
+
try {
|
|
1050
|
+
const parsed = JSON.parse(rawSession);
|
|
1051
|
+
if (isUuid(parsed.sessionId) && typeof parsed.timestamp === "number") {
|
|
1052
|
+
return {
|
|
1053
|
+
sessionId: parsed.sessionId,
|
|
1054
|
+
timestamp: parsed.timestamp
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
} catch {
|
|
1058
|
+
persistence.removeItem(SESSION_STORAGE_KEY);
|
|
426
1059
|
}
|
|
427
|
-
return
|
|
1060
|
+
return void 0;
|
|
1061
|
+
}
|
|
1062
|
+
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1063
|
+
persistence.setItem(SESSION_STORAGE_KEY, JSON.stringify({ sessionId, timestamp }));
|
|
1064
|
+
}
|
|
1065
|
+
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1066
|
+
function resolveSessionId() {
|
|
1067
|
+
const now = Date.now();
|
|
1068
|
+
const urlSessionId = getUrlParam2("sid") ?? getUrlParam2("session_id");
|
|
1069
|
+
if (isUuid(urlSessionId)) {
|
|
1070
|
+
writeStoredSession(persistence, urlSessionId, now);
|
|
1071
|
+
return urlSessionId;
|
|
1072
|
+
}
|
|
1073
|
+
const storedSession = readStoredSession(persistence);
|
|
1074
|
+
if (storedSession && now - storedSession.timestamp <= idleTimeoutSeconds * 1e3) {
|
|
1075
|
+
writeStoredSession(persistence, storedSession.sessionId, now);
|
|
1076
|
+
return storedSession.sessionId;
|
|
1077
|
+
}
|
|
1078
|
+
const sessionId = createUuid();
|
|
1079
|
+
writeStoredSession(persistence, sessionId, now);
|
|
1080
|
+
return sessionId;
|
|
1081
|
+
}
|
|
1082
|
+
return {
|
|
1083
|
+
getSessionId() {
|
|
1084
|
+
return resolveSessionId();
|
|
1085
|
+
},
|
|
1086
|
+
reset() {
|
|
1087
|
+
const sessionId = createUuid();
|
|
1088
|
+
writeStoredSession(persistence, sessionId, Date.now());
|
|
1089
|
+
return sessionId;
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
428
1092
|
}
|
|
429
1093
|
|
|
430
1094
|
// src/browser/core/DriveMetaDataSDK.ts
|
|
431
|
-
function createId2(prefix) {
|
|
432
|
-
return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
433
|
-
}
|
|
434
1095
|
function endpointFromConfig(config) {
|
|
435
1096
|
const host = config.apiHost ?? "https://sdk.drivemetadata.com/v2";
|
|
436
1097
|
return `${host.replace(/\/$/, "")}/data-collector`;
|
|
437
1098
|
}
|
|
438
|
-
function
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return browserWindow?.localStorage;
|
|
442
|
-
} catch {
|
|
443
|
-
return void 0;
|
|
1099
|
+
function requireConfigString(value, field) {
|
|
1100
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
1101
|
+
throw new Error(`DMD SDK config ${field} is required`);
|
|
444
1102
|
}
|
|
1103
|
+
return value;
|
|
445
1104
|
}
|
|
446
1105
|
var DriveMetaDataSDK = class {
|
|
447
1106
|
constructor(config) {
|
|
@@ -449,31 +1108,41 @@ var DriveMetaDataSDK = class {
|
|
|
449
1108
|
this.queue = [];
|
|
450
1109
|
this.offline = false;
|
|
451
1110
|
this.droppedEvents = 0;
|
|
1111
|
+
requireConfigString(config.clientId, "clientId");
|
|
1112
|
+
requireConfigString(config.workspaceId, "workspaceId");
|
|
1113
|
+
requireConfigString(config.appId, "appId");
|
|
1114
|
+
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
452
1115
|
this.config = config;
|
|
453
1116
|
this.endpoint = endpointFromConfig(config);
|
|
454
|
-
|
|
1117
|
+
this.persistence = createBrowserPersistence(config.persistence);
|
|
1118
|
+
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
455
1119
|
const deliveryConfig = {
|
|
456
|
-
endpoint: this.endpoint
|
|
1120
|
+
endpoint: this.endpoint,
|
|
1121
|
+
storage: this.persistence
|
|
457
1122
|
};
|
|
458
1123
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
459
1124
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
460
1125
|
if (config.delivery?.retryDelayMs !== void 0) deliveryConfig.retryDelayMs = config.delivery.retryDelayMs;
|
|
461
1126
|
if (config.delivery?.maxRetryDelayMs !== void 0) deliveryConfig.maxRetryDelayMs = config.delivery.maxRetryDelayMs;
|
|
462
1127
|
if (config.delivery?.maxPayloadBytes !== void 0) deliveryConfig.maxPayloadBytes = config.delivery.maxPayloadBytes;
|
|
1128
|
+
if (config.delivery?.payloadSizePolicy !== void 0) deliveryConfig.payloadSizePolicy = config.delivery.payloadSizePolicy;
|
|
1129
|
+
if (config.delivery?.payloadTruncateStringLength !== void 0) {
|
|
1130
|
+
deliveryConfig.payloadTruncateStringLength = config.delivery.payloadTruncateStringLength;
|
|
1131
|
+
}
|
|
1132
|
+
if (config.delivery?.useBeacon !== void 0) deliveryConfig.useBeacon = config.delivery.useBeacon;
|
|
463
1133
|
if (config.delivery?.batchSize !== void 0) deliveryConfig.batchSize = config.delivery.batchSize;
|
|
464
1134
|
if (config.onDrop !== void 0) deliveryConfig.onDrop = config.onDrop;
|
|
465
1135
|
if (config.onError !== void 0) deliveryConfig.onError = config.onError;
|
|
466
|
-
this.delivery = createDeliveryManager(
|
|
467
|
-
...deliveryConfig,
|
|
468
|
-
storage
|
|
469
|
-
} : deliveryConfig);
|
|
1136
|
+
this.delivery = createDeliveryManager(deliveryConfig);
|
|
470
1137
|
this.initialRetryDelayMs = config.delivery?.retryDelayMs ?? 1e3;
|
|
471
1138
|
this.retryDelayMs = this.initialRetryDelayMs;
|
|
472
1139
|
this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 3e4;
|
|
473
1140
|
this.writeKey = config.writeKey || config.token || "";
|
|
474
|
-
this.identity = { anonymousId:
|
|
1141
|
+
this.identity = { anonymousId: resolveAnonymousId(this.persistence) };
|
|
1142
|
+
captureAttributionFromUrl(this.persistence);
|
|
475
1143
|
this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);
|
|
476
1144
|
this.gdprConsent = this.consentState.analytics;
|
|
1145
|
+
this.installAutocapture();
|
|
477
1146
|
if (!config.delivery?.disableLifecycleFlush) {
|
|
478
1147
|
this.installLifecycleFlush();
|
|
479
1148
|
}
|
|
@@ -513,7 +1182,8 @@ var DriveMetaDataSDK = class {
|
|
|
513
1182
|
}
|
|
514
1183
|
}
|
|
515
1184
|
reset() {
|
|
516
|
-
this.identity = { anonymousId:
|
|
1185
|
+
this.identity = { anonymousId: resetAnonymousId(this.persistence) };
|
|
1186
|
+
this.session.reset();
|
|
517
1187
|
this.queue = [];
|
|
518
1188
|
this.offline = false;
|
|
519
1189
|
if (this.retryTimer !== void 0) {
|
|
@@ -522,8 +1192,20 @@ var DriveMetaDataSDK = class {
|
|
|
522
1192
|
}
|
|
523
1193
|
this.lifecycleCleanup?.();
|
|
524
1194
|
this.lifecycleCleanup = void 0;
|
|
1195
|
+
this.autocaptureCleanup?.();
|
|
1196
|
+
this.autocaptureCleanup = void 0;
|
|
525
1197
|
this.delivery.clearQueue("manual_clear");
|
|
526
1198
|
}
|
|
1199
|
+
disposeForTests() {
|
|
1200
|
+
if (this.retryTimer !== void 0) {
|
|
1201
|
+
clearTimeout(this.retryTimer);
|
|
1202
|
+
this.retryTimer = void 0;
|
|
1203
|
+
}
|
|
1204
|
+
this.lifecycleCleanup?.();
|
|
1205
|
+
this.lifecycleCleanup = void 0;
|
|
1206
|
+
this.autocaptureCleanup?.();
|
|
1207
|
+
this.autocaptureCleanup = void 0;
|
|
1208
|
+
}
|
|
527
1209
|
setConsent(consent) {
|
|
528
1210
|
this.consentState = typeof consent === "object" ? mergeConsent(this.consentState, consent) : normalizeConsent(consent);
|
|
529
1211
|
this.gdprConsent = this.consentState.analytics;
|
|
@@ -538,6 +1220,7 @@ var DriveMetaDataSDK = class {
|
|
|
538
1220
|
initialized: this.initialized,
|
|
539
1221
|
consent: this.gdprConsent,
|
|
540
1222
|
consentPurposes: this.consentState,
|
|
1223
|
+
persistence: this.persistence.getHealth(),
|
|
541
1224
|
queueSize: deliveryDiagnostics.queued,
|
|
542
1225
|
offline: this.offline || deliveryDiagnostics.queued > 0,
|
|
543
1226
|
droppedEvents: this.droppedEvents + deliveryDiagnostics.dropped.length,
|
|
@@ -552,7 +1235,9 @@ var DriveMetaDataSDK = class {
|
|
|
552
1235
|
void this.delivery.send(payload).then(() => {
|
|
553
1236
|
const diagnostics = this.delivery.getDiagnostics();
|
|
554
1237
|
this.offline = diagnostics.queued > 0;
|
|
555
|
-
|
|
1238
|
+
if (diagnostics.lastError !== void 0) {
|
|
1239
|
+
this.lastError = diagnostics.lastError;
|
|
1240
|
+
}
|
|
556
1241
|
if (diagnostics.queued > 0) {
|
|
557
1242
|
this.scheduleRetryFlush();
|
|
558
1243
|
}
|
|
@@ -584,6 +1269,28 @@ var DriveMetaDataSDK = class {
|
|
|
584
1269
|
}
|
|
585
1270
|
};
|
|
586
1271
|
}
|
|
1272
|
+
installAutocapture() {
|
|
1273
|
+
const browserWindow = getBrowserWindow();
|
|
1274
|
+
if (!browserWindow) return;
|
|
1275
|
+
if (this.config.autocapture === false) return;
|
|
1276
|
+
const capturePageview = this.config.capturePageview !== false;
|
|
1277
|
+
const capturePageleave = this.config.capturePageleave !== false;
|
|
1278
|
+
const controller = installAutocapture({
|
|
1279
|
+
browserWindow,
|
|
1280
|
+
capturePageview,
|
|
1281
|
+
capturePageleave,
|
|
1282
|
+
onPageView: () => {
|
|
1283
|
+
this.page();
|
|
1284
|
+
},
|
|
1285
|
+
onPageLeave: () => {
|
|
1286
|
+
this.trackEvent("page_leave", { url: browserWindow.location.href });
|
|
1287
|
+
},
|
|
1288
|
+
onRouteChange: () => {
|
|
1289
|
+
captureAttributionFromUrl(this.persistence);
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
this.autocaptureCleanup = controller.cleanup;
|
|
1293
|
+
}
|
|
587
1294
|
scheduleRetryFlush() {
|
|
588
1295
|
if (this.retryTimer !== void 0) return;
|
|
589
1296
|
const delay = Math.min(this.retryDelayMs, this.maxRetryDelayMs);
|
|
@@ -609,7 +1316,7 @@ var DriveMetaDataSDK = class {
|
|
|
609
1316
|
type,
|
|
610
1317
|
event,
|
|
611
1318
|
properties: sanitizeProperties(properties),
|
|
612
|
-
messageId: options.messageId
|
|
1319
|
+
messageId: ensureUuid(options.messageId),
|
|
613
1320
|
timestamp: options.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
614
1321
|
context: options.context ?? {},
|
|
615
1322
|
anonymousId: this.identity.anonymousId,
|
|
@@ -617,7 +1324,8 @@ var DriveMetaDataSDK = class {
|
|
|
617
1324
|
workspaceId: this.config.workspaceId,
|
|
618
1325
|
appId: this.config.appId,
|
|
619
1326
|
writeKey: this.writeKey,
|
|
620
|
-
consent: this.consentState
|
|
1327
|
+
consent: this.consentState,
|
|
1328
|
+
sessionId: this.session.getSessionId()
|
|
621
1329
|
};
|
|
622
1330
|
if (this.identity.userId !== void 0) prepared.userId = this.identity.userId;
|
|
623
1331
|
if (this.identity.groupId !== void 0) prepared.groupId = this.identity.groupId;
|
|
@@ -641,7 +1349,41 @@ var DriveMetaDataSDK = class {
|
|
|
641
1349
|
if (!validation.ok) {
|
|
642
1350
|
this.lastError = `DMD SDK schema warning: ${validation.errors.join(", ")}`;
|
|
643
1351
|
}
|
|
644
|
-
this.
|
|
1352
|
+
const collectorPayload = this.toCollectorPayload(prepared);
|
|
1353
|
+
const backendValidation = validateBackendCollectorPayload(collectorPayload);
|
|
1354
|
+
if (!backendValidation.ok && this.config.schemaValidation === "strict") {
|
|
1355
|
+
this.lastError = `DMD SDK backend schema warning: ${backendValidation.errors.join(", ")}`;
|
|
1356
|
+
this.recordDrop(type, "invalid_payload", event);
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
if (!backendValidation.ok) {
|
|
1360
|
+
this.lastError = `DMD SDK backend schema warning: ${backendValidation.errors.join(", ")}`;
|
|
1361
|
+
}
|
|
1362
|
+
this.sendEvent(collectorPayload);
|
|
1363
|
+
}
|
|
1364
|
+
toCollectorPayload(prepared) {
|
|
1365
|
+
const browserWindow = getBrowserWindow();
|
|
1366
|
+
return createBackendCollectorPayload({
|
|
1367
|
+
requestId: prepared.messageId,
|
|
1368
|
+
timestamp: prepared.timestamp,
|
|
1369
|
+
eventType: prepared.event,
|
|
1370
|
+
clientId: prepared.clientId,
|
|
1371
|
+
workspaceId: prepared.workspaceId,
|
|
1372
|
+
token: prepared.writeKey,
|
|
1373
|
+
anonymousId: prepared.anonymousId,
|
|
1374
|
+
sessionId: prepared.sessionId,
|
|
1375
|
+
ua: browserWindow?.navigator?.userAgent,
|
|
1376
|
+
appId: prepared.appId,
|
|
1377
|
+
pageUrl: browserWindow?.location?.href,
|
|
1378
|
+
eventData: mergeStoredAttribution({
|
|
1379
|
+
...prepared.properties,
|
|
1380
|
+
anonymousId: prepared.anonymousId,
|
|
1381
|
+
sessionId: prepared.sessionId,
|
|
1382
|
+
timestamp: prepared.timestamp,
|
|
1383
|
+
requestSentAt: prepared.timestamp,
|
|
1384
|
+
requestReceivedAt: prepared.timestamp
|
|
1385
|
+
}, this.persistence)
|
|
1386
|
+
});
|
|
645
1387
|
}
|
|
646
1388
|
recordDrop(type, reason, event) {
|
|
647
1389
|
this.droppedEvents += 1;
|
|
@@ -655,22 +1397,6 @@ var DriveMetaDataSDK = class {
|
|
|
655
1397
|
}
|
|
656
1398
|
};
|
|
657
1399
|
|
|
658
|
-
// src/browser/legacy-loader.ts
|
|
659
|
-
function getLegacySdkInstanceFromWindow() {
|
|
660
|
-
const browserWindow = getBrowserWindow();
|
|
661
|
-
return browserWindow?.__DriveMetaDataSDKInstance;
|
|
662
|
-
}
|
|
663
|
-
function ensureLegacySdkLoaded() {
|
|
664
|
-
if (!isBrowserRuntime()) {
|
|
665
|
-
throw new Error("DMD legacy SDK is only available in a browser runtime");
|
|
666
|
-
}
|
|
667
|
-
const browserWindow = getBrowserWindow();
|
|
668
|
-
if (!browserWindow?.DriveMetaDataSDK) {
|
|
669
|
-
throw new Error("DMD legacy SDK constructor is missing from window.DriveMetaDataSDK");
|
|
670
|
-
}
|
|
671
|
-
return browserWindow.DriveMetaDataSDK;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
1400
|
// src/browser/client.ts
|
|
675
1401
|
var singleton;
|
|
676
1402
|
var publicSingleton;
|
|
@@ -679,56 +1405,34 @@ var lastError;
|
|
|
679
1405
|
var lastDroppedEvent;
|
|
680
1406
|
function createPublicClient(instance) {
|
|
681
1407
|
return {
|
|
682
|
-
__legacy: instance,
|
|
683
1408
|
track(event, properties, options) {
|
|
684
|
-
|
|
685
|
-
instance.trackEvent(event, properties, options);
|
|
686
|
-
return;
|
|
687
|
-
}
|
|
688
|
-
instance.sendEvent?.({ eventName: event, event, properties, options });
|
|
1409
|
+
instance.trackEvent(event, properties, options);
|
|
689
1410
|
},
|
|
690
1411
|
identify(userId, traits, options) {
|
|
691
|
-
|
|
692
|
-
instance.identify(userId, traits, options);
|
|
693
|
-
return;
|
|
694
|
-
}
|
|
695
|
-
instance.identifyUser?.(userId, traits);
|
|
1412
|
+
instance.identify(userId, traits, options);
|
|
696
1413
|
},
|
|
697
1414
|
page(name, properties, options) {
|
|
698
|
-
|
|
699
|
-
instance.page(name, properties, options);
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
instance.trackPageview?.();
|
|
1415
|
+
instance.page(name, properties, options);
|
|
703
1416
|
},
|
|
704
1417
|
group(groupId, traits, options) {
|
|
705
|
-
instance.group
|
|
1418
|
+
instance.group(groupId, traits, options);
|
|
706
1419
|
},
|
|
707
1420
|
alias(previousId, userId, options) {
|
|
708
|
-
instance.alias
|
|
1421
|
+
instance.alias(previousId, userId, options);
|
|
709
1422
|
},
|
|
710
1423
|
async flush() {
|
|
711
|
-
await instance.flush
|
|
1424
|
+
await instance.flush();
|
|
712
1425
|
},
|
|
713
1426
|
reset() {
|
|
714
|
-
instance.reset
|
|
1427
|
+
instance.reset();
|
|
715
1428
|
singleton = void 0;
|
|
716
1429
|
publicSingleton = void 0;
|
|
717
1430
|
},
|
|
718
1431
|
setConsent(consent) {
|
|
719
|
-
|
|
720
|
-
instance.setConsent(consent);
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
if (typeof consent === "string") {
|
|
724
|
-
instance.gdprConsent = consent;
|
|
725
|
-
}
|
|
1432
|
+
instance.setConsent(consent);
|
|
726
1433
|
},
|
|
727
1434
|
getHealth() {
|
|
728
|
-
|
|
729
|
-
return instance.getHealth();
|
|
730
|
-
}
|
|
731
|
-
return getDmdHealth();
|
|
1435
|
+
return instance.getHealth();
|
|
732
1436
|
}
|
|
733
1437
|
};
|
|
734
1438
|
}
|
|
@@ -753,23 +1457,8 @@ function initDmdSDK(config) {
|
|
|
753
1457
|
if (publicSingleton) {
|
|
754
1458
|
return publicSingleton;
|
|
755
1459
|
}
|
|
756
|
-
const legacyConfig = normalizeBrowserConfig(config);
|
|
757
|
-
const existingInstance = getLegacySdkInstanceFromWindow();
|
|
758
|
-
if (existingInstance) {
|
|
759
|
-
return setSingleton(existingInstance);
|
|
760
|
-
}
|
|
761
1460
|
try {
|
|
762
|
-
|
|
763
|
-
try {
|
|
764
|
-
const LegacySdk = ensureLegacySdkLoaded();
|
|
765
|
-
instance = new LegacySdk(legacyConfig);
|
|
766
|
-
} catch (error) {
|
|
767
|
-
if (error instanceof Error && error.message.includes("constructor is missing")) {
|
|
768
|
-
instance = new DriveMetaDataSDK(config);
|
|
769
|
-
} else {
|
|
770
|
-
throw error;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
1461
|
+
const instance = new DriveMetaDataSDK(normalizeBrowserConfig(config));
|
|
773
1462
|
return setSingleton(instance);
|
|
774
1463
|
} catch (error) {
|
|
775
1464
|
lastError = error instanceof Error ? error.message : String(error);
|
|
@@ -836,14 +1525,14 @@ function setConsent(consent) {
|
|
|
836
1525
|
getDmdSDK()?.setConsent(consent);
|
|
837
1526
|
}
|
|
838
1527
|
function getDmdHealth() {
|
|
839
|
-
if (singleton
|
|
1528
|
+
if (singleton) {
|
|
840
1529
|
return singleton.getHealth();
|
|
841
1530
|
}
|
|
842
1531
|
const health = {
|
|
843
|
-
initialized:
|
|
844
|
-
consent:
|
|
845
|
-
queueSize:
|
|
846
|
-
offline:
|
|
1532
|
+
initialized: false,
|
|
1533
|
+
consent: "pending",
|
|
1534
|
+
queueSize: 0,
|
|
1535
|
+
offline: false,
|
|
847
1536
|
droppedEvents
|
|
848
1537
|
};
|
|
849
1538
|
if (lastError !== void 0) {
|