@virex-tech/paywallo-sdk 1.0.0 → 1.0.1
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/LICENSE +1 -1
- package/{MonetySdk.podspec → PaywalloSdk.podspec} +4 -4
- package/README.md +19 -19
- package/android/build.gradle +1 -1
- package/dist/index.js +17 -121
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +17 -121
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -5
- package/react-native.config.js +3 -3
- package/android/src/main/java/com/monety/sdk/MonetySdkPackage.kt +0 -16
- package/android/src/main/java/com/monety/sdk/PanelStoreKitModule.kt +0 -315
- package/android/src/main/java/com/monety/sdk/PanelWebView.kt +0 -74
- package/android/src/main/java/com/monety/sdk/PanelWebViewManager.kt +0 -52
- package/ios/PanelStoreKit.m +0 -21
- package/ios/PanelStoreKit.swift +0 -245
- package/ios/PanelWebView.h +0 -15
- package/ios/PanelWebView.m +0 -182
- package/ios/PanelWebViewManager.m +0 -41
- package/ios/PanelWebViewModule.h +0 -8
- package/ios/PanelWebViewModule.m +0 -42
package/dist/index.js
CHANGED
|
@@ -224,8 +224,8 @@ async function loadKeychain() {
|
|
|
224
224
|
}
|
|
225
225
|
var KEYCHAIN_SERVICE_PREFIX = "com.paywallo.sdk.";
|
|
226
226
|
var SecureStorage = class {
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
|
228
|
+
constructor(_debug = false) {
|
|
229
229
|
}
|
|
230
230
|
/**
|
|
231
231
|
* Get a value, trying Keychain first (survives reinstalls on iOS), then AsyncStorage.
|
|
@@ -233,18 +233,15 @@ var SecureStorage = class {
|
|
|
233
233
|
async get(key) {
|
|
234
234
|
const keychainValue = await this.getFromKeychain(key);
|
|
235
235
|
if (keychainValue) {
|
|
236
|
-
this.log(`Retrieved ${key} from keychain`);
|
|
237
236
|
return keychainValue;
|
|
238
237
|
}
|
|
239
238
|
try {
|
|
240
239
|
const value = await import_async_storage.default.getItem(`@paywallo:${key}`);
|
|
241
240
|
if (value) {
|
|
242
|
-
this.log(`Retrieved ${key} from async storage`);
|
|
243
241
|
await this.setToKeychain(key, value);
|
|
244
242
|
}
|
|
245
243
|
return value;
|
|
246
|
-
} catch
|
|
247
|
-
this.log(`Storage read failed for ${key}:`, error);
|
|
244
|
+
} catch {
|
|
248
245
|
return null;
|
|
249
246
|
}
|
|
250
247
|
}
|
|
@@ -257,10 +254,8 @@ var SecureStorage = class {
|
|
|
257
254
|
import_async_storage.default.setItem(`@paywallo:${key}`, value),
|
|
258
255
|
this.setToKeychain(key, value)
|
|
259
256
|
]);
|
|
260
|
-
this.log(`Stored ${key} in storage`);
|
|
261
257
|
return true;
|
|
262
|
-
} catch
|
|
263
|
-
this.log(`Storage write failed for ${key}:`, error);
|
|
258
|
+
} catch {
|
|
264
259
|
return false;
|
|
265
260
|
}
|
|
266
261
|
}
|
|
@@ -270,10 +265,8 @@ var SecureStorage = class {
|
|
|
270
265
|
import_async_storage.default.removeItem(`@paywallo:${key}`),
|
|
271
266
|
this.removeFromKeychain(key)
|
|
272
267
|
]);
|
|
273
|
-
this.log(`Removed ${key} from storage`);
|
|
274
268
|
return true;
|
|
275
|
-
} catch
|
|
276
|
-
this.log(`Storage remove failed for ${key}:`, error);
|
|
269
|
+
} catch {
|
|
277
270
|
return false;
|
|
278
271
|
}
|
|
279
272
|
}
|
|
@@ -313,11 +306,6 @@ var SecureStorage = class {
|
|
|
313
306
|
return false;
|
|
314
307
|
}
|
|
315
308
|
}
|
|
316
|
-
log(...args) {
|
|
317
|
-
if (this.debug) {
|
|
318
|
-
console.warn("[Panel Storage]", ...args);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
309
|
};
|
|
322
310
|
var secureStorage = new SecureStorage();
|
|
323
311
|
|
|
@@ -642,21 +630,13 @@ var IAPService = class {
|
|
|
642
630
|
}
|
|
643
631
|
async loadProducts(productIds) {
|
|
644
632
|
if (!nativeStoreKit.isAvailable()) {
|
|
645
|
-
if (this.debug) console.warn("[Paywallo][Products] StoreKit not available");
|
|
646
633
|
return [];
|
|
647
634
|
}
|
|
648
635
|
try {
|
|
649
|
-
if (this.debug) console.warn("[Paywallo][Products] Loading from StoreKit:", productIds);
|
|
650
636
|
const products = await nativeStoreKit.getProducts(productIds);
|
|
651
|
-
if (this.debug) console.warn("[Paywallo][Products] StoreKit returned:", products.length, "products");
|
|
652
637
|
for (const product of products) {
|
|
653
|
-
if (this.debug) console.warn("[Paywallo][Products]", product.productId, "\u2192", product.localizedPrice, "(", product.currency, ")");
|
|
654
638
|
this.productsCache.set(product.productId, product);
|
|
655
639
|
}
|
|
656
|
-
if (products.length < productIds.length) {
|
|
657
|
-
const missing = productIds.filter((id) => !products.find((p) => p.productId === id));
|
|
658
|
-
if (this.debug) console.warn("[Paywallo][Products] Missing from StoreKit:", missing);
|
|
659
|
-
}
|
|
660
640
|
return products;
|
|
661
641
|
} catch (error) {
|
|
662
642
|
if (this.debug) console.warn("[Paywallo][Products] StoreKit error:", error);
|
|
@@ -674,7 +654,6 @@ var IAPService = class {
|
|
|
674
654
|
const product = this.productsCache.get(productId);
|
|
675
655
|
const platform = import_react_native2.Platform.OS;
|
|
676
656
|
const distinctId = PaywalloClient.getDistinctId();
|
|
677
|
-
if (this.debug) console.warn("[Paywallo][Purchase] Validating with server:", purchase.productId, "tx:", purchase.transactionId, "price:", product?.priceValue, product?.currency);
|
|
678
657
|
const validation = await apiClient.validatePurchase(
|
|
679
658
|
platform,
|
|
680
659
|
purchase.receipt,
|
|
@@ -687,33 +666,28 @@ var IAPService = class {
|
|
|
687
666
|
options?.paywallPlacement,
|
|
688
667
|
options?.variantKey
|
|
689
668
|
);
|
|
690
|
-
if (this.debug) console.warn("[Paywallo][Purchase] Server validation result:", JSON.stringify(validation));
|
|
691
669
|
return validation;
|
|
692
670
|
}
|
|
693
671
|
async finishTransaction(transactionId) {
|
|
694
672
|
try {
|
|
695
|
-
if (this.debug) console.warn("[Paywallo][Purchase] Finishing transaction:", transactionId);
|
|
696
673
|
await nativeStoreKit.finishTransaction(transactionId);
|
|
697
|
-
if (this.debug) console.warn("[Paywallo][Purchase] Transaction finished OK");
|
|
698
674
|
} catch (finishError) {
|
|
699
675
|
if (this.debug) console.warn("[Paywallo][Purchase] Failed to finish transaction:", finishError instanceof Error ? finishError.message : finishError);
|
|
700
676
|
}
|
|
701
677
|
}
|
|
702
678
|
async purchase(productId, options) {
|
|
703
679
|
if (!nativeStoreKit.isAvailable()) {
|
|
680
|
+
if (this.debug) console.warn("[Paywallo][Purchase] StoreKit not available");
|
|
704
681
|
return {
|
|
705
682
|
success: false,
|
|
706
683
|
error: new PurchaseError(PURCHASE_ERROR_CODES.STORE_NOT_AVAILABLE, "In-app purchases are not available on this device")
|
|
707
684
|
};
|
|
708
685
|
}
|
|
709
686
|
try {
|
|
710
|
-
if (this.debug) console.warn("[Paywallo][Purchase] StoreKit purchase starting:", productId);
|
|
711
687
|
const purchase = await nativeStoreKit.purchase(productId);
|
|
712
688
|
if (!purchase) {
|
|
713
|
-
if (this.debug) console.warn("[Paywallo][Purchase] StoreKit returned null (user cancelled or pending)");
|
|
714
689
|
return { success: false };
|
|
715
690
|
}
|
|
716
|
-
if (this.debug) console.warn("[Paywallo][Purchase] StoreKit OK \u2014 tx:", purchase.transactionId, "product:", purchase.productId, "receipt length:", purchase.receipt?.length);
|
|
717
691
|
let validation = null;
|
|
718
692
|
try {
|
|
719
693
|
validation = await this.validateWithServer(purchase, productId, options);
|
|
@@ -725,14 +699,12 @@ var IAPService = class {
|
|
|
725
699
|
};
|
|
726
700
|
}
|
|
727
701
|
if (!validation?.success) {
|
|
728
|
-
if (this.debug) console.warn("[Paywallo][Purchase] Validation returned failure:", validation?.error || "no validation result");
|
|
729
702
|
return {
|
|
730
703
|
success: false,
|
|
731
704
|
error: new PurchaseError(PURCHASE_ERROR_CODES.VALIDATION_FAILED, validation?.error ? `Server validation: ${validation.error}` : "Server validation failed")
|
|
732
705
|
};
|
|
733
706
|
}
|
|
734
707
|
await this.finishTransaction(purchase.transactionId);
|
|
735
|
-
if (this.debug) console.warn("[Paywallo][Purchase] COMPLETE \u2014 validated & finished:", purchase.productId);
|
|
736
708
|
return { success: true, purchase };
|
|
737
709
|
} catch (error) {
|
|
738
710
|
const e = error instanceof PurchaseError ? error : new PurchaseError(PURCHASE_ERROR_CODES.PURCHASE_FAILED, error instanceof Error ? error.message : String(error));
|
|
@@ -742,20 +714,16 @@ var IAPService = class {
|
|
|
742
714
|
}
|
|
743
715
|
async restore() {
|
|
744
716
|
if (!nativeStoreKit.isAvailable()) {
|
|
745
|
-
if (this.debug) console.warn("[Paywallo][Restore] StoreKit not available");
|
|
746
717
|
return [];
|
|
747
718
|
}
|
|
748
719
|
try {
|
|
749
|
-
if (this.debug) console.warn("[Paywallo][Restore] Getting active transactions...");
|
|
750
720
|
const transactions = await nativeStoreKit.getActiveTransactions();
|
|
751
|
-
if (this.debug) console.warn("[Paywallo][Restore] Found", transactions.length, "active transactions");
|
|
752
721
|
const apiClient = this.getApiClient();
|
|
753
722
|
const distinctId = PaywalloClient.getDistinctId();
|
|
754
723
|
const platform = import_react_native2.Platform.OS;
|
|
755
724
|
const results = await Promise.allSettled(
|
|
756
725
|
transactions.map((tx) => {
|
|
757
726
|
const product = this.productsCache.get(tx.productId);
|
|
758
|
-
if (this.debug) console.warn("[Paywallo][Restore] Validating tx:", tx.transactionId, "product:", tx.productId);
|
|
759
727
|
return apiClient.validatePurchase(
|
|
760
728
|
platform,
|
|
761
729
|
tx.receipt,
|
|
@@ -772,22 +740,18 @@ var IAPService = class {
|
|
|
772
740
|
for (let i = 0; i < results.length; i++) {
|
|
773
741
|
const r = results[i];
|
|
774
742
|
const tx = transactions[i];
|
|
775
|
-
if (this.debug) console.warn("[Paywallo][Restore] Validation:", r.status, r.status === "fulfilled" ? JSON.stringify(r.value) : r.reason?.message);
|
|
776
743
|
if (r.status === "fulfilled" && r.value.success) {
|
|
777
744
|
try {
|
|
778
745
|
await nativeStoreKit.finishTransaction(tx.transactionId);
|
|
779
|
-
if (this.debug) console.warn("[Paywallo][Restore] Finished tx:", tx.transactionId);
|
|
780
746
|
} catch (finishError) {
|
|
781
747
|
if (this.debug) console.warn("[Paywallo][Restore] Failed to finish tx:", tx.transactionId, finishError instanceof Error ? finishError.message : finishError);
|
|
782
748
|
}
|
|
783
749
|
validated.push(tx);
|
|
784
|
-
} else {
|
|
785
|
-
if (this.debug) console.warn("[Paywallo][Restore] Skipping unvalidated tx:", tx.transactionId);
|
|
786
750
|
}
|
|
787
751
|
}
|
|
788
752
|
return validated;
|
|
789
753
|
} catch (error) {
|
|
790
|
-
if (this.debug) console.warn("[Paywallo][Restore] FAILED:", error instanceof Error ? error.message : error);
|
|
754
|
+
if (this.debug) console.warn("[Paywallo][Restore] \u274C FAILED:", error instanceof Error ? error.message : error);
|
|
791
755
|
return [];
|
|
792
756
|
}
|
|
793
757
|
}
|
|
@@ -909,7 +873,6 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
909
873
|
}
|
|
910
874
|
onResult({ presented: true, purchased: false, cancelled: false, restored: true });
|
|
911
875
|
} else {
|
|
912
|
-
if (PaywalloClient.getConfig()?.debug) console.warn("[Paywallo] No purchases to restore");
|
|
913
876
|
onResult({ presented: true, purchased: false, cancelled: false, restored: false });
|
|
914
877
|
}
|
|
915
878
|
} catch (error) {
|
|
@@ -1045,7 +1008,7 @@ function buildPaywallInjectionScript(data) {
|
|
|
1045
1008
|
secondaryProductId: data.secondaryProductId
|
|
1046
1009
|
}
|
|
1047
1010
|
};
|
|
1048
|
-
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);}else{console.warn('[
|
|
1011
|
+
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);}else{console.warn('[Paywallo WV] FAILED to inject after '+m+' attempts');}}t();})();true;`;
|
|
1049
1012
|
}
|
|
1050
1013
|
function buildPurchaseStateScript(isPurchasing) {
|
|
1051
1014
|
return `if(window.receiveNativeMessage){window.receiveNativeMessage({type:"purchaseState",data:{isPurchasing:${isPurchasing}}});}true;`;
|
|
@@ -1204,16 +1167,13 @@ function PaywallModal({
|
|
|
1204
1167
|
const openAnim = (0, import_react5.useRef)(new import_react_native5.Animated.Value(SCREEN_HEIGHT2)).current;
|
|
1205
1168
|
(0, import_react5.useEffect)(() => {
|
|
1206
1169
|
if (visible) {
|
|
1207
|
-
if (PaywalloClient.getConfig()?.debug) console.warn("[Paywallo] PaywallModal opening \u2014 starting slide-up animation (550ms)");
|
|
1208
1170
|
openAnim.setValue(SCREEN_HEIGHT2);
|
|
1209
1171
|
import_react_native5.Animated.timing(openAnim, {
|
|
1210
1172
|
toValue: 0,
|
|
1211
1173
|
duration: 550,
|
|
1212
1174
|
easing: import_react_native5.Easing.out(import_react_native5.Easing.cubic),
|
|
1213
1175
|
useNativeDriver: true
|
|
1214
|
-
}).start(
|
|
1215
|
-
if (PaywalloClient.getConfig()?.debug) console.warn("[Paywallo] PaywallModal slide-up animation completed");
|
|
1216
|
-
});
|
|
1176
|
+
}).start();
|
|
1217
1177
|
}
|
|
1218
1178
|
}, [visible, openAnim]);
|
|
1219
1179
|
if (!visible) return null;
|
|
@@ -1617,8 +1577,7 @@ function buildConditionalFlagUrl(baseUrl, flagKey, context) {
|
|
|
1617
1577
|
}
|
|
1618
1578
|
|
|
1619
1579
|
// src/domains/iap/apiPurchaseMethods.ts
|
|
1620
|
-
async function validatePurchase(client, appKey, platform, receipt, productId, transactionId, priceLocal, currency, country, distinctId, paywallPlacement, variantKey
|
|
1621
|
-
if (debug) console.warn("[Paywallo][API] POST /purchases/validate", { platform, productId, transactionId, priceLocal, currency, country, distinctId, paywallPlacement, variantKey, receiptLen: receipt?.length });
|
|
1580
|
+
async function validatePurchase(client, appKey, platform, receipt, productId, transactionId, priceLocal, currency, country, distinctId, paywallPlacement, variantKey) {
|
|
1622
1581
|
const response = await client.post(
|
|
1623
1582
|
`/purchases/validate/${appKey}`,
|
|
1624
1583
|
{
|
|
@@ -1635,7 +1594,6 @@ async function validatePurchase(client, appKey, platform, receipt, productId, tr
|
|
|
1635
1594
|
},
|
|
1636
1595
|
false
|
|
1637
1596
|
);
|
|
1638
|
-
if (debug) console.warn("[Paywallo][API] Validation response:", JSON.stringify(response.data));
|
|
1639
1597
|
return response.data;
|
|
1640
1598
|
}
|
|
1641
1599
|
async function getSubscriptionStatus(client, baseUrl, appKey, distinctId) {
|
|
@@ -1713,11 +1671,6 @@ var HttpClient = class {
|
|
|
1713
1671
|
if (state.attempt < retryConfig.maxRetries) {
|
|
1714
1672
|
state.attempt++;
|
|
1715
1673
|
const delay = this.calculateDelay(state.attempt, retryConfig);
|
|
1716
|
-
this.log(`Retrying request (attempt ${state.attempt}/${retryConfig.maxRetries})`, {
|
|
1717
|
-
url,
|
|
1718
|
-
status: response.status,
|
|
1719
|
-
delay
|
|
1720
|
-
});
|
|
1721
1674
|
await this.sleep(delay);
|
|
1722
1675
|
continue;
|
|
1723
1676
|
}
|
|
@@ -1728,11 +1681,6 @@ var HttpClient = class {
|
|
|
1728
1681
|
if (this.isNetworkError(state.lastError) && state.attempt < retryConfig.maxRetries) {
|
|
1729
1682
|
state.attempt++;
|
|
1730
1683
|
const delay = this.calculateDelay(state.attempt, retryConfig);
|
|
1731
|
-
this.log(`Network error, retrying (attempt ${state.attempt}/${retryConfig.maxRetries})`, {
|
|
1732
|
-
url,
|
|
1733
|
-
error: state.lastError.message,
|
|
1734
|
-
delay
|
|
1735
|
-
});
|
|
1736
1684
|
await this.sleep(delay);
|
|
1737
1685
|
continue;
|
|
1738
1686
|
}
|
|
@@ -1750,11 +1698,6 @@ var HttpClient = class {
|
|
|
1750
1698
|
controller.abort();
|
|
1751
1699
|
}
|
|
1752
1700
|
}, timeout);
|
|
1753
|
-
this.log("Request starting", {
|
|
1754
|
-
url,
|
|
1755
|
-
method: options.method,
|
|
1756
|
-
headers: options.headers
|
|
1757
|
-
});
|
|
1758
1701
|
try {
|
|
1759
1702
|
const response = await fetch(url, {
|
|
1760
1703
|
...options,
|
|
@@ -1767,20 +1710,8 @@ var HttpClient = class {
|
|
|
1767
1710
|
data = await response.json();
|
|
1768
1711
|
} else {
|
|
1769
1712
|
const textData = await response.text();
|
|
1770
|
-
this.log("Non-JSON response received", {
|
|
1771
|
-
url,
|
|
1772
|
-
status: response.status,
|
|
1773
|
-
contentType,
|
|
1774
|
-
bodyPreview: textData.substring(0, 200)
|
|
1775
|
-
});
|
|
1776
1713
|
data = textData;
|
|
1777
1714
|
}
|
|
1778
|
-
this.log("Request completed", {
|
|
1779
|
-
url,
|
|
1780
|
-
status: response.status,
|
|
1781
|
-
ok: response.ok,
|
|
1782
|
-
contentType
|
|
1783
|
-
});
|
|
1784
1715
|
const headers = {};
|
|
1785
1716
|
response.headers.forEach((value, key) => {
|
|
1786
1717
|
headers[key] = value;
|
|
@@ -2063,7 +1994,6 @@ var OfflineQueueClass = class {
|
|
|
2063
1994
|
this.cleanupExpired();
|
|
2064
1995
|
this.cleanupTimer = setInterval(() => this.cleanupExpired(), 60 * 60 * 1e3);
|
|
2065
1996
|
this.initialized = true;
|
|
2066
|
-
this.log("OfflineQueue initialized", { queueSize: this.queue.length });
|
|
2067
1997
|
}
|
|
2068
1998
|
async loadFromStorage() {
|
|
2069
1999
|
try {
|
|
@@ -2094,7 +2024,6 @@ var OfflineQueueClass = class {
|
|
|
2094
2024
|
const before = this.queue.length;
|
|
2095
2025
|
this.queue = this.queue.filter((item) => Date.now() - item.timestamp < this.config.maxAge);
|
|
2096
2026
|
if (before !== this.queue.length) {
|
|
2097
|
-
this.log("Cleaned up expired items", { removed: before - this.queue.length });
|
|
2098
2027
|
void this.saveToStorage();
|
|
2099
2028
|
}
|
|
2100
2029
|
}
|
|
@@ -2111,7 +2040,6 @@ var OfflineQueueClass = class {
|
|
|
2111
2040
|
};
|
|
2112
2041
|
const existingIndex = this.findDuplicateIndex(item);
|
|
2113
2042
|
if (existingIndex !== -1) {
|
|
2114
|
-
this.log("Duplicate item found, updating timestamp", { id: this.queue[existingIndex].id });
|
|
2115
2043
|
this.queue[existingIndex].timestamp = Date.now();
|
|
2116
2044
|
await this.saveToStorage();
|
|
2117
2045
|
return this.queue[existingIndex];
|
|
@@ -2119,14 +2047,12 @@ var OfflineQueueClass = class {
|
|
|
2119
2047
|
if (this.queue.length >= this.config.maxItems) {
|
|
2120
2048
|
const removed = this.queue.shift();
|
|
2121
2049
|
if (removed) {
|
|
2122
|
-
this.log("Queue full, evicted oldest item:", removed.url);
|
|
2123
2050
|
this.emit({ type: "item:evicted", item: removed, queueSize: this.queue.length });
|
|
2124
2051
|
}
|
|
2125
2052
|
}
|
|
2126
2053
|
this.queue.push(item);
|
|
2127
2054
|
await this.saveToStorage();
|
|
2128
2055
|
this.emit({ type: "item:added", item, queueSize: this.queue.length });
|
|
2129
|
-
this.log("Item enqueued", { id: item.id, url: item.url });
|
|
2130
2056
|
return item;
|
|
2131
2057
|
}
|
|
2132
2058
|
findDuplicateIndex(item) {
|
|
@@ -2155,7 +2081,6 @@ var OfflineQueueClass = class {
|
|
|
2155
2081
|
this.processingLock = true;
|
|
2156
2082
|
this.processing = true;
|
|
2157
2083
|
this.emit({ type: "processing:start", queueSize: this.queue.length });
|
|
2158
|
-
this.log("Processing queue", { items: this.queue.length });
|
|
2159
2084
|
let processed = 0;
|
|
2160
2085
|
let failed = 0;
|
|
2161
2086
|
const delayMs = options?.delayBetweenItems ?? 100;
|
|
@@ -2172,7 +2097,6 @@ var OfflineQueueClass = class {
|
|
|
2172
2097
|
await this.removeItem(item.id);
|
|
2173
2098
|
processed++;
|
|
2174
2099
|
this.emit({ type: "item:success", item, queueSize: this.queue.length });
|
|
2175
|
-
this.log("Item processed successfully", { id: item.id });
|
|
2176
2100
|
} else {
|
|
2177
2101
|
const didFail = await this.handleItemFailure(item, void 0, permanent);
|
|
2178
2102
|
if (didFail) failed++;
|
|
@@ -2187,7 +2111,6 @@ var OfflineQueueClass = class {
|
|
|
2187
2111
|
this.processing = false;
|
|
2188
2112
|
this.processingLock = false;
|
|
2189
2113
|
this.emit({ type: "processing:end", queueSize: this.queue.length });
|
|
2190
|
-
this.log("Queue processing complete", { processed, failed, remaining: this.queue.length });
|
|
2191
2114
|
return { processed, failed };
|
|
2192
2115
|
}
|
|
2193
2116
|
/** Returns true if the item was permanently removed (counted as failed). */
|
|
@@ -2200,14 +2123,9 @@ var OfflineQueueClass = class {
|
|
|
2200
2123
|
error: error ?? new ClientError(CLIENT_ERROR_CODES.UNKNOWN, permanent ? "Permanent failure" : "Max attempts reached"),
|
|
2201
2124
|
queueSize: this.queue.length
|
|
2202
2125
|
});
|
|
2203
|
-
this.log(
|
|
2204
|
-
permanent ? "Item failed permanently - removed" : "Item failed after max attempts",
|
|
2205
|
-
{ id: item.id, attempts: item.attempts }
|
|
2206
|
-
);
|
|
2207
2126
|
return true;
|
|
2208
2127
|
}
|
|
2209
2128
|
await this.saveToStorage();
|
|
2210
|
-
this.log("Item will be retried", { id: item.id, attempts: item.attempts });
|
|
2211
2129
|
return false;
|
|
2212
2130
|
}
|
|
2213
2131
|
sleep(ms) {
|
|
@@ -2228,7 +2146,6 @@ var OfflineQueueClass = class {
|
|
|
2228
2146
|
async clear() {
|
|
2229
2147
|
this.queue = [];
|
|
2230
2148
|
await this.saveToStorage();
|
|
2231
|
-
this.log("Queue cleared");
|
|
2232
2149
|
}
|
|
2233
2150
|
async clearItemsWithInvalidAppKey(validAppKey) {
|
|
2234
2151
|
const before = this.queue.length;
|
|
@@ -2239,7 +2156,6 @@ var OfflineQueueClass = class {
|
|
|
2239
2156
|
const removed = before - this.queue.length;
|
|
2240
2157
|
if (removed > 0) {
|
|
2241
2158
|
await this.saveToStorage();
|
|
2242
|
-
this.log("Cleared items with invalid app key", { removed, validAppKey });
|
|
2243
2159
|
}
|
|
2244
2160
|
return removed;
|
|
2245
2161
|
}
|
|
@@ -2493,7 +2409,6 @@ var ApiClient = class {
|
|
|
2493
2409
|
this.environment = environment;
|
|
2494
2410
|
this.offlineQueueEnabled = offlineQueueEnabled;
|
|
2495
2411
|
this.httpClient = new HttpClient(this.baseUrl, { timeout, debug });
|
|
2496
|
-
this.log("ApiClient initialized", { baseUrl: this.baseUrl, environment, offlineQueueEnabled });
|
|
2497
2412
|
}
|
|
2498
2413
|
// ─── Infrastructure ──────────────────────────────────────────────────────────
|
|
2499
2414
|
/** Exposed only for QueueProcessor initialization. Prefer get()/post() for requests. */
|
|
@@ -2517,7 +2432,6 @@ var ApiClient = class {
|
|
|
2517
2432
|
}
|
|
2518
2433
|
setEnvironment(environment) {
|
|
2519
2434
|
this.environment = environment;
|
|
2520
|
-
this.log("Environment set to:", environment);
|
|
2521
2435
|
}
|
|
2522
2436
|
setDebug(debug) {
|
|
2523
2437
|
this.debug = debug;
|
|
@@ -2547,7 +2461,6 @@ var ApiClient = class {
|
|
|
2547
2461
|
}
|
|
2548
2462
|
// ─── Business methods ────────────────────────────────────────────────────────
|
|
2549
2463
|
async trackEvent(eventName, distinctId, properties, timestamp) {
|
|
2550
|
-
this.log("Tracking event:", eventName);
|
|
2551
2464
|
await this.postWithQueue("/api/v1/events", {
|
|
2552
2465
|
eventName,
|
|
2553
2466
|
distinctId,
|
|
@@ -2558,7 +2471,6 @@ var ApiClient = class {
|
|
|
2558
2471
|
}
|
|
2559
2472
|
async identify(distinctId, properties, email) {
|
|
2560
2473
|
await this.postWithQueue("/api/v1/identify", { distinctId, properties: properties ?? {}, email, platform: import_react_native7.Platform.OS }, "identify");
|
|
2561
|
-
this.log("Identity updated:", distinctId);
|
|
2562
2474
|
}
|
|
2563
2475
|
async startSession(distinctId, sessionId, platform) {
|
|
2564
2476
|
await this.postWithQueue("/api/v1/sessions/start", {
|
|
@@ -2567,12 +2479,10 @@ var ApiClient = class {
|
|
|
2567
2479
|
platform: platform ?? import_react_native7.Platform.OS,
|
|
2568
2480
|
environment: this.environment.toLowerCase()
|
|
2569
2481
|
}, `session.start:${sessionId}`);
|
|
2570
|
-
this.log("Session started:", sessionId);
|
|
2571
2482
|
return { success: true };
|
|
2572
2483
|
}
|
|
2573
2484
|
async endSession(sessionId, durationSeconds) {
|
|
2574
2485
|
await this.postWithQueue("/api/v1/sessions/end", { sessionId, durationSeconds }, `session.end:${sessionId}`);
|
|
2575
|
-
this.log("Session ended:", sessionId);
|
|
2576
2486
|
return { success: true };
|
|
2577
2487
|
}
|
|
2578
2488
|
async getVariant(flagKey, distinctId) {
|
|
@@ -2588,7 +2498,6 @@ var ApiClient = class {
|
|
|
2588
2498
|
this.cache.setVariant(key, v);
|
|
2589
2499
|
return v;
|
|
2590
2500
|
}
|
|
2591
|
-
this.log("Got variant:", flagKey, res.data);
|
|
2592
2501
|
this.cache.setVariant(key, res.data);
|
|
2593
2502
|
return res.data;
|
|
2594
2503
|
} catch (error) {
|
|
@@ -2607,7 +2516,6 @@ var ApiClient = class {
|
|
|
2607
2516
|
this.cache.setPaywall(placement, null);
|
|
2608
2517
|
return null;
|
|
2609
2518
|
}
|
|
2610
|
-
this.log("Got paywall:", placement);
|
|
2611
2519
|
this.cache.setPaywall(placement, res.data);
|
|
2612
2520
|
return res.data;
|
|
2613
2521
|
} catch (error) {
|
|
@@ -2656,8 +2564,7 @@ var ApiClient = class {
|
|
|
2656
2564
|
country,
|
|
2657
2565
|
distinctId,
|
|
2658
2566
|
paywallPlacement,
|
|
2659
|
-
variantKey
|
|
2660
|
-
this.debug
|
|
2567
|
+
variantKey
|
|
2661
2568
|
);
|
|
2662
2569
|
this.log("Purchase validated:", result.success);
|
|
2663
2570
|
return result;
|
|
@@ -2703,7 +2610,7 @@ var ApiClient = class {
|
|
|
2703
2610
|
}
|
|
2704
2611
|
}
|
|
2705
2612
|
log(...args) {
|
|
2706
|
-
if (this.debug) console.warn("[
|
|
2613
|
+
if (this.debug) console.warn("[Paywallo API]", ...args);
|
|
2707
2614
|
}
|
|
2708
2615
|
};
|
|
2709
2616
|
|
|
@@ -3029,7 +2936,6 @@ var SessionManager = class {
|
|
|
3029
2936
|
this.setupAppStateListener();
|
|
3030
2937
|
}
|
|
3031
2938
|
this.initialized = true;
|
|
3032
|
-
this.log("SessionManager initialized");
|
|
3033
2939
|
}
|
|
3034
2940
|
async startSession() {
|
|
3035
2941
|
this.ensureInitialized();
|
|
@@ -3045,7 +2951,6 @@ var SessionManager = class {
|
|
|
3045
2951
|
this.secureStorage.remove(EMERGENCY_PAYWALL_SHOWN_KEY)
|
|
3046
2952
|
]);
|
|
3047
2953
|
await this.trackSessionStart();
|
|
3048
|
-
this.log("Session started:", this.sessionId);
|
|
3049
2954
|
return this.sessionId;
|
|
3050
2955
|
}
|
|
3051
2956
|
async endSession() {
|
|
@@ -3060,7 +2965,6 @@ var SessionManager = class {
|
|
|
3060
2965
|
this.secureStorage.remove(SESSION_ID_KEY),
|
|
3061
2966
|
this.secureStorage.remove(SESSION_START_KEY)
|
|
3062
2967
|
]);
|
|
3063
|
-
this.log("Session ended");
|
|
3064
2968
|
}
|
|
3065
2969
|
getSessionId() {
|
|
3066
2970
|
return this.sessionId;
|
|
@@ -3256,12 +3160,8 @@ var InstallTracker = class {
|
|
|
3256
3160
|
attStatus: adIds.attStatus
|
|
3257
3161
|
});
|
|
3258
3162
|
const stored = await storage.set("install_tracked", String(installedAt));
|
|
3259
|
-
if (this.debug) {
|
|
3260
|
-
|
|
3261
|
-
console.warn("[Paywallo] Install event tracked");
|
|
3262
|
-
} else {
|
|
3263
|
-
console.warn("[Paywallo] Install event tracked but flag storage failed \u2014 may re-track on next launch");
|
|
3264
|
-
}
|
|
3163
|
+
if (this.debug && !stored) {
|
|
3164
|
+
console.warn("[Paywallo] Install event tracked but flag storage failed \u2014 may re-track on next launch");
|
|
3265
3165
|
}
|
|
3266
3166
|
} catch (error) {
|
|
3267
3167
|
if (this.debug) {
|
|
@@ -3348,7 +3248,6 @@ var PaywalloClientClass = class {
|
|
|
3348
3248
|
}
|
|
3349
3249
|
if (!isValidEventName(eventName)) {
|
|
3350
3250
|
const msg = `Invalid event name: "${eventName}". Use snake_case or $reserved_name.`;
|
|
3351
|
-
if (this.config?.debug) console.warn("[Paywallo]", msg);
|
|
3352
3251
|
throw new ClientError(CLIENT_ERROR_CODES.INVALID_EVENT_NAME, msg);
|
|
3353
3252
|
}
|
|
3354
3253
|
const sessionId = sessionManager.getSessionId();
|
|
@@ -3367,7 +3266,6 @@ var PaywalloClientClass = class {
|
|
|
3367
3266
|
}
|
|
3368
3267
|
if (!Number.isInteger(index) || index < 0) {
|
|
3369
3268
|
const msg = `Invalid stepIndex: "${index}". Must be a non-negative integer.`;
|
|
3370
|
-
if (this.config?.debug) console.warn("[Paywallo]", msg);
|
|
3371
3269
|
throw new AnalyticsError(ANALYTICS_ERROR_CODES.INVALID_STEP_INDEX, msg);
|
|
3372
3270
|
}
|
|
3373
3271
|
const now = Date.now();
|
|
@@ -3392,7 +3290,6 @@ var PaywalloClientClass = class {
|
|
|
3392
3290
|
}
|
|
3393
3291
|
if (!actionName || typeof actionName !== "string") {
|
|
3394
3292
|
const msg = `Invalid actionName: "${actionName}". Must be a non-empty string.`;
|
|
3395
|
-
if (this.config?.debug) console.warn("[Paywallo]", msg);
|
|
3396
3293
|
throw new AnalyticsError(ANALYTICS_ERROR_CODES.INVALID_ACTION_NAME, msg);
|
|
3397
3294
|
}
|
|
3398
3295
|
const sessionId = sessionManager.getSessionId();
|
|
@@ -3910,7 +3807,6 @@ var SubscriptionManagerClass = class {
|
|
|
3910
3807
|
if (config.cacheTTL) {
|
|
3911
3808
|
this.cache.setTTL(config.cacheTTL);
|
|
3912
3809
|
}
|
|
3913
|
-
this.log("SubscriptionManager initialized");
|
|
3914
3810
|
}
|
|
3915
3811
|
setUserId(userId) {
|
|
3916
3812
|
if (this.userId !== userId) {
|
|
@@ -4243,7 +4139,7 @@ function useProductLoader() {
|
|
|
4243
4139
|
for (const p of loaded) map.set(p.productId, p);
|
|
4244
4140
|
setProducts(map);
|
|
4245
4141
|
} catch (error) {
|
|
4246
|
-
if (PaywalloClient.getConfig()?.debug) console.warn("[
|
|
4142
|
+
if (PaywalloClient.getConfig()?.debug) console.warn("[Paywallo] Product load failed:", error);
|
|
4247
4143
|
} finally {
|
|
4248
4144
|
setIsLoadingProducts(false);
|
|
4249
4145
|
}
|
|
@@ -4282,7 +4178,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
4282
4178
|
clearPreloadedWebView();
|
|
4283
4179
|
resolvePreloadedPaywall({ presented: true, purchased: true, cancelled: false, restored: false });
|
|
4284
4180
|
} catch (error) {
|
|
4285
|
-
if (PaywalloClient.getConfig()?.debug) console.warn("[
|
|
4181
|
+
if (PaywalloClient.getConfig()?.debug) console.warn("[Paywallo] Preloaded purchase error:", error);
|
|
4286
4182
|
setShowingPreloadedWebView(false);
|
|
4287
4183
|
clearPreloadedWebView();
|
|
4288
4184
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: false });
|
|
@@ -4302,7 +4198,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
4302
4198
|
clearPreloadedWebView();
|
|
4303
4199
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: true });
|
|
4304
4200
|
} catch (error) {
|
|
4305
|
-
if (PaywalloClient.getConfig()?.debug) console.warn("[
|
|
4201
|
+
if (PaywalloClient.getConfig()?.debug) console.warn("[Paywallo] Preloaded restore error:", error);
|
|
4306
4202
|
setShowingPreloadedWebView(false);
|
|
4307
4203
|
clearPreloadedWebView();
|
|
4308
4204
|
resolvePreloadedPaywall({ presented: true, purchased: false, cancelled: false, restored: false });
|