@virex-tech/paywallo-sdk 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +192 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -428,11 +428,28 @@ function parseProperties(json) {
|
|
|
428
428
|
return {};
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
|
-
|
|
431
|
+
async function persistAnonIdDurably(storage, anonId) {
|
|
432
|
+
let stored = await storage.set(ANON_ID_KEY, anonId);
|
|
433
|
+
for (let i = 0; i < ANON_ID_SET_RETRIES && !stored; i++) {
|
|
434
|
+
await new Promise((r) => setTimeout(r, ANON_ID_RETRY_DELAY_MS));
|
|
435
|
+
stored = await storage.set(ANON_ID_KEY, anonId);
|
|
436
|
+
}
|
|
437
|
+
if (!stored) {
|
|
438
|
+
await nativeStorage.set(ANON_ID_FALLBACK_KEY, anonId).catch(() => void 0);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async function readAnonIdDurably(storage) {
|
|
442
|
+
const secure = await readWithMigration(storage, ANON_ID_KEY, LEGACY_ANON_ID_KEY);
|
|
443
|
+
if (secure) return secure;
|
|
444
|
+
return nativeStorage.get(ANON_ID_FALLBACK_KEY);
|
|
445
|
+
}
|
|
446
|
+
var DEVICE_ID_KEY, ANON_ID_FALLBACK_KEY, ANON_ID_KEY, USER_EMAIL_KEY, USER_PROPERTIES_KEY, USER_DISTINCT_ID_KEY, USER_NAME_KEY, USER_COUNTRY_KEY, USER_LOCALE_KEY, USER_PHONE_KEY, USER_FIRST_NAME_KEY, USER_LAST_NAME_KEY, USER_DOB_KEY, USER_GENDER_KEY, LEGACY_USER_PHONE_KEY, LEGACY_USER_FIRST_NAME_KEY, LEGACY_USER_LAST_NAME_KEY, LEGACY_USER_DOB_KEY, LEGACY_USER_GENDER_KEY, LEGACY_DEVICE_ID_KEY, LEGACY_ANON_ID_KEY, LEGACY_EMAIL_KEY, LEGACY_PROPERTIES_KEY, LEGACY_DISTINCT_ID_KEY, LEGACY_NAME_KEY, LEGACY_COUNTRY_KEY, LEGACY_LOCALE_KEY, ANON_ID_SET_RETRIES, ANON_ID_RETRY_DELAY_MS;
|
|
432
447
|
var init_IdentityStorage = __esm({
|
|
433
448
|
"src/domains/identity/IdentityStorage.ts"() {
|
|
434
449
|
"use strict";
|
|
450
|
+
init_NativeStorage();
|
|
435
451
|
DEVICE_ID_KEY = "@paywallo:device_id";
|
|
452
|
+
ANON_ID_FALLBACK_KEY = "@paywallo:anon_id_fallback";
|
|
436
453
|
ANON_ID_KEY = "@paywallo:anon_id";
|
|
437
454
|
USER_EMAIL_KEY = "@paywallo:user_email";
|
|
438
455
|
USER_PROPERTIES_KEY = "@paywallo:user_properties";
|
|
@@ -458,6 +475,8 @@ var init_IdentityStorage = __esm({
|
|
|
458
475
|
LEGACY_NAME_KEY = "user_name";
|
|
459
476
|
LEGACY_COUNTRY_KEY = "user_country";
|
|
460
477
|
LEGACY_LOCALE_KEY = "user_locale";
|
|
478
|
+
ANON_ID_SET_RETRIES = 2;
|
|
479
|
+
ANON_ID_RETRY_DELAY_MS = 50;
|
|
461
480
|
}
|
|
462
481
|
});
|
|
463
482
|
|
|
@@ -537,8 +556,7 @@ var init_IdentityManager = __esm({
|
|
|
537
556
|
}
|
|
538
557
|
if (!this.anonId) {
|
|
539
558
|
this.anonId = generateUUID();
|
|
540
|
-
await this.secureStorage
|
|
541
|
-
});
|
|
559
|
+
await persistAnonIdDurably(this.secureStorage, this.anonId);
|
|
542
560
|
}
|
|
543
561
|
this.initialized = true;
|
|
544
562
|
return this.deviceId ?? "";
|
|
@@ -598,7 +616,8 @@ var init_IdentityManager = __esm({
|
|
|
598
616
|
dateOfBirth: this.dateOfBirth ?? void 0,
|
|
599
617
|
gender: this.gender ?? void 0
|
|
600
618
|
});
|
|
601
|
-
} catch {
|
|
619
|
+
} catch (err) {
|
|
620
|
+
if (this.debug) console.log("[Paywallo] identify dispatch error", err);
|
|
602
621
|
}
|
|
603
622
|
}
|
|
604
623
|
}
|
|
@@ -622,7 +641,8 @@ var init_IdentityManager = __esm({
|
|
|
622
641
|
if (this.apiClient && this.anonId) {
|
|
623
642
|
try {
|
|
624
643
|
await this.apiClient.identify(this.anonId, this.properties, this.email ?? void 0, this.deviceId ?? void 0);
|
|
625
|
-
} catch {
|
|
644
|
+
} catch (err) {
|
|
645
|
+
if (this.debug) console.log("[Paywallo] identify dispatch error", err);
|
|
626
646
|
}
|
|
627
647
|
}
|
|
628
648
|
}
|
|
@@ -665,18 +685,20 @@ var init_IdentityManager = __esm({
|
|
|
665
685
|
}
|
|
666
686
|
async loadPersistedState() {
|
|
667
687
|
if (!this.secureStorage) return;
|
|
668
|
-
const state = await
|
|
688
|
+
const [state, rawAnonId] = await Promise.all([
|
|
689
|
+
loadPersistedIdentity(this.secureStorage),
|
|
690
|
+
readAnonIdDurably(this.secureStorage)
|
|
691
|
+
]);
|
|
669
692
|
const deviceId = state.deviceId ?? await readDeviceIdWithFallback(this.secureStorage);
|
|
670
693
|
if (deviceId) this.deviceId = deviceId;
|
|
671
|
-
if (
|
|
694
|
+
if (rawAnonId) {
|
|
672
695
|
const legacyPrefix = "$paywallo_anon:";
|
|
673
|
-
if (
|
|
674
|
-
const stripped =
|
|
696
|
+
if (rawAnonId.startsWith(legacyPrefix)) {
|
|
697
|
+
const stripped = rawAnonId.slice(legacyPrefix.length);
|
|
675
698
|
this.anonId = stripped;
|
|
676
|
-
await this.secureStorage.set(ANON_ID_KEY, stripped).catch(() =>
|
|
677
|
-
});
|
|
699
|
+
await this.secureStorage.set(ANON_ID_KEY, stripped).catch(() => void 0);
|
|
678
700
|
} else {
|
|
679
|
-
this.anonId =
|
|
701
|
+
this.anonId = rawAnonId;
|
|
680
702
|
}
|
|
681
703
|
}
|
|
682
704
|
if (state.email) this.email = state.email;
|
|
@@ -901,21 +923,23 @@ var init_AdvertisingIdManager = __esm({
|
|
|
901
923
|
if (import_react_native3.Platform.OS === "ios") {
|
|
902
924
|
if (!tracking.isAvailable()) {
|
|
903
925
|
const idfv2 = await this.collectIdfv();
|
|
904
|
-
|
|
905
|
-
|
|
926
|
+
const result2 = { ...fallback, idfv: idfv2 };
|
|
927
|
+
if (idfv2 !== null) this.cached = result2;
|
|
928
|
+
return result2;
|
|
906
929
|
}
|
|
907
930
|
const current = await tracking.getTrackingPermissionsAsync();
|
|
908
931
|
let status = current.status;
|
|
909
932
|
let granted = current.granted;
|
|
910
933
|
if (status === "undetermined" && requestATT) {
|
|
911
|
-
const
|
|
912
|
-
status =
|
|
913
|
-
granted =
|
|
934
|
+
const result2 = await tracking.requestTrackingPermissionsAsync();
|
|
935
|
+
status = result2.status;
|
|
936
|
+
granted = result2.granted;
|
|
914
937
|
}
|
|
915
938
|
const idfv = await this.collectIdfv();
|
|
916
939
|
const idfa = granted ? this.sanitizeId(tracking.getAdvertisingId()) : null;
|
|
917
|
-
|
|
918
|
-
|
|
940
|
+
const result = { idfv, idfa, gaid: null, attStatus: status };
|
|
941
|
+
if (idfv !== null) this.cached = result;
|
|
942
|
+
return result;
|
|
919
943
|
}
|
|
920
944
|
if (import_react_native3.Platform.OS === "android") {
|
|
921
945
|
const rawGaid = tracking.getAdvertisingId();
|
|
@@ -931,12 +955,20 @@ var init_AdvertisingIdManager = __esm({
|
|
|
931
955
|
}
|
|
932
956
|
}
|
|
933
957
|
async collectIdfv() {
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
958
|
+
const RETRY_DELAY_MS = 80;
|
|
959
|
+
const MAX_ATTEMPTS = 3;
|
|
960
|
+
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
961
|
+
try {
|
|
962
|
+
const info = await nativeDeviceInfo.getDeviceInfo();
|
|
963
|
+
const idfv = this.sanitizeId(info.idfv);
|
|
964
|
+
if (idfv !== null) return idfv;
|
|
965
|
+
} catch {
|
|
966
|
+
}
|
|
967
|
+
if (attempt < MAX_ATTEMPTS - 1) {
|
|
968
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));
|
|
969
|
+
}
|
|
939
970
|
}
|
|
971
|
+
return null;
|
|
940
972
|
}
|
|
941
973
|
sanitizeId(id) {
|
|
942
974
|
if (!id || id === ZERO_IDFA) return null;
|
|
@@ -1374,6 +1406,8 @@ var init_AttributionTracker = __esm({
|
|
|
1374
1406
|
|
|
1375
1407
|
// src/domains/identity/InstallIdempotency.ts
|
|
1376
1408
|
async function checkAndArmInstallGuard(storage) {
|
|
1409
|
+
if (armedThisLaunch) return true;
|
|
1410
|
+
armedThisLaunch = true;
|
|
1377
1411
|
const alreadyTracked = await storage.get(INSTALL_KEYS.INSTALL_TRACKED);
|
|
1378
1412
|
if (alreadyTracked) return true;
|
|
1379
1413
|
let fallbackTracked = null;
|
|
@@ -1407,7 +1441,7 @@ async function getOrCreateInstallEventId() {
|
|
|
1407
1441
|
});
|
|
1408
1442
|
return id;
|
|
1409
1443
|
}
|
|
1410
|
-
var INSTALL_KEYS;
|
|
1444
|
+
var INSTALL_KEYS, armedThisLaunch;
|
|
1411
1445
|
var init_InstallIdempotency = __esm({
|
|
1412
1446
|
"src/domains/identity/InstallIdempotency.ts"() {
|
|
1413
1447
|
"use strict";
|
|
@@ -1432,6 +1466,7 @@ var init_InstallIdempotency = __esm({
|
|
|
1432
1466
|
/** Legacy anon ID key written by SDK versions that used @panel: prefix. */
|
|
1433
1467
|
LEGACY_ANON_ID: "@panel:anon_id"
|
|
1434
1468
|
};
|
|
1469
|
+
armedThisLaunch = false;
|
|
1435
1470
|
}
|
|
1436
1471
|
});
|
|
1437
1472
|
|
|
@@ -2386,8 +2421,8 @@ var init_NotificationHandlerSetup = __esm({
|
|
|
2386
2421
|
// src/core/version.ts
|
|
2387
2422
|
function resolveVersion() {
|
|
2388
2423
|
try {
|
|
2389
|
-
if ("2.
|
|
2390
|
-
return "2.
|
|
2424
|
+
if ("2.4.0") {
|
|
2425
|
+
return "2.4.0";
|
|
2391
2426
|
}
|
|
2392
2427
|
} catch {
|
|
2393
2428
|
}
|
|
@@ -4249,10 +4284,10 @@ var init_OfflineQueueStorage = __esm({
|
|
|
4249
4284
|
init_NativeStorage();
|
|
4250
4285
|
init_QueueJournal();
|
|
4251
4286
|
OfflineQueueStorage = class {
|
|
4252
|
-
constructor(config, emit,
|
|
4287
|
+
constructor(config, emit, log3) {
|
|
4253
4288
|
this.config = config;
|
|
4254
4289
|
this.emit = emit;
|
|
4255
|
-
this.log =
|
|
4290
|
+
this.log = log3;
|
|
4256
4291
|
}
|
|
4257
4292
|
async loadFromStorage(queue) {
|
|
4258
4293
|
const { merged, recovered, hadJournal } = await mergeJournalIntoMain(
|
|
@@ -7937,7 +7972,36 @@ var init_http = __esm({
|
|
|
7937
7972
|
});
|
|
7938
7973
|
|
|
7939
7974
|
// src/core/ApiClient.ts
|
|
7940
|
-
|
|
7975
|
+
function normalizeDateOfBirth(raw) {
|
|
7976
|
+
if (!raw) return void 0;
|
|
7977
|
+
if (DATE_OF_BIRTH_RE.test(raw)) return raw;
|
|
7978
|
+
const d = new Date(raw);
|
|
7979
|
+
if (isNaN(d.getTime())) return void 0;
|
|
7980
|
+
const hasTimeComponent = raw.includes("T") || raw.includes("Z");
|
|
7981
|
+
const yyyy = hasTimeComponent ? d.getUTCFullYear() : d.getFullYear();
|
|
7982
|
+
const mm = String((hasTimeComponent ? d.getUTCMonth() : d.getMonth()) + 1).padStart(2, "0");
|
|
7983
|
+
const dd = String(hasTimeComponent ? d.getUTCDate() : d.getDate()).padStart(2, "0");
|
|
7984
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
7985
|
+
}
|
|
7986
|
+
function buildPiiPayload(pii) {
|
|
7987
|
+
const result = {};
|
|
7988
|
+
if (pii.phone) result.phone = pii.phone;
|
|
7989
|
+
if (pii.firstName) result.firstName = pii.firstName;
|
|
7990
|
+
if (pii.lastName) result.lastName = pii.lastName;
|
|
7991
|
+
const dob = normalizeDateOfBirth(pii.dateOfBirth);
|
|
7992
|
+
if (dob) result.dateOfBirth = dob;
|
|
7993
|
+
const g = normalizeGender(pii.gender);
|
|
7994
|
+
if (g) result.gender = g;
|
|
7995
|
+
return result;
|
|
7996
|
+
}
|
|
7997
|
+
function normalizeGender(raw) {
|
|
7998
|
+
if (!raw) return void 0;
|
|
7999
|
+
const lower = raw.toLowerCase();
|
|
8000
|
+
if (lower === "m" || lower === "male") return "m";
|
|
8001
|
+
if (lower === "f" || lower === "female") return "f";
|
|
8002
|
+
return void 0;
|
|
8003
|
+
}
|
|
8004
|
+
var import_react_native25, DATE_OF_BIRTH_RE, ApiClient;
|
|
7941
8005
|
var init_ApiClient = __esm({
|
|
7942
8006
|
"src/core/ApiClient.ts"() {
|
|
7943
8007
|
"use strict";
|
|
@@ -7951,6 +8015,7 @@ var init_ApiClient = __esm({
|
|
|
7951
8015
|
init_http();
|
|
7952
8016
|
init_queue();
|
|
7953
8017
|
init_version();
|
|
8018
|
+
DATE_OF_BIRTH_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
7954
8019
|
ApiClient = class {
|
|
7955
8020
|
constructor(appKey, apiUrl, debug = false, environment = "Production", offlineQueueEnabled = true, timeout = 3e4) {
|
|
7956
8021
|
this.cache = new ApiCache();
|
|
@@ -8125,11 +8190,7 @@ var init_ApiClient = __esm({
|
|
|
8125
8190
|
traits,
|
|
8126
8191
|
...attribution && { attribution },
|
|
8127
8192
|
...deviceId && { deviceId },
|
|
8128
|
-
...pii
|
|
8129
|
-
...pii?.firstName && { firstName: pii.firstName },
|
|
8130
|
-
...pii?.lastName && { lastName: pii.lastName },
|
|
8131
|
-
...pii?.dateOfBirth && { dateOfBirth: pii.dateOfBirth },
|
|
8132
|
-
...pii?.gender && { gender: pii.gender }
|
|
8193
|
+
...pii ? buildPiiPayload(pii) : {}
|
|
8133
8194
|
},
|
|
8134
8195
|
"identify"
|
|
8135
8196
|
);
|
|
@@ -9769,6 +9830,88 @@ init_paywall();
|
|
|
9769
9830
|
init_paywall();
|
|
9770
9831
|
init_paywall();
|
|
9771
9832
|
|
|
9833
|
+
// src/domains/paywall/SuperwallAttributeBridge.ts
|
|
9834
|
+
init_identity();
|
|
9835
|
+
var lastSignature = null;
|
|
9836
|
+
function log(debug, msg, data) {
|
|
9837
|
+
if (!debug) return;
|
|
9838
|
+
if (data !== void 0) console.log(`[Paywallo:SuperwallAttr] ${msg}`, data);
|
|
9839
|
+
else console.log(`[Paywallo:SuperwallAttr] ${msg}`);
|
|
9840
|
+
}
|
|
9841
|
+
var PAID_MEDIUM = /cpc|ppc|cpm|cpa|paid|display/i;
|
|
9842
|
+
function deriveIsPaid(a) {
|
|
9843
|
+
if (a.fbclid || a.gclid || a.ttclid || a.tiktokCampaignId) return true;
|
|
9844
|
+
return Boolean(a.utmMedium && PAID_MEDIUM.test(a.utmMedium));
|
|
9845
|
+
}
|
|
9846
|
+
function deriveAdNetwork(a) {
|
|
9847
|
+
if (a.fbclid) return "meta";
|
|
9848
|
+
if (a.ttclid || a.tiktokCampaignId) return "tiktok";
|
|
9849
|
+
if (a.gclid) return "google";
|
|
9850
|
+
return a.utmSource;
|
|
9851
|
+
}
|
|
9852
|
+
function buildSuperwallAttributes(a) {
|
|
9853
|
+
const out = {};
|
|
9854
|
+
if (!a) {
|
|
9855
|
+
out.pw_is_paid = false;
|
|
9856
|
+
return out;
|
|
9857
|
+
}
|
|
9858
|
+
const set2 = (key, value) => {
|
|
9859
|
+
if (value) out[key] = value;
|
|
9860
|
+
};
|
|
9861
|
+
set2("pw_utm_source", a.utmSource);
|
|
9862
|
+
set2("pw_utm_medium", a.utmMedium);
|
|
9863
|
+
set2("pw_utm_campaign", a.utmCampaign);
|
|
9864
|
+
set2("pw_utm_content", a.utmContent);
|
|
9865
|
+
set2("pw_utm_term", a.utmTerm);
|
|
9866
|
+
set2("pw_fbclid", a.fbclid);
|
|
9867
|
+
set2("pw_gclid", a.gclid);
|
|
9868
|
+
set2("pw_ttclid", a.ttclid);
|
|
9869
|
+
set2("pw_tiktok_campaign_id", a.tiktokCampaignId);
|
|
9870
|
+
set2("pw_tiktok_adgroup_id", a.tiktokAdgroupId);
|
|
9871
|
+
set2("pw_tiktok_ad_id", a.tiktokAdId);
|
|
9872
|
+
set2("pw_referrer", a.referrer);
|
|
9873
|
+
set2("pw_install_referrer_source", a.installReferrerSource);
|
|
9874
|
+
set2("pw_ad_network", deriveAdNetwork(a));
|
|
9875
|
+
out.pw_is_paid = deriveIsPaid(a);
|
|
9876
|
+
out.pw_attributed_at = a.capturedAt;
|
|
9877
|
+
return out;
|
|
9878
|
+
}
|
|
9879
|
+
function pickShared(mod) {
|
|
9880
|
+
const shared = mod?.default?.shared ?? mod?.shared;
|
|
9881
|
+
return shared && typeof shared.setUserAttributes === "function" ? shared : null;
|
|
9882
|
+
}
|
|
9883
|
+
async function resolveSuperwallShared(debug) {
|
|
9884
|
+
try {
|
|
9885
|
+
const shared = pickShared(await import("expo-superwall/compat"));
|
|
9886
|
+
if (shared) return shared;
|
|
9887
|
+
} catch {
|
|
9888
|
+
}
|
|
9889
|
+
try {
|
|
9890
|
+
const shared = pickShared(await import("expo-superwall"));
|
|
9891
|
+
if (shared) return shared;
|
|
9892
|
+
} catch {
|
|
9893
|
+
}
|
|
9894
|
+
log(debug, "expo-superwall not available \u2014 attribute push skipped");
|
|
9895
|
+
return null;
|
|
9896
|
+
}
|
|
9897
|
+
async function pushAttributionToSuperwall(debug = false) {
|
|
9898
|
+
const attrs = buildSuperwallAttributes(attributionTracker.get());
|
|
9899
|
+
const signature = JSON.stringify(attrs);
|
|
9900
|
+
if (signature === lastSignature) {
|
|
9901
|
+
log(debug, "attributes unchanged \u2014 skipping push");
|
|
9902
|
+
return;
|
|
9903
|
+
}
|
|
9904
|
+
const shared = await resolveSuperwallShared(debug);
|
|
9905
|
+
if (!shared) return;
|
|
9906
|
+
try {
|
|
9907
|
+
await shared.setUserAttributes(attrs);
|
|
9908
|
+
lastSignature = signature;
|
|
9909
|
+
log(debug, "attributes pushed to Superwall", attrs);
|
|
9910
|
+
} catch (err) {
|
|
9911
|
+
log(debug, "setUserAttributes error", { err: String(err) });
|
|
9912
|
+
}
|
|
9913
|
+
}
|
|
9914
|
+
|
|
9772
9915
|
// src/domains/paywall/SuperwallAutoBridge.ts
|
|
9773
9916
|
init_PaywalloClient();
|
|
9774
9917
|
|
|
@@ -9802,7 +9945,7 @@ function buildDeterministicEventId(parts) {
|
|
|
9802
9945
|
var bridgeStarted = false;
|
|
9803
9946
|
var unsubscribe = null;
|
|
9804
9947
|
var debugEnabled = false;
|
|
9805
|
-
function
|
|
9948
|
+
function log2(msg, data) {
|
|
9806
9949
|
if (!debugEnabled) return;
|
|
9807
9950
|
if (data !== void 0) {
|
|
9808
9951
|
console.log(`[Paywallo:SuperwallBridge] ${msg}`, data);
|
|
@@ -9832,7 +9975,7 @@ async function trackPaywallEvent(type, identifier, ts, extra) {
|
|
|
9832
9975
|
}
|
|
9833
9976
|
});
|
|
9834
9977
|
} catch (err) {
|
|
9835
|
-
|
|
9978
|
+
log2("track error", { type, identifier, eventId: _eventId, err: String(err) });
|
|
9836
9979
|
}
|
|
9837
9980
|
}
|
|
9838
9981
|
function mapDismissToCloseReason(resultType) {
|
|
@@ -9852,7 +9995,7 @@ function buildCallbacks() {
|
|
|
9852
9995
|
return {
|
|
9853
9996
|
onPaywallPresent: (info) => {
|
|
9854
9997
|
const ts = Date.now();
|
|
9855
|
-
|
|
9998
|
+
log2("onPaywallPresent", { identifier: info.identifier });
|
|
9856
9999
|
void trackPaywallEvent("viewed", info.identifier, ts, {
|
|
9857
10000
|
placement: info.presentedByEventWithName,
|
|
9858
10001
|
variant_id: info.experiment?.variant?.id,
|
|
@@ -9861,7 +10004,7 @@ function buildCallbacks() {
|
|
|
9861
10004
|
},
|
|
9862
10005
|
onPaywallDismiss: (info, result) => {
|
|
9863
10006
|
const ts = Date.now();
|
|
9864
|
-
|
|
10007
|
+
log2("onPaywallDismiss", { identifier: info.identifier, result: result.type });
|
|
9865
10008
|
void trackPaywallEvent("closed", info.identifier, ts, {
|
|
9866
10009
|
placement: info.presentedByEventWithName,
|
|
9867
10010
|
variant_id: info.experiment?.variant?.id,
|
|
@@ -9875,7 +10018,7 @@ function buildCallbacks() {
|
|
|
9875
10018
|
const safe = params !== null && typeof params === "object" ? params : {};
|
|
9876
10019
|
const productId = "productId" in safe && typeof safe.productId === "string" ? safe.productId : "unknown";
|
|
9877
10020
|
const identifier = "paywallIdentifier" in safe && typeof safe.paywallIdentifier === "string" ? safe.paywallIdentifier : productId;
|
|
9878
|
-
|
|
10021
|
+
log2("onPurchase", { productId, identifier });
|
|
9879
10022
|
void trackPaywallEvent("purchased", identifier, ts, { product_id: productId });
|
|
9880
10023
|
},
|
|
9881
10024
|
// Global Superwall event listener — used specifically for `transactionComplete`
|
|
@@ -9890,7 +10033,7 @@ function buildCallbacks() {
|
|
|
9890
10033
|
const product = ev.product;
|
|
9891
10034
|
const transaction = ev.transaction;
|
|
9892
10035
|
if (!product) {
|
|
9893
|
-
|
|
10036
|
+
log2("transactionComplete missing product \u2014 skipping transaction track");
|
|
9894
10037
|
return;
|
|
9895
10038
|
}
|
|
9896
10039
|
const productId = product.productIdentifier ?? product.id ?? "unknown";
|
|
@@ -9899,7 +10042,7 @@ function buildCallbacks() {
|
|
|
9899
10042
|
const transactionId = transaction?.storeTransactionId ?? transaction?.originalTransactionIdentifier ?? `${productId}_${String(ts)}`;
|
|
9900
10043
|
const isTrial = product.hasFreeTrial === true || (product.trialPeriodPrice ?? 0) > 0;
|
|
9901
10044
|
const paywallIdentifier = ev.paywallInfo?.identifier;
|
|
9902
|
-
|
|
10045
|
+
log2("onSuperwallEvent: transactionComplete", { productId, currency, price, transactionId, isTrial });
|
|
9903
10046
|
void (async () => {
|
|
9904
10047
|
try {
|
|
9905
10048
|
await PaywalloClient.track("transaction", {
|
|
@@ -9917,7 +10060,7 @@ function buildCallbacks() {
|
|
|
9917
10060
|
}
|
|
9918
10061
|
});
|
|
9919
10062
|
} catch (err) {
|
|
9920
|
-
|
|
10063
|
+
log2("transactionComplete track error", { err: String(err) });
|
|
9921
10064
|
}
|
|
9922
10065
|
})();
|
|
9923
10066
|
}
|
|
@@ -9926,7 +10069,7 @@ function buildCallbacks() {
|
|
|
9926
10069
|
function startSuperwallAutoBridge(debug = false) {
|
|
9927
10070
|
debugEnabled = debug;
|
|
9928
10071
|
if (bridgeStarted) {
|
|
9929
|
-
|
|
10072
|
+
log2("already started, skipping");
|
|
9930
10073
|
return;
|
|
9931
10074
|
}
|
|
9932
10075
|
void detectAndStart();
|
|
@@ -9938,7 +10081,7 @@ async function detectAndStart() {
|
|
|
9938
10081
|
if (!mod || typeof mod.subscribeToSuperwallEvents !== "function") {
|
|
9939
10082
|
const internal = await import("expo-superwall/build/src/internal/superwallEventBridge");
|
|
9940
10083
|
if (typeof internal.subscribeToSuperwallEvents !== "function") {
|
|
9941
|
-
|
|
10084
|
+
log2("expo-superwall subscribeToSuperwallEvents not found \u2014 bridge inactive");
|
|
9942
10085
|
return;
|
|
9943
10086
|
}
|
|
9944
10087
|
subscribeFn = internal.subscribeToSuperwallEvents;
|
|
@@ -9946,16 +10089,16 @@ async function detectAndStart() {
|
|
|
9946
10089
|
subscribeFn = mod.subscribeToSuperwallEvents;
|
|
9947
10090
|
}
|
|
9948
10091
|
} catch {
|
|
9949
|
-
|
|
10092
|
+
log2("expo-superwall not installed \u2014 bridge inactive");
|
|
9950
10093
|
return;
|
|
9951
10094
|
}
|
|
9952
10095
|
try {
|
|
9953
10096
|
const callbacks = buildCallbacks();
|
|
9954
10097
|
unsubscribe = subscribeFn(void 0, () => callbacks);
|
|
9955
10098
|
bridgeStarted = true;
|
|
9956
|
-
|
|
10099
|
+
log2("bridge started");
|
|
9957
10100
|
} catch (err) {
|
|
9958
|
-
|
|
10101
|
+
log2("subscribe failed", { err: String(err) });
|
|
9959
10102
|
}
|
|
9960
10103
|
}
|
|
9961
10104
|
|
|
@@ -10528,6 +10671,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10528
10671
|
if (!mounted) return;
|
|
10529
10672
|
setDistinctId(PaywalloClient.getDistinctId());
|
|
10530
10673
|
startSuperwallAutoBridge(configRef.current.debug);
|
|
10674
|
+
void pushAttributionToSuperwall(configRef.current.debug);
|
|
10531
10675
|
setIsInitialized(true);
|
|
10532
10676
|
if (!autoPreloadTriggeredRef.current) {
|
|
10533
10677
|
autoPreloadTriggeredRef.current = true;
|