@analyticscli/sdk 0.1.0-preview.4 → 0.1.0-preview.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +162 -39
- package/dist/browser.cjs +266 -46
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +5 -1
- package/dist/{chunk-UILQQPVJ.js → chunk-HL2VOD3Z.js} +264 -46
- package/dist/index.cjs +266 -46
- package/dist/index.d.cts +142 -56
- package/dist/index.d.ts +142 -56
- package/dist/index.js +5 -1
- package/dist/react-native.cjs +266 -46
- package/dist/react-native.d.cts +1 -1
- package/dist/react-native.d.ts +1 -1
- package/dist/react-native.js +5 -1
- package/package.json +1 -1
- package/dist/chunk-CY4KHPLT.js +0 -1455
- package/dist/chunk-NC6ANZ4H.js +0 -1455
- package/dist/chunk-W4RJPJLF.js +0 -1426
- package/dist/chunk-ZIOGPQNP.js +0 -1478
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,8 @@ __export(index_exports, {
|
|
|
37
37
|
init: () => init,
|
|
38
38
|
initAsync: () => initAsync,
|
|
39
39
|
initBrowserFromEnv: () => initBrowserFromEnv,
|
|
40
|
+
initConsentFirst: () => initConsentFirst,
|
|
41
|
+
initConsentFirstAsync: () => initConsentFirstAsync,
|
|
40
42
|
initFromEnv: () => initFromEnv,
|
|
41
43
|
initReactNativeFromEnv: () => initReactNativeFromEnv
|
|
42
44
|
});
|
|
@@ -137,6 +139,9 @@ var validateEvent = (event, index) => {
|
|
|
137
139
|
if (!isOptionalStringMax(event.platform, 64)) {
|
|
138
140
|
return { success: false, reason: `events[${index}].platform is invalid` };
|
|
139
141
|
}
|
|
142
|
+
if (!isOptionalStringMax(event.projectSurface, 64)) {
|
|
143
|
+
return { success: false, reason: `events[${index}].projectSurface is invalid` };
|
|
144
|
+
}
|
|
140
145
|
if (!isOptionalStringMax(event.appVersion, 64)) {
|
|
141
146
|
return { success: false, reason: `events[${index}].appVersion is invalid` };
|
|
142
147
|
}
|
|
@@ -565,6 +570,7 @@ var sanitizeSurveyResponseInput = (input) => {
|
|
|
565
570
|
};
|
|
566
571
|
|
|
567
572
|
// src/analytics-client.ts
|
|
573
|
+
var DEFAULT_CONSENT_STORAGE_KEY = "analyticscli:consent:v1";
|
|
568
574
|
var AnalyticsClient = class {
|
|
569
575
|
apiKey;
|
|
570
576
|
hasIngestConfig;
|
|
@@ -574,10 +580,17 @@ var AnalyticsClient = class {
|
|
|
574
580
|
maxRetries;
|
|
575
581
|
debug;
|
|
576
582
|
platform;
|
|
583
|
+
projectSurface;
|
|
577
584
|
appVersion;
|
|
585
|
+
identityTrackingMode;
|
|
578
586
|
context;
|
|
587
|
+
configuredStorage;
|
|
579
588
|
storage;
|
|
580
589
|
storageReadsAreAsync;
|
|
590
|
+
persistConsentState;
|
|
591
|
+
consentStorageKey;
|
|
592
|
+
hasExplicitInitialConsent;
|
|
593
|
+
hasExplicitInitialFullTrackingConsent;
|
|
581
594
|
sessionTimeoutMs;
|
|
582
595
|
dedupeOnboardingStepViewsPerSession;
|
|
583
596
|
runtimeEnv;
|
|
@@ -588,6 +601,7 @@ var AnalyticsClient = class {
|
|
|
588
601
|
flushTimer = null;
|
|
589
602
|
isFlushing = false;
|
|
590
603
|
consentGranted = true;
|
|
604
|
+
fullTrackingConsentGranted = false;
|
|
591
605
|
userId = null;
|
|
592
606
|
anonId;
|
|
593
607
|
sessionId;
|
|
@@ -610,34 +624,46 @@ var AnalyticsClient = class {
|
|
|
610
624
|
this.maxRetries = normalizedOptions.maxRetries ?? 4;
|
|
611
625
|
this.debug = normalizedOptions.debug ?? false;
|
|
612
626
|
this.platform = this.normalizePlatformOption(normalizedOptions.platform) ?? detectDefaultPlatform();
|
|
627
|
+
this.projectSurface = this.normalizeProjectSurfaceOption(normalizedOptions.projectSurface);
|
|
613
628
|
this.appVersion = this.readRequiredStringOption(normalizedOptions.appVersion) || detectDefaultAppVersion();
|
|
629
|
+
this.identityTrackingMode = this.resolveIdentityTrackingModeOption(normalizedOptions);
|
|
614
630
|
this.context = { ...normalizedOptions.context ?? {} };
|
|
615
631
|
this.runtimeEnv = detectRuntimeEnv();
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
normalizedOptions.cookieMaxAgeSeconds ?? DEFAULT_COOKIE_MAX_AGE_SECONDS
|
|
621
|
-
);
|
|
622
|
-
const browserStorage = resolveBrowserStorageAdapter();
|
|
623
|
-
this.storage = normalizedOptions.storage ?? (cookieStorage && browserStorage ? combineStorageAdapters(cookieStorage, browserStorage) : cookieStorage ?? browserStorage);
|
|
624
|
-
this.storageReadsAreAsync = this.detectAsyncStorageReads();
|
|
632
|
+
this.persistConsentState = normalizedOptions.persistConsentState ?? false;
|
|
633
|
+
this.consentStorageKey = this.readRequiredStringOption(normalizedOptions.consentStorageKey) || DEFAULT_CONSENT_STORAGE_KEY;
|
|
634
|
+
this.hasExplicitInitialConsent = typeof normalizedOptions.initialConsentGranted === "boolean";
|
|
635
|
+
this.hasExplicitInitialFullTrackingConsent = typeof normalizedOptions.initialFullTrackingConsentGranted === "boolean";
|
|
625
636
|
this.sessionTimeoutMs = normalizedOptions.sessionTimeoutMs ?? DEFAULT_SESSION_TIMEOUT_MS;
|
|
626
|
-
this.dedupeOnboardingStepViewsPerSession = normalizedOptions.dedupeOnboardingStepViewsPerSession ??
|
|
627
|
-
|
|
628
|
-
const
|
|
637
|
+
this.dedupeOnboardingStepViewsPerSession = normalizedOptions.dedupeOnboardingStepViewsPerSession ?? true;
|
|
638
|
+
this.configuredStorage = this.resolveConfiguredStorage(normalizedOptions);
|
|
639
|
+
const persistedFullTrackingConsent = this.readPersistedConsentSync(this.configuredStorage);
|
|
640
|
+
const configuredFullTrackingConsent = normalizedOptions.initialFullTrackingConsentGranted;
|
|
641
|
+
const initialFullTrackingConsentGranted = typeof configuredFullTrackingConsent === "boolean" ? configuredFullTrackingConsent : persistedFullTrackingConsent ?? false;
|
|
642
|
+
this.fullTrackingConsentGranted = this.identityTrackingMode === "always_on" || initialFullTrackingConsentGranted;
|
|
643
|
+
this.storage = this.isFullTrackingActive() ? this.configuredStorage : null;
|
|
644
|
+
this.storageReadsAreAsync = this.detectAsyncStorageReads();
|
|
645
|
+
const providedAnonId = this.isFullTrackingActive() ? this.readRequiredStringOption(normalizedOptions.anonId) : "";
|
|
646
|
+
const providedSessionId = this.isFullTrackingActive() ? this.readRequiredStringOption(normalizedOptions.sessionId) : "";
|
|
629
647
|
this.hasExplicitAnonId = Boolean(providedAnonId);
|
|
630
648
|
this.hasExplicitSessionId = Boolean(providedSessionId);
|
|
631
649
|
this.anonId = providedAnonId || this.ensureDeviceId();
|
|
632
650
|
this.sessionId = providedSessionId || this.ensureSessionId();
|
|
633
651
|
this.sessionEventSeq = this.readSessionEventSeq(this.sessionId);
|
|
634
|
-
|
|
652
|
+
const persistedConsent = this.readPersistedConsentSync(this.storage);
|
|
653
|
+
const configuredConsent = normalizedOptions.initialConsentGranted;
|
|
654
|
+
const initialConsentGranted = typeof configuredConsent === "boolean" ? configuredConsent : persistedConsent ?? this.hasIngestConfig;
|
|
655
|
+
this.consentGranted = this.hasIngestConfig && initialConsentGranted;
|
|
656
|
+
if (this.hasExplicitInitialConsent && this.persistConsentState) {
|
|
657
|
+
this.writePersistedConsent(this.storage, this.consentGranted);
|
|
658
|
+
}
|
|
659
|
+
if (this.hasExplicitInitialFullTrackingConsent && this.persistConsentState) {
|
|
660
|
+
this.writePersistedConsent(this.configuredStorage, this.fullTrackingConsentGranted);
|
|
661
|
+
}
|
|
635
662
|
this.hydrationPromise = this.hydrateIdentityFromStorage();
|
|
636
663
|
this.startAutoFlush();
|
|
637
664
|
}
|
|
638
665
|
/**
|
|
639
|
-
* Resolves once
|
|
640
|
-
* Useful in React Native when using async persistence (for example AsyncStorage).
|
|
666
|
+
* Resolves once client initialization work completes.
|
|
641
667
|
*/
|
|
642
668
|
async ready() {
|
|
643
669
|
await this.hydrationPromise;
|
|
@@ -646,22 +672,41 @@ var AnalyticsClient = class {
|
|
|
646
672
|
* Enables or disables event collection.
|
|
647
673
|
* When disabled, queued events are dropped immediately.
|
|
648
674
|
*/
|
|
649
|
-
setConsent(granted) {
|
|
675
|
+
setConsent(granted, options = {}) {
|
|
650
676
|
if (granted && !this.hasIngestConfig) {
|
|
651
677
|
this.log("Ignoring consent opt-in because `apiKey` is missing");
|
|
652
678
|
return;
|
|
653
679
|
}
|
|
654
680
|
this.consentGranted = granted;
|
|
681
|
+
if ((options.persist ?? true) && this.persistConsentState) {
|
|
682
|
+
this.writePersistedConsent(this.storage, granted);
|
|
683
|
+
}
|
|
684
|
+
if (this.identityTrackingMode === "consent_gated") {
|
|
685
|
+
this.setFullTrackingConsent(granted, options);
|
|
686
|
+
}
|
|
655
687
|
if (!granted) {
|
|
656
688
|
this.queue = [];
|
|
657
689
|
this.deferredEventsBeforeHydration = [];
|
|
658
690
|
}
|
|
659
691
|
}
|
|
660
|
-
optIn() {
|
|
661
|
-
this.setConsent(true);
|
|
692
|
+
optIn(options) {
|
|
693
|
+
this.setConsent(true, options);
|
|
662
694
|
}
|
|
663
|
-
optOut() {
|
|
664
|
-
this.setConsent(false);
|
|
695
|
+
optOut(options) {
|
|
696
|
+
this.setConsent(false, options);
|
|
697
|
+
}
|
|
698
|
+
getConsent() {
|
|
699
|
+
return this.consentGranted;
|
|
700
|
+
}
|
|
701
|
+
getConsentState() {
|
|
702
|
+
const persisted = this.readPersistedConsentSync(this.storage);
|
|
703
|
+
if (persisted === true) {
|
|
704
|
+
return "granted";
|
|
705
|
+
}
|
|
706
|
+
if (persisted === false) {
|
|
707
|
+
return "denied";
|
|
708
|
+
}
|
|
709
|
+
return this.consentGranted ? "granted" : "unknown";
|
|
665
710
|
}
|
|
666
711
|
/**
|
|
667
712
|
* Sets or updates shared event context fields (useful for mobile device/app metadata).
|
|
@@ -677,22 +722,25 @@ var AnalyticsClient = class {
|
|
|
677
722
|
* Anonymous history remains linked by anonId/sessionId.
|
|
678
723
|
*/
|
|
679
724
|
identify(userId, traits) {
|
|
680
|
-
if (!this.consentGranted) {
|
|
681
|
-
return;
|
|
682
|
-
}
|
|
683
725
|
const normalizedUserId = this.readRequiredStringOption(userId);
|
|
684
726
|
if (!normalizedUserId) {
|
|
685
|
-
this.log("Dropping identify call without required `userId`");
|
|
686
727
|
return;
|
|
687
728
|
}
|
|
729
|
+
if (!this.isFullTrackingActive()) {
|
|
730
|
+
this.log("Ignoring identify() because identity persistence is not enabled");
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
this.userId = normalizedUserId;
|
|
734
|
+
if (!this.consentGranted) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const normalizedTraits = this.cloneProperties(traits);
|
|
688
738
|
if (this.shouldDeferEventsUntilHydrated()) {
|
|
689
|
-
const deferredTraits = this.cloneProperties(traits);
|
|
690
739
|
this.deferEventUntilHydrated(() => {
|
|
691
|
-
this.identify(normalizedUserId,
|
|
740
|
+
this.identify(normalizedUserId, normalizedTraits);
|
|
692
741
|
});
|
|
693
742
|
return;
|
|
694
743
|
}
|
|
695
|
-
this.userId = normalizedUserId;
|
|
696
744
|
const sessionId = this.getSessionId();
|
|
697
745
|
this.enqueue({
|
|
698
746
|
eventId: randomId(),
|
|
@@ -701,8 +749,9 @@ var AnalyticsClient = class {
|
|
|
701
749
|
sessionId,
|
|
702
750
|
anonId: this.anonId,
|
|
703
751
|
userId: normalizedUserId,
|
|
704
|
-
properties: this.withRuntimeMetadata(
|
|
752
|
+
properties: this.withRuntimeMetadata(normalizedTraits, sessionId),
|
|
705
753
|
platform: this.platform,
|
|
754
|
+
projectSurface: this.projectSurface,
|
|
706
755
|
appVersion: this.appVersion,
|
|
707
756
|
...this.withEventContext(),
|
|
708
757
|
type: "identify"
|
|
@@ -714,13 +763,39 @@ var AnalyticsClient = class {
|
|
|
714
763
|
* - pass null/undefined/empty string to clear user linkage
|
|
715
764
|
*/
|
|
716
765
|
setUser(userId, traits) {
|
|
717
|
-
const normalizedUserId =
|
|
766
|
+
const normalizedUserId = this.readRequiredStringOption(userId);
|
|
718
767
|
if (!normalizedUserId) {
|
|
719
768
|
this.clearUser();
|
|
720
769
|
return;
|
|
721
770
|
}
|
|
722
771
|
this.identify(normalizedUserId, traits);
|
|
723
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Sets consent specifically for persistent identity tracking.
|
|
775
|
+
* In `consent_gated` mode this toggles strict-vs-full identity behavior while generic event tracking can stay enabled.
|
|
776
|
+
*/
|
|
777
|
+
setFullTrackingConsent(granted, options = {}) {
|
|
778
|
+
if (this.identityTrackingMode === "strict") {
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
if (this.identityTrackingMode === "always_on") {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
this.fullTrackingConsentGranted = granted;
|
|
785
|
+
if ((options.persist ?? true) && this.persistConsentState) {
|
|
786
|
+
this.writePersistedConsent(this.configuredStorage, granted);
|
|
787
|
+
}
|
|
788
|
+
this.applyIdentityTrackingState();
|
|
789
|
+
}
|
|
790
|
+
optInFullTracking(options) {
|
|
791
|
+
this.setFullTrackingConsent(true, options);
|
|
792
|
+
}
|
|
793
|
+
optOutFullTracking(options) {
|
|
794
|
+
this.setFullTrackingConsent(false, options);
|
|
795
|
+
}
|
|
796
|
+
isFullTrackingEnabled() {
|
|
797
|
+
return this.isFullTrackingActive();
|
|
798
|
+
}
|
|
724
799
|
/**
|
|
725
800
|
* Clears the current identified user from in-memory SDK state.
|
|
726
801
|
*/
|
|
@@ -751,9 +826,10 @@ var AnalyticsClient = class {
|
|
|
751
826
|
ts: nowIso(),
|
|
752
827
|
sessionId,
|
|
753
828
|
anonId: this.anonId,
|
|
754
|
-
userId: this.
|
|
829
|
+
userId: this.getEventUserId(),
|
|
755
830
|
properties: this.withRuntimeMetadata(properties, sessionId),
|
|
756
831
|
platform: this.platform,
|
|
832
|
+
projectSurface: this.projectSurface,
|
|
757
833
|
appVersion: this.appVersion,
|
|
758
834
|
...this.withEventContext(),
|
|
759
835
|
type: "track"
|
|
@@ -850,6 +926,8 @@ var AnalyticsClient = class {
|
|
|
850
926
|
/**
|
|
851
927
|
* Creates a scoped paywall tracker that applies shared paywall defaults to every journey event.
|
|
852
928
|
* Useful when a flow has a stable `source`, `paywallId`, `offering`, or experiment metadata.
|
|
929
|
+
* Reuse the returned tracker for that flow context; creating a new tracker per event resets
|
|
930
|
+
* paywall entry correlation.
|
|
853
931
|
*/
|
|
854
932
|
createPaywallTracker(defaults) {
|
|
855
933
|
const { source: rawDefaultSource, ...defaultProperties } = defaults;
|
|
@@ -953,9 +1031,10 @@ var AnalyticsClient = class {
|
|
|
953
1031
|
ts: nowIso(),
|
|
954
1032
|
sessionId,
|
|
955
1033
|
anonId: this.anonId,
|
|
956
|
-
userId: this.
|
|
1034
|
+
userId: this.getEventUserId(),
|
|
957
1035
|
properties: this.withRuntimeMetadata(properties, sessionId),
|
|
958
1036
|
platform: this.platform,
|
|
1037
|
+
projectSurface: this.projectSurface,
|
|
959
1038
|
appVersion: this.appVersion,
|
|
960
1039
|
...this.withEventContext(),
|
|
961
1040
|
type: "screen"
|
|
@@ -988,9 +1067,10 @@ var AnalyticsClient = class {
|
|
|
988
1067
|
ts: nowIso(),
|
|
989
1068
|
sessionId,
|
|
990
1069
|
anonId: this.anonId,
|
|
991
|
-
userId: this.
|
|
1070
|
+
userId: this.getEventUserId(),
|
|
992
1071
|
properties: this.withRuntimeMetadata({ message, rating, ...properties }, sessionId),
|
|
993
1072
|
platform: this.platform,
|
|
1073
|
+
projectSurface: this.projectSurface,
|
|
994
1074
|
appVersion: this.appVersion,
|
|
995
1075
|
...this.withEventContext(),
|
|
996
1076
|
type: "feedback"
|
|
@@ -1078,6 +1158,36 @@ var AnalyticsClient = class {
|
|
|
1078
1158
|
}
|
|
1079
1159
|
}
|
|
1080
1160
|
}
|
|
1161
|
+
parsePersistedConsent(raw) {
|
|
1162
|
+
if (raw === "granted") {
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
if (raw === "denied") {
|
|
1166
|
+
return false;
|
|
1167
|
+
}
|
|
1168
|
+
return null;
|
|
1169
|
+
}
|
|
1170
|
+
readPersistedConsentSync(storage) {
|
|
1171
|
+
if (!this.persistConsentState) {
|
|
1172
|
+
return null;
|
|
1173
|
+
}
|
|
1174
|
+
if (storage === this.storage && this.storageReadsAreAsync) {
|
|
1175
|
+
return null;
|
|
1176
|
+
}
|
|
1177
|
+
return this.parsePersistedConsent(readStorageSync(storage, this.consentStorageKey));
|
|
1178
|
+
}
|
|
1179
|
+
async readPersistedConsentAsync(storage) {
|
|
1180
|
+
if (!this.persistConsentState) {
|
|
1181
|
+
return null;
|
|
1182
|
+
}
|
|
1183
|
+
return this.parsePersistedConsent(await readStorageAsync(storage, this.consentStorageKey));
|
|
1184
|
+
}
|
|
1185
|
+
writePersistedConsent(storage, granted) {
|
|
1186
|
+
if (!this.persistConsentState) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
writeStorageSync(storage, this.consentStorageKey, granted ? "granted" : "denied");
|
|
1190
|
+
}
|
|
1081
1191
|
startAutoFlush() {
|
|
1082
1192
|
if (!this.hasIngestConfig) {
|
|
1083
1193
|
return;
|
|
@@ -1169,10 +1279,11 @@ var AnalyticsClient = class {
|
|
|
1169
1279
|
return;
|
|
1170
1280
|
}
|
|
1171
1281
|
try {
|
|
1172
|
-
const [storedAnonId, storedSessionId, storedLastSeen] = await Promise.all([
|
|
1282
|
+
const [storedAnonId, storedSessionId, storedLastSeen, storedConsent] = await Promise.all([
|
|
1173
1283
|
readStorageAsync(this.storage, DEVICE_ID_KEY),
|
|
1174
1284
|
readStorageAsync(this.storage, SESSION_ID_KEY),
|
|
1175
|
-
readStorageAsync(this.storage, LAST_SEEN_KEY)
|
|
1285
|
+
readStorageAsync(this.storage, LAST_SEEN_KEY),
|
|
1286
|
+
this.readPersistedConsentAsync(this.storage)
|
|
1176
1287
|
]);
|
|
1177
1288
|
if (!this.hasExplicitAnonId && storedAnonId) {
|
|
1178
1289
|
this.anonId = storedAnonId;
|
|
@@ -1184,6 +1295,13 @@ var AnalyticsClient = class {
|
|
|
1184
1295
|
this.inMemoryLastSeenMs = Date.now();
|
|
1185
1296
|
}
|
|
1186
1297
|
}
|
|
1298
|
+
if (!this.hasExplicitInitialConsent && typeof storedConsent === "boolean") {
|
|
1299
|
+
this.consentGranted = this.hasIngestConfig && storedConsent;
|
|
1300
|
+
if (!this.consentGranted) {
|
|
1301
|
+
this.queue = [];
|
|
1302
|
+
this.deferredEventsBeforeHydration = [];
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1187
1305
|
this.sessionEventSeq = await this.readSessionEventSeqAsync(this.sessionId);
|
|
1188
1306
|
await this.hydrateOnboardingStepViewState(this.sessionId);
|
|
1189
1307
|
writeStorageSync(this.storage, DEVICE_ID_KEY, this.anonId);
|
|
@@ -1352,6 +1470,81 @@ var AnalyticsClient = class {
|
|
|
1352
1470
|
return null;
|
|
1353
1471
|
}
|
|
1354
1472
|
}
|
|
1473
|
+
resolveIdentityTrackingModeOption(options) {
|
|
1474
|
+
const explicitMode = this.readRequiredStringOption(options.identityTrackingMode).toLowerCase();
|
|
1475
|
+
if (explicitMode === "strict") {
|
|
1476
|
+
return "strict";
|
|
1477
|
+
}
|
|
1478
|
+
if (explicitMode === "consent_gated") {
|
|
1479
|
+
return "consent_gated";
|
|
1480
|
+
}
|
|
1481
|
+
if (explicitMode === "always_on") {
|
|
1482
|
+
return "always_on";
|
|
1483
|
+
}
|
|
1484
|
+
if (options.enableFullTrackingWithoutConsent === true) {
|
|
1485
|
+
return "always_on";
|
|
1486
|
+
}
|
|
1487
|
+
return "consent_gated";
|
|
1488
|
+
}
|
|
1489
|
+
resolveConfiguredStorage(options) {
|
|
1490
|
+
if (this.identityTrackingMode === "strict") {
|
|
1491
|
+
if (options.storage || options.useCookieStorage || options.cookieDomain) {
|
|
1492
|
+
this.log("Ignoring storage/cookie configuration because identityTrackingMode=strict");
|
|
1493
|
+
}
|
|
1494
|
+
return null;
|
|
1495
|
+
}
|
|
1496
|
+
const customStorage = options.storage ?? null;
|
|
1497
|
+
const browserStorage = resolveBrowserStorageAdapter();
|
|
1498
|
+
const primaryStorage = customStorage ?? browserStorage;
|
|
1499
|
+
const cookieStorage = resolveCookieStorageAdapter(
|
|
1500
|
+
options.useCookieStorage === true,
|
|
1501
|
+
this.readRequiredStringOption(options.cookieDomain) || void 0,
|
|
1502
|
+
this.normalizeCookieMaxAgeSeconds(options.cookieMaxAgeSeconds)
|
|
1503
|
+
);
|
|
1504
|
+
if (primaryStorage && cookieStorage) {
|
|
1505
|
+
return combineStorageAdapters(primaryStorage, cookieStorage);
|
|
1506
|
+
}
|
|
1507
|
+
return primaryStorage ?? cookieStorage;
|
|
1508
|
+
}
|
|
1509
|
+
normalizeCookieMaxAgeSeconds(value) {
|
|
1510
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
1511
|
+
return DEFAULT_COOKIE_MAX_AGE_SECONDS;
|
|
1512
|
+
}
|
|
1513
|
+
return Math.floor(value);
|
|
1514
|
+
}
|
|
1515
|
+
isFullTrackingActive() {
|
|
1516
|
+
if (!this.hasIngestConfig) {
|
|
1517
|
+
return false;
|
|
1518
|
+
}
|
|
1519
|
+
if (this.identityTrackingMode === "always_on") {
|
|
1520
|
+
return true;
|
|
1521
|
+
}
|
|
1522
|
+
if (this.identityTrackingMode === "strict") {
|
|
1523
|
+
return false;
|
|
1524
|
+
}
|
|
1525
|
+
return this.fullTrackingConsentGranted;
|
|
1526
|
+
}
|
|
1527
|
+
applyIdentityTrackingState() {
|
|
1528
|
+
if (!this.isFullTrackingActive()) {
|
|
1529
|
+
this.storage = null;
|
|
1530
|
+
this.storageReadsAreAsync = false;
|
|
1531
|
+
this.userId = null;
|
|
1532
|
+
return;
|
|
1533
|
+
}
|
|
1534
|
+
this.storage = this.configuredStorage;
|
|
1535
|
+
this.storageReadsAreAsync = this.detectAsyncStorageReads();
|
|
1536
|
+
this.sessionId = this.ensureSessionId();
|
|
1537
|
+
this.sessionEventSeq = this.readSessionEventSeq(this.sessionId);
|
|
1538
|
+
writeStorageSync(this.storage, DEVICE_ID_KEY, this.anonId);
|
|
1539
|
+
writeStorageSync(this.storage, SESSION_ID_KEY, this.sessionId);
|
|
1540
|
+
writeStorageSync(this.storage, LAST_SEEN_KEY, String(this.inMemoryLastSeenMs));
|
|
1541
|
+
}
|
|
1542
|
+
getEventUserId() {
|
|
1543
|
+
if (!this.isFullTrackingActive()) {
|
|
1544
|
+
return null;
|
|
1545
|
+
}
|
|
1546
|
+
return this.userId;
|
|
1547
|
+
}
|
|
1355
1548
|
withEventContext() {
|
|
1356
1549
|
return {
|
|
1357
1550
|
appBuild: this.context.appBuild,
|
|
@@ -1387,6 +1580,16 @@ var AnalyticsClient = class {
|
|
|
1387
1580
|
}
|
|
1388
1581
|
return void 0;
|
|
1389
1582
|
}
|
|
1583
|
+
normalizeProjectSurfaceOption(value) {
|
|
1584
|
+
const normalized = this.readRequiredStringOption(value).toLowerCase();
|
|
1585
|
+
if (!normalized) {
|
|
1586
|
+
return void 0;
|
|
1587
|
+
}
|
|
1588
|
+
if (normalized.length > 64) {
|
|
1589
|
+
return normalized.slice(0, 64);
|
|
1590
|
+
}
|
|
1591
|
+
return normalized;
|
|
1592
|
+
}
|
|
1390
1593
|
log(message, data) {
|
|
1391
1594
|
if (!this.debug) {
|
|
1392
1595
|
return;
|
|
@@ -1395,17 +1598,17 @@ var AnalyticsClient = class {
|
|
|
1395
1598
|
}
|
|
1396
1599
|
reportMissingApiKey() {
|
|
1397
1600
|
console.error(
|
|
1398
|
-
"[analyticscli-sdk] Missing required `apiKey`. Tracking is disabled (safe no-op). Pass your
|
|
1601
|
+
"[analyticscli-sdk] Missing required `apiKey`. Tracking is disabled (safe no-op). Pass your publishable API key."
|
|
1399
1602
|
);
|
|
1400
1603
|
}
|
|
1401
1604
|
};
|
|
1402
1605
|
|
|
1403
1606
|
// src/bootstrap.ts
|
|
1404
1607
|
var DEFAULT_API_KEY_ENV_KEYS = [
|
|
1405
|
-
"
|
|
1406
|
-
"
|
|
1407
|
-
"
|
|
1408
|
-
"
|
|
1608
|
+
"ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1609
|
+
"NEXT_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1610
|
+
"EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1611
|
+
"VITE_ANALYTICSCLI_PUBLISHABLE_API_KEY"
|
|
1409
1612
|
];
|
|
1410
1613
|
var readTrimmedString2 = (value) => {
|
|
1411
1614
|
if (typeof value === "string") {
|
|
@@ -1472,26 +1675,41 @@ var normalizeInitInput = (input) => {
|
|
|
1472
1675
|
if (typeof input === "string") {
|
|
1473
1676
|
return { apiKey: input };
|
|
1474
1677
|
}
|
|
1678
|
+
if (input === null || input === void 0) {
|
|
1679
|
+
return {};
|
|
1680
|
+
}
|
|
1475
1681
|
return input;
|
|
1476
1682
|
};
|
|
1477
1683
|
var init = (input = {}) => {
|
|
1478
1684
|
return new AnalyticsClient(normalizeInitInput(input));
|
|
1479
1685
|
};
|
|
1686
|
+
var initConsentFirst = (input = {}) => {
|
|
1687
|
+
const normalized = normalizeInitInput(input);
|
|
1688
|
+
return new AnalyticsClient({
|
|
1689
|
+
...normalized,
|
|
1690
|
+
initialConsentGranted: false
|
|
1691
|
+
});
|
|
1692
|
+
};
|
|
1480
1693
|
var initAsync = async (input = {}) => {
|
|
1481
1694
|
const client = new AnalyticsClient(normalizeInitInput(input));
|
|
1482
1695
|
await client.ready();
|
|
1483
1696
|
return client;
|
|
1484
1697
|
};
|
|
1698
|
+
var initConsentFirstAsync = async (input = {}) => {
|
|
1699
|
+
const client = initConsentFirst(input);
|
|
1700
|
+
await client.ready();
|
|
1701
|
+
return client;
|
|
1702
|
+
};
|
|
1485
1703
|
var BROWSER_API_KEY_ENV_KEYS = [
|
|
1486
|
-
"
|
|
1487
|
-
"
|
|
1488
|
-
"
|
|
1489
|
-
"
|
|
1490
|
-
"
|
|
1704
|
+
"ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1705
|
+
"NEXT_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1706
|
+
"PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1707
|
+
"VITE_ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1708
|
+
"EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY"
|
|
1491
1709
|
];
|
|
1492
1710
|
var REACT_NATIVE_API_KEY_ENV_KEYS = [
|
|
1493
|
-
"
|
|
1494
|
-
"
|
|
1711
|
+
"ANALYTICSCLI_PUBLISHABLE_API_KEY",
|
|
1712
|
+
"EXPO_PUBLIC_ANALYTICSCLI_PUBLISHABLE_API_KEY"
|
|
1495
1713
|
];
|
|
1496
1714
|
var initBrowserFromEnv = (options = {}) => {
|
|
1497
1715
|
const { apiKeyEnvKeys, ...rest } = options;
|
|
@@ -1526,6 +1744,8 @@ var initReactNativeFromEnv = (options = {}) => {
|
|
|
1526
1744
|
init,
|
|
1527
1745
|
initAsync,
|
|
1528
1746
|
initBrowserFromEnv,
|
|
1747
|
+
initConsentFirst,
|
|
1748
|
+
initConsentFirstAsync,
|
|
1529
1749
|
initFromEnv,
|
|
1530
1750
|
initReactNativeFromEnv
|
|
1531
1751
|
});
|