@altertable/altertable-js 0.5.7 → 1.0.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 CHANGED
@@ -39,6 +39,9 @@ altertable.identify('u_01jza857w4f23s1hf2s61befmw', {
39
39
  altertable.updateTraits({
40
40
  onboarding_completed: true,
41
41
  });
42
+
43
+ // Link a new ID to the current identity
44
+ altertable.alias('new_user_id-019aca6a-1e42-71af-81a0-1e14bbe2ccbd');
42
45
  ```
43
46
 
44
47
  ## Features
@@ -136,6 +139,7 @@ altertable.page('https://example.com/products');
136
139
  #### `altertable.identify(userId, traits?)`
137
140
 
138
141
  Identifies a user with their ID and optional traits.
142
+ It flags the identity as being a identitied user.
139
143
 
140
144
  **Parameters:**
141
145
 
@@ -173,30 +177,44 @@ altertable.updateTraits({
173
177
  });
174
178
  ```
175
179
 
180
+ #### `altertable.alias(newUserId)`
181
+
182
+ Links a new ID to the current identity.
183
+
184
+ **Parameters:**
185
+
186
+ | Parameter | Type | Required | Default | Description |
187
+ | ----------- | -------- | -------- | ------- | -------------------------------------- |
188
+ | `newUserId` | `string` | Yes | ------- | New ID to link to the current identity |
189
+
190
+ **Example:**
191
+
192
+ ```javascript
193
+ altertable.alias("new_user_id-019aca6a-1e42-71af-81a0-1e14bbe2ccbd");
194
+ ```
195
+
176
196
  ### Session Management
177
197
 
178
198
  #### `altertable.reset(options?)`
179
199
 
180
- Resets visitor and session IDs.
200
+ Resets the current identity context so future events are not associated with the previous user.
181
201
 
182
202
  **Parameters:**
183
203
 
184
204
  | Parameter | Type | Required | Default | Description |
185
205
  | ------------------------ | --------- | -------- | ------- | --------------------------- |
186
206
  | `options` | `object` | No | `{}` | Reset options |
187
- | `options.resetVisitorId` | `boolean` | No | `false` | Whether to reset visitor ID |
188
- | `options.resetSessionId` | `boolean` | No | `true` | Whether to reset session ID |
207
+ | `options.resetDeviceId` | `boolean` | No | `false` | Whether to reset device ID |
189
208
 
190
209
  **Example:**
191
210
 
192
211
  ```javascript
193
- // Reset session only (default)
212
+ // Reset everything except device ID
194
213
  altertable.reset();
195
214
 
196
- // Reset both visitor and session
215
+ // Reset all IDs
197
216
  altertable.reset({
198
- resetVisitorId: true,
199
- resetSessionId: true,
217
+ resetDeviceId: true,
200
218
  });
201
219
  ```
202
220
 
@@ -251,7 +269,7 @@ Configuration options for the Altertable SDK.
251
269
  | `release` | `string` | - | The release ID of the application |
252
270
  | `debug` | `boolean` | `false` | Whether to log events to the console |
253
271
  | `persistence` | [`StorageType`](#storagetype) | `"localStorage+cookie"` | The persistence strategy for storing IDs |
254
- | `trackingConsent` | [`TrackingConsentType`](#trackingconsenttype) | `"pending"` | The tracking consent state |
272
+ | `trackingConsent` | [`TrackingConsentType`](#trackingconsenttype) | `"granted"` | The tracking consent state |
255
273
 
256
274
  ### `EventProperties`
257
275
 
package/dist/index.d.mts CHANGED
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Available tracking consent states.
3
+ *
4
+ * Use these constants to manage user consent for tracking and analytics.
5
+ *
6
+ * @property GRANTED User has granted consent for tracking
7
+ * @property DENIED User has denied consent for tracking
8
+ * @property PENDING User hasn't made a decision yet
9
+ * @property DISMISSED User dismissed the consent prompt
10
+ *
11
+ * @example
12
+ * ```javascript
13
+ * import { altertable, TrackingConsent } from '@altertable/altertable-js';
14
+ *
15
+ * // Set tracking consent to granted
16
+ * altertable.configure({
17
+ * trackingConsent: TrackingConsent.GRANTED,
18
+ * });
19
+ *
20
+ * // Check current consent state
21
+ * const consent = altertable.getTrackingConsent();
22
+ * if (consent === TrackingConsent.GRANTED) {
23
+ * // Tracking is allowed
24
+ * }
25
+ * ```
26
+ */
1
27
  declare const TrackingConsent: {
2
28
  readonly DENIED: "denied";
3
29
  readonly DISMISSED: "dismissed";
@@ -10,6 +36,9 @@ type StorageType = 'localStorage' | 'sessionStorage' | 'cookie' | 'memory' | 'lo
10
36
 
11
37
  type StringWithAutocomplete<T> = T | (string & {});
12
38
  type EventProperties = Record<string, unknown>;
39
+ type UserId = string;
40
+ type DistinctId = StringWithAutocomplete<UserId | VisitorId>;
41
+ type VisitorId = `visitor-${string}`;
13
42
  type Environment = StringWithAutocomplete<'production' | 'development' | 'staging'>;
14
43
  interface UserTraits extends Record<string, unknown> {
15
44
  email?: string;
@@ -48,9 +77,13 @@ interface AltertableConfig {
48
77
  persistence?: StorageType;
49
78
  /**
50
79
  * The tracking consent state.
51
- * @default "pending"
80
+ * @default "granted"
52
81
  */
53
82
  trackingConsent?: TrackingConsentType;
83
+ /**
84
+ * Optional error handler for intercepting SDK errors.
85
+ */
86
+ onError?: (error: Error) => void;
54
87
  }
55
88
  declare class Altertable {
56
89
  private _cleanupAutoCapture;
@@ -65,17 +98,150 @@ declare class Altertable {
65
98
  private _storage;
66
99
  private _storageKey;
67
100
  constructor();
101
+ /**
102
+ * Initializes the Altertable SDK with your API key and optional configuration.
103
+ *
104
+ * @param apiKey Your Altertable API key
105
+ * @param config Configuration options
106
+ * @returns A cleanup function to remove event listeners
107
+ *
108
+ * @example
109
+ * ```javascript
110
+ * altertable.init('YOUR_API_KEY', {
111
+ * environment: 'development',
112
+ * });
113
+ * ```
114
+ */
68
115
  init(apiKey: string, config?: AltertableConfig): () => void;
116
+ /**
117
+ * Updates the configuration after initialization.
118
+ *
119
+ * @param updates Configuration updates to apply
120
+ *
121
+ * @example
122
+ * ```javascript
123
+ * altertable.configure({
124
+ * trackingConsent: 'granted',
125
+ * });
126
+ * ```
127
+ */
69
128
  configure(updates: Partial<AltertableConfig>): void;
70
129
  private _handleAutoCaptureChange;
130
+ /**
131
+ * Identifies a user with their ID and optional traits.
132
+ *
133
+ * @param userId The user's unique identifier
134
+ * @param traits User properties
135
+ *
136
+ * @example
137
+ * ```javascript
138
+ * altertable.identify('u_01jza857w4f23s1hf2s61befmw', {
139
+ * email: 'john.doe@example.com',
140
+ * name: 'John Doe',
141
+ * company: 'Acme Corp',
142
+ * role: 'Software Engineer',
143
+ * });
144
+ * ```
145
+ */
71
146
  identify(userId: string, traits?: UserTraits): void;
147
+ /**
148
+ * Link a new ID to the current identity.
149
+ *
150
+ * @param newUserId The new user ID
151
+ *
152
+ * @example
153
+ * ```javascript
154
+ * altertable.alias('u_01jza857w4f23s1hf2s61befmw');
155
+ * ```
156
+ */
157
+ alias(newUserId: DistinctId): void;
158
+ /**
159
+ * Updates user traits for the current user.
160
+ *
161
+ * @param traits User properties to update
162
+ *
163
+ * @example
164
+ * ```javascript
165
+ * altertable.updateTraits({
166
+ * onboarding_completed: true,
167
+ * });
168
+ * ```
169
+ */
72
170
  updateTraits(traits: UserTraits): void;
73
- reset({ resetVisitorId, resetSessionId, }?: {
74
- resetVisitorId?: boolean;
75
- resetSessionId?: boolean;
171
+ /**
172
+ * Resets device and session IDs.
173
+ *
174
+ * @example
175
+ * ```javascript
176
+ * // Reset session, user and visitor (default)
177
+ * altertable.reset();
178
+ *
179
+ * // Reset session, user, visitor and device
180
+ * altertable.reset({
181
+ * resetDeviceId: true,
182
+ * });
183
+ * ```
184
+ */
185
+ reset({ resetDeviceId, }?: {
186
+ /** Whether to reset device ID (default: false) */
187
+ resetDeviceId?: boolean;
76
188
  }): void;
189
+ /**
190
+ * Tracks a page view event.
191
+ *
192
+ * When `autoCapture` is enabled (default), this method is automatically called when the page URL changes.
193
+ *
194
+ * @param url The page URL
195
+ *
196
+ * @example
197
+ * ```javascript
198
+ * altertable.page('https://example.com/products');
199
+ * ```
200
+ *
201
+ * @remarks
202
+ * **Page Tracking**: By default, Altertable automatically captures page views. Only use `page()` when you've disabled auto-capture.
203
+ *
204
+ * **Why use auto-capture (default)?**
205
+ * - No manual tracking required
206
+ * - Handles browser navigation events (popstate, hashchange)
207
+ * - Consistent tracking across all page changes
208
+ *
209
+ * **When to use `page()`:**
210
+ * - Custom routing that doesn't trigger browser events
211
+ * - Virtual page views that don't trigger URL changes (modals, step changes)
212
+ * - Server-side tracking where auto-capture isn't available
213
+ */
77
214
  page(url: string): void;
215
+ /**
216
+ * Tracks a custom event with optional properties.
217
+ *
218
+ * @param eventThe event name
219
+ * @param properties Custom event properties
220
+ *
221
+ * @example
222
+ * ```javascript
223
+ * altertable.track('Purchase Completed', {
224
+ * product_id: 'p_01jza8fr5efvgbxxdd1bwkd0m5',
225
+ * amount: 29.99,
226
+ * currency: 'USD',
227
+ * });
228
+ * ```
229
+ */
78
230
  track(event: string, properties?: EventProperties): void;
231
+ /**
232
+ * Returns the current tracking consent state.
233
+ *
234
+ * @returns The current tracking consent state
235
+ * @see {@link TrackingConsent}
236
+ *
237
+ * @example
238
+ * ```javascript
239
+ * const consent = altertable.getTrackingConsent();
240
+ * if (consent === 'granted') {
241
+ * // Tracking is allowed
242
+ * }
243
+ * ```
244
+ */
79
245
  getTrackingConsent(): TrackingConsentType;
80
246
  private _checkForChanges;
81
247
  private _getContext;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Available tracking consent states.
3
+ *
4
+ * Use these constants to manage user consent for tracking and analytics.
5
+ *
6
+ * @property GRANTED User has granted consent for tracking
7
+ * @property DENIED User has denied consent for tracking
8
+ * @property PENDING User hasn't made a decision yet
9
+ * @property DISMISSED User dismissed the consent prompt
10
+ *
11
+ * @example
12
+ * ```javascript
13
+ * import { altertable, TrackingConsent } from '@altertable/altertable-js';
14
+ *
15
+ * // Set tracking consent to granted
16
+ * altertable.configure({
17
+ * trackingConsent: TrackingConsent.GRANTED,
18
+ * });
19
+ *
20
+ * // Check current consent state
21
+ * const consent = altertable.getTrackingConsent();
22
+ * if (consent === TrackingConsent.GRANTED) {
23
+ * // Tracking is allowed
24
+ * }
25
+ * ```
26
+ */
1
27
  declare const TrackingConsent: {
2
28
  readonly DENIED: "denied";
3
29
  readonly DISMISSED: "dismissed";
@@ -10,6 +36,9 @@ type StorageType = 'localStorage' | 'sessionStorage' | 'cookie' | 'memory' | 'lo
10
36
 
11
37
  type StringWithAutocomplete<T> = T | (string & {});
12
38
  type EventProperties = Record<string, unknown>;
39
+ type UserId = string;
40
+ type DistinctId = StringWithAutocomplete<UserId | VisitorId>;
41
+ type VisitorId = `visitor-${string}`;
13
42
  type Environment = StringWithAutocomplete<'production' | 'development' | 'staging'>;
14
43
  interface UserTraits extends Record<string, unknown> {
15
44
  email?: string;
@@ -48,9 +77,13 @@ interface AltertableConfig {
48
77
  persistence?: StorageType;
49
78
  /**
50
79
  * The tracking consent state.
51
- * @default "pending"
80
+ * @default "granted"
52
81
  */
53
82
  trackingConsent?: TrackingConsentType;
83
+ /**
84
+ * Optional error handler for intercepting SDK errors.
85
+ */
86
+ onError?: (error: Error) => void;
54
87
  }
55
88
  declare class Altertable {
56
89
  private _cleanupAutoCapture;
@@ -65,17 +98,150 @@ declare class Altertable {
65
98
  private _storage;
66
99
  private _storageKey;
67
100
  constructor();
101
+ /**
102
+ * Initializes the Altertable SDK with your API key and optional configuration.
103
+ *
104
+ * @param apiKey Your Altertable API key
105
+ * @param config Configuration options
106
+ * @returns A cleanup function to remove event listeners
107
+ *
108
+ * @example
109
+ * ```javascript
110
+ * altertable.init('YOUR_API_KEY', {
111
+ * environment: 'development',
112
+ * });
113
+ * ```
114
+ */
68
115
  init(apiKey: string, config?: AltertableConfig): () => void;
116
+ /**
117
+ * Updates the configuration after initialization.
118
+ *
119
+ * @param updates Configuration updates to apply
120
+ *
121
+ * @example
122
+ * ```javascript
123
+ * altertable.configure({
124
+ * trackingConsent: 'granted',
125
+ * });
126
+ * ```
127
+ */
69
128
  configure(updates: Partial<AltertableConfig>): void;
70
129
  private _handleAutoCaptureChange;
130
+ /**
131
+ * Identifies a user with their ID and optional traits.
132
+ *
133
+ * @param userId The user's unique identifier
134
+ * @param traits User properties
135
+ *
136
+ * @example
137
+ * ```javascript
138
+ * altertable.identify('u_01jza857w4f23s1hf2s61befmw', {
139
+ * email: 'john.doe@example.com',
140
+ * name: 'John Doe',
141
+ * company: 'Acme Corp',
142
+ * role: 'Software Engineer',
143
+ * });
144
+ * ```
145
+ */
71
146
  identify(userId: string, traits?: UserTraits): void;
147
+ /**
148
+ * Link a new ID to the current identity.
149
+ *
150
+ * @param newUserId The new user ID
151
+ *
152
+ * @example
153
+ * ```javascript
154
+ * altertable.alias('u_01jza857w4f23s1hf2s61befmw');
155
+ * ```
156
+ */
157
+ alias(newUserId: DistinctId): void;
158
+ /**
159
+ * Updates user traits for the current user.
160
+ *
161
+ * @param traits User properties to update
162
+ *
163
+ * @example
164
+ * ```javascript
165
+ * altertable.updateTraits({
166
+ * onboarding_completed: true,
167
+ * });
168
+ * ```
169
+ */
72
170
  updateTraits(traits: UserTraits): void;
73
- reset({ resetVisitorId, resetSessionId, }?: {
74
- resetVisitorId?: boolean;
75
- resetSessionId?: boolean;
171
+ /**
172
+ * Resets device and session IDs.
173
+ *
174
+ * @example
175
+ * ```javascript
176
+ * // Reset session, user and visitor (default)
177
+ * altertable.reset();
178
+ *
179
+ * // Reset session, user, visitor and device
180
+ * altertable.reset({
181
+ * resetDeviceId: true,
182
+ * });
183
+ * ```
184
+ */
185
+ reset({ resetDeviceId, }?: {
186
+ /** Whether to reset device ID (default: false) */
187
+ resetDeviceId?: boolean;
76
188
  }): void;
189
+ /**
190
+ * Tracks a page view event.
191
+ *
192
+ * When `autoCapture` is enabled (default), this method is automatically called when the page URL changes.
193
+ *
194
+ * @param url The page URL
195
+ *
196
+ * @example
197
+ * ```javascript
198
+ * altertable.page('https://example.com/products');
199
+ * ```
200
+ *
201
+ * @remarks
202
+ * **Page Tracking**: By default, Altertable automatically captures page views. Only use `page()` when you've disabled auto-capture.
203
+ *
204
+ * **Why use auto-capture (default)?**
205
+ * - No manual tracking required
206
+ * - Handles browser navigation events (popstate, hashchange)
207
+ * - Consistent tracking across all page changes
208
+ *
209
+ * **When to use `page()`:**
210
+ * - Custom routing that doesn't trigger browser events
211
+ * - Virtual page views that don't trigger URL changes (modals, step changes)
212
+ * - Server-side tracking where auto-capture isn't available
213
+ */
77
214
  page(url: string): void;
215
+ /**
216
+ * Tracks a custom event with optional properties.
217
+ *
218
+ * @param eventThe event name
219
+ * @param properties Custom event properties
220
+ *
221
+ * @example
222
+ * ```javascript
223
+ * altertable.track('Purchase Completed', {
224
+ * product_id: 'p_01jza8fr5efvgbxxdd1bwkd0m5',
225
+ * amount: 29.99,
226
+ * currency: 'USD',
227
+ * });
228
+ * ```
229
+ */
78
230
  track(event: string, properties?: EventProperties): void;
231
+ /**
232
+ * Returns the current tracking consent state.
233
+ *
234
+ * @returns The current tracking consent state
235
+ * @see {@link TrackingConsent}
236
+ *
237
+ * @example
238
+ * ```javascript
239
+ * const consent = altertable.getTrackingConsent();
240
+ * if (consent === 'granted') {
241
+ * // Tracking is allowed
242
+ * }
243
+ * ```
244
+ */
79
245
  getTrackingConsent(): TrackingConsentType;
80
246
  private _checkForChanges;
81
247
  private _getContext;
@@ -1,9 +1,9 @@
1
- /*! @altertable/altertable-js 0.5.7 | MIT License | Altertable | https://github.com/altertable-ai/altertable-js */
2
- var Altertable=(()=>{var $=Object.defineProperty;var ve=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Se=Object.prototype.hasOwnProperty;var Ie=(n,e)=>{for(var t in e)$(n,t,{get:e[t],enumerable:!0})},Te=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ee(e))!Se.call(n,s)&&s!==t&&$(n,s,{get:()=>e[s],enumerable:!(r=ve(e,s))||r.enumerable});return n};var ye=n=>Te($({},"__esModule",{value:!0}),n);var $e={};Ie($e,{TrackingConsent:()=>o,altertable:()=>F});function z(n,e){return(...t)=>[n,...t].join(e)}var be="atbl",L=z(be,"."),u=L("check"),K="session",G="visitor",ke=1e3*60,Y=100,Q=30*ke,W=1e3,X=5e3,j="$pageview",H="$lib",J="$lib_version",Z="$referer",ee="$release",d="$url",te="$viewport",o={DENIED:"denied",DISMISSED:"dismissed",GRANTED:"granted",PENDING:"pending"},N=["anonymous_id","anonymous","distinct_id","distinctid","false","guest","id","not_authenticated","true","undefined","user_id","user","visitor_id","visitor"],V=new Set(["[object Object]","0","NaN","none","None","null"]);var I=class{_queue=[];_queueMaxSize;constructor(e){this._queueMaxSize=e}enqueue(e,t,r){this._queue.length>=this._queueMaxSize&&this._queue.shift(),this._queue.push({eventType:e,payload:t,context:r,sentAt:new Date})}flush(){let e=[...this._queue];return this._queue=[],e}clear(){this._queue=[]}getSize(){return this._queue.length}};function l(n,e){if(!n)throw new Error("Invariant failed")}function ie(n){return{log:(...e)=>{console.log(`[${n}]`,...e)},logHeader:()=>{let e="Altertable v0.5.7 %c\u2022 Debug mode enabled";T.current[e]||(T.current[e]=!0,console.log(e,"color: #64748b;"))},logEvent:(e,{trackingConsent:t})=>{let[r,s]=ne(e.event==="$pageview"?"Page":"Track"),[i,c]=we(e.event==="$pageview"?String(e.properties[d]):e.event),[g,_]=re(e.environment),[h,R]=De(e.timestamp),[w,A]=se(t);console.groupCollapsed(`[${n}] %c${r}%c ${i} %c[${g}] %c${h} %c${w}`,s,c,_,R,A);let[D,P]=m("User ID"),[x,U]=v(e.user_id??"Not set"),[ge,ue]=m("Visitor ID"),[de,fe]=v(e.visitor_id??"Not set"),[pe,_e]=m("Session ID"),[he,me]=v(e.session_id??"Not set");console.log(`%c${D} %c${x}`,P,U),console.log(`%c${ge} %c${de}`,ue,fe),console.log(`%c${pe} %c${he}`,_e,me),console.table(e.properties),console.groupEnd()},logIdentify:(e,{trackingConsent:t})=>{let[r,s]=ne("Identify"),[i,c]=re(e.environment),[g,_]=se(t);console.groupCollapsed(`[${n}] %c${r}%c ${e.user_id} %c[${i}] %c${g}`,s,"font-weight: 600;",c,_);let[h,R]=m("User ID"),[w,A]=v(e.user_id??"Not set"),[D,P]=m("Visitor ID"),[x,U]=v(e.visitor_id??"Not set");console.log(`%c${h} %c${w}`,R,A),console.log(`%c${D} %c${x}`,P,U),console.table(e.traits),console.groupEnd()},warn:(...e)=>{console.warn(`[${n}]`,...e)},warnDev:(e,...t)=>{},error:(...e)=>{console.error(`[${n}]`,...e)}}}var T={current:{}};function Ce(n){return new Date(n).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}function Re(n){switch(n){case"Page":return"#64748b";case"Identify":return"#a855f7";case"Track":return"#10b981";default:return"#1e293b"}}function ne(n){return[n,`background: ${Re(n)}; color: #ffffff; padding: 2px 8px; border-radius: 6px; font-weight: 400;`]}function we(n){return[n==="$pageview"?"Page Viewed":n,"font-weight: 600;"]}function re(n){return[n,`color: ${Ae(n)}; font-weight: 400;`]}function Ae(n){switch(n.toLocaleLowerCase().startsWith("prod")?"production":n){case"production":return"#ef4444";default:return"#3b82f6"}}function De(n){return[Ce(n),"color: #64748b; font-weight: 400;"]}function m(n){return[n,"color: #64748b; font-size: 11px;"]}function v(n){return[n,'background: #f8fafc; color: #1e293b; padding: 2px 8px; border: 1px solid #e2e8f0; border-radius: 6px; font-family: "SF Mono", "Monaco", monospace; font-size: 11px;']}function se(n){switch(n){case o.GRANTED:return["",""];case o.DENIED:return["DENIED","background: #ef4444; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;"];case o.PENDING:case o.DISMISSED:return["PENDING","background: #f59e0b; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;"];default:return["UNKNOWN","background: #6b7280; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;"]}}function O(n){try{let e=new URL(n);return{baseUrl:`${e.origin}${e.pathname}`,searchParams:Object.fromEntries(e.searchParams)}}catch{return null}}function oe(){return typeof window<"u"&&typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}var y=class{_config;constructor(e){this._config=e}_constructUrl(e){return`${this._config.baseUrl}${e}?apiKey=${encodeURIComponent(this._config.apiKey)}`}async send(e,t){return oe()?this._sendWithBeacon(e,t):this._sendWithFetch(e,t)}async _sendWithBeacon(e,t){let r=this._constructUrl(e),s=new Blob([JSON.stringify(t)],{type:"application/json"});try{if(!navigator.sendBeacon(r,s))return this._sendWithFetch(e,t)}catch{return this._sendWithFetch(e,t)}}async _sendWithFetch(e,t){let r=this._constructUrl(e),s=new AbortController,i=setTimeout(()=>s.abort(),this._config.requestTimeout);try{let c=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0,signal:s.signal});if(!c.ok)throw new Error(`HTTP ${c.status}: ${c.statusText}`)}finally{clearTimeout(i)}}};function a(n,e=()=>{}){return typeof window>"u"?e():n({window})}function M(n){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")try{return`${n}-${crypto.randomUUID()}`}catch{}return`${n}-${Math.random().toString(36).substring(2)}`}var b=class{_defaultTrackingConsent;_logger;_sessionData;_storage;_storageKey;constructor(e){this._storage=e.storage,this._storageKey=e.storageKey,this._logger=e.logger,this._defaultTrackingConsent=e.defaultTrackingConsent??o.PENDING,this._sessionData=this._createDefaultSessionData()}init(){let e=this._storage.getItem(this._storageKey);if(!e){this._sessionData=this._createDefaultSessionData(),this._persistToStorage();return}try{let t=JSON.parse(e);this._sessionData={visitorId:t.visitorId||this._generateVisitorId(),sessionId:t.sessionId||this._generateSessionId(),userId:t.userId||null,lastEventAt:t.lastEventAt||null,trackingConsent:Pe(t.trackingConsent)?t.trackingConsent:this._defaultTrackingConsent}}catch{this._logger.warnDev("Failed to parse storage data. Resetting session data."),this._sessionData=this._createDefaultSessionData()}this._persistToStorage()}getVisitorId(){return this._sessionData.visitorId}getSessionId(){return this._sessionData.sessionId}getUserId(){return this._sessionData.userId}getLastEventAt(){return this._sessionData.lastEventAt}getTrackingConsent(){return this._sessionData.trackingConsent}setUserId(e){this._sessionData.userId=e,this._persistToStorage()}setTrackingConsent(e){this._sessionData.trackingConsent=e,this._persistToStorage()}updateLastEventAt(e){this._sessionData.lastEventAt=e,this._persistToStorage()}renewSessionIfNeeded(){return this._shouldRenewSession()?(this._renewSession(),this._persistToStorage(),!0):!1}reset({resetVisitorId:e=!1,resetSessionId:t=!0,resetTrackingConsent:r=!1}={}){e&&(this._sessionData.visitorId=this._generateVisitorId()),t&&(this._sessionData.sessionId=this._generateSessionId()),r&&(this._sessionData.trackingConsent=this._defaultTrackingConsent),this._sessionData.userId=null,this._sessionData.lastEventAt=null,this._persistToStorage()}_createDefaultSessionData(){return{visitorId:this._generateVisitorId(),sessionId:this._generateSessionId(),userId:null,lastEventAt:null,trackingConsent:this._defaultTrackingConsent}}_generateSessionId(){return M(K)}_generateVisitorId(){return M(G)}_shouldRenewSession(){let{lastEventAt:e}=this._sessionData;if(!e)return!0;let t=new Date().getTime(),r=new Date(e).getTime();return t-r>Q}_renewSession(){this._sessionData.sessionId=this._generateSessionId(),this._sessionData.lastEventAt=null}_persistToStorage(){try{this._storage.setItem(this._storageKey,JSON.stringify(this._sessionData))}catch{this._logger.warnDev("Failed to persist session data to storage.")}}};function Pe(n){return typeof n=="string"&&Object.values(o).includes(n)}function q(n,e,t){for(let r of t){let s=e.getItem(r);s!==null&&(n.setItem(r,s),e.removeItem(r))}}var f=class{store={};getItem(e){return this.store[e]??null}setItem(e,t){this.store[e]=t}removeItem(e){delete this.store[e]}migrate(e,t){q(this,e,t)}},S=class{getItem(e){return a(({window:t})=>{let r=t.document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return r?decodeURIComponent(r[2]):null},()=>null)}setItem(e,t){a(({window:r})=>{r.document.cookie=`${e}=${encodeURIComponent(t)}; path=/;`})}removeItem(e){a(({window:t})=>{t.document.cookie=`${e}=; Max-Age=0; path=/;`})}migrate(e,t){q(this,e,t)}},p=class{constructor(e){this.storage=e}getItem(e){return a(({window:t})=>{try{return t[this.storage].getItem(e)}catch{return null}},()=>null)}setItem(e,t){a(({window:r})=>{try{r[this.storage].setItem(e,t)}catch{}})}removeItem(e){a(({window:t})=>{try{t[this.storage].removeItem(e)}catch{}})}migrate(e,t){q(this,e,t)}},B=class{localStore=new p("localStorage");cookieStore=new S;getItem(e){return this.localStore.getItem(e)??this.cookieStore.getItem(e)}setItem(e,t){this.localStore.setItem(e,t),this.cookieStore.setItem(e,t)}removeItem(e){this.localStore.removeItem(e),this.cookieStore.removeItem(e)}migrate(e,t){for(let r of t){let s=e.getItem(r);s!==null&&(this.localStore.setItem(r,s),this.cookieStore.setItem(r,s))}for(let r of t)e.removeItem(r)}};function E(n){return a(({window:e})=>{try{if(n==="cookie"){e.document.cookie=`${u}=1`;let t=e.document.cookie.indexOf(`${u}=`)!==-1;return e.document.cookie=`${u}=; Max-Age=0`,t}else return e[n].setItem(u,"1"),e[n].removeItem(u),!0}catch{return!1}},()=>!1)}function k(n,e){let{onFallback:t}=e;switch(n){case"localStorage":return E("localStorage")?new p("localStorage"):(t("localStorage not supported, falling back to localStorage+cookie."),k("localStorage+cookie",e));case"localStorage+cookie":{let r=E("localStorage"),s=E("cookie");return r&&s?new B:s?(t("localStorage+cookie not fully supported, falling back to cookie."),new S):r?(t("cookie not supported, falling back to localStorage."),new p("localStorage")):(t("Neither localStorage nor cookie supported, falling back to memory."),new f)}case"sessionStorage":return E("sessionStorage")?new p("sessionStorage"):(t("sessionStorage not supported, falling back to memory."),new f);case"cookie":return E("cookie")?new S:(t("cookie not supported, falling back to memory."),new f);case"memory":return new f;default:throw new Error(`Unknown storage type: "${n}". Valid types are: localStorage, sessionStorage, cookie, memory, localStorage+cookie.`)}}var xe=[...N,...V].map(n=>`- "${n}"`).join(`
3
- `),ae=`List of reserved identifiers:
4
- ${xe}`;function ce(n){if(!n||n.trim()==="")throw new Error("User ID cannot be empty or contain only whitespace.");if(N.some(r=>n.toLowerCase()===r.toLowerCase()))throw new Error(`User ID "${n}" is a reserved identifier and cannot be used.
1
+ /*! @altertable/altertable-js 1.0.1 | MIT License | Altertable | https://github.com/altertable-ai/altertable-js */
2
+ var Altertable=(()=>{var O=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var De=Object.prototype.hasOwnProperty;var Ae=(n,e)=>{for(var t in e)O(n,t,{get:e[t],enumerable:!0})},Re=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of we(e))!De.call(n,r)&&r!==t&&O(n,r,{get:()=>e[r],enumerable:!(s=Ce(e,r))||s.enumerable});return n};var xe=n=>Re(O({},"__esModule",{value:!0}),n);var Fe={};Ae(Fe,{TrackingConsent:()=>a,altertable:()=>X});function j(n,e){return(...t)=>[n,...t].join(e)}var Pe="atbl",B=j(Pe,"."),f=B("check"),H="session",J="visitor",Z="device",$e=1e3*60,ee=100,te=30*$e,ne=1e3,se=5e3,re="$pageview",ie="$lib",oe="$lib_version",ae="$referer",ce="$release",h="$url",le="$viewport",a={DENIED:"denied",DISMISSED:"dismissed",GRANTED:"granted",PENDING:"pending"},M=["anonymous_id","anonymous","distinct_id","distinctid","false","guest","id","not_authenticated","true","undefined","user_id","user","visitor_id","visitor"],q=new Set(["[object Object]","0","NaN","none","None","null"]);var w=class extends Error{constructor(e){super(e),this.name="AltertableError"}},m=class extends w{constructor(t,s,r,i,o){super(`HTTP ${t}: ${s}${r?` (${r})`:""}`);this.status=t;this.statusText=s;this.errorCode=r;this.details=i;this.requestContext=o;this.name="ApiError"}},D=class extends w{constructor(t,s){super(t);this.cause=s;this.name="NetworkError"}};function ge(n){return n instanceof w}function de(n){return n instanceof m}function ue(n){return n instanceof D}var x=class{_queue=[];_queueMaxSize;constructor(e){this._queueMaxSize=e}enqueue(e,t,s){this._queue.length>=this._queueMaxSize&&this._queue.shift(),this._queue.push({eventType:e,payload:t,context:s,sentAt:new Date})}flush(){let e=[...this._queue];return this._queue=[],e}clear(){this._queue=[]}getSize(){return this._queue.length}};function g(n,e){if(!n)throw new Error("Invariant failed")}function _e(n=""){return`https://altertable.ai/dashboard${n}`}function pe(n){return{log:(...e)=>{console.log(`[${n}]`,...e)},logHeader:()=>{let e="Altertable v1.0.1 %c\u2022 Debug mode enabled";P.current[e]||(P.current[e]=!0,console.log(e,"color: #64748b;"))},logEvent:(e,{trackingConsent:t})=>{let[s,r]=F(e.event==="$pageview"?"Page":"Track"),[i,o]=Ne(e.event==="$pageview"?String(e.properties[h]):e.event),[l,d]=z(e.environment),[u,E]=Oe(e.timestamp),[y,S]=K(t);console.groupCollapsed(`[${n}] %c${s}%c ${i} %c[${l}] %c${u} %c${y}`,r,o,d,E,S);let[T,b]=_("User ID"),[k,C]=p(e.distinct_id??"Not set"),[Ie,ve]=_("Visitor ID"),[Ee,ye]=p(e.anonymous_id??"Not set"),[Se,Te]=_("Session ID"),[be,ke]=p(e.session_id??"Not set");console.log(`%c${T} %c${k}`,b,C),console.log(`%c${Ie} %c${Ee}`,ve,ye),console.log(`%c${Se} %c${be}`,Te,ke),console.table(e.properties),console.groupEnd()},logIdentify:(e,{trackingConsent:t})=>{let[s,r]=F("Identify"),[i,o]=z(e.environment),[l,d]=K(t);console.groupCollapsed(`[${n}] %c${s}%c ${e.distinct_id} %c[${i}] %c${l}`,r,"font-weight: 600;",o,d);let[u,E]=_("Distinct ID"),[y,S]=p(e.distinct_id??"Not set"),[T,b]=_("Anonymous ID"),[k,C]=p(e.anonymous_id??"Not set");console.log(`%c${u} %c${y}`,E,S),console.log(`%c${T} %c${k}`,b,C),console.table(e.traits),console.groupEnd()},logAlias:(e,{trackingConsent:t})=>{let[s,r]=F("Alias"),[i,o]=z(e.environment),[l,d]=K(t);console.groupCollapsed(`[${n}] %c${s}%c ${e.distinct_id} %c[${i}] %c${l}`,r,"font-weight: 600;",o,d);let[u,E]=_("Distinct ID"),[y,S]=p(e.distinct_id??"Not set"),[T,b]=_("New User ID"),[k,C]=p(e.new_user_id??"Not set");console.log(`%c${u} %c${y}`,E,S),console.log(`%c${T} %c${k}`,b,C),console.groupEnd()},warn:(...e)=>{console.warn(`[${n}]`,...e)},warnDev:(e,...t)=>{return;if(!r){P.current[s]=!0;let i=`[${n}] ${s}`;console.warn(i,...t);try{throw new Error(i)}catch{}}},error:(...e)=>{console.error(`[${n}]`,...e)}}}var P={current:{}};function Ue(n){return new Date(n).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}function Le(n){switch(n){case"Page":return"#64748b";case"Identify":return"#a855f7";case"Track":return"#10b981";default:return"#1e293b"}}function F(n){return[n,`background: ${Le(n)}; color: #ffffff; padding: 2px 8px; border-radius: 6px; font-weight: 400;`]}function Ne(n){return[n==="$pageview"?"Page Viewed":n,"font-weight: 600;"]}function z(n){return[n,`color: ${Ve(n)}; font-weight: 400;`]}function Ve(n){switch(n.toLocaleLowerCase().startsWith("prod")?"production":n){case"production":return"#ef4444";default:return"#3b82f6"}}function Oe(n){return[Ue(n),"color: #64748b; font-weight: 400;"]}function _(n){return[n,"color: #64748b; font-size: 11px;"]}function p(n){return[n,'background: #f8fafc; color: #1e293b; padding: 2px 8px; border: 1px solid #e2e8f0; border-radius: 6px; font-family: "SF Mono", "Monaco", monospace; font-size: 11px;']}function K(n){switch(n){case a.GRANTED:return["",""];case a.DENIED:return["DENIED","background: #ef4444; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;"];case a.PENDING:case a.DISMISSED:return["PENDING","background: #f59e0b; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;"];default:return["UNKNOWN","background: #6b7280; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;"]}}function G(n){try{let e=new URL(n);return{baseUrl:`${e.origin}${e.pathname}`,searchParams:Object.fromEntries(e.searchParams)}}catch{return null}}function fe(){return typeof window<"u"&&typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}var $=class{_config;constructor(e){this._config=e}_constructUrl(e){return`${this._config.baseUrl}${e}?apiKey=${encodeURIComponent(this._config.apiKey)}`}async send(e,t){return fe()?this._sendWithBeacon(e,t):this._sendWithFetch(e,t)}async _sendWithBeacon(e,t){let s=this._constructUrl(e),r=new Blob([JSON.stringify(t)],{type:"application/json"});try{if(!navigator.sendBeacon(s,r))return this._sendWithFetch(e,t)}catch{return this._sendWithFetch(e,t)}}async _sendWithFetch(e,t){let s=this._constructUrl(e),r=new AbortController,i=setTimeout(()=>r.abort(),this._config.requestTimeout);try{let o=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),keepalive:!0,signal:r.signal});if(!o.ok){let l;try{l=await o.json()}catch{}throw new m(o.status,o.statusText,l?.error_code,l,{url:s,method:"POST",payload:t})}}catch(o){throw o instanceof m?o:new D(o instanceof Error?o.message:"Network request failed",o)}finally{clearTimeout(i)}}};function c(n,e=()=>{}){return typeof window>"u"?e():n({window})}function U(n){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")try{return`${n}-${crypto.randomUUID()}`}catch{}return`${n}-${Math.random().toString(36).substring(2)}`}var L=class{_defaultTrackingConsent;_logger;_sessionData;_storage;_storageKey;constructor(e){this._storage=e.storage,this._storageKey=e.storageKey,this._logger=e.logger,this._defaultTrackingConsent=e.defaultTrackingConsent??a.PENDING,this._sessionData=this._createDefaultSessionData()}init(){let e=this._storage.getItem(this._storageKey);if(!e){this._sessionData=this._createDefaultSessionData(),this._persistToStorage();return}try{let t=JSON.parse(e);this._sessionData={deviceId:t.deviceId||this._generateDeviceId(),distinctId:t.distinctId||this._generateVisitorId(),sessionId:t.sessionId||this._generateSessionId(),anonymousId:t.anonymousId||null,lastEventAt:t.lastEventAt||null,trackingConsent:Be(t.trackingConsent)?t.trackingConsent:this._defaultTrackingConsent}}catch{this._logger.warnDev("Failed to parse storage data. Resetting session data."),this._sessionData=this._createDefaultSessionData()}this._persistToStorage()}getSessionId(){return this._sessionData.sessionId}getDeviceId(){return this._sessionData.deviceId}getDistinctId(){return this._sessionData.distinctId}getAnonymousId(){return this._sessionData.anonymousId}isIdentified(){return!!this._sessionData.anonymousId}getLastEventAt(){return this._sessionData.lastEventAt}getTrackingConsent(){return this._sessionData.trackingConsent}identify(e){this._sessionData.anonymousId=this._sessionData.distinctId,this._sessionData.distinctId=e,this._persistToStorage()}setTrackingConsent(e){this._sessionData.trackingConsent=e,this._persistToStorage()}updateLastEventAt(e){this._sessionData.lastEventAt=e,this._persistToStorage()}renewSessionIfNeeded(){return this._shouldRenewSession()?(this._renewSession(),this._persistToStorage(),!0):!1}reset({resetDeviceId:e=!1,resetTrackingConsent:t=!1}={}){e&&(this._sessionData.deviceId=this._generateDeviceId()),t&&(this._sessionData.trackingConsent=this._defaultTrackingConsent),this._sessionData.sessionId=this._generateSessionId(),this._sessionData.anonymousId=null,this._sessionData.distinctId=this._generateVisitorId(),this._sessionData.lastEventAt=null,this._persistToStorage()}_createDefaultSessionData(){return{anonymousId:null,deviceId:this._generateDeviceId(),distinctId:this._generateVisitorId(),lastEventAt:null,sessionId:this._generateSessionId(),trackingConsent:this._defaultTrackingConsent}}_generateSessionId(){return U(H)}_generateDeviceId(){return U(Z)}_generateVisitorId(){return U(J)}_shouldRenewSession(){let{lastEventAt:e}=this._sessionData;if(!e)return!0;let t=new Date().getTime(),s=new Date(e).getTime();return t-s>te}_renewSession(){this._sessionData.sessionId=this._generateSessionId(),this._sessionData.lastEventAt=null}_persistToStorage(){try{this._storage.setItem(this._storageKey,JSON.stringify(this._sessionData))}catch{this._logger.warnDev("Failed to persist session data to storage.")}}};function Be(n){return typeof n=="string"&&Object.values(a).includes(n)}function W(n,e,t){for(let s of t){let r=e.getItem(s);r!==null&&(n.setItem(s,r),e.removeItem(s))}}var I=class{store={};getItem(e){return this.store[e]??null}setItem(e,t){this.store[e]=t}removeItem(e){delete this.store[e]}migrate(e,t){W(this,e,t)}},R=class{getItem(e){return c(({window:t})=>{let s=t.document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return s?decodeURIComponent(s[2]):null},()=>null)}setItem(e,t){c(({window:s})=>{s.document.cookie=`${e}=${encodeURIComponent(t)}; path=/;`})}removeItem(e){c(({window:t})=>{t.document.cookie=`${e}=; Max-Age=0; path=/;`})}migrate(e,t){W(this,e,t)}},v=class{constructor(e){this.storage=e}getItem(e){return c(({window:t})=>{try{return t[this.storage].getItem(e)}catch{return null}},()=>null)}setItem(e,t){c(({window:s})=>{try{s[this.storage].setItem(e,t)}catch{}})}removeItem(e){c(({window:t})=>{try{t[this.storage].removeItem(e)}catch{}})}migrate(e,t){W(this,e,t)}},Y=class{localStore=new v("localStorage");cookieStore=new R;getItem(e){return this.localStore.getItem(e)??this.cookieStore.getItem(e)}setItem(e,t){this.localStore.setItem(e,t),this.cookieStore.setItem(e,t)}removeItem(e){this.localStore.removeItem(e),this.cookieStore.removeItem(e)}migrate(e,t){for(let s of t){let r=e.getItem(s);r!==null&&(this.localStore.setItem(s,r),this.cookieStore.setItem(s,r))}for(let s of t)e.removeItem(s)}};function A(n){return c(({window:e})=>{try{if(n==="cookie"){e.document.cookie=`${f}=1`;let t=e.document.cookie.indexOf(`${f}=`)!==-1;return e.document.cookie=`${f}=; Max-Age=0`,t}else return e[n].setItem(f,"1"),e[n].removeItem(f),!0}catch{return!1}},()=>!1)}function N(n,e){let{onFallback:t}=e;switch(n){case"localStorage":return A("localStorage")?new v("localStorage"):(t("localStorage not supported, falling back to localStorage+cookie."),N("localStorage+cookie",e));case"localStorage+cookie":{let s=A("localStorage"),r=A("cookie");return s&&r?new Y:r?(t("localStorage+cookie not fully supported, falling back to cookie."),new R):s?(t("cookie not supported, falling back to localStorage."),new v("localStorage")):(t("Neither localStorage nor cookie supported, falling back to memory."),new I)}case"sessionStorage":return A("sessionStorage")?new v("sessionStorage"):(t("sessionStorage not supported, falling back to memory."),new I);case"cookie":return A("cookie")?new R:(t("cookie not supported, falling back to memory."),new I);case"memory":return new I;default:throw new Error(`Unknown storage type: "${n}". Valid types are: localStorage, sessionStorage, cookie, memory, localStorage+cookie.`)}}var Me=[...M,...q].map(n=>`- "${n}"`).join(`
3
+ `),he=`List of reserved identifiers:
4
+ ${Me}`;function Q(n){if(!n||n.trim()==="")throw new Error("User ID cannot be empty or contain only whitespace.");if(M.some(s=>n.toLowerCase()===s.toLowerCase()))throw new Error(`User ID "${n}" is a reserved identifier and cannot be used.
5
5
 
6
- `+ae);if(V.has(n))throw new Error(`User ID "${n}" is a reserved identifier and cannot be used.
6
+ `+he);if(q.has(n))throw new Error(`User ID "${n}" is a reserved identifier and cannot be used.
7
7
 
8
- `+ae)}function le(){return a(({window:n})=>`${n.innerWidth}x${n.innerHeight}`,()=>null)}var Ue={autoCapture:!0,baseUrl:"https://api.altertable.ai",debug:!1,environment:"production",persistence:"localStorage+cookie",release:void 0,trackingConsent:o.PENDING},C=class{_cleanupAutoCapture;_config;_eventQueue;_isInitialized=!1;_lastUrl;_logger=ie("Altertable");_referrer;_requester;_sessionManager;_storage;_storageKey;constructor(){this._lastUrl=null,this._referrer=null,this._eventQueue=new I(W)}init(e,t={}){return l(e,"Missing API key"),this._config={...Ue,...t},this._storageKey=L(e,this._config.environment),this._referrer=a(({window:r})=>r.document.referrer||null,()=>null),this._lastUrl=a(({window:r})=>r.location.href||null,()=>null),this._storage=k(this._config.persistence,{onFallback:r=>this._logger.warn(r)}),this._requester=new y({baseUrl:this._config.baseUrl,apiKey:e,requestTimeout:X}),this._sessionManager=new b({storage:this._storage,storageKey:this._storageKey,logger:this._logger,defaultTrackingConsent:this._config.trackingConsent}),this._sessionManager.init(),this._isInitialized=!0,this._config.debug&&this._logger.logHeader(),this._handleAutoCaptureChange(this._config.autoCapture),()=>{this._cleanupAutoCapture?.()}}configure(e){if(l(this._isInitialized,"The client must be initialized with init() before configuring."),e.autoCapture!==void 0&&e.autoCapture!==this._config.autoCapture&&this._handleAutoCaptureChange(e.autoCapture),e.persistence!==void 0&&e.persistence!==this._config.persistence){let r=this._storage;this._storage=k(e.persistence,{onFallback:s=>this._logger.warn(s)}),this._storage.migrate(r,[this._storageKey])}let t=this._sessionManager.getTrackingConsent();if(e.trackingConsent!==void 0&&e.trackingConsent!==t)if(this._sessionManager.setTrackingConsent(e.trackingConsent),t!==o.GRANTED&&e.trackingConsent===o.GRANTED){let r=this._eventQueue.flush();r.length>0&&r.forEach(s=>{this._processEvent(s.eventType,s.payload,s.context)})}else e.trackingConsent===o.DENIED&&this._eventQueue.clear();this._config={...this._config,...e}}_handleAutoCaptureChange(e){if(this._cleanupAutoCapture?.(),e){this._lastUrl&&this.page(this._lastUrl);let t=this._checkForChanges.bind(this),r=setInterval(t,Y);a(({window:s})=>{s.addEventListener("popstate",t),s.addEventListener("hashchange",t)}),this._cleanupAutoCapture=()=>{clearInterval(r),a(({window:s})=>{s.removeEventListener("popstate",t),s.removeEventListener("hashchange",t)})}}else this._cleanupAutoCapture=void 0}identify(e,t={}){l(this._isInitialized,"The client must be initialized with init() before identifying users.");try{ce(e)}catch(i){throw new Error(`[Altertable] ${i.message}`)}this._sessionManager.setUserId(e);let r=this._getContext(),s={environment:r.environment,traits:t,user_id:e,visitor_id:r.visitor_id};if(this._processEvent("identify",s,r),this._config.debug){let i=this._sessionManager.getTrackingConsent();this._logger.logIdentify(s,{trackingConsent:i})}}updateTraits(e){let t=this._sessionManager.getUserId();l(t,"User must be identified with identify() before updating traits.");let r=this._getContext(),s={environment:r.environment,traits:e,user_id:t,visitor_id:r.visitor_id};if(this._processEvent("identify",s,r),this._config.debug){let i=this._sessionManager.getTrackingConsent();this._logger.logIdentify(s,{trackingConsent:i})}}reset({resetVisitorId:e=!1,resetSessionId:t=!0}={}){l(this._isInitialized,"The client must be initialized with init() before resetting."),this._sessionManager.reset({resetVisitorId:e,resetSessionId:t})}page(e){l(this._isInitialized,"The client must be initialized with init() before tracking page views.");let t=O(e),r=t?t.baseUrl:e;this.track(j,{[d]:r,[te]:le(),[Z]:this._referrer,...t?.searchParams})}track(e,t={}){l(this._isInitialized,"The client must be initialized with init() before tracking events."),this._sessionManager.renewSessionIfNeeded();let r=new Date().toISOString();this._sessionManager.updateLastEventAt(r);let s=this._getContext(),i={timestamp:r,event:e,environment:s.environment,user_id:s.user_id,session_id:s.session_id,visitor_id:s.visitor_id,properties:{[H]:"@altertable/altertable-js",[J]:"0.5.7",[ee]:this._config.release,...t[d]===void 0&&(()=>{let c=a(({window:h})=>h.location.href||null,()=>null),g=O(c),_=g?g.baseUrl:c;return{[d]:_}})(),...t}};if(this._processEvent("track",i,s),this._config.debug){let c=this._sessionManager.getTrackingConsent();this._logger.logEvent(i,{trackingConsent:c})}}getTrackingConsent(){return this._sessionManager.getTrackingConsent()}_checkForChanges(){a(({window:e})=>{let t=e.location.href;t!==this._lastUrl&&(this.page(t),this._referrer=this._lastUrl,this._lastUrl=t)})}_getContext(){return{environment:this._config.environment,user_id:this._sessionManager.getUserId(),visitor_id:this._sessionManager.getVisitorId(),session_id:this._sessionManager.getSessionId()}}async _processEvent(e,t,r){switch(this._sessionManager.getTrackingConsent()){case o.GRANTED:try{await this._requester.send(`/${e}`,t)}catch(i){this._logger.error("Failed to send event",{error:i,eventType:e,payload:t})}break;case o.PENDING:case o.DISMISSED:this._eventQueue.enqueue(e,t,r);break;case o.DENIED:break}}};var F=new C;a(({window:n})=>{let e=n.Altertable;if(e&&Array.isArray(e))for(let t of e){let r=t[0],s=t.slice(1);F[r](...s)}n.Altertable=F});return ye($e);})();
8
+ `+he)}function me(){return c(({window:n})=>`${n.innerWidth}x${n.innerHeight}`,()=>null)}var qe={autoCapture:!0,baseUrl:"https://api.altertable.ai",debug:!1,environment:"production",persistence:"localStorage+cookie",release:void 0,trackingConsent:a.GRANTED},V=class{_cleanupAutoCapture;_config;_eventQueue;_isInitialized=!1;_lastUrl;_logger=pe("Altertable");_referrer;_requester;_sessionManager;_storage;_storageKey;constructor(){this._lastUrl=null,this._referrer=null,this._eventQueue=new x(ne)}init(e,t={}){return g(e,"Missing API key"),this._config={...qe,...t},this._storageKey=B(e,this._config.environment),this._referrer=c(({window:s})=>s.document.referrer||null,()=>null),this._lastUrl=c(({window:s})=>s.location.href||null,()=>null),this._storage=N(this._config.persistence,{onFallback:s=>this._logger.warn(s)}),this._requester=new $({baseUrl:this._config.baseUrl,apiKey:e,requestTimeout:se}),this._sessionManager=new L({storage:this._storage,storageKey:this._storageKey,logger:this._logger,defaultTrackingConsent:this._config.trackingConsent}),this._sessionManager.init(),this._isInitialized=!0,this._config.debug&&this._logger.logHeader(),this._handleAutoCaptureChange(this._config.autoCapture),()=>{this._cleanupAutoCapture?.()}}configure(e){if(g(this._isInitialized,"The client must be initialized with init() before configuring."),e.autoCapture!==void 0&&e.autoCapture!==this._config.autoCapture&&this._handleAutoCaptureChange(e.autoCapture),e.persistence!==void 0&&e.persistence!==this._config.persistence){let s=this._storage;this._storage=N(e.persistence,{onFallback:r=>this._logger.warn(r)}),this._storage.migrate(s,[this._storageKey])}let t=this._sessionManager.getTrackingConsent();if(e.trackingConsent!==void 0&&e.trackingConsent!==t)if(this._sessionManager.setTrackingConsent(e.trackingConsent),t!==a.GRANTED&&e.trackingConsent===a.GRANTED){let s=this._eventQueue.flush();s.length>0&&s.forEach(r=>{this._processEvent(r.eventType,r.payload,r.context)})}else e.trackingConsent===a.DENIED&&this._eventQueue.clear();this._config={...this._config,...e}}_handleAutoCaptureChange(e){if(this._cleanupAutoCapture?.(),e){this._lastUrl&&this.page(this._lastUrl);let t=this._checkForChanges.bind(this),s=setInterval(t,ee);c(({window:r})=>{r.addEventListener("popstate",t),r.addEventListener("hashchange",t)}),this._cleanupAutoCapture=()=>{clearInterval(s),c(({window:r})=>{r.removeEventListener("popstate",t),r.removeEventListener("hashchange",t)})}}else this._cleanupAutoCapture=void 0}identify(e,t={}){g(this._isInitialized,"The client must be initialized with init() before identifying users.");let s=this._getContext();g(!this._sessionManager.isIdentified()||e===this._sessionManager.getDistinctId(),`User (${e}) is already identified as a different user (${this._sessionManager.getDistinctId()}). This usually indicates a development issue, as it would merge two separate identities. Call reset() before identifying a new user, or use alias() to link the new ID to the existing one.`);try{Q(e)}catch(i){throw new Error(`[Altertable] ${i.message}`)}this._sessionManager.identify(e);let r={environment:s.environment,device_id:s.device_id,distinct_id:e,traits:t,anonymous_id:s.distinct_id};if(this._processEvent("identify",r,s),this._config.debug){let i=this._sessionManager.getTrackingConsent();this._logger.logIdentify(r,{trackingConsent:i})}}alias(e){g(this._isInitialized,"The client must be initialized with init() before aliasing users.");try{Q(e)}catch(r){throw new Error(`[Altertable] ${r.message}`)}let t=this._getContext(),s={environment:t.environment,device_id:t.device_id,anonymous_id:t.anonymous_id,distinct_id:t.distinct_id,new_user_id:e};if(this._processEvent("alias",s,t),this._config.debug){let r=this._sessionManager.getTrackingConsent();this._logger.logAlias(s,{trackingConsent:r})}}updateTraits(e){let t=this._getContext();g(t.anonymous_id!==null,"User must be identified with identify() before updating traits.");let s={environment:t.environment,device_id:t.device_id,distinct_id:t.distinct_id,traits:e,anonymous_id:t.anonymous_id,session_id:t.session_id};if(this._processEvent("identify",s,t),this._config.debug){let r=this._sessionManager.getTrackingConsent();this._logger.logIdentify(s,{trackingConsent:r})}}reset({resetDeviceId:e=!1}={}){g(this._isInitialized,"The client must be initialized with init() before resetting."),this._sessionManager.reset({resetDeviceId:e})}page(e){g(this._isInitialized,"The client must be initialized with init() before tracking page views.");let t=G(e),s=t?t.baseUrl:e;this.track(re,{[h]:s,[le]:me(),[ae]:this._referrer,...t?.searchParams})}track(e,t={}){g(this._isInitialized,"The client must be initialized with init() before tracking events."),this._sessionManager.renewSessionIfNeeded();let s=new Date().toISOString();this._sessionManager.updateLastEventAt(s);let r=this._getContext(),i={timestamp:s,event:e,environment:r.environment,device_id:r.device_id,distinct_id:r.distinct_id,anonymous_id:r.anonymous_id,session_id:r.session_id,properties:{[ie]:"@altertable/altertable-js",[oe]:"1.0.1",[ce]:this._config.release,...t[h]===void 0&&(()=>{let o=c(({window:u})=>u.location.href||null,()=>null),l=G(o),d=l?l.baseUrl:o;return{[h]:d}})(),...t}};if(this._processEvent("track",i,r),this._config.debug){let o=this._sessionManager.getTrackingConsent();this._logger.logEvent(i,{trackingConsent:o})}}getTrackingConsent(){return this._sessionManager.getTrackingConsent()}_checkForChanges(){c(({window:e})=>{let t=e.location.href;t!==this._lastUrl&&(this.page(t),this._referrer=this._lastUrl,this._lastUrl=t)})}_getContext(){return{environment:this._config.environment,device_id:this._sessionManager.getDeviceId(),distinct_id:this._sessionManager.getDistinctId(),anonymous_id:this._sessionManager.getAnonymousId(),session_id:this._sessionManager.getSessionId()}}async _processEvent(e,t,s){switch(this._sessionManager.getTrackingConsent()){case a.GRANTED:try{await this._requester.send(`/${e}`,t)}catch(i){ge(i)&&this._config.onError?.(i),de(i)&&i.errorCode==="environment-not-found"?this._logger.warnDev(`Environment "${this._config.environment}" not found. Please create this environment in your Altertable dashboard at ${_e(`/environments/new?name=${this._config.environment}`)} before tracking events.`):ue(i)?this._logger.error("Network error while sending event",{error:i.message,cause:i.cause,eventType:e}):this._logger.error("Failed to send event",{error:i,eventType:e,payload:t})}break;case a.PENDING:case a.DISMISSED:this._eventQueue.enqueue(e,t,s);break;case a.DENIED:break}}};var X=new V;c(({window:n})=>{let e=n.Altertable;if(e&&Array.isArray(e))for(let t of e){let s=t[0],r=t.slice(1);X[s](...r)}n.Altertable=X});return xe(Fe);})();
9
9
  //# sourceMappingURL=index.global.js.map