@namiml/expo-sdk 3.4.5-dev.202607100416 → 3.4.5-dev.202607101515
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.cjs +82 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.mjs +83 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/index.ts +2 -1
- package/src/components/NamiView.tsx +6 -0
- package/src/components/elements/NamiSegmentPicker.tsx +10 -1
- package/src/nami.ts +20 -2
- package/src/products/productStore.ts +63 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _namiml_sdk_core from '@namiml/sdk-core';
|
|
2
|
-
import { IUIAdapter, IPaywall, NamiPaywallLaunchContext, FlowNavigationOptions, PaywallHandle,
|
|
2
|
+
import { IUIAdapter, IPaywall, NamiPaywallLaunchContext, FlowNavigationOptions, PaywallHandle, IPurchaseAdapter, NamiProductDetails, PurchaseContext, PurchaseResult, IStorageAdapter, IDeviceAdapter, DevicePayload, TDevice, ScreenInfo, Nami as Nami$1, NamiPaywallEvent, NamiCampaign, NamiFlow, TPaywallContext, ISkuMenu, FormFieldValidator, TimerState, NamiSKU, NamiAppSuppliedVideoDetails, TPaywallMedia, TComponent } from '@namiml/sdk-core';
|
|
3
3
|
export { CustomerJourneyState, FormFieldValidator, IPurchaseAdapter, NamiCampaign, NamiCampaignManager, NamiConfiguration, NamiCustomerManager, NamiEntitlement, NamiEntitlementManager, NamiFlow, NamiFlowEventHandler, NamiFlowHandoffStepHandler, NamiFlowManager, NamiHandoffAttributeValue, NamiHandoffComplete, NamiHandoffOutcome, NamiHandoffTag, NamiLanguageCodes, NamiLogLevel, NamiLoginSuccess, NamiPaywallAction, NamiPaywallEvent, NamiPaywallLaunchContext, NamiPaywallManager, NamiPermissionOutcome, NamiProductDetails, NamiPurchase, NamiPurchaseManager, NamiPurchaseSuccess, NamiSKU, NamiSKUType, NamiUserDataEnvelope, PurchaseContext, PurchaseResult, TTextInputComponent, TTextInputType } from '@namiml/sdk-core';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
|
|
@@ -31,6 +31,12 @@ declare class ExpoUIAdapter implements IUIAdapter {
|
|
|
31
31
|
onReset(): void;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
declare class ExpoPurchaseAdapter implements IPurchaseAdapter {
|
|
35
|
+
getProducts(skuIds: string[]): Promise<NamiProductDetails[]>;
|
|
36
|
+
purchase(skuId: string, context?: PurchaseContext): Promise<PurchaseResult>;
|
|
37
|
+
restorePurchases(): Promise<PurchaseResult[]>;
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
declare class ExpoStorageAdapter implements IStorageAdapter {
|
|
35
41
|
private db;
|
|
36
42
|
private memoryFallback;
|
|
@@ -52,12 +58,6 @@ declare class ExpoDeviceAdapter implements IDeviceAdapter {
|
|
|
52
58
|
getLanguage(): string;
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
declare class ExpoPurchaseAdapter implements IPurchaseAdapter {
|
|
56
|
-
getProducts(skuIds: string[]): Promise<NamiProductDetails[]>;
|
|
57
|
-
purchase(skuId: string, context?: PurchaseContext): Promise<PurchaseResult>;
|
|
58
|
-
restorePurchases(): Promise<PurchaseResult[]>;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
61
|
declare class Nami {
|
|
62
62
|
static get sdkVersion(): string;
|
|
63
63
|
static sdkPackageVersion(): string;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NAMI_SDK_PACKAGE_VERSION, registerPlatformAdapters, registerPurchaseAdapter, logger, Nami as Nami$1, PaywallState, initialState, getUrlParams, SMART_TEXT_PATTERN, VAR_REGEX, LIQUID_VARIABLE_REGEX, isAnonymousMode, NamiAPI, storageService, getDeviceScaleFactor, NamiEventEmitter, PAYWALL_ACTION_EVENT, NamiPaywallAction, NamiReservedActions, _internal, isValidUrl, isNamiFlowCampaign, hasAllPaywalls, getPaywallDataFromLabel, getPaywall } from '@namiml/sdk-core';
|
|
1
|
+
import { NAMI_SDK_PACKAGE_VERSION, registerPlatformAdapters, registerPurchaseAdapter, logger, NamiPaywallManager, Nami as Nami$1, PaywallState, initialState, getUrlParams, SMART_TEXT_PATTERN, VAR_REGEX, LIQUID_VARIABLE_REGEX, isAnonymousMode, NamiAPI, storageService, getDeviceScaleFactor, NamiEventEmitter, PAYWALL_ACTION_EVENT, NamiPaywallAction, NamiReservedActions, _internal, isValidUrl, isNamiFlowCampaign, hasAllPaywalls, getPaywallDataFromLabel, getPaywall } from '@namiml/sdk-core';
|
|
2
2
|
export { NamiCampaignManager, NamiCustomerManager, NamiEntitlementManager, NamiFlowManager, NamiHandoffTag, NamiPaywallManager, NamiPermissionOutcome, NamiPurchaseManager } from '@namiml/sdk-core';
|
|
3
3
|
import { Platform, Dimensions, StyleSheet, View, ScrollView, ImageBackground, BackHandler, ActivityIndicator, StatusBar, Animated } from 'react-native';
|
|
4
4
|
import require$$0, { createContext, useRef, useState, useEffect, useMemo, useContext, useCallback, useLayoutEffect } from 'react';
|
|
@@ -291,6 +291,7 @@ class ExpoPurchaseAdapter {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
const expoUIAdapter = new ExpoUIAdapter();
|
|
294
|
+
const expoPurchaseAdapter = new ExpoPurchaseAdapter();
|
|
294
295
|
let adaptersRegistered = false;
|
|
295
296
|
function registerExpoAdapters() {
|
|
296
297
|
if (adaptersRegistered) {
|
|
@@ -302,7 +303,7 @@ function registerExpoAdapters() {
|
|
|
302
303
|
device: new ExpoDeviceAdapter(),
|
|
303
304
|
ui: expoUIAdapter,
|
|
304
305
|
});
|
|
305
|
-
registerPurchaseAdapter(
|
|
306
|
+
registerPurchaseAdapter(expoPurchaseAdapter);
|
|
306
307
|
adaptersRegistered = true;
|
|
307
308
|
}
|
|
308
309
|
catch (error) {
|
|
@@ -311,6 +312,79 @@ function registerExpoAdapters() {
|
|
|
311
312
|
}
|
|
312
313
|
registerExpoAdapters();
|
|
313
314
|
|
|
315
|
+
// Accumulated store product details, keyed by product_ref_id (== sku_ref_id).
|
|
316
|
+
const productsById = new Map();
|
|
317
|
+
// Serializes backfill runs so concurrent launches/prefetches don't double-fetch
|
|
318
|
+
// or race the map (parity with the Apple SDK's backfillTaskLock).
|
|
319
|
+
let pending = Promise.resolve(false);
|
|
320
|
+
/** Collect unique store product ids (sku_ref_id) from the given paywalls' sku menus. */
|
|
321
|
+
function collectSkuRefIds(paywalls) {
|
|
322
|
+
const ids = new Set();
|
|
323
|
+
for (const paywall of paywalls ?? []) {
|
|
324
|
+
for (const menu of paywall?.sku_menus ?? []) {
|
|
325
|
+
for (const sku of menu?.products ?? []) {
|
|
326
|
+
if (sku?.sku_ref_id)
|
|
327
|
+
ids.add(sku.sku_ref_id);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return [...ids];
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Fetch store product details for any of `skuRefIds` not already loaded, merge them into
|
|
335
|
+
* the accumulated set, and push the union to core via NamiPaywallManager.setProductDetails.
|
|
336
|
+
* Serialized; returns whether new products were added. Never throws.
|
|
337
|
+
*/
|
|
338
|
+
function backfill(skuRefIds) {
|
|
339
|
+
pending = pending.then(() => backfillOnce(skuRefIds));
|
|
340
|
+
return pending;
|
|
341
|
+
}
|
|
342
|
+
async function backfillOnce(skuRefIds) {
|
|
343
|
+
const missing = [...new Set(skuRefIds)].filter((id) => id && !productsById.has(id));
|
|
344
|
+
if (!missing.length)
|
|
345
|
+
return false;
|
|
346
|
+
try {
|
|
347
|
+
const products = await expoPurchaseAdapter.getProducts(missing);
|
|
348
|
+
let added = false;
|
|
349
|
+
for (const product of products ?? []) {
|
|
350
|
+
if (product?.product_ref_id) {
|
|
351
|
+
productsById.set(product.product_ref_id, product);
|
|
352
|
+
added = true;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (added) {
|
|
356
|
+
NamiPaywallManager.setProductDetails([...productsById.values()]);
|
|
357
|
+
}
|
|
358
|
+
return added;
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
logger.warn('[NamiExpo] Failed to load store products.', error);
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/** Clear accumulated products. Called on Nami.reset so reconfigure doesn't serve stale data. */
|
|
366
|
+
function reset() {
|
|
367
|
+
pending = pending.then(() => {
|
|
368
|
+
productsById.clear();
|
|
369
|
+
return false;
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Prefetch StoreKit/Play product details for every configured paywall's SKUs so that
|
|
375
|
+
* prices are available before any paywall mounts (mirrors the Apple SDK startup load).
|
|
376
|
+
* Fire-and-forget and error-safe: a failure here never blocks configure.
|
|
377
|
+
*/
|
|
378
|
+
async function prefetchProducts() {
|
|
379
|
+
try {
|
|
380
|
+
const ids = collectSkuRefIds(NamiPaywallManager.allPaywalls());
|
|
381
|
+
if (ids.length)
|
|
382
|
+
await backfill(ids);
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
logger.warn('[NamiExpo] Product prefetch skipped.', error);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
314
388
|
class Nami {
|
|
315
389
|
static get sdkVersion() {
|
|
316
390
|
return Nami$1.sdkVersion();
|
|
@@ -319,9 +393,12 @@ class Nami {
|
|
|
319
393
|
return Nami$1.sdkPackageVersion();
|
|
320
394
|
}
|
|
321
395
|
static async configure(config) {
|
|
322
|
-
|
|
396
|
+
const result = await Nami$1.configure(config);
|
|
397
|
+
void prefetchProducts();
|
|
398
|
+
return result;
|
|
323
399
|
}
|
|
324
400
|
static async reset() {
|
|
401
|
+
reset();
|
|
325
402
|
await Nami$1.reset?.();
|
|
326
403
|
}
|
|
327
404
|
}
|
|
@@ -3705,6 +3782,9 @@ const NamiView = ({ placement, url, onClose, onSignIn, onDeepLink, onPurchase, o
|
|
|
3705
3782
|
launchCacheRef.current.set(cacheKey, nextLaunch);
|
|
3706
3783
|
}
|
|
3707
3784
|
prewarmPaywallFonts([paywall, ...flowPaywalls]);
|
|
3785
|
+
const launchSkuRefIds = collectSkuRefIds([paywall, ...flowPaywalls].filter((item) => item != null));
|
|
3786
|
+
if (launchSkuRefIds.length)
|
|
3787
|
+
void backfill(launchSkuRefIds);
|
|
3708
3788
|
if (initialPaywall?.fonts) {
|
|
3709
3789
|
void prepareAndLoadFontsWithTimeout(initialPaywall.fonts);
|
|
3710
3790
|
}
|