@virex-tech/paywallo-sdk 2.2.3 → 2.2.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/android/build.gradle +5 -3
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloFirebaseMessagingService.kt +33 -5
- package/android/src/main/java/com/paywallo/sdk/PaywalloNotificationsModule.kt +47 -30
- package/android/src/main/java/com/paywallo/sdk/PaywalloStoreKitModule.kt +7 -3
- package/android/src/main/java/com/paywallo/sdk/PaywalloWebViewEvent.kt +4 -2
- package/dist/index.d.mts +74 -9
- package/dist/index.d.ts +74 -9
- package/dist/index.js +306 -193
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +325 -210
- package/dist/index.mjs.map +1 -1
- package/ios/PaywalloWebView.m +5 -0
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1067,7 +1067,7 @@ var init_sessionTracking = __esm({
|
|
|
1067
1067
|
});
|
|
1068
1068
|
|
|
1069
1069
|
// src/domains/session/SessionManager.ts
|
|
1070
|
-
var import_react_native4, SESSION_ID_KEY, SESSION_START_KEY,
|
|
1070
|
+
var import_react_native4, SESSION_ID_KEY, SESSION_START_KEY, LEGACY_SESSION_ID_KEY, LEGACY_SESSION_START_KEY, SESSION_TIMEOUT_MS, SessionManager, sessionManager;
|
|
1071
1071
|
var init_SessionManager = __esm({
|
|
1072
1072
|
"src/domains/session/SessionManager.ts"() {
|
|
1073
1073
|
"use strict";
|
|
@@ -1079,11 +1079,9 @@ var init_SessionManager = __esm({
|
|
|
1079
1079
|
init_sessionTracking();
|
|
1080
1080
|
SESSION_ID_KEY = "@paywallo:current_session_id";
|
|
1081
1081
|
SESSION_START_KEY = "@paywallo:session_start";
|
|
1082
|
-
EMERGENCY_PAYWALL_SHOWN_KEY = "@paywallo:emergency_paywall_shown";
|
|
1083
1082
|
LEGACY_SESSION_ID_KEY = "current_session_id";
|
|
1084
1083
|
LEGACY_SESSION_START_KEY = "session_start";
|
|
1085
1084
|
SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
1086
|
-
BACKGROUND_FLUSH_TIMEOUT_MS = 2e3;
|
|
1087
1085
|
SessionManager = class {
|
|
1088
1086
|
constructor() {
|
|
1089
1087
|
this.sessionId = null;
|
|
@@ -1145,8 +1143,7 @@ var init_SessionManager = __esm({
|
|
|
1145
1143
|
this.emergencyPaywallShownInSession = false;
|
|
1146
1144
|
await Promise.all([
|
|
1147
1145
|
this.secureStorage.set(SESSION_ID_KEY, this.sessionId),
|
|
1148
|
-
this.secureStorage.set(SESSION_START_KEY, this.sessionStartedAt.toISOString())
|
|
1149
|
-
this.secureStorage.remove(EMERGENCY_PAYWALL_SHOWN_KEY)
|
|
1146
|
+
this.secureStorage.set(SESSION_START_KEY, this.sessionStartedAt.toISOString())
|
|
1150
1147
|
]);
|
|
1151
1148
|
await this.trackSessionStart();
|
|
1152
1149
|
return this.sessionId;
|
|
@@ -1156,10 +1153,10 @@ var init_SessionManager = __esm({
|
|
|
1156
1153
|
if (!this.sessionId || !this.sessionStartedAt) {
|
|
1157
1154
|
return;
|
|
1158
1155
|
}
|
|
1156
|
+
await this.trackSessionEnd();
|
|
1159
1157
|
if (this.apiClient) {
|
|
1160
1158
|
await this.apiClient.flushEventBatch();
|
|
1161
1159
|
}
|
|
1162
|
-
await this.trackSessionEnd();
|
|
1163
1160
|
this.sessionId = null;
|
|
1164
1161
|
this.sessionStartedAt = null;
|
|
1165
1162
|
await Promise.all([
|
|
@@ -1244,7 +1241,6 @@ var init_SessionManager = __esm({
|
|
|
1244
1241
|
async handleBackground() {
|
|
1245
1242
|
this.backgroundTimestamp = Date.now();
|
|
1246
1243
|
await this.trackAppBackground();
|
|
1247
|
-
await this.flushEventsWithTimeout(BACKGROUND_FLUSH_TIMEOUT_MS);
|
|
1248
1244
|
await this.endSession();
|
|
1249
1245
|
}
|
|
1250
1246
|
async flushEventsWithTimeout(timeoutMs) {
|
|
@@ -1263,7 +1259,6 @@ var init_SessionManager = __esm({
|
|
|
1263
1259
|
const response = await this.apiClient.getEmergencyPaywall().catch(() => null);
|
|
1264
1260
|
if (response?.enabled && response.paywallId) {
|
|
1265
1261
|
this.emergencyPaywallShownInSession = true;
|
|
1266
|
-
await this.secureStorage.set(EMERGENCY_PAYWALL_SHOWN_KEY, "true");
|
|
1267
1262
|
await this.emergencyPaywallHandler(response.paywallId);
|
|
1268
1263
|
}
|
|
1269
1264
|
}
|
|
@@ -1563,7 +1558,7 @@ var init_MetaBridge = __esm({
|
|
|
1563
1558
|
try {
|
|
1564
1559
|
await NativeBridge.logEvent(name, params);
|
|
1565
1560
|
} catch (error) {
|
|
1566
|
-
|
|
1561
|
+
console.error("[Paywallo:MetaBridge] logEvent failed", { name, error });
|
|
1567
1562
|
}
|
|
1568
1563
|
}
|
|
1569
1564
|
async logPurchase(amount, currency, params = {}) {
|
|
@@ -1571,7 +1566,7 @@ var init_MetaBridge = __esm({
|
|
|
1571
1566
|
try {
|
|
1572
1567
|
await NativeBridge.logPurchase(amount, currency, params);
|
|
1573
1568
|
} catch (error) {
|
|
1574
|
-
|
|
1569
|
+
console.error("[Paywallo:MetaBridge] logPurchase failed", { amount, currency, error });
|
|
1575
1570
|
}
|
|
1576
1571
|
}
|
|
1577
1572
|
setUserID(userId) {
|
|
@@ -1579,7 +1574,7 @@ var init_MetaBridge = __esm({
|
|
|
1579
1574
|
try {
|
|
1580
1575
|
NativeBridge.setUserID(userId);
|
|
1581
1576
|
} catch (error) {
|
|
1582
|
-
|
|
1577
|
+
console.error("[Paywallo:MetaBridge] setUserID failed", { error });
|
|
1583
1578
|
}
|
|
1584
1579
|
}
|
|
1585
1580
|
flush() {
|
|
@@ -1587,7 +1582,7 @@ var init_MetaBridge = __esm({
|
|
|
1587
1582
|
try {
|
|
1588
1583
|
NativeBridge.flush();
|
|
1589
1584
|
} catch (error) {
|
|
1590
|
-
|
|
1585
|
+
console.error("[Paywallo:MetaBridge] flush failed", { error });
|
|
1591
1586
|
}
|
|
1592
1587
|
}
|
|
1593
1588
|
};
|
|
@@ -1803,7 +1798,7 @@ var init_InstallTracker = __esm({
|
|
|
1803
1798
|
screenWidth: deviceData.screenWidth,
|
|
1804
1799
|
screenHeight: deviceData.screenHeight,
|
|
1805
1800
|
timezone: deviceData.timezone,
|
|
1806
|
-
|
|
1801
|
+
language: deviceData.locale,
|
|
1807
1802
|
fbAnonId: anonId,
|
|
1808
1803
|
installTimestamp: new Date(installedAt).toISOString()
|
|
1809
1804
|
}),
|
|
@@ -2029,13 +2024,21 @@ var init_NativePushBridge = __esm({
|
|
|
2029
2024
|
if (!raw || typeof raw !== "object") return null;
|
|
2030
2025
|
const r = raw;
|
|
2031
2026
|
const notification = r["notification"];
|
|
2027
|
+
const asString = (v) => typeof v === "string" ? v : void 0;
|
|
2032
2028
|
return {
|
|
2033
|
-
messageId:
|
|
2029
|
+
messageId: asString(r["messageId"]),
|
|
2034
2030
|
data: typeof r["data"] === "object" && r["data"] !== null ? r["data"] : void 0,
|
|
2035
2031
|
notification: notification && typeof notification === "object" ? {
|
|
2036
|
-
title:
|
|
2037
|
-
body:
|
|
2032
|
+
title: asString(notification["title"]),
|
|
2033
|
+
body: asString(notification["body"]),
|
|
2034
|
+
imageUrl: asString(notification["imageUrl"])
|
|
2038
2035
|
} : void 0,
|
|
2036
|
+
// Pass through top-level title/body/imageUrl emitted by the native modules
|
|
2037
|
+
// (both iOS and Android currently emit these at the top level rather than
|
|
2038
|
+
// nested under `notification`).
|
|
2039
|
+
title: asString(r["title"]),
|
|
2040
|
+
body: asString(r["body"]),
|
|
2041
|
+
imageUrl: asString(r["imageUrl"]),
|
|
2039
2042
|
sentTime: typeof r["sentTime"] === "number" ? r["sentTime"] : void 0
|
|
2040
2043
|
};
|
|
2041
2044
|
} catch {
|
|
@@ -2174,10 +2177,11 @@ function setupForegroundHandler(deps, onReceive) {
|
|
|
2174
2177
|
const data = message.data ?? {};
|
|
2175
2178
|
const payload = extractPayload({
|
|
2176
2179
|
...data,
|
|
2177
|
-
title: data["title"] ?? message.notification?.title ?? "",
|
|
2178
|
-
body: data["body"] ?? message.notification?.body ?? ""
|
|
2180
|
+
title: data["title"] ?? message.notification?.title ?? message.title ?? "",
|
|
2181
|
+
body: data["body"] ?? message.notification?.body ?? message.body ?? "",
|
|
2182
|
+
imageUrl: data["imageUrl"] ?? message.notification?.imageUrl ?? message.imageUrl
|
|
2179
2183
|
});
|
|
2180
|
-
if (debug) console.
|
|
2184
|
+
if (debug) console.log("[Paywallo PUSH] foreground message received:", payload.notificationId);
|
|
2181
2185
|
onReceive(payload);
|
|
2182
2186
|
const messageId = message.messageId ?? payload.notificationId;
|
|
2183
2187
|
await tracker.track("notification_delivered", {
|
|
@@ -2207,14 +2211,21 @@ function getTimezone() {
|
|
|
2207
2211
|
function detectPlatform() {
|
|
2208
2212
|
return import_react_native10.Platform.OS === "ios" ? "ios" : "android";
|
|
2209
2213
|
}
|
|
2210
|
-
var import_react_native10, SEEN_MESSAGES_KEY, SEEN_TTL_MS, MAX_SEEN_SIZE, NotificationEventTracker;
|
|
2214
|
+
var import_react_native10, SEEN_MESSAGES_KEY, LEGACY_SEEN_MESSAGES_KEY, SEEN_TTL_MS, MAX_SEEN_SIZE, NOTIFICATION_TYPE_TO_FAMILY, NotificationEventTracker;
|
|
2211
2215
|
var init_NotificationEventTracker = __esm({
|
|
2212
2216
|
"src/domains/notifications/NotificationEventTracker.ts"() {
|
|
2213
2217
|
"use strict";
|
|
2214
2218
|
import_react_native10 = require("react-native");
|
|
2215
|
-
SEEN_MESSAGES_KEY = "seen_messages";
|
|
2219
|
+
SEEN_MESSAGES_KEY = "@paywallo:seen_messages";
|
|
2220
|
+
LEGACY_SEEN_MESSAGES_KEY = "seen_messages";
|
|
2216
2221
|
SEEN_TTL_MS = 60 * 60 * 1e3;
|
|
2217
2222
|
MAX_SEEN_SIZE = 1e3;
|
|
2223
|
+
NOTIFICATION_TYPE_TO_FAMILY = {
|
|
2224
|
+
notification_delivered: "delivered",
|
|
2225
|
+
notification_displayed: "displayed",
|
|
2226
|
+
notification_clicked: "clicked",
|
|
2227
|
+
notification_dismissed: "dismissed"
|
|
2228
|
+
};
|
|
2218
2229
|
NotificationEventTracker = class {
|
|
2219
2230
|
constructor(batcher, config, secureStorage2) {
|
|
2220
2231
|
this.batcher = batcher;
|
|
@@ -2235,9 +2246,13 @@ var init_NotificationEventTracker = __esm({
|
|
|
2235
2246
|
if (this.config.debug) console.log("[Paywallo PUSH] skipped (no distinctId):", eventType);
|
|
2236
2247
|
return;
|
|
2237
2248
|
}
|
|
2249
|
+
const canonicalType = NOTIFICATION_TYPE_TO_FAMILY[eventType];
|
|
2250
|
+
if (!canonicalType) {
|
|
2251
|
+
if (this.config.debug) console.log("[Paywallo PUSH] eventType not mapped to family schema, skipping ingest:", eventType);
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
2238
2254
|
const properties = {
|
|
2239
|
-
|
|
2240
|
-
type: eventType,
|
|
2255
|
+
type: canonicalType,
|
|
2241
2256
|
notification_id: notificationId,
|
|
2242
2257
|
campaign_id: campaignId,
|
|
2243
2258
|
variant_key: variantKey ?? null,
|
|
@@ -2249,7 +2264,7 @@ var init_NotificationEventTracker = __esm({
|
|
|
2249
2264
|
if (payload.failureReason) properties.failure_reason = payload.failureReason;
|
|
2250
2265
|
if (payload.appUserId) properties.app_user_id = payload.appUserId;
|
|
2251
2266
|
if (payload.properties) Object.assign(properties, payload.properties);
|
|
2252
|
-
if (this.config.debug) console.log("[Paywallo PUSH] tracking event:",
|
|
2267
|
+
if (this.config.debug) console.log("[Paywallo PUSH] tracking event:", canonicalType, notificationId);
|
|
2253
2268
|
await this.batcher.trackEvent("notification", distinctId, properties);
|
|
2254
2269
|
}
|
|
2255
2270
|
async isDuplicate(messageId, eventType) {
|
|
@@ -2294,7 +2309,10 @@ var init_NotificationEventTracker = __esm({
|
|
|
2294
2309
|
return;
|
|
2295
2310
|
}
|
|
2296
2311
|
try {
|
|
2297
|
-
|
|
2312
|
+
let raw = await this.secureStorage.get(SEEN_MESSAGES_KEY);
|
|
2313
|
+
if (!raw) {
|
|
2314
|
+
raw = await this.secureStorage.get(LEGACY_SEEN_MESSAGES_KEY).catch(() => null);
|
|
2315
|
+
}
|
|
2298
2316
|
if (raw) {
|
|
2299
2317
|
const parsed = JSON.parse(raw);
|
|
2300
2318
|
const now = Date.now();
|
|
@@ -2352,8 +2370,8 @@ async function getInitialNotificationPayload(bridge) {
|
|
|
2352
2370
|
notificationId: String(data["notificationId"] ?? data["notification_id"] ?? ""),
|
|
2353
2371
|
campaignId: String(data["campaignId"] ?? data["campaign_id"] ?? ""),
|
|
2354
2372
|
variantKey: data["variantKey"] != null ? String(data["variantKey"]) : void 0,
|
|
2355
|
-
title: String(data["title"] ?? message.notification?.title ?? ""),
|
|
2356
|
-
body: String(data["body"] ?? message.notification?.body ?? ""),
|
|
2373
|
+
title: String(data["title"] ?? message.notification?.title ?? message.title ?? ""),
|
|
2374
|
+
body: String(data["body"] ?? message.notification?.body ?? message.body ?? ""),
|
|
2357
2375
|
data
|
|
2358
2376
|
};
|
|
2359
2377
|
}
|
|
@@ -2368,8 +2386,8 @@ var init_NotificationHandlerSetup = __esm({
|
|
|
2368
2386
|
// src/core/version.ts
|
|
2369
2387
|
function resolveVersion() {
|
|
2370
2388
|
try {
|
|
2371
|
-
if ("2.2.
|
|
2372
|
-
return "2.2.
|
|
2389
|
+
if ("2.2.5") {
|
|
2390
|
+
return "2.2.5";
|
|
2373
2391
|
}
|
|
2374
2392
|
} catch {
|
|
2375
2393
|
}
|
|
@@ -2501,7 +2519,7 @@ async function buildRegistration(token, getDeviceId, getDistinctId) {
|
|
|
2501
2519
|
async function registerToken(deps, token) {
|
|
2502
2520
|
const { httpClient, appKey, getDeviceId, getDistinctId, debug } = deps;
|
|
2503
2521
|
if (!httpClient || !appKey) {
|
|
2504
|
-
if (debug) console.
|
|
2522
|
+
if (debug) console.log("[Paywallo PUSH] httpClient not ready, skipping token registration");
|
|
2505
2523
|
return;
|
|
2506
2524
|
}
|
|
2507
2525
|
const registration = await buildRegistration(token, getDeviceId, getDistinctId);
|
|
@@ -2511,22 +2529,25 @@ async function registerToken(deps, token) {
|
|
|
2511
2529
|
registration,
|
|
2512
2530
|
{ headers: { "X-App-Key": appKey } }
|
|
2513
2531
|
);
|
|
2514
|
-
if (debug) console.
|
|
2532
|
+
if (debug) console.log("[Paywallo PUSH] token registered successfully");
|
|
2515
2533
|
} catch (err) {
|
|
2516
|
-
|
|
2534
|
+
console.error("[Paywallo PUSH] token registration failed:", err);
|
|
2517
2535
|
throw new RegistrationFailedError("Token registration failed", err);
|
|
2518
2536
|
}
|
|
2519
2537
|
}
|
|
2520
|
-
async function unregisterToken(httpClient, appKey, debug) {
|
|
2538
|
+
async function unregisterToken(httpClient, appKey, debug, token, distinctId) {
|
|
2521
2539
|
if (!httpClient || !appKey) return;
|
|
2540
|
+
if (!token || !distinctId) return;
|
|
2522
2541
|
try {
|
|
2542
|
+
const body = JSON.stringify({ token, distinct_id: distinctId });
|
|
2523
2543
|
await httpClient.request(TOKEN_ENDPOINT, {
|
|
2524
2544
|
method: "DELETE",
|
|
2525
|
-
headers: { "X-App-Key": appKey },
|
|
2545
|
+
headers: { "X-App-Key": appKey, "Content-Type": "application/json" },
|
|
2546
|
+
body,
|
|
2526
2547
|
timeout: 1e4
|
|
2527
2548
|
});
|
|
2528
2549
|
} catch (err) {
|
|
2529
|
-
|
|
2550
|
+
console.error("[Paywallo PUSH] optOut error:", err);
|
|
2530
2551
|
}
|
|
2531
2552
|
}
|
|
2532
2553
|
var FCM_TOKEN_KEY, TOKEN_ENDPOINT;
|
|
@@ -2558,7 +2579,7 @@ async function registerAndPersistToken(deps, token) {
|
|
|
2558
2579
|
}
|
|
2559
2580
|
function subscribeTokenRefresh(bridge, deps, onToken) {
|
|
2560
2581
|
return bridge.onTokenRefresh((newToken) => {
|
|
2561
|
-
if (deps.debug) console.
|
|
2582
|
+
if (deps.debug) console.log("[Paywallo PUSH] token refreshed");
|
|
2562
2583
|
onToken(newToken);
|
|
2563
2584
|
persistToken(deps.secureStorage, newToken).catch(() => void 0);
|
|
2564
2585
|
registerToken(
|
|
@@ -2574,8 +2595,8 @@ function subscribeTokenRefresh(bridge, deps, onToken) {
|
|
|
2574
2595
|
).catch(() => void 0);
|
|
2575
2596
|
});
|
|
2576
2597
|
}
|
|
2577
|
-
async function optOutToken(httpClient, secureStorage2, appKey, debug) {
|
|
2578
|
-
await unregisterToken(httpClient, appKey, debug);
|
|
2598
|
+
async function optOutToken(httpClient, secureStorage2, appKey, debug, token, distinctId) {
|
|
2599
|
+
await unregisterToken(httpClient, appKey, debug, token, distinctId);
|
|
2579
2600
|
await clearPersistedToken(secureStorage2);
|
|
2580
2601
|
}
|
|
2581
2602
|
async function invalidateLocalTokenStorage(secureStorage2, debug) {
|
|
@@ -2595,7 +2616,7 @@ async function captureAndRegisterToken(bridge, deps, onTokenCaptured, subscribeR
|
|
|
2595
2616
|
await waitForApnsToken(bridge, deps.debug);
|
|
2596
2617
|
const token = await bridge.getToken();
|
|
2597
2618
|
if (!token) {
|
|
2598
|
-
if (deps.debug) console.
|
|
2619
|
+
if (deps.debug) console.log("[Paywallo PUSH] token unavailable after grant");
|
|
2599
2620
|
return;
|
|
2600
2621
|
}
|
|
2601
2622
|
onTokenCaptured(token);
|
|
@@ -2662,18 +2683,18 @@ var init_PermissionManager = __esm({
|
|
|
2662
2683
|
}
|
|
2663
2684
|
async requestPermission(options) {
|
|
2664
2685
|
const platform = this.platformOverride ?? getPlatform();
|
|
2665
|
-
if (this.debug) console.
|
|
2686
|
+
if (this.debug) console.log("[paywallo-push] platform detected:", platform.OS, "version:", String(platform.Version ?? "n/a"));
|
|
2666
2687
|
if (platform.OS === "ios") {
|
|
2667
|
-
if (this.debug) console.
|
|
2688
|
+
if (this.debug) console.log("[paywallo-push] requestPermission iOS \u2014 calling bridge...");
|
|
2668
2689
|
try {
|
|
2669
2690
|
const raw2 = await this.bridge.requestPermission(options);
|
|
2670
|
-
if (this.debug) console.
|
|
2691
|
+
if (this.debug) console.log("[paywallo-push] bridge returned raw:", raw2);
|
|
2671
2692
|
const status2 = mapPermissionStatus2(raw2);
|
|
2672
|
-
if (this.debug) console.
|
|
2693
|
+
if (this.debug) console.log("[paywallo-push] mapped status:", status2);
|
|
2673
2694
|
this.emitOsEvent(status2);
|
|
2674
2695
|
return status2;
|
|
2675
2696
|
} catch (err) {
|
|
2676
|
-
|
|
2697
|
+
console.error("[paywallo-push] requestPermission iOS CRASHED:", err instanceof Error ? err.message : String(err));
|
|
2677
2698
|
throw err;
|
|
2678
2699
|
}
|
|
2679
2700
|
}
|
|
@@ -2806,11 +2827,11 @@ var init_NotificationsManager = __esm({
|
|
|
2806
2827
|
await waitForApnsToken(this.bridge, this.debug);
|
|
2807
2828
|
const token = await this.bridge.getToken();
|
|
2808
2829
|
if (!token) {
|
|
2809
|
-
if (this.debug) console.
|
|
2830
|
+
if (this.debug) console.log("[Paywallo PUSH] token unavailable, skipping registration");
|
|
2810
2831
|
this.isInitialized = true;
|
|
2811
2832
|
return;
|
|
2812
2833
|
}
|
|
2813
|
-
if (this.debug) console.
|
|
2834
|
+
if (this.debug) console.log("[Paywallo PUSH] token acquired:", token);
|
|
2814
2835
|
this.currentToken = token;
|
|
2815
2836
|
await this.doRegisterToken(token);
|
|
2816
2837
|
this.subscribeTokenRefresh();
|
|
@@ -2828,7 +2849,7 @@ var init_NotificationsManager = __esm({
|
|
|
2828
2849
|
async refreshPermissionStatus() {
|
|
2829
2850
|
const permStatus = await this.bridge.hasPermission();
|
|
2830
2851
|
this.permissionStatus = mapPermissionStatus(permStatus);
|
|
2831
|
-
if (this.debug) console.
|
|
2852
|
+
if (this.debug) console.log("[Paywallo PUSH] permission status:", this.permissionStatus);
|
|
2832
2853
|
}
|
|
2833
2854
|
tokenDeps() {
|
|
2834
2855
|
return {
|
|
@@ -2856,7 +2877,7 @@ var init_NotificationsManager = __esm({
|
|
|
2856
2877
|
async optOut() {
|
|
2857
2878
|
await optOutToken(this.httpClient, this.secureStorage, this.appKey, this.debug);
|
|
2858
2879
|
this.currentToken = null;
|
|
2859
|
-
if (this.debug) console.
|
|
2880
|
+
if (this.debug) console.log("[Paywallo PUSH] opted out");
|
|
2860
2881
|
}
|
|
2861
2882
|
/** Clears token locally without server call (used on sign-out/reset). */
|
|
2862
2883
|
async invalidateLocalToken() {
|
|
@@ -2873,21 +2894,21 @@ var init_NotificationsManager = __esm({
|
|
|
2873
2894
|
}
|
|
2874
2895
|
/** Requests OS permission and, on success, captures + registers the push token. */
|
|
2875
2896
|
async requestPushPermission(options) {
|
|
2876
|
-
if (this.debug) console.
|
|
2897
|
+
if (this.debug) console.log("[Paywallo PUSH] requestPushPermission called");
|
|
2877
2898
|
try {
|
|
2878
2899
|
const status = await this.permissionManager.requestPermission(options);
|
|
2879
|
-
if (this.debug) console.
|
|
2900
|
+
if (this.debug) console.log("[Paywallo PUSH] permissionManager returned:", status);
|
|
2880
2901
|
this.permissionStatus = status;
|
|
2881
2902
|
if (status === "granted" || status === "provisional") {
|
|
2882
|
-
if (this.debug) console.
|
|
2903
|
+
if (this.debug) console.log("[Paywallo PUSH] permission granted \u2014 capturing token...");
|
|
2883
2904
|
await this.captureAndRegisterToken();
|
|
2884
|
-
if (this.debug) console.
|
|
2905
|
+
if (this.debug) console.log("[Paywallo PUSH] token capture complete");
|
|
2885
2906
|
} else {
|
|
2886
|
-
if (this.debug) console.
|
|
2907
|
+
if (this.debug) console.log("[Paywallo PUSH] permission not granted, skipping token register:", status);
|
|
2887
2908
|
}
|
|
2888
2909
|
return status;
|
|
2889
2910
|
} catch (err) {
|
|
2890
|
-
|
|
2911
|
+
console.error("[Paywallo PUSH] requestPushPermission CRASHED:", err instanceof Error ? err.message : String(err));
|
|
2891
2912
|
throw err;
|
|
2892
2913
|
}
|
|
2893
2914
|
}
|
|
@@ -3049,7 +3070,9 @@ function parseWebViewMessage(raw) {
|
|
|
3049
3070
|
const safePayload = payload !== null && typeof payload === "object" ? {
|
|
3050
3071
|
productId: typeof payload.productId === "string" ? String(payload.productId) : void 0,
|
|
3051
3072
|
url: typeof payload.url === "string" ? String(payload.url) : void 0,
|
|
3052
|
-
timestamp: typeof payload.timestamp === "number" ? Number(payload.timestamp) : void 0
|
|
3073
|
+
timestamp: typeof payload.timestamp === "number" ? Number(payload.timestamp) : void 0,
|
|
3074
|
+
variantKey: typeof payload.variantKey === "string" ? String(payload.variantKey) : void 0,
|
|
3075
|
+
style: HAPTIC_STYLES.has(String(payload.style)) ? String(payload.style) : typeof payload.style !== "undefined" ? "light" : void 0
|
|
3053
3076
|
} : void 0;
|
|
3054
3077
|
return {
|
|
3055
3078
|
type: parsed.type,
|
|
@@ -3060,17 +3083,19 @@ function parseWebViewMessage(raw) {
|
|
|
3060
3083
|
return null;
|
|
3061
3084
|
}
|
|
3062
3085
|
}
|
|
3063
|
-
var ALLOWED_MESSAGE_TYPES;
|
|
3086
|
+
var HAPTIC_STYLES, ALLOWED_MESSAGE_TYPES;
|
|
3064
3087
|
var init_parseWebViewMessage = __esm({
|
|
3065
3088
|
"src/domains/paywall/parseWebViewMessage.ts"() {
|
|
3066
3089
|
"use strict";
|
|
3090
|
+
HAPTIC_STYLES = /* @__PURE__ */ new Set(["light", "medium", "heavy"]);
|
|
3067
3091
|
ALLOWED_MESSAGE_TYPES = /* @__PURE__ */ new Set([
|
|
3068
3092
|
"purchase",
|
|
3069
3093
|
"close",
|
|
3070
3094
|
"restore",
|
|
3071
3095
|
"select-product",
|
|
3072
3096
|
"open-url",
|
|
3073
|
-
"ready"
|
|
3097
|
+
"ready",
|
|
3098
|
+
"haptic"
|
|
3074
3099
|
]);
|
|
3075
3100
|
}
|
|
3076
3101
|
});
|
|
@@ -3112,7 +3137,7 @@ var init_PaywallErrorBoundary = __esm({
|
|
|
3112
3137
|
return { hasError: true };
|
|
3113
3138
|
}
|
|
3114
3139
|
componentDidCatch(error) {
|
|
3115
|
-
|
|
3140
|
+
console.error("[Paywallo] Paywall render error:", error);
|
|
3116
3141
|
try {
|
|
3117
3142
|
PaywalloClient.getApiClient()?.reportError("PAYWALL_RENDER_ERROR", error.message);
|
|
3118
3143
|
} catch {
|
|
@@ -3279,7 +3304,9 @@ function buildPaywallInjectionScript(data) {
|
|
|
3279
3304
|
craftData: data.craftData,
|
|
3280
3305
|
products: data.products,
|
|
3281
3306
|
primaryProductId: data.primaryProductId,
|
|
3282
|
-
secondaryProductId: data.secondaryProductId
|
|
3307
|
+
secondaryProductId: data.secondaryProductId,
|
|
3308
|
+
currentLanguage: getCurrentLanguage(),
|
|
3309
|
+
defaultLanguage: getDefaultLanguage()
|
|
3283
3310
|
}
|
|
3284
3311
|
};
|
|
3285
3312
|
return `(function(){var d=${JSON.stringify(paywallData)},a=0,m=50;function t(){a++;if(window.receiveNativeMessage){window.receiveNativeMessage(d);return;}if(a<m){setTimeout(t,100);}}t();})();true;`;
|
|
@@ -3287,9 +3314,28 @@ function buildPaywallInjectionScript(data) {
|
|
|
3287
3314
|
function buildPurchaseStateScript(isPurchasing) {
|
|
3288
3315
|
return `if(window.receiveNativeMessage){window.receiveNativeMessage({type:"purchaseState",data:{isPurchasing:${isPurchasing}}});}true;`;
|
|
3289
3316
|
}
|
|
3317
|
+
function buildBackButtonScript(nonce = Date.now()) {
|
|
3318
|
+
return [
|
|
3319
|
+
`/*${nonce}*/`,
|
|
3320
|
+
"(function(){",
|
|
3321
|
+
"try{",
|
|
3322
|
+
"var h=window.__paywalloHandleBackPress;",
|
|
3323
|
+
"var consumed=typeof h==='function'?!!h():false;",
|
|
3324
|
+
"if(!consumed&&window.ReactNativeWebView){",
|
|
3325
|
+
'window.ReactNativeWebView.postMessage(JSON.stringify({type:"close"}));',
|
|
3326
|
+
"}",
|
|
3327
|
+
"}catch(e){",
|
|
3328
|
+
"if(window.ReactNativeWebView){",
|
|
3329
|
+
'window.ReactNativeWebView.postMessage(JSON.stringify({type:"close"}));',
|
|
3330
|
+
"}",
|
|
3331
|
+
"}",
|
|
3332
|
+
"})();true;"
|
|
3333
|
+
].join("");
|
|
3334
|
+
}
|
|
3290
3335
|
var init_paywallScripts = __esm({
|
|
3291
3336
|
"src/domains/paywall/paywallScripts.ts"() {
|
|
3292
3337
|
"use strict";
|
|
3338
|
+
init_localization();
|
|
3293
3339
|
}
|
|
3294
3340
|
});
|
|
3295
3341
|
|
|
@@ -3312,6 +3358,24 @@ function getWebViewEmitter() {
|
|
|
3312
3358
|
webViewEmitter = new import_react_native14.NativeEventEmitter(mod);
|
|
3313
3359
|
return webViewEmitter;
|
|
3314
3360
|
}
|
|
3361
|
+
async function triggerNativeHaptic(style) {
|
|
3362
|
+
try {
|
|
3363
|
+
const module2 = await import("react-native-haptic-feedback");
|
|
3364
|
+
const hapticModule = module2.default ?? module2;
|
|
3365
|
+
const trigger = hapticModule.trigger;
|
|
3366
|
+
if (typeof trigger !== "function") return;
|
|
3367
|
+
const typeMap = {
|
|
3368
|
+
light: "impactLight",
|
|
3369
|
+
medium: "impactMedium",
|
|
3370
|
+
heavy: "impactHeavy"
|
|
3371
|
+
};
|
|
3372
|
+
trigger(typeMap[style], {
|
|
3373
|
+
enableVibrateFallback: true,
|
|
3374
|
+
ignoreAndroidSystemSettings: false
|
|
3375
|
+
});
|
|
3376
|
+
} catch {
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3315
3379
|
function parseErrorEvent(raw) {
|
|
3316
3380
|
return {
|
|
3317
3381
|
code: typeof raw["code"] === "number" ? raw["code"] : -1,
|
|
@@ -3336,6 +3400,7 @@ function PaywallWebView({
|
|
|
3336
3400
|
const paywallDataSent = (0, import_react3.useRef)(false);
|
|
3337
3401
|
const loadEndReceived = (0, import_react3.useRef)(false);
|
|
3338
3402
|
const [scriptToInject, setScriptToInject] = (0, import_react3.useState)(void 0);
|
|
3403
|
+
const webViewRef = (0, import_react3.useRef)(null);
|
|
3339
3404
|
const onErrorRef = (0, import_react3.useRef)(onError);
|
|
3340
3405
|
onErrorRef.current = onError;
|
|
3341
3406
|
const onReadyRef = (0, import_react3.useRef)(onReady);
|
|
@@ -3379,6 +3444,15 @@ function PaywallWebView({
|
|
|
3379
3444
|
});
|
|
3380
3445
|
}
|
|
3381
3446
|
}, []);
|
|
3447
|
+
const injectScript = (0, import_react3.useCallback)((script) => {
|
|
3448
|
+
if (import_react_native14.Platform.OS === "android") {
|
|
3449
|
+
const handle = (0, import_react_native14.findNodeHandle)(webViewRef.current);
|
|
3450
|
+
if (handle == null) return;
|
|
3451
|
+
import_react_native14.UIManager.dispatchViewManagerCommand(handle, "injectJavaScript", [script]);
|
|
3452
|
+
return;
|
|
3453
|
+
}
|
|
3454
|
+
setScriptToInject(script);
|
|
3455
|
+
}, []);
|
|
3382
3456
|
const buildAndSetInjectionScript = (0, import_react3.useCallback)(() => {
|
|
3383
3457
|
if (!craftData || paywallDataSent.current) return;
|
|
3384
3458
|
paywallDataSent.current = true;
|
|
@@ -3388,8 +3462,8 @@ function PaywallWebView({
|
|
|
3388
3462
|
primaryProductId,
|
|
3389
3463
|
secondaryProductId
|
|
3390
3464
|
});
|
|
3391
|
-
|
|
3392
|
-
}, [craftData, products, primaryProductId, secondaryProductId]);
|
|
3465
|
+
injectScript(script);
|
|
3466
|
+
}, [craftData, products, primaryProductId, secondaryProductId, injectScript]);
|
|
3393
3467
|
const processedIdsRef = (0, import_react3.useRef)(/* @__PURE__ */ new Set());
|
|
3394
3468
|
const dedupeTimersRef = (0, import_react3.useRef)(/* @__PURE__ */ new Map());
|
|
3395
3469
|
(0, import_react3.useEffect)(() => {
|
|
@@ -3426,6 +3500,9 @@ function PaywallWebView({
|
|
|
3426
3500
|
case "restore":
|
|
3427
3501
|
onRestore();
|
|
3428
3502
|
break;
|
|
3503
|
+
case "select-product":
|
|
3504
|
+
console.log("[Paywallo:PaywallWebView] select-product received", message.payload?.productId);
|
|
3505
|
+
break;
|
|
3429
3506
|
case "open-url":
|
|
3430
3507
|
if (message.payload?.url) {
|
|
3431
3508
|
const url = message.payload.url;
|
|
@@ -3434,6 +3511,9 @@ function PaywallWebView({
|
|
|
3434
3511
|
}
|
|
3435
3512
|
}
|
|
3436
3513
|
break;
|
|
3514
|
+
case "haptic":
|
|
3515
|
+
void triggerNativeHaptic(message.payload?.style ?? "light");
|
|
3516
|
+
break;
|
|
3437
3517
|
}
|
|
3438
3518
|
},
|
|
3439
3519
|
[buildAndSetInjectionScript, onPurchase, onClose, onRestore]
|
|
@@ -3505,13 +3585,24 @@ function PaywallWebView({
|
|
|
3505
3585
|
);
|
|
3506
3586
|
(0, import_react3.useEffect)(() => {
|
|
3507
3587
|
if (!paywallDataSent.current) return;
|
|
3508
|
-
|
|
3509
|
-
}, [isPurchasing]);
|
|
3588
|
+
injectScript(buildPurchaseStateScript(isPurchasing));
|
|
3589
|
+
}, [isPurchasing, injectScript]);
|
|
3590
|
+
(0, import_react3.useEffect)(() => {
|
|
3591
|
+
if (import_react_native14.Platform.OS !== "android") return;
|
|
3592
|
+
const onBackPress = () => {
|
|
3593
|
+
if (!paywallDataSent.current) return false;
|
|
3594
|
+
injectScript(buildBackButtonScript());
|
|
3595
|
+
return true;
|
|
3596
|
+
};
|
|
3597
|
+
const subscription = import_react_native14.BackHandler.addEventListener("hardwareBackPress", onBackPress);
|
|
3598
|
+
return () => subscription.remove();
|
|
3599
|
+
}, [injectScript]);
|
|
3510
3600
|
if (!resolvedWebUrl || !NativeWebView) return null;
|
|
3511
3601
|
const paywallUrl = `${resolvedWebUrl}/paywall/${paywallId}`;
|
|
3512
3602
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native14.View, { style: styles.container, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3513
3603
|
NativeWebView,
|
|
3514
3604
|
{
|
|
3605
|
+
ref: webViewRef,
|
|
3515
3606
|
sourceUrl: paywallUrl,
|
|
3516
3607
|
injectedJavaScript: scriptToInject,
|
|
3517
3608
|
onMessage: handleMessage,
|
|
@@ -3741,7 +3832,7 @@ var init_NativeStoreKit = __esm({
|
|
|
3741
3832
|
try {
|
|
3742
3833
|
await PaywalloStoreKitNative.finishTransaction(transactionId);
|
|
3743
3834
|
} catch (err) {
|
|
3744
|
-
|
|
3835
|
+
console.error("[Paywallo] finishTransaction native error", err);
|
|
3745
3836
|
}
|
|
3746
3837
|
},
|
|
3747
3838
|
async getActiveTransactions() {
|
|
@@ -3750,7 +3841,7 @@ var init_NativeStoreKit = __esm({
|
|
|
3750
3841
|
const results = await PaywalloStoreKitNative.getActiveTransactions();
|
|
3751
3842
|
return results.map(mapNativePurchase);
|
|
3752
3843
|
} catch (err) {
|
|
3753
|
-
|
|
3844
|
+
console.error("[Paywallo] getActiveTransactions failed", err);
|
|
3754
3845
|
return [];
|
|
3755
3846
|
}
|
|
3756
3847
|
},
|
|
@@ -4601,7 +4692,7 @@ var init_QueueProcessor = __esm({
|
|
|
4601
4692
|
}
|
|
4602
4693
|
const allItems = offlineQueue.getQueue();
|
|
4603
4694
|
const eventItems = allItems.filter(
|
|
4604
|
-
(i) =>
|
|
4695
|
+
(i) => i.url.includes("/events") || i.url.includes("/ingest")
|
|
4605
4696
|
);
|
|
4606
4697
|
const eventItemIds = new Set(eventItems.map((i) => i.id));
|
|
4607
4698
|
const { processed: batchProcessed, failed: batchFailed, retryIds } = await this.processEventBatches(eventItems);
|
|
@@ -4641,12 +4732,24 @@ var init_QueueProcessor = __esm({
|
|
|
4641
4732
|
const freshHeaders = this.config.getFreshHeaders?.() ?? {};
|
|
4642
4733
|
const headers = { ...persistedHeaders, ...freshHeaders };
|
|
4643
4734
|
this.log("Sending event batch", { size: batch.length, batchIndex: Math.floor(i / BATCH_SIZE) });
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4735
|
+
let response;
|
|
4736
|
+
try {
|
|
4737
|
+
response = await this.httpClient.request("/sdk/ingest/batch", {
|
|
4738
|
+
method: "POST",
|
|
4739
|
+
body: { events: bodies },
|
|
4740
|
+
headers,
|
|
4741
|
+
skipRetry: false
|
|
4742
|
+
});
|
|
4743
|
+
} catch (error) {
|
|
4744
|
+
for (const item of batch) {
|
|
4745
|
+
retryIds.add(item.id);
|
|
4746
|
+
}
|
|
4747
|
+
this.log("Event batch threw network error - will retry", {
|
|
4748
|
+
size: batch.length,
|
|
4749
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4750
|
+
});
|
|
4751
|
+
continue;
|
|
4752
|
+
}
|
|
4650
4753
|
if (response.ok) {
|
|
4651
4754
|
for (const item of batch) {
|
|
4652
4755
|
await offlineQueue.removeItem(item.id);
|
|
@@ -4686,12 +4789,21 @@ var init_QueueProcessor = __esm({
|
|
|
4686
4789
|
});
|
|
4687
4790
|
const persistedHeaders = item.headers ?? {};
|
|
4688
4791
|
const freshHeaders = this.config.getFreshHeaders?.() ?? {};
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4792
|
+
let response;
|
|
4793
|
+
try {
|
|
4794
|
+
response = await this.httpClient.request(item.url, {
|
|
4795
|
+
method: item.method,
|
|
4796
|
+
body: item.body,
|
|
4797
|
+
headers: { ...persistedHeaders, ...freshHeaders },
|
|
4798
|
+
skipRetry: false
|
|
4799
|
+
});
|
|
4800
|
+
} catch (error) {
|
|
4801
|
+
this.log("Request threw network error - will retry", {
|
|
4802
|
+
id: item.id,
|
|
4803
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4804
|
+
});
|
|
4805
|
+
return { success: false, permanent: false };
|
|
4806
|
+
}
|
|
4695
4807
|
if (response.ok) {
|
|
4696
4808
|
this.log("Queue item processed successfully", { id: item.id });
|
|
4697
4809
|
return { success: true, permanent: false };
|
|
@@ -4836,19 +4948,19 @@ var init_IAPValidator = __esm({
|
|
|
4836
4948
|
const appKey = apiClient.getAppKey();
|
|
4837
4949
|
const body = {
|
|
4838
4950
|
platform,
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4951
|
+
receipt_data: purchase.receipt,
|
|
4952
|
+
product_id: purchase.productId,
|
|
4953
|
+
transaction_id: purchase.transactionId,
|
|
4954
|
+
price_local: product?.priceValue ?? 0,
|
|
4843
4955
|
currency: product?.currency ?? "USD",
|
|
4844
4956
|
country: this.getDeviceCountry(),
|
|
4845
|
-
distinctId
|
|
4957
|
+
distinct_id: distinctId
|
|
4846
4958
|
};
|
|
4847
|
-
if (options?.paywallPlacement !== void 0) body.
|
|
4848
|
-
if (options?.variantKey !== void 0) body.
|
|
4959
|
+
if (options?.paywallPlacement !== void 0) body.paywall_placement = options.paywallPlacement;
|
|
4960
|
+
if (options?.variantKey !== void 0) body.variant_key = options.variantKey;
|
|
4849
4961
|
await offlineQueue.enqueue(
|
|
4850
4962
|
"POST",
|
|
4851
|
-
"/purchases/validate",
|
|
4963
|
+
"/sdk/purchases/validate",
|
|
4852
4964
|
body,
|
|
4853
4965
|
{ "X-App-Key": appKey },
|
|
4854
4966
|
`validate:${purchase.transactionId}`,
|
|
@@ -4856,7 +4968,7 @@ var init_IAPValidator = __esm({
|
|
|
4856
4968
|
);
|
|
4857
4969
|
if (this.getDebug()) console.log("[Paywallo PURCHASE] validation retry enqueued", purchase.transactionId);
|
|
4858
4970
|
} catch (err) {
|
|
4859
|
-
|
|
4971
|
+
console.error("[Paywallo PURCHASE] failed to enqueue validation retry", err);
|
|
4860
4972
|
}
|
|
4861
4973
|
}
|
|
4862
4974
|
};
|
|
@@ -4935,7 +5047,7 @@ var init_IAPService = __esm({
|
|
|
4935
5047
|
}
|
|
4936
5048
|
return products;
|
|
4937
5049
|
} catch (err) {
|
|
4938
|
-
|
|
5050
|
+
console.error("[Paywallo] loadProducts failed", err);
|
|
4939
5051
|
return [];
|
|
4940
5052
|
}
|
|
4941
5053
|
}
|
|
@@ -4954,7 +5066,7 @@ var init_IAPService = __esm({
|
|
|
4954
5066
|
await nativeStoreKit.finishTransaction(transactionId);
|
|
4955
5067
|
this.finishedTransactions.add(transactionId);
|
|
4956
5068
|
} catch (err) {
|
|
4957
|
-
|
|
5069
|
+
console.error("[Paywallo] finishTransaction failed", err);
|
|
4958
5070
|
}
|
|
4959
5071
|
}
|
|
4960
5072
|
startTransactionListener() {
|
|
@@ -5003,7 +5115,7 @@ var init_IAPService = __esm({
|
|
|
5003
5115
|
await this.finishTransaction(purchase.transactionId);
|
|
5004
5116
|
return;
|
|
5005
5117
|
}
|
|
5006
|
-
|
|
5118
|
+
console.error("[Paywallo PURCHASE] background validation failed (network) \u2014 queued for retry", err);
|
|
5007
5119
|
await this.validator.enqueueValidationRetry(purchase, productId, {
|
|
5008
5120
|
paywallPlacement: options?.paywallPlacement,
|
|
5009
5121
|
variantKey: options?.variantKey
|
|
@@ -5011,7 +5123,7 @@ var init_IAPService = __esm({
|
|
|
5011
5123
|
});
|
|
5012
5124
|
return { success: true, purchase };
|
|
5013
5125
|
} catch (error) {
|
|
5014
|
-
|
|
5126
|
+
console.error(`[Paywallo PURCHASE] ${productId} failed`, error);
|
|
5015
5127
|
const e = error instanceof PurchaseError ? error : new PurchaseError(PURCHASE_ERROR_CODES.PURCHASE_FAILED, error instanceof Error ? error.message : String(error));
|
|
5016
5128
|
return { success: false, error: e };
|
|
5017
5129
|
} finally {
|
|
@@ -5055,7 +5167,7 @@ var init_IAPService = __esm({
|
|
|
5055
5167
|
if (this.debug) console.log("[Paywallo RESTORE] validation rejected (4xx) \u2014 dropping", tx.transactionId);
|
|
5056
5168
|
await this.finishTransaction(tx.transactionId);
|
|
5057
5169
|
} else {
|
|
5058
|
-
|
|
5170
|
+
console.error("[Paywallo RESTORE] validation failed (network) \u2014 queued for retry", r.reason);
|
|
5059
5171
|
await this.validator.enqueueValidationRetry(tx, tx.productId);
|
|
5060
5172
|
}
|
|
5061
5173
|
} else if (r.status === "fulfilled" && !r.value.success) {
|
|
@@ -5065,7 +5177,7 @@ var init_IAPService = __esm({
|
|
|
5065
5177
|
}
|
|
5066
5178
|
return validated;
|
|
5067
5179
|
} catch (err) {
|
|
5068
|
-
|
|
5180
|
+
console.error("[Paywallo] restore failed", err);
|
|
5069
5181
|
return [];
|
|
5070
5182
|
}
|
|
5071
5183
|
}
|
|
@@ -5281,7 +5393,7 @@ function usePaywallLoader(placement, visible, preloadedConfig, preloadedProducts
|
|
|
5281
5393
|
setProducts(map);
|
|
5282
5394
|
}
|
|
5283
5395
|
} catch (err) {
|
|
5284
|
-
|
|
5396
|
+
console.error("[Paywallo] loadProducts in paywall failed", err);
|
|
5285
5397
|
if (!cancelled) setProducts(/* @__PURE__ */ new Map());
|
|
5286
5398
|
}
|
|
5287
5399
|
} else {
|
|
@@ -6410,11 +6522,9 @@ var init_SubscriptionManager = __esm({
|
|
|
6410
6522
|
if (!this.config) {
|
|
6411
6523
|
return this.getEmptyStatus();
|
|
6412
6524
|
}
|
|
6413
|
-
const
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
}
|
|
6417
|
-
const response = await fetch(url.toString(), {
|
|
6525
|
+
const userId = this.userId ?? "";
|
|
6526
|
+
const url = `${this.config.serverUrl}/sdk/purchases/status?distinctId=${encodeURIComponent(userId)}`;
|
|
6527
|
+
const response = await fetch(url, {
|
|
6418
6528
|
method: "GET",
|
|
6419
6529
|
headers: {
|
|
6420
6530
|
"Content-Type": "application/json",
|
|
@@ -6427,17 +6537,32 @@ var init_SubscriptionManager = __esm({
|
|
|
6427
6537
|
`Failed to fetch subscription status: ${response.status}`
|
|
6428
6538
|
);
|
|
6429
6539
|
}
|
|
6430
|
-
const
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6540
|
+
const envelope = await response.json();
|
|
6541
|
+
const raw = envelope.data ?? envelope;
|
|
6542
|
+
const data = {
|
|
6543
|
+
hasActiveSubscription: !!(raw["has_active_subscription"] ?? raw["hasActiveSubscription"]),
|
|
6544
|
+
subscription: null,
|
|
6545
|
+
entitlements: raw["entitlements"] ?? []
|
|
6546
|
+
};
|
|
6547
|
+
const sub = raw["subscription"];
|
|
6548
|
+
if (sub) {
|
|
6549
|
+
const cancellationRaw = sub["cancellationDate"] ?? sub["cancellation_date"];
|
|
6550
|
+
const gracePeriodRaw = sub["gracePeriodExpiresAt"] ?? sub["grace_period_expires_at"];
|
|
6551
|
+
data.subscription = {
|
|
6552
|
+
id: sub["id"],
|
|
6553
|
+
productId: sub["product_id"] ?? sub["productId"],
|
|
6554
|
+
status: sub["status"],
|
|
6555
|
+
expiresAt: new Date(sub["expires_at"] ?? sub["expiresAt"]),
|
|
6556
|
+
originalPurchaseDate: new Date(sub["originalPurchaseDate"] ?? sub["original_purchase_date"]),
|
|
6557
|
+
latestPurchaseDate: new Date(sub["latestPurchaseDate"] ?? sub["latest_purchase_date"]),
|
|
6558
|
+
willRenew: !!(sub["will_renew"] ?? sub["willRenew"] ?? sub["auto_renew_enabled"] ?? sub["autoRenewEnabled"]),
|
|
6559
|
+
isTrial: !!(sub["is_trial"] ?? sub["isTrial"]),
|
|
6560
|
+
isIntroductoryPeriod: !!(sub["is_introductory_period"] ?? sub["isIntroductoryPeriod"]),
|
|
6561
|
+
platform: sub["platform"],
|
|
6562
|
+
storeTransactionId: sub["store_transaction_id"] ?? sub["storeTransactionId"],
|
|
6563
|
+
cancellationDate: cancellationRaw ? new Date(cancellationRaw) : void 0,
|
|
6564
|
+
gracePeriodExpiresAt: gracePeriodRaw ? new Date(gracePeriodRaw) : void 0
|
|
6565
|
+
};
|
|
6441
6566
|
}
|
|
6442
6567
|
return data;
|
|
6443
6568
|
}
|
|
@@ -6475,15 +6600,15 @@ async function validatePurchase(client, appKey, platform, receipt, productId, tr
|
|
|
6475
6600
|
"/sdk/purchases/validate",
|
|
6476
6601
|
{
|
|
6477
6602
|
platform,
|
|
6478
|
-
receipt,
|
|
6479
|
-
productId,
|
|
6480
|
-
transactionId,
|
|
6481
|
-
priceLocal,
|
|
6603
|
+
receipt_data: receipt,
|
|
6604
|
+
product_id: productId,
|
|
6605
|
+
transaction_id: transactionId,
|
|
6606
|
+
price_local: priceLocal,
|
|
6482
6607
|
currency,
|
|
6483
6608
|
country,
|
|
6484
|
-
distinctId,
|
|
6485
|
-
...paywallPlacement !== void 0 && { paywallPlacement },
|
|
6486
|
-
...variantKey !== void 0 && { variantKey }
|
|
6609
|
+
distinct_id: distinctId,
|
|
6610
|
+
...paywallPlacement !== void 0 && { paywall_placement: paywallPlacement },
|
|
6611
|
+
...variantKey !== void 0 && { variant_key: variantKey }
|
|
6487
6612
|
},
|
|
6488
6613
|
false
|
|
6489
6614
|
);
|
|
@@ -6495,7 +6620,7 @@ async function validatePurchase(client, appKey, platform, receipt, productId, tr
|
|
|
6495
6620
|
response.status
|
|
6496
6621
|
);
|
|
6497
6622
|
}
|
|
6498
|
-
return response.data;
|
|
6623
|
+
return response.data.data;
|
|
6499
6624
|
}
|
|
6500
6625
|
async function getSubscriptionStatus(client, baseUrl, appKey, distinctId) {
|
|
6501
6626
|
const url = new URL(`${baseUrl}/sdk/purchases/status`);
|
|
@@ -6504,7 +6629,7 @@ async function getSubscriptionStatus(client, baseUrl, appKey, distinctId) {
|
|
|
6504
6629
|
if (!response.ok) {
|
|
6505
6630
|
throw new PurchaseError(PURCHASE_ERROR_CODES.NETWORK_ERROR, `Subscription status check failed: HTTP ${response.status}`);
|
|
6506
6631
|
}
|
|
6507
|
-
return response.data;
|
|
6632
|
+
return response.data.data;
|
|
6508
6633
|
}
|
|
6509
6634
|
async function getEmergencyPaywall(client) {
|
|
6510
6635
|
try {
|
|
@@ -6713,7 +6838,7 @@ async function evaluateFlags2(deps, keys, distinctId) {
|
|
|
6713
6838
|
const result = {};
|
|
6714
6839
|
for (const key of Object.keys(record)) {
|
|
6715
6840
|
const value = record[key];
|
|
6716
|
-
const variant = typeof value === "
|
|
6841
|
+
const variant = typeof value === "string" ? value : null;
|
|
6717
6842
|
result[key] = variant;
|
|
6718
6843
|
const flagVariant = { variant };
|
|
6719
6844
|
deps.cache.setVariant(`${key}:${distinctId}`, flagVariant);
|
|
@@ -7026,7 +7151,7 @@ var init_eventEnvelopeV2 = __esm({
|
|
|
7026
7151
|
payload: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown())
|
|
7027
7152
|
});
|
|
7028
7153
|
v2ContextSchema = import_zod2.z.object({
|
|
7029
|
-
distinct_id: import_zod2.z.string().
|
|
7154
|
+
distinct_id: import_zod2.z.string().min(1),
|
|
7030
7155
|
session_id: import_zod2.z.string().optional(),
|
|
7031
7156
|
device_id: import_zod2.z.string().optional(),
|
|
7032
7157
|
app_version: import_zod2.z.string().optional(),
|
|
@@ -7069,7 +7194,7 @@ var init_events = __esm({
|
|
|
7069
7194
|
});
|
|
7070
7195
|
|
|
7071
7196
|
// src/core/EventBatcher.ts
|
|
7072
|
-
var import_react_native22, BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT,
|
|
7197
|
+
var import_react_native22, BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
|
|
7073
7198
|
var init_EventBatcher = __esm({
|
|
7074
7199
|
"src/core/EventBatcher.ts"() {
|
|
7075
7200
|
"use strict";
|
|
@@ -7080,15 +7205,12 @@ var init_EventBatcher = __esm({
|
|
|
7080
7205
|
BATCH_FLUSH_MS = 1e4;
|
|
7081
7206
|
EVENT_NAME_REGEX = /^(\$[a-zA-Z0-9_]+|[a-z][a-z0-9_]*)$/;
|
|
7082
7207
|
V2_BATCH_ENDPOINT = "/sdk/ingest/batch";
|
|
7083
|
-
V1_BATCH_ENDPOINT = "/sdk/events/batch";
|
|
7084
|
-
V1_SINGLE_ENDPOINT = "/sdk/events";
|
|
7085
7208
|
EventBatcher = class {
|
|
7086
7209
|
constructor(post, debug = false, contextProvider = null) {
|
|
7087
7210
|
this.criticalQueue = [];
|
|
7088
7211
|
this.normalQueue = [];
|
|
7089
7212
|
this.normalTimer = null;
|
|
7090
7213
|
this.criticalScheduled = false;
|
|
7091
|
-
this.v2Disabled = false;
|
|
7092
7214
|
this.post = post;
|
|
7093
7215
|
this.debug = debug;
|
|
7094
7216
|
this.contextProvider = contextProvider;
|
|
@@ -7184,11 +7306,7 @@ var init_EventBatcher = __esm({
|
|
|
7184
7306
|
try {
|
|
7185
7307
|
await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
|
|
7186
7308
|
} catch {
|
|
7187
|
-
|
|
7188
|
-
await this.post(V1_SINGLE_ENDPOINT, event, `event:${event.eventName}`, "critical");
|
|
7189
|
-
} catch {
|
|
7190
|
-
if (this.debug) console.log(`[Paywallo] critical event ${event.eventName} post failed`);
|
|
7191
|
-
}
|
|
7309
|
+
if (this.debug) console.log(`[Paywallo] critical event ${event.eventName} post failed`);
|
|
7192
7310
|
}
|
|
7193
7311
|
}
|
|
7194
7312
|
}
|
|
@@ -7202,50 +7320,24 @@ var init_EventBatcher = __esm({
|
|
|
7202
7320
|
try {
|
|
7203
7321
|
await this.postBatch(batch, `event_batch:${batch.length}`);
|
|
7204
7322
|
} catch {
|
|
7205
|
-
|
|
7206
|
-
await this.post(V1_SINGLE_ENDPOINT, event, `event:${event.eventName}`);
|
|
7207
|
-
}
|
|
7323
|
+
if (this.debug) console.log(`[Paywallo] normal batch post failed \u2014 OfflineQueue will handle durability`);
|
|
7208
7324
|
}
|
|
7209
7325
|
}
|
|
7210
|
-
/**
|
|
7211
|
-
* POST the batch with V2 envelope semantics. Tries `/ingest/batch`
|
|
7212
|
-
* first; on failure (404/network) falls back to `/events/batch`
|
|
7213
|
-
* with the legacy per-event shape for retrocompat.
|
|
7214
|
-
*
|
|
7215
|
-
* After a single V2 failure we flip `v2Disabled` and stop trying V2 for
|
|
7216
|
-
* the lifetime of this EventBatcher — avoids N retries per batch on old
|
|
7217
|
-
* servers that will never have the endpoint. A fresh `new EventBatcher()`
|
|
7218
|
-
* (e.g. after `Paywallo.init` on a new server URL) resets the flag.
|
|
7219
|
-
*/
|
|
7220
7326
|
async postBatch(events, label, priority = "normal") {
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
|
|
7234
|
-
throw parsed.error;
|
|
7235
|
-
}
|
|
7236
|
-
await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
|
|
7237
|
-
return;
|
|
7238
|
-
} catch (error) {
|
|
7239
|
-
this.v2Disabled = true;
|
|
7240
|
-
if (this.debug) {
|
|
7241
|
-
console.log(
|
|
7242
|
-
"[Paywallo EVENTS] V2 ingest unavailable, falling back to /events/batch:",
|
|
7243
|
-
error
|
|
7244
|
-
);
|
|
7245
|
-
}
|
|
7246
|
-
}
|
|
7327
|
+
const providerContext = resolveProviderContext(this.contextProvider);
|
|
7328
|
+
const inputs = events.map((e) => ({
|
|
7329
|
+
eventName: e.eventName,
|
|
7330
|
+
distinctId: e.distinctId,
|
|
7331
|
+
properties: e.properties,
|
|
7332
|
+
timestamp: e.timestamp
|
|
7333
|
+
}));
|
|
7334
|
+
const envelope = buildV2Envelope(inputs, providerContext);
|
|
7335
|
+
const parsed = v2EnvelopeSchema.safeParse(envelope);
|
|
7336
|
+
if (!parsed.success) {
|
|
7337
|
+
if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
|
|
7338
|
+
throw parsed.error;
|
|
7247
7339
|
}
|
|
7248
|
-
await this.post(
|
|
7340
|
+
await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
|
|
7249
7341
|
}
|
|
7250
7342
|
};
|
|
7251
7343
|
}
|
|
@@ -7632,6 +7724,26 @@ var init_ApiClient = __esm({
|
|
|
7632
7724
|
this.batcher.dispose();
|
|
7633
7725
|
}
|
|
7634
7726
|
async identify(distinctId, properties, email, deviceId, pii) {
|
|
7727
|
+
const rawTraits = {
|
|
7728
|
+
email: email || void 0,
|
|
7729
|
+
platform: import_react_native23.Platform.OS,
|
|
7730
|
+
name: properties?.name,
|
|
7731
|
+
country: properties?.country,
|
|
7732
|
+
locale: properties?.locale,
|
|
7733
|
+
app_version: properties?.appVersion ?? properties?.["app_version"]
|
|
7734
|
+
};
|
|
7735
|
+
const traits = Object.fromEntries(
|
|
7736
|
+
Object.entries(rawTraits).filter(([, v]) => v !== void 0)
|
|
7737
|
+
);
|
|
7738
|
+
const attributionKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content", "fbclid", "gclid", "ttclid", "referrer"];
|
|
7739
|
+
const rawAttribution = {};
|
|
7740
|
+
if (properties) {
|
|
7741
|
+
for (const key of attributionKeys) {
|
|
7742
|
+
const val = properties[key];
|
|
7743
|
+
if (val !== void 0) rawAttribution[key] = val;
|
|
7744
|
+
}
|
|
7745
|
+
}
|
|
7746
|
+
const attribution = Object.keys(rawAttribution).length > 0 ? rawAttribution : void 0;
|
|
7635
7747
|
await postWithQueue(
|
|
7636
7748
|
{
|
|
7637
7749
|
isOfflineQueueEnabled: () => this.offlineQueueEnabled,
|
|
@@ -7639,12 +7751,11 @@ var init_ApiClient = __esm({
|
|
|
7639
7751
|
isDebug: () => this.debug,
|
|
7640
7752
|
post: (path, body, skipRetry) => this.post(path, body, skipRetry)
|
|
7641
7753
|
},
|
|
7642
|
-
"/sdk/identify",
|
|
7754
|
+
"/sdk/identity/identify",
|
|
7643
7755
|
{
|
|
7644
|
-
distinctId,
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
platform: import_react_native23.Platform.OS,
|
|
7756
|
+
distinct_id: distinctId,
|
|
7757
|
+
traits,
|
|
7758
|
+
...attribution && { attribution },
|
|
7648
7759
|
...deviceId && { deviceId },
|
|
7649
7760
|
...pii?.phone && { phone: pii.phone },
|
|
7650
7761
|
...pii?.firstName && { firstName: pii.firstName },
|
|
@@ -7655,10 +7766,9 @@ var init_ApiClient = __esm({
|
|
|
7655
7766
|
"identify"
|
|
7656
7767
|
);
|
|
7657
7768
|
}
|
|
7658
|
-
// Session lifecycle endpoints
|
|
7659
|
-
//
|
|
7660
|
-
//
|
|
7661
|
-
// EventBatcher pipeline.
|
|
7769
|
+
// Session lifecycle endpoints were dropped. All session bookkeeping is now
|
|
7770
|
+
// derived on the server from `$session_start` and `session.end` events that
|
|
7771
|
+
// flow through the unified EventBatcher pipeline.
|
|
7662
7772
|
async getVariant(flagKey, distinctId) {
|
|
7663
7773
|
return getVariant2(this.flagDeps(), flagKey, distinctId);
|
|
7664
7774
|
}
|
|
@@ -7716,7 +7826,7 @@ var init_ApiClient = __esm({
|
|
|
7716
7826
|
const hit = this.cache.getCampaign(key);
|
|
7717
7827
|
if (hit !== void 0) return hit;
|
|
7718
7828
|
try {
|
|
7719
|
-
const res = await this.get(`/
|
|
7829
|
+
const res = await this.get(`/campaigns/public/primary?distinctId=${encodeURIComponent(distinctId)}`);
|
|
7720
7830
|
if (res.status === 404) {
|
|
7721
7831
|
this.cache.setCampaign(key, null, this.cache.nullTTL);
|
|
7722
7832
|
return null;
|
|
@@ -7816,10 +7926,10 @@ function setupNotifications(apiClient, config, environment, eventPipeline) {
|
|
|
7816
7926
|
debug: config.debug,
|
|
7817
7927
|
environment: environment === "Sandbox" ? "sandbox" : "production"
|
|
7818
7928
|
}).catch((err) => {
|
|
7819
|
-
|
|
7929
|
+
console.error("[Paywallo PUSH] initialization warning:", err instanceof Error ? err.message : String(err));
|
|
7820
7930
|
});
|
|
7821
7931
|
} catch (err) {
|
|
7822
|
-
|
|
7932
|
+
console.error("[Paywallo PUSH] setup warning:", err instanceof Error ? err.message : String(err));
|
|
7823
7933
|
}
|
|
7824
7934
|
}
|
|
7825
7935
|
function setupAutoPreload(state, apiClient, config, distinctId) {
|
|
@@ -7944,7 +8054,7 @@ function reportInitFailure(state, config, error, reason) {
|
|
|
7944
8054
|
error: error instanceof Error ? error.message : String(error)
|
|
7945
8055
|
});
|
|
7946
8056
|
} catch (err) {
|
|
7947
|
-
|
|
8057
|
+
console.error("[Paywallo] reportInitFailure error", err);
|
|
7948
8058
|
}
|
|
7949
8059
|
}
|
|
7950
8060
|
function reportInitSuccess(state, config, attempts) {
|
|
@@ -7953,7 +8063,7 @@ function reportInitSuccess(state, config, attempts) {
|
|
|
7953
8063
|
void state.apiClient.reportError("INIT_RECOVERED", `Succeeded after ${attempts} retries`, { attempts });
|
|
7954
8064
|
}
|
|
7955
8065
|
} catch (err) {
|
|
7956
|
-
|
|
8066
|
+
console.error("[Paywallo] reportInitSuccess error", err);
|
|
7957
8067
|
}
|
|
7958
8068
|
}
|
|
7959
8069
|
async function resolveSessionFlags(state, keys, apiClient, distinctId) {
|
|
@@ -8007,7 +8117,7 @@ async function doInit(state, config) {
|
|
|
8007
8117
|
try {
|
|
8008
8118
|
await identityManager.identify(pending);
|
|
8009
8119
|
} catch (err) {
|
|
8010
|
-
|
|
8120
|
+
console.error("[Paywallo INIT] pending identify replay failed", err);
|
|
8011
8121
|
}
|
|
8012
8122
|
}
|
|
8013
8123
|
state.pendingIdentifies = [];
|
|
@@ -8085,7 +8195,7 @@ async function doInit(state, config) {
|
|
|
8085
8195
|
setupNotifications(apiClient, config, environment, eventPipeline);
|
|
8086
8196
|
if (config.autoStartSession !== false) {
|
|
8087
8197
|
sessionManager.startSession().catch((err) => {
|
|
8088
|
-
|
|
8198
|
+
console.error("[Paywallo INIT] autoStart session error", err);
|
|
8089
8199
|
});
|
|
8090
8200
|
}
|
|
8091
8201
|
new InstallTracker(config.debug, {
|
|
@@ -8103,7 +8213,7 @@ async function doInit(state, config) {
|
|
|
8103
8213
|
state.resolveReady();
|
|
8104
8214
|
state.resolveReady = null;
|
|
8105
8215
|
}
|
|
8106
|
-
if (config.debug) console.
|
|
8216
|
+
if (config.debug) console.log("[Paywallo] initialized successfully");
|
|
8107
8217
|
if (distinctId) {
|
|
8108
8218
|
apiClient.getSubscriptionStatus(distinctId).then(() => {
|
|
8109
8219
|
if (config.debug) console.log("[Paywallo SUB] preloaded on boot");
|
|
@@ -8220,7 +8330,7 @@ async function checkActiveSubscription(state) {
|
|
|
8220
8330
|
if (state.config?.debug) console.log("[Paywallo SUB] hasActiveSubscription (server):", isActive);
|
|
8221
8331
|
return isActive;
|
|
8222
8332
|
} catch (error) {
|
|
8223
|
-
|
|
8333
|
+
console.error("[Paywallo SUB] hasActiveSubscription error", error);
|
|
8224
8334
|
if (state.apiClient) void state.apiClient.reportError("SUBSCRIPTION_CHECK_FAILED", error instanceof Error ? error.message : "hasActiveSubscription failed");
|
|
8225
8335
|
return false;
|
|
8226
8336
|
}
|
|
@@ -8665,6 +8775,7 @@ var init_OfferingService = __esm({
|
|
|
8665
8775
|
var index_exports = {};
|
|
8666
8776
|
__export(index_exports, {
|
|
8667
8777
|
ApiClient: () => ApiClient,
|
|
8778
|
+
AttributionTracker: () => AttributionTracker,
|
|
8668
8779
|
CAMPAIGN_ERROR_CODES: () => CAMPAIGN_ERROR_CODES,
|
|
8669
8780
|
CampaignError: () => CampaignError,
|
|
8670
8781
|
ERROR_CODES: () => PURCHASE_ERROR_CODES,
|
|
@@ -8699,6 +8810,7 @@ __export(index_exports, {
|
|
|
8699
8810
|
SessionError: () => SessionError,
|
|
8700
8811
|
SessionManager: () => SessionManager,
|
|
8701
8812
|
SubscriptionCache: () => SubscriptionCache,
|
|
8813
|
+
attributionTracker: () => attributionTracker,
|
|
8702
8814
|
createPurchaseError: () => createPurchaseError,
|
|
8703
8815
|
default: () => index_default,
|
|
8704
8816
|
detectDeviceLanguage: () => detectDeviceLanguage,
|
|
@@ -8761,6 +8873,7 @@ init_PurchaseError();
|
|
|
8761
8873
|
// src/index.ts
|
|
8762
8874
|
init_identity();
|
|
8763
8875
|
init_identity();
|
|
8876
|
+
init_identity();
|
|
8764
8877
|
init_notifications();
|
|
8765
8878
|
|
|
8766
8879
|
// src/domains/offering/index.ts
|
|
@@ -9432,7 +9545,6 @@ function useCampaignPreload() {
|
|
|
9432
9545
|
|
|
9433
9546
|
// src/hooks/useProductLoader.ts
|
|
9434
9547
|
var import_react22 = require("react");
|
|
9435
|
-
init_PaywalloClient();
|
|
9436
9548
|
function useProductLoader() {
|
|
9437
9549
|
const [products, setProducts] = (0, import_react22.useState)(/* @__PURE__ */ new Map());
|
|
9438
9550
|
const [isLoadingProducts, setIsLoadingProducts] = (0, import_react22.useState)(false);
|
|
@@ -9445,7 +9557,7 @@ function useProductLoader() {
|
|
|
9445
9557
|
for (const p of loaded) map.set(p.productId, p);
|
|
9446
9558
|
setProducts(map);
|
|
9447
9559
|
} catch (err) {
|
|
9448
|
-
|
|
9560
|
+
console.error("[Paywallo] refreshProducts failed", err);
|
|
9449
9561
|
} finally {
|
|
9450
9562
|
setIsLoadingProducts(false);
|
|
9451
9563
|
}
|
|
@@ -9455,7 +9567,6 @@ function useProductLoader() {
|
|
|
9455
9567
|
|
|
9456
9568
|
// src/hooks/usePurchaseOrchestrator.ts
|
|
9457
9569
|
var import_react23 = require("react");
|
|
9458
|
-
init_PaywalloClient();
|
|
9459
9570
|
init_paywall();
|
|
9460
9571
|
function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clearPreloadedWebView, setShowingPreloadedWebView, presentedAtRef, invalidateSubscriptionCache) {
|
|
9461
9572
|
const { trackDismissed, trackProductSelected, trackPurchased } = usePaywallTracking();
|
|
@@ -9489,7 +9600,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
9489
9600
|
clearPreloadedWebView();
|
|
9490
9601
|
resolvePreloadedPaywall({ presented: true, purchased: true, cancelled: false, restored: false });
|
|
9491
9602
|
} catch (error) {
|
|
9492
|
-
|
|
9603
|
+
console.error("[Paywallo] preloaded purchase failed", error);
|
|
9493
9604
|
setShowingPreloadedWebView(false);
|
|
9494
9605
|
clearPreloadedWebView();
|
|
9495
9606
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: false });
|
|
@@ -9510,7 +9621,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
9510
9621
|
clearPreloadedWebView();
|
|
9511
9622
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: true });
|
|
9512
9623
|
} catch (error) {
|
|
9513
|
-
|
|
9624
|
+
console.error("[Paywallo] preloaded restore failed", error);
|
|
9514
9625
|
setShowingPreloadedWebView(false);
|
|
9515
9626
|
clearPreloadedWebView();
|
|
9516
9627
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: false });
|
|
@@ -10163,6 +10274,7 @@ var index_default = Paywallo;
|
|
|
10163
10274
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10164
10275
|
0 && (module.exports = {
|
|
10165
10276
|
ApiClient,
|
|
10277
|
+
AttributionTracker,
|
|
10166
10278
|
CAMPAIGN_ERROR_CODES,
|
|
10167
10279
|
CampaignError,
|
|
10168
10280
|
ERROR_CODES,
|
|
@@ -10197,6 +10309,7 @@ var index_default = Paywallo;
|
|
|
10197
10309
|
SessionError,
|
|
10198
10310
|
SessionManager,
|
|
10199
10311
|
SubscriptionCache,
|
|
10312
|
+
attributionTracker,
|
|
10200
10313
|
createPurchaseError,
|
|
10201
10314
|
detectDeviceLanguage,
|
|
10202
10315
|
getCurrentLanguage,
|