@drivemetadata-ai/sdk 0.1.1-beta.1 → 0.1.1-beta.2

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.
Files changed (42) hide show
  1. package/README.md +18 -15
  2. package/dist/angular/index.cjs +118 -115
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.d.cts +2 -2
  5. package/dist/angular/index.d.ts +2 -2
  6. package/dist/angular/index.js +118 -115
  7. package/dist/angular/index.js.map +1 -1
  8. package/dist/browser/index.cjs +119 -116
  9. package/dist/browser/index.cjs.map +1 -1
  10. package/dist/browser/index.d.cts +5 -68
  11. package/dist/browser/index.d.ts +5 -68
  12. package/dist/browser/index.js +119 -116
  13. package/dist/browser/index.js.map +1 -1
  14. package/dist/next/index.cjs +119 -115
  15. package/dist/next/index.cjs.map +1 -1
  16. package/dist/next/index.d.cts +1 -1
  17. package/dist/next/index.d.ts +1 -1
  18. package/dist/next/index.js +119 -115
  19. package/dist/next/index.js.map +1 -1
  20. package/dist/node/index.cjs +80 -7
  21. package/dist/node/index.cjs.map +1 -1
  22. package/dist/node/index.d.cts +7 -1
  23. package/dist/node/index.d.ts +7 -1
  24. package/dist/node/index.js +80 -7
  25. package/dist/node/index.js.map +1 -1
  26. package/dist/react/index.cjs +119 -115
  27. package/dist/react/index.cjs.map +1 -1
  28. package/dist/react/index.d.cts +2 -2
  29. package/dist/react/index.d.ts +2 -2
  30. package/dist/react/index.js +119 -115
  31. package/dist/react/index.js.map +1 -1
  32. package/dist/{types-BwtS0ZDu.d.cts → types--V8TVIqT.d.cts} +7 -3
  33. package/dist/{types-BwtS0ZDu.d.ts → types--V8TVIqT.d.ts} +7 -3
  34. package/docs/angular-integration.md +6 -6
  35. package/docs/index.md +4 -6
  36. package/docs/integration.md +322 -0
  37. package/docs/node-server-integration.md +16 -7
  38. package/docs/npm-browser-sdk.md +4 -8
  39. package/docs/react-next-integration.md +9 -9
  40. package/docs/security-privacy.md +11 -11
  41. package/package.json +4 -5
  42. package/docs/migration-cdn-to-npm.md +0 -99
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/DmdProvider.tsx","../../src/core/config.ts","../../src/core/environment.ts","../../src/browser/core/consent.ts","../../src/browser/core/delivery.ts","../../src/browser/core/privacy.ts","../../src/browser/core/schema.ts","../../src/browser/core/DriveMetaDataSDK.ts","../../src/browser/legacy-loader.ts","../../src/browser/client.ts","../../src/next/useDmdAppRouterPageTracking.ts","../../src/next/useDmdPagesRouterPageTracking.ts","../../src/react/hooks.ts"],"sourcesContent":["import React from 'react';\nimport { getDmdSDK, initDmdSDK } from '../browser/client';\nimport type { DmdBrowserClient, DmdBrowserConfig } from '../core/types';\n\nexport const DmdContext = React.createContext<DmdBrowserClient | undefined>(undefined);\n\nexport interface DmdProviderProps {\n config: DmdBrowserConfig;\n children: React.ReactNode;\n enabled?: boolean;\n onReady?: (client: DmdBrowserClient) => void;\n onError?: (error: Error) => void;\n}\n\nexport function DmdProvider({\n config,\n children,\n enabled = true,\n onReady,\n onError\n}: DmdProviderProps) {\n const [client, setClient] = React.useState<DmdBrowserClient | undefined>(() => getDmdSDK());\n\n React.useEffect(() => {\n if (!enabled) return;\n\n try {\n const initializedClient = initDmdSDK(config);\n const configuredConsent = config.gdprConsent ?? config.consent;\n if (configuredConsent !== undefined) {\n initializedClient.setConsent(configuredConsent);\n }\n setClient(initializedClient);\n onReady?.(initializedClient);\n } catch (error) {\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n onError?.(normalizedError);\n }\n }, [\n enabled,\n config.clientId,\n config.workspaceId,\n config.appId,\n config.writeKey,\n config.apiHost,\n config.consent,\n config.gdprConsent,\n onReady,\n onError\n ]);\n\n return <DmdContext.Provider value={client}>{children}</DmdContext.Provider>;\n}\n","import type { DmdBrowserConfig, DmdLegacyConfig } from './types';\n\nfunction requireString(value: string | undefined, field: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`DMD SDK config ${field} is required`);\n }\n return value;\n}\n\nexport function normalizeBrowserConfig(config: DmdBrowserConfig): DmdLegacyConfig {\n const writeKey = config.writeKey || config.token;\n const legacyConfig: DmdLegacyConfig = {\n client_id: requireString(config.clientId, 'clientId'),\n workspace_id: requireString(config.workspaceId, 'workspaceId'),\n app_id: requireString(config.appId, 'appId'),\n token: requireString(writeKey, 'writeKey')\n };\n\n if (config.apiHost !== undefined) legacyConfig.api_host = config.apiHost;\n if (config.uiHost !== undefined) legacyConfig.ui_host = config.uiHost;\n if (config.deeplink !== undefined) legacyConfig.deeplink = config.deeplink;\n if (config.debug !== undefined) legacyConfig.debug = config.debug;\n if (config.consent !== undefined) legacyConfig.consent = config.consent;\n if (config.gdprConsent !== undefined) legacyConfig.gdprConsent = config.gdprConsent;\n if (config.autocapture !== undefined) legacyConfig.autocapture = config.autocapture;\n if (config.capturePageview !== undefined) legacyConfig.capture_pageview = config.capturePageview;\n if (config.capturePageleave !== undefined) legacyConfig.capture_pageleave = config.capturePageleave;\n if (config.captureDeadClicks !== undefined) legacyConfig.capture_dead_clicks = config.captureDeadClicks;\n if (config.crossSubdomainCookie !== undefined) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;\n if (config.disablePersistence !== undefined) legacyConfig.disable_persistence = config.disablePersistence;\n if (config.disableSurveys !== undefined) legacyConfig.disable_surveys = config.disableSurveys;\n if (config.disableSessionRecording !== undefined) legacyConfig.disable_session_recording = config.disableSessionRecording;\n if (config.enableHeatmaps !== undefined) legacyConfig.enable_heatmaps = config.enableHeatmaps;\n if (config.maskAllText !== undefined) legacyConfig.mask_all_text = config.maskAllText;\n if (config.maskAllElementAttributes !== undefined) {\n legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;\n }\n if (config.persistence !== undefined) legacyConfig.persistence = config.persistence;\n if (config.propertyDenylist !== undefined) legacyConfig.property_denylist = config.propertyDenylist;\n if (config.sessionIdleTimeoutSeconds !== undefined) {\n legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;\n }\n if (config.beforeSend !== undefined) legacyConfig.before_send = config.beforeSend;\n\n return legacyConfig;\n}\n","export function isBrowserRuntime(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function getBrowserWindow(): Window | undefined {\n return typeof window === 'undefined' ? undefined : window;\n}\n","import type {\n DmdConsentInput,\n DmdConsentPurpose,\n DmdConsentState,\n DmdPurposeConsent\n} from './types';\n\nexport type DmdResolvedConsent = Record<DmdConsentPurpose, DmdConsentState>;\n\nconst purposes: DmdConsentPurpose[] = [\n 'analytics',\n 'advertising',\n 'personalization',\n 'functional',\n 'saleOfData'\n];\n\nfunction normalizeConsentValue(value: unknown): DmdConsentState {\n if (value === true) return 'granted';\n if (value === false) return 'denied';\n if (value === 'granted' || value === 'denied' || value === 'pending') return value;\n return 'pending';\n}\n\nexport function normalizeConsent(input: DmdConsentInput | undefined): DmdResolvedConsent {\n const defaultValue = normalizeConsentValue(input ?? 'pending');\n const resolved = Object.fromEntries(\n purposes.map(purpose => [purpose, defaultValue])\n ) as DmdResolvedConsent;\n\n if (input && typeof input === 'object') {\n for (const purpose of purposes) {\n const value = input[purpose];\n if (value !== undefined) {\n resolved[purpose] = normalizeConsentValue(value);\n }\n }\n }\n\n return resolved;\n}\n\nexport function mergeConsent(current: DmdResolvedConsent, update: DmdPurposeConsent): DmdResolvedConsent {\n const next = { ...current };\n for (const [purpose, value] of Object.entries(update) as Array<[DmdConsentPurpose, DmdConsentState]>) {\n next[purpose] = normalizeConsentValue(value);\n }\n return next;\n}\n\nexport function canCollectPurpose(consent: DmdResolvedConsent, purpose: DmdConsentPurpose): boolean {\n return consent[purpose] === 'granted';\n}\n","export interface DmdQueuedRecord {\n messageId: string;\n savedAt: number;\n attempts: number;\n lastError?: string;\n payload: Record<string, unknown>;\n}\n\nexport interface DmdDeliveryDiagnostics {\n queued: number;\n inFlight: number;\n dropped: Array<{ messageId?: string; reason: string; timestamp: string }>;\n lastError?: string;\n}\n\nexport interface DmdDeliveryManager {\n send(payload: Record<string, unknown>): Promise<void>;\n flushQueue(): Promise<void>;\n clearQueue(reason: string): void;\n enqueueForTests(record: DmdQueuedRecord): void;\n flushExpired(): void;\n acquireFlushLease(): boolean;\n releaseFlushLease(): void;\n getDiagnostics(): DmdDeliveryDiagnostics;\n}\n\nexport interface DmdDeliveryStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): unknown;\n removeItem(key: string): unknown;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return JSON.stringify(value);\n }\n return JSON.stringify(\n Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([left], [right]) => left.localeCompare(right))\n )\n );\n}\n\nfunction createIdempotencyKey(payload: Record<string, unknown>, messageId: string): string {\n const event = String(payload.event ?? payload.type ?? 'event');\n const properties = payload.properties as Record<string, unknown> | undefined;\n const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;\n if (orderId !== undefined) return `${event}:${String(orderId)}`;\n return `${event}:${stableStringify(properties ?? {}) || messageId}`;\n}\n\nexport function createDeliveryManager(config: {\n endpoint: string;\n fetch?: typeof fetch;\n queueTtlMs?: number;\n maxQueueSize?: number;\n storage?: DmdDeliveryStorage;\n queueKey?: string;\n lockKey?: string;\n lockTtlMs?: number;\n tabId?: string;\n retryDelayMs?: number;\n maxRetryDelayMs?: number;\n maxPayloadBytes?: number;\n batchSize?: number;\n onDrop?: (event: { messageId?: string; reason: string; timestamp: string }) => void;\n onError?: (error: Error) => void;\n}): DmdDeliveryManager {\n const queue: DmdQueuedRecord[] = [];\n const diagnostics: DmdDeliveryDiagnostics = { queued: 0, inFlight: 0, dropped: [] };\n const maxQueueSize = config.maxQueueSize ?? 100;\n const queueKey = config.queueKey ?? 'dmd_delivery_queue';\n const lockKey = config.lockKey ?? 'dmd_delivery_flush_lock';\n const lockTtlMs = config.lockTtlMs ?? 5_000;\n const tabId = config.tabId ?? createId('tab');\n const batchSize = config.batchSize ?? 25;\n const maxPayloadBytes = config.maxPayloadBytes ?? 64_000;\n\n function recordDrop(event: { messageId?: string; reason: string; timestamp: string }): void {\n diagnostics.dropped.push(event);\n config.onDrop?.(event);\n }\n\n function recordError(error: Error): void {\n diagnostics.lastError = error.message;\n config.onError?.(error);\n }\n\n function payloadByteLength(payload: Record<string, unknown>): number {\n const serialized = JSON.stringify(payload);\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(serialized).length;\n }\n return serialized.length;\n }\n\n function recordStorageUnavailable(): void {\n recordDrop({\n reason: 'storage_unavailable',\n timestamp: new Date().toISOString()\n });\n }\n\n function safeGetItem(key: string): string | null {\n try {\n return config.storage?.getItem(key) ?? null;\n } catch {\n recordStorageUnavailable();\n return null;\n }\n }\n\n function safeSetItem(key: string, value: string): boolean {\n try {\n config.storage?.setItem(key, value);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function safeRemoveItem(key: string): boolean {\n try {\n config.storage?.removeItem(key);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function persistQueue(): void {\n if (!config.storage) return;\n if (queue.length === 0) {\n safeRemoveItem(queueKey);\n return;\n }\n safeSetItem(queueKey, JSON.stringify(queue));\n }\n\n function loadQueue(): void {\n if (!config.storage) return;\n const rawQueue = safeGetItem(queueKey);\n if (!rawQueue) return;\n try {\n const records = JSON.parse(rawQueue) as DmdQueuedRecord[];\n queue.splice(0, queue.length, ...records.filter(record => record && typeof record.messageId === 'string'));\n diagnostics.queued = queue.length;\n } catch {\n safeRemoveItem(queueKey);\n recordDrop({\n reason: 'queue_corrupt',\n timestamp: new Date().toISOString()\n });\n }\n }\n\n function enqueue(record: DmdQueuedRecord): void {\n queue.push(record);\n while (queue.length > maxQueueSize) {\n const dropped = queue.shift();\n const diagnostic: { messageId?: string; reason: string; timestamp: string } = {\n reason: 'queue_limit_exceeded',\n timestamp: new Date().toISOString()\n };\n if (dropped?.messageId !== undefined) diagnostic.messageId = dropped.messageId;\n recordDrop(diagnostic);\n }\n diagnostics.queued = queue.length;\n persistQueue();\n }\n\n function withEnvelope(payload: Record<string, unknown>): Record<string, unknown> {\n const messageId = String(payload.messageId ?? createId('msg'));\n return {\n ...payload,\n messageId,\n idempotencyKey: String(payload.idempotencyKey ?? createIdempotencyKey(payload, messageId))\n };\n }\n\n async function deliver(body: Record<string, unknown>): Promise<void> {\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new Error('fetch_unavailable');\n }\n\n const response = await fetchImpl(config.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n keepalive: true\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n }\n\n loadQueue();\n\n return {\n async send(payload: Record<string, unknown>): Promise<void> {\n const body = withEnvelope(payload);\n\n if (payloadByteLength(body) > maxPayloadBytes) {\n recordDrop({\n messageId: String(body.messageId),\n reason: 'payload_too_large',\n timestamp: new Date().toISOString()\n });\n return;\n }\n\n diagnostics.inFlight += 1;\n try {\n await deliver(body);\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n recordError(deliveryError);\n enqueue({\n messageId: String(body.messageId),\n savedAt: Date.now(),\n attempts: 1,\n lastError: deliveryError.message,\n payload: body\n });\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n }\n },\n async flushQueue(): Promise<void> {\n this.flushExpired();\n if (queue.length === 0 || !this.acquireFlushLease()) return;\n\n diagnostics.inFlight += 1;\n try {\n let sentInBatch = 0;\n for (let index = 0; index < queue.length && sentInBatch < batchSize;) {\n const record = queue[index];\n if (!record) {\n index += 1;\n continue;\n }\n\n try {\n await deliver(record.payload);\n queue.splice(index, 1);\n sentInBatch += 1;\n persistQueue();\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n record.attempts += 1;\n record.lastError = deliveryError.message;\n recordError(deliveryError);\n index += 1;\n persistQueue();\n break;\n }\n }\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n this.releaseFlushLease();\n }\n },\n clearQueue(reason: string): void {\n for (const record of queue) {\n recordDrop({\n messageId: record.messageId,\n reason,\n timestamp: new Date().toISOString()\n });\n }\n queue.splice(0, queue.length);\n diagnostics.queued = 0;\n persistQueue();\n },\n enqueueForTests(record: DmdQueuedRecord): void {\n enqueue(record);\n },\n flushExpired(): void {\n const ttl = config.queueTtlMs ?? 86_400_000;\n const now = Date.now();\n for (let index = queue.length - 1; index >= 0; index -= 1) {\n const record = queue[index];\n if (record && now - record.savedAt > ttl) {\n recordDrop({\n messageId: record.messageId,\n reason: 'queue_ttl_expired',\n timestamp: new Date().toISOString()\n });\n queue.splice(index, 1);\n }\n }\n diagnostics.queued = queue.length;\n persistQueue();\n },\n acquireFlushLease(): boolean {\n if (!config.storage) return true;\n\n const now = Date.now();\n const rawLock = safeGetItem(lockKey);\n let existingLock: { owner?: string; expiresAt?: number } | undefined;\n if (rawLock) {\n try {\n existingLock = JSON.parse(rawLock) as { owner?: string; expiresAt?: number };\n } catch {\n existingLock = undefined;\n }\n }\n\n const lockExpired = !existingLock?.expiresAt || existingLock.expiresAt <= now;\n const lockOwnedByThisTab = existingLock?.owner === tabId;\n if (!existingLock || lockExpired || lockOwnedByThisTab) {\n if (!safeSetItem(lockKey, JSON.stringify({ owner: tabId, expiresAt: now + lockTtlMs }))) {\n return true;\n }\n return true;\n }\n\n return false;\n },\n releaseFlushLease(): void {\n if (!config.storage) return;\n const rawLock = safeGetItem(lockKey);\n if (!rawLock) return;\n\n try {\n const existingLock = JSON.parse(rawLock) as { owner?: string };\n if (existingLock.owner === tabId) {\n safeRemoveItem(lockKey);\n }\n } catch {\n safeRemoveItem(lockKey);\n }\n },\n getDiagnostics(): DmdDeliveryDiagnostics {\n return diagnostics;\n }\n };\n}\n","const sensitiveKeys = new Set([\n 'email',\n 'phone',\n 'mobile',\n 'address',\n 'address1',\n 'address2',\n 'first_name',\n 'last_name',\n 'name',\n 'token',\n 'secret',\n 'password',\n 'session',\n 'cookie'\n]);\n\nexport function redactUrl(\n url: string,\n allowQueryKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']\n): string {\n const parsed = new URL(url, 'https://placeholder.local');\n for (const key of Array.from(parsed.searchParams.keys())) {\n if (!allowQueryKeys.includes(key)) {\n parsed.searchParams.set(key, '[REDACTED]');\n }\n }\n return url.startsWith('http') ? parsed.toString() : `${parsed.pathname}${parsed.search}`;\n}\n\nfunction sanitizeValue(value: unknown, allow: Set<string>): unknown {\n if (Array.isArray(value)) {\n return value.map(item => sanitizeValue(item, allow));\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .filter(([key]) => !sensitiveKeys.has(key.toLowerCase()) || allow.has(key.toLowerCase()))\n .map(([key, nestedValue]) => [key, sanitizeValue(nestedValue, allow)])\n );\n }\n\n return value;\n}\n\nexport function sanitizeProperties(input: Record<string, unknown>, allowRawKeys: string[] = []): Record<string, unknown> {\n const allow = new Set(allowRawKeys.map(key => key.toLowerCase()));\n return sanitizeValue(input, allow) as Record<string, unknown>;\n}\n\nexport async function sha256LowerTrimmed(value: string): Promise<string> {\n const bytes = new TextEncoder().encode(value.trim().toLowerCase());\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n return Array.from(new Uint8Array(digest)).map(byte => byte.toString(16).padStart(2, '0')).join('');\n}\n","const reservedKeys = new Set(['messageId', 'timestamp', 'type', 'event', 'anonymousId', 'userId', 'context']);\n\nexport interface DmdSchemaValidationResult {\n ok: boolean;\n errors: string[];\n}\n\nexport function validateEventEnvelope(\n envelope: {\n type?: unknown;\n event?: unknown;\n properties?: Record<string, unknown>;\n messageId?: unknown;\n timestamp?: unknown;\n },\n options: { mode?: 'off' | 'warn' | 'strict' } = {}\n): DmdSchemaValidationResult {\n if (options.mode === 'off') return { ok: true, errors: [] };\n const errors: string[] = [];\n if (typeof envelope.type !== 'string') errors.push('type must be a string');\n if (envelope.type === 'track' && typeof envelope.event !== 'string') {\n errors.push('track event must include event name');\n }\n if (typeof envelope.messageId !== 'string') errors.push('messageId must be a string');\n if (typeof envelope.timestamp !== 'string') errors.push('timestamp must be an ISO string');\n for (const key of Object.keys(envelope.properties ?? {})) {\n if (reservedKeys.has(key)) errors.push(`properties.${key} is reserved`);\n }\n return { ok: errors.length === 0, errors };\n}\n","import type { DmdDroppedEventDiagnostic, DmdDroppedEventReason, DmdDroppedEventType } from '../../core/diagnostics';\nimport type { DmdBrowserConfig, DmdConsentInput, DmdEventOptions, DmdHealthStatus } from '../../core/types';\nimport { getBrowserWindow } from '../../core/environment';\nimport { canCollectPurpose, mergeConsent, normalizeConsent, type DmdResolvedConsent } from './consent';\nimport { createDeliveryManager, type DmdDeliveryManager } from './delivery';\nimport { sanitizeProperties } from './privacy';\nimport { validateEventEnvelope } from './schema';\nimport type { DmdIdentityState } from './types';\n\ninterface DmdPreparedEvent {\n type: 'track' | 'page' | 'identify' | 'group' | 'alias';\n event: string;\n properties: Record<string, unknown>;\n messageId: string;\n timestamp: string;\n context: Record<string, unknown>;\n anonymousId: string;\n userId?: string;\n groupId?: string;\n clientId: string;\n workspaceId: string;\n appId: string;\n writeKey: string;\n consent: DmdResolvedConsent;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction endpointFromConfig(config: DmdBrowserConfig): string {\n const host = config.apiHost ?? 'https://sdk.drivemetadata.com/v2';\n return `${host.replace(/\\/$/, '')}/data-collector`;\n}\n\nfunction getBrowserStorage() {\n const browserWindow = getBrowserWindow();\n try {\n return browserWindow?.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class DriveMetaDataSDK {\n public initialized = true;\n public queue: unknown[] = [];\n public offline = false;\n public gdprConsent: 'granted' | 'denied' | 'pending';\n\n private readonly endpoint: string;\n private readonly config: DmdBrowserConfig;\n private readonly writeKey: string;\n private readonly delivery: DmdDeliveryManager;\n private identity: DmdIdentityState;\n private consentState: DmdResolvedConsent;\n private droppedEvents = 0;\n private lastError: string | undefined;\n private lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n private retryTimer: ReturnType<typeof setTimeout> | undefined;\n private retryDelayMs: number;\n private readonly initialRetryDelayMs: number;\n private readonly maxRetryDelayMs: number;\n private lifecycleCleanup: (() => void) | undefined;\n\n constructor(config: DmdBrowserConfig) {\n this.config = config;\n this.endpoint = endpointFromConfig(config);\n const storage = getBrowserStorage();\n const deliveryConfig: Parameters<typeof createDeliveryManager>[0] = {\n endpoint: this.endpoint,\n };\n if (config.delivery?.maxQueueSize !== undefined) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;\n if (config.delivery?.queueTtlMs !== undefined) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;\n if (config.delivery?.retryDelayMs !== undefined) deliveryConfig.retryDelayMs = config.delivery.retryDelayMs;\n if (config.delivery?.maxRetryDelayMs !== undefined) deliveryConfig.maxRetryDelayMs = config.delivery.maxRetryDelayMs;\n if (config.delivery?.maxPayloadBytes !== undefined) deliveryConfig.maxPayloadBytes = config.delivery.maxPayloadBytes;\n if (config.delivery?.batchSize !== undefined) deliveryConfig.batchSize = config.delivery.batchSize;\n if (config.onDrop !== undefined) deliveryConfig.onDrop = config.onDrop;\n if (config.onError !== undefined) deliveryConfig.onError = config.onError;\n this.delivery = createDeliveryManager(storage ? {\n ...deliveryConfig,\n storage\n } : deliveryConfig);\n this.initialRetryDelayMs = config.delivery?.retryDelayMs ?? 1_000;\n this.retryDelayMs = this.initialRetryDelayMs;\n this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 30_000;\n this.writeKey = config.writeKey || config.token || '';\n this.identity = { anonymousId: createId('anon') };\n this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);\n this.gdprConsent = this.consentState.analytics;\n if (!config.delivery?.disableLifecycleFlush) {\n this.installLifecycleFlush();\n }\n }\n\n trackEvent(event: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('track', event, properties, options);\n }\n\n page(name?: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('page', 'page_view', { name, ...properties }, options);\n }\n\n trackPageview(): void {\n this.page();\n }\n\n identify(userId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, userId, traits };\n this.sendPreparedEvent('identify', 'identify', { userId, traits }, options);\n }\n\n identifyUser(userId: string, traits: Record<string, unknown> = {}): void {\n this.identify(userId, traits);\n }\n\n group(groupId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, groupId };\n this.sendPreparedEvent('group', 'group', { groupId, traits }, options);\n }\n\n alias(previousId: string, userId: string, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('alias', 'alias', { previousId, userId }, options);\n }\n\n async flush(): Promise<void> {\n await this.delivery.flushQueue();\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n } else {\n this.retryDelayMs = this.initialRetryDelayMs;\n }\n }\n\n reset(): void {\n this.identity = { anonymousId: createId('anon') };\n this.queue = [];\n this.offline = false;\n if (this.retryTimer !== undefined) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.lifecycleCleanup?.();\n this.lifecycleCleanup = undefined;\n this.delivery.clearQueue('manual_clear');\n }\n\n setConsent(consent: DmdConsentInput): void {\n this.consentState = typeof consent === 'object'\n ? mergeConsent(this.consentState, consent)\n : normalizeConsent(consent);\n this.gdprConsent = this.consentState.analytics;\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.queue = [];\n this.delivery.clearQueue('consent_revoked');\n }\n }\n\n getHealth(): DmdHealthStatus {\n const deliveryDiagnostics = this.delivery.getDiagnostics();\n const health: DmdHealthStatus = {\n initialized: this.initialized,\n consent: this.gdprConsent,\n consentPurposes: this.consentState,\n queueSize: deliveryDiagnostics.queued,\n offline: this.offline || deliveryDiagnostics.queued > 0,\n droppedEvents: this.droppedEvents + deliveryDiagnostics.dropped.length,\n delivery: deliveryDiagnostics\n };\n const lastError = this.lastError ?? deliveryDiagnostics.lastError;\n if (lastError !== undefined) health.lastError = lastError;\n if (this.lastDroppedEvent !== undefined) health.lastDroppedEvent = this.lastDroppedEvent;\n return health;\n }\n\n sendEvent(payload: unknown): void {\n void this.delivery.send(payload as Record<string, unknown>).then(() => {\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n }\n });\n }\n\n private installLifecycleFlush(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow) return;\n if (typeof browserWindow.addEventListener !== 'function') return;\n if (typeof browserWindow.removeEventListener !== 'function') return;\n\n const flushOnLifecycle = () => {\n void this.flush();\n };\n const flushOnVisibility = () => {\n if (browserWindow.document?.visibilityState === 'hidden') {\n void this.flush();\n }\n };\n\n browserWindow.addEventListener('online', flushOnLifecycle);\n browserWindow.addEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.addEventListener === 'function') {\n browserWindow.document.addEventListener('visibilitychange', flushOnVisibility);\n }\n\n this.lifecycleCleanup = () => {\n browserWindow.removeEventListener('online', flushOnLifecycle);\n browserWindow.removeEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.removeEventListener === 'function') {\n browserWindow.document.removeEventListener('visibilitychange', flushOnVisibility);\n }\n };\n }\n\n private scheduleRetryFlush(): void {\n if (this.retryTimer !== undefined) return;\n\n const delay = Math.min(this.retryDelayMs, this.maxRetryDelayMs);\n this.retryTimer = setTimeout(() => {\n this.retryTimer = undefined;\n void this.flush().then(() => {\n if (this.delivery.getDiagnostics().queued > 0) {\n this.retryDelayMs = Math.min(this.retryDelayMs * 2, this.maxRetryDelayMs);\n this.scheduleRetryFlush();\n }\n });\n }, delay);\n }\n\n private sendPreparedEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): void {\n void this.prepareAndSendEvent(type, event, properties, options);\n }\n\n private async prepareAndSendEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): Promise<void> {\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.recordDrop(type, 'consent_denied', event);\n return;\n }\n\n let prepared: DmdPreparedEvent = {\n type,\n event,\n properties: sanitizeProperties(properties),\n messageId: options.messageId ?? createId('msg'),\n timestamp: options.timestamp ?? new Date().toISOString(),\n context: options.context ?? {},\n anonymousId: this.identity.anonymousId,\n clientId: this.config.clientId,\n workspaceId: this.config.workspaceId,\n appId: this.config.appId,\n writeKey: this.writeKey,\n consent: this.consentState\n };\n\n if (this.identity.userId !== undefined) prepared.userId = this.identity.userId;\n if (this.identity.groupId !== undefined) prepared.groupId = this.identity.groupId;\n\n if (this.config.beforeSend !== undefined) {\n const beforeSendResult = await this.config.beforeSend(prepared);\n if (beforeSendResult === null) {\n this.recordDrop(type, 'before_send_dropped', event);\n return;\n }\n prepared = {\n ...prepared,\n ...beforeSendResult,\n properties: sanitizeProperties(beforeSendResult.properties ?? prepared.properties)\n };\n }\n\n const validation = validateEventEnvelope(prepared, { mode: this.config.schemaValidation ?? 'warn' });\n if (!validation.ok && this.config.schemaValidation === 'strict') {\n this.recordDrop(type, 'invalid_payload', event);\n return;\n }\n if (!validation.ok) {\n this.lastError = `DMD SDK schema warning: ${validation.errors.join(', ')}`;\n }\n\n this.sendEvent(prepared);\n }\n\n private recordDrop(type: DmdDroppedEventType, reason: DmdDroppedEventReason, event?: string): void {\n this.droppedEvents += 1;\n this.lastDroppedEvent = {\n type,\n reason,\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) this.lastDroppedEvent.event = event;\n this.lastError = `DMD SDK ${type} dropped because ${reason}`;\n }\n}\n","import { getBrowserWindow, isBrowserRuntime } from '../core/environment';\n\nexport type LegacySdkConstructor = new (config: unknown) => LegacySdkInstance;\n\nexport interface LegacySdkInstance {\n sendEvent?: (payload: unknown) => void;\n trackEvent?: (event: string, properties?: Record<string, unknown>, options?: unknown) => void;\n identify?: (userId: string, traits?: Record<string, unknown>, options?: unknown) => void;\n identifyUser?: (userId: string, traits?: Record<string, unknown>) => void;\n page?: (name?: string, properties?: Record<string, unknown>, options?: unknown) => void;\n group?: (groupId: string, traits?: Record<string, unknown>, options?: unknown) => void;\n alias?: (previousId: string, userId: string, options?: unknown) => void;\n flush?: () => Promise<void>;\n reset?: () => void;\n setConsent?: (consent: unknown) => void;\n getHealth?: () => unknown;\n trackPageview?: () => void;\n blockTrackingForMe?: () => void;\n gdprConsent?: 'granted' | 'denied' | 'pending';\n initialized?: boolean;\n queue?: unknown[];\n offline?: boolean;\n}\n\ninterface DmdWindow extends Window {\n DriveMetaDataSDK?: LegacySdkConstructor;\n __DriveMetaDataSDKInstance?: LegacySdkInstance;\n}\n\nexport function getLegacySdkInstanceFromWindow(): LegacySdkInstance | undefined {\n const browserWindow = getBrowserWindow() as DmdWindow | undefined;\n return browserWindow?.__DriveMetaDataSDKInstance;\n}\n\nexport function ensureLegacySdkLoaded(): LegacySdkConstructor {\n if (!isBrowserRuntime()) {\n throw new Error('DMD legacy SDK is only available in a browser runtime');\n }\n\n const browserWindow = getBrowserWindow() as DmdWindow | undefined;\n if (!browserWindow?.DriveMetaDataSDK) {\n throw new Error('DMD legacy SDK constructor is missing from window.DriveMetaDataSDK');\n }\n\n return browserWindow.DriveMetaDataSDK;\n}\n","import { normalizeBrowserConfig } from '../core/config';\nimport type { DmdDroppedEventDiagnostic, DmdDroppedEventType } from '../core/diagnostics';\nimport type {\n DmdBrowserClient,\n DmdBrowserConfig,\n DmdConsentInput,\n DmdEventOptions,\n DmdHealthStatus\n} from '../core/types';\nimport { DriveMetaDataSDK } from './core/DriveMetaDataSDK';\nimport {\n ensureLegacySdkLoaded,\n getLegacySdkInstanceFromWindow,\n type LegacySdkInstance\n} from './legacy-loader';\n\ntype DmdRuntimeInstance = LegacySdkInstance | DriveMetaDataSDK;\n\nexport interface DmdBrowserClientWithLegacy extends DmdBrowserClient {\n __legacy: DmdRuntimeInstance;\n}\n\nlet singleton: DmdRuntimeInstance | undefined;\nlet publicSingleton: DmdBrowserClientWithLegacy | undefined;\nlet droppedEvents = 0;\nlet lastError: string | undefined;\nlet lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n\nfunction createPublicClient(instance: DmdRuntimeInstance): DmdBrowserClientWithLegacy {\n return {\n __legacy: instance,\n track(event, properties, options) {\n if (instance.trackEvent) {\n instance.trackEvent(event, properties, options);\n return;\n }\n instance.sendEvent?.({ eventName: event, event, properties, options });\n },\n identify(userId, traits, options) {\n if (instance.identify) {\n instance.identify(userId, traits, options);\n return;\n }\n instance.identifyUser?.(userId, traits);\n },\n page(name, properties, options) {\n if (instance.page) {\n instance.page(name, properties, options);\n return;\n }\n instance.trackPageview?.();\n },\n group(groupId, traits, options) {\n instance.group?.(groupId, traits, options);\n },\n alias(previousId, userId, options) {\n instance.alias?.(previousId, userId, options);\n },\n async flush() {\n await instance.flush?.();\n },\n reset() {\n instance.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n },\n setConsent(consent) {\n if (instance.setConsent) {\n instance.setConsent(consent);\n return;\n }\n if (typeof consent === 'string') {\n instance.gdprConsent = consent;\n }\n },\n getHealth() {\n if (instance.getHealth) {\n return instance.getHealth() as DmdHealthStatus;\n }\n return getDmdHealth();\n }\n };\n}\n\nfunction setSingleton(instance: DmdRuntimeInstance): DmdBrowserClientWithLegacy {\n singleton = instance;\n publicSingleton = createPublicClient(instance);\n return publicSingleton;\n}\n\nfunction recordDroppedEvent(type: DmdDroppedEventType, event?: string): void {\n droppedEvents += 1;\n lastDroppedEvent = {\n type,\n reason: 'not_initialized',\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) {\n lastDroppedEvent.event = event;\n }\n lastError = `DMD SDK ${type} called before initialization`;\n}\n\nexport function initDmdSDK(config: DmdBrowserConfig): DmdBrowserClientWithLegacy {\n if (publicSingleton) {\n return publicSingleton;\n }\n\n const legacyConfig = normalizeBrowserConfig(config);\n const existingInstance = getLegacySdkInstanceFromWindow();\n if (existingInstance) {\n return setSingleton(existingInstance);\n }\n\n try {\n let instance: DmdRuntimeInstance;\n try {\n const LegacySdk = ensureLegacySdkLoaded();\n instance = new LegacySdk(legacyConfig);\n } catch (error) {\n if (error instanceof Error && error.message.includes('constructor is missing')) {\n instance = new DriveMetaDataSDK(config);\n } else {\n throw error;\n }\n }\n return setSingleton(instance);\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n throw error;\n }\n}\n\nexport function getDmdSDK(): DmdBrowserClientWithLegacy | undefined {\n return publicSingleton;\n}\n\nexport function track(event: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('track', event);\n return;\n }\n sdk.track(event, properties, options);\n}\n\nexport function identify(userId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('identify');\n return;\n }\n sdk.identify(userId, traits, options);\n}\n\nexport function page(name?: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('page');\n return;\n }\n sdk.page(name, properties, options);\n}\n\nexport function group(groupId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('group');\n return;\n }\n sdk.group(groupId, traits, options);\n}\n\nexport function alias(previousId: string, userId: string, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('alias');\n return;\n }\n sdk.alias(previousId, userId, options);\n}\n\nexport async function flush(): Promise<void> {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('flush');\n return;\n }\n await sdk.flush();\n}\n\nexport function reset(): void {\n singleton?.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n}\n\nexport function setConsent(consent: DmdConsentInput): void {\n getDmdSDK()?.setConsent(consent);\n}\n\nexport const consent = {\n update(state: DmdConsentInput): void {\n setConsent(state);\n }\n};\n\nexport async function ready(): Promise<DmdBrowserClientWithLegacy | undefined> {\n return getDmdSDK();\n}\n\nexport function getDmdHealth(): DmdHealthStatus {\n if (singleton?.getHealth) {\n return singleton.getHealth() as DmdHealthStatus;\n }\n\n const health: DmdHealthStatus = {\n initialized: Boolean(singleton?.initialized ?? singleton),\n consent: singleton?.gdprConsent ?? 'pending',\n queueSize: singleton?.queue?.length ?? 0,\n offline: Boolean(singleton?.offline),\n droppedEvents\n };\n\n if (lastError !== undefined) {\n health.lastError = lastError;\n }\n if (lastDroppedEvent !== undefined) {\n health.lastDroppedEvent = lastDroppedEvent;\n }\n\n return health;\n}\n\nexport function resetDmdSDKForTests(): void {\n singleton?.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n droppedEvents = 0;\n lastError = undefined;\n lastDroppedEvent = undefined;\n}\n","'use client';\n\nimport React from 'react';\nimport { page } from '../browser/client';\n\nexport interface DmdNextPageTrackingOptions {\n name?: string;\n properties?: Record<string, unknown>;\n}\n\nexport function useDmdAppRouterPageTracking(\n pathname: string | null,\n search?: string | null,\n options: DmdNextPageTrackingOptions = {}\n): void {\n const lastRouteKey = React.useRef<string | undefined>(undefined);\n const routeKey = pathname ? `${pathname}?${search ?? ''}` : '';\n\n React.useEffect(() => {\n if (!pathname || !routeKey || lastRouteKey.current === routeKey) return;\n\n lastRouteKey.current = routeKey;\n page(options.name, {\n ...options.properties,\n pathname,\n search: search ?? ''\n });\n }, [options.name, options.properties, pathname, routeKey, search]);\n}\n","'use client';\n\nimport React from 'react';\nimport { page } from '../browser/client';\nimport type { DmdNextPageTrackingOptions } from './useDmdAppRouterPageTracking';\n\nexport interface DmdPagesRouterLike {\n asPath?: string;\n pathname?: string;\n}\n\nexport function useDmdPagesRouterPageTracking(\n router: DmdPagesRouterLike | null | undefined,\n options: DmdNextPageTrackingOptions = {}\n): void {\n const lastRouteKey = React.useRef<string | undefined>(undefined);\n const routeKey = router?.asPath ?? router?.pathname ?? '';\n\n React.useEffect(() => {\n if (!routeKey || lastRouteKey.current === routeKey) return;\n\n lastRouteKey.current = routeKey;\n page(options.name, {\n ...options.properties,\n route: routeKey\n });\n }, [options.name, options.properties, routeKey]);\n}\n","import React from 'react';\nimport {\n alias,\n flush,\n getDmdHealth,\n group,\n identify,\n page,\n reset,\n setConsent,\n track\n} from '../browser/client';\nimport type { DmdBrowserClient, DmdConsentInput, DmdEventOptions, DmdHealthStatus } from '../core/types';\nimport { DmdContext } from './DmdProvider';\n\nexport function useDmdSDK(): DmdBrowserClient | undefined {\n return React.useContext(DmdContext);\n}\n\nexport function useTrackEvent(): (\n event: string,\n properties?: Record<string, unknown>,\n options?: DmdEventOptions\n) => void {\n return React.useCallback((event: string, properties?: Record<string, unknown>, options?: DmdEventOptions) => {\n track(event, properties, options);\n }, []);\n}\n\nexport function useIdentify(): (userId: string, traits?: Record<string, unknown>) => void {\n return React.useCallback((userId: string, traits?: Record<string, unknown>) => {\n identify(userId, traits);\n }, []);\n}\n\nexport function usePage(): (\n name?: string,\n properties?: Record<string, unknown>,\n options?: DmdEventOptions\n) => void {\n return React.useCallback((name?: string, properties?: Record<string, unknown>, options?: DmdEventOptions) => {\n page(name, properties, options);\n }, []);\n}\n\nexport function useGroup(): (\n groupId: string,\n traits?: Record<string, unknown>,\n options?: DmdEventOptions\n) => void {\n return React.useCallback((groupId: string, traits?: Record<string, unknown>, options?: DmdEventOptions) => {\n group(groupId, traits, options);\n }, []);\n}\n\nexport function useAlias(): (previousId: string, userId: string, options?: DmdEventOptions) => void {\n return React.useCallback((previousId: string, userId: string, options?: DmdEventOptions) => {\n alias(previousId, userId, options);\n }, []);\n}\n\nexport function useReset(): () => void {\n return React.useCallback(() => {\n reset();\n }, []);\n}\n\nexport function useDmdFlush(): () => Promise<void> {\n return React.useCallback(async () => {\n await flush();\n }, []);\n}\n\nexport function useDmdConsent(): (consent: DmdConsentInput) => void {\n return React.useCallback((consent: DmdConsentInput) => {\n setConsent(consent);\n }, []);\n}\n\nexport function useDmdHealth(): DmdHealthStatus {\n const client = useDmdSDK();\n const [health, setHealth] = React.useState<DmdHealthStatus>(() => getDmdHealth());\n\n React.useEffect(() => {\n setHealth(getDmdHealth());\n }, [client]);\n\n return health;\n}\n"],"mappings":";;;AAAA,OAAO,WAAW;;;ACElB,SAAS,cAAc,OAA2B,OAAuB;AACvE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,UAAM,IAAI,MAAM,kBAAkB,KAAK,cAAc;AAAA,EACvD;AACA,SAAO;AACT;AAEO,SAAS,uBAAuB,QAA2C;AAChF,QAAM,WAAW,OAAO,YAAY,OAAO;AAC3C,QAAM,eAAgC;AAAA,IACpC,WAAW,cAAc,OAAO,UAAU,UAAU;AAAA,IACpD,cAAc,cAAc,OAAO,aAAa,aAAa;AAAA,IAC7D,QAAQ,cAAc,OAAO,OAAO,OAAO;AAAA,IAC3C,OAAO,cAAc,UAAU,UAAU;AAAA,EAC3C;AAEA,MAAI,OAAO,YAAY,OAAW,cAAa,WAAW,OAAO;AACjE,MAAI,OAAO,WAAW,OAAW,cAAa,UAAU,OAAO;AAC/D,MAAI,OAAO,aAAa,OAAW,cAAa,WAAW,OAAO;AAClE,MAAI,OAAO,UAAU,OAAW,cAAa,QAAQ,OAAO;AAC5D,MAAI,OAAO,YAAY,OAAW,cAAa,UAAU,OAAO;AAChE,MAAI,OAAO,gBAAgB,OAAW,cAAa,cAAc,OAAO;AACxE,MAAI,OAAO,gBAAgB,OAAW,cAAa,cAAc,OAAO;AACxE,MAAI,OAAO,oBAAoB,OAAW,cAAa,mBAAmB,OAAO;AACjF,MAAI,OAAO,qBAAqB,OAAW,cAAa,oBAAoB,OAAO;AACnF,MAAI,OAAO,sBAAsB,OAAW,cAAa,sBAAsB,OAAO;AACtF,MAAI,OAAO,yBAAyB,OAAW,cAAa,yBAAyB,OAAO;AAC5F,MAAI,OAAO,uBAAuB,OAAW,cAAa,sBAAsB,OAAO;AACvF,MAAI,OAAO,mBAAmB,OAAW,cAAa,kBAAkB,OAAO;AAC/E,MAAI,OAAO,4BAA4B,OAAW,cAAa,4BAA4B,OAAO;AAClG,MAAI,OAAO,mBAAmB,OAAW,cAAa,kBAAkB,OAAO;AAC/E,MAAI,OAAO,gBAAgB,OAAW,cAAa,gBAAgB,OAAO;AAC1E,MAAI,OAAO,6BAA6B,QAAW;AACjD,iBAAa,8BAA8B,OAAO;AAAA,EACpD;AACA,MAAI,OAAO,gBAAgB,OAAW,cAAa,cAAc,OAAO;AACxE,MAAI,OAAO,qBAAqB,OAAW,cAAa,oBAAoB,OAAO;AACnF,MAAI,OAAO,8BAA8B,QAAW;AAClD,iBAAa,+BAA+B,OAAO;AAAA,EACrD;AACA,MAAI,OAAO,eAAe,OAAW,cAAa,cAAc,OAAO;AAEvE,SAAO;AACT;;;AC7CO,SAAS,mBAA4B;AAC1C,SAAO,OAAO,WAAW,eAAe,OAAO,aAAa;AAC9D;AAEO,SAAS,mBAAuC;AACrD,SAAO,OAAO,WAAW,cAAc,SAAY;AACrD;;;ACGA,IAAM,WAAgC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,sBAAsB,OAAiC;AAC9D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,MAAO,QAAO;AAC5B,MAAI,UAAU,aAAa,UAAU,YAAY,UAAU,UAAW,QAAO;AAC7E,SAAO;AACT;AAEO,SAAS,iBAAiB,OAAwD;AACvF,QAAM,eAAe,sBAAsB,SAAS,SAAS;AAC7D,QAAM,WAAW,OAAO;AAAA,IACtB,SAAS,IAAI,aAAW,CAAC,SAAS,YAAY,CAAC;AAAA,EACjD;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,eAAW,WAAW,UAAU;AAC9B,YAAM,QAAQ,MAAM,OAAO;AAC3B,UAAI,UAAU,QAAW;AACvB,iBAAS,OAAO,IAAI,sBAAsB,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,aAAa,SAA6B,QAA+C;AACvG,QAAM,OAAO,EAAE,GAAG,QAAQ;AAC1B,aAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAkD;AACpG,SAAK,OAAO,IAAI,sBAAsB,KAAK;AAAA,EAC7C;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,SAA6B,SAAqC;AAClG,SAAO,QAAQ,OAAO,MAAM;AAC9B;;;ACpBA,SAAS,SAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC;AACnF;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,SAAO,KAAK;AAAA,IACV,OAAO;AAAA,MACL,OAAO,QAAQ,KAAgC,EAAE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC;AAAA,IACtG;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAkC,WAA2B;AACzF,QAAM,QAAQ,OAAO,QAAQ,SAAS,QAAQ,QAAQ,OAAO;AAC7D,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,YAAY,WAAW,YAAY,YAAY,YAAY;AAC3E,MAAI,YAAY,OAAW,QAAO,GAAG,KAAK,IAAI,OAAO,OAAO,CAAC;AAC7D,SAAO,GAAG,KAAK,IAAI,gBAAgB,cAAc,CAAC,CAAC,KAAK,SAAS;AACnE;AAEO,SAAS,sBAAsB,QAgBf;AACrB,QAAM,QAA2B,CAAC;AAClC,QAAM,cAAsC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,EAAE;AAClF,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,QAAQ,OAAO,SAAS,SAAS,KAAK;AAC5C,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,kBAAkB,OAAO,mBAAmB;AAElD,WAAS,WAAW,OAAwE;AAC1F,gBAAY,QAAQ,KAAK,KAAK;AAC9B,WAAO,SAAS,KAAK;AAAA,EACvB;AAEA,WAAS,YAAY,OAAoB;AACvC,gBAAY,YAAY,MAAM;AAC9B,WAAO,UAAU,KAAK;AAAA,EACxB;AAEA,WAAS,kBAAkB,SAA0C;AACnE,UAAM,aAAa,KAAK,UAAU,OAAO;AACzC,QAAI,OAAO,gBAAgB,aAAa;AACtC,aAAO,IAAI,YAAY,EAAE,OAAO,UAAU,EAAE;AAAA,IAC9C;AACA,WAAO,WAAW;AAAA,EACpB;AAEA,WAAS,2BAAiC;AACxC,eAAW;AAAA,MACT,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH;AAEA,WAAS,YAAY,KAA4B;AAC/C,QAAI;AACF,aAAO,OAAO,SAAS,QAAQ,GAAG,KAAK;AAAA,IACzC,QAAQ;AACN,+BAAyB;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,YAAY,KAAa,OAAwB;AACxD,QAAI;AACF,aAAO,SAAS,QAAQ,KAAK,KAAK;AAClC,aAAO;AAAA,IACT,QAAQ;AACN,+BAAyB;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,eAAe,KAAsB;AAC5C,QAAI;AACF,aAAO,SAAS,WAAW,GAAG;AAC9B,aAAO;AAAA,IACT,QAAQ;AACN,+BAAyB;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,eAAqB;AAC5B,QAAI,CAAC,OAAO,QAAS;AACrB,QAAI,MAAM,WAAW,GAAG;AACtB,qBAAe,QAAQ;AACvB;AAAA,IACF;AACA,gBAAY,UAAU,KAAK,UAAU,KAAK,CAAC;AAAA,EAC7C;AAEA,WAAS,YAAkB;AACzB,QAAI,CAAC,OAAO,QAAS;AACrB,UAAM,WAAW,YAAY,QAAQ;AACrC,QAAI,CAAC,SAAU;AACf,QAAI;AACF,YAAM,UAAU,KAAK,MAAM,QAAQ;AACnC,YAAM,OAAO,GAAG,MAAM,QAAQ,GAAG,QAAQ,OAAO,YAAU,UAAU,OAAO,OAAO,cAAc,QAAQ,CAAC;AACzG,kBAAY,SAAS,MAAM;AAAA,IAC7B,QAAQ;AACN,qBAAe,QAAQ;AACvB,iBAAW;AAAA,QACT,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,QAAQ,QAA+B;AAC9C,UAAM,KAAK,MAAM;AACjB,WAAO,MAAM,SAAS,cAAc;AAClC,YAAM,UAAU,MAAM,MAAM;AAC5B,YAAM,aAAwE;AAAA,QAC5E,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AACA,UAAI,SAAS,cAAc,OAAW,YAAW,YAAY,QAAQ;AACrE,iBAAW,UAAU;AAAA,IACvB;AACA,gBAAY,SAAS,MAAM;AAC3B,iBAAa;AAAA,EACf;AAEA,WAAS,aAAa,SAA2D;AAC/E,UAAM,YAAY,OAAO,QAAQ,aAAa,SAAS,KAAK,CAAC;AAC7D,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,gBAAgB,OAAO,QAAQ,kBAAkB,qBAAqB,SAAS,SAAS,CAAC;AAAA,IAC3F;AAAA,EACF;AAEA,iBAAe,QAAQ,MAA8C;AACnE,UAAM,YAAY,OAAO,SAAS,WAAW;AAC7C,QAAI,OAAO,cAAc,YAAY;AACnC,YAAM,IAAI,MAAM,mBAAmB;AAAA,IACrC;AAEA,UAAM,WAAW,MAAM,UAAU,OAAO,UAAU;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB,WAAW;AAAA,IACb,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAAA,EAC7D;AAEA,YAAU;AAEV,SAAO;AAAA,IACL,MAAM,KAAK,SAAiD;AAC1D,YAAM,OAAO,aAAa,OAAO;AAEjC,UAAI,kBAAkB,IAAI,IAAI,iBAAiB;AAC7C,mBAAW;AAAA,UACT,WAAW,OAAO,KAAK,SAAS;AAAA,UAChC,QAAQ;AAAA,UACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AACD;AAAA,MACF;AAEA,kBAAY,YAAY;AACxB,UAAI;AACF,cAAM,QAAQ,IAAI;AAAA,MACpB,SAAS,OAAO;AACd,cAAM,gBAAgB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAC9E,oBAAY,aAAa;AACzB,gBAAQ;AAAA,UACN,WAAW,OAAO,KAAK,SAAS;AAAA,UAChC,SAAS,KAAK,IAAI;AAAA,UAClB,UAAU;AAAA,UACV,WAAW,cAAc;AAAA,UACzB,SAAS;AAAA,QACX,CAAC;AAAA,MACH,UAAE;AACA,oBAAY,YAAY;AACxB,oBAAY,SAAS,MAAM;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,MAAM,aAA4B;AAChC,WAAK,aAAa;AAClB,UAAI,MAAM,WAAW,KAAK,CAAC,KAAK,kBAAkB,EAAG;AAErD,kBAAY,YAAY;AACxB,UAAI;AACF,YAAI,cAAc;AAClB,iBAAS,QAAQ,GAAG,QAAQ,MAAM,UAAU,cAAc,aAAY;AACpE,gBAAM,SAAS,MAAM,KAAK;AAC1B,cAAI,CAAC,QAAQ;AACX,qBAAS;AACT;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,QAAQ,OAAO,OAAO;AAC5B,kBAAM,OAAO,OAAO,CAAC;AACrB,2BAAe;AACf,yBAAa;AAAA,UACf,SAAS,OAAO;AACd,kBAAM,gBAAgB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAC9E,mBAAO,YAAY;AACnB,mBAAO,YAAY,cAAc;AACjC,wBAAY,aAAa;AACzB,qBAAS;AACT,yBAAa;AACb;AAAA,UACF;AAAA,QACF;AAAA,MACF,UAAE;AACA,oBAAY,YAAY;AACxB,oBAAY,SAAS,MAAM;AAC3B,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AAAA,IACA,WAAW,QAAsB;AAC/B,iBAAW,UAAU,OAAO;AAC1B,mBAAW;AAAA,UACT,WAAW,OAAO;AAAA,UAClB;AAAA,UACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AAAA,MACH;AACA,YAAM,OAAO,GAAG,MAAM,MAAM;AAC5B,kBAAY,SAAS;AACrB,mBAAa;AAAA,IACf;AAAA,IACA,gBAAgB,QAA+B;AAC7C,cAAQ,MAAM;AAAA,IAChB;AAAA,IACA,eAAqB;AACnB,YAAM,MAAM,OAAO,cAAc;AACjC,YAAM,MAAM,KAAK,IAAI;AACrB,eAAS,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AACzD,cAAM,SAAS,MAAM,KAAK;AAC1B,YAAI,UAAU,MAAM,OAAO,UAAU,KAAK;AACxC,qBAAW;AAAA,YACT,WAAW,OAAO;AAAA,YAClB,QAAQ;AAAA,YACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC,CAAC;AACD,gBAAM,OAAO,OAAO,CAAC;AAAA,QACvB;AAAA,MACF;AACA,kBAAY,SAAS,MAAM;AAC3B,mBAAa;AAAA,IACf;AAAA,IACA,oBAA6B;AAC3B,UAAI,CAAC,OAAO,QAAS,QAAO;AAE5B,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,UAAU,YAAY,OAAO;AACnC,UAAI;AACJ,UAAI,SAAS;AACX,YAAI;AACF,yBAAe,KAAK,MAAM,OAAO;AAAA,QACnC,QAAQ;AACN,yBAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,cAAc,CAAC,cAAc,aAAa,aAAa,aAAa;AAC1E,YAAM,qBAAqB,cAAc,UAAU;AACnD,UAAI,CAAC,gBAAgB,eAAe,oBAAoB;AACtD,YAAI,CAAC,YAAY,SAAS,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,MAAM,UAAU,CAAC,CAAC,GAAG;AACvF,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAAA,IACA,oBAA0B;AACxB,UAAI,CAAC,OAAO,QAAS;AACrB,YAAM,UAAU,YAAY,OAAO;AACnC,UAAI,CAAC,QAAS;AAEd,UAAI;AACF,cAAM,eAAe,KAAK,MAAM,OAAO;AACvC,YAAI,aAAa,UAAU,OAAO;AAChC,yBAAe,OAAO;AAAA,QACxB;AAAA,MACF,QAAQ;AACN,uBAAe,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,IACA,iBAAyC;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACxVA,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAeD,SAAS,cAAc,OAAgB,OAA6B;AAClE,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,UAAQ,cAAc,MAAM,KAAK,CAAC;AAAA,EACrD;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,KAAgC,EAC5C,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,cAAc,IAAI,IAAI,YAAY,CAAC,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,CAAC,EACvF,IAAI,CAAC,CAAC,KAAK,WAAW,MAAM,CAAC,KAAK,cAAc,aAAa,KAAK,CAAC,CAAC;AAAA,IACzE;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,OAAgC,eAAyB,CAAC,GAA4B;AACvH,QAAM,QAAQ,IAAI,IAAI,aAAa,IAAI,SAAO,IAAI,YAAY,CAAC,CAAC;AAChE,SAAO,cAAc,OAAO,KAAK;AACnC;;;ACjDA,IAAM,eAAe,oBAAI,IAAI,CAAC,aAAa,aAAa,QAAQ,SAAS,eAAe,UAAU,SAAS,CAAC;AAOrG,SAAS,sBACd,UAOA,UAAgD,CAAC,GACtB;AAC3B,MAAI,QAAQ,SAAS,MAAO,QAAO,EAAE,IAAI,MAAM,QAAQ,CAAC,EAAE;AAC1D,QAAM,SAAmB,CAAC;AAC1B,MAAI,OAAO,SAAS,SAAS,SAAU,QAAO,KAAK,uBAAuB;AAC1E,MAAI,SAAS,SAAS,WAAW,OAAO,SAAS,UAAU,UAAU;AACnE,WAAO,KAAK,qCAAqC;AAAA,EACnD;AACA,MAAI,OAAO,SAAS,cAAc,SAAU,QAAO,KAAK,4BAA4B;AACpF,MAAI,OAAO,SAAS,cAAc,SAAU,QAAO,KAAK,iCAAiC;AACzF,aAAW,OAAO,OAAO,KAAK,SAAS,cAAc,CAAC,CAAC,GAAG;AACxD,QAAI,aAAa,IAAI,GAAG,EAAG,QAAO,KAAK,cAAc,GAAG,cAAc;AAAA,EACxE;AACA,SAAO,EAAE,IAAI,OAAO,WAAW,GAAG,OAAO;AAC3C;;;ACHA,SAASA,UAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC;AACnF;AAEA,SAAS,mBAAmB,QAAkC;AAC5D,QAAM,OAAO,OAAO,WAAW;AAC/B,SAAO,GAAG,KAAK,QAAQ,OAAO,EAAE,CAAC;AACnC;AAEA,SAAS,oBAAoB;AAC3B,QAAM,gBAAgB,iBAAiB;AACvC,MAAI;AACF,WAAO,eAAe;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAqB5B,YAAY,QAA0B;AApBtC,SAAO,cAAc;AACrB,SAAO,QAAmB,CAAC;AAC3B,SAAO,UAAU;AASjB,SAAQ,gBAAgB;AAUtB,SAAK,SAAS;AACd,SAAK,WAAW,mBAAmB,MAAM;AACzC,UAAM,UAAU,kBAAkB;AAClC,UAAM,iBAA8D;AAAA,MAClE,UAAU,KAAK;AAAA,IACjB;AACA,QAAI,OAAO,UAAU,iBAAiB,OAAW,gBAAe,eAAe,OAAO,SAAS;AAC/F,QAAI,OAAO,UAAU,eAAe,OAAW,gBAAe,aAAa,OAAO,SAAS;AAC3F,QAAI,OAAO,UAAU,iBAAiB,OAAW,gBAAe,eAAe,OAAO,SAAS;AAC/F,QAAI,OAAO,UAAU,oBAAoB,OAAW,gBAAe,kBAAkB,OAAO,SAAS;AACrG,QAAI,OAAO,UAAU,oBAAoB,OAAW,gBAAe,kBAAkB,OAAO,SAAS;AACrG,QAAI,OAAO,UAAU,cAAc,OAAW,gBAAe,YAAY,OAAO,SAAS;AACzF,QAAI,OAAO,WAAW,OAAW,gBAAe,SAAS,OAAO;AAChE,QAAI,OAAO,YAAY,OAAW,gBAAe,UAAU,OAAO;AAClE,SAAK,WAAW,sBAAsB,UAAU;AAAA,MAC9C,GAAG;AAAA,MACH;AAAA,IACF,IAAI,cAAc;AAClB,SAAK,sBAAsB,OAAO,UAAU,gBAAgB;AAC5D,SAAK,eAAe,KAAK;AACzB,SAAK,kBAAkB,OAAO,UAAU,mBAAmB;AAC3D,SAAK,WAAW,OAAO,YAAY,OAAO,SAAS;AACnD,SAAK,WAAW,EAAE,aAAaA,UAAS,MAAM,EAAE;AAChD,SAAK,eAAe,iBAAiB,OAAO,eAAe,OAAO,OAAO;AACzE,SAAK,cAAc,KAAK,aAAa;AACrC,QAAI,CAAC,OAAO,UAAU,uBAAuB;AAC3C,WAAK,sBAAsB;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,WAAW,OAAe,aAAsC,CAAC,GAAG,UAA2B,CAAC,GAAS;AACvG,SAAK,kBAAkB,SAAS,OAAO,YAAY,OAAO;AAAA,EAC5D;AAAA,EAEA,KAAK,MAAe,aAAsC,CAAC,GAAG,UAA2B,CAAC,GAAS;AACjG,SAAK,kBAAkB,QAAQ,aAAa,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO;AAAA,EAC9E;AAAA,EAEA,gBAAsB;AACpB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,SAAS,QAAgB,SAAkC,CAAC,GAAG,UAA2B,CAAC,GAAS;AAClG,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,QAAQ,OAAO;AACnD,SAAK,kBAAkB,YAAY,YAAY,EAAE,QAAQ,OAAO,GAAG,OAAO;AAAA,EAC5E;AAAA,EAEA,aAAa,QAAgB,SAAkC,CAAC,GAAS;AACvE,SAAK,SAAS,QAAQ,MAAM;AAAA,EAC9B;AAAA,EAEA,MAAM,SAAiB,SAAkC,CAAC,GAAG,UAA2B,CAAC,GAAS;AAChG,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,QAAQ;AAC5C,SAAK,kBAAkB,SAAS,SAAS,EAAE,SAAS,OAAO,GAAG,OAAO;AAAA,EACvE;AAAA,EAEA,MAAM,YAAoB,QAAgB,UAA2B,CAAC,GAAS;AAC7E,SAAK,kBAAkB,SAAS,SAAS,EAAE,YAAY,OAAO,GAAG,OAAO;AAAA,EAC1E;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,SAAS,WAAW;AAC/B,UAAM,cAAc,KAAK,SAAS,eAAe;AACjD,SAAK,UAAU,YAAY,SAAS;AACpC,SAAK,YAAY,YAAY;AAC7B,QAAI,YAAY,SAAS,GAAG;AAC1B,WAAK,mBAAmB;AAAA,IAC1B,OAAO;AACL,WAAK,eAAe,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,WAAW,EAAE,aAAaA,UAAS,MAAM,EAAE;AAChD,SAAK,QAAQ,CAAC;AACd,SAAK,UAAU;AACf,QAAI,KAAK,eAAe,QAAW;AACjC,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,SAAS,WAAW,cAAc;AAAA,EACzC;AAAA,EAEA,WAAW,SAAgC;AACzC,SAAK,eAAe,OAAO,YAAY,WACnC,aAAa,KAAK,cAAc,OAAO,IACvC,iBAAiB,OAAO;AAC5B,SAAK,cAAc,KAAK,aAAa;AACrC,QAAI,CAAC,kBAAkB,KAAK,cAAc,WAAW,GAAG;AACtD,WAAK,QAAQ,CAAC;AACd,WAAK,SAAS,WAAW,iBAAiB;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,YAA6B;AAC3B,UAAM,sBAAsB,KAAK,SAAS,eAAe;AACzD,UAAM,SAA0B;AAAA,MAC9B,aAAa,KAAK;AAAA,MAClB,SAAS,KAAK;AAAA,MACd,iBAAiB,KAAK;AAAA,MACtB,WAAW,oBAAoB;AAAA,MAC/B,SAAS,KAAK,WAAW,oBAAoB,SAAS;AAAA,MACtD,eAAe,KAAK,gBAAgB,oBAAoB,QAAQ;AAAA,MAChE,UAAU;AAAA,IACZ;AACA,UAAMC,aAAY,KAAK,aAAa,oBAAoB;AACxD,QAAIA,eAAc,OAAW,QAAO,YAAYA;AAChD,QAAI,KAAK,qBAAqB,OAAW,QAAO,mBAAmB,KAAK;AACxE,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,SAAwB;AAChC,SAAK,KAAK,SAAS,KAAK,OAAkC,EAAE,KAAK,MAAM;AACrE,YAAM,cAAc,KAAK,SAAS,eAAe;AACjD,WAAK,UAAU,YAAY,SAAS;AACpC,WAAK,YAAY,YAAY;AAC7B,UAAI,YAAY,SAAS,GAAG;AAC1B,aAAK,mBAAmB;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,wBAA8B;AACpC,UAAM,gBAAgB,iBAAiB;AACvC,QAAI,CAAC,cAAe;AACpB,QAAI,OAAO,cAAc,qBAAqB,WAAY;AAC1D,QAAI,OAAO,cAAc,wBAAwB,WAAY;AAE7D,UAAM,mBAAmB,MAAM;AAC7B,WAAK,KAAK,MAAM;AAAA,IAClB;AACA,UAAM,oBAAoB,MAAM;AAC9B,UAAI,cAAc,UAAU,oBAAoB,UAAU;AACxD,aAAK,KAAK,MAAM;AAAA,MAClB;AAAA,IACF;AAEA,kBAAc,iBAAiB,UAAU,gBAAgB;AACzD,kBAAc,iBAAiB,YAAY,gBAAgB;AAC3D,QAAI,OAAO,cAAc,UAAU,qBAAqB,YAAY;AAClE,oBAAc,SAAS,iBAAiB,oBAAoB,iBAAiB;AAAA,IAC/E;AAEA,SAAK,mBAAmB,MAAM;AAC5B,oBAAc,oBAAoB,UAAU,gBAAgB;AAC5D,oBAAc,oBAAoB,YAAY,gBAAgB;AAC9D,UAAI,OAAO,cAAc,UAAU,wBAAwB,YAAY;AACrE,sBAAc,SAAS,oBAAoB,oBAAoB,iBAAiB;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBAA2B;AACjC,QAAI,KAAK,eAAe,OAAW;AAEnC,UAAM,QAAQ,KAAK,IAAI,KAAK,cAAc,KAAK,eAAe;AAC9D,SAAK,aAAa,WAAW,MAAM;AACjC,WAAK,aAAa;AAClB,WAAK,KAAK,MAAM,EAAE,KAAK,MAAM;AAC3B,YAAI,KAAK,SAAS,eAAe,EAAE,SAAS,GAAG;AAC7C,eAAK,eAAe,KAAK,IAAI,KAAK,eAAe,GAAG,KAAK,eAAe;AACxE,eAAK,mBAAmB;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH,GAAG,KAAK;AAAA,EACV;AAAA,EAEQ,kBACN,MACA,OACA,YACA,SACM;AACN,SAAK,KAAK,oBAAoB,MAAM,OAAO,YAAY,OAAO;AAAA,EAChE;AAAA,EAEA,MAAc,oBACZ,MACA,OACA,YACA,SACe;AACf,QAAI,CAAC,kBAAkB,KAAK,cAAc,WAAW,GAAG;AACtD,WAAK,WAAW,MAAM,kBAAkB,KAAK;AAC7C;AAAA,IACF;AAEA,QAAI,WAA6B;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,YAAY,mBAAmB,UAAU;AAAA,MACzC,WAAW,QAAQ,aAAaD,UAAS,KAAK;AAAA,MAC9C,WAAW,QAAQ,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACvD,SAAS,QAAQ,WAAW,CAAC;AAAA,MAC7B,aAAa,KAAK,SAAS;AAAA,MAC3B,UAAU,KAAK,OAAO;AAAA,MACtB,aAAa,KAAK,OAAO;AAAA,MACzB,OAAO,KAAK,OAAO;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,IAChB;AAEA,QAAI,KAAK,SAAS,WAAW,OAAW,UAAS,SAAS,KAAK,SAAS;AACxE,QAAI,KAAK,SAAS,YAAY,OAAW,UAAS,UAAU,KAAK,SAAS;AAE1E,QAAI,KAAK,OAAO,eAAe,QAAW;AACxC,YAAM,mBAAmB,MAAM,KAAK,OAAO,WAAW,QAAQ;AAC9D,UAAI,qBAAqB,MAAM;AAC7B,aAAK,WAAW,MAAM,uBAAuB,KAAK;AAClD;AAAA,MACF;AACA,iBAAW;AAAA,QACT,GAAG;AAAA,QACH,GAAG;AAAA,QACH,YAAY,mBAAmB,iBAAiB,cAAc,SAAS,UAAU;AAAA,MACnF;AAAA,IACF;AAEA,UAAM,aAAa,sBAAsB,UAAU,EAAE,MAAM,KAAK,OAAO,oBAAoB,OAAO,CAAC;AACnG,QAAI,CAAC,WAAW,MAAM,KAAK,OAAO,qBAAqB,UAAU;AAC/D,WAAK,WAAW,MAAM,mBAAmB,KAAK;AAC9C;AAAA,IACF;AACA,QAAI,CAAC,WAAW,IAAI;AAClB,WAAK,YAAY,2BAA2B,WAAW,OAAO,KAAK,IAAI,CAAC;AAAA,IAC1E;AAEA,SAAK,UAAU,QAAQ;AAAA,EACzB;AAAA,EAEQ,WAAW,MAA2B,QAA+B,OAAsB;AACjG,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AAAA,MACtB;AAAA,MACA;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AACA,QAAI,UAAU,OAAW,MAAK,iBAAiB,QAAQ;AACvD,SAAK,YAAY,WAAW,IAAI,oBAAoB,MAAM;AAAA,EAC5D;AACF;;;ACvRO,SAAS,iCAAgE;AAC9E,QAAM,gBAAgB,iBAAiB;AACvC,SAAO,eAAe;AACxB;AAEO,SAAS,wBAA8C;AAC5D,MAAI,CAAC,iBAAiB,GAAG;AACvB,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEA,QAAM,gBAAgB,iBAAiB;AACvC,MAAI,CAAC,eAAe,kBAAkB;AACpC,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AAEA,SAAO,cAAc;AACvB;;;ACvBA,IAAI;AACJ,IAAI;AACJ,IAAI,gBAAgB;AACpB,IAAI;AACJ,IAAI;AAEJ,SAAS,mBAAmB,UAA0D;AACpF,SAAO;AAAA,IACL,UAAU;AAAA,IACV,MAAM,OAAO,YAAY,SAAS;AAChC,UAAI,SAAS,YAAY;AACvB,iBAAS,WAAW,OAAO,YAAY,OAAO;AAC9C;AAAA,MACF;AACA,eAAS,YAAY,EAAE,WAAW,OAAO,OAAO,YAAY,QAAQ,CAAC;AAAA,IACvE;AAAA,IACA,SAAS,QAAQ,QAAQ,SAAS;AAChC,UAAI,SAAS,UAAU;AACrB,iBAAS,SAAS,QAAQ,QAAQ,OAAO;AACzC;AAAA,MACF;AACA,eAAS,eAAe,QAAQ,MAAM;AAAA,IACxC;AAAA,IACA,KAAK,MAAM,YAAY,SAAS;AAC9B,UAAI,SAAS,MAAM;AACjB,iBAAS,KAAK,MAAM,YAAY,OAAO;AACvC;AAAA,MACF;AACA,eAAS,gBAAgB;AAAA,IAC3B;AAAA,IACA,MAAM,SAAS,QAAQ,SAAS;AAC9B,eAAS,QAAQ,SAAS,QAAQ,OAAO;AAAA,IAC3C;AAAA,IACA,MAAM,YAAY,QAAQ,SAAS;AACjC,eAAS,QAAQ,YAAY,QAAQ,OAAO;AAAA,IAC9C;AAAA,IACA,MAAM,QAAQ;AACZ,YAAM,SAAS,QAAQ;AAAA,IACzB;AAAA,IACA,QAAQ;AACN,eAAS,QAAQ;AACjB,kBAAY;AACZ,wBAAkB;AAAA,IACpB;AAAA,IACA,WAAW,SAAS;AAClB,UAAI,SAAS,YAAY;AACvB,iBAAS,WAAW,OAAO;AAC3B;AAAA,MACF;AACA,UAAI,OAAO,YAAY,UAAU;AAC/B,iBAAS,cAAc;AAAA,MACzB;AAAA,IACF;AAAA,IACA,YAAY;AACV,UAAI,SAAS,WAAW;AACtB,eAAO,SAAS,UAAU;AAAA,MAC5B;AACA,aAAO,aAAa;AAAA,IACtB;AAAA,EACF;AACF;AAEA,SAAS,aAAa,UAA0D;AAC9E,cAAY;AACZ,oBAAkB,mBAAmB,QAAQ;AAC7C,SAAO;AACT;AAEA,SAAS,mBAAmB,MAA2B,OAAsB;AAC3E,mBAAiB;AACjB,qBAAmB;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,MAAI,UAAU,QAAW;AACvB,qBAAiB,QAAQ;AAAA,EAC3B;AACA,cAAY,WAAW,IAAI;AAC7B;AAEO,SAAS,WAAW,QAAsD;AAC/E,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,uBAAuB,MAAM;AAClD,QAAM,mBAAmB,+BAA+B;AACxD,MAAI,kBAAkB;AACpB,WAAO,aAAa,gBAAgB;AAAA,EACtC;AAEA,MAAI;AACF,QAAI;AACJ,QAAI;AACF,YAAM,YAAY,sBAAsB;AACxC,iBAAW,IAAI,UAAU,YAAY;AAAA,IACvC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,wBAAwB,GAAG;AAC9E,mBAAW,IAAI,iBAAiB,MAAM;AAAA,MACxC,OAAO;AACL,cAAM;AAAA,MACR;AAAA,IACF;AACA,WAAO,aAAa,QAAQ;AAAA,EAC9B,SAAS,OAAO;AACd,gBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,UAAM;AAAA,EACR;AACF;AAEO,SAAS,YAAoD;AAClE,SAAO;AACT;AAEO,SAAS,MAAM,OAAe,YAAsC,SAAiC;AAC1G,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,SAAS,KAAK;AACjC;AAAA,EACF;AACA,MAAI,MAAM,OAAO,YAAY,OAAO;AACtC;AAEO,SAAS,SAAS,QAAgB,QAAkC,SAAiC;AAC1G,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,UAAU;AAC7B;AAAA,EACF;AACA,MAAI,SAAS,QAAQ,QAAQ,OAAO;AACtC;AAEO,SAAS,KAAK,MAAe,YAAsC,SAAiC;AACzG,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,MAAM;AACzB;AAAA,EACF;AACA,MAAI,KAAK,MAAM,YAAY,OAAO;AACpC;AAmCO,SAAS,WAAW,SAAgC;AACzD,YAAU,GAAG,WAAW,OAAO;AACjC;AAYO,SAAS,eAAgC;AAC9C,MAAI,WAAW,WAAW;AACxB,WAAO,UAAU,UAAU;AAAA,EAC7B;AAEA,QAAM,SAA0B;AAAA,IAC9B,aAAa,QAAQ,WAAW,eAAe,SAAS;AAAA,IACxD,SAAS,WAAW,eAAe;AAAA,IACnC,WAAW,WAAW,OAAO,UAAU;AAAA,IACvC,SAAS,QAAQ,WAAW,OAAO;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,cAAc,QAAW;AAC3B,WAAO,YAAY;AAAA,EACrB;AACA,MAAI,qBAAqB,QAAW;AAClC,WAAO,mBAAmB;AAAA,EAC5B;AAEA,SAAO;AACT;;;ATrLS;AA/CF,IAAM,aAAa,MAAM,cAA4C,MAAS;AAU9E,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAuC,MAAM,UAAU,CAAC;AAE1F,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,QAAS;AAEd,QAAI;AACF,YAAM,oBAAoB,WAAW,MAAM;AAC3C,YAAM,oBAAoB,OAAO,eAAe,OAAO;AACvD,UAAI,sBAAsB,QAAW;AACnC,0BAAkB,WAAW,iBAAiB;AAAA,MAChD;AACA,gBAAU,iBAAiB;AAC3B,gBAAU,iBAAiB;AAAA,IAC7B,SAAS,OAAO;AACd,YAAM,kBAAkB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAChF,gBAAU,eAAe;AAAA,IAC3B;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,oBAAC,WAAW,UAAX,EAAoB,OAAO,QAAS,UAAS;AACvD;;;AUlDA,OAAOE,YAAW;AAQX,SAAS,4BACd,UACA,QACA,UAAsC,CAAC,GACjC;AACN,QAAM,eAAeC,OAAM,OAA2B,MAAS;AAC/D,QAAM,WAAW,WAAW,GAAG,QAAQ,IAAI,UAAU,EAAE,KAAK;AAE5D,EAAAA,OAAM,UAAU,MAAM;AACpB,QAAI,CAAC,YAAY,CAAC,YAAY,aAAa,YAAY,SAAU;AAEjE,iBAAa,UAAU;AACvB,SAAK,QAAQ,MAAM;AAAA,MACjB,GAAG,QAAQ;AAAA,MACX;AAAA,MACA,QAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,MAAM,QAAQ,YAAY,UAAU,UAAU,MAAM,CAAC;AACnE;;;AC1BA,OAAOC,YAAW;AASX,SAAS,8BACd,QACA,UAAsC,CAAC,GACjC;AACN,QAAM,eAAeC,OAAM,OAA2B,MAAS;AAC/D,QAAM,WAAW,QAAQ,UAAU,QAAQ,YAAY;AAEvD,EAAAA,OAAM,UAAU,MAAM;AACpB,QAAI,CAAC,YAAY,aAAa,YAAY,SAAU;AAEpD,iBAAa,UAAU;AACvB,SAAK,QAAQ,MAAM;AAAA,MACjB,GAAG,QAAQ;AAAA,MACX,OAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,MAAM,QAAQ,YAAY,QAAQ,CAAC;AACjD;;;AC3BA,OAAOC,YAAW;AAeX,SAAS,YAA0C;AACxD,SAAOC,OAAM,WAAW,UAAU;AACpC;AAEO,SAAS,gBAIN;AACR,SAAOA,OAAM,YAAY,CAAC,OAAe,YAAsC,YAA8B;AAC3G,UAAM,OAAO,YAAY,OAAO;AAAA,EAClC,GAAG,CAAC,CAAC;AACP;AAEO,SAAS,cAA0E;AACxF,SAAOA,OAAM,YAAY,CAAC,QAAgB,WAAqC;AAC7E,aAAS,QAAQ,MAAM;AAAA,EACzB,GAAG,CAAC,CAAC;AACP;AAwCO,SAAS,gBAAoD;AAClE,SAAOC,OAAM,YAAY,CAAC,YAA6B;AACrD,eAAW,OAAO;AAAA,EACpB,GAAG,CAAC,CAAC;AACP;AAEO,SAAS,eAAgC;AAC9C,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,QAAQ,SAAS,IAAIA,OAAM,SAA0B,MAAM,aAAa,CAAC;AAEhF,EAAAA,OAAM,UAAU,MAAM;AACpB,cAAU,aAAa,CAAC;AAAA,EAC1B,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;","names":["createId","lastError","React","React","React","React","React","React","React"]}
1
+ {"version":3,"sources":["../../src/react/DmdProvider.tsx","../../src/core/backend-payload.ts","../../src/core/environment.ts","../../src/browser/core/consent.ts","../../src/browser/core/delivery.ts","../../src/browser/core/privacy.ts","../../src/browser/core/schema.ts","../../src/browser/core/DriveMetaDataSDK.ts","../../src/browser/client.ts","../../src/next/useDmdAppRouterPageTracking.ts","../../src/next/useDmdPagesRouterPageTracking.ts","../../src/react/hooks.ts"],"sourcesContent":["import React from 'react';\nimport { getDmdSDK, initDmdSDK } from '../browser/client';\nimport type { DmdBrowserClient, DmdBrowserConfig } from '../core/types';\n\nexport const DmdContext = React.createContext<DmdBrowserClient | undefined>(undefined);\n\nexport interface DmdProviderProps {\n config: DmdBrowserConfig;\n children: React.ReactNode;\n enabled?: boolean;\n onReady?: (client: DmdBrowserClient) => void;\n onError?: (error: Error) => void;\n}\n\nexport function DmdProvider({\n config,\n children,\n enabled = true,\n onReady,\n onError\n}: DmdProviderProps) {\n const [client, setClient] = React.useState<DmdBrowserClient | undefined>(() => getDmdSDK());\n\n React.useEffect(() => {\n if (!enabled) return;\n\n try {\n const initializedClient = initDmdSDK(config);\n const configuredConsent = config.gdprConsent ?? config.consent;\n if (configuredConsent !== undefined) {\n initializedClient.setConsent(configuredConsent);\n }\n setClient(initializedClient);\n onReady?.(initializedClient);\n } catch (error) {\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n onError?.(normalizedError);\n }\n }, [\n enabled,\n config.clientId,\n config.workspaceId,\n config.appId,\n config.writeKey,\n config.token,\n config.apiHost,\n config.consent,\n config.gdprConsent,\n onReady,\n onError\n ]);\n\n return <DmdContext.Provider value={client}>{children}</DmdContext.Provider>;\n}\n","function formatUtcTimestamp(value: unknown): string {\n if (typeof value !== 'string') return new Date().toISOString().replace('T', ' ').slice(0, 19);\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: input.requestId,\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: eventData.anonymousId ?? input.anonymousId,\n sessionId: eventData.sessionId ?? input.sessionId,\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","export function isBrowserRuntime(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function getBrowserWindow(): Window | undefined {\n return typeof window === 'undefined' ? undefined : window;\n}\n","import type {\n DmdConsentInput,\n DmdConsentPurpose,\n DmdConsentState,\n DmdPurposeConsent\n} from './types';\n\nexport type DmdResolvedConsent = Record<DmdConsentPurpose, DmdConsentState>;\n\nconst purposes: DmdConsentPurpose[] = [\n 'analytics',\n 'advertising',\n 'personalization',\n 'functional',\n 'saleOfData'\n];\n\nfunction normalizeConsentValue(value: unknown): DmdConsentState {\n if (value === true) return 'granted';\n if (value === false) return 'denied';\n if (value === 'granted' || value === 'denied' || value === 'pending') return value;\n return 'pending';\n}\n\nexport function normalizeConsent(input: DmdConsentInput | undefined): DmdResolvedConsent {\n const defaultValue = normalizeConsentValue(input ?? 'pending');\n const resolved = Object.fromEntries(\n purposes.map(purpose => [purpose, defaultValue])\n ) as DmdResolvedConsent;\n\n if (input && typeof input === 'object') {\n for (const purpose of purposes) {\n const value = input[purpose];\n if (value !== undefined) {\n resolved[purpose] = normalizeConsentValue(value);\n }\n }\n }\n\n return resolved;\n}\n\nexport function mergeConsent(current: DmdResolvedConsent, update: DmdPurposeConsent): DmdResolvedConsent {\n const next = { ...current };\n for (const [purpose, value] of Object.entries(update) as Array<[DmdConsentPurpose, DmdConsentState]>) {\n next[purpose] = normalizeConsentValue(value);\n }\n return next;\n}\n\nexport function canCollectPurpose(consent: DmdResolvedConsent, purpose: DmdConsentPurpose): boolean {\n return consent[purpose] === 'granted';\n}\n","export interface DmdQueuedRecord {\n messageId: string;\n savedAt: number;\n attempts: number;\n lastError?: string;\n payload: Record<string, unknown>;\n}\n\nexport interface DmdDeliveryDiagnostics {\n queued: number;\n inFlight: number;\n dropped: Array<{ messageId?: string; reason: string; timestamp: string }>;\n lastError?: string;\n}\n\nexport interface DmdDeliveryManager {\n send(payload: Record<string, unknown>): Promise<void>;\n flushQueue(): Promise<void>;\n clearQueue(reason: string): void;\n enqueueForTests(record: DmdQueuedRecord): void;\n flushExpired(): void;\n acquireFlushLease(): boolean;\n releaseFlushLease(): void;\n getDiagnostics(): DmdDeliveryDiagnostics;\n}\n\nexport interface DmdDeliveryStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): unknown;\n removeItem(key: string): unknown;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return JSON.stringify(value);\n }\n return JSON.stringify(\n Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([left], [right]) => left.localeCompare(right))\n )\n );\n}\n\nfunction createIdempotencyKey(payload: Record<string, unknown>, messageId: string): string {\n const metaData = payload.metaData as Record<string, unknown> | undefined;\n const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? 'event');\n const properties = (metaData ?? payload.properties) as Record<string, unknown> | undefined;\n const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;\n if (orderId !== undefined) return `${event}:${String(orderId)}`;\n return `${event}:${stableStringify(properties ?? {}) || messageId}`;\n}\n\nexport function createDeliveryManager(config: {\n endpoint: string;\n fetch?: typeof fetch;\n queueTtlMs?: number;\n maxQueueSize?: number;\n storage?: DmdDeliveryStorage;\n queueKey?: string;\n lockKey?: string;\n lockTtlMs?: number;\n tabId?: string;\n retryDelayMs?: number;\n maxRetryDelayMs?: number;\n maxPayloadBytes?: number;\n batchSize?: number;\n onDrop?: (event: { messageId?: string; reason: string; timestamp: string }) => void;\n onError?: (error: Error) => void;\n}): DmdDeliveryManager {\n const queue: DmdQueuedRecord[] = [];\n const diagnostics: DmdDeliveryDiagnostics = { queued: 0, inFlight: 0, dropped: [] };\n const maxQueueSize = config.maxQueueSize ?? 100;\n const queueKey = config.queueKey ?? 'dmd_delivery_queue';\n const lockKey = config.lockKey ?? 'dmd_delivery_flush_lock';\n const lockTtlMs = config.lockTtlMs ?? 5_000;\n const tabId = config.tabId ?? createId('tab');\n const batchSize = config.batchSize ?? 25;\n const maxPayloadBytes = config.maxPayloadBytes ?? 64_000;\n\n function recordDrop(event: { messageId?: string; reason: string; timestamp: string }): void {\n diagnostics.dropped.push(event);\n config.onDrop?.(event);\n }\n\n function recordError(error: Error): void {\n diagnostics.lastError = error.message;\n config.onError?.(error);\n }\n\n function payloadByteLength(payload: Record<string, unknown>): number {\n const serialized = JSON.stringify(payload);\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(serialized).length;\n }\n return serialized.length;\n }\n\n function recordStorageUnavailable(): void {\n recordDrop({\n reason: 'storage_unavailable',\n timestamp: new Date().toISOString()\n });\n }\n\n function safeGetItem(key: string): string | null {\n try {\n return config.storage?.getItem(key) ?? null;\n } catch {\n recordStorageUnavailable();\n return null;\n }\n }\n\n function safeSetItem(key: string, value: string): boolean {\n try {\n config.storage?.setItem(key, value);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function safeRemoveItem(key: string): boolean {\n try {\n config.storage?.removeItem(key);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function persistQueue(): void {\n if (!config.storage) return;\n if (queue.length === 0) {\n safeRemoveItem(queueKey);\n return;\n }\n safeSetItem(queueKey, JSON.stringify(queue));\n }\n\n function loadQueue(): void {\n if (!config.storage) return;\n const rawQueue = safeGetItem(queueKey);\n if (!rawQueue) return;\n try {\n const records = JSON.parse(rawQueue) as DmdQueuedRecord[];\n queue.splice(0, queue.length, ...records.filter(record => record && typeof record.messageId === 'string'));\n diagnostics.queued = queue.length;\n } catch {\n safeRemoveItem(queueKey);\n recordDrop({\n reason: 'queue_corrupt',\n timestamp: new Date().toISOString()\n });\n }\n }\n\n function enqueue(record: DmdQueuedRecord): void {\n queue.push(record);\n while (queue.length > maxQueueSize) {\n const dropped = queue.shift();\n const diagnostic: { messageId?: string; reason: string; timestamp: string } = {\n reason: 'queue_limit_exceeded',\n timestamp: new Date().toISOString()\n };\n if (dropped?.messageId !== undefined) diagnostic.messageId = dropped.messageId;\n recordDrop(diagnostic);\n }\n diagnostics.queued = queue.length;\n persistQueue();\n }\n\n function withEnvelope(payload: Record<string, unknown>): Record<string, unknown> {\n const metaData = payload.metaData as Record<string, unknown> | undefined;\n const messageId = String(metaData?.requestId ?? payload.messageId ?? createId('msg'));\n if (metaData) {\n return {\n ...payload,\n metaData: {\n ...metaData,\n requestId: messageId\n }\n };\n }\n return {\n ...payload,\n messageId,\n idempotencyKey: String(payload.idempotencyKey ?? createIdempotencyKey(payload, messageId))\n };\n }\n\n async function deliver(body: Record<string, unknown>): Promise<void> {\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new Error('fetch_unavailable');\n }\n\n const response = await fetchImpl(config.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n keepalive: true\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n }\n\n loadQueue();\n\n return {\n async send(payload: Record<string, unknown>): Promise<void> {\n const body = withEnvelope(payload);\n\n if (payloadByteLength(body) > maxPayloadBytes) {\n recordDrop({\n messageId: String((body.metaData as Record<string, unknown> | undefined)?.requestId ?? body.messageId),\n reason: 'payload_too_large',\n timestamp: new Date().toISOString()\n });\n return;\n }\n\n diagnostics.inFlight += 1;\n try {\n await deliver(body);\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n recordError(deliveryError);\n enqueue({\n messageId: String((body.metaData as Record<string, unknown> | undefined)?.requestId ?? body.messageId),\n savedAt: Date.now(),\n attempts: 1,\n lastError: deliveryError.message,\n payload: body\n });\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n }\n },\n async flushQueue(): Promise<void> {\n this.flushExpired();\n if (queue.length === 0 || !this.acquireFlushLease()) return;\n\n diagnostics.inFlight += 1;\n try {\n let sentInBatch = 0;\n for (let index = 0; index < queue.length && sentInBatch < batchSize;) {\n const record = queue[index];\n if (!record) {\n index += 1;\n continue;\n }\n\n try {\n await deliver(record.payload);\n queue.splice(index, 1);\n sentInBatch += 1;\n persistQueue();\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n record.attempts += 1;\n record.lastError = deliveryError.message;\n recordError(deliveryError);\n index += 1;\n persistQueue();\n break;\n }\n }\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n this.releaseFlushLease();\n }\n },\n clearQueue(reason: string): void {\n for (const record of queue) {\n recordDrop({\n messageId: record.messageId,\n reason,\n timestamp: new Date().toISOString()\n });\n }\n queue.splice(0, queue.length);\n diagnostics.queued = 0;\n persistQueue();\n },\n enqueueForTests(record: DmdQueuedRecord): void {\n enqueue(record);\n },\n flushExpired(): void {\n const ttl = config.queueTtlMs ?? 86_400_000;\n const now = Date.now();\n for (let index = queue.length - 1; index >= 0; index -= 1) {\n const record = queue[index];\n if (record && now - record.savedAt > ttl) {\n recordDrop({\n messageId: record.messageId,\n reason: 'queue_ttl_expired',\n timestamp: new Date().toISOString()\n });\n queue.splice(index, 1);\n }\n }\n diagnostics.queued = queue.length;\n persistQueue();\n },\n acquireFlushLease(): boolean {\n if (!config.storage) return true;\n\n const now = Date.now();\n const rawLock = safeGetItem(lockKey);\n let existingLock: { owner?: string; expiresAt?: number } | undefined;\n if (rawLock) {\n try {\n existingLock = JSON.parse(rawLock) as { owner?: string; expiresAt?: number };\n } catch {\n existingLock = undefined;\n }\n }\n\n const lockExpired = !existingLock?.expiresAt || existingLock.expiresAt <= now;\n const lockOwnedByThisTab = existingLock?.owner === tabId;\n if (!existingLock || lockExpired || lockOwnedByThisTab) {\n if (!safeSetItem(lockKey, JSON.stringify({ owner: tabId, expiresAt: now + lockTtlMs }))) {\n return true;\n }\n return true;\n }\n\n return false;\n },\n releaseFlushLease(): void {\n if (!config.storage) return;\n const rawLock = safeGetItem(lockKey);\n if (!rawLock) return;\n\n try {\n const existingLock = JSON.parse(rawLock) as { owner?: string };\n if (existingLock.owner === tabId) {\n safeRemoveItem(lockKey);\n }\n } catch {\n safeRemoveItem(lockKey);\n }\n },\n getDiagnostics(): DmdDeliveryDiagnostics {\n return diagnostics;\n }\n };\n}\n","const sensitiveKeys = new Set([\n 'email',\n 'phone',\n 'mobile',\n 'address',\n 'address1',\n 'address2',\n 'first_name',\n 'last_name',\n 'name',\n 'token',\n 'secret',\n 'password',\n 'session',\n 'cookie'\n]);\n\nexport function redactUrl(\n url: string,\n allowQueryKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']\n): string {\n const parsed = new URL(url, 'https://placeholder.local');\n for (const key of Array.from(parsed.searchParams.keys())) {\n if (!allowQueryKeys.includes(key)) {\n parsed.searchParams.set(key, '[REDACTED]');\n }\n }\n return url.startsWith('http') ? parsed.toString() : `${parsed.pathname}${parsed.search}`;\n}\n\nfunction sanitizeValue(value: unknown, allow: Set<string>): unknown {\n if (Array.isArray(value)) {\n return value.map(item => sanitizeValue(item, allow));\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .filter(([key]) => !sensitiveKeys.has(key.toLowerCase()) || allow.has(key.toLowerCase()))\n .map(([key, nestedValue]) => [key, sanitizeValue(nestedValue, allow)])\n );\n }\n\n return value;\n}\n\nexport function sanitizeProperties(input: Record<string, unknown>, allowRawKeys: string[] = []): Record<string, unknown> {\n const allow = new Set(allowRawKeys.map(key => key.toLowerCase()));\n return sanitizeValue(input, allow) as Record<string, unknown>;\n}\n\nexport async function sha256LowerTrimmed(value: string): Promise<string> {\n const bytes = new TextEncoder().encode(value.trim().toLowerCase());\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n return Array.from(new Uint8Array(digest)).map(byte => byte.toString(16).padStart(2, '0')).join('');\n}\n","const reservedKeys = new Set(['messageId', 'timestamp', 'type', 'event', 'anonymousId', 'userId', 'context']);\n\nexport interface DmdSchemaValidationResult {\n ok: boolean;\n errors: string[];\n}\n\nexport function validateEventEnvelope(\n envelope: {\n type?: unknown;\n event?: unknown;\n properties?: Record<string, unknown>;\n messageId?: unknown;\n timestamp?: unknown;\n },\n options: { mode?: 'off' | 'warn' | 'strict' } = {}\n): DmdSchemaValidationResult {\n if (options.mode === 'off') return { ok: true, errors: [] };\n const errors: string[] = [];\n if (typeof envelope.type !== 'string') errors.push('type must be a string');\n if (envelope.type === 'track' && typeof envelope.event !== 'string') {\n errors.push('track event must include event name');\n }\n if (typeof envelope.messageId !== 'string') errors.push('messageId must be a string');\n if (typeof envelope.timestamp !== 'string') errors.push('timestamp must be an ISO string');\n for (const key of Object.keys(envelope.properties ?? {})) {\n if (reservedKeys.has(key)) errors.push(`properties.${key} is reserved`);\n }\n return { ok: errors.length === 0, errors };\n}\n","import type { DmdDroppedEventDiagnostic, DmdDroppedEventReason, DmdDroppedEventType } from '../../core/diagnostics';\nimport type { DmdBrowserConfig, DmdConsentInput, DmdEventOptions, DmdHealthStatus } from '../../core/types';\nimport { createBackendCollectorPayload } from '../../core/backend-payload';\nimport { getBrowserWindow } from '../../core/environment';\nimport { canCollectPurpose, mergeConsent, normalizeConsent, type DmdResolvedConsent } from './consent';\nimport { createDeliveryManager, type DmdDeliveryManager } from './delivery';\nimport { sanitizeProperties } from './privacy';\nimport { validateEventEnvelope } from './schema';\nimport type { DmdIdentityState } from './types';\n\ninterface DmdPreparedEvent {\n type: 'track' | 'page' | 'identify' | 'group' | 'alias';\n event: string;\n properties: Record<string, unknown>;\n messageId: string;\n timestamp: string;\n context: Record<string, unknown>;\n anonymousId: string;\n userId?: string;\n groupId?: string;\n clientId: string;\n workspaceId: string;\n appId: string;\n writeKey: string;\n consent: DmdResolvedConsent;\n sessionId: string;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction endpointFromConfig(config: DmdBrowserConfig): string {\n const host = config.apiHost ?? 'https://sdk.drivemetadata.com/v2';\n return `${host.replace(/\\/$/, '')}/data-collector`;\n}\n\nfunction requireConfigString(value: string | undefined, field: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`DMD SDK config ${field} is required`);\n }\n return value;\n}\n\nfunction getBrowserStorage() {\n const browserWindow = getBrowserWindow();\n try {\n return browserWindow?.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class DriveMetaDataSDK {\n public initialized = true;\n public queue: unknown[] = [];\n public offline = false;\n public gdprConsent: 'granted' | 'denied' | 'pending';\n\n private readonly endpoint: string;\n private readonly config: DmdBrowserConfig;\n private readonly writeKey: string;\n private readonly sessionId: string;\n private readonly delivery: DmdDeliveryManager;\n private identity: DmdIdentityState;\n private consentState: DmdResolvedConsent;\n private droppedEvents = 0;\n private lastError: string | undefined;\n private lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n private retryTimer: ReturnType<typeof setTimeout> | undefined;\n private retryDelayMs: number;\n private readonly initialRetryDelayMs: number;\n private readonly maxRetryDelayMs: number;\n private lifecycleCleanup: (() => void) | undefined;\n\n constructor(config: DmdBrowserConfig) {\n requireConfigString(config.clientId, 'clientId');\n requireConfigString(config.workspaceId, 'workspaceId');\n requireConfigString(config.appId, 'appId');\n requireConfigString(config.writeKey || config.token, 'writeKey or token');\n this.config = config;\n this.endpoint = endpointFromConfig(config);\n const storage = getBrowserStorage();\n const deliveryConfig: Parameters<typeof createDeliveryManager>[0] = {\n endpoint: this.endpoint,\n };\n if (config.delivery?.maxQueueSize !== undefined) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;\n if (config.delivery?.queueTtlMs !== undefined) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;\n if (config.delivery?.retryDelayMs !== undefined) deliveryConfig.retryDelayMs = config.delivery.retryDelayMs;\n if (config.delivery?.maxRetryDelayMs !== undefined) deliveryConfig.maxRetryDelayMs = config.delivery.maxRetryDelayMs;\n if (config.delivery?.maxPayloadBytes !== undefined) deliveryConfig.maxPayloadBytes = config.delivery.maxPayloadBytes;\n if (config.delivery?.batchSize !== undefined) deliveryConfig.batchSize = config.delivery.batchSize;\n if (config.onDrop !== undefined) deliveryConfig.onDrop = config.onDrop;\n if (config.onError !== undefined) deliveryConfig.onError = config.onError;\n this.delivery = createDeliveryManager(storage ? {\n ...deliveryConfig,\n storage\n } : deliveryConfig);\n this.initialRetryDelayMs = config.delivery?.retryDelayMs ?? 1_000;\n this.retryDelayMs = this.initialRetryDelayMs;\n this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 30_000;\n this.writeKey = config.writeKey || config.token || '';\n this.identity = { anonymousId: createId('anon') };\n this.sessionId = createId('session');\n this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);\n this.gdprConsent = this.consentState.analytics;\n if (!config.delivery?.disableLifecycleFlush) {\n this.installLifecycleFlush();\n }\n }\n\n trackEvent(event: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('track', event, properties, options);\n }\n\n page(name?: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('page', 'page_view', { name, ...properties }, options);\n }\n\n trackPageview(): void {\n this.page();\n }\n\n identify(userId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, userId, traits };\n this.sendPreparedEvent('identify', 'identify', { userId, traits }, options);\n }\n\n identifyUser(userId: string, traits: Record<string, unknown> = {}): void {\n this.identify(userId, traits);\n }\n\n group(groupId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, groupId };\n this.sendPreparedEvent('group', 'group', { groupId, traits }, options);\n }\n\n alias(previousId: string, userId: string, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('alias', 'alias', { previousId, userId }, options);\n }\n\n async flush(): Promise<void> {\n await this.delivery.flushQueue();\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n } else {\n this.retryDelayMs = this.initialRetryDelayMs;\n }\n }\n\n reset(): void {\n this.identity = { anonymousId: createId('anon') };\n this.queue = [];\n this.offline = false;\n if (this.retryTimer !== undefined) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.lifecycleCleanup?.();\n this.lifecycleCleanup = undefined;\n this.delivery.clearQueue('manual_clear');\n }\n\n setConsent(consent: DmdConsentInput): void {\n this.consentState = typeof consent === 'object'\n ? mergeConsent(this.consentState, consent)\n : normalizeConsent(consent);\n this.gdprConsent = this.consentState.analytics;\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.queue = [];\n this.delivery.clearQueue('consent_revoked');\n }\n }\n\n getHealth(): DmdHealthStatus {\n const deliveryDiagnostics = this.delivery.getDiagnostics();\n const health: DmdHealthStatus = {\n initialized: this.initialized,\n consent: this.gdprConsent,\n consentPurposes: this.consentState,\n queueSize: deliveryDiagnostics.queued,\n offline: this.offline || deliveryDiagnostics.queued > 0,\n droppedEvents: this.droppedEvents + deliveryDiagnostics.dropped.length,\n delivery: deliveryDiagnostics\n };\n const lastError = this.lastError ?? deliveryDiagnostics.lastError;\n if (lastError !== undefined) health.lastError = lastError;\n if (this.lastDroppedEvent !== undefined) health.lastDroppedEvent = this.lastDroppedEvent;\n return health;\n }\n\n sendEvent(payload: unknown): void {\n void this.delivery.send(payload as Record<string, unknown>).then(() => {\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n }\n });\n }\n\n private installLifecycleFlush(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow) return;\n if (typeof browserWindow.addEventListener !== 'function') return;\n if (typeof browserWindow.removeEventListener !== 'function') return;\n\n const flushOnLifecycle = () => {\n void this.flush();\n };\n const flushOnVisibility = () => {\n if (browserWindow.document?.visibilityState === 'hidden') {\n void this.flush();\n }\n };\n\n browserWindow.addEventListener('online', flushOnLifecycle);\n browserWindow.addEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.addEventListener === 'function') {\n browserWindow.document.addEventListener('visibilitychange', flushOnVisibility);\n }\n\n this.lifecycleCleanup = () => {\n browserWindow.removeEventListener('online', flushOnLifecycle);\n browserWindow.removeEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.removeEventListener === 'function') {\n browserWindow.document.removeEventListener('visibilitychange', flushOnVisibility);\n }\n };\n }\n\n private scheduleRetryFlush(): void {\n if (this.retryTimer !== undefined) return;\n\n const delay = Math.min(this.retryDelayMs, this.maxRetryDelayMs);\n this.retryTimer = setTimeout(() => {\n this.retryTimer = undefined;\n void this.flush().then(() => {\n if (this.delivery.getDiagnostics().queued > 0) {\n this.retryDelayMs = Math.min(this.retryDelayMs * 2, this.maxRetryDelayMs);\n this.scheduleRetryFlush();\n }\n });\n }, delay);\n }\n\n private sendPreparedEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): void {\n void this.prepareAndSendEvent(type, event, properties, options);\n }\n\n private async prepareAndSendEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): Promise<void> {\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.recordDrop(type, 'consent_denied', event);\n return;\n }\n\n let prepared: DmdPreparedEvent = {\n type,\n event,\n properties: sanitizeProperties(properties),\n messageId: options.messageId ?? createId('msg'),\n timestamp: options.timestamp ?? new Date().toISOString(),\n context: options.context ?? {},\n anonymousId: this.identity.anonymousId,\n clientId: this.config.clientId,\n workspaceId: this.config.workspaceId,\n appId: this.config.appId,\n writeKey: this.writeKey,\n consent: this.consentState,\n sessionId: this.sessionId\n };\n\n if (this.identity.userId !== undefined) prepared.userId = this.identity.userId;\n if (this.identity.groupId !== undefined) prepared.groupId = this.identity.groupId;\n\n if (this.config.beforeSend !== undefined) {\n const beforeSendResult = await this.config.beforeSend(prepared);\n if (beforeSendResult === null) {\n this.recordDrop(type, 'before_send_dropped', event);\n return;\n }\n prepared = {\n ...prepared,\n ...beforeSendResult,\n properties: sanitizeProperties(beforeSendResult.properties ?? prepared.properties)\n };\n }\n\n const validation = validateEventEnvelope(prepared, { mode: this.config.schemaValidation ?? 'warn' });\n if (!validation.ok && this.config.schemaValidation === 'strict') {\n this.recordDrop(type, 'invalid_payload', event);\n return;\n }\n if (!validation.ok) {\n this.lastError = `DMD SDK schema warning: ${validation.errors.join(', ')}`;\n }\n\n this.sendEvent(this.toCollectorPayload(prepared));\n }\n\n private toCollectorPayload(prepared: DmdPreparedEvent): Record<string, unknown> {\n const browserWindow = getBrowserWindow();\n return createBackendCollectorPayload({\n requestId: prepared.messageId,\n timestamp: prepared.timestamp,\n eventType: prepared.event,\n clientId: prepared.clientId,\n workspaceId: prepared.workspaceId,\n token: prepared.writeKey,\n anonymousId: prepared.anonymousId,\n sessionId: prepared.sessionId,\n ua: browserWindow?.navigator?.userAgent,\n appId: prepared.appId,\n pageUrl: browserWindow?.location?.href,\n eventData: {\n ...prepared.properties,\n anonymousId: prepared.anonymousId,\n sessionId: prepared.sessionId,\n timestamp: prepared.timestamp,\n requestSentAt: prepared.timestamp,\n requestReceivedAt: prepared.timestamp\n }\n });\n }\n\n private recordDrop(type: DmdDroppedEventType, reason: DmdDroppedEventReason, event?: string): void {\n this.droppedEvents += 1;\n this.lastDroppedEvent = {\n type,\n reason,\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) this.lastDroppedEvent.event = event;\n this.lastError = `DMD SDK ${type} dropped because ${reason}`;\n }\n}\n","import type { DmdDroppedEventDiagnostic, DmdDroppedEventType } from '../core/diagnostics';\nimport type {\n DmdBrowserClient,\n DmdBrowserConfig,\n DmdConsentInput,\n DmdEventOptions,\n DmdHealthStatus\n} from '../core/types';\nimport { DriveMetaDataSDK } from './core/DriveMetaDataSDK';\n\nlet singleton: DriveMetaDataSDK | undefined;\nlet publicSingleton: DmdBrowserClient | undefined;\nlet droppedEvents = 0;\nlet lastError: string | undefined;\nlet lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n\nfunction createPublicClient(instance: DriveMetaDataSDK): DmdBrowserClient {\n return {\n track(event, properties, options) {\n instance.trackEvent(event, properties, options);\n },\n identify(userId, traits, options) {\n instance.identify(userId, traits, options);\n },\n page(name, properties, options) {\n instance.page(name, properties, options);\n },\n group(groupId, traits, options) {\n instance.group(groupId, traits, options);\n },\n alias(previousId, userId, options) {\n instance.alias(previousId, userId, options);\n },\n async flush() {\n await instance.flush();\n },\n reset() {\n instance.reset();\n singleton = undefined;\n publicSingleton = undefined;\n },\n setConsent(consent) {\n instance.setConsent(consent);\n },\n getHealth() {\n return instance.getHealth();\n }\n };\n}\n\nfunction setSingleton(instance: DriveMetaDataSDK): DmdBrowserClient {\n singleton = instance;\n publicSingleton = createPublicClient(instance);\n return publicSingleton;\n}\n\nfunction recordDroppedEvent(type: DmdDroppedEventType, event?: string): void {\n droppedEvents += 1;\n lastDroppedEvent = {\n type,\n reason: 'not_initialized',\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) {\n lastDroppedEvent.event = event;\n }\n lastError = `DMD SDK ${type} called before initialization`;\n}\n\nexport function initDmdSDK(config: DmdBrowserConfig): DmdBrowserClient {\n if (publicSingleton) {\n return publicSingleton;\n }\n\n try {\n const instance = new DriveMetaDataSDK(config);\n return setSingleton(instance);\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n throw error;\n }\n}\n\nexport function getDmdSDK(): DmdBrowserClient | undefined {\n return publicSingleton;\n}\n\nexport function track(event: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('track', event);\n return;\n }\n sdk.track(event, properties, options);\n}\n\nexport function identify(userId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('identify');\n return;\n }\n sdk.identify(userId, traits, options);\n}\n\nexport function page(name?: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('page');\n return;\n }\n sdk.page(name, properties, options);\n}\n\nexport function group(groupId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('group');\n return;\n }\n sdk.group(groupId, traits, options);\n}\n\nexport function alias(previousId: string, userId: string, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('alias');\n return;\n }\n sdk.alias(previousId, userId, options);\n}\n\nexport async function flush(): Promise<void> {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('flush');\n return;\n }\n await sdk.flush();\n}\n\nexport function reset(): void {\n singleton?.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n}\n\nexport function setConsent(consent: DmdConsentInput): void {\n getDmdSDK()?.setConsent(consent);\n}\n\nexport const consent = {\n update(state: DmdConsentInput): void {\n setConsent(state);\n }\n};\n\nexport async function ready(): Promise<DmdBrowserClient | undefined> {\n return getDmdSDK();\n}\n\nexport function getDmdHealth(): DmdHealthStatus {\n if (singleton) {\n return singleton.getHealth();\n }\n\n const health: DmdHealthStatus = {\n initialized: false,\n consent: 'pending',\n queueSize: 0,\n offline: false,\n droppedEvents\n };\n\n if (lastError !== undefined) {\n health.lastError = lastError;\n }\n if (lastDroppedEvent !== undefined) {\n health.lastDroppedEvent = lastDroppedEvent;\n }\n\n return health;\n}\n\nexport function resetDmdSDKForTests(): void {\n singleton?.reset();\n singleton = undefined;\n publicSingleton = undefined;\n droppedEvents = 0;\n lastError = undefined;\n lastDroppedEvent = undefined;\n}\n","'use client';\n\nimport React from 'react';\nimport { page } from '../browser/client';\n\nexport interface DmdNextPageTrackingOptions {\n name?: string;\n properties?: Record<string, unknown>;\n}\n\nexport function useDmdAppRouterPageTracking(\n pathname: string | null,\n search?: string | null,\n options: DmdNextPageTrackingOptions = {}\n): void {\n const lastRouteKey = React.useRef<string | undefined>(undefined);\n const routeKey = pathname ? `${pathname}?${search ?? ''}` : '';\n\n React.useEffect(() => {\n if (!pathname || !routeKey || lastRouteKey.current === routeKey) return;\n\n lastRouteKey.current = routeKey;\n page(options.name, {\n ...options.properties,\n pathname,\n search: search ?? ''\n });\n }, [options.name, options.properties, pathname, routeKey, search]);\n}\n","'use client';\n\nimport React from 'react';\nimport { page } from '../browser/client';\nimport type { DmdNextPageTrackingOptions } from './useDmdAppRouterPageTracking';\n\nexport interface DmdPagesRouterLike {\n asPath?: string;\n pathname?: string;\n}\n\nexport function useDmdPagesRouterPageTracking(\n router: DmdPagesRouterLike | null | undefined,\n options: DmdNextPageTrackingOptions = {}\n): void {\n const lastRouteKey = React.useRef<string | undefined>(undefined);\n const routeKey = router?.asPath ?? router?.pathname ?? '';\n\n React.useEffect(() => {\n if (!routeKey || lastRouteKey.current === routeKey) return;\n\n lastRouteKey.current = routeKey;\n page(options.name, {\n ...options.properties,\n route: routeKey\n });\n }, [options.name, options.properties, routeKey]);\n}\n","import React from 'react';\nimport {\n alias,\n flush,\n getDmdHealth,\n group,\n identify,\n page,\n reset,\n setConsent,\n track\n} from '../browser/client';\nimport type { DmdBrowserClient, DmdConsentInput, DmdEventOptions, DmdHealthStatus } from '../core/types';\nimport { DmdContext } from './DmdProvider';\n\nexport function useDmdSDK(): DmdBrowserClient | undefined {\n return React.useContext(DmdContext);\n}\n\nexport function useTrackEvent(): (\n event: string,\n properties?: Record<string, unknown>,\n options?: DmdEventOptions\n) => void {\n return React.useCallback((event: string, properties?: Record<string, unknown>, options?: DmdEventOptions) => {\n track(event, properties, options);\n }, []);\n}\n\nexport function useIdentify(): (userId: string, traits?: Record<string, unknown>) => void {\n return React.useCallback((userId: string, traits?: Record<string, unknown>) => {\n identify(userId, traits);\n }, []);\n}\n\nexport function usePage(): (\n name?: string,\n properties?: Record<string, unknown>,\n options?: DmdEventOptions\n) => void {\n return React.useCallback((name?: string, properties?: Record<string, unknown>, options?: DmdEventOptions) => {\n page(name, properties, options);\n }, []);\n}\n\nexport function useGroup(): (\n groupId: string,\n traits?: Record<string, unknown>,\n options?: DmdEventOptions\n) => void {\n return React.useCallback((groupId: string, traits?: Record<string, unknown>, options?: DmdEventOptions) => {\n group(groupId, traits, options);\n }, []);\n}\n\nexport function useAlias(): (previousId: string, userId: string, options?: DmdEventOptions) => void {\n return React.useCallback((previousId: string, userId: string, options?: DmdEventOptions) => {\n alias(previousId, userId, options);\n }, []);\n}\n\nexport function useReset(): () => void {\n return React.useCallback(() => {\n reset();\n }, []);\n}\n\nexport function useDmdFlush(): () => Promise<void> {\n return React.useCallback(async () => {\n await flush();\n }, []);\n}\n\nexport function useDmdConsent(): (consent: DmdConsentInput) => void {\n return React.useCallback((consent: DmdConsentInput) => {\n setConsent(consent);\n }, []);\n}\n\nexport function useDmdHealth(): DmdHealthStatus {\n const client = useDmdSDK();\n const [health, setHealth] = React.useState<DmdHealthStatus>(() => getDmdHealth());\n\n React.useEffect(() => {\n setHealth(getDmdHealth());\n }, [client]);\n\n return health;\n}\n"],"mappings":"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","names":["page","createId","lastError","React","React","React","React","React","React","React"]}
@@ -49,6 +49,61 @@ var DmdServerRequestError = class extends DmdServerSdkError {
49
49
  }
50
50
  };
51
51
 
52
+ // src/core/backend-payload.ts
53
+ function formatUtcTimestamp(value) {
54
+ if (typeof value !== "string") return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
55
+ const date = new Date(value);
56
+ if (Number.isNaN(date.getTime())) return value;
57
+ return date.toISOString().replace("T", " ").slice(0, 19);
58
+ }
59
+ function cleanObject(value) {
60
+ if (Array.isArray(value)) {
61
+ const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
62
+ return cleaned.length > 0 ? cleaned : void 0;
63
+ }
64
+ if (value && typeof value === "object") {
65
+ const cleaned = Object.fromEntries(
66
+ Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
67
+ if (item === null || item === void 0 || item === "") return false;
68
+ if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
69
+ return true;
70
+ })
71
+ );
72
+ return Object.keys(cleaned).length > 0 ? cleaned : void 0;
73
+ }
74
+ return value;
75
+ }
76
+ function createBackendCollectorPayload(input) {
77
+ const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
78
+ const page = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
79
+ const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
80
+ const normalizedEventData = {
81
+ ...eventData,
82
+ timestamp,
83
+ requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
84
+ requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
85
+ };
86
+ const metaData = {
87
+ ...normalizedEventData,
88
+ requestId: input.requestId,
89
+ timestamp,
90
+ eventType: input.eventType,
91
+ requestFrom: input.requestFrom ?? "3",
92
+ clientId: input.clientId,
93
+ workspaceId: input.workspaceId,
94
+ token: input.token,
95
+ anonymousId: eventData.anonymousId ?? input.anonymousId,
96
+ sessionId: eventData.sessionId ?? input.sessionId,
97
+ ua: input.ua,
98
+ appDetails: { app_id: input.appId },
99
+ page: { ...page, url: page.url ?? input.pageUrl },
100
+ requestSentAt: normalizedEventData.requestSentAt,
101
+ requestReceivedAt: normalizedEventData.requestReceivedAt
102
+ };
103
+ const payload = { metaData };
104
+ return cleanObject(payload);
105
+ }
106
+
52
107
  // src/node/retry.ts
53
108
  function isRetryableStatus(status) {
54
109
  return status === 408 || status === 429 || status >= 500;
@@ -71,7 +126,7 @@ function requireString(value, message) {
71
126
  return value;
72
127
  }
73
128
  function validateServerConfig(config) {
74
- requireString(config.writeKey, "DMD server SDK config writeKey is required");
129
+ requireString(config.writeKey || config.token, "DMD server SDK config writeKey or token is required");
75
130
  }
76
131
  function validateTrackPayload(payload) {
77
132
  requireString(payload.event, "DMD server SDK track event is required");
@@ -132,6 +187,28 @@ function withBatchItemTimestamp(item) {
132
187
  if (item.type === "alias") return { type: item.type, payload: withTimestamp(item.payload) };
133
188
  return { type: item.type, payload: withTimestamp(item.payload) };
134
189
  }
190
+ function toCollectorPayload(config, type, payload, token) {
191
+ const basePayload = payload;
192
+ const properties = "properties" in payload && payload.properties ? payload.properties : {};
193
+ return createBackendCollectorPayload({
194
+ requestId: payload.messageId ?? `${type}_${Date.now()}`,
195
+ timestamp: payload.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
196
+ eventType: type === "track" ? basePayload.event : type,
197
+ requestFrom: config.requestFrom ?? "3",
198
+ clientId: config.clientId,
199
+ workspaceId: config.workspaceId,
200
+ token,
201
+ anonymousId: basePayload.anonymousId,
202
+ sessionId: basePayload.sessionId,
203
+ appId: config.appId,
204
+ eventData: {
205
+ ...properties,
206
+ anonymousId: basePayload.anonymousId,
207
+ sessionId: basePayload.sessionId,
208
+ timestamp: payload.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
209
+ }
210
+ });
211
+ }
135
212
  function createTimeoutController(timeoutMs) {
136
213
  if (!timeoutMs) {
137
214
  return { cleanup: () => void 0 };
@@ -147,6 +224,7 @@ function createDmdServerClient(config) {
147
224
  validateServerConfig(config);
148
225
  const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;
149
226
  const fetchImpl = config.fetch ?? globalThis.fetch;
227
+ const authorizationToken = config.writeKey || config.token;
150
228
  if (typeof fetchImpl !== "function") {
151
229
  throw new Error("DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.");
152
230
  }
@@ -158,7 +236,6 @@ function createDmdServerClient(config) {
158
236
  const requestInit = {
159
237
  method: "POST",
160
238
  headers: {
161
- Authorization: `Bearer ${config.writeKey}`,
162
239
  "Content-Type": "application/json"
163
240
  },
164
241
  body: JSON.stringify(requestPayload)
@@ -189,11 +266,7 @@ function createDmdServerClient(config) {
189
266
  throw new DmdServerRequestError("DMD server SDK request failed", void 0, lastError);
190
267
  }
191
268
  function envelope(type, payload) {
192
- return {
193
- type,
194
- payload,
195
- sentAt: (/* @__PURE__ */ new Date()).toISOString()
196
- };
269
+ return toCollectorPayload(config, type, payload, authorizationToken);
197
270
  }
198
271
  return {
199
272
  async track(payload) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/node/index.ts","../../src/node/errors.ts","../../src/node/retry.ts","../../src/node/validation.ts","../../src/node/client.ts"],"sourcesContent":["export { createDmdServerClient } from './client';\nexport {\n DmdServerRequestError,\n DmdServerSdkError,\n DmdServerValidationError\n} from './errors';\nexport type {\n DmdServerAliasPayload,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerRetryConfig,\n DmdServerTrackPayload\n} from './types';\n","export class DmdServerSdkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DmdServerSdkError';\n }\n}\n\nexport class DmdServerValidationError extends DmdServerSdkError {\n constructor(message: string) {\n super(message);\n this.name = 'DmdServerValidationError';\n }\n}\n\nexport class DmdServerRequestError extends DmdServerSdkError {\n constructor(message: string, public readonly status?: number, cause?: unknown) {\n super(message, cause);\n this.name = 'DmdServerRequestError';\n }\n}\n","import type { DmdServerRetryConfig } from './types';\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nexport function getRetryDelayMs(attemptIndex: number, retry: DmdServerRetryConfig = {}): number {\n const minDelayMs = retry.minDelayMs ?? 250;\n const maxDelayMs = retry.maxDelayMs ?? 2000;\n const exponentialDelay = minDelayMs * 2 ** attemptIndex;\n\n return Math.min(exponentialDelay, maxDelayMs);\n}\n\nexport function getRetryAttempts(retry: DmdServerRetryConfig | undefined): number {\n return retry?.attempts ?? 0;\n}\n","import { DmdServerValidationError } from './errors';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerTrackPayload\n} from './types';\n\nfunction requireString(value: string | undefined, message: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new DmdServerValidationError(message);\n }\n\n return value;\n}\n\nexport function validateServerConfig(config: DmdServerConfig): void {\n requireString(config.writeKey, 'DMD server SDK config writeKey is required');\n}\n\nexport function validateTrackPayload(payload: DmdServerTrackPayload): void {\n requireString(payload.event, 'DMD server SDK track event is required');\n\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK track requires userId or anonymousId');\n }\n}\n\nexport function validateIdentifyPayload(payload: DmdServerIdentifyPayload): void {\n requireString(payload.userId, 'DMD server SDK identify requires userId');\n}\n\nexport function validatePagePayload(payload: DmdServerPagePayload): void {\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK page requires userId or anonymousId');\n }\n}\n\nexport function validateAliasPayload(payload: DmdServerAliasPayload): void {\n const hasPreviousId = typeof payload.previousId === 'string' && payload.previousId.trim() !== '';\n const hasUserId = typeof payload.userId === 'string' && payload.userId.trim() !== '';\n if (!hasPreviousId || !hasUserId) {\n throw new DmdServerValidationError('DMD server SDK alias requires previousId and userId');\n }\n}\n\nexport function validateGroupPayload(payload: DmdServerGroupPayload): void {\n requireString(payload.groupId, 'DMD server SDK group requires groupId');\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK group requires userId or anonymousId');\n }\n}\n\nexport function validateBatchPayload(items: DmdServerBatchItem[]): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new DmdServerValidationError('DMD server SDK batch requires at least one item');\n }\n\n for (const item of items) {\n if (item.type === 'track') validateTrackPayload(item.payload);\n else if (item.type === 'identify') validateIdentifyPayload(item.payload);\n else if (item.type === 'page') validatePagePayload(item.payload);\n else if (item.type === 'alias') validateAliasPayload(item.payload);\n else if (item.type === 'group') validateGroupPayload(item.payload);\n else throw new DmdServerValidationError('DMD server SDK batch item has invalid type');\n }\n}\n","import { DmdServerRequestError } from './errors';\nimport { getRetryAttempts, getRetryDelayMs, isRetryableStatus } from './retry';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerRequestPayload,\n DmdServerSingleRequestPayload,\n DmdServerTrackPayload\n} from './types';\nimport {\n validateAliasPayload,\n validateBatchPayload,\n validateGroupPayload,\n validateIdentifyPayload,\n validatePagePayload,\n validateServerConfig,\n validateTrackPayload\n} from './validation';\n\nconst DEFAULT_ENDPOINT = 'https://sdk.drivemetadata.com/v2/data-collector';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction withTimestamp<T extends { timestamp?: string }>(payload: T): T {\n return {\n ...payload,\n timestamp: payload.timestamp ?? new Date().toISOString()\n };\n}\n\nfunction withBatchItemTimestamp(item: DmdServerBatchItem): DmdServerBatchItem {\n if (item.type === 'track') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'identify') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'page') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'alias') return { type: item.type, payload: withTimestamp(item.payload) };\n return { type: item.type, payload: withTimestamp(item.payload) };\n}\n\nfunction createTimeoutController(timeoutMs: number | undefined): { signal?: AbortSignal; cleanup: () => void } {\n if (!timeoutMs) {\n return { cleanup: () => undefined };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timer)\n };\n}\n\nexport function createDmdServerClient(config: DmdServerConfig): DmdServerClient {\n validateServerConfig(config);\n\n const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n\n if (typeof fetchImpl !== 'function') {\n throw new Error('DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.');\n }\n\n async function send(requestPayload: DmdServerRequestPayload): Promise<void> {\n const attempts = getRetryAttempts(config.retry);\n let lastError: unknown;\n\n for (let attemptIndex = 0; attemptIndex <= attempts; attemptIndex += 1) {\n try {\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${config.writeKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestPayload)\n };\n const timeout = createTimeoutController(config.timeoutMs);\n if (timeout.signal !== undefined) {\n requestInit.signal = timeout.signal;\n }\n\n const response = await fetchImpl(endpoint, requestInit).finally(timeout.cleanup);\n\n if (response.ok) {\n return;\n }\n\n if (!isRetryableStatus(response.status) || attemptIndex === attempts) {\n throw new DmdServerRequestError(\n `DMD server SDK request failed with status ${response.status}`,\n response.status\n );\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n } catch (error) {\n lastError = error;\n\n if (error instanceof DmdServerRequestError || attemptIndex === attempts) {\n throw error;\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n }\n }\n\n throw new DmdServerRequestError('DMD server SDK request failed', undefined, lastError);\n }\n\n function envelope(type: DmdServerSingleRequestPayload['type'], payload: DmdServerSingleRequestPayload['payload']) {\n return {\n type,\n payload,\n sentAt: new Date().toISOString()\n };\n }\n\n return {\n async track(payload: DmdServerTrackPayload) {\n validateTrackPayload(payload);\n await send(envelope('track', withTimestamp(payload)));\n },\n async identify(payload: DmdServerIdentifyPayload) {\n validateIdentifyPayload(payload);\n await send(envelope('identify', withTimestamp(payload)));\n },\n async page(payload: DmdServerPagePayload) {\n validatePagePayload(payload);\n await send(envelope('page', withTimestamp(payload)));\n },\n async alias(payload: DmdServerAliasPayload) {\n validateAliasPayload(payload);\n await send(envelope('alias', withTimestamp(payload)));\n },\n async group(payload: DmdServerGroupPayload) {\n validateGroupPayload(payload);\n await send(envelope('group', withTimestamp(payload)));\n },\n async batch(items: DmdServerBatchItem[]) {\n validateBatchPayload(items);\n await send({\n type: 'batch',\n batch: items.map(withBatchItemTimestamp),\n sentAt: new Date().toISOString()\n });\n },\n async flush() {\n return Promise.resolve();\n }\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/node/index.ts","../../src/node/errors.ts","../../src/core/backend-payload.ts","../../src/node/retry.ts","../../src/node/validation.ts","../../src/node/client.ts"],"sourcesContent":["export { createDmdServerClient } from './client';\nexport {\n DmdServerRequestError,\n DmdServerSdkError,\n DmdServerValidationError\n} from './errors';\nexport type {\n DmdServerAliasPayload,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerRetryConfig,\n DmdServerTrackPayload\n} from './types';\n","export class DmdServerSdkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DmdServerSdkError';\n }\n}\n\nexport class DmdServerValidationError extends DmdServerSdkError {\n constructor(message: string) {\n super(message);\n this.name = 'DmdServerValidationError';\n }\n}\n\nexport class DmdServerRequestError extends DmdServerSdkError {\n constructor(message: string, public readonly status?: number, cause?: unknown) {\n super(message, cause);\n this.name = 'DmdServerRequestError';\n }\n}\n","function formatUtcTimestamp(value: unknown): string {\n if (typeof value !== 'string') return new Date().toISOString().replace('T', ' ').slice(0, 19);\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: input.requestId,\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: eventData.anonymousId ?? input.anonymousId,\n sessionId: eventData.sessionId ?? input.sessionId,\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","import type { DmdServerRetryConfig } from './types';\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nexport function getRetryDelayMs(attemptIndex: number, retry: DmdServerRetryConfig = {}): number {\n const minDelayMs = retry.minDelayMs ?? 250;\n const maxDelayMs = retry.maxDelayMs ?? 2000;\n const exponentialDelay = minDelayMs * 2 ** attemptIndex;\n\n return Math.min(exponentialDelay, maxDelayMs);\n}\n\nexport function getRetryAttempts(retry: DmdServerRetryConfig | undefined): number {\n return retry?.attempts ?? 0;\n}\n","import { DmdServerValidationError } from './errors';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerTrackPayload\n} from './types';\n\nfunction requireString(value: string | undefined, message: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new DmdServerValidationError(message);\n }\n\n return value;\n}\n\nexport function validateServerConfig(config: DmdServerConfig): void {\n requireString(config.writeKey || config.token, 'DMD server SDK config writeKey or token is required');\n}\n\nexport function validateTrackPayload(payload: DmdServerTrackPayload): void {\n requireString(payload.event, 'DMD server SDK track event is required');\n\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK track requires userId or anonymousId');\n }\n}\n\nexport function validateIdentifyPayload(payload: DmdServerIdentifyPayload): void {\n requireString(payload.userId, 'DMD server SDK identify requires userId');\n}\n\nexport function validatePagePayload(payload: DmdServerPagePayload): void {\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK page requires userId or anonymousId');\n }\n}\n\nexport function validateAliasPayload(payload: DmdServerAliasPayload): void {\n const hasPreviousId = typeof payload.previousId === 'string' && payload.previousId.trim() !== '';\n const hasUserId = typeof payload.userId === 'string' && payload.userId.trim() !== '';\n if (!hasPreviousId || !hasUserId) {\n throw new DmdServerValidationError('DMD server SDK alias requires previousId and userId');\n }\n}\n\nexport function validateGroupPayload(payload: DmdServerGroupPayload): void {\n requireString(payload.groupId, 'DMD server SDK group requires groupId');\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK group requires userId or anonymousId');\n }\n}\n\nexport function validateBatchPayload(items: DmdServerBatchItem[]): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new DmdServerValidationError('DMD server SDK batch requires at least one item');\n }\n\n for (const item of items) {\n if (item.type === 'track') validateTrackPayload(item.payload);\n else if (item.type === 'identify') validateIdentifyPayload(item.payload);\n else if (item.type === 'page') validatePagePayload(item.payload);\n else if (item.type === 'alias') validateAliasPayload(item.payload);\n else if (item.type === 'group') validateGroupPayload(item.payload);\n else throw new DmdServerValidationError('DMD server SDK batch item has invalid type');\n }\n}\n","import { DmdServerRequestError } from './errors';\nimport { createBackendCollectorPayload } from '../core/backend-payload';\nimport { getRetryAttempts, getRetryDelayMs, isRetryableStatus } from './retry';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerSingleRequestPayload,\n DmdServerTrackPayload\n} from './types';\nimport {\n validateAliasPayload,\n validateBatchPayload,\n validateGroupPayload,\n validateIdentifyPayload,\n validatePagePayload,\n validateServerConfig,\n validateTrackPayload\n} from './validation';\n\nconst DEFAULT_ENDPOINT = 'https://sdk.drivemetadata.com/v2/data-collector';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction withTimestamp<T extends { timestamp?: string }>(payload: T): T {\n return {\n ...payload,\n timestamp: payload.timestamp ?? new Date().toISOString()\n };\n}\n\nfunction withBatchItemTimestamp(item: DmdServerBatchItem): DmdServerBatchItem {\n if (item.type === 'track') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'identify') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'page') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'alias') return { type: item.type, payload: withTimestamp(item.payload) };\n return { type: item.type, payload: withTimestamp(item.payload) };\n}\n\nfunction toCollectorPayload(\n config: DmdServerConfig,\n type: DmdServerSingleRequestPayload['type'],\n payload: DmdServerSingleRequestPayload['payload'],\n token: string | undefined\n) {\n const basePayload = payload as DmdServerTrackPayload & { anonymousId?: string; sessionId?: string };\n const properties = 'properties' in payload && payload.properties ? payload.properties : {};\n return createBackendCollectorPayload({\n requestId: payload.messageId ?? `${type}_${Date.now()}`,\n timestamp: payload.timestamp ?? new Date().toISOString(),\n eventType: type === 'track' ? basePayload.event : type,\n requestFrom: config.requestFrom ?? '3',\n clientId: config.clientId,\n workspaceId: config.workspaceId,\n token,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n appId: config.appId,\n eventData: {\n ...properties,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n timestamp: payload.timestamp ?? new Date().toISOString()\n }\n });\n}\n\nfunction createTimeoutController(timeoutMs: number | undefined): { signal?: AbortSignal; cleanup: () => void } {\n if (!timeoutMs) {\n return { cleanup: () => undefined };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timer)\n };\n}\n\nexport function createDmdServerClient(config: DmdServerConfig): DmdServerClient {\n validateServerConfig(config);\n\n const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n const authorizationToken = config.writeKey || config.token;\n\n if (typeof fetchImpl !== 'function') {\n throw new Error('DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.');\n }\n\n async function send(requestPayload: Record<string, unknown>): Promise<void> {\n const attempts = getRetryAttempts(config.retry);\n let lastError: unknown;\n\n for (let attemptIndex = 0; attemptIndex <= attempts; attemptIndex += 1) {\n try {\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestPayload)\n };\n const timeout = createTimeoutController(config.timeoutMs);\n if (timeout.signal !== undefined) {\n requestInit.signal = timeout.signal;\n }\n\n const response = await fetchImpl(endpoint, requestInit).finally(timeout.cleanup);\n\n if (response.ok) {\n return;\n }\n\n if (!isRetryableStatus(response.status) || attemptIndex === attempts) {\n throw new DmdServerRequestError(\n `DMD server SDK request failed with status ${response.status}`,\n response.status\n );\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n } catch (error) {\n lastError = error;\n\n if (error instanceof DmdServerRequestError || attemptIndex === attempts) {\n throw error;\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n }\n }\n\n throw new DmdServerRequestError('DMD server SDK request failed', undefined, lastError);\n }\n\n function envelope(type: DmdServerSingleRequestPayload['type'], payload: DmdServerSingleRequestPayload['payload']) {\n return toCollectorPayload(config, type, payload, authorizationToken);\n }\n\n return {\n async track(payload: DmdServerTrackPayload) {\n validateTrackPayload(payload);\n await send(envelope('track', withTimestamp(payload)));\n },\n async identify(payload: DmdServerIdentifyPayload) {\n validateIdentifyPayload(payload);\n await send(envelope('identify', withTimestamp(payload)));\n },\n async page(payload: DmdServerPagePayload) {\n validatePagePayload(payload);\n await send(envelope('page', withTimestamp(payload)));\n },\n async alias(payload: DmdServerAliasPayload) {\n validateAliasPayload(payload);\n await send(envelope('alias', withTimestamp(payload)));\n },\n async group(payload: DmdServerGroupPayload) {\n validateGroupPayload(payload);\n await send(envelope('group', withTimestamp(payload)));\n },\n async batch(items: DmdServerBatchItem[]) {\n validateBatchPayload(items);\n await send({\n type: 'batch',\n batch: items.map(withBatchItemTimestamp),\n sentAt: new Date().toISOString()\n });\n },\n async flush() {\n return Promise.resolve();\n }\n };\n}\n"],"mappings":"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","names":[]}
@@ -4,7 +4,12 @@ interface DmdServerRetryConfig {
4
4
  maxDelayMs?: number;
5
5
  }
6
6
  interface DmdServerConfig {
7
- writeKey: string;
7
+ writeKey?: string;
8
+ token?: string;
9
+ clientId?: string;
10
+ workspaceId?: string;
11
+ appId?: string;
12
+ requestFrom?: string;
8
13
  endpoint?: string;
9
14
  timeoutMs?: number;
10
15
  retry?: DmdServerRetryConfig;
@@ -13,6 +18,7 @@ interface DmdServerConfig {
13
18
  interface DmdServerBasePayload {
14
19
  userId?: string;
15
20
  anonymousId?: string;
21
+ sessionId?: string;
16
22
  timestamp?: string;
17
23
  context?: Record<string, unknown>;
18
24
  messageId?: string;
@@ -4,7 +4,12 @@ interface DmdServerRetryConfig {
4
4
  maxDelayMs?: number;
5
5
  }
6
6
  interface DmdServerConfig {
7
- writeKey: string;
7
+ writeKey?: string;
8
+ token?: string;
9
+ clientId?: string;
10
+ workspaceId?: string;
11
+ appId?: string;
12
+ requestFrom?: string;
8
13
  endpoint?: string;
9
14
  timeoutMs?: number;
10
15
  retry?: DmdServerRetryConfig;
@@ -13,6 +18,7 @@ interface DmdServerConfig {
13
18
  interface DmdServerBasePayload {
14
19
  userId?: string;
15
20
  anonymousId?: string;
21
+ sessionId?: string;
16
22
  timestamp?: string;
17
23
  context?: Record<string, unknown>;
18
24
  messageId?: string;