@analyticscli/sdk 0.1.0-preview.11 → 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;
@@ -1856,78 +1874,8 @@ var AnalyticsClient = class {
1856
1874
  }
1857
1875
  };
1858
1876
 
1859
- // src/context.ts
1860
- var normalizeInitInput = (input) => {
1861
- if (typeof input === "string") {
1862
- return { apiKey: input };
1863
- }
1864
- if (input === null || input === void 0) {
1865
- return {};
1866
- }
1867
- return input;
1868
- };
1869
- var resolveClient = (input) => {
1870
- if (input instanceof AnalyticsClient) {
1871
- return input;
1872
- }
1873
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1874
- };
1875
- var createAnalyticsContext = (options = {}) => {
1876
- const client = resolveClient(options.client);
1877
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1878
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1879
- const consent = {
1880
- get: () => client.getConsent(),
1881
- getState: () => client.getConsentState(),
1882
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1883
- optIn: (setOptions) => client.optIn(setOptions),
1884
- optOut: (setOptions) => client.optOut(setOptions),
1885
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1886
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1887
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1888
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1889
- };
1890
- const user = {
1891
- identify: (userId, traits) => client.identify(userId, traits),
1892
- set: (userId, traits) => client.setUser(userId, traits),
1893
- clear: () => client.clearUser()
1894
- };
1895
- return {
1896
- client,
1897
- get onboarding() {
1898
- return onboardingTracker;
1899
- },
1900
- get paywall() {
1901
- return paywallTracker;
1902
- },
1903
- consent,
1904
- user,
1905
- track: (eventName, properties) => client.track(eventName, properties),
1906
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1907
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1908
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1909
- screen: (name, properties) => client.screen(name, properties),
1910
- page: (name, properties) => client.page(name, properties),
1911
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1912
- setContext: (context) => client.setContext(context),
1913
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1914
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1915
- configureOnboarding: (defaults) => {
1916
- onboardingTracker = client.createOnboardingTracker(defaults);
1917
- return onboardingTracker;
1918
- },
1919
- configurePaywall: (defaults) => {
1920
- paywallTracker = client.createPaywallTracker(defaults);
1921
- return paywallTracker;
1922
- },
1923
- ready: () => client.ready(),
1924
- flush: () => client.flush(),
1925
- shutdown: () => client.shutdown()
1926
- };
1927
- };
1928
-
1929
1877
  // src/index.ts
1930
- var normalizeInitInput2 = (input) => {
1878
+ var normalizeInitInput = (input) => {
1931
1879
  if (typeof input === "string") {
1932
1880
  return { apiKey: input };
1933
1881
  }
@@ -1937,17 +1885,17 @@ var normalizeInitInput2 = (input) => {
1937
1885
  return input;
1938
1886
  };
1939
1887
  var init = (input = {}) => {
1940
- return new AnalyticsClient(normalizeInitInput2(input));
1888
+ return new AnalyticsClient(normalizeInitInput(input));
1941
1889
  };
1942
1890
  var initConsentFirst = (input = {}) => {
1943
- const normalized = normalizeInitInput2(input);
1891
+ const normalized = normalizeInitInput(input);
1944
1892
  return new AnalyticsClient({
1945
1893
  ...normalized,
1946
1894
  initialConsentGranted: false
1947
1895
  });
1948
1896
  };
1949
1897
  var initAsync = async (input = {}) => {
1950
- const client = new AnalyticsClient(normalizeInitInput2(input));
1898
+ const client = new AnalyticsClient(normalizeInitInput(input));
1951
1899
  await client.ready();
1952
1900
  return client;
1953
1901
  };
@@ -1969,7 +1917,6 @@ var initConsentFirstAsync = async (input = {}) => {
1969
1917
  PAYWALL_SKIP_EVENT_CANDIDATES,
1970
1918
  PURCHASE_EVENTS,
1971
1919
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1972
- createAnalyticsContext,
1973
1920
  init,
1974
1921
  initAsync,
1975
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-LDRYFY5K.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;
@@ -1815,78 +1834,8 @@ var AnalyticsClient = class {
1815
1834
  }
1816
1835
  };
1817
1836
 
1818
- // src/context.ts
1819
- var normalizeInitInput = (input) => {
1820
- if (typeof input === "string") {
1821
- return { apiKey: input };
1822
- }
1823
- if (input === null || input === void 0) {
1824
- return {};
1825
- }
1826
- return input;
1827
- };
1828
- var resolveClient = (input) => {
1829
- if (input instanceof AnalyticsClient) {
1830
- return input;
1831
- }
1832
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1833
- };
1834
- var createAnalyticsContext = (options = {}) => {
1835
- const client = resolveClient(options.client);
1836
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1837
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1838
- const consent = {
1839
- get: () => client.getConsent(),
1840
- getState: () => client.getConsentState(),
1841
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1842
- optIn: (setOptions) => client.optIn(setOptions),
1843
- optOut: (setOptions) => client.optOut(setOptions),
1844
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1845
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1846
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1847
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1848
- };
1849
- const user = {
1850
- identify: (userId, traits) => client.identify(userId, traits),
1851
- set: (userId, traits) => client.setUser(userId, traits),
1852
- clear: () => client.clearUser()
1853
- };
1854
- return {
1855
- client,
1856
- get onboarding() {
1857
- return onboardingTracker;
1858
- },
1859
- get paywall() {
1860
- return paywallTracker;
1861
- },
1862
- consent,
1863
- user,
1864
- track: (eventName, properties) => client.track(eventName, properties),
1865
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1866
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1867
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1868
- screen: (name, properties) => client.screen(name, properties),
1869
- page: (name, properties) => client.page(name, properties),
1870
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1871
- setContext: (context) => client.setContext(context),
1872
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1873
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1874
- configureOnboarding: (defaults) => {
1875
- onboardingTracker = client.createOnboardingTracker(defaults);
1876
- return onboardingTracker;
1877
- },
1878
- configurePaywall: (defaults) => {
1879
- paywallTracker = client.createPaywallTracker(defaults);
1880
- return paywallTracker;
1881
- },
1882
- ready: () => client.ready(),
1883
- flush: () => client.flush(),
1884
- shutdown: () => client.shutdown()
1885
- };
1886
- };
1887
-
1888
1837
  // src/index.ts
1889
- var normalizeInitInput2 = (input) => {
1838
+ var normalizeInitInput = (input) => {
1890
1839
  if (typeof input === "string") {
1891
1840
  return { apiKey: input };
1892
1841
  }
@@ -1896,17 +1845,17 @@ var normalizeInitInput2 = (input) => {
1896
1845
  return input;
1897
1846
  };
1898
1847
  var init = (input = {}) => {
1899
- return new AnalyticsClient(normalizeInitInput2(input));
1848
+ return new AnalyticsClient(normalizeInitInput(input));
1900
1849
  };
1901
1850
  var initConsentFirst = (input = {}) => {
1902
- const normalized = normalizeInitInput2(input);
1851
+ const normalized = normalizeInitInput(input);
1903
1852
  return new AnalyticsClient({
1904
1853
  ...normalized,
1905
1854
  initialConsentGranted: false
1906
1855
  });
1907
1856
  };
1908
1857
  var initAsync = async (input = {}) => {
1909
- const client = new AnalyticsClient(normalizeInitInput2(input));
1858
+ const client = new AnalyticsClient(normalizeInitInput(input));
1910
1859
  await client.ready();
1911
1860
  return client;
1912
1861
  };
@@ -1928,7 +1877,6 @@ export {
1928
1877
  PAYWALL_SKIP_EVENT_CANDIDATES,
1929
1878
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1930
1879
  AnalyticsClient,
1931
- createAnalyticsContext,
1932
1880
  init,
1933
1881
  initConsentFirst,
1934
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;
@@ -1856,78 +1874,8 @@ var AnalyticsClient = class {
1856
1874
  }
1857
1875
  };
1858
1876
 
1859
- // src/context.ts
1860
- var normalizeInitInput = (input) => {
1861
- if (typeof input === "string") {
1862
- return { apiKey: input };
1863
- }
1864
- if (input === null || input === void 0) {
1865
- return {};
1866
- }
1867
- return input;
1868
- };
1869
- var resolveClient = (input) => {
1870
- if (input instanceof AnalyticsClient) {
1871
- return input;
1872
- }
1873
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1874
- };
1875
- var createAnalyticsContext = (options = {}) => {
1876
- const client = resolveClient(options.client);
1877
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1878
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1879
- const consent = {
1880
- get: () => client.getConsent(),
1881
- getState: () => client.getConsentState(),
1882
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1883
- optIn: (setOptions) => client.optIn(setOptions),
1884
- optOut: (setOptions) => client.optOut(setOptions),
1885
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1886
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1887
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1888
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1889
- };
1890
- const user = {
1891
- identify: (userId, traits) => client.identify(userId, traits),
1892
- set: (userId, traits) => client.setUser(userId, traits),
1893
- clear: () => client.clearUser()
1894
- };
1895
- return {
1896
- client,
1897
- get onboarding() {
1898
- return onboardingTracker;
1899
- },
1900
- get paywall() {
1901
- return paywallTracker;
1902
- },
1903
- consent,
1904
- user,
1905
- track: (eventName, properties) => client.track(eventName, properties),
1906
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1907
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1908
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1909
- screen: (name, properties) => client.screen(name, properties),
1910
- page: (name, properties) => client.page(name, properties),
1911
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1912
- setContext: (context) => client.setContext(context),
1913
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1914
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1915
- configureOnboarding: (defaults) => {
1916
- onboardingTracker = client.createOnboardingTracker(defaults);
1917
- return onboardingTracker;
1918
- },
1919
- configurePaywall: (defaults) => {
1920
- paywallTracker = client.createPaywallTracker(defaults);
1921
- return paywallTracker;
1922
- },
1923
- ready: () => client.ready(),
1924
- flush: () => client.flush(),
1925
- shutdown: () => client.shutdown()
1926
- };
1927
- };
1928
-
1929
1877
  // src/index.ts
1930
- var normalizeInitInput2 = (input) => {
1878
+ var normalizeInitInput = (input) => {
1931
1879
  if (typeof input === "string") {
1932
1880
  return { apiKey: input };
1933
1881
  }
@@ -1937,17 +1885,17 @@ var normalizeInitInput2 = (input) => {
1937
1885
  return input;
1938
1886
  };
1939
1887
  var init = (input = {}) => {
1940
- return new AnalyticsClient(normalizeInitInput2(input));
1888
+ return new AnalyticsClient(normalizeInitInput(input));
1941
1889
  };
1942
1890
  var initConsentFirst = (input = {}) => {
1943
- const normalized = normalizeInitInput2(input);
1891
+ const normalized = normalizeInitInput(input);
1944
1892
  return new AnalyticsClient({
1945
1893
  ...normalized,
1946
1894
  initialConsentGranted: false
1947
1895
  });
1948
1896
  };
1949
1897
  var initAsync = async (input = {}) => {
1950
- const client = new AnalyticsClient(normalizeInitInput2(input));
1898
+ const client = new AnalyticsClient(normalizeInitInput(input));
1951
1899
  await client.ready();
1952
1900
  return client;
1953
1901
  };
@@ -1969,7 +1917,6 @@ var initConsentFirstAsync = async (input = {}) => {
1969
1917
  PAYWALL_SKIP_EVENT_CANDIDATES,
1970
1918
  PURCHASE_EVENTS,
1971
1919
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1972
- createAnalyticsContext,
1973
1920
  init,
1974
1921
  initAsync,
1975
1922
  initConsentFirst,
package/dist/index.d.cts CHANGED
@@ -486,6 +486,7 @@ declare class AnalyticsClient {
486
486
  private shouldDropOnboardingStepView;
487
487
  private shouldDropScreenView;
488
488
  private getScreenViewDedupeKey;
489
+ private normalizeScreenName;
489
490
  private getOnboardingStepViewDedupeKey;
490
491
  private readPropertyAsString;
491
492
  private readPropertyAsStepIndex;
@@ -509,65 +510,6 @@ declare class AnalyticsClient {
509
510
  private reportMissingApiKey;
510
511
  }
511
512
 
512
- type ContextClientInput = InitInput | AnalyticsClient | null | undefined;
513
- type AnalyticsContextConsentControls = {
514
- get: () => boolean;
515
- getState: () => AnalyticsConsentState;
516
- set: (granted: boolean, options?: SetConsentOptions) => void;
517
- optIn: (options?: SetConsentOptions) => void;
518
- optOut: (options?: SetConsentOptions) => void;
519
- setFullTracking: (granted: boolean, options?: SetConsentOptions) => void;
520
- optInFullTracking: (options?: SetConsentOptions) => void;
521
- optOutFullTracking: (options?: SetConsentOptions) => void;
522
- isFullTrackingEnabled: () => boolean;
523
- };
524
- type AnalyticsContextUserControls = {
525
- identify: (userId: string, traits?: EventProperties) => void;
526
- set: (userId: string | null | undefined, traits?: EventProperties) => void;
527
- clear: () => void;
528
- };
529
- type AnalyticsContext = {
530
- client: AnalyticsClient;
531
- onboarding: OnboardingTracker;
532
- paywall: PaywallTracker | null;
533
- consent: AnalyticsContextConsentControls;
534
- user: AnalyticsContextUserControls;
535
- track: (eventName: string, properties?: EventProperties) => void;
536
- trackOnboardingEvent: (eventName: OnboardingEventName, properties?: OnboardingEventProperties) => void;
537
- trackOnboardingSurveyResponse: (input: OnboardingSurveyResponseInput, eventName?: OnboardingSurveyEventName) => void;
538
- trackPaywallEvent: (eventName: PaywallJourneyEventName, properties: PaywallEventProperties) => void;
539
- screen: (name: string, properties?: EventProperties) => void;
540
- page: (name: string, properties?: EventProperties) => void;
541
- feedback: (message: string, rating?: number, properties?: EventProperties) => void;
542
- setContext: (context: EventContext) => void;
543
- createOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
544
- createPaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
545
- configureOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
546
- configurePaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
547
- ready: () => Promise<void>;
548
- flush: () => Promise<void>;
549
- shutdown: () => void;
550
- };
551
- type CreateAnalyticsContextOptions = {
552
- /**
553
- * Either an existing client instance or standard `init(...)` input.
554
- */
555
- client?: ContextClientInput;
556
- /**
557
- * Defaults used for the exported `context.onboarding` tracker instance.
558
- */
559
- onboarding?: OnboardingTrackerDefaults | null;
560
- /**
561
- * Optional defaults used for the exported `context.paywall` tracker instance.
562
- */
563
- paywall?: PaywallTrackerDefaults | null;
564
- };
565
- /**
566
- * Host-app friendly SDK context with low boilerplate and rich defaults.
567
- * Provides pre-wired onboarding + consent/user controls and optional paywall tracker binding.
568
- */
569
- declare const createAnalyticsContext: (options?: CreateAnalyticsContextOptions) => AnalyticsContext;
570
-
571
513
  /**
572
514
  * Creates a browser analytics client instance.
573
515
  */
@@ -583,4 +525,4 @@ declare const initConsentFirst: (input?: InitInput) => AnalyticsClient;
583
525
  declare const initAsync: (input?: InitInput) => Promise<AnalyticsClient>;
584
526
  declare const initConsentFirstAsync: (input?: InitInput) => Promise<AnalyticsClient>;
585
527
 
586
- 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
@@ -486,6 +486,7 @@ declare class AnalyticsClient {
486
486
  private shouldDropOnboardingStepView;
487
487
  private shouldDropScreenView;
488
488
  private getScreenViewDedupeKey;
489
+ private normalizeScreenName;
489
490
  private getOnboardingStepViewDedupeKey;
490
491
  private readPropertyAsString;
491
492
  private readPropertyAsStepIndex;
@@ -509,65 +510,6 @@ declare class AnalyticsClient {
509
510
  private reportMissingApiKey;
510
511
  }
511
512
 
512
- type ContextClientInput = InitInput | AnalyticsClient | null | undefined;
513
- type AnalyticsContextConsentControls = {
514
- get: () => boolean;
515
- getState: () => AnalyticsConsentState;
516
- set: (granted: boolean, options?: SetConsentOptions) => void;
517
- optIn: (options?: SetConsentOptions) => void;
518
- optOut: (options?: SetConsentOptions) => void;
519
- setFullTracking: (granted: boolean, options?: SetConsentOptions) => void;
520
- optInFullTracking: (options?: SetConsentOptions) => void;
521
- optOutFullTracking: (options?: SetConsentOptions) => void;
522
- isFullTrackingEnabled: () => boolean;
523
- };
524
- type AnalyticsContextUserControls = {
525
- identify: (userId: string, traits?: EventProperties) => void;
526
- set: (userId: string | null | undefined, traits?: EventProperties) => void;
527
- clear: () => void;
528
- };
529
- type AnalyticsContext = {
530
- client: AnalyticsClient;
531
- onboarding: OnboardingTracker;
532
- paywall: PaywallTracker | null;
533
- consent: AnalyticsContextConsentControls;
534
- user: AnalyticsContextUserControls;
535
- track: (eventName: string, properties?: EventProperties) => void;
536
- trackOnboardingEvent: (eventName: OnboardingEventName, properties?: OnboardingEventProperties) => void;
537
- trackOnboardingSurveyResponse: (input: OnboardingSurveyResponseInput, eventName?: OnboardingSurveyEventName) => void;
538
- trackPaywallEvent: (eventName: PaywallJourneyEventName, properties: PaywallEventProperties) => void;
539
- screen: (name: string, properties?: EventProperties) => void;
540
- page: (name: string, properties?: EventProperties) => void;
541
- feedback: (message: string, rating?: number, properties?: EventProperties) => void;
542
- setContext: (context: EventContext) => void;
543
- createOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
544
- createPaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
545
- configureOnboarding: (defaults: OnboardingTrackerDefaults) => OnboardingTracker;
546
- configurePaywall: (defaults: PaywallTrackerDefaults) => PaywallTracker;
547
- ready: () => Promise<void>;
548
- flush: () => Promise<void>;
549
- shutdown: () => void;
550
- };
551
- type CreateAnalyticsContextOptions = {
552
- /**
553
- * Either an existing client instance or standard `init(...)` input.
554
- */
555
- client?: ContextClientInput;
556
- /**
557
- * Defaults used for the exported `context.onboarding` tracker instance.
558
- */
559
- onboarding?: OnboardingTrackerDefaults | null;
560
- /**
561
- * Optional defaults used for the exported `context.paywall` tracker instance.
562
- */
563
- paywall?: PaywallTrackerDefaults | null;
564
- };
565
- /**
566
- * Host-app friendly SDK context with low boilerplate and rich defaults.
567
- * Provides pre-wired onboarding + consent/user controls and optional paywall tracker binding.
568
- */
569
- declare const createAnalyticsContext: (options?: CreateAnalyticsContextOptions) => AnalyticsContext;
570
-
571
513
  /**
572
514
  * Creates a browser analytics client instance.
573
515
  */
@@ -583,4 +525,4 @@ declare const initConsentFirst: (input?: InitInput) => AnalyticsClient;
583
525
  declare const initAsync: (input?: InitInput) => Promise<AnalyticsClient>;
584
526
  declare const initConsentFirstAsync: (input?: InitInput) => Promise<AnalyticsClient>;
585
527
 
586
- 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-LDRYFY5K.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;
@@ -1856,78 +1874,8 @@ var AnalyticsClient = class {
1856
1874
  }
1857
1875
  };
1858
1876
 
1859
- // src/context.ts
1860
- var normalizeInitInput = (input) => {
1861
- if (typeof input === "string") {
1862
- return { apiKey: input };
1863
- }
1864
- if (input === null || input === void 0) {
1865
- return {};
1866
- }
1867
- return input;
1868
- };
1869
- var resolveClient = (input) => {
1870
- if (input instanceof AnalyticsClient) {
1871
- return input;
1872
- }
1873
- return new AnalyticsClient(normalizeInitInput(input ?? {}));
1874
- };
1875
- var createAnalyticsContext = (options = {}) => {
1876
- const client = resolveClient(options.client);
1877
- let onboardingTracker = client.createOnboardingTracker(options.onboarding ?? {});
1878
- let paywallTracker = options.paywall ? client.createPaywallTracker(options.paywall) : null;
1879
- const consent = {
1880
- get: () => client.getConsent(),
1881
- getState: () => client.getConsentState(),
1882
- set: (granted, setOptions) => client.setConsent(granted, setOptions),
1883
- optIn: (setOptions) => client.optIn(setOptions),
1884
- optOut: (setOptions) => client.optOut(setOptions),
1885
- setFullTracking: (granted, setOptions) => client.setFullTrackingConsent(granted, setOptions),
1886
- optInFullTracking: (setOptions) => client.optInFullTracking(setOptions),
1887
- optOutFullTracking: (setOptions) => client.optOutFullTracking(setOptions),
1888
- isFullTrackingEnabled: () => client.isFullTrackingEnabled()
1889
- };
1890
- const user = {
1891
- identify: (userId, traits) => client.identify(userId, traits),
1892
- set: (userId, traits) => client.setUser(userId, traits),
1893
- clear: () => client.clearUser()
1894
- };
1895
- return {
1896
- client,
1897
- get onboarding() {
1898
- return onboardingTracker;
1899
- },
1900
- get paywall() {
1901
- return paywallTracker;
1902
- },
1903
- consent,
1904
- user,
1905
- track: (eventName, properties) => client.track(eventName, properties),
1906
- trackOnboardingEvent: (eventName, properties) => client.trackOnboardingEvent(eventName, properties),
1907
- trackOnboardingSurveyResponse: (input, eventName) => client.trackOnboardingSurveyResponse(input, eventName),
1908
- trackPaywallEvent: (eventName, properties) => client.trackPaywallEvent(eventName, properties),
1909
- screen: (name, properties) => client.screen(name, properties),
1910
- page: (name, properties) => client.page(name, properties),
1911
- feedback: (message, rating, properties) => client.feedback(message, rating, properties),
1912
- setContext: (context) => client.setContext(context),
1913
- createOnboarding: (defaults) => client.createOnboardingTracker(defaults),
1914
- createPaywall: (defaults) => client.createPaywallTracker(defaults),
1915
- configureOnboarding: (defaults) => {
1916
- onboardingTracker = client.createOnboardingTracker(defaults);
1917
- return onboardingTracker;
1918
- },
1919
- configurePaywall: (defaults) => {
1920
- paywallTracker = client.createPaywallTracker(defaults);
1921
- return paywallTracker;
1922
- },
1923
- ready: () => client.ready(),
1924
- flush: () => client.flush(),
1925
- shutdown: () => client.shutdown()
1926
- };
1927
- };
1928
-
1929
1877
  // src/index.ts
1930
- var normalizeInitInput2 = (input) => {
1878
+ var normalizeInitInput = (input) => {
1931
1879
  if (typeof input === "string") {
1932
1880
  return { apiKey: input };
1933
1881
  }
@@ -1937,17 +1885,17 @@ var normalizeInitInput2 = (input) => {
1937
1885
  return input;
1938
1886
  };
1939
1887
  var init = (input = {}) => {
1940
- return new AnalyticsClient(normalizeInitInput2(input));
1888
+ return new AnalyticsClient(normalizeInitInput(input));
1941
1889
  };
1942
1890
  var initConsentFirst = (input = {}) => {
1943
- const normalized = normalizeInitInput2(input);
1891
+ const normalized = normalizeInitInput(input);
1944
1892
  return new AnalyticsClient({
1945
1893
  ...normalized,
1946
1894
  initialConsentGranted: false
1947
1895
  });
1948
1896
  };
1949
1897
  var initAsync = async (input = {}) => {
1950
- const client = new AnalyticsClient(normalizeInitInput2(input));
1898
+ const client = new AnalyticsClient(normalizeInitInput(input));
1951
1899
  await client.ready();
1952
1900
  return client;
1953
1901
  };
@@ -1969,7 +1917,6 @@ var initConsentFirstAsync = async (input = {}) => {
1969
1917
  PAYWALL_SKIP_EVENT_CANDIDATES,
1970
1918
  PURCHASE_EVENTS,
1971
1919
  PURCHASE_SUCCESS_EVENT_CANDIDATES,
1972
- createAnalyticsContext,
1973
1920
  init,
1974
1921
  initAsync,
1975
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-LDRYFY5K.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.11",
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",