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