@drivemetadata-ai/sdk 0.1.1-beta.4 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -21
- package/dist/angular/index.cjs +173 -8
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.js +173 -8
- package/dist/angular/index.js.map +1 -1
- package/dist/browser/index.cjs +173 -8
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +173 -8
- package/dist/browser/index.js.map +1 -1
- package/dist/next/index.cjs +173 -8
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +173 -8
- package/dist/next/index.js.map +1 -1
- package/dist/react/index.cjs +173 -8
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +173 -8
- package/dist/react/index.js.map +1 -1
- package/docs/integration.md +177 -5
- package/package.json +2 -1
package/docs/integration.md
CHANGED
|
@@ -33,12 +33,72 @@ const browserConfig = {
|
|
|
33
33
|
};
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
Use camelCase config keys in npm integrations. The backend payload still sends the backend-required `metaData` shape, but SDK configuration should use `clientId`, `workspaceId`, `appId`, `apiHost`, `capturePageview`, `capturePageleave`, `schemaValidation`, and `beforeSend`.
|
|
37
|
+
|
|
36
38
|
Node integrations use a server token stored only in backend environment variables:
|
|
37
39
|
|
|
38
40
|
```bash
|
|
39
41
|
DMD_SERVER_TOKEN=server_write_key
|
|
40
42
|
```
|
|
41
43
|
|
|
44
|
+
### Environment Variables
|
|
45
|
+
|
|
46
|
+
For React/Vite-style browser builds, expose only public browser values:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
VITE_DMD_CLIENT_ID=client_xxx
|
|
50
|
+
VITE_DMD_WORKSPACE_ID=workspace_xxx
|
|
51
|
+
VITE_DMD_APP_ID=app_xxx
|
|
52
|
+
VITE_DMD_TOKEN=public_token
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For Next.js browser integrations, use `NEXT_PUBLIC_` only for public browser values:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
NEXT_PUBLIC_DMD_CLIENT_ID=client_xxx
|
|
59
|
+
NEXT_PUBLIC_DMD_WORKSPACE_ID=workspace_xxx
|
|
60
|
+
NEXT_PUBLIC_DMD_APP_ID=app_xxx
|
|
61
|
+
NEXT_PUBLIC_DMD_TOKEN=public_token
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For Node/server integrations, do not use `NEXT_PUBLIC_`:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
DMD_SERVER_TOKEN=server_write_key
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Common Browser Config
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const config = {
|
|
74
|
+
clientId: 'client_xxx',
|
|
75
|
+
workspaceId: 'workspace_xxx',
|
|
76
|
+
appId: 'app_xxx',
|
|
77
|
+
token: 'public_token',
|
|
78
|
+
apiHost: 'https://sdk.drivemetadata.com/v2',
|
|
79
|
+
consent: { analytics: 'pending', advertising: 'denied' },
|
|
80
|
+
capturePageview: true,
|
|
81
|
+
capturePageleave: true,
|
|
82
|
+
schemaValidation: 'warn',
|
|
83
|
+
delivery: {
|
|
84
|
+
retryDelayMs: 1000,
|
|
85
|
+
maxRetryDelayMs: 30000,
|
|
86
|
+
maxQueueSize: 100,
|
|
87
|
+
useBeacon: true
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Recommended defaults:
|
|
93
|
+
|
|
94
|
+
| Option | Recommended | Notes |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `consent.analytics` | `pending` | Grant after consent manager resolves |
|
|
97
|
+
| `capturePageview` | `true` | Sends automatic page views in browser runtimes |
|
|
98
|
+
| `capturePageleave` | `true` | Sends lifecycle/page leave events |
|
|
99
|
+
| `schemaValidation` | `warn` | Use `strict` in controlled integrations after testing |
|
|
100
|
+
| `delivery.useBeacon` | `true` | Helps lifecycle delivery during navigation |
|
|
101
|
+
|
|
42
102
|
## Consent First Setup
|
|
43
103
|
|
|
44
104
|
Enterprise integrations should start with analytics consent as `pending` or `denied`, then grant it after the consent manager resolves.
|
|
@@ -92,6 +152,20 @@ await flush();
|
|
|
92
152
|
console.log(getDmdHealth());
|
|
93
153
|
```
|
|
94
154
|
|
|
155
|
+
Browser API methods:
|
|
156
|
+
|
|
157
|
+
| Method | Use for |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `track(event, properties, options)` | custom events |
|
|
160
|
+
| `page(name, properties, options)` | page views |
|
|
161
|
+
| `identify(userId, traits, options)` | known users |
|
|
162
|
+
| `group(groupId, traits, options)` | accounts/workspaces/organizations |
|
|
163
|
+
| `alias(previousId, userId, options)` | identity merge |
|
|
164
|
+
| `flush()` | force queued delivery |
|
|
165
|
+
| `reset()` | reset identity/session state |
|
|
166
|
+
| `setConsent(consent)` / `consent.update(consent)` | consent updates |
|
|
167
|
+
| `getDmdHealth()` | diagnostics |
|
|
168
|
+
|
|
95
169
|
## Backend Timestamp Fields
|
|
96
170
|
|
|
97
171
|
Every collector request sends these timestamp fields inside `metaData`:
|
|
@@ -104,6 +178,42 @@ Every collector request sends these timestamp fields inside `metaData`:
|
|
|
104
178
|
|
|
105
179
|
If a caller provides an invalid timestamp string, the SDK normalizes it to the current UTC time instead of sending the invalid value to the backend.
|
|
106
180
|
|
|
181
|
+
## Default Page Context
|
|
182
|
+
|
|
183
|
+
Browser, React, Next.js, and Angular integrations automatically add browser page context to each collector payload.
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"metaData": {
|
|
188
|
+
"page": {
|
|
189
|
+
"url": "https://example.com/products/sku-123?utm_source=paid",
|
|
190
|
+
"path": "/products/sku-123",
|
|
191
|
+
"search": "?utm_source=paid",
|
|
192
|
+
"title": "Product Detail",
|
|
193
|
+
"referrer": "https://google.com/search?q=%5BREDACTED%5D"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The SDK reads this from `window.location`, `document.title`, and `document.referrer`. Query strings in `search` and `referrer` are redacted by default except common attribution parameters such as `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, and `utm_content`.
|
|
200
|
+
|
|
201
|
+
Node/server integrations do not automatically capture page context. Pass page details explicitly in server event properties if needed.
|
|
202
|
+
|
|
203
|
+
## Default Identity, Session, Attribution
|
|
204
|
+
|
|
205
|
+
Browser, React, Next.js, and Angular integrations also add these fields by default:
|
|
206
|
+
|
|
207
|
+
| Field | Behavior |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `requestId` | generated UUID for each event |
|
|
210
|
+
| `anonymousId` | persisted anonymous browser visitor ID |
|
|
211
|
+
| `sessionId` | persisted browser session ID with idle timeout |
|
|
212
|
+
| `attributionData` | stored click IDs and `_fbc`/`_fbp` when available |
|
|
213
|
+
| `utmParameter` | stored UTM values when available |
|
|
214
|
+
|
|
215
|
+
The SDK stores anonymous/session/attribution state using the configured browser persistence mode and falls back safely when browser storage is blocked.
|
|
216
|
+
|
|
107
217
|
## React Integration
|
|
108
218
|
|
|
109
219
|
Wrap the app once:
|
|
@@ -128,6 +238,18 @@ export function App() {
|
|
|
128
238
|
}
|
|
129
239
|
```
|
|
130
240
|
|
|
241
|
+
For Vite React apps, the provider config commonly comes from `import.meta.env`:
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
const config = {
|
|
245
|
+
clientId: import.meta.env.VITE_DMD_CLIENT_ID,
|
|
246
|
+
workspaceId: import.meta.env.VITE_DMD_WORKSPACE_ID,
|
|
247
|
+
appId: import.meta.env.VITE_DMD_APP_ID,
|
|
248
|
+
token: import.meta.env.VITE_DMD_TOKEN,
|
|
249
|
+
consent: { analytics: 'pending' as const, advertising: 'denied' as const }
|
|
250
|
+
};
|
|
251
|
+
```
|
|
252
|
+
|
|
131
253
|
Track from components:
|
|
132
254
|
|
|
133
255
|
```tsx
|
|
@@ -140,7 +262,7 @@ export function CheckoutButton() {
|
|
|
140
262
|
const consent = useDmdConsent();
|
|
141
263
|
|
|
142
264
|
async function onClick() {
|
|
143
|
-
consent
|
|
265
|
+
consent({ analytics: 'granted' });
|
|
144
266
|
identify('user_123', { plan: 'enterprise' });
|
|
145
267
|
track('Checkout Started', { source: 'cart' });
|
|
146
268
|
await flush();
|
|
@@ -159,13 +281,18 @@ Create a client provider:
|
|
|
159
281
|
|
|
160
282
|
import { DmdProvider, useDmdAppRouterPageTracking } from '@drivemetadata-ai/sdk/next';
|
|
161
283
|
import { usePathname, useSearchParams } from 'next/navigation';
|
|
284
|
+
import type { ReactNode } from 'react';
|
|
162
285
|
|
|
163
|
-
|
|
286
|
+
function RouteTracking() {
|
|
164
287
|
const pathname = usePathname();
|
|
165
288
|
const searchParams = useSearchParams();
|
|
166
289
|
|
|
167
290
|
useDmdAppRouterPageTracking(pathname, searchParams.toString());
|
|
168
291
|
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function AnalyticsProvider({ children }: { children: ReactNode }) {
|
|
169
296
|
return (
|
|
170
297
|
<DmdProvider
|
|
171
298
|
config={{
|
|
@@ -176,6 +303,7 @@ export function AnalyticsProvider({ children }: { children: React.ReactNode }) {
|
|
|
176
303
|
consent: { analytics: 'pending', advertising: 'denied' }
|
|
177
304
|
}}
|
|
178
305
|
>
|
|
306
|
+
<RouteTracking />
|
|
179
307
|
{children}
|
|
180
308
|
</DmdProvider>
|
|
181
309
|
);
|
|
@@ -186,8 +314,9 @@ Use it from `app/layout.tsx`:
|
|
|
186
314
|
|
|
187
315
|
```tsx
|
|
188
316
|
import { AnalyticsProvider } from './AnalyticsProvider';
|
|
317
|
+
import type { ReactNode } from 'react';
|
|
189
318
|
|
|
190
|
-
export default function RootLayout({ children }: { children:
|
|
319
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
191
320
|
return (
|
|
192
321
|
<html lang="en">
|
|
193
322
|
<body>
|
|
@@ -205,6 +334,14 @@ import type { AppProps } from 'next/app';
|
|
|
205
334
|
import { useRouter } from 'next/router';
|
|
206
335
|
import { DmdProvider, useDmdPagesRouterPageTracking } from '@drivemetadata-ai/sdk/next';
|
|
207
336
|
|
|
337
|
+
const config = {
|
|
338
|
+
clientId: process.env.NEXT_PUBLIC_DMD_CLIENT_ID!,
|
|
339
|
+
workspaceId: process.env.NEXT_PUBLIC_DMD_WORKSPACE_ID!,
|
|
340
|
+
appId: process.env.NEXT_PUBLIC_DMD_APP_ID!,
|
|
341
|
+
token: process.env.NEXT_PUBLIC_DMD_TOKEN!,
|
|
342
|
+
consent: { analytics: 'pending' as const, advertising: 'denied' as const }
|
|
343
|
+
};
|
|
344
|
+
|
|
208
345
|
function PageTracking() {
|
|
209
346
|
const router = useRouter();
|
|
210
347
|
useDmdPagesRouterPageTracking(router);
|
|
@@ -242,10 +379,24 @@ export const appConfig: ApplicationConfig = {
|
|
|
242
379
|
};
|
|
243
380
|
```
|
|
244
381
|
|
|
382
|
+
For Angular environment files, keep only the public browser token in frontend config:
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
export const environment = {
|
|
386
|
+
dmd: {
|
|
387
|
+
clientId: 'client_xxx',
|
|
388
|
+
workspaceId: 'workspace_xxx',
|
|
389
|
+
appId: 'app_xxx',
|
|
390
|
+
token: 'public_token'
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
```
|
|
394
|
+
|
|
245
395
|
Initialize and track:
|
|
246
396
|
|
|
247
397
|
```ts
|
|
248
|
-
import {
|
|
398
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
399
|
+
import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core';
|
|
249
400
|
import { DmdAnalyticsService } from '@drivemetadata-ai/sdk/angular';
|
|
250
401
|
|
|
251
402
|
@Component({
|
|
@@ -253,10 +404,16 @@ import { DmdAnalyticsService } from '@drivemetadata-ai/sdk/angular';
|
|
|
253
404
|
template: '<router-outlet />'
|
|
254
405
|
})
|
|
255
406
|
export class AppComponent implements OnInit {
|
|
256
|
-
constructor(
|
|
407
|
+
constructor(
|
|
408
|
+
private readonly dmd: DmdAnalyticsService,
|
|
409
|
+
@Inject(PLATFORM_ID) private readonly platformId: object
|
|
410
|
+
) {}
|
|
257
411
|
|
|
258
412
|
ngOnInit() {
|
|
413
|
+
if (!isPlatformBrowser(this.platformId)) return;
|
|
414
|
+
|
|
259
415
|
this.dmd.init();
|
|
416
|
+
this.dmd.setConsent({ analytics: 'granted' });
|
|
260
417
|
this.dmd.track('App Loaded');
|
|
261
418
|
}
|
|
262
419
|
}
|
|
@@ -296,6 +453,21 @@ await dmd.track({
|
|
|
296
453
|
|
|
297
454
|
Use `messageId` for a unique event ID and `idempotencyKey` for business events that may retry, such as orders, invoices, subscriptions, and webhooks.
|
|
298
455
|
|
|
456
|
+
Server-side page context is explicit:
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
await dmd.page({
|
|
460
|
+
userId: 'user_123',
|
|
461
|
+
properties: {
|
|
462
|
+
page: {
|
|
463
|
+
url: 'https://example.com/orders/123',
|
|
464
|
+
path: '/orders/123',
|
|
465
|
+
title: 'Order Detail'
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
```
|
|
470
|
+
|
|
299
471
|
## Diagnostics
|
|
300
472
|
|
|
301
473
|
Use health diagnostics when events do not appear:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drivemetadata-ai/sdk",
|
|
3
|
-
"version": "0.1.1
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "DriveMetaData JavaScript and TypeScript SDK.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"test": "vitest run",
|
|
60
60
|
"test:package": "npm run build && vitest run tests/package/package-contents.test.ts tests/package/package-install-smoke.test.ts",
|
|
61
61
|
"pack:check": "npm run build && npm pack --dry-run",
|
|
62
|
+
"release:version": "node scripts/release-version.mjs",
|
|
62
63
|
"release:check": "npm run ci && npm_config_cache=/tmp/npm-cache npm run pack:check",
|
|
63
64
|
"ci": "npm run typecheck && npm run test && npm run build && npm run test:package",
|
|
64
65
|
"ci:phase1": "npm run typecheck && npm run test && npm run build"
|