@analyticscli/sdk 0.1.0-preview.10 → 0.1.0-preview.12

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
@@ -38,30 +38,27 @@ Before integrating, collect required values in [dash.analyticscli.com](https://d
38
38
  ## Usage (Low Boilerplate)
39
39
 
40
40
  ```ts
41
- import { createAnalyticsContext } from '@analyticscli/sdk';
42
-
43
- const analytics = createAnalyticsContext({
44
- client: {
45
- apiKey: '<YOUR_APP_KEY>',
46
- identityTrackingMode: 'consent_gated', // explicit host-app default
47
- },
48
- onboarding: {
49
- onboardingFlowId: 'onboarding_v1',
50
- onboardingFlowVersion: '1.0.0',
51
- isNewUser: true,
52
- },
41
+ import { init } from '@analyticscli/sdk';
42
+
43
+ const analytics = init({
44
+ apiKey: '<YOUR_APP_KEY>',
45
+ identityTrackingMode: 'consent_gated', // explicit host-app default
46
+ });
47
+
48
+ const onboarding = analytics.createOnboardingTracker({
49
+ onboardingFlowId: 'onboarding_v1',
50
+ onboardingFlowVersion: '1.0.0',
51
+ isNewUser: true,
53
52
  });
54
53
 
55
- analytics.onboarding.start();
56
- analytics.onboarding.step('welcome', 0).view();
54
+ onboarding.start();
55
+ onboarding.step('welcome', 0).view();
57
56
  ```
58
57
 
59
- `createAnalyticsContext(...)` gives you:
60
- - `analytics.client` (raw `AnalyticsClient`)
61
- - `analytics.onboarding` (pre-wired tracker instance)
62
- - `analytics.paywall` (optional tracker instance)
63
- - `analytics.consent.*` (collection + full-tracking controls)
64
- - `analytics.user.*` (`set`, `clear`, `identify`)
58
+ `init(...)` returns `AnalyticsClient` directly.
59
+ Use tracker factories for flow-scoped instrumentation:
60
+ - `analytics.createOnboardingTracker(...)`
61
+ - `analytics.createPaywallTracker(...)`
65
62
 
66
63
  For host-app integration, prefer explicit client config with
67
64
  `identityTrackingMode: 'consent_gated'` unless you intentionally need another mode.
@@ -69,36 +66,32 @@ For host-app integration, prefer explicit client config with
69
66
  Optional runtime collection pause/resume:
70
67
 
71
68
  ```ts
72
- import { createAnalyticsContext } from '@analyticscli/sdk';
69
+ import { init } from '@analyticscli/sdk';
73
70
 
74
- const analytics = createAnalyticsContext({
75
- client: {
76
- apiKey: '<YOUR_APP_KEY>',
77
- identityTrackingMode: 'consent_gated',
78
- },
71
+ const analytics = init({
72
+ apiKey: '<YOUR_APP_KEY>',
73
+ identityTrackingMode: 'consent_gated',
79
74
  });
80
- analytics.consent.optOut(); // stop sending until optIn()
75
+ analytics.optOut(); // stop sending until optIn()
81
76
  // ...
82
- analytics.consent.optIn();
77
+ analytics.optIn();
83
78
  ```
84
79
 
85
80
  Optional full-tracking consent gate (recommended default):
86
81
 
87
82
  ```ts
88
- import { createAnalyticsContext } from '@analyticscli/sdk';
83
+ import { init } from '@analyticscli/sdk';
89
84
 
90
- const analytics = createAnalyticsContext({
91
- client: {
92
- apiKey: '<YOUR_APP_KEY>',
93
- identityTrackingMode: 'consent_gated',
94
- },
85
+ const analytics = init({
86
+ apiKey: '<YOUR_APP_KEY>',
87
+ identityTrackingMode: 'consent_gated',
95
88
  });
96
89
 
97
90
  // user accepts full tracking in your consent UI
98
- analytics.consent.setFullTracking(true);
91
+ analytics.setFullTrackingConsent(true);
99
92
 
100
93
  // user rejects full tracking but you still keep strict anonymous analytics
101
- analytics.consent.setFullTracking(false);
94
+ analytics.setFullTrackingConsent(false);
102
95
  ```
103
96
 
104
97
  If `apiKey` is missing, the SDK logs a console error and remains a safe no-op client.
@@ -108,28 +101,20 @@ If `apiKey` is missing, the SDK logs a console error and remains a safe no-op cl
108
101
  ```ts
109
102
  import * as Application from 'expo-application';
110
103
  import { Platform } from 'react-native';
111
- import { createAnalyticsContext } from '@analyticscli/sdk';
112
-
113
- const analytics = createAnalyticsContext({
114
- client: {
115
- apiKey: process.env.EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY,
116
- debug: __DEV__,
117
- platform: Platform.OS,
118
- projectSurface: 'app',
119
- appVersion: Application.nativeApplicationVersion,
120
- initialConsentGranted: true,
121
- identityTrackingMode: 'consent_gated',
122
- initialFullTrackingConsentGranted: false,
123
- dedupeOnboardingStepViewsPerSession: true,
124
- dedupeScreenViewsPerSession: true,
125
- screenViewDedupeWindowMs: 1200,
126
- },
127
- onboarding: {
128
- onboardingFlowId: 'onboarding_main',
129
- onboardingFlowVersion: '1',
130
- isNewUser: true,
131
- stepCount: 7,
132
- },
104
+ import { init } from '@analyticscli/sdk';
105
+
106
+ const analytics = init({
107
+ apiKey: process.env.EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY,
108
+ debug: __DEV__,
109
+ platform: Platform.OS,
110
+ projectSurface: 'app',
111
+ appVersion: Application.nativeApplicationVersion,
112
+ initialConsentGranted: true,
113
+ identityTrackingMode: 'consent_gated',
114
+ initialFullTrackingConsentGranted: false,
115
+ dedupeOnboardingStepViewsPerSession: true,
116
+ dedupeScreenViewsPerSession: true,
117
+ screenViewDedupeWindowMs: 1200,
133
118
  });
134
119
  ```
135
120
 
@@ -151,7 +136,7 @@ For paywall funnels with stable `source` + `paywallId`, create one tracker per
151
136
  flow context and reuse it:
152
137
 
153
138
  ```ts
154
- const paywall = analytics.createPaywall({
139
+ const paywall = analytics.createPaywallTracker({
155
140
  source: 'onboarding',
156
141
  paywallId: 'default_paywall',
157
142
  offering: 'rc_main', // RevenueCat example
@@ -161,7 +146,7 @@ paywall.shown({ fromScreen: 'onboarding_offer' });
161
146
  paywall.purchaseSuccess({ packageId: 'annual' });
162
147
  ```
163
148
 
164
- Do not create a new `createPaywall(...)` instance for every paywall callback/event.
149
+ Do not create a new `createPaywallTracker(...)` instance for every paywall callback/event.
165
150
  If your paywall provider exposes it, pass `offering` in tracker defaults
166
151
  (RevenueCat offering id, Adapty paywall/placement id, Superwall placement/paywall id).
167
152
 
@@ -169,7 +154,7 @@ For onboarding surveys, avoid repeating unchanged flow metadata at every callsit
169
154
  Create one onboarding tracker with defaults and emit minimal survey payloads:
170
155
 
171
156
  ```ts
172
- const onboarding = analytics.createOnboarding({
157
+ const onboarding = analytics.createOnboardingTracker({
173
158
  onboardingFlowId: 'onboarding_main',
174
159
  onboardingFlowVersion: '1',
175
160
  stepCount: 7,
@@ -187,11 +172,11 @@ onboarding.step('budget-survey', 6).surveyResponse({
187
172
  For RevenueCat correlation, keep identity and paywall purchase metadata aligned:
188
173
 
189
174
  ```ts
190
- analytics.user.set(appUserId); // same id passed to Purchases.logIn(appUserId)
175
+ analytics.setUser(appUserId); // same id passed to Purchases.logIn(appUserId)
191
176
  // in purchase callbacks, prefer provider-native ids
192
177
  paywall.purchaseStarted({ packageId: packageBeingPurchased.identifier });
193
178
  // on sign-out
194
- analytics.user.clear();
179
+ analytics.clearUser();
195
180
  ```
196
181
 
197
182
  Identity tracking modes:
@@ -205,25 +190,25 @@ Recommendation for global tenant apps:
205
190
  In strict phase (and in `strict` mode):
206
191
  - no persistent SDK identity across app/browser restarts
207
192
  - no cookie-domain identity continuity
208
- - `analytics.user.identify(...)` / `analytics.user.set(...)` are ignored
193
+ - `analytics.identify(...)` / `analytics.setUser(...)` are ignored
209
194
 
210
195
  `initialConsentGranted` is optional:
211
196
  - default: `true` when `apiKey` is present
212
197
  - you can still pause/resume collection at runtime with consent APIs when your app needs that
213
198
 
214
199
  Runtime collection control APIs:
215
- - `analytics.consent.get()` -> current in-memory consent
216
- - `analytics.consent.getState()` -> `'granted' | 'denied' | 'unknown'`
217
- - `analytics.consent.optIn()` / `analytics.consent.optOut()`
218
- - `analytics.consent.set(true|false)`
200
+ - `analytics.getConsent()` -> current in-memory consent
201
+ - `analytics.getConsentState()` -> `'granted' | 'denied' | 'unknown'`
202
+ - `analytics.optIn()` / `analytics.optOut()`
203
+ - `analytics.setConsent(true|false)`
219
204
 
220
205
  Full-tracking control APIs:
221
- - `analytics.consent.setFullTracking(true|false)`
222
- - `analytics.consent.optInFullTracking()` / `analytics.consent.optOutFullTracking()`
223
- - `analytics.consent.isFullTrackingEnabled()`
206
+ - `analytics.setFullTrackingConsent(true|false)`
207
+ - `analytics.optInFullTracking()` / `analytics.optOutFullTracking()`
208
+ - `analytics.isFullTrackingEnabled()`
224
209
 
225
- `analytics.ready()` / `analytics.client.ready()` do not "start" tracking. With default settings, tracking
226
- starts on `createAnalyticsContext(...)`.
210
+ `analytics.ready()` does not "start" tracking. With default settings, tracking
211
+ starts on `init(...)`.
227
212
 
228
213
  Use your project-specific publishable API key from the AnalyticsCLI dashboard in your workspace.
229
214
  Only the publishable API key (`apiKey`) is needed for SDK setup calls.
package/dist/browser.cjs CHANGED
@@ -31,7 +31,6 @@ __export(browser_exports, {
31
31
  PAYWALL_SKIP_EVENT_CANDIDATES: () => PAYWALL_SKIP_EVENT_CANDIDATES,
32
32
  PURCHASE_EVENTS: () => PURCHASE_EVENTS,
33
33
  PURCHASE_SUCCESS_EVENT_CANDIDATES: () => PURCHASE_SUCCESS_EVENT_CANDIDATES,
34
- createAnalyticsContext: () => createAnalyticsContext,
35
34
  init: () => init,
36
35
  initAsync: () => initAsync,
37
36
  initConsentFirst: () => initConsentFirst,
@@ -1121,20 +1120,25 @@ var AnalyticsClient = class {
1121
1120
  if (!this.consentGranted) {
1122
1121
  return;
1123
1122
  }
1123
+ const normalizedScreenName = this.normalizeScreenName(name);
1124
+ if (!normalizedScreenName) {
1125
+ this.log("Dropping screen event with invalid name", { name });
1126
+ return;
1127
+ }
1124
1128
  if (this.shouldDeferEventsUntilHydrated()) {
1125
1129
  const deferredProperties = this.cloneProperties(properties);
1126
1130
  this.deferEventUntilHydrated(() => {
1127
- this.screen(name, deferredProperties);
1131
+ this.screen(normalizedScreenName, deferredProperties);
1128
1132
  });
1129
1133
  return;
1130
1134
  }
1131
1135
  const sessionId = this.getSessionId();
1132
- if (this.shouldDropScreenView(name, properties, sessionId)) {
1136
+ if (this.shouldDropScreenView(normalizedScreenName, properties, sessionId)) {
1133
1137
  return;
1134
1138
  }
1135
1139
  this.enqueue({
1136
1140
  eventId: randomId(),
1137
- eventName: `screen:${name}`,
1141
+ eventName: `screen:${normalizedScreenName}`,
1138
1142
  ts: nowIso(),
1139
1143
  sessionId,
1140
1144
  anonId: this.anonId,
@@ -1639,6 +1643,20 @@ var AnalyticsClient = class {
1639
1643
  const resolvedScreenClass = screenClass ?? normalizedName;
1640
1644
  return `${normalizedName}|${resolvedScreenClass}`;
1641
1645
  }
1646
+ normalizeScreenName(name) {
1647
+ const trimmed = this.readRequiredStringOption(name);
1648
+ if (!trimmed) {
1649
+ return null;
1650
+ }
1651
+ const withoutEdgeSlashes = trimmed.replace(/^\/+|\/+$/g, "");
1652
+ const candidate = withoutEdgeSlashes || "root";
1653
+ const normalized = candidate.replace(/[^a-zA-Z0-9_:\-.]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
1654
+ if (!normalized) {
1655
+ return null;
1656
+ }
1657
+ const maxScreenNameLength = 100 - "screen:".length;
1658
+ return normalized.slice(0, maxScreenNameLength);
1659
+ }
1642
1660
  getOnboardingStepViewDedupeKey(properties) {
1643
1661
  if (!properties) {
1644
1662
  return null;
@@ -1804,7 +1822,6 @@ var AnalyticsClient = class {
1804
1822
  appBuild: this.context.appBuild,
1805
1823
  osName: this.context.osName,
1806
1824
  osVersion: this.context.osVersion,
1807
- country: this.context.country,
1808
1825
  region: this.context.region,
1809
1826
  city: this.context.city
1810
1827
  };
@@ -1857,78 +1874,8 @@ var AnalyticsClient = class {
1857
1874
  }
1858
1875
  };
1859
1876
 
1860
- // src/context.ts
1861
- var normalizeInitInput = (input) => {
1862
- if (typeof input === "string") {
1863
- return { apiKey: input };
1864
- }
1865
- if (input === null || input === void 0) {
1866
- return {};
1867
- }
1868
- return input;
1869
- };
1870
- var resolveClient = (input) => {
1871
- if (input instanceof AnalyticsClient) {
1872
- return input;
1873
- }
1874
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1875
- };
1876
- var createAnalyticsContext = (options = {}) => {
1877
- const client = resolveClient(options.client);
1878
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1879
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1880
- const consent = {
1881
- get: () => client.getConsent(),
1882
- getState: () => client.getConsentState(),
1883
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1884
- optIn: (setOptions) => client.optIn(setOptions),
1885
- optOut: (setOptions) => client.optOut(setOptions),
1886
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1887
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1888
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1889
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1890
- };
1891
- const user = {
1892
- identify: (userId, traits) => client.identify(userId, traits),
1893
- set: (userId, traits) => client.setUser(userId, traits),
1894
- clear: () => client.clearUser()
1895
- };
1896
- return {
1897
- client,
1898
- get onboarding() {
1899
- return onboardingTracker;
1900
- },
1901
- get paywall() {
1902
- return paywallTracker;
1903
- },
1904
- consent,
1905
- user,
1906
- track: (eventName, properties) => client.track(eventName, properties),
1907
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1908
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1909
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1910
- screen: (name, properties) => client.screen(name, properties),
1911
- page: (name, properties) => client.page(name, properties),
1912
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1913
- setContext: (context) => client.setContext(context),
1914
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1915
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1916
- configureOnboarding: (defaults) => {
1917
- onboardingTracker = client.createOnboardingTracker(defaults);
1918
- return onboardingTracker;
1919
- },
1920
- configurePaywall: (defaults) => {
1921
- paywallTracker = client.createPaywallTracker(defaults);
1922
- return paywallTracker;
1923
- },
1924
- ready: () => client.ready(),
1925
- flush: () => client.flush(),
1926
- shutdown: () => client.shutdown()
1927
- };
1928
- };
1929
-
1930
1877
  // src/index.ts
1931
- var normalizeInitInput2 = (input) => {
1878
+ var normalizeInitInput = (input) => {
1932
1879
  if (typeof input === "string") {
1933
1880
  return { apiKey: input };
1934
1881
  }
@@ -1938,17 +1885,17 @@ var normalizeInitInput2 = (input) => {
1938
1885
  return input;
1939
1886
  };
1940
1887
  var init = (input = {}) => {
1941
- return new AnalyticsClient(normalizeInitInput2(input));
1888
+ return new AnalyticsClient(normalizeInitInput(input));
1942
1889
  };
1943
1890
  var initConsentFirst = (input = {}) => {
1944
- const normalized = normalizeInitInput2(input);
1891
+ const normalized = normalizeInitInput(input);
1945
1892
  return new AnalyticsClient({
1946
1893
  ...normalized,
1947
1894
  initialConsentGranted: false
1948
1895
  });
1949
1896
  };
1950
1897
  var initAsync = async (input = {}) => {
1951
- const client = new AnalyticsClient(normalizeInitInput2(input));
1898
+ const client = new AnalyticsClient(normalizeInitInput(input));
1952
1899
  await client.ready();
1953
1900
  return client;
1954
1901
  };
@@ -1970,7 +1917,6 @@ var initConsentFirstAsync = async (input = {}) => {
1970
1917
  PAYWALL_SKIP_EVENT_CANDIDATES,
1971
1918
  PURCHASE_EVENTS,
1972
1919
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1973
- createAnalyticsContext,
1974
1920
  init,
1975
1921
  initAsync,
1976
1922
  initConsentFirst,
@@ -1 +1 @@
1
- export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsContext, AnalyticsContextConsentControls, AnalyticsContextUserControls, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, CreateAnalyticsContextOptions, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, createAnalyticsContext, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.cjs';
1
+ export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.cjs';
package/dist/browser.d.ts CHANGED
@@ -1 +1 @@
1
- export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsContext, AnalyticsContextConsentControls, AnalyticsContextUserControls, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, CreateAnalyticsContextOptions, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, createAnalyticsContext, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.js';
1
+ export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.js';
package/dist/browser.js CHANGED
@@ -10,12 +10,11 @@ import {
10
10
  PAYWALL_SKIP_EVENT_CANDIDATES,
11
11
  PURCHASE_EVENTS,
12
12
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
13
- createAnalyticsContext,
14
13
  init,
15
14
  initAsync,
16
15
  initConsentFirst,
17
16
  initConsentFirstAsync
18
- } from "./chunk-6EPJZLLK.js";
17
+ } from "./chunk-4DKQNTSO.js";
19
18
  export {
20
19
  AnalyticsClient,
21
20
  ONBOARDING_EVENTS,
@@ -28,7 +27,6 @@ export {
28
27
  PAYWALL_SKIP_EVENT_CANDIDATES,
29
28
  PURCHASE_EVENTS,
30
29
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
31
- createAnalyticsContext,
32
30
  init,
33
31
  initAsync,
34
32
  initConsentFirst,
@@ -1080,20 +1080,25 @@ var AnalyticsClient = class {
1080
1080
  if (!this.consentGranted) {
1081
1081
  return;
1082
1082
  }
1083
+ const normalizedScreenName = this.normalizeScreenName(name);
1084
+ if (!normalizedScreenName) {
1085
+ this.log("Dropping screen event with invalid name", { name });
1086
+ return;
1087
+ }
1083
1088
  if (this.shouldDeferEventsUntilHydrated()) {
1084
1089
  const deferredProperties = this.cloneProperties(properties);
1085
1090
  this.deferEventUntilHydrated(() => {
1086
- this.screen(name, deferredProperties);
1091
+ this.screen(normalizedScreenName, deferredProperties);
1087
1092
  });
1088
1093
  return;
1089
1094
  }
1090
1095
  const sessionId = this.getSessionId();
1091
- if (this.shouldDropScreenView(name, properties, sessionId)) {
1096
+ if (this.shouldDropScreenView(normalizedScreenName, properties, sessionId)) {
1092
1097
  return;
1093
1098
  }
1094
1099
  this.enqueue({
1095
1100
  eventId: randomId(),
1096
- eventName: `screen:${name}`,
1101
+ eventName: `screen:${normalizedScreenName}`,
1097
1102
  ts: nowIso(),
1098
1103
  sessionId,
1099
1104
  anonId: this.anonId,
@@ -1598,6 +1603,20 @@ var AnalyticsClient = class {
1598
1603
  const resolvedScreenClass = screenClass ?? normalizedName;
1599
1604
  return `${normalizedName}|${resolvedScreenClass}`;
1600
1605
  }
1606
+ normalizeScreenName(name) {
1607
+ const trimmed = this.readRequiredStringOption(name);
1608
+ if (!trimmed) {
1609
+ return null;
1610
+ }
1611
+ const withoutEdgeSlashes = trimmed.replace(/^\/+|\/+$/g, "");
1612
+ const candidate = withoutEdgeSlashes || "root";
1613
+ const normalized = candidate.replace(/[^a-zA-Z0-9_:\-.]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
1614
+ if (!normalized) {
1615
+ return null;
1616
+ }
1617
+ const maxScreenNameLength = 100 - "screen:".length;
1618
+ return normalized.slice(0, maxScreenNameLength);
1619
+ }
1601
1620
  getOnboardingStepViewDedupeKey(properties) {
1602
1621
  if (!properties) {
1603
1622
  return null;
@@ -1763,7 +1782,6 @@ var AnalyticsClient = class {
1763
1782
  appBuild: this.context.appBuild,
1764
1783
  osName: this.context.osName,
1765
1784
  osVersion: this.context.osVersion,
1766
- country: this.context.country,
1767
1785
  region: this.context.region,
1768
1786
  city: this.context.city
1769
1787
  };
@@ -1816,78 +1834,8 @@ var AnalyticsClient = class {
1816
1834
  }
1817
1835
  };
1818
1836
 
1819
- // src/context.ts
1820
- var normalizeInitInput = (input) => {
1821
- if (typeof input === "string") {
1822
- return { apiKey: input };
1823
- }
1824
- if (input === null || input === void 0) {
1825
- return {};
1826
- }
1827
- return input;
1828
- };
1829
- var resolveClient = (input) => {
1830
- if (input instanceof AnalyticsClient) {
1831
- return input;
1832
- }
1833
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1834
- };
1835
- var createAnalyticsContext = (options = {}) => {
1836
- const client = resolveClient(options.client);
1837
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1838
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1839
- const consent = {
1840
- get: () => client.getConsent(),
1841
- getState: () => client.getConsentState(),
1842
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1843
- optIn: (setOptions) => client.optIn(setOptions),
1844
- optOut: (setOptions) => client.optOut(setOptions),
1845
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1846
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1847
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1848
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1849
- };
1850
- const user = {
1851
- identify: (userId, traits) => client.identify(userId, traits),
1852
- set: (userId, traits) => client.setUser(userId, traits),
1853
- clear: () => client.clearUser()
1854
- };
1855
- return {
1856
- client,
1857
- get onboarding() {
1858
- return onboardingTracker;
1859
- },
1860
- get paywall() {
1861
- return paywallTracker;
1862
- },
1863
- consent,
1864
- user,
1865
- track: (eventName, properties) => client.track(eventName, properties),
1866
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1867
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1868
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1869
- screen: (name, properties) => client.screen(name, properties),
1870
- page: (name, properties) => client.page(name, properties),
1871
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1872
- setContext: (context) => client.setContext(context),
1873
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1874
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1875
- configureOnboarding: (defaults) => {
1876
- onboardingTracker = client.createOnboardingTracker(defaults);
1877
- return onboardingTracker;
1878
- },
1879
- configurePaywall: (defaults) => {
1880
- paywallTracker = client.createPaywallTracker(defaults);
1881
- return paywallTracker;
1882
- },
1883
- ready: () => client.ready(),
1884
- flush: () => client.flush(),
1885
- shutdown: () => client.shutdown()
1886
- };
1887
- };
1888
-
1889
1837
  // src/index.ts
1890
- var normalizeInitInput2 = (input) => {
1838
+ var normalizeInitInput = (input) => {
1891
1839
  if (typeof input === "string") {
1892
1840
  return { apiKey: input };
1893
1841
  }
@@ -1897,17 +1845,17 @@ var normalizeInitInput2 = (input) => {
1897
1845
  return input;
1898
1846
  };
1899
1847
  var init = (input = {}) => {
1900
- return new AnalyticsClient(normalizeInitInput2(input));
1848
+ return new AnalyticsClient(normalizeInitInput(input));
1901
1849
  };
1902
1850
  var initConsentFirst = (input = {}) => {
1903
- const normalized = normalizeInitInput2(input);
1851
+ const normalized = normalizeInitInput(input);
1904
1852
  return new AnalyticsClient({
1905
1853
  ...normalized,
1906
1854
  initialConsentGranted: false
1907
1855
  });
1908
1856
  };
1909
1857
  var initAsync = async (input = {}) => {
1910
- const client = new AnalyticsClient(normalizeInitInput2(input));
1858
+ const client = new AnalyticsClient(normalizeInitInput(input));
1911
1859
  await client.ready();
1912
1860
  return client;
1913
1861
  };
@@ -1929,7 +1877,6 @@ export {
1929
1877
  PAYWALL_SKIP_EVENT_CANDIDATES,
1930
1878
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1931
1879
  AnalyticsClient,
1932
- createAnalyticsContext,
1933
1880
  init,
1934
1881
  initConsentFirst,
1935
1882
  initAsync,
package/dist/index.cjs CHANGED
@@ -31,7 +31,6 @@ __export(index_exports, {
31
31
  PAYWALL_SKIP_EVENT_CANDIDATES: () => PAYWALL_SKIP_EVENT_CANDIDATES,
32
32
  PURCHASE_EVENTS: () => PURCHASE_EVENTS,
33
33
  PURCHASE_SUCCESS_EVENT_CANDIDATES: () => PURCHASE_SUCCESS_EVENT_CANDIDATES,
34
- createAnalyticsContext: () => createAnalyticsContext,
35
34
  init: () => init,
36
35
  initAsync: () => initAsync,
37
36
  initConsentFirst: () => initConsentFirst,
@@ -1121,20 +1120,25 @@ var AnalyticsClient = class {
1121
1120
  if (!this.consentGranted) {
1122
1121
  return;
1123
1122
  }
1123
+ const normalizedScreenName = this.normalizeScreenName(name);
1124
+ if (!normalizedScreenName) {
1125
+ this.log("Dropping screen event with invalid name", { name });
1126
+ return;
1127
+ }
1124
1128
  if (this.shouldDeferEventsUntilHydrated()) {
1125
1129
  const deferredProperties = this.cloneProperties(properties);
1126
1130
  this.deferEventUntilHydrated(() => {
1127
- this.screen(name, deferredProperties);
1131
+ this.screen(normalizedScreenName, deferredProperties);
1128
1132
  });
1129
1133
  return;
1130
1134
  }
1131
1135
  const sessionId = this.getSessionId();
1132
- if (this.shouldDropScreenView(name, properties, sessionId)) {
1136
+ if (this.shouldDropScreenView(normalizedScreenName, properties, sessionId)) {
1133
1137
  return;
1134
1138
  }
1135
1139
  this.enqueue({
1136
1140
  eventId: randomId(),
1137
- eventName: `screen:${name}`,
1141
+ eventName: `screen:${normalizedScreenName}`,
1138
1142
  ts: nowIso(),
1139
1143
  sessionId,
1140
1144
  anonId: this.anonId,
@@ -1639,6 +1643,20 @@ var AnalyticsClient = class {
1639
1643
  const resolvedScreenClass = screenClass ?? normalizedName;
1640
1644
  return `${normalizedName}|${resolvedScreenClass}`;
1641
1645
  }
1646
+ normalizeScreenName(name) {
1647
+ const trimmed = this.readRequiredStringOption(name);
1648
+ if (!trimmed) {
1649
+ return null;
1650
+ }
1651
+ const withoutEdgeSlashes = trimmed.replace(/^\/+|\/+$/g, "");
1652
+ const candidate = withoutEdgeSlashes || "root";
1653
+ const normalized = candidate.replace(/[^a-zA-Z0-9_:\-.]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
1654
+ if (!normalized) {
1655
+ return null;
1656
+ }
1657
+ const maxScreenNameLength = 100 - "screen:".length;
1658
+ return normalized.slice(0, maxScreenNameLength);
1659
+ }
1642
1660
  getOnboardingStepViewDedupeKey(properties) {
1643
1661
  if (!properties) {
1644
1662
  return null;
@@ -1804,7 +1822,6 @@ var AnalyticsClient = class {
1804
1822
  appBuild: this.context.appBuild,
1805
1823
  osName: this.context.osName,
1806
1824
  osVersion: this.context.osVersion,
1807
- country: this.context.country,
1808
1825
  region: this.context.region,
1809
1826
  city: this.context.city
1810
1827
  };
@@ -1857,78 +1874,8 @@ var AnalyticsClient = class {
1857
1874
  }
1858
1875
  };
1859
1876
 
1860
- // src/context.ts
1861
- var normalizeInitInput = (input) => {
1862
- if (typeof input === "string") {
1863
- return { apiKey: input };
1864
- }
1865
- if (input === null || input === void 0) {
1866
- return {};
1867
- }
1868
- return input;
1869
- };
1870
- var resolveClient = (input) => {
1871
- if (input instanceof AnalyticsClient) {
1872
- return input;
1873
- }
1874
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1875
- };
1876
- var createAnalyticsContext = (options = {}) => {
1877
- const client = resolveClient(options.client);
1878
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1879
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1880
- const consent = {
1881
- get: () => client.getConsent(),
1882
- getState: () => client.getConsentState(),
1883
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1884
- optIn: (setOptions) => client.optIn(setOptions),
1885
- optOut: (setOptions) => client.optOut(setOptions),
1886
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1887
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1888
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1889
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1890
- };
1891
- const user = {
1892
- identify: (userId, traits) => client.identify(userId, traits),
1893
- set: (userId, traits) => client.setUser(userId, traits),
1894
- clear: () => client.clearUser()
1895
- };
1896
- return {
1897
- client,
1898
- get onboarding() {
1899
- return onboardingTracker;
1900
- },
1901
- get paywall() {
1902
- return paywallTracker;
1903
- },
1904
- consent,
1905
- user,
1906
- track: (eventName, properties) => client.track(eventName, properties),
1907
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1908
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1909
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1910
- screen: (name, properties) => client.screen(name, properties),
1911
- page: (name, properties) => client.page(name, properties),
1912
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1913
- setContext: (context) => client.setContext(context),
1914
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1915
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1916
- configureOnboarding: (defaults) => {
1917
- onboardingTracker = client.createOnboardingTracker(defaults);
1918
- return onboardingTracker;
1919
- },
1920
- configurePaywall: (defaults) => {
1921
- paywallTracker = client.createPaywallTracker(defaults);
1922
- return paywallTracker;
1923
- },
1924
- ready: () => client.ready(),
1925
- flush: () => client.flush(),
1926
- shutdown: () => client.shutdown()
1927
- };
1928
- };
1929
-
1930
1877
  // src/index.ts
1931
- var normalizeInitInput2 = (input) => {
1878
+ var normalizeInitInput = (input) => {
1932
1879
  if (typeof input === "string") {
1933
1880
  return { apiKey: input };
1934
1881
  }
@@ -1938,17 +1885,17 @@ var normalizeInitInput2 = (input) => {
1938
1885
  return input;
1939
1886
  };
1940
1887
  var init = (input = {}) => {
1941
- return new AnalyticsClient(normalizeInitInput2(input));
1888
+ return new AnalyticsClient(normalizeInitInput(input));
1942
1889
  };
1943
1890
  var initConsentFirst = (input = {}) => {
1944
- const normalized = normalizeInitInput2(input);
1891
+ const normalized = normalizeInitInput(input);
1945
1892
  return new AnalyticsClient({
1946
1893
  ...normalized,
1947
1894
  initialConsentGranted: false
1948
1895
  });
1949
1896
  };
1950
1897
  var initAsync = async (input = {}) => {
1951
- const client = new AnalyticsClient(normalizeInitInput2(input));
1898
+ const client = new AnalyticsClient(normalizeInitInput(input));
1952
1899
  await client.ready();
1953
1900
  return client;
1954
1901
  };
@@ -1970,7 +1917,6 @@ var initConsentFirstAsync = async (input = {}) => {
1970
1917
  PAYWALL_SKIP_EVENT_CANDIDATES,
1971
1918
  PURCHASE_EVENTS,
1972
1919
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1973
- createAnalyticsContext,
1974
1920
  init,
1975
1921
  initAsync,
1976
1922
  initConsentFirst,
package/dist/index.d.cts CHANGED
@@ -49,7 +49,6 @@ type EventContext = {
49
49
  appBuild?: string;
50
50
  osName?: string;
51
51
  osVersion?: string;
52
- country?: string;
53
52
  region?: string;
54
53
  city?: string;
55
54
  };
@@ -487,6 +486,7 @@ declare class AnalyticsClient {
487
486
  private shouldDropOnboardingStepView;
488
487
  private shouldDropScreenView;
489
488
  private getScreenViewDedupeKey;
489
+ private normalizeScreenName;
490
490
  private getOnboardingStepViewDedupeKey;
491
491
  private readPropertyAsString;
492
492
  private readPropertyAsStepIndex;
@@ -510,65 +510,6 @@ declare class AnalyticsClient {
510
510
  private reportMissingApiKey;
511
511
  }
512
512
 
513
- type ContextClientInput = InitInput | AnalyticsClient | null | undefined;
514
- type AnalyticsContextConsentControls = {
515
- get: () => boolean;
516
- getState: () => AnalyticsConsentState;
517
- set: (granted: boolean, options?: SetConsentOptions) => void;
518
- optIn: (options?: SetConsentOptions) => void;
519
- optOut: (options?: SetConsentOptions) => void;
520
- setFullTracking: (granted: boolean, options?: SetConsentOptions) => void;
521
- optInFullTracking: (options?: SetConsentOptions) => void;
522
- optOutFullTracking: (options?: SetConsentOptions) => void;
523
- isFullTrackingEnabled: () => boolean;
524
- };
525
- type AnalyticsContextUserControls = {
526
- identify: (userId: string, traits?: EventProperties) => void;
527
- set: (userId: string | null | undefined, traits?: EventProperties) => void;
528
- clear: () => void;
529
- };
530
- type AnalyticsContext = {
531
- client: AnalyticsClient;
532
- onboarding: OnboardingTracker;
533
- paywall: PaywallTracker | null;
534
- consent: AnalyticsContextConsentControls;
535
- user: AnalyticsContextUserControls;
536
- track: (eventName: string, properties?: EventProperties) => void;
537
- trackOnboardingEvent: (eventName: OnboardingEventName, properties?: OnboardingEventProperties) => void;
538
- trackOnboardingSurveyResponse: (input: OnboardingSurveyResponseInput, eventName?: OnboardingSurveyEventName) => void;
539
- trackPaywallEvent: (eventName: PaywallJourneyEventName, properties: PaywallEventProperties) => void;
540
- screen: (name: string, properties?: EventProperties) => void;
541
- page: (name: string, properties?: EventProperties) => void;
542
- feedback: (message: string, rating?: number, properties?: EventProperties) => void;
543
- setContext: (context: EventContext) => void;
544
- createOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
545
- createPaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
546
- configureOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
547
- configurePaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
548
- ready: () => Promise<void>;
549
- flush: () => Promise<void>;
550
- shutdown: () => void;
551
- };
552
- type CreateAnalyticsContextOptions = {
553
- /**
554
- * Either an existing client instance or standard `init(...)` input.
555
- */
556
- client?: ContextClientInput;
557
- /**
558
- * Defaults used for the exported `context.onboarding` tracker instance.
559
- */
560
- onboarding?: OnboardingTrackerDefaults | null;
561
- /**
562
- * Optional defaults used for the exported `context.paywall` tracker instance.
563
- */
564
- paywall?: PaywallTrackerDefaults | null;
565
- };
566
- /**
567
- * Host-app friendly SDK context with low boilerplate and rich defaults.
568
- * Provides pre-wired onboarding + consent/user controls and optional paywall tracker binding.
569
- */
570
- declare const createAnalyticsContext: (options?: CreateAnalyticsContextOptions) => AnalyticsContext;
571
-
572
513
  /**
573
514
  * Creates a browser analytics client instance.
574
515
  */
@@ -584,4 +525,4 @@ declare const initConsentFirst: (input?: InitInput) => AnalyticsClient;
584
525
  declare const initAsync: (input?: InitInput) => Promise<AnalyticsClient>;
585
526
  declare const initConsentFirstAsync: (input?: InitInput) => Promise<AnalyticsClient>;
586
527
 
587
- export { AnalyticsClient, type AnalyticsClientOptions, type AnalyticsConsentState, type AnalyticsContext, type AnalyticsContextConsentControls, type AnalyticsContextUserControls, type AnalyticsIngestError, type AnalyticsIngestErrorHandler, type AnalyticsStorageAdapter, type CreateAnalyticsContextOptions, type EventContext, type EventProperties, type IdentityTrackingMode, 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, type SetConsentOptions, createAnalyticsContext, init, initAsync, initConsentFirst, initConsentFirstAsync };
528
+ export { AnalyticsClient, type AnalyticsClientOptions, type AnalyticsConsentState, type AnalyticsIngestError, type AnalyticsIngestErrorHandler, type AnalyticsStorageAdapter, type EventContext, type EventProperties, type IdentityTrackingMode, 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, type SetConsentOptions, init, initAsync, initConsentFirst, initConsentFirstAsync };
package/dist/index.d.ts CHANGED
@@ -49,7 +49,6 @@ type EventContext = {
49
49
  appBuild?: string;
50
50
  osName?: string;
51
51
  osVersion?: string;
52
- country?: string;
53
52
  region?: string;
54
53
  city?: string;
55
54
  };
@@ -487,6 +486,7 @@ declare class AnalyticsClient {
487
486
  private shouldDropOnboardingStepView;
488
487
  private shouldDropScreenView;
489
488
  private getScreenViewDedupeKey;
489
+ private normalizeScreenName;
490
490
  private getOnboardingStepViewDedupeKey;
491
491
  private readPropertyAsString;
492
492
  private readPropertyAsStepIndex;
@@ -510,65 +510,6 @@ declare class AnalyticsClient {
510
510
  private reportMissingApiKey;
511
511
  }
512
512
 
513
- type ContextClientInput = InitInput | AnalyticsClient | null | undefined;
514
- type AnalyticsContextConsentControls = {
515
- get: () => boolean;
516
- getState: () => AnalyticsConsentState;
517
- set: (granted: boolean, options?: SetConsentOptions) => void;
518
- optIn: (options?: SetConsentOptions) => void;
519
- optOut: (options?: SetConsentOptions) => void;
520
- setFullTracking: (granted: boolean, options?: SetConsentOptions) => void;
521
- optInFullTracking: (options?: SetConsentOptions) => void;
522
- optOutFullTracking: (options?: SetConsentOptions) => void;
523
- isFullTrackingEnabled: () => boolean;
524
- };
525
- type AnalyticsContextUserControls = {
526
- identify: (userId: string, traits?: EventProperties) => void;
527
- set: (userId: string | null | undefined, traits?: EventProperties) => void;
528
- clear: () => void;
529
- };
530
- type AnalyticsContext = {
531
- client: AnalyticsClient;
532
- onboarding: OnboardingTracker;
533
- paywall: PaywallTracker | null;
534
- consent: AnalyticsContextConsentControls;
535
- user: AnalyticsContextUserControls;
536
- track: (eventName: string, properties?: EventProperties) => void;
537
- trackOnboardingEvent: (eventName: OnboardingEventName, properties?: OnboardingEventProperties) => void;
538
- trackOnboardingSurveyResponse: (input: OnboardingSurveyResponseInput, eventName?: OnboardingSurveyEventName) => void;
539
- trackPaywallEvent: (eventName: PaywallJourneyEventName, properties: PaywallEventProperties) => void;
540
- screen: (name: string, properties?: EventProperties) => void;
541
- page: (name: string, properties?: EventProperties) => void;
542
- feedback: (message: string, rating?: number, properties?: EventProperties) => void;
543
- setContext: (context: EventContext) => void;
544
- createOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
545
- createPaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
546
- configureOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
547
- configurePaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
548
- ready: () => Promise<void>;
549
- flush: () => Promise<void>;
550
- shutdown: () => void;
551
- };
552
- type CreateAnalyticsContextOptions = {
553
- /**
554
- * Either an existing client instance or standard `init(...)` input.
555
- */
556
- client?: ContextClientInput;
557
- /**
558
- * Defaults used for the exported `context.onboarding` tracker instance.
559
- */
560
- onboarding?: OnboardingTrackerDefaults | null;
561
- /**
562
- * Optional defaults used for the exported `context.paywall` tracker instance.
563
- */
564
- paywall?: PaywallTrackerDefaults | null;
565
- };
566
- /**
567
- * Host-app friendly SDK context with low boilerplate and rich defaults.
568
- * Provides pre-wired onboarding + consent/user controls and optional paywall tracker binding.
569
- */
570
- declare const createAnalyticsContext: (options?: CreateAnalyticsContextOptions) => AnalyticsContext;
571
-
572
513
  /**
573
514
  * Creates a browser analytics client instance.
574
515
  */
@@ -584,4 +525,4 @@ declare const initConsentFirst: (input?: InitInput) => AnalyticsClient;
584
525
  declare const initAsync: (input?: InitInput) => Promise<AnalyticsClient>;
585
526
  declare const initConsentFirstAsync: (input?: InitInput) => Promise<AnalyticsClient>;
586
527
 
587
- export { AnalyticsClient, type AnalyticsClientOptions, type AnalyticsConsentState, type AnalyticsContext, type AnalyticsContextConsentControls, type AnalyticsContextUserControls, type AnalyticsIngestError, type AnalyticsIngestErrorHandler, type AnalyticsStorageAdapter, type CreateAnalyticsContextOptions, type EventContext, type EventProperties, type IdentityTrackingMode, 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, type SetConsentOptions, createAnalyticsContext, init, initAsync, initConsentFirst, initConsentFirstAsync };
528
+ export { AnalyticsClient, type AnalyticsClientOptions, type AnalyticsConsentState, type AnalyticsIngestError, type AnalyticsIngestErrorHandler, type AnalyticsStorageAdapter, type EventContext, type EventProperties, type IdentityTrackingMode, 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, type SetConsentOptions, init, initAsync, initConsentFirst, initConsentFirstAsync };
package/dist/index.js CHANGED
@@ -10,12 +10,11 @@ import {
10
10
  PAYWALL_SKIP_EVENT_CANDIDATES,
11
11
  PURCHASE_EVENTS,
12
12
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
13
- createAnalyticsContext,
14
13
  init,
15
14
  initAsync,
16
15
  initConsentFirst,
17
16
  initConsentFirstAsync
18
- } from "./chunk-6EPJZLLK.js";
17
+ } from "./chunk-4DKQNTSO.js";
19
18
  export {
20
19
  AnalyticsClient,
21
20
  ONBOARDING_EVENTS,
@@ -28,7 +27,6 @@ export {
28
27
  PAYWALL_SKIP_EVENT_CANDIDATES,
29
28
  PURCHASE_EVENTS,
30
29
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
31
- createAnalyticsContext,
32
30
  init,
33
31
  initAsync,
34
32
  initConsentFirst,
@@ -31,7 +31,6 @@ __export(react_native_exports, {
31
31
  PAYWALL_SKIP_EVENT_CANDIDATES: () => PAYWALL_SKIP_EVENT_CANDIDATES,
32
32
  PURCHASE_EVENTS: () => PURCHASE_EVENTS,
33
33
  PURCHASE_SUCCESS_EVENT_CANDIDATES: () => PURCHASE_SUCCESS_EVENT_CANDIDATES,
34
- createAnalyticsContext: () => createAnalyticsContext,
35
34
  init: () => init,
36
35
  initAsync: () => initAsync,
37
36
  initConsentFirst: () => initConsentFirst,
@@ -1121,20 +1120,25 @@ var AnalyticsClient = class {
1121
1120
  if (!this.consentGranted) {
1122
1121
  return;
1123
1122
  }
1123
+ const normalizedScreenName = this.normalizeScreenName(name);
1124
+ if (!normalizedScreenName) {
1125
+ this.log("Dropping screen event with invalid name", { name });
1126
+ return;
1127
+ }
1124
1128
  if (this.shouldDeferEventsUntilHydrated()) {
1125
1129
  const deferredProperties = this.cloneProperties(properties);
1126
1130
  this.deferEventUntilHydrated(() => {
1127
- this.screen(name, deferredProperties);
1131
+ this.screen(normalizedScreenName, deferredProperties);
1128
1132
  });
1129
1133
  return;
1130
1134
  }
1131
1135
  const sessionId = this.getSessionId();
1132
- if (this.shouldDropScreenView(name, properties, sessionId)) {
1136
+ if (this.shouldDropScreenView(normalizedScreenName, properties, sessionId)) {
1133
1137
  return;
1134
1138
  }
1135
1139
  this.enqueue({
1136
1140
  eventId: randomId(),
1137
- eventName: `screen:${name}`,
1141
+ eventName: `screen:${normalizedScreenName}`,
1138
1142
  ts: nowIso(),
1139
1143
  sessionId,
1140
1144
  anonId: this.anonId,
@@ -1639,6 +1643,20 @@ var AnalyticsClient = class {
1639
1643
  const resolvedScreenClass = screenClass ?? normalizedName;
1640
1644
  return `${normalizedName}|${resolvedScreenClass}`;
1641
1645
  }
1646
+ normalizeScreenName(name) {
1647
+ const trimmed = this.readRequiredStringOption(name);
1648
+ if (!trimmed) {
1649
+ return null;
1650
+ }
1651
+ const withoutEdgeSlashes = trimmed.replace(/^\/+|\/+$/g, "");
1652
+ const candidate = withoutEdgeSlashes || "root";
1653
+ const normalized = candidate.replace(/[^a-zA-Z0-9_:\-.]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
1654
+ if (!normalized) {
1655
+ return null;
1656
+ }
1657
+ const maxScreenNameLength = 100 - "screen:".length;
1658
+ return normalized.slice(0, maxScreenNameLength);
1659
+ }
1642
1660
  getOnboardingStepViewDedupeKey(properties) {
1643
1661
  if (!properties) {
1644
1662
  return null;
@@ -1804,7 +1822,6 @@ var AnalyticsClient = class {
1804
1822
  appBuild: this.context.appBuild,
1805
1823
  osName: this.context.osName,
1806
1824
  osVersion: this.context.osVersion,
1807
- country: this.context.country,
1808
1825
  region: this.context.region,
1809
1826
  city: this.context.city
1810
1827
  };
@@ -1857,78 +1874,8 @@ var AnalyticsClient = class {
1857
1874
  }
1858
1875
  };
1859
1876
 
1860
- // src/context.ts
1861
- var normalizeInitInput = (input) => {
1862
- if (typeof input === "string") {
1863
- return { apiKey: input };
1864
- }
1865
- if (input === null || input === void 0) {
1866
- return {};
1867
- }
1868
- return input;
1869
- };
1870
- var resolveClient = (input) => {
1871
- if (input instanceof AnalyticsClient) {
1872
- return input;
1873
- }
1874
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1875
- };
1876
- var createAnalyticsContext = (options = {}) => {
1877
- const client = resolveClient(options.client);
1878
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1879
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1880
- const consent = {
1881
- get: () => client.getConsent(),
1882
- getState: () => client.getConsentState(),
1883
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1884
- optIn: (setOptions) => client.optIn(setOptions),
1885
- optOut: (setOptions) => client.optOut(setOptions),
1886
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1887
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1888
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1889
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1890
- };
1891
- const user = {
1892
- identify: (userId, traits) => client.identify(userId, traits),
1893
- set: (userId, traits) => client.setUser(userId, traits),
1894
- clear: () => client.clearUser()
1895
- };
1896
- return {
1897
- client,
1898
- get onboarding() {
1899
- return onboardingTracker;
1900
- },
1901
- get paywall() {
1902
- return paywallTracker;
1903
- },
1904
- consent,
1905
- user,
1906
- track: (eventName, properties) => client.track(eventName, properties),
1907
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1908
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1909
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1910
- screen: (name, properties) => client.screen(name, properties),
1911
- page: (name, properties) => client.page(name, properties),
1912
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1913
- setContext: (context) => client.setContext(context),
1914
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1915
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1916
- configureOnboarding: (defaults) => {
1917
- onboardingTracker = client.createOnboardingTracker(defaults);
1918
- return onboardingTracker;
1919
- },
1920
- configurePaywall: (defaults) => {
1921
- paywallTracker = client.createPaywallTracker(defaults);
1922
- return paywallTracker;
1923
- },
1924
- ready: () => client.ready(),
1925
- flush: () => client.flush(),
1926
- shutdown: () => client.shutdown()
1927
- };
1928
- };
1929
-
1930
1877
  // src/index.ts
1931
- var normalizeInitInput2 = (input) => {
1878
+ var normalizeInitInput = (input) => {
1932
1879
  if (typeof input === "string") {
1933
1880
  return { apiKey: input };
1934
1881
  }
@@ -1938,17 +1885,17 @@ var normalizeInitInput2 = (input) => {
1938
1885
  return input;
1939
1886
  };
1940
1887
  var init = (input = {}) => {
1941
- return new AnalyticsClient(normalizeInitInput2(input));
1888
+ return new AnalyticsClient(normalizeInitInput(input));
1942
1889
  };
1943
1890
  var initConsentFirst = (input = {}) => {
1944
- const normalized = normalizeInitInput2(input);
1891
+ const normalized = normalizeInitInput(input);
1945
1892
  return new AnalyticsClient({
1946
1893
  ...normalized,
1947
1894
  initialConsentGranted: false
1948
1895
  });
1949
1896
  };
1950
1897
  var initAsync = async (input = {}) => {
1951
- const client = new AnalyticsClient(normalizeInitInput2(input));
1898
+ const client = new AnalyticsClient(normalizeInitInput(input));
1952
1899
  await client.ready();
1953
1900
  return client;
1954
1901
  };
@@ -1970,7 +1917,6 @@ var initConsentFirstAsync = async (input = {}) => {
1970
1917
  PAYWALL_SKIP_EVENT_CANDIDATES,
1971
1918
  PURCHASE_EVENTS,
1972
1919
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1973
- createAnalyticsContext,
1974
1920
  init,
1975
1921
  initAsync,
1976
1922
  initConsentFirst,
@@ -1 +1 @@
1
- export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsContext, AnalyticsContextConsentControls, AnalyticsContextUserControls, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, CreateAnalyticsContextOptions, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, createAnalyticsContext, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.cjs';
1
+ export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.cjs';
@@ -1 +1 @@
1
- export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsContext, AnalyticsContextConsentControls, AnalyticsContextUserControls, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, CreateAnalyticsContextOptions, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, createAnalyticsContext, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.js';
1
+ export { AnalyticsClient, AnalyticsClientOptions, AnalyticsConsentState, AnalyticsIngestError, AnalyticsIngestErrorHandler, AnalyticsStorageAdapter, EventContext, EventProperties, IdentityTrackingMode, InitInput, InitOptions, ONBOARDING_EVENTS, ONBOARDING_PROGRESS_EVENT_ORDER, ONBOARDING_SCREEN_EVENT_PREFIXES, ONBOARDING_SURVEY_EVENTS, OnboardingEventName, OnboardingEventProperties, OnboardingStepTracker, OnboardingSurveyAnswerType, OnboardingSurveyEventName, OnboardingSurveyResponseInput, OnboardingTracker, OnboardingTrackerDefaults, OnboardingTrackerSurveyInput, PAYWALL_ANCHOR_EVENT_CANDIDATES, PAYWALL_EVENTS, PAYWALL_JOURNEY_EVENT_ORDER, PAYWALL_SKIP_EVENT_CANDIDATES, PURCHASE_EVENTS, PURCHASE_SUCCESS_EVENT_CANDIDATES, PaywallEventName, PaywallEventProperties, PaywallJourneyEventName, PaywallTracker, PaywallTrackerDefaults, PaywallTrackerProperties, PurchaseEventName, SetConsentOptions, init, initAsync, initConsentFirst, initConsentFirstAsync } from './index.js';
@@ -10,12 +10,11 @@ import {
10
10
  PAYWALL_SKIP_EVENT_CANDIDATES,
11
11
  PURCHASE_EVENTS,
12
12
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
13
- createAnalyticsContext,
14
13
  init,
15
14
  initAsync,
16
15
  initConsentFirst,
17
16
  initConsentFirstAsync
18
- } from "./chunk-6EPJZLLK.js";
17
+ } from "./chunk-4DKQNTSO.js";
19
18
  export {
20
19
  AnalyticsClient,
21
20
  ONBOARDING_EVENTS,
@@ -28,7 +27,6 @@ export {
28
27
  PAYWALL_SKIP_EVENT_CANDIDATES,
29
28
  PURCHASE_EVENTS,
30
29
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
31
- createAnalyticsContext,
32
30
  init,
33
31
  initAsync,
34
32
  initConsentFirst,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analyticscli/sdk",
3
- "version": "0.1.0-preview.10",
3
+ "version": "0.1.0-preview.12",
4
4
  "description": "TypeScript SDK for sending onboarding, paywall, purchase and survey analytics events to AnalyticsCLI.",
5
5
  "license": "MIT",
6
6
  "type": "module",