@treasuredata/web-sdk 1.0.0

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 (50) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +807 -0
  4. package/dist/browser.d.ts +9 -0
  5. package/dist/checksums.txt +8 -0
  6. package/dist/core/config.d.ts +10 -0
  7. package/dist/core/config.template.d.ts +10 -0
  8. package/dist/core/configurator.d.ts +35 -0
  9. package/dist/core/sdk.d.ts +3 -0
  10. package/dist/index.d.ts +37 -0
  11. package/dist/init.d.ts +18 -0
  12. package/dist/loader.d.ts +59 -0
  13. package/dist/loader.js +1 -0
  14. package/dist/loader.min.js +1 -0
  15. package/dist/plugins/clicks.d.ts +21 -0
  16. package/dist/plugins/conversion-api.d.ts +23 -0
  17. package/dist/plugins/global-id.d.ts +17 -0
  18. package/dist/plugins/in-browser-message.d.ts +6 -0
  19. package/dist/plugins/page-personalize/bridge/constants.d.ts +9 -0
  20. package/dist/plugins/page-personalize/bridge/rpc.d.ts +15 -0
  21. package/dist/plugins/page-personalize/index.d.ts +34 -0
  22. package/dist/plugins/page-personalize/injection/inject.d.ts +17 -0
  23. package/dist/plugins/page-personalize/modes/preview.d.ts +3 -0
  24. package/dist/plugins/page-personalize/modes/spot-selection.d.ts +9 -0
  25. package/dist/plugins/page-personalize/offers.d.ts +72 -0
  26. package/dist/plugins/page-personalize/router.d.ts +17 -0
  27. package/dist/plugins/page-personalize/types.d.ts +27 -0
  28. package/dist/plugins/page-personalize/utils/selector-generator.d.ts +6 -0
  29. package/dist/plugins/personalization.d.ts +39 -0
  30. package/dist/plugins/record.d.ts +32 -0
  31. package/dist/plugins/server-cookie.d.ts +14 -0
  32. package/dist/plugins/session.d.ts +25 -0
  33. package/dist/plugins/track.d.ts +16 -0
  34. package/dist/plugins/utm.d.ts +16 -0
  35. package/dist/td-sdk.cjs +3263 -0
  36. package/dist/td-sdk.esm.js +3263 -0
  37. package/dist/td-sdk.esm.min.js +1 -0
  38. package/dist/td-sdk.js +3176 -0
  39. package/dist/td-sdk.min.cjs +1 -0
  40. package/dist/td-sdk.min.js +1 -0
  41. package/dist/treasure.d.ts +198 -0
  42. package/dist/types/index.d.ts +177 -0
  43. package/dist/utils/element.d.ts +20 -0
  44. package/dist/utils/lodash.d.ts +18 -0
  45. package/dist/utils/misc.d.ts +17 -0
  46. package/dist/utils/set-cookie.d.ts +14 -0
  47. package/dist/utils/uuid.d.ts +14 -0
  48. package/dist/utils/xhr.d.ts +58 -0
  49. package/dist/vendor/js-cookies.d.ts +19 -0
  50. package/package.json +90 -0
package/README.md ADDED
@@ -0,0 +1,807 @@
1
+ # Treasure Data Web SDK
2
+
3
+ Modern, TypeScript-first analytics SDK for browser event tracking with comprehensive type safety and plugin architecture.
4
+
5
+ ## Quick Start
6
+
7
+ ### Install
8
+
9
+ **NPM (Recommended)**
10
+ ```bash
11
+ npm install @treasuredata/web-sdk
12
+ ```
13
+
14
+ **CDN Script**
15
+ ```html
16
+ <script type="text/javascript">
17
+ !function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["set","collectTags","blockEvents","unblockEvents","setSignedMode","setAnonymousMode","fetchServerCookie","fetchGlobalID","fetchUserSegments","fetchPersonalization","resetUUID","addRecord","trackEvent","trackPageview","trackClicks","ready"],c=0;c<s.length;c++){var o=s[c];e[t].prototype[o]=r(o)}var n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=("https:"===document.location.protocol?"https:":"http:")+"//cdn.treasuredata.com/sdk/web/1.0/td-sdk.min.js";var i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(n,i)}}("Treasure",this);
18
+ </script>
19
+ ```
20
+
21
+ ### First Event
22
+
23
+ ```typescript
24
+ // TypeScript
25
+ import Treasure from '@treasuredata/web-sdk'
26
+
27
+ const td = new Treasure({
28
+ writeKey: 'your-write-key',
29
+ database: 'your-database'
30
+ })
31
+
32
+ // Track your first event
33
+ td.trackEvent('user_actions', {
34
+ action: 'click',
35
+ button: 'signup'
36
+ })
37
+ ```
38
+
39
+ ```javascript
40
+ // JavaScript (Node.js/CommonJS)
41
+ const Treasure = require('@treasuredata/web-sdk').default
42
+
43
+ // Or ES modules
44
+ import Treasure from '@treasuredata/web-sdk'
45
+
46
+ const td = new Treasure({
47
+ writeKey: 'your-write-key',
48
+ database: 'your-database'
49
+ })
50
+ ```
51
+
52
+ ## Key Features
53
+
54
+ - **TypeScript-first**: Full type safety and IntelliSense support
55
+ - **Modern Architecture**: Composable plugin-based system
56
+ - **Privacy Compliance**: GDPR-ready with privacy controls
57
+ - **Automatic UTM Collection**: UTM parameters captured on init
58
+ - **Cross-device**: Global ID and server-side cookies for ITP compliance
59
+ - **Zero Dependencies**: Lightweight, self-contained
60
+
61
+ ## Common Use Cases
62
+
63
+ ### Page View Tracking
64
+ ```javascript
65
+ // Track page view
66
+ td.trackPageview('pageviews')
67
+
68
+ // With success/error callbacks
69
+ td.trackPageview('pageviews',
70
+ (response) => console.log('Pageview tracked!'),
71
+ (error) => console.error('Failed:', error)
72
+ )
73
+
74
+ // With personalization: configure it once on the constructor. When set, every
75
+ // trackEvent/trackPageview call fetches personalization INSTEAD of ingesting the
76
+ // event (the call no longer records to your database — see below)
77
+ const td = new Treasure({
78
+ writeKey: 'your-write-key',
79
+ database: 'your-database',
80
+ personalization: {
81
+ endpoint: 'personalization.example.com',
82
+ token: 'personalization_token',
83
+ database: 'personalization_db' // optional; defaults to the main `database`
84
+ }
85
+ })
86
+
87
+ // The personalization table comes from the tracking call ('pageviews' here),
88
+ // and the request payload is the event data (track values + globals + record)
89
+ td.trackPageview('pageviews',
90
+ (response) => console.log('Personalization fetched!'),
91
+ (error) => console.error('Failed:', error)
92
+ )
93
+ ```
94
+
95
+ ### Event Tracking
96
+ ```javascript
97
+ // Basic event
98
+ td.trackEvent('events', {
99
+ event_type: 'purchase',
100
+ item_id: 'SKU-123',
101
+ revenue: 29.99
102
+ })
103
+
104
+ // With success/error callbacks
105
+ td.trackEvent('button_clicks', { button: 'header_cta' },
106
+ (response) => console.log('Tracked!'),
107
+ (error) => console.error('Failed:', error)
108
+ )
109
+ ```
110
+
111
+ ### Global Properties
112
+ ```javascript
113
+ // Set user properties for all events
114
+ td.set('$global', 'user_id', '12345')
115
+ td.set('$global', 'plan', 'premium')
116
+
117
+ // Set table-specific defaults
118
+ td.set('purchases', 'currency', 'USD')
119
+
120
+ // Multiple properties at once
121
+ td.set('$global', {
122
+ user_id: '12345',
123
+ plan: 'premium',
124
+ signup_date: '2024-01-15'
125
+ })
126
+ ```
127
+
128
+ ### Automatic Click Tracking
129
+ ```javascript
130
+ // Track all clicks on buttons and links
131
+ td.trackClicks()
132
+
133
+ // Custom configuration
134
+ td.trackClicks({
135
+ tableName: 'ui_interactions',
136
+ element: document.getElementById('main-content')
137
+ })
138
+ ```
139
+
140
+ ### UTM Parameter Collection
141
+ ```javascript
142
+ // Collect UTM parameters from URL
143
+ const utmParams = td.collectUTMParameters()
144
+ console.log(utmParams) // { utm_source: 'google', utm_campaign: 'summer2024' }
145
+
146
+ // Get previously collected UTMs
147
+ const storedUtms = td.getUTMParameters()
148
+ ```
149
+
150
+ ## Privacy & Consent Management
151
+
152
+ ### Signed vs Anonymous Mode
153
+ ```javascript
154
+ const td = new Treasure({
155
+ writeKey: 'key',
156
+ database: 'db',
157
+ startInSignedMode: false // Default: anonymous mode
158
+ })
159
+
160
+ // Anonymous mode (default) - no PII collected
161
+ td.setAnonymousMode()
162
+ td.trackEvent('events', { action: 'view' })
163
+ // Sends: { action: 'view', td_version: '1.0.0' }
164
+ // Omits: td_client_id, td_ip, td_global_id
165
+
166
+ // Signed mode - PII collection enabled
167
+ td.setSignedMode()
168
+ td.trackEvent('events', { action: 'purchase' })
169
+ // Sends: { action: 'purchase', td_client_id: 'uuid', td_ip: '192.168.1.1' }
170
+ ```
171
+
172
+ ### Event Blocking
173
+ ```javascript
174
+ // Temporarily block all events
175
+ td.blockEvents()
176
+ td.trackEvent('blocked', {}) // Not sent
177
+
178
+ // Resume tracking
179
+ td.unblockEvents()
180
+ td.trackEvent('tracked', {}) // Sent normally
181
+
182
+ // Check status
183
+ if (td.areEventsBlocked()) {
184
+ console.log('Tracking is currently blocked')
185
+ }
186
+ ```
187
+
188
+ ### Privacy Control Example
189
+ ```javascript
190
+ const td = new Treasure({ writeKey: 'key', database: 'db' })
191
+
192
+ // Programmatically manage privacy based on user preferences
193
+ function handleUserPrivacyChoice(privacyLevel) {
194
+ switch (privacyLevel) {
195
+ case 'full_tracking':
196
+ td.unblockEvents()
197
+ td.setSignedMode()
198
+ break
199
+ case 'anonymous_only':
200
+ td.unblockEvents()
201
+ td.setAnonymousMode()
202
+ break
203
+ case 'no_tracking':
204
+ td.blockEvents()
205
+ break
206
+ }
207
+ }
208
+
209
+ // Example: User clicks privacy preference buttons
210
+ document.getElementById('accept-all').onclick = () => handleUserPrivacyChoice('full_tracking')
211
+ document.getElementById('essential-only').onclick = () => handleUserPrivacyChoice('anonymous_only')
212
+ document.getElementById('reject-all').onclick = () => handleUserPrivacyChoice('no_tracking')
213
+ ```
214
+
215
+ ## Advanced Features
216
+
217
+ ### Global ID (Cross-device Tracking)
218
+ ```javascript
219
+ // 1. Enable Global ID collection
220
+ td.set('$global', 'td_global_id', 'td_global_id')
221
+
222
+ // 2. Switch to signed mode
223
+ td.setSignedMode()
224
+
225
+ // 3. Fetch Global ID
226
+ td.fetchGlobalID(
227
+ (globalId) => {
228
+ console.log('Global ID:', globalId)
229
+ // Use for cross-device analytics
230
+ },
231
+ (error) => console.error('Failed to get Global ID:', error),
232
+ false, // forceFetch
233
+ {
234
+ domain: '.yourdomain.com',
235
+ secure: true,
236
+ sameSite: 'None'
237
+ }
238
+ )
239
+ ```
240
+
241
+ ### Server-Side Cookies (ITP Compliance)
242
+ ```javascript
243
+ const td = new Treasure({
244
+ writeKey: 'key',
245
+ database: 'db',
246
+ useServerSideCookie: true,
247
+ sscDomain: 'yourdomain.com'
248
+ })
249
+
250
+ td.fetchServerCookie(
251
+ (serverId) => console.log('Server ID:', serverId),
252
+ (error) => console.error('Server cookie failed:', error)
253
+ )
254
+ ```
255
+
256
+ ### User Segmentation
257
+ ```javascript
258
+ // Fetch user segments for personalization
259
+ td.fetchUserSegments(
260
+ 'audience_token_abc123',
261
+ (segments) => {
262
+ segments.forEach(segment => {
263
+ console.log('Segment:', segment.values)
264
+ console.log('Attributes:', segment.attributes)
265
+ })
266
+ },
267
+ (error) => console.error('Segmentation failed:', error)
268
+ )
269
+
270
+ // With custom keys
271
+ td.fetchUserSegments({
272
+ audienceToken: ['token1', 'token2'],
273
+ keys: { user_id: '12345', email: 'user@example.com' }
274
+ }, successCallback, errorCallback)
275
+ ```
276
+
277
+ ### Personalization & In-Browser Messaging
278
+ ```javascript
279
+ // Manual personalization fetch
280
+ td.fetchPersonalization({
281
+ endpoint: 'personalization.example.com',
282
+ database: 'recommendations_db',
283
+ table: 'user_offers',
284
+ token: 'p13n_token_123'
285
+ }, {
286
+ user_id: '12345',
287
+ page_type: 'product_detail',
288
+ product_category: 'electronics'
289
+ }, (response) => {
290
+ console.log('Personalization response:', response)
291
+ })
292
+
293
+ // Personalization driven by tracking calls
294
+ // Configure personalization once on the constructor...
295
+ const td = new Treasure({
296
+ writeKey: 'your-write-key',
297
+ database: 'your-database',
298
+ personalization: {
299
+ endpoint: 'personalization.example.com',
300
+ token: 'p13n_token_123',
301
+ database: 'recommendations_db' // optional; defaults to the main `database`
302
+ }
303
+ })
304
+
305
+ // ...then trackEvent and trackPageview fetch personalization instead of
306
+ // ingesting the event. The personalization table is the tracking call's table,
307
+ // and the request payload is the event data ($global + table defaults + track
308
+ // values + record) — not recorded to your database.
309
+ td.trackEvent('events', { action: 'view' })
310
+ td.trackPageview('pageviews',
311
+ (response) => console.log('Personalization fetched'),
312
+ (error) => console.error('Personalization failed')
313
+ )
314
+ ```
315
+
316
+ ## Plugin Architecture
317
+
318
+ For advanced users who need custom plugin combinations:
319
+
320
+ ```typescript
321
+ import {
322
+ createSDK,
323
+ session,
324
+ record,
325
+ track,
326
+ clicks,
327
+ utm,
328
+ globalId
329
+ } from '@treasuredata/web-sdk'
330
+
331
+ // Build custom SDK with only needed plugins
332
+ const sdk = createSDK({
333
+ writeKey: 'your-key',
334
+ database: 'your-db'
335
+ })
336
+ .use(session()) // Identity & consent management
337
+ .use(record()) // Core event submission
338
+ .use(track()) // Auto-tracked properties
339
+ .use(clicks()) // Click tracking (optional)
340
+ .use(utm()) // UTM collection (optional)
341
+ .use(globalId()) // Global ID (optional)
342
+
343
+ // Same API as the full Treasure constructor
344
+ sdk.trackEvent('events', { custom: 'data' })
345
+ ```
346
+
347
+ ## Automatic Data Collection
348
+
349
+ When using `trackEvent()` or `trackPageview()`, these properties are automatically included:
350
+
351
+ | Property | Description | Example |
352
+ |----------|-------------|---------|
353
+ | `td_version` | SDK version | `"1.0.0"` |
354
+ | `td_client_id` | Client UUID* | `"abc-123-def"` |
355
+ | `td_charset` | Page character set | `"utf-8"` |
356
+ | `td_language` | Browser language | `"en-us"` |
357
+ | `td_color` | Screen color depth | `"24-bit"` |
358
+ | `td_screen` | Screen resolution | `"1920x1080"` |
359
+ | `td_viewport` | Viewport size | `"1200x800"` |
360
+ | `td_title` | Page title | `"Home Page"` |
361
+ | `td_description` | Meta description | `"Welcome to..."` |
362
+ | `td_url` | Page URL | `"https://example.com/page"` |
363
+ | `td_user_agent` | User agent + SDK info | `"Mozilla/5.0...;WEBSDK/1.0.0"` |
364
+ | `td_platform` | Platform | `"MacIntel"` |
365
+ | `td_host` | Hostname | `"example.com"` |
366
+ | `td_path` | URL path | `"/products/123"` |
367
+ | `td_referrer` | Referrer URL | `"https://google.com"` |
368
+
369
+ **Server-side properties** (populated by Treasure Data):
370
+ | Property | Description | Signed Mode Only |
371
+ |----------|-------------|------------------|
372
+ | `td_ip` | Request IP address | ✓ |
373
+
374
+ \* *Marked properties are considered PII and only sent in signed mode*
375
+
376
+ ## Configuration Options
377
+
378
+ ### Core Configuration
379
+ ```javascript
380
+ const td = new Treasure({
381
+ // Required
382
+ writeKey: 'your-write-key', // Get from Treasure Data console
383
+ database: 'your-database', // Target database name
384
+
385
+ // Optional
386
+ host: 'us01.records.in.treasuredata.com', // API endpoint host
387
+ development: false, // Enable development mode (no events sent)
388
+ logging: true, // Enable console logging
389
+ startInSignedMode: false, // Default consent mode
390
+ jsonpTimeout: 10000, // Request timeout (ms)
391
+ })
392
+ ```
393
+
394
+ ### Personalization Configuration
395
+ When set, every `trackEvent` and `trackPageview` call fetches personalization and renders any in-browser messages **instead of** ingesting the event to your database. The personalization table is the table passed to the tracking call, and the request payload is the event data (`$global` + table defaults + track values + record).
396
+ ```javascript
397
+ const td = new Treasure({
398
+ writeKey: 'key',
399
+ database: 'db',
400
+ personalization: {
401
+ endpoint: 'personalization.example.com', // Personalization API endpoint
402
+ token: 'p13n_token_123', // Personalization API token
403
+ database: 'recommendations_db' // Optional; defaults to the main `database`
404
+ }
405
+ })
406
+ ```
407
+
408
+ ### Storage Configuration
409
+ ```javascript
410
+ const td = new Treasure({
411
+ writeKey: 'key',
412
+ database: 'db',
413
+ storage: {
414
+ name: '_td', // Cookie name
415
+ expires: 63072000, // Expiry (seconds, 2 years default)
416
+ domain: '.yourdomain.com', // Cookie domain
417
+ path: '/' // Cookie path
418
+ }
419
+ })
420
+
421
+ // Disable cookie storage
422
+ const td = new Treasure({
423
+ writeKey: 'key',
424
+ database: 'db',
425
+ storage: 'none'
426
+ })
427
+ ```
428
+
429
+ ### Server-Side Cookie Configuration
430
+ ```javascript
431
+ const td = new Treasure({
432
+ writeKey: 'key',
433
+ database: 'db',
434
+ useServerSideCookie: true,
435
+ sscDomain: 'yourdomain.com', // Or function: () => window.location.hostname
436
+ sscServer: 'ssc.yourdomain.com' // Or function: (domain) => `ssc.${domain}`
437
+ })
438
+ ```
439
+
440
+
441
+ ## API Reference
442
+
443
+ ### Constructor
444
+ ```javascript
445
+ new Treasure(config: TDConfig): Treasure
446
+ ```
447
+
448
+ **Parameters:**
449
+ - `config` (Object, required): Configuration object
450
+ - `writeKey` (string, required): Write-only API key from Treasure Data console
451
+ - `database` (string, required): Target database name
452
+ - `host` (string, optional): API endpoint host. Default: `'us01.records.in.treasuredata.com'`
453
+ - `development` (boolean, optional): Development mode - logs events without sending. Default: `false`
454
+ - `logging` (boolean, optional): Enable console logging. Default: `true`
455
+ - `startInSignedMode` (boolean, optional): Start in signed mode. Default: `false`
456
+ - `jsonpTimeout` (number, optional): Request timeout in milliseconds. Default: `10000`
457
+ - `storage` (Object|string, optional): Cookie storage configuration or `'none'` to disable
458
+ - `useServerSideCookie` (boolean, optional): Enable server-side cookie support. Default: `false`
459
+ - `personalization` (Object, optional): Personalization config. When set, every `trackEvent`/`trackPageview` fetches personalization instead of ingesting the event
460
+ - `endpoint` (string, required): Personalization API endpoint
461
+ - `token` (string, required): Personalization API token
462
+ - `database` (string, optional): Personalization database name. Defaults to the main `database`
463
+ - The personalization **table** is the table passed to the tracking call (e.g. `'events'`, `'pageviews'`), not configured here
464
+ - The request **payload** is the event data (`$global` + table defaults + track values + the call's `record`), not configured here
465
+
466
+ ### Core Methods
467
+
468
+ #### `addRecord(table, record, success?, error?)`
469
+ Manual event submission without automatic tracking data.
470
+
471
+ **Parameters:**
472
+ - `table` (string, required): Table name (3-255 chars, lowercase, numbers, underscore only)
473
+ - `record` (Object, required): Event data object to send
474
+ - `success` (Function, optional): Success callback `(response: TrackResponse) => void`
475
+ - `error` (Function, optional): Error callback `(error: TDError) => void`
476
+
477
+ #### `trackEvent(table?, record?, success?, error?)`
478
+ Event tracking with automatic browser/session properties included. When `personalization` is configured on the constructor, fetches personalization instead of ingesting the event (see Behavior below).
479
+
480
+ **Parameters:**
481
+ - `table` (string, optional): Table name. Default: `'events'`
482
+ - `record` (Object, optional): Additional event data. Default: `{}`
483
+ - `success` (Function, optional): Success callback `(response: TrackResponse) => void`
484
+ - `error` (Function, optional): Error callback `(error: TDError) => void`
485
+
486
+ **Behavior:**
487
+ - When `personalization` is **not** configured: records the event with automatic properties via `addRecord`, invoking the `success`/`error` callbacks.
488
+ - When `personalization` **is** configured (see Configuration Options): calls the personalization API **instead of** recording the event. The personalization table is `table`, and the request payload is the event data layered as `$global` → table defaults → automatic track values → `record`.
489
+ - Personalization responses trigger in-browser message rendering
490
+ - Personalization errors are logged
491
+ - The `success`/`error` callbacks are **not** invoked on this path
492
+
493
+ #### `trackPageview(table?, success?, error?, options?)`
494
+ Page view tracking with automatic browser/session properties. Delegates to `trackEvent`, so it shares the same personalization behavior.
495
+
496
+ **Parameters:**
497
+ - `table` (string, optional): Table name. Default: `'pageviews'`
498
+ - `success` (Function, optional): Success callback `(response: TrackResponse) => void`
499
+ - `error` (Function, optional): Error callback `(error: TDError) => void`
500
+ - `options` (Object, optional): Tracking options
501
+ - `payload` (Object, optional): Additional event data to merge into the tracking record
502
+
503
+ **Behavior:**
504
+ - Delegates to `trackEvent` with the resolved table name and `options.payload` as the record
505
+ - When `personalization` is **not** configured on the constructor: records the pageview with automatic properties via `addRecord`
506
+ - When `personalization` **is** configured: fetches personalization instead of ingesting (same XOR behavior as `trackEvent`). Personalization responses trigger in-browser message rendering and page personalization. Page personalization is suppressed while loaded in Personalization Studio
507
+
508
+ #### `set(table, key, value)` or `set(table, object)`
509
+ Set default properties for tables or globally.
510
+
511
+ **Parameters:**
512
+ - `table` (string, required): Table name or `'$global'` for all tables
513
+ - `key` (string, required): Property name (when using 3-parameter form)
514
+ - `value` (JSONValue, required): Property value (when using 3-parameter form)
515
+ - `object` (Object, required): Multiple properties object (when using 2-parameter form)
516
+
517
+ #### `get(table?, key?)`
518
+ Retrieve stored default properties.
519
+
520
+ **Parameters:**
521
+ - `table` (string, optional): Table name. Default: `'$global'`
522
+ - `key` (string, optional): Specific property name. If omitted, returns all properties for table
523
+
524
+ **Returns:** `JSONValue` - The property value or properties object
525
+
526
+ ### Identity & Privacy Methods
527
+
528
+ #### `setSignedMode()`
529
+ Enable signed mode - allows collection of PII (td_client_id, td_ip, td_global_id).
530
+
531
+ #### `setAnonymousMode(keepIdentifier?)`
532
+ Enable anonymous mode - blocks PII collection.
533
+
534
+ **Parameters:**
535
+ - `keepIdentifier` (boolean, optional): Keep existing cookies/identifiers. Default: `false`
536
+
537
+ #### `inSignedMode()`
538
+ Check current privacy mode.
539
+
540
+ **Returns:** `boolean` - True if in signed mode, false if anonymous
541
+
542
+ #### `blockEvents()`
543
+ Block all event tracking. Events will not be sent or cached.
544
+
545
+ #### `unblockEvents()`
546
+ Resume event tracking.
547
+
548
+ #### `areEventsBlocked()`
549
+ Check if events are currently blocked.
550
+
551
+ **Returns:** `boolean` - True if events are blocked
552
+
553
+ #### `resetUUID(storage?, clientId?)`
554
+ Generate new client UUID and update cookie.
555
+
556
+ **Parameters:**
557
+ - `storage` (Object, optional): Custom storage configuration
558
+ - `clientId` (string, optional): Specific UUID to set. If omitted, generates random UUID
559
+
560
+ ### Plugin Methods
561
+
562
+ #### `trackClicks(options?)`
563
+ Enable automatic click tracking for buttons and links.
564
+
565
+ **Parameters:**
566
+ - `options` (Object, optional): Click tracking configuration
567
+ - `tableName` (string, optional): Table name. Default: `'clicks'`
568
+ - `element` (string|HTMLElement, optional): Target element or selector. Default: `document`
569
+
570
+ #### `collectUTMParameters()`
571
+ Extract UTM parameters from current URL.
572
+
573
+ **Returns:** `Object` - UTM parameters object (utm_source, utm_campaign, etc.)
574
+
575
+ #### `getUTMParameters()`
576
+ Get previously collected UTM parameters.
577
+
578
+ **Returns:** `Object` - Stored UTM parameters
579
+
580
+ #### `fetchGlobalID(success?, error?, forceFetch?, options?)`
581
+ Fetch Treasure Data Global ID for cross-device tracking.
582
+
583
+ **Prerequisites:** Must call `setSignedMode()` and `set('$global', 'td_global_id', 'td_global_id')` first.
584
+
585
+ **Parameters:**
586
+ - `success` (Function, optional): Success callback `(globalId: string | null) => void`
587
+ - `error` (Function, optional): Error callback `(error: unknown) => void`
588
+ - `forceFetch` (boolean, optional): Skip cache and fetch fresh ID. Default: `false`
589
+ - `options` (Object, optional): Cookie options
590
+ - `path` (string, optional): Cookie path
591
+ - `domain` (string, optional): Cookie domain
592
+ - `secure` (boolean, optional): Secure flag
593
+ - `maxAge` (number|string|Date, optional): Cookie expiry. Default: `6000`
594
+ - `sameSite` (string, optional): SameSite attribute ('None'|'Lax'|'Strict'). Default: `'None'`
595
+
596
+ #### `fetchServerCookie(success?, error?, forceFetch?)`
597
+ Fetch server-side cookie for ITP compliance.
598
+
599
+ **Prerequisites:** Must enable with `useServerSideCookie: true` in config and call `setSignedMode()`.
600
+
601
+ **Parameters:**
602
+ - `success` (Function, optional): Success callback `(serverSideId: string) => void`
603
+ - `error` (Function, optional): Error callback `(error: string | Error) => void`
604
+ - `forceFetch` (boolean, optional): Skip cache and fetch fresh cookie. Default: `false`
605
+
606
+ #### `fetchUserSegments(audienceToken, success?, error?)` or `fetchUserSegments(options, success?, error?)`
607
+ Fetch user segments for personalization.
608
+
609
+ **Parameters (Form 1):**
610
+ - `audienceToken` (string|string[], required): Audience token(s)
611
+ - `success` (Function, optional): Success callback with segment data
612
+ - `error` (Function, optional): Error callback
613
+
614
+ **Parameters (Form 2):**
615
+ - `options` (Object, required): Segmentation options
616
+ - `audienceToken` (string|string[], required): Audience token(s)
617
+ - `keys` (Object, optional): Additional key-value data
618
+ - `success` (Function, optional): Success callback with segment data
619
+ - `error` (Function, optional): Error callback
620
+
621
+ #### `fetchPersonalization(config, data?, success?, error?)`
622
+ Fetch personalization data from CDP API.
623
+
624
+ **Parameters:**
625
+ - `config` (Object, required): Personalization configuration
626
+ - `endpoint` (string, required): API endpoint URL
627
+ - `database` (string, required): Database name
628
+ - `table` (string, required): Table name
629
+ - `token` (string, required): API token
630
+ - `data` (Object, optional): Additional request data
631
+ - `success` (Function, optional): Success callback `(response: Object) => void`
632
+ - `error` (Function, optional): Error callback `(error: Error) => void`
633
+
634
+ #### `collectTags(options?)`
635
+ Collect conversion tracking tags for ad platforms.
636
+
637
+ **Parameters:**
638
+ - `options` (Object, optional): Collection options
639
+ - `table` (string, optional): Table name for storing tags
640
+ - `success` (Function, optional): Success callback `(response: TrackResponse) => void`
641
+ - `error` (Function, optional): Error callback `(error: TDError) => void`
642
+
643
+ ## Examples
644
+
645
+ ### E-commerce Tracking
646
+ ```javascript
647
+ const td = new Treasure({ writeKey: 'key', database: 'ecommerce' })
648
+
649
+ // Product view
650
+ td.trackEvent('product_views', {
651
+ product_id: 'SKU-123',
652
+ category: 'electronics',
653
+ price: 299.99,
654
+ currency: 'USD'
655
+ })
656
+
657
+ // Purchase
658
+ td.trackEvent('purchases', {
659
+ order_id: 'ORDER-456',
660
+ items: ['SKU-123', 'SKU-789'],
661
+ total: 349.98,
662
+ payment_method: 'credit_card'
663
+ })
664
+
665
+ // Set user context
666
+ td.set('$global', {
667
+ user_id: '12345',
668
+ customer_tier: 'gold',
669
+ signup_date: '2024-01-15'
670
+ })
671
+ ```
672
+
673
+ ### SaaS Application Analytics
674
+ ```javascript
675
+ const td = new Treasure({ writeKey: 'key', database: 'saas_analytics' })
676
+
677
+ // Feature usage
678
+ td.trackEvent('feature_usage', {
679
+ feature: 'dashboard_export',
680
+ plan: 'pro',
681
+ execution_time_ms: 1250
682
+ })
683
+
684
+ // User onboarding
685
+ td.trackEvent('onboarding_steps', {
686
+ step: 'profile_completed',
687
+ step_number: 3,
688
+ time_to_complete_sec: 45
689
+ })
690
+
691
+ // Error tracking
692
+ td.trackEvent('errors', {
693
+ error_type: 'validation_failed',
694
+ form: 'user_signup',
695
+ field: 'email'
696
+ })
697
+ ```
698
+
699
+ ### Content & Media Site
700
+ ```javascript
701
+ const td = new Treasure({ writeKey: 'key', database: 'content_analytics' })
702
+
703
+ // Article engagement
704
+ td.trackEvent('content_engagement', {
705
+ article_id: 'post-123',
706
+ engagement_type: 'scroll_75_percent',
707
+ time_on_page_sec: 120,
708
+ reading_speed_wpm: 200
709
+ })
710
+
711
+ // Video tracking
712
+ td.trackEvent('video_events', {
713
+ video_id: 'vid-789',
714
+ event: 'play',
715
+ position_sec: 0,
716
+ duration_sec: 300
717
+ })
718
+
719
+ // Newsletter signup
720
+ td.trackEvent('conversions', {
721
+ type: 'newsletter_signup',
722
+ source: 'article_cta',
723
+ article_category: 'technology'
724
+ })
725
+ ```
726
+
727
+ ## Troubleshooting
728
+
729
+ ### Common Issues
730
+
731
+ **Events not appearing in Treasure Data:**
732
+ - Check `development: false` in config
733
+ - Verify `writeKey` and `database` are correct
734
+ - Ensure events aren't blocked: `td.areEventsBlocked()`
735
+ - Check browser console for error messages
736
+
737
+ **TypeScript errors:**
738
+ ```bash
739
+ npm install --save-dev @types/node # If using Node.js types
740
+ ```
741
+
742
+ **Global ID not working:**
743
+ - Must call `td.setSignedMode()` first
744
+ - Must enable with `td.set('$global', 'td_global_id', 'td_global_id')`
745
+ - Check HTTPS requirement for secure cookies
746
+
747
+ **Server-side cookie fails:**
748
+ - Verify `useServerSideCookie: true` in config
749
+ - Check `sscDomain` configuration
750
+ - Ensure signed mode is enabled
751
+
752
+ ### Debug Mode
753
+ ```javascript
754
+ const td = new Treasure({
755
+ writeKey: 'key',
756
+ database: 'db',
757
+ development: true, // Events logged, not sent
758
+ logging: true // Enable debug logs
759
+ })
760
+ ```
761
+
762
+ ## Browser Support
763
+
764
+ - **Modern**: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
765
+ - **Baseline**: All browsers with ES2022 support
766
+ - **Polyfills**: None required for target browsers
767
+
768
+ ## Security
769
+
770
+ - All requests use HTTPS
771
+ - Write-only API keys (no read access)
772
+ - Optional PII collection controls
773
+ - SameSite=None cookies for cross-site tracking
774
+ - No sensitive data in localStorage
775
+
776
+ ## Development
777
+
778
+ ### Code Quality
779
+
780
+ This project uses automated code quality checks that run before each commit:
781
+
782
+ - **Type checking** - TypeScript compilation validation
783
+ - **Linting** - ESLint rules enforcement
784
+ - **Formatting** - Prettier code formatting
785
+
786
+ #### Setting up pre-commit hooks
787
+
788
+ To enable automatic code quality checks on commit:
789
+
790
+ ```bash
791
+ npm run hooks:install
792
+ ```
793
+
794
+ This configures git to run type-check, linting, and formatting before each commit. If formatting changes are needed, the commit will be blocked and you'll need to review and stage the changes.
795
+
796
+ #### Manual code quality checks
797
+
798
+ You can also run these checks manually:
799
+
800
+ ```bash
801
+ npm run type-check # TypeScript compilation check
802
+ npm run lint # ESLint linting
803
+ npm run lint:fix # Auto-fix linting issues
804
+ npm run format # Apply Prettier formatting
805
+ npm run format:check # Check formatting without applying changes
806
+ ```
807
+