@analyticscli/sdk 0.1.0-preview.4 → 0.1.0-preview.5

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/dist/index.d.cts CHANGED
@@ -34,30 +34,24 @@ declare const PURCHASE_SUCCESS_EVENT_CANDIDATES: readonly ["purchase:success"];
34
34
  * Arbitrary key/value payload sent with an event.
35
35
  */
36
36
  type EventProperties = Record<string, unknown>;
37
+ type StorageGetItemCallback = (error?: Error | null, value?: string | null) => void;
38
+ type StorageMutationCallback = (error?: Error | null) => void;
37
39
  type AnalyticsStorageAdapter = {
38
40
  /**
39
41
  * Storage APIs can be sync or async.
40
- * This allows plugging in AsyncStorage (React Native), MMKV wrappers, or custom secure stores.
42
+ * This allows passing AsyncStorage/localStorage directly, or custom adapters.
41
43
  */
42
- getItem: (key: string) => string | null | Promise<string | null>;
43
- setItem: (key: string, value: string) => void | Promise<void>;
44
- removeItem?: (key: string) => void | Promise<void>;
44
+ getItem: (key: string, callback?: StorageGetItemCallback) => string | null | Promise<string | null>;
45
+ setItem: (key: string, value: string, callback?: StorageMutationCallback) => void | Promise<void>;
46
+ removeItem?: (key: string, callback?: StorageMutationCallback) => void | Promise<void>;
45
47
  };
46
48
  type EventContext = {
47
49
  appBuild?: string;
48
50
  osName?: string;
49
51
  osVersion?: string;
50
- deviceModel?: string;
51
- deviceManufacturer?: string;
52
- deviceType?: string;
53
- locale?: string;
54
52
  country?: string;
55
53
  region?: string;
56
54
  city?: string;
57
- timezone?: string;
58
- networkType?: string;
59
- carrier?: string;
60
- installSource?: string;
61
55
  };
62
56
  type OnboardingEventProperties = EventProperties & {
63
57
  isNewUser?: boolean;
@@ -134,55 +128,112 @@ type PaywallTracker = {
134
128
  purchaseFailed: (properties?: PaywallTrackerProperties) => void;
135
129
  purchaseCancel: (properties?: PaywallTrackerProperties) => void;
136
130
  };
131
+ type AnalyticsConsentState = 'granted' | 'denied' | 'unknown';
132
+ type IdentityTrackingMode = 'strict' | 'consent_gated' | 'always_on';
133
+ type SetConsentOptions = {
134
+ /**
135
+ * Whether consent state should be persisted to storage when enabled.
136
+ */
137
+ persist?: boolean;
138
+ };
137
139
  type AnalyticsClientOptions = {
138
140
  /**
139
- * Write key (long API key).
141
+ * Publishable ingest API key.
140
142
  * If omitted, the client becomes a safe no-op until a valid key is provided.
141
143
  */
142
- apiKey?: string;
144
+ apiKey?: string | null;
143
145
  /**
144
146
  * Optional collector override reserved for SDK/internal testing.
145
147
  * Host app integrations should not set this option.
146
148
  */
147
- endpoint?: string;
148
- batchSize?: number;
149
- flushIntervalMs?: number;
150
- maxRetries?: number;
149
+ endpoint?: string | null;
150
+ batchSize?: number | null;
151
+ flushIntervalMs?: number | null;
152
+ maxRetries?: number | null;
151
153
  /**
152
154
  * Enables SDK debug logs (`console.debug`).
153
155
  * Defaults to `false`.
154
156
  *
155
157
  * React Native/Expo recommendation:
156
- * `debug: typeof __DEV__ === 'boolean' ? __DEV__ : false`
158
+ * `debug: __DEV__`
157
159
  */
158
- debug?: boolean;
159
- platform?: string;
160
- appVersion?: string;
161
- context?: EventContext;
160
+ debug?: boolean | null;
161
+ /**
162
+ * Optional platform hint.
163
+ * React Native/Expo: passing `Platform.OS` directly is supported.
164
+ */
165
+ platform?: string | null;
166
+ /**
167
+ * Optional app version hint.
168
+ * Accepts nullable runtime values (for example Expo's `nativeApplicationVersion`).
169
+ */
170
+ appVersion?: string | null;
162
171
  /**
163
- * Optional custom persistence adapter.
164
- * If omitted, browser storage/cookies are used when available; otherwise in-memory IDs are used.
172
+ * Optional project surface hint to separate product surfaces/channels
173
+ * (for example `landing`, `dashboard`, `app`) from runtime `platform`.
165
174
  */
166
- storage?: AnalyticsStorageAdapter;
167
- anonId?: string;
168
- sessionId?: string;
169
- sessionTimeoutMs?: number;
175
+ projectSurface?: string | null;
176
+ /**
177
+ * Initial event-collection consent state.
178
+ * Defaults to `true` when `apiKey` is present.
179
+ * Set to `false` to enforce explicit `optIn()` / `setConsent(true)` before event collection.
180
+ */
181
+ initialConsentGranted?: boolean | null;
182
+ /**
183
+ * Controls identity persistence behavior.
184
+ * - `consent_gated` (default): starts in strict mode and enables persistence only after consent
185
+ * - `always_on`: enables persistence immediately
186
+ * - `strict`: disables persistence and identity linkage
187
+ */
188
+ identityTrackingMode?: IdentityTrackingMode | null;
189
+ /**
190
+ * Boolean shortcut for `identityTrackingMode: 'always_on'`.
191
+ * Kept for host-app ergonomics.
192
+ */
193
+ enableFullTrackingWithoutConsent?: boolean | null;
194
+ /**
195
+ * Initial consent state for identity persistence when `identityTrackingMode='consent_gated'`.
196
+ * Defaults to `false`.
197
+ */
198
+ initialFullTrackingConsentGranted?: boolean | null;
199
+ /**
200
+ * Persist full-tracking consent in configured storage.
201
+ */
202
+ persistConsentState?: boolean | null;
203
+ /**
204
+ * Storage key for persisted full-tracking consent state.
205
+ * Defaults to `analyticscli:consent:v1`.
206
+ */
207
+ consentStorageKey?: string | null;
208
+ context?: EventContext | null;
209
+ /**
210
+ * Optional custom persistence adapter used when identity persistence is active.
211
+ */
212
+ storage?: AnalyticsStorageAdapter | null;
213
+ /**
214
+ * Optional explicit anonymous device id when identity persistence is active.
215
+ */
216
+ anonId?: string | null;
217
+ /**
218
+ * Optional explicit session id when identity persistence is active.
219
+ */
220
+ sessionId?: string | null;
221
+ sessionTimeoutMs?: number | null;
170
222
  /**
171
223
  * Drops duplicate `onboarding:step_view` events for the same step within one session.
172
224
  * This only affects the dedicated onboarding step-view event, not `screen(...)` or paywall events.
225
+ * Defaults to `true`. Set to `false` to disable this behavior.
173
226
  */
174
- dedupeOnboardingStepViewsPerSession?: boolean;
227
+ dedupeOnboardingStepViewsPerSession?: boolean | null;
175
228
  /**
176
- * Optional cookie domain to persist device/session ids across subdomains.
177
- * Example: `.analyticscli.com`
229
+ * Cookie domain for optional cookie-backed persistence.
178
230
  */
179
- cookieDomain?: string;
180
- cookieMaxAgeSeconds?: number;
231
+ cookieDomain?: string | null;
232
+ cookieMaxAgeSeconds?: number | null;
181
233
  /**
182
- * Enables cookie-backed id/session persistence.
183
- * Defaults to true when `cookieDomain` is provided, otherwise false.
234
+ * Enables cookie-backed persistence in browsers.
184
235
  */
185
- useCookieStorage?: boolean;
236
+ useCookieStorage?: boolean | null;
186
237
  };
187
238
  type InitOptions = AnalyticsClientOptions;
188
239
  type InitFromEnvMissingConfigMode = 'noop' | 'throw';
@@ -195,27 +246,27 @@ type InitFromEnvOptions = Omit<AnalyticsClientOptions, 'apiKey'> & {
195
246
  * Optional environment-like object.
196
247
  * Defaults to `globalThis.process?.env` when available.
197
248
  */
198
- env?: Record<string, unknown>;
249
+ env?: Record<string, unknown> | null;
199
250
  /**
200
251
  * Explicit api key override.
201
252
  */
202
- apiKey?: string;
253
+ apiKey?: string | null;
203
254
  /**
204
255
  * Candidate env keys resolved in order.
205
256
  */
206
- apiKeyEnvKeys?: string[];
257
+ apiKeyEnvKeys?: string[] | null;
207
258
  /**
208
259
  * How missing config is handled.
209
260
  * - `noop` (default): returns a safe no-op client
210
261
  * - `throw`: throws when required config is missing
211
262
  */
212
- missingConfigMode?: InitFromEnvMissingConfigMode;
263
+ missingConfigMode?: InitFromEnvMissingConfigMode | null;
213
264
  /**
214
265
  * Optional callback for custom logging when config is missing.
215
266
  */
216
- onMissingConfig?: (details: InitFromEnvMissingConfig) => void;
267
+ onMissingConfig?: ((details: InitFromEnvMissingConfig) => void) | null;
217
268
  };
218
- type InitInput = InitOptions | string;
269
+ type InitInput = InitOptions | string | null | undefined;
219
270
 
220
271
  declare class AnalyticsClient {
221
272
  private readonly apiKey;
@@ -226,10 +277,17 @@ declare class AnalyticsClient {
226
277
  private readonly maxRetries;
227
278
  private readonly debug;
228
279
  private readonly platform;
280
+ private readonly projectSurface;
229
281
  private readonly appVersion;
282
+ private readonly identityTrackingMode;
230
283
  private context;
231
- private readonly storage;
232
- private readonly storageReadsAreAsync;
284
+ private readonly configuredStorage;
285
+ private storage;
286
+ private storageReadsAreAsync;
287
+ private readonly persistConsentState;
288
+ private readonly consentStorageKey;
289
+ private readonly hasExplicitInitialConsent;
290
+ private readonly hasExplicitInitialFullTrackingConsent;
233
291
  private readonly sessionTimeoutMs;
234
292
  private readonly dedupeOnboardingStepViewsPerSession;
235
293
  private readonly runtimeEnv;
@@ -240,6 +298,7 @@ declare class AnalyticsClient {
240
298
  private flushTimer;
241
299
  private isFlushing;
242
300
  private consentGranted;
301
+ private fullTrackingConsentGranted;
243
302
  private userId;
244
303
  private anonId;
245
304
  private sessionId;
@@ -251,17 +310,18 @@ declare class AnalyticsClient {
251
310
  private onboardingStepViewsSeen;
252
311
  constructor(options: AnalyticsClientOptions);
253
312
  /**
254
- * Resolves once any async storage adapter hydration completes.
255
- * Useful in React Native when using async persistence (for example AsyncStorage).
313
+ * Resolves once client initialization work completes.
256
314
  */
257
315
  ready(): Promise<void>;
258
316
  /**
259
317
  * Enables or disables event collection.
260
318
  * When disabled, queued events are dropped immediately.
261
319
  */
262
- setConsent(granted: boolean): void;
263
- optIn(): void;
264
- optOut(): void;
320
+ setConsent(granted: boolean, options?: SetConsentOptions): void;
321
+ optIn(options?: SetConsentOptions): void;
322
+ optOut(options?: SetConsentOptions): void;
323
+ getConsent(): boolean;
324
+ getConsentState(): AnalyticsConsentState;
265
325
  /**
266
326
  * Sets or updates shared event context fields (useful for mobile device/app metadata).
267
327
  */
@@ -277,6 +337,14 @@ declare class AnalyticsClient {
277
337
  * - pass null/undefined/empty string to clear user linkage
278
338
  */
279
339
  setUser(userId: string | null | undefined, traits?: EventProperties): void;
340
+ /**
341
+ * Sets consent specifically for persistent identity tracking.
342
+ * In `consent_gated` mode this toggles strict-vs-full identity behavior while generic event tracking can stay enabled.
343
+ */
344
+ setFullTrackingConsent(granted: boolean, options?: SetConsentOptions): void;
345
+ optInFullTracking(options?: SetConsentOptions): void;
346
+ optOutFullTracking(options?: SetConsentOptions): void;
347
+ isFullTrackingEnabled(): boolean;
280
348
  /**
281
349
  * Clears the current identified user from in-memory SDK state.
282
350
  */
@@ -297,6 +365,8 @@ declare class AnalyticsClient {
297
365
  /**
298
366
  * Creates a scoped paywall tracker that applies shared paywall defaults to every journey event.
299
367
  * Useful when a flow has a stable `source`, `paywallId`, `offering`, or experiment metadata.
368
+ * Reuse the returned tracker for that flow context; creating a new tracker per event resets
369
+ * paywall entry correlation.
300
370
  */
301
371
  createPaywallTracker(defaults: PaywallTrackerDefaults): PaywallTracker;
302
372
  /**
@@ -333,6 +403,10 @@ declare class AnalyticsClient {
333
403
  private enqueue;
334
404
  private scheduleFlush;
335
405
  private sendWithRetry;
406
+ private parsePersistedConsent;
407
+ private readPersistedConsentSync;
408
+ private readPersistedConsentAsync;
409
+ private writePersistedConsent;
336
410
  private startAutoFlush;
337
411
  private ensureDeviceId;
338
412
  private ensureSessionId;
@@ -356,15 +430,22 @@ declare class AnalyticsClient {
356
430
  private hydrateOnboardingStepViewState;
357
431
  private persistOnboardingStepViewState;
358
432
  private parseOnboardingStepViewState;
433
+ private resolveIdentityTrackingModeOption;
434
+ private resolveConfiguredStorage;
435
+ private normalizeCookieMaxAgeSeconds;
436
+ private isFullTrackingActive;
437
+ private applyIdentityTrackingState;
438
+ private getEventUserId;
359
439
  private withEventContext;
360
440
  private normalizeOptions;
361
441
  private readRequiredStringOption;
362
442
  private normalizePlatformOption;
443
+ private normalizeProjectSurfaceOption;
363
444
  private log;
364
445
  private reportMissingApiKey;
365
446
  }
366
447
 
367
- declare const DEFAULT_API_KEY_ENV_KEYS: readonly ["ANALYTICSCLI_WRITE_KEY", "NEXT_PUBLIC_ANALYTICSCLI_WRITE_KEY", "EXPO_PUBLIC_ANALYTICSCLI_WRITE_KEY", "VITE_ANALYTICSCLI_WRITE_KEY"];
448
+ declare const DEFAULT_API_KEY_ENV_KEYS: readonly ["ANALYTICSCLI_PUBLISHABLE_API_KEY", "NEXT_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY", "EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY", "VITE_ANALYTICSCLI_PUBLISHABLE_API_KEY"];
368
449
  /**
369
450
  * Minimal host-app bootstrap helper.
370
451
  * Resolves `apiKey` (required) from explicit options or env-like objects.
@@ -376,12 +457,17 @@ declare const initFromEnv: (options?: InitFromEnvOptions) => AnalyticsClient;
376
457
  */
377
458
  declare const init: (input?: InitInput) => AnalyticsClient;
378
459
  /**
379
- * Creates an analytics client and waits for async storage hydration.
380
- * Prefer this in React Native when using async persistence (for example AsyncStorage).
460
+ * Creates an analytics client with consent-first defaults.
461
+ * Tracking stays disabled until `optIn()` / `setConsent(true)` is called.
462
+ */
463
+ declare const initConsentFirst: (input?: InitInput) => AnalyticsClient;
464
+ /**
465
+ * Creates an analytics client and resolves once client initialization completes.
381
466
  */
382
467
  declare const initAsync: (input?: InitInput) => Promise<AnalyticsClient>;
383
- declare const BROWSER_API_KEY_ENV_KEYS: readonly ["ANALYTICSCLI_WRITE_KEY", "NEXT_PUBLIC_ANALYTICSCLI_WRITE_KEY", "PUBLIC_ANALYTICSCLI_WRITE_KEY", "VITE_ANALYTICSCLI_WRITE_KEY", "EXPO_PUBLIC_ANALYTICSCLI_WRITE_KEY"];
384
- declare const REACT_NATIVE_API_KEY_ENV_KEYS: readonly ["ANALYTICSCLI_WRITE_KEY", "EXPO_PUBLIC_ANALYTICSCLI_WRITE_KEY"];
468
+ declare const initConsentFirstAsync: (input?: InitInput) => Promise<AnalyticsClient>;
469
+ declare const BROWSER_API_KEY_ENV_KEYS: readonly ["ANALYTICSCLI_PUBLISHABLE_API_KEY", "NEXT_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY", "PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY", "VITE_ANALYTICSCLI_PUBLISHABLE_API_KEY", "EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY"];
470
+ declare const REACT_NATIVE_API_KEY_ENV_KEYS: readonly ["ANALYTICSCLI_PUBLISHABLE_API_KEY", "EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY"];
385
471
  type BrowserInitFromEnvOptions = Omit<InitFromEnvOptions, 'apiKeyEnvKeys'> & {
386
472
  apiKeyEnvKeys?: readonly string[];
387
473
  };
@@ -399,4 +485,4 @@ declare const initBrowserFromEnv: (options?: BrowserInitFromEnvOptions) => Analy
399
485
  */
400
486
  declare const initReactNativeFromEnv: (options?: ReactNativeInitFromEnvOptions) => AnalyticsClient;
401
487
 
402
- export { AnalyticsClient, type AnalyticsClientOptions, type AnalyticsStorageAdapter, BROWSER_API_KEY_ENV_KEYS, type BrowserInitFromEnvOptions, DEFAULT_API_KEY_ENV_KEYS, type EventContext, type EventProperties, type InitFromEnvMissingConfig, type InitFromEnvMissingConfigMode, type InitFromEnvOptions, type InitInput, type InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, type OnboardingEventName, type OnboardingEventProperties, type OnboardingStepTracker, type OnboardingSurveyAnswerType, type OnboardingSurveyEventName, type OnboardingSurveyResponseInput, type OnboardingTracker, type OnboardingTrackerDefaults, type OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, type PaywallEventName, type PaywallEventProperties, type PaywallJourneyEventName, type PaywallTracker, type PaywallTrackerDefaults, type PaywallTrackerProperties, type PurchaseEventName, REACT_NATIVE_API_KEY_ENV_KEYS, type ReactNativeInitFromEnvOptions, init, initAsync, initBrowserFromEnv, initFromEnv, initReactNativeFromEnv };
488
+ export { AnalyticsClient, type AnalyticsClientOptions, type AnalyticsConsentState, type AnalyticsStorageAdapter, BROWSER_API_KEY_ENV_KEYS, type BrowserInitFromEnvOptions, DEFAULT_API_KEY_ENV_KEYS, type EventContext, type EventProperties, type IdentityTrackingMode, type InitFromEnvMissingConfig, type InitFromEnvMissingConfigMode, type InitFromEnvOptions, type InitInput, type InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, type OnboardingEventName, type OnboardingEventProperties, type OnboardingStepTracker, type OnboardingSurveyAnswerType, type OnboardingSurveyEventName, type OnboardingSurveyResponseInput, type OnboardingTracker, type OnboardingTrackerDefaults, type OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, type PaywallEventName, type PaywallEventProperties, type PaywallJourneyEventName, type PaywallTracker, type PaywallTrackerDefaults, type PaywallTrackerProperties, type PurchaseEventName, REACT_NATIVE_API_KEY_ENV_KEYS, type ReactNativeInitFromEnvOptions, type SetConsentOptions, init, initAsync, initBrowserFromEnv, initConsentFirst, initConsentFirstAsync, initFromEnv, initReactNativeFromEnv };