@chipmobilesdk/rn-ads 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +139 -0
- package/README.md +4 -2
- package/lib/commonjs/config/resolveAdUnit.js +80 -0
- package/lib/commonjs/config/resolveAdUnit.js.map +1 -0
- package/lib/commonjs/config/types.js +138 -0
- package/lib/commonjs/config/types.js.map +1 -0
- package/lib/commonjs/config/validate.js +150 -0
- package/lib/commonjs/config/validate.js.map +1 -0
- package/lib/commonjs/core/adOriginatedReturn.js +119 -0
- package/lib/commonjs/core/adOriginatedReturn.js.map +1 -0
- package/lib/commonjs/core/adsInstance.js +129 -0
- package/lib/commonjs/core/adsInstance.js.map +1 -0
- package/lib/commonjs/core/consentFlow.js +154 -0
- package/lib/commonjs/core/consentFlow.js.map +1 -0
- package/lib/commonjs/core/enablement.js +64 -0
- package/lib/commonjs/core/enablement.js.map +1 -0
- package/lib/commonjs/core/fullScreenLock.js +48 -0
- package/lib/commonjs/core/fullScreenLock.js.map +1 -0
- package/lib/commonjs/core/gates.js +95 -0
- package/lib/commonjs/core/gates.js.map +1 -0
- package/lib/commonjs/core/initMachine.js +159 -0
- package/lib/commonjs/core/initMachine.js.map +1 -0
- package/lib/commonjs/core/instance/consent.js +155 -0
- package/lib/commonjs/core/instance/consent.js.map +1 -0
- package/lib/commonjs/core/instance/context.js +217 -0
- package/lib/commonjs/core/instance/context.js.map +1 -0
- package/lib/commonjs/core/instance/gate.js +194 -0
- package/lib/commonjs/core/instance/gate.js.map +1 -0
- package/lib/commonjs/core/instance/init.js +326 -0
- package/lib/commonjs/core/instance/init.js.map +1 -0
- package/lib/commonjs/core/instance/internals.js +115 -0
- package/lib/commonjs/core/instance/internals.js.map +1 -0
- package/lib/commonjs/core/instance/load.js +458 -0
- package/lib/commonjs/core/instance/load.js.map +1 -0
- package/lib/commonjs/core/instance/show.js +243 -0
- package/lib/commonjs/core/instance/show.js.map +1 -0
- package/lib/commonjs/core/instance/types.js +6 -0
- package/lib/commonjs/core/instance/types.js.map +1 -0
- package/lib/commonjs/core/placementMachine.js +116 -0
- package/lib/commonjs/core/placementMachine.js.map +1 -0
- package/lib/commonjs/core/privacyGate.js +93 -0
- package/lib/commonjs/core/privacyGate.js.map +1 -0
- package/lib/commonjs/core/requestThrottle.js +152 -0
- package/lib/commonjs/core/requestThrottle.js.map +1 -0
- package/lib/commonjs/core/retryPolicy.js +120 -0
- package/lib/commonjs/core/retryPolicy.js.map +1 -0
- package/lib/commonjs/core/rewardedSession.js +65 -0
- package/lib/commonjs/core/rewardedSession.js.map +1 -0
- package/lib/commonjs/core/timers.js +162 -0
- package/lib/commonjs/core/timers.js.map +1 -0
- package/lib/commonjs/diagnostics/correlation.js +33 -0
- package/lib/commonjs/diagnostics/correlation.js.map +1 -0
- package/lib/commonjs/diagnostics/errors.js +152 -0
- package/lib/commonjs/diagnostics/errors.js.map +1 -0
- package/lib/commonjs/diagnostics/events.js +132 -0
- package/lib/commonjs/diagnostics/events.js.map +1 -0
- package/lib/commonjs/engine/admobBanner.js +58 -0
- package/lib/commonjs/engine/admobBanner.js.map +1 -0
- package/lib/commonjs/engine/admobEngine.js +343 -0
- package/lib/commonjs/engine/admobEngine.js.map +1 -0
- package/lib/commonjs/engine/admobErrors.js +45 -0
- package/lib/commonjs/engine/admobErrors.js.map +1 -0
- package/lib/commonjs/engine/port.js +6 -0
- package/lib/commonjs/engine/port.js.map +1 -0
- package/lib/commonjs/engine/testAdUnits.js +61 -0
- package/lib/commonjs/engine/testAdUnits.js.map +1 -0
- package/lib/commonjs/index.js +218 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/react/AdsBanner.js +317 -0
- package/lib/commonjs/react/AdsBanner.js.map +1 -0
- package/lib/commonjs/react/AdsProvider.js +54 -0
- package/lib/commonjs/react/AdsProvider.js.map +1 -0
- package/lib/commonjs/react/hooks.js +63 -0
- package/lib/commonjs/react/hooks.js.map +1 -0
- package/lib/commonjs/testing/clock.js +76 -0
- package/lib/commonjs/testing/clock.js.map +1 -0
- package/lib/commonjs/testing/conformance.js +99 -0
- package/lib/commonjs/testing/conformance.js.map +1 -0
- package/lib/commonjs/testing/index.js +389 -0
- package/lib/commonjs/testing/index.js.map +1 -0
- package/lib/module/config/resolveAdUnit.js +75 -0
- package/lib/module/config/resolveAdUnit.js.map +1 -0
- package/lib/module/config/types.js +134 -0
- package/lib/module/config/types.js.map +1 -0
- package/lib/module/config/validate.js +146 -0
- package/lib/module/config/validate.js.map +1 -0
- package/lib/module/core/adOriginatedReturn.js +115 -0
- package/lib/module/core/adOriginatedReturn.js.map +1 -0
- package/lib/module/core/adsInstance.js +121 -0
- package/lib/module/core/adsInstance.js.map +1 -0
- package/lib/module/core/consentFlow.js +143 -0
- package/lib/module/core/consentFlow.js.map +1 -0
- package/lib/module/core/enablement.js +58 -0
- package/lib/module/core/enablement.js.map +1 -0
- package/lib/module/core/fullScreenLock.js +44 -0
- package/lib/module/core/fullScreenLock.js.map +1 -0
- package/lib/module/core/gates.js +91 -0
- package/lib/module/core/gates.js.map +1 -0
- package/lib/module/core/initMachine.js +152 -0
- package/lib/module/core/initMachine.js.map +1 -0
- package/lib/module/core/instance/consent.js +151 -0
- package/lib/module/core/instance/consent.js.map +1 -0
- package/lib/module/core/instance/context.js +212 -0
- package/lib/module/core/instance/context.js.map +1 -0
- package/lib/module/core/instance/gate.js +183 -0
- package/lib/module/core/instance/gate.js.map +1 -0
- package/lib/module/core/instance/init.js +321 -0
- package/lib/module/core/instance/init.js.map +1 -0
- package/lib/module/core/instance/internals.js +109 -0
- package/lib/module/core/instance/internals.js.map +1 -0
- package/lib/module/core/instance/load.js +452 -0
- package/lib/module/core/instance/load.js.map +1 -0
- package/lib/module/core/instance/show.js +238 -0
- package/lib/module/core/instance/show.js.map +1 -0
- package/lib/module/core/instance/types.js +4 -0
- package/lib/module/core/instance/types.js.map +1 -0
- package/lib/module/core/placementMachine.js +109 -0
- package/lib/module/core/placementMachine.js.map +1 -0
- package/lib/module/core/privacyGate.js +86 -0
- package/lib/module/core/privacyGate.js.map +1 -0
- package/lib/module/core/requestThrottle.js +146 -0
- package/lib/module/core/requestThrottle.js.map +1 -0
- package/lib/module/core/retryPolicy.js +113 -0
- package/lib/module/core/retryPolicy.js.map +1 -0
- package/lib/module/core/rewardedSession.js +61 -0
- package/lib/module/core/rewardedSession.js.map +1 -0
- package/lib/module/core/timers.js +150 -0
- package/lib/module/core/timers.js.map +1 -0
- package/lib/module/diagnostics/correlation.js +29 -0
- package/lib/module/diagnostics/correlation.js.map +1 -0
- package/lib/module/diagnostics/errors.js +143 -0
- package/lib/module/diagnostics/errors.js.map +1 -0
- package/lib/module/diagnostics/events.js +128 -0
- package/lib/module/diagnostics/events.js.map +1 -0
- package/lib/module/engine/admobBanner.js +52 -0
- package/lib/module/engine/admobBanner.js.map +1 -0
- package/lib/module/engine/admobEngine.js +334 -0
- package/lib/module/engine/admobEngine.js.map +1 -0
- package/lib/module/engine/admobErrors.js +41 -0
- package/lib/module/engine/admobErrors.js.map +1 -0
- package/lib/module/engine/port.js +4 -0
- package/lib/module/engine/port.js.map +1 -0
- package/lib/module/engine/testAdUnits.js +56 -0
- package/lib/module/engine/testAdUnits.js.map +1 -0
- package/lib/module/index.js +59 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/react/AdsBanner.js +312 -0
- package/lib/module/react/AdsBanner.js.map +1 -0
- package/lib/module/react/AdsProvider.js +48 -0
- package/lib/module/react/AdsProvider.js.map +1 -0
- package/lib/module/react/hooks.js +58 -0
- package/lib/module/react/hooks.js.map +1 -0
- package/lib/module/testing/clock.js +72 -0
- package/lib/module/testing/clock.js.map +1 -0
- package/lib/module/testing/conformance.js +93 -0
- package/lib/module/testing/conformance.js.map +1 -0
- package/lib/module/testing/index.js +366 -0
- package/lib/module/testing/index.js.map +1 -0
- package/lib/typescript/commonjs/config/resolveAdUnit.d.ts +43 -0
- package/lib/typescript/commonjs/config/resolveAdUnit.d.ts.map +1 -0
- package/lib/typescript/commonjs/config/types.d.ts +280 -0
- package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/config/validate.d.ts +49 -0
- package/lib/typescript/commonjs/config/validate.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/adOriginatedReturn.d.ts +61 -0
- package/lib/typescript/commonjs/core/adOriginatedReturn.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/adsInstance.d.ts +33 -0
- package/lib/typescript/commonjs/core/adsInstance.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/consentFlow.d.ts +84 -0
- package/lib/typescript/commonjs/core/consentFlow.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/enablement.d.ts +74 -0
- package/lib/typescript/commonjs/core/enablement.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/fullScreenLock.d.ts +25 -0
- package/lib/typescript/commonjs/core/fullScreenLock.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/gates.d.ts +76 -0
- package/lib/typescript/commonjs/core/gates.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/initMachine.d.ts +66 -0
- package/lib/typescript/commonjs/core/initMachine.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/consent.d.ts +4 -0
- package/lib/typescript/commonjs/core/instance/consent.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/context.d.ts +118 -0
- package/lib/typescript/commonjs/core/instance/context.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/gate.d.ts +38 -0
- package/lib/typescript/commonjs/core/instance/gate.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/init.d.ts +13 -0
- package/lib/typescript/commonjs/core/instance/init.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/internals.d.ts +60 -0
- package/lib/typescript/commonjs/core/instance/internals.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/load.d.ts +9 -0
- package/lib/typescript/commonjs/core/instance/load.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/show.d.ts +7 -0
- package/lib/typescript/commonjs/core/instance/show.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/instance/types.d.ts +240 -0
- package/lib/typescript/commonjs/core/instance/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/placementMachine.d.ts +55 -0
- package/lib/typescript/commonjs/core/placementMachine.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/privacyGate.d.ts +40 -0
- package/lib/typescript/commonjs/core/privacyGate.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/requestThrottle.d.ts +99 -0
- package/lib/typescript/commonjs/core/requestThrottle.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/retryPolicy.d.ts +66 -0
- package/lib/typescript/commonjs/core/retryPolicy.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/rewardedSession.d.ts +37 -0
- package/lib/typescript/commonjs/core/rewardedSession.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/timers.d.ts +135 -0
- package/lib/typescript/commonjs/core/timers.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/correlation.d.ts +18 -0
- package/lib/typescript/commonjs/diagnostics/correlation.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts +59 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/events.d.ts +126 -0
- package/lib/typescript/commonjs/diagnostics/events.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/admobBanner.d.ts +10 -0
- package/lib/typescript/commonjs/engine/admobBanner.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/admobEngine.d.ts +71 -0
- package/lib/typescript/commonjs/engine/admobEngine.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/admobErrors.d.ts +9 -0
- package/lib/typescript/commonjs/engine/admobErrors.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/port.d.ts +171 -0
- package/lib/typescript/commonjs/engine/port.d.ts.map +1 -0
- package/lib/typescript/commonjs/engine/testAdUnits.d.ts +33 -0
- package/lib/typescript/commonjs/engine/testAdUnits.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +42 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/react/AdsBanner.d.ts +29 -0
- package/lib/typescript/commonjs/react/AdsBanner.d.ts.map +1 -0
- package/lib/typescript/commonjs/react/AdsProvider.d.ts +36 -0
- package/lib/typescript/commonjs/react/AdsProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/react/hooks.d.ts +27 -0
- package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/clock.d.ts +29 -0
- package/lib/typescript/commonjs/testing/clock.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/conformance.d.ts +26 -0
- package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/index.d.ts +133 -0
- package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
- package/lib/typescript/module/config/resolveAdUnit.d.ts +43 -0
- package/lib/typescript/module/config/resolveAdUnit.d.ts.map +1 -0
- package/lib/typescript/module/config/types.d.ts +280 -0
- package/lib/typescript/module/config/types.d.ts.map +1 -0
- package/lib/typescript/module/config/validate.d.ts +49 -0
- package/lib/typescript/module/config/validate.d.ts.map +1 -0
- package/lib/typescript/module/core/adOriginatedReturn.d.ts +61 -0
- package/lib/typescript/module/core/adOriginatedReturn.d.ts.map +1 -0
- package/lib/typescript/module/core/adsInstance.d.ts +33 -0
- package/lib/typescript/module/core/adsInstance.d.ts.map +1 -0
- package/lib/typescript/module/core/consentFlow.d.ts +84 -0
- package/lib/typescript/module/core/consentFlow.d.ts.map +1 -0
- package/lib/typescript/module/core/enablement.d.ts +74 -0
- package/lib/typescript/module/core/enablement.d.ts.map +1 -0
- package/lib/typescript/module/core/fullScreenLock.d.ts +25 -0
- package/lib/typescript/module/core/fullScreenLock.d.ts.map +1 -0
- package/lib/typescript/module/core/gates.d.ts +76 -0
- package/lib/typescript/module/core/gates.d.ts.map +1 -0
- package/lib/typescript/module/core/initMachine.d.ts +66 -0
- package/lib/typescript/module/core/initMachine.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/consent.d.ts +4 -0
- package/lib/typescript/module/core/instance/consent.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/context.d.ts +118 -0
- package/lib/typescript/module/core/instance/context.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/gate.d.ts +38 -0
- package/lib/typescript/module/core/instance/gate.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/init.d.ts +13 -0
- package/lib/typescript/module/core/instance/init.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/internals.d.ts +60 -0
- package/lib/typescript/module/core/instance/internals.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/load.d.ts +9 -0
- package/lib/typescript/module/core/instance/load.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/show.d.ts +7 -0
- package/lib/typescript/module/core/instance/show.d.ts.map +1 -0
- package/lib/typescript/module/core/instance/types.d.ts +240 -0
- package/lib/typescript/module/core/instance/types.d.ts.map +1 -0
- package/lib/typescript/module/core/placementMachine.d.ts +55 -0
- package/lib/typescript/module/core/placementMachine.d.ts.map +1 -0
- package/lib/typescript/module/core/privacyGate.d.ts +40 -0
- package/lib/typescript/module/core/privacyGate.d.ts.map +1 -0
- package/lib/typescript/module/core/requestThrottle.d.ts +99 -0
- package/lib/typescript/module/core/requestThrottle.d.ts.map +1 -0
- package/lib/typescript/module/core/retryPolicy.d.ts +66 -0
- package/lib/typescript/module/core/retryPolicy.d.ts.map +1 -0
- package/lib/typescript/module/core/rewardedSession.d.ts +37 -0
- package/lib/typescript/module/core/rewardedSession.d.ts.map +1 -0
- package/lib/typescript/module/core/timers.d.ts +135 -0
- package/lib/typescript/module/core/timers.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/correlation.d.ts +18 -0
- package/lib/typescript/module/diagnostics/correlation.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/errors.d.ts +59 -0
- package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/events.d.ts +126 -0
- package/lib/typescript/module/diagnostics/events.d.ts.map +1 -0
- package/lib/typescript/module/engine/admobBanner.d.ts +10 -0
- package/lib/typescript/module/engine/admobBanner.d.ts.map +1 -0
- package/lib/typescript/module/engine/admobEngine.d.ts +71 -0
- package/lib/typescript/module/engine/admobEngine.d.ts.map +1 -0
- package/lib/typescript/module/engine/admobErrors.d.ts +9 -0
- package/lib/typescript/module/engine/admobErrors.d.ts.map +1 -0
- package/lib/typescript/module/engine/port.d.ts +171 -0
- package/lib/typescript/module/engine/port.d.ts.map +1 -0
- package/lib/typescript/module/engine/testAdUnits.d.ts +33 -0
- package/lib/typescript/module/engine/testAdUnits.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +42 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/react/AdsBanner.d.ts +29 -0
- package/lib/typescript/module/react/AdsBanner.d.ts.map +1 -0
- package/lib/typescript/module/react/AdsProvider.d.ts +36 -0
- package/lib/typescript/module/react/AdsProvider.d.ts.map +1 -0
- package/lib/typescript/module/react/hooks.d.ts +27 -0
- package/lib/typescript/module/react/hooks.d.ts.map +1 -0
- package/lib/typescript/module/testing/clock.d.ts +29 -0
- package/lib/typescript/module/testing/clock.d.ts.map +1 -0
- package/lib/typescript/module/testing/conformance.d.ts +26 -0
- package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
- package/lib/typescript/module/testing/index.d.ts +133 -0
- package/lib/typescript/module/testing/index.d.ts.map +1 -0
- package/package.json +48 -12
- package/skills/sdk-rn-ads/SKILL.md +2 -1
- package/src/core/adsInstance.ts +72 -1829
- package/src/core/consentFlow.ts +1 -20
- package/src/core/instance/consent.ts +162 -0
- package/src/core/instance/context.ts +328 -0
- package/src/core/instance/gate.ts +147 -0
- package/src/core/instance/init.ts +262 -0
- package/src/core/instance/internals.ts +138 -0
- package/src/core/instance/load.ts +426 -0
- package/src/core/instance/show.ts +202 -0
- package/src/core/instance/types.ts +198 -0
- package/src/core/requestThrottle.ts +11 -17
- package/src/diagnostics/errors.ts +24 -5
- package/src/engine/admobBanner.tsx +55 -0
- package/src/engine/admobEngine.ts +21 -12
- package/src/engine/admobErrors.ts +44 -0
- package/src/engine/port.ts +46 -1
- package/src/engine/testAdUnits.ts +0 -5
- package/src/react/AdsBanner.tsx +81 -80
- package/src/testing/clock.ts +75 -0
- package/src/testing/index.ts +43 -68
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ads instance's public contract: what `createAds` returns and what each
|
|
3
|
+
* operation reports. Implementation lives beside this file, one module per
|
|
4
|
+
* responsibility (ADS-10).
|
|
5
|
+
*/
|
|
6
|
+
import type { AdsError } from '../../diagnostics/errors.js';
|
|
7
|
+
import type { ConsentSnapshot, Enablement, InitStatus, PlacementState, PrivacyBlockReason, PrivacyOptions, UnavailableReason, Unsubscribe } from '../../config/types.js';
|
|
8
|
+
import type { AdEventListener } from '../../diagnostics/events.js';
|
|
9
|
+
import type { AdsEngine } from '../../engine/port.js';
|
|
10
|
+
import type { EnablementResult } from '../enablement.js';
|
|
11
|
+
import type { Scheduler } from '../timers.js';
|
|
12
|
+
export type InitResult = {
|
|
13
|
+
readonly status: 'ready';
|
|
14
|
+
} | {
|
|
15
|
+
readonly status: 'blocked';
|
|
16
|
+
readonly reason: PrivacyBlockReason;
|
|
17
|
+
} | {
|
|
18
|
+
readonly status: 'disabled';
|
|
19
|
+
}
|
|
20
|
+
/** The app has not decided whether ads are on. Nothing was requested (FR-115). */
|
|
21
|
+
| {
|
|
22
|
+
readonly status: 'undecided';
|
|
23
|
+
} | {
|
|
24
|
+
readonly status: 'unavailable';
|
|
25
|
+
readonly reason: UnavailableReason;
|
|
26
|
+
} | {
|
|
27
|
+
readonly status: 'failed';
|
|
28
|
+
readonly error: AdsError;
|
|
29
|
+
};
|
|
30
|
+
export type PrivacyUpdateResult = {
|
|
31
|
+
readonly status: 'applied';
|
|
32
|
+
} | {
|
|
33
|
+
readonly status: 'blocked';
|
|
34
|
+
readonly reason: PrivacyBlockReason;
|
|
35
|
+
} | {
|
|
36
|
+
readonly status: 'requires_reinitialization';
|
|
37
|
+
} | {
|
|
38
|
+
readonly status: 'disabled';
|
|
39
|
+
} | {
|
|
40
|
+
readonly status: 'undecided';
|
|
41
|
+
} | {
|
|
42
|
+
readonly status: 'unavailable';
|
|
43
|
+
readonly reason: UnavailableReason;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The initialization this update triggered failed (added in 0.5.0). Before,
|
|
47
|
+
* it was reported as `applied`, so the app never retried and no ad ever
|
|
48
|
+
* showed, with nothing to say why.
|
|
49
|
+
*/
|
|
50
|
+
| {
|
|
51
|
+
readonly status: 'failed';
|
|
52
|
+
readonly error: AdsError;
|
|
53
|
+
};
|
|
54
|
+
export type LoadResult = {
|
|
55
|
+
readonly status: 'loaded';
|
|
56
|
+
readonly correlationId: string;
|
|
57
|
+
} | {
|
|
58
|
+
readonly status: 'disabled';
|
|
59
|
+
} | {
|
|
60
|
+
readonly status: 'undecided';
|
|
61
|
+
} | {
|
|
62
|
+
readonly status: 'blocked';
|
|
63
|
+
readonly reason: PrivacyBlockReason;
|
|
64
|
+
} | {
|
|
65
|
+
readonly status: 'unavailable';
|
|
66
|
+
readonly reason: UnavailableReason;
|
|
67
|
+
} | {
|
|
68
|
+
readonly status: 'no_fill';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Refused by the per-placement request throttle (FR-140), added in 0.3.0.
|
|
72
|
+
*
|
|
73
|
+
* Nothing was requested and nothing is broken — this placement asked too
|
|
74
|
+
* recently. Distinct from `no_fill` on purpose: no-fill means the network had
|
|
75
|
+
* nothing to give, this means we did not ask. An app that treats them the same
|
|
76
|
+
* will misdiagnose the first time a banner goes quiet.
|
|
77
|
+
*/
|
|
78
|
+
| ThrottledResult | {
|
|
79
|
+
readonly status: 'timeout';
|
|
80
|
+
} | {
|
|
81
|
+
readonly status: 'failed';
|
|
82
|
+
readonly error: AdsError;
|
|
83
|
+
};
|
|
84
|
+
export interface ThrottledResult {
|
|
85
|
+
readonly status: 'throttled';
|
|
86
|
+
readonly retryAfterMs: number;
|
|
87
|
+
}
|
|
88
|
+
/** A gate refusal: what a load gets when it may not ask at all. */
|
|
89
|
+
export type LoadRefusal = Extract<LoadResult, {
|
|
90
|
+
status: 'disabled' | 'undecided' | 'blocked' | 'unavailable';
|
|
91
|
+
}>;
|
|
92
|
+
export type ShowResult = {
|
|
93
|
+
readonly status: 'shown';
|
|
94
|
+
readonly correlationId: string;
|
|
95
|
+
} | {
|
|
96
|
+
readonly status: 'not_ready';
|
|
97
|
+
} | {
|
|
98
|
+
readonly status: 'busy';
|
|
99
|
+
} | {
|
|
100
|
+
readonly status: 'consumed';
|
|
101
|
+
} | {
|
|
102
|
+
readonly status: 'app_inactive';
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The user came back to the app from an ad, or from a browser an ad opened,
|
|
106
|
+
* so an app-open ad would be an ad immediately after an ad. Distinct from
|
|
107
|
+
* `busy` and `not_ready` because the app cannot detect this itself and
|
|
108
|
+
* therefore cannot infer it from either of those (FR-128).
|
|
109
|
+
*/
|
|
110
|
+
| {
|
|
111
|
+
readonly status: 'ad_originated_return';
|
|
112
|
+
} | {
|
|
113
|
+
readonly status: 'disabled';
|
|
114
|
+
} | {
|
|
115
|
+
readonly status: 'undecided';
|
|
116
|
+
} | {
|
|
117
|
+
readonly status: 'blocked';
|
|
118
|
+
readonly reason: PrivacyBlockReason;
|
|
119
|
+
} | {
|
|
120
|
+
readonly status: 'unavailable';
|
|
121
|
+
readonly reason: UnavailableReason;
|
|
122
|
+
} | {
|
|
123
|
+
readonly status: 'timeout';
|
|
124
|
+
} | {
|
|
125
|
+
readonly status: 'failed';
|
|
126
|
+
readonly error: AdsError;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* What `consent.showPrivacyOptionsForm()` reports (FR-151), added in 0.4.0.
|
|
130
|
+
*
|
|
131
|
+
* Every refusal is its own member, so an app can tell "there is nothing to
|
|
132
|
+
* offer here" from "you asked too early" from "it broke" without parsing an
|
|
133
|
+
* error. None of them throws.
|
|
134
|
+
*/
|
|
135
|
+
export type PrivacyOptionsFormResult =
|
|
136
|
+
/**
|
|
137
|
+
* The provider's form was presented and has closed. `consent` is the state it
|
|
138
|
+
* left behind, already applied to the gate. A user who closed the form without
|
|
139
|
+
* changing anything lands here too, with the state they already had.
|
|
140
|
+
*/
|
|
141
|
+
{
|
|
142
|
+
readonly status: 'shown';
|
|
143
|
+
readonly consent: ConsentSnapshot;
|
|
144
|
+
}
|
|
145
|
+
/** The provider does not require privacy options here. Nothing was presented. */
|
|
146
|
+
| {
|
|
147
|
+
readonly status: 'not_required';
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The requirement is not known yet: no successful `requestInfoUpdate()` since
|
|
151
|
+
* the instance was created or reset, or the last one failed. Nothing was
|
|
152
|
+
* presented.
|
|
153
|
+
*/
|
|
154
|
+
| {
|
|
155
|
+
readonly status: 'info_update_required';
|
|
156
|
+
}
|
|
157
|
+
/** A consent form is already on screen. Nothing was presented. */
|
|
158
|
+
| {
|
|
159
|
+
readonly status: 'busy';
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The form could not be presented or failed while open. The consent state is
|
|
163
|
+
* whatever the provider reports it still holds, and never a new grant.
|
|
164
|
+
*/
|
|
165
|
+
| {
|
|
166
|
+
readonly status: 'failed';
|
|
167
|
+
readonly error: AdsError;
|
|
168
|
+
} | {
|
|
169
|
+
readonly status: 'unavailable';
|
|
170
|
+
readonly reason: UnavailableReason;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* The optional consent capability (FR-101).
|
|
174
|
+
*
|
|
175
|
+
* Grouped under its own namespace rather than flattened onto the instance so
|
|
176
|
+
* that FR-102's optionality stays legible: an app that never touches
|
|
177
|
+
* `ads.consent` never starts a flow. Five loose methods on the instance would
|
|
178
|
+
* invite the assumption that they are part of the normal path.
|
|
179
|
+
*/
|
|
180
|
+
export interface ConsentApi {
|
|
181
|
+
/** Refreshes consent information from the provider. */
|
|
182
|
+
requestInfoUpdate(): Promise<ConsentSnapshot>;
|
|
183
|
+
/** Presents the provider's form if one is required. Renders nothing itself. */
|
|
184
|
+
showFormIfRequired(): Promise<ConsentSnapshot>;
|
|
185
|
+
/**
|
|
186
|
+
* Presents the provider's privacy options form, so a user can change an
|
|
187
|
+
* answer already given (FR-151). Added in 0.4.0.
|
|
188
|
+
*
|
|
189
|
+
* Offer it when `getState().privacyOptionsRequirement` is `required`. Where
|
|
190
|
+
* the entry point lives, and what it says, stay the app's. The outcome feeds
|
|
191
|
+
* the privacy gate by itself, exactly as `showFormIfRequired` does.
|
|
192
|
+
*/
|
|
193
|
+
showPrivacyOptionsForm(): Promise<PrivacyOptionsFormResult>;
|
|
194
|
+
getState(): ConsentSnapshot;
|
|
195
|
+
subscribe(listener: (snapshot: ConsentSnapshot) => void): Unsubscribe;
|
|
196
|
+
/** Clears the stored decision. Inert in production (FR-113). */
|
|
197
|
+
reset(): Promise<void>;
|
|
198
|
+
}
|
|
199
|
+
export interface AdsInstance {
|
|
200
|
+
initialize(privacy: PrivacyOptions): Promise<InitResult>;
|
|
201
|
+
updatePrivacy(privacy: PrivacyOptions): Promise<PrivacyUpdateResult>;
|
|
202
|
+
/**
|
|
203
|
+
* Turns ads on or off. Returns a result rather than `void` (FR-122).
|
|
204
|
+
*
|
|
205
|
+
* 0.1.0 returned nothing, which meant an app re-enabling ads after a lapsed
|
|
206
|
+
* subscription had no way to learn that it also had to re-initialize — and
|
|
207
|
+
* every load and show after that was refused in silence.
|
|
208
|
+
*/
|
|
209
|
+
setEnabled(enabled: boolean): EnablementResult;
|
|
210
|
+
/** The same, including the third state the app has not resolved yet. */
|
|
211
|
+
setEnablement(next: Enablement): EnablementResult;
|
|
212
|
+
setAppActive(active: boolean): void;
|
|
213
|
+
readonly consent: ConsentApi;
|
|
214
|
+
getStatus(): InitStatus;
|
|
215
|
+
subscribeStatus(listener: (status: InitStatus) => void): Unsubscribe;
|
|
216
|
+
load(placementKey: string): Promise<LoadResult>;
|
|
217
|
+
show(placementKey: string): Promise<ShowResult>;
|
|
218
|
+
getPlacementState(placementKey: string): PlacementState;
|
|
219
|
+
subscribePlacement(key: string, listener: (state: PlacementState) => void): Unsubscribe;
|
|
220
|
+
subscribeEvents(listener: AdEventListener): Unsubscribe;
|
|
221
|
+
/** FR-011a — substitution is observable state, not only a log line. */
|
|
222
|
+
getSubstitutedPlacements(): readonly string[];
|
|
223
|
+
/** FR-113 — the same treatment for consent tools dropped in production. */
|
|
224
|
+
getIgnoredConsentTools(): readonly string[];
|
|
225
|
+
dispose(): void;
|
|
226
|
+
}
|
|
227
|
+
export interface CreateAdsOptions {
|
|
228
|
+
/** Injected in tests; the AdMob adapter is the default in production. */
|
|
229
|
+
readonly engine?: AdsEngine;
|
|
230
|
+
/** Injected so the FR-012 rule is testable without touching a global. */
|
|
231
|
+
readonly isDevBuild?: boolean;
|
|
232
|
+
readonly now?: () => number;
|
|
233
|
+
/**
|
|
234
|
+
* Injected so retry backoff, app-open expiry, and the undecided warning can
|
|
235
|
+
* be driven by a test clock instead of by waiting. Production uses real
|
|
236
|
+
* timers.
|
|
237
|
+
*/
|
|
238
|
+
readonly scheduler?: Scheduler;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/core/instance/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-placement lifecycle (FR-026 – FR-031, FR-034).
|
|
3
|
+
*
|
|
4
|
+
* Pure and synchronous, per data-model.md §3.2. Two variants share one reducer:
|
|
5
|
+
*
|
|
6
|
+
* full-screen — load, show once, become `consumed`, reload before the next show
|
|
7
|
+
* banner — continuous; it renders and may refresh, and never reaches
|
|
8
|
+
* `consumed`, because a banner is not a single-use resource
|
|
9
|
+
*
|
|
10
|
+
* Staleness is handled here rather than at the show site so that a stale ad can
|
|
11
|
+
* never be *reported* ready either — a consumer that renders a "Watch ad" button
|
|
12
|
+
* from `state === 'ready'` would otherwise offer a button that fails on tap.
|
|
13
|
+
*/
|
|
14
|
+
import type { AdFormat, PlacementState, UnavailableReason } from '../config/types.js';
|
|
15
|
+
import type { AdsError } from '../diagnostics/errors.js';
|
|
16
|
+
export type PlacementEvent = {
|
|
17
|
+
readonly type: 'LOAD';
|
|
18
|
+
} | {
|
|
19
|
+
readonly type: 'LOADED';
|
|
20
|
+
readonly atMs: number;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: 'LOAD_FAILED';
|
|
23
|
+
readonly error: AdsError;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: 'SHOW';
|
|
26
|
+
} | {
|
|
27
|
+
readonly type: 'SHOW_FAILED';
|
|
28
|
+
readonly error: AdsError;
|
|
29
|
+
} | {
|
|
30
|
+
readonly type: 'DISMISSED';
|
|
31
|
+
} | {
|
|
32
|
+
readonly type: 'EXPIRE';
|
|
33
|
+
} | {
|
|
34
|
+
readonly type: 'UNAVAILABLE';
|
|
35
|
+
readonly reason: UnavailableReason;
|
|
36
|
+
} | {
|
|
37
|
+
readonly type: 'RESET';
|
|
38
|
+
};
|
|
39
|
+
export interface PlacementSnapshot {
|
|
40
|
+
readonly state: PlacementState;
|
|
41
|
+
readonly loadedAtMs: number | null;
|
|
42
|
+
readonly error: AdsError | null;
|
|
43
|
+
readonly correlationId: string | null;
|
|
44
|
+
}
|
|
45
|
+
export declare const initialPlacement: PlacementSnapshot;
|
|
46
|
+
/**
|
|
47
|
+
* A load is only legal from a settled state; `loading` is where FR-029 bites.
|
|
48
|
+
* `throttled` is settled too: it records that the last request was refused, and
|
|
49
|
+
* the throttle itself decides whether the next one may proceed.
|
|
50
|
+
*/
|
|
51
|
+
export declare function canLoad(state: PlacementState): boolean;
|
|
52
|
+
/** Only a ready ad may be shown. Everything else is a determinate refusal (FR-028). */
|
|
53
|
+
export declare function canShow(state: PlacementState): boolean;
|
|
54
|
+
export declare function placementReducer(state: PlacementSnapshot, event: PlacementEvent, format: AdFormat): PlacementSnapshot;
|
|
55
|
+
//# sourceMappingURL=placementMachine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placementMachine.d.ts","sourceRoot":"","sources":["../../../../src/core/placementMachine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAiB,CAAC;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAAuB,CAAC;AAEtD,MAAM,MAAM,cAAc,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9B,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,gBAAgB,EAAE,iBAK9B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAQtD;AAED,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAEtD;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,QAAQ,GACd,iBAAiB,CAyDnB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The privacy gate (FR-016 – FR-021).
|
|
3
|
+
*
|
|
4
|
+
* The package enforces ordering; the app owns policy. It renders no consent UI,
|
|
5
|
+
* writes no legal copy, and decides nothing about a jurisdiction — it accepts a
|
|
6
|
+
* gate outcome and refuses to let any request precede it.
|
|
7
|
+
*
|
|
8
|
+
* That refusal is the whole value. Consent ordering is easy to get wrong by
|
|
9
|
+
* accident, and the failure is invisible: an ad request that should not have
|
|
10
|
+
* happened looks exactly like one that should. A package that enforces the order
|
|
11
|
+
* is worth more than documentation that describes it.
|
|
12
|
+
*
|
|
13
|
+
* Pure — no provider, no React, no I/O. The engine adapter translates the
|
|
14
|
+
* outcome into provider configuration.
|
|
15
|
+
*/
|
|
16
|
+
import type { PrivacyBlockReason, PrivacyOptions } from '../config/types.js';
|
|
17
|
+
import type { EnginePrivacy, EngineRequestOptions } from '../engine/port.js';
|
|
18
|
+
export type GateDecision = {
|
|
19
|
+
readonly allowed: true;
|
|
20
|
+
} | {
|
|
21
|
+
readonly allowed: false;
|
|
22
|
+
readonly reason: PrivacyBlockReason;
|
|
23
|
+
};
|
|
24
|
+
export declare function evaluateGate(privacy: PrivacyOptions | null): GateDecision;
|
|
25
|
+
export declare function requiresReinitialization(applied: PrivacyOptions | null, next: PrivacyOptions): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Projects consumer privacy options onto what the engine needs.
|
|
28
|
+
*
|
|
29
|
+
* `personalizedAds` is carried through rather than inverted here; the adapter
|
|
30
|
+
* owns the translation to the provider's `requestNonPersonalizedAdsOnly`, so
|
|
31
|
+
* the polarity flip lives next to the API that requires it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function toEnginePrivacy(privacy: PrivacyOptions, testDeviceIds: readonly string[]): EnginePrivacy;
|
|
34
|
+
/**
|
|
35
|
+
* What every ad request carries. Unset means personalized, matching the
|
|
36
|
+
* documented default of `PrivacyOptions.personalizedAds`; only an explicit
|
|
37
|
+
* `false` opts out.
|
|
38
|
+
*/
|
|
39
|
+
export declare function toEngineRequest(privacy: PrivacyOptions | null): EngineRequestOptions;
|
|
40
|
+
//# sourceMappingURL=privacyGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privacyGate.d.ts","sourceRoot":"","sources":["../../../../src/core/privacyGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,mBAAgB,CAAC;AAE1E,MAAM,MAAM,YAAY,GACvB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE/F,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,YAAY,CAczE;AAmBD,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,IAAI,EAAE,cAAc,GAClB,OAAO,CAKT;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC9B,aAAa,CAQf;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,oBAAoB,CAEpF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-placement request throttle (FR-140).
|
|
3
|
+
*
|
|
4
|
+
* This exists to protect the **ad account**, not to shape product behaviour, and
|
|
5
|
+
* that distinction is the whole reason it lives in the package:
|
|
6
|
+
*
|
|
7
|
+
* | Decision | Owner |
|
|
8
|
+
* |---|---|
|
|
9
|
+
* | How often to *show* an interstitial | the app — product policy |
|
|
10
|
+
* | How often the same placement may *request* | the package — account safety |
|
|
11
|
+
*
|
|
12
|
+
* Rapid repeat requests for one placement are read by ad networks as invalid
|
|
13
|
+
* traffic, and the penalty is account-level and not recoverable by shipping a
|
|
14
|
+
* fix. That puts it in the same class as the test-ad substitution the package
|
|
15
|
+
* already enforces: a safety property the library guarantees rather than
|
|
16
|
+
* documents and hopes each app remembers.
|
|
17
|
+
*
|
|
18
|
+
* ## The pattern it is built for
|
|
19
|
+
*
|
|
20
|
+
* A banner mounted inside a view the user navigates between — a day in a
|
|
21
|
+
* calendar, a tab, a row in a list — is unmounted and remounted by React on every
|
|
22
|
+
* navigation. Each remount is a fresh provider request. A user swiping quickly
|
|
23
|
+
* through ten days produces ten requests in a few seconds, and nothing about that
|
|
24
|
+
* is the app author doing something wrong.
|
|
25
|
+
*
|
|
26
|
+
* Full-screen formats do not have this problem: they are loaded by an explicit
|
|
27
|
+
* call, not mounted by a renderer. That asymmetry is why the default differs by
|
|
28
|
+
* format — see `defaultMinRequestIntervalMs`.
|
|
29
|
+
*
|
|
30
|
+
* The better *architectural* answer is to keep the banner outside the subtree that
|
|
31
|
+
* remounts. This throttle is the safety net for when that is not possible, not a
|
|
32
|
+
* licence to ignore the problem; the README says so where an app author will read
|
|
33
|
+
* it.
|
|
34
|
+
*/
|
|
35
|
+
import type { AdFormat } from '../config/types.js';
|
|
36
|
+
/**
|
|
37
|
+
* AdMob's own documented floor for banner auto-refresh is 60 seconds, so
|
|
38
|
+
* requesting the same banner placement more often than that is, by the provider's
|
|
39
|
+
* own standard, more often than it considers reasonable. Taking the provider's
|
|
40
|
+
* number rather than inventing one means the default is defensible rather than
|
|
41
|
+
* arbitrary.
|
|
42
|
+
*/
|
|
43
|
+
export declare const DEFAULT_BANNER_MIN_REQUEST_INTERVAL_MS = 60000;
|
|
44
|
+
/**
|
|
45
|
+
* Off by default for full-screen formats.
|
|
46
|
+
*
|
|
47
|
+
* `load` → `show` → `load` is the normal, healthy cycle for an interstitial, and
|
|
48
|
+
* an app that sells three things in two minutes legitimately loads three times.
|
|
49
|
+
* Throttling that by default would break correct apps to solve a problem those
|
|
50
|
+
* formats do not have. An app that wants a floor here can set one.
|
|
51
|
+
*/
|
|
52
|
+
export declare const DEFAULT_FULL_SCREEN_MIN_REQUEST_INTERVAL_MS = 0;
|
|
53
|
+
export declare const MIN_REQUEST_INTERVAL_BOUNDS: {
|
|
54
|
+
readonly min: 0;
|
|
55
|
+
readonly max: 600000;
|
|
56
|
+
};
|
|
57
|
+
/** The format-aware default, applied when a placement configures nothing. */
|
|
58
|
+
export declare function defaultMinRequestIntervalMs(format: AdFormat): number;
|
|
59
|
+
export type ThrottleDecision = {
|
|
60
|
+
readonly allowed: true;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* `retryAfterMs` is reported rather than left for the caller to compute,
|
|
64
|
+
* because the app needs it to decide between collapsing the space and holding
|
|
65
|
+
* it — and a caller recomputing it from a timestamp would drift from the
|
|
66
|
+
* clock this throttle actually used.
|
|
67
|
+
*/
|
|
68
|
+
| {
|
|
69
|
+
readonly allowed: false;
|
|
70
|
+
readonly retryAfterMs: number;
|
|
71
|
+
};
|
|
72
|
+
export interface RequestThrottle {
|
|
73
|
+
/**
|
|
74
|
+
* Records a request and reports whether it may proceed.
|
|
75
|
+
*
|
|
76
|
+
* Call immediately before handing a request to the provider.
|
|
77
|
+
*
|
|
78
|
+
* `token` makes the acquisition **idempotent for one request cycle**, and the
|
|
79
|
+
* banner path depends on it. React may run a `useMemo` or an effect more than
|
|
80
|
+
* once for a single committed render — StrictMode does it deliberately — and
|
|
81
|
+
* without a token the second run would consume a second slot and be refused,
|
|
82
|
+
* so a banner would never appear in development. Passing the banner mount's
|
|
83
|
+
* token means "this is the same request I already asked about", and the
|
|
84
|
+
* previous decision is returned unchanged.
|
|
85
|
+
*
|
|
86
|
+
* Omit `token` for a genuinely new imperative request, where every call is a
|
|
87
|
+
* distinct intent to ask the network.
|
|
88
|
+
*/
|
|
89
|
+
tryAcquire(key: string, minIntervalMs: number, token?: string): ThrottleDecision;
|
|
90
|
+
/**
|
|
91
|
+
* How long until this placement may ask again, without taking a slot: 0 when
|
|
92
|
+
* it may ask now. A load retry waits at least this long, so a retry policy
|
|
93
|
+
* cannot request faster than the floor allows (ADS-07).
|
|
94
|
+
*/
|
|
95
|
+
waitFor(key: string, minIntervalMs: number): number;
|
|
96
|
+
clear(): void;
|
|
97
|
+
}
|
|
98
|
+
export declare function createRequestThrottle(now: () => number): RequestThrottle;
|
|
99
|
+
//# sourceMappingURL=requestThrottle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestThrottle.d.ts","sourceRoot":"","sources":["../../../../src/core/requestThrottle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAiB,CAAC;AAEhD;;;;;;GAMG;AACH,eAAO,MAAM,sCAAsC,QAAS,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,2CAA2C,IAAI,CAAC;AAE7D,eAAO,MAAM,2BAA2B;;;CAAoC,CAAC;AAE7E,6EAA6E;AAC7E,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAIpE;AAED,MAAM,MAAM,gBAAgB,GACzB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE;AAC5B;;;;;GAKG;GACD;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACjF;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IACpD,KAAK,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,MAAM,GAAG,eAAe,CAmExE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded, opt-in retry for failed loads (FR-134 – FR-139).
|
|
3
|
+
*
|
|
4
|
+
* 0.1.0 shipped no retry on purpose, and the reason was sound: every retry is a
|
|
5
|
+
* billable request, and only the app knows what that costs. But the practical
|
|
6
|
+
* result was that every app rewrote the same backoff loop, and the cost of
|
|
7
|
+
* writing it wrong landed on a bill. This ships the loop once, keeps it **off by
|
|
8
|
+
* default**, and makes every attempt visible.
|
|
9
|
+
*
|
|
10
|
+
* Three properties do the work:
|
|
11
|
+
*
|
|
12
|
+
* - Off unless configured, so upgrading from 0.1.0 issues not one extra
|
|
13
|
+
* request (FR-134, and the compat test proves it rather than asserting it).
|
|
14
|
+
* - Only `retryable` errors. Configuration and consent errors, an unsupported
|
|
15
|
+
* platform, and a disabled or undecided instance are states another attempt
|
|
16
|
+
* cannot change, so retrying them would spend money on a certainty (FR-135).
|
|
17
|
+
* - Every attempt is an event carrying the load cycle's correlation id, so a
|
|
18
|
+
* bill can be reconciled against the event stream alone (FR-138).
|
|
19
|
+
*
|
|
20
|
+
* Pure — the schedule is computed here, the waiting happens in the instance's
|
|
21
|
+
* TimerSet so `dispose()` can prove it released everything.
|
|
22
|
+
*/
|
|
23
|
+
import type { RetryPolicy } from '../config/types.js';
|
|
24
|
+
export interface ResolvedRetryPolicy {
|
|
25
|
+
readonly maxRetries: number;
|
|
26
|
+
readonly initialDelayMs: number;
|
|
27
|
+
readonly maxDelayMs: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Validates one policy against the bounds.
|
|
31
|
+
*
|
|
32
|
+
* Out-of-range values **throw** rather than being clamped, matching the rule
|
|
33
|
+
* `timers.ts` already follows: silently clamping a request for ten retries down
|
|
34
|
+
* to five tells the app it configured something it did not, and the discrepancy
|
|
35
|
+
* only surfaces later as a bill that does not match the code.
|
|
36
|
+
*
|
|
37
|
+
* `label` names the offending field precisely — an error that says only
|
|
38
|
+
* "invalid retry policy" makes an integrator hunt through a catalog by hand.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveRetryPolicy(policy: RetryPolicy, label: string): ResolvedRetryPolicy;
|
|
41
|
+
/**
|
|
42
|
+
* Resolves the effective policy for one placement.
|
|
43
|
+
*
|
|
44
|
+
* An override **replaces** the instance-wide policy rather than merging into it.
|
|
45
|
+
* Merging would mean the effective policy for a placement could not be read off
|
|
46
|
+
* the configuration — you would have to simulate the merge to know what it was —
|
|
47
|
+
* and a per-field merge makes "this placement retries twice" quietly depend on a
|
|
48
|
+
* value written somewhere else.
|
|
49
|
+
*
|
|
50
|
+
* Both are validated against the same bounds, so an override narrows behavior
|
|
51
|
+
* but can never exceed a ceiling (FR-136a).
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveEffectiveRetry(instancePolicy: RetryPolicy | undefined, placementPolicy: RetryPolicy | false | undefined, placementKey: string): ResolvedRetryPolicy | null;
|
|
54
|
+
/**
|
|
55
|
+
* Delay before the given attempt. `attempt` is 1-based — the first retry is 1.
|
|
56
|
+
*
|
|
57
|
+
* Exponential with a fixed x2 multiplier and **no jitter**. Jitter exists to
|
|
58
|
+
* desynchronize a fleet of clients hitting one server; a single device retrying
|
|
59
|
+
* its own load has no herd to avoid. Leaving it out keeps "two retries, 2s then
|
|
60
|
+
* 4s" an exact assertion instead of a statistical one, which matters more here
|
|
61
|
+
* than a property that does not apply.
|
|
62
|
+
*/
|
|
63
|
+
export declare function delayForAttempt(policy: ResolvedRetryPolicy, attempt: number): number;
|
|
64
|
+
/** Whether another attempt is permitted. `attemptsMade` counts retries only. */
|
|
65
|
+
export declare function canRetry(policy: ResolvedRetryPolicy | null, attemptsMade: number): boolean;
|
|
66
|
+
//# sourceMappingURL=retryPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryPolicy.d.ts","sourceRoot":"","sources":["../../../../src/core/retryPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAiB,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAiC1F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACpC,cAAc,EAAE,WAAW,GAAG,SAAS,EACvC,eAAe,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,EAChD,YAAY,EAAE,MAAM,GAClB,mBAAmB,GAAG,IAAI,CAgB5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOpF;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAE1F"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewarded session bookkeeping (FR-046 – FR-049).
|
|
3
|
+
*
|
|
4
|
+
* Two independent booleans, never derived from one another:
|
|
5
|
+
*
|
|
6
|
+
* rewardConfirmed=false rewardConfirmed=true
|
|
7
|
+
* dismissed=false in progress reward emitted, awaiting dismissal
|
|
8
|
+
* dismissed=true dismissed_no_reward earned
|
|
9
|
+
*
|
|
10
|
+
* The defect this exists to prevent is inferring "earned" from dismissal. It is
|
|
11
|
+
* the most common way rewarded integrations go wrong, and it is a direct revenue
|
|
12
|
+
* and fairness fault: a user who closed the ad after two seconds gets the prize,
|
|
13
|
+
* and the publisher is billed for nothing.
|
|
14
|
+
*
|
|
15
|
+
* Tracking two flags and deriving the outcome makes both callback orderings
|
|
16
|
+
* produce the same result *by construction* rather than by the provider
|
|
17
|
+
* happening to fire in a convenient order (SC-007).
|
|
18
|
+
*/
|
|
19
|
+
import type { Reward } from '../config/types.js';
|
|
20
|
+
export type RewardedOutcome = 'in_progress' | 'earned' | 'dismissed_without_reward';
|
|
21
|
+
export interface RewardedSession {
|
|
22
|
+
/**
|
|
23
|
+
* Records a provider reward confirmation. Returns the reward the first time
|
|
24
|
+
* and `null` on every repeat, which is what collapses a duplicate provider
|
|
25
|
+
* emission into exactly one public event (FR-054).
|
|
26
|
+
*/
|
|
27
|
+
confirmReward(reward: Reward): Reward | null;
|
|
28
|
+
/** Records dismissal. Returns true the first time only. */
|
|
29
|
+
dismiss(): boolean;
|
|
30
|
+
outcome(): RewardedOutcome;
|
|
31
|
+
/** True only once the provider actually confirmed. Never inferred (FR-046). */
|
|
32
|
+
get rewardEarned(): boolean;
|
|
33
|
+
get dismissed(): boolean;
|
|
34
|
+
reward(): Reward | null;
|
|
35
|
+
}
|
|
36
|
+
export declare function createRewardedSession(): RewardedSession;
|
|
37
|
+
//# sourceMappingURL=rewardedSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewardedSession.d.ts","sourceRoot":"","sources":["../../../../src/core/rewardedSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAiB,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,GAAG,0BAA0B,CAAC;AAEpF,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC7C,2DAA2D;IAC3D,OAAO,IAAI,OAAO,CAAC;IACnB,OAAO,IAAI,eAAe,CAAC;IAC3B,+EAA+E;IAC/E,IAAI,YAAY,IAAI,OAAO,CAAC;IAC5B,IAAI,SAAS,IAAI,OAAO,CAAC;IACzB,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CA4CvD"}
|