expo-superwall 1.1.1 → 1.1.2
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/CHANGELOG.md
CHANGED
package/android/build.gradle
CHANGED
|
@@ -43,7 +43,7 @@ android {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
dependencies {
|
|
46
|
-
implementation "com.superwall.sdk:superwall-android:2.7.
|
|
46
|
+
implementation "com.superwall.sdk:superwall-android:2.7.15"
|
|
47
47
|
implementation 'com.android.billingclient:billing:8.0.0'
|
|
48
48
|
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2'
|
|
49
49
|
}
|
package/build/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePlacement.d.ts","sourceRoot":"","sources":["../../src/usePlacement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,oBAAoB,EACrB,MAAM,6BAA6B,CAAA;AAKpC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GACjD;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAC9C,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;IACrE,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAA;IAC/C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,CAAA;CACtG;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,YAAY,CAAC,SAAS,GAAE,qBAA0B;iEAmDvB,qBAAqB;;
|
|
1
|
+
{"version":3,"file":"usePlacement.d.ts","sourceRoot":"","sources":["../../src/usePlacement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,oBAAoB,EACrB,MAAM,6BAA6B,CAAA;AAKpC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GACjD;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAC9C,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;IACrE,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAA;IAC/C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,CAAA;CACtG;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,YAAY,CAAC,SAAS,GAAE,qBAA0B;iEAmDvB,qBAAqB;;EAiB/D"}
|
|
@@ -63,21 +63,16 @@ export function usePlacement(callbacks = {}) {
|
|
|
63
63
|
handlerId: id,
|
|
64
64
|
onPaywallDismiss(info, result) {
|
|
65
65
|
setState({ status: "dismissed", result });
|
|
66
|
-
if (result.type === "purchased" || result.type === "restored") {
|
|
67
|
-
runPendingFeature();
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
clearPendingFeature();
|
|
71
|
-
}
|
|
72
66
|
callbacks.onDismiss?.(info, result);
|
|
73
67
|
},
|
|
74
68
|
onPaywallSkip(reason) {
|
|
75
69
|
setState({ status: "skipped", reason });
|
|
76
|
-
runPendingFeature();
|
|
77
70
|
callbacks.onSkip?.(reason);
|
|
78
71
|
},
|
|
79
72
|
onPaywallError(error) {
|
|
80
73
|
setState({ status: "error", error });
|
|
74
|
+
// Native won't resolve the register promise on error, so drop the pending
|
|
75
|
+
// feature here to avoid firing it on a later unrelated registerPlacement.
|
|
81
76
|
clearPendingFeature();
|
|
82
77
|
callbacks.onError?.(error);
|
|
83
78
|
},
|
|
@@ -91,16 +86,22 @@ export function usePlacement(callbacks = {}) {
|
|
|
91
86
|
registerPlacement: state.registerPlacement,
|
|
92
87
|
}));
|
|
93
88
|
/* -------------------- Helpers -------------------- */
|
|
89
|
+
// The native module passes a feature closure to Superwall.register; that closure
|
|
90
|
+
// resolves this promise. The native SDK only invokes it when access is granted —
|
|
91
|
+
// including Non-Gated dismissals, skips, and successful purchases — so awaiting
|
|
92
|
+
// the promise is the correct gate for running `feature`. Letting JS infer this
|
|
93
|
+
// from dismiss `result.type` is wrong: it can't distinguish Gated from Non-Gated.
|
|
94
94
|
const registerPlacement = useCallback(async ({ placement, params, feature }) => {
|
|
95
95
|
pendingFeatureRef.current = feature;
|
|
96
96
|
try {
|
|
97
97
|
await storeRegisterPlacement(placement, params, id);
|
|
98
|
+
runPendingFeature();
|
|
98
99
|
}
|
|
99
100
|
catch (error) {
|
|
100
|
-
|
|
101
|
+
clearPendingFeature();
|
|
101
102
|
throw error;
|
|
102
103
|
}
|
|
103
|
-
}, [storeRegisterPlacement, id]);
|
|
104
|
+
}, [storeRegisterPlacement, id, runPendingFeature, clearPendingFeature]);
|
|
104
105
|
return {
|
|
105
106
|
registerPlacement,
|
|
106
107
|
state,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePlacement.js","sourceRoot":"","sources":["../../src/usePlacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAS5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAmDzD,iDAAiD;AACjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,YAAY,CAAC,YAAmC,EAAE;IAChE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAA;IAElB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACpE,MAAM,iBAAiB,GAAG,MAAM,CAAmC,SAAS,CAAC,CAAA;IAE7E,MAAM,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3C,iBAAiB,CAAC,OAAO,GAAG,SAAS,CAAA;IACvC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAA;QACzC,iBAAiB,CAAC,OAAO,GAAG,SAAS,CAAA;QACrC,OAAO,EAAE,EAAE,CAAA;IACb,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,kBAAkB,CAAC;QACjB,SAAS,EAAE,EAAE;QACb,gBAAgB,CAAC,IAAI,EAAE,MAAM;YAC3B,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;YACzC,
|
|
1
|
+
{"version":3,"file":"usePlacement.js","sourceRoot":"","sources":["../../src/usePlacement.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useId, useRef, useState } from \"react\"\n\nimport type {\n CustomCallback,\n CustomCallbackResult,\n PaywallInfo,\n PaywallResult,\n PaywallSkippedReason,\n} from \"./SuperwallExpoModule.types\"\nimport { useSuperwall } from \"./useSuperwall\"\nimport { useSuperwallEvents } from \"./useSuperwallEvents\"\n\n// -------------------- Types --------------------\n/**\n * @category Hooks\n * @since 0.0.15\n * Possible states returned by `usePlacement`.\n */\nexport type PaywallState =\n | { status: \"idle\" }\n | { status: \"presented\"; paywallInfo: PaywallInfo }\n | { status: \"dismissed\"; result: PaywallResult }\n | { status: \"skipped\"; reason: PaywallSkippedReason }\n | { status: \"error\"; error: string }\n\n/**\n * @category Hooks\n * @since 0.0.15\n */\nexport interface usePlacementCallbacks {\n /** Called when a paywall is presented. */\n onPresent?: (paywallInfo: PaywallInfo) => void\n /** Called when a paywall is dismissed. */\n onDismiss?: (paywallInfo: PaywallInfo, result: PaywallResult) => void\n /** Called when a paywall is skipped. */\n onSkip?: (reason: PaywallSkippedReason) => void\n /** Called when a paywall fails to present or another SDK error occurs. */\n onError?: (error: string) => void\n /**\n * Called when a custom callback is invoked from a paywall.\n * Return a result to send back to the paywall.\n */\n onCustomCallback?: (callback: CustomCallback) => Promise<CustomCallbackResult> | CustomCallbackResult\n}\n\n/**\n * @category Hooks\n * @since 0.0.15\n */\nexport interface RegisterPlacementArgs {\n /** The placement name defined on the Superwall dashboard. */\n placement: string\n /** Optional parameters passed to the placement. */\n params?: Record<string, any>\n /**\n * An optional feature/function to execute if the placement does **not** result\n * in a paywall presentation – i.e. the user is allowed through.\n */\n feature?: () => void\n}\n\n// -------------------- Hook --------------------\n/**\n * @category Hooks\n * @since 0.0.15\n * React hook for managing paywall presentation based on placements.\n *\n * This hook provides a way to register placements configured on the Superwall dashboard.\n * It handles the state of paywall presentation (`PaywallState`) and allows you\n * to define callbacks for various paywall lifecycle events (`usePlacementCallbacks`).\n *\n * It must be used within a component that is a descendant of `<SuperwallProvider />`.\n *\n * @param callbacks - An optional object containing callback functions for paywall events\n * like `onPresent`, `onDismiss`, `onSkip`, and `onError`.\n * @returns An object containing:\n * - `registerPlacement: (args: RegisterPlacementArgs) => Promise<void>`:\n * A function to register a placement and potentially trigger a paywall.\n * - `args.placement`: The placement name defined on the Superwall dashboard.\n * - `args.params`: Optional parameters to pass to the placement.\n * - `args.feature`: An optional function to execute if the placement does not result\n * in a paywall presentation (e.g., user is already subscribed or part of a holdout).\n * - `state: PaywallState`: The current state of the paywall interaction for this hook instance.\n * This includes states like \"idle\", \"presented\", \"dismissed\", \"skipped\", or \"error\".\n *\n * @example\n * const { registerPlacement, state } = usePlacement({\n * onPresent: (paywallInfo) => console.log(\"Paywall presented:\", paywallInfo.name),\n * onDismiss: (paywallInfo, result) => console.log(\"Paywall dismissed:\", result.type),\n * onSkip: (reason) => console.log(\"Paywall skipped:\", reason.type),\n * onError: (error) => console.error(\"Paywall error:\", error),\n * });\n *\n * const showMyFeaturePaywall = async () => {\n * await registerPlacement({\n * placement: \"MyFeaturePlacement\",\n * feature: () => {\n * // Logic to execute if paywall is not shown (e.g., navigate to feature)\n * console.log(\"Accessing feature directly.\");\n * }\n * });\n * };\n *\n * // In your component:\n * // <Button title=\"Unlock Feature\" onPress={showMyFeaturePaywall} />\n * // <Text>Current paywall state: {state.status}</Text>\n */\nexport function usePlacement(callbacks: usePlacementCallbacks = {}) {\n const id = useId()\n\n const [state, setState] = useState<PaywallState>({ status: \"idle\" })\n const pendingFeatureRef = useRef<RegisterPlacementArgs[\"feature\"]>(undefined)\n\n const clearPendingFeature = useCallback(() => {\n pendingFeatureRef.current = undefined\n }, [])\n\n const runPendingFeature = useCallback(() => {\n const feature = pendingFeatureRef.current\n pendingFeatureRef.current = undefined\n feature?.()\n }, [])\n\n useSuperwallEvents({\n handlerId: id,\n onPaywallDismiss(info, result) {\n setState({ status: \"dismissed\", result })\n callbacks.onDismiss?.(info, result)\n },\n onPaywallSkip(reason) {\n setState({ status: \"skipped\", reason })\n callbacks.onSkip?.(reason)\n },\n onPaywallError(error) {\n setState({ status: \"error\", error })\n // Native won't resolve the register promise on error, so drop the pending\n // feature here to avoid firing it on a later unrelated registerPlacement.\n clearPendingFeature()\n callbacks.onError?.(error)\n },\n onPaywallPresent(info) {\n setState({ status: \"presented\", paywallInfo: info })\n callbacks.onPresent?.(info)\n },\n onCustomCallback: callbacks.onCustomCallback,\n })\n\n const { registerPlacement: storeRegisterPlacement } = useSuperwall((state) => ({\n registerPlacement: state.registerPlacement,\n }))\n\n /* -------------------- Helpers -------------------- */\n // The native module passes a feature closure to Superwall.register; that closure\n // resolves this promise. The native SDK only invokes it when access is granted —\n // including Non-Gated dismissals, skips, and successful purchases — so awaiting\n // the promise is the correct gate for running `feature`. Letting JS infer this\n // from dismiss `result.type` is wrong: it can't distinguish Gated from Non-Gated.\n const registerPlacement = useCallback(\n async ({ placement, params, feature }: RegisterPlacementArgs) => {\n pendingFeatureRef.current = feature\n try {\n await storeRegisterPlacement(placement, params, id)\n runPendingFeature()\n } catch (error) {\n clearPendingFeature()\n throw error\n }\n },\n [storeRegisterPlacement, id, runPendingFeature, clearPendingFeature],\n )\n\n return {\n registerPlacement,\n state,\n } as const\n}\n"]}
|