@chipmobilesdk/rn-ads 0.7.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 +88 -0
- 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/src/testing/index.ts +17 -3
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Bounded, opt-in retry for failed loads (FR-134 – FR-139).
|
|
5
|
+
*
|
|
6
|
+
* 0.1.0 shipped no retry on purpose, and the reason was sound: every retry is a
|
|
7
|
+
* billable request, and only the app knows what that costs. But the practical
|
|
8
|
+
* result was that every app rewrote the same backoff loop, and the cost of
|
|
9
|
+
* writing it wrong landed on a bill. This ships the loop once, keeps it **off by
|
|
10
|
+
* default**, and makes every attempt visible.
|
|
11
|
+
*
|
|
12
|
+
* Three properties do the work:
|
|
13
|
+
*
|
|
14
|
+
* - Off unless configured, so upgrading from 0.1.0 issues not one extra
|
|
15
|
+
* request (FR-134, and the compat test proves it rather than asserting it).
|
|
16
|
+
* - Only `retryable` errors. Configuration and consent errors, an unsupported
|
|
17
|
+
* platform, and a disabled or undecided instance are states another attempt
|
|
18
|
+
* cannot change, so retrying them would spend money on a certainty (FR-135).
|
|
19
|
+
* - Every attempt is an event carrying the load cycle's correlation id, so a
|
|
20
|
+
* bill can be reconciled against the event stream alone (FR-138).
|
|
21
|
+
*
|
|
22
|
+
* Pure — the schedule is computed here, the waiting happens in the instance's
|
|
23
|
+
* TimerSet so `dispose()` can prove it released everything.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { computeBackoff } from '@chipmobilesdk/rn-core';
|
|
27
|
+
import { AdsConfigError } from "../diagnostics/errors.js";
|
|
28
|
+
import { checkBand, DEFAULT_RETRY_POLICY, RETRY_BOUNDS } from "./timers.js";
|
|
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 function resolveRetryPolicy(policy, label) {
|
|
41
|
+
const maxRetries = checkBand(`${label}.maxRetries`, policy.maxRetries ?? DEFAULT_RETRY_POLICY.maxRetries, RETRY_BOUNDS.maxRetries, 'retry_out_of_bounds', '');
|
|
42
|
+
const initialDelayMs = checkBand(`${label}.initialDelayMs`, policy.initialDelayMs ?? DEFAULT_RETRY_POLICY.initialDelayMs, RETRY_BOUNDS.initialDelayMs, 'retry_out_of_bounds');
|
|
43
|
+
const maxDelayMs = checkBand(`${label}.maxDelayMs`, policy.maxDelayMs ?? DEFAULT_RETRY_POLICY.maxDelayMs, RETRY_BOUNDS.maxDelayMs, 'retry_out_of_bounds');
|
|
44
|
+
if (!Number.isInteger(maxRetries)) {
|
|
45
|
+
throw new AdsConfigError('retry_out_of_bounds', {
|
|
46
|
+
message: `${label}.maxRetries must be a whole number; received ${maxRetries}`
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (initialDelayMs > maxDelayMs) {
|
|
50
|
+
throw new AdsConfigError('retry_out_of_bounds', {
|
|
51
|
+
message: `${label}.initialDelayMs (${initialDelayMs}ms) exceeds ${label}.maxDelayMs (${maxDelayMs}ms); the first retry would already be past the ceiling`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
maxRetries,
|
|
56
|
+
initialDelayMs,
|
|
57
|
+
maxDelayMs
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolves the effective policy for one placement.
|
|
63
|
+
*
|
|
64
|
+
* An override **replaces** the instance-wide policy rather than merging into it.
|
|
65
|
+
* Merging would mean the effective policy for a placement could not be read off
|
|
66
|
+
* the configuration — you would have to simulate the merge to know what it was —
|
|
67
|
+
* and a per-field merge makes "this placement retries twice" quietly depend on a
|
|
68
|
+
* value written somewhere else.
|
|
69
|
+
*
|
|
70
|
+
* Both are validated against the same bounds, so an override narrows behavior
|
|
71
|
+
* but can never exceed a ceiling (FR-136a).
|
|
72
|
+
*/
|
|
73
|
+
export function resolveEffectiveRetry(instancePolicy, placementPolicy, placementKey) {
|
|
74
|
+
if (placementPolicy === false) {
|
|
75
|
+
// Explicit opt-out for this placement alone. A banner retry is cheap and
|
|
76
|
+
// invisible; a rewarded retry happens with a user waiting on the other
|
|
77
|
+
// side of it. An app may reasonably want one and not the other.
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
if (placementPolicy) {
|
|
81
|
+
return resolveRetryPolicy(placementPolicy, `placements.${placementKey}.retry`);
|
|
82
|
+
}
|
|
83
|
+
if (instancePolicy) {
|
|
84
|
+
return resolveRetryPolicy(instancePolicy, 'retry');
|
|
85
|
+
}
|
|
86
|
+
// Nothing configured anywhere: retry is entirely off, which is the default
|
|
87
|
+
// and the only behavior a 0.1.0 consumer can observe (FR-134).
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Delay before the given attempt. `attempt` is 1-based — the first retry is 1.
|
|
93
|
+
*
|
|
94
|
+
* Exponential with a fixed x2 multiplier and **no jitter**. Jitter exists to
|
|
95
|
+
* desynchronize a fleet of clients hitting one server; a single device retrying
|
|
96
|
+
* its own load has no herd to avoid. Leaving it out keeps "two retries, 2s then
|
|
97
|
+
* 4s" an exact assertion instead of a statistical one, which matters more here
|
|
98
|
+
* than a property that does not apply.
|
|
99
|
+
*/
|
|
100
|
+
export function delayForAttempt(policy, attempt) {
|
|
101
|
+
return computeBackoff(attempt, {
|
|
102
|
+
initialDelayMs: policy.initialDelayMs,
|
|
103
|
+
maxDelayMs: policy.maxDelayMs,
|
|
104
|
+
factor: 2,
|
|
105
|
+
jitter: 'none'
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Whether another attempt is permitted. `attemptsMade` counts retries only. */
|
|
110
|
+
export function canRetry(policy, attemptsMade) {
|
|
111
|
+
return policy !== null && attemptsMade < policy.maxRetries;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=retryPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["computeBackoff","AdsConfigError","checkBand","DEFAULT_RETRY_POLICY","RETRY_BOUNDS","resolveRetryPolicy","policy","label","maxRetries","initialDelayMs","maxDelayMs","Number","isInteger","message","resolveEffectiveRetry","instancePolicy","placementPolicy","placementKey","delayForAttempt","attempt","factor","jitter","canRetry","attemptsMade"],"sourceRoot":"../../../src","sources":["core/retryPolicy.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,cAAc,QAAQ,wBAAwB;AAEvD,SAASC,cAAc,QAAQ,0BAAuB;AACtD,SAASC,SAAS,EAAEC,oBAAoB,EAAEC,YAAY,QAAQ,aAAU;AASxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAACC,MAAmB,EAAEC,KAAa,EAAuB;EAC3F,MAAMC,UAAU,GAAGN,SAAS,CAC3B,GAAGK,KAAK,aAAa,EACrBD,MAAM,CAACE,UAAU,IAAIL,oBAAoB,CAACK,UAAU,EACpDJ,YAAY,CAACI,UAAU,EACvB,qBAAqB,EACrB,EACD,CAAC;EACD,MAAMC,cAAc,GAAGP,SAAS,CAC/B,GAAGK,KAAK,iBAAiB,EACzBD,MAAM,CAACG,cAAc,IAAIN,oBAAoB,CAACM,cAAc,EAC5DL,YAAY,CAACK,cAAc,EAC3B,qBACD,CAAC;EACD,MAAMC,UAAU,GAAGR,SAAS,CAC3B,GAAGK,KAAK,aAAa,EACrBD,MAAM,CAACI,UAAU,IAAIP,oBAAoB,CAACO,UAAU,EACpDN,YAAY,CAACM,UAAU,EACvB,qBACD,CAAC;EAED,IAAI,CAACC,MAAM,CAACC,SAAS,CAACJ,UAAU,CAAC,EAAE;IAClC,MAAM,IAAIP,cAAc,CAAC,qBAAqB,EAAE;MAC/CY,OAAO,EAAE,GAAGN,KAAK,gDAAgDC,UAAU;IAC5E,CAAC,CAAC;EACH;EACA,IAAIC,cAAc,GAAGC,UAAU,EAAE;IAChC,MAAM,IAAIT,cAAc,CAAC,qBAAqB,EAAE;MAC/CY,OAAO,EAAE,GAAGN,KAAK,oBAAoBE,cAAc,eAAeF,KAAK,gBAAgBG,UAAU;IAClG,CAAC,CAAC;EACH;EAEA,OAAO;IAAEF,UAAU;IAAEC,cAAc;IAAEC;EAAW,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASI,qBAAqBA,CACpCC,cAAuC,EACvCC,eAAgD,EAChDC,YAAoB,EACS;EAC7B,IAAID,eAAe,KAAK,KAAK,EAAE;IAC9B;IACA;IACA;IACA,OAAO,IAAI;EACZ;EACA,IAAIA,eAAe,EAAE;IACpB,OAAOX,kBAAkB,CAACW,eAAe,EAAE,cAAcC,YAAY,QAAQ,CAAC;EAC/E;EACA,IAAIF,cAAc,EAAE;IACnB,OAAOV,kBAAkB,CAACU,cAAc,EAAE,OAAO,CAAC;EACnD;EACA;EACA;EACA,OAAO,IAAI;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,eAAeA,CAACZ,MAA2B,EAAEa,OAAe,EAAU;EACrF,OAAOnB,cAAc,CAACmB,OAAO,EAAE;IAC9BV,cAAc,EAAEH,MAAM,CAACG,cAAc;IACrCC,UAAU,EAAEJ,MAAM,CAACI,UAAU;IAC7BU,MAAM,EAAE,CAAC;IACTC,MAAM,EAAE;EACT,CAAC,CAAC;AACH;;AAEA;AACA,OAAO,SAASC,QAAQA,CAAChB,MAAkC,EAAEiB,YAAoB,EAAW;EAC3F,OAAOjB,MAAM,KAAK,IAAI,IAAIiB,YAAY,GAAGjB,MAAM,CAACE,UAAU;AAC3D","ignoreList":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Rewarded session bookkeeping (FR-046 – FR-049).
|
|
5
|
+
*
|
|
6
|
+
* Two independent booleans, never derived from one another:
|
|
7
|
+
*
|
|
8
|
+
* rewardConfirmed=false rewardConfirmed=true
|
|
9
|
+
* dismissed=false in progress reward emitted, awaiting dismissal
|
|
10
|
+
* dismissed=true dismissed_no_reward earned
|
|
11
|
+
*
|
|
12
|
+
* The defect this exists to prevent is inferring "earned" from dismissal. It is
|
|
13
|
+
* the most common way rewarded integrations go wrong, and it is a direct revenue
|
|
14
|
+
* and fairness fault: a user who closed the ad after two seconds gets the prize,
|
|
15
|
+
* and the publisher is billed for nothing.
|
|
16
|
+
*
|
|
17
|
+
* Tracking two flags and deriving the outcome makes both callback orderings
|
|
18
|
+
* produce the same result *by construction* rather than by the provider
|
|
19
|
+
* happening to fire in a convenient order (SC-007).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export function createRewardedSession() {
|
|
23
|
+
let confirmed = false;
|
|
24
|
+
let dismissed = false;
|
|
25
|
+
let earnedReward = null;
|
|
26
|
+
return {
|
|
27
|
+
confirmReward(reward) {
|
|
28
|
+
if (confirmed) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
confirmed = true;
|
|
32
|
+
earnedReward = reward;
|
|
33
|
+
return reward;
|
|
34
|
+
},
|
|
35
|
+
dismiss() {
|
|
36
|
+
if (dismissed) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
dismissed = true;
|
|
40
|
+
return true;
|
|
41
|
+
},
|
|
42
|
+
outcome() {
|
|
43
|
+
if (!dismissed) {
|
|
44
|
+
return 'in_progress';
|
|
45
|
+
}
|
|
46
|
+
// Read at dismissal time, so a reward that arrived first is honored and
|
|
47
|
+
// one that never arrives is not invented.
|
|
48
|
+
return confirmed ? 'earned' : 'dismissed_without_reward';
|
|
49
|
+
},
|
|
50
|
+
get rewardEarned() {
|
|
51
|
+
return confirmed;
|
|
52
|
+
},
|
|
53
|
+
get dismissed() {
|
|
54
|
+
return dismissed;
|
|
55
|
+
},
|
|
56
|
+
reward() {
|
|
57
|
+
return earnedReward;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=rewardedSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createRewardedSession","confirmed","dismissed","earnedReward","confirmReward","reward","dismiss","outcome","rewardEarned"],"sourceRoot":"../../../src","sources":["core/rewardedSession.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAsBA,OAAO,SAASA,qBAAqBA,CAAA,EAAoB;EACxD,IAAIC,SAAS,GAAG,KAAK;EACrB,IAAIC,SAAS,GAAG,KAAK;EACrB,IAAIC,YAA2B,GAAG,IAAI;EAEtC,OAAO;IACNC,aAAaA,CAACC,MAAM,EAAE;MACrB,IAAIJ,SAAS,EAAE;QACd,OAAO,IAAI;MACZ;MACAA,SAAS,GAAG,IAAI;MAChBE,YAAY,GAAGE,MAAM;MACrB,OAAOA,MAAM;IACd,CAAC;IAEDC,OAAOA,CAAA,EAAG;MACT,IAAIJ,SAAS,EAAE;QACd,OAAO,KAAK;MACb;MACAA,SAAS,GAAG,IAAI;MAChB,OAAO,IAAI;IACZ,CAAC;IAEDK,OAAOA,CAAA,EAAG;MACT,IAAI,CAACL,SAAS,EAAE;QACf,OAAO,aAAa;MACrB;MACA;MACA;MACA,OAAOD,SAAS,GAAG,QAAQ,GAAG,0BAA0B;IACzD,CAAC;IAED,IAAIO,YAAYA,CAAA,EAAG;MAClB,OAAOP,SAAS;IACjB,CAAC;IAED,IAAIC,SAASA,CAAA,EAAG;MACf,OAAOA,SAAS;IACjB,CAAC;IAEDG,MAAMA,CAAA,EAAG;MACR,OAAOF,YAAY;IACpB;EACD,CAAC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Timeout and staleness policy (FR-032, FR-034).
|
|
5
|
+
*
|
|
6
|
+
* Defaults and bounds live here rather than at each call site so there is one
|
|
7
|
+
* place to read what the package will wait for. Values outside a band are a
|
|
8
|
+
* configuration error rather than being silently clamped: silently clamping a
|
|
9
|
+
* one-second load timeout to five would mean the app is told it configured
|
|
10
|
+
* something it did not (FR-008).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { checkRange } from '@chipmobilesdk/rn-core';
|
|
14
|
+
import { AdsConfigError } from "../diagnostics/errors.js";
|
|
15
|
+
/** Comfortably longer than a normal fill on a slow mobile network, still bounded. */
|
|
16
|
+
export const DEFAULT_LOAD_TIMEOUT_MS = 30_000;
|
|
17
|
+
/** Generous for what is essentially a local presentation. */
|
|
18
|
+
export const DEFAULT_SHOW_TIMEOUT_MS = 10_000;
|
|
19
|
+
/**
|
|
20
|
+
* Google documents that a loaded ad object expires about an hour after load.
|
|
21
|
+
* Sixty minutes is the provider's own number; choosing anything else would be
|
|
22
|
+
* inventing a constraint (R7).
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_AD_VALIDITY_MS = 3_600_000;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* App-open's own window, deliberately shorter than the hour the other
|
|
28
|
+
* full-screen formats get (FR-130).
|
|
29
|
+
*
|
|
30
|
+
* Worth being explicit about why: Google expires app-open ads after **four
|
|
31
|
+
* hours**, which is *longer* than DEFAULT_AD_VALIDITY_MS, so the provider does
|
|
32
|
+
* not constrain this at all. The shorter window is a product decision. An
|
|
33
|
+
* app-open ad shows at the most prominent moment the app has, and a creative
|
|
34
|
+
* cached for an hour is stale by then; thirty minutes still spares a returning
|
|
35
|
+
* user the spinner of a cold load, which is both the worst app-open experience
|
|
36
|
+
* and the specific behavior store policy penalizes.
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_APP_OPEN_VALIDITY_MS = 1_800_000;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* How long `enabled: 'undecided'` may go unresolved before one warning fires.
|
|
42
|
+
*
|
|
43
|
+
* Ten seconds is several times a realistic worst case for the round trip this
|
|
44
|
+
* state exists to cover — asking a store whether the user owns an ad-removal
|
|
45
|
+
* entitlement — so an app doing the right thing essentially never trips it,
|
|
46
|
+
* while an app that forgot to resolve trips it inside a single QA session,
|
|
47
|
+
* which is where it needs to be caught (FR-119).
|
|
48
|
+
*/
|
|
49
|
+
export const DEFAULT_UNDECIDED_WARNING_MS = 10_000;
|
|
50
|
+
export const LOAD_TIMEOUT_BOUNDS = {
|
|
51
|
+
min: 5_000,
|
|
52
|
+
max: 120_000
|
|
53
|
+
};
|
|
54
|
+
export const SHOW_TIMEOUT_BOUNDS = {
|
|
55
|
+
min: 5_000,
|
|
56
|
+
max: 30_000
|
|
57
|
+
};
|
|
58
|
+
export const AD_VALIDITY_BOUNDS = {
|
|
59
|
+
min: 60_000,
|
|
60
|
+
max: 3_600_000
|
|
61
|
+
};
|
|
62
|
+
/** Ceiling is one hour so app-open can never outlive the general window. */
|
|
63
|
+
export const APP_OPEN_VALIDITY_BOUNDS = {
|
|
64
|
+
min: 60_000,
|
|
65
|
+
max: 3_600_000
|
|
66
|
+
};
|
|
67
|
+
export const UNDECIDED_WARNING_BOUNDS = {
|
|
68
|
+
min: 1_000,
|
|
69
|
+
max: 120_000
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Retry defaults (FR-136).
|
|
74
|
+
*
|
|
75
|
+
* Two retries rather than more: each one is a billable request, and two covers
|
|
76
|
+
* the transient network failure and the momentary no-fill — the cases where
|
|
77
|
+
* trying again plausibly helps. A third mostly pays for a failure that was not
|
|
78
|
+
* transient. 2s then 4s keeps both inside a window the user still associates
|
|
79
|
+
* with the action that triggered the load.
|
|
80
|
+
*/
|
|
81
|
+
export const DEFAULT_RETRY_POLICY = {
|
|
82
|
+
maxRetries: 2,
|
|
83
|
+
initialDelayMs: 2_000,
|
|
84
|
+
maxDelayMs: 30_000
|
|
85
|
+
};
|
|
86
|
+
export const RETRY_BOUNDS = {
|
|
87
|
+
maxRetries: {
|
|
88
|
+
min: 1,
|
|
89
|
+
max: 5
|
|
90
|
+
},
|
|
91
|
+
initialDelayMs: {
|
|
92
|
+
min: 500,
|
|
93
|
+
max: 30_000
|
|
94
|
+
},
|
|
95
|
+
maxDelayMs: {
|
|
96
|
+
min: 1_000,
|
|
97
|
+
max: 60_000
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Ad-originated return detection (FR-128).
|
|
103
|
+
*
|
|
104
|
+
* A background transition within CLICK_WINDOW of a click is attributed to a
|
|
105
|
+
* browser the ad opened. An absence longer than MAX_AWAY is no longer
|
|
106
|
+
* attributable to the ad — the user did something else in between. GRACE covers
|
|
107
|
+
* the moment right after the return, where an app-open show would otherwise
|
|
108
|
+
* fire, without outliving it and refusing a genuinely later show.
|
|
109
|
+
*/
|
|
110
|
+
export const AD_CLICK_WINDOW_MS = 2_000;
|
|
111
|
+
export const AD_RETURN_MAX_AWAY_MS = 300_000;
|
|
112
|
+
export const AD_RETURN_GRACE_MS = 10_000;
|
|
113
|
+
/**
|
|
114
|
+
* `value` when it is inside `bounds`, else an `AdsConfigError` with `code`: each
|
|
115
|
+
* field reports the code its documentation names, so a retry policy out of bounds
|
|
116
|
+
* is `retry_out_of_bounds`, not a timeout's code (CORE-04, ADS-16).
|
|
117
|
+
*/
|
|
118
|
+
export function checkBand(label, value, bounds, code = 'timeout_out_of_bounds', unit = 'ms') {
|
|
119
|
+
return checkRange(label, value, bounds, message => new AdsConfigError(code, {
|
|
120
|
+
message
|
|
121
|
+
}), unit);
|
|
122
|
+
}
|
|
123
|
+
export function resolveTimeouts(input) {
|
|
124
|
+
const {
|
|
125
|
+
timeouts,
|
|
126
|
+
adValidityMs,
|
|
127
|
+
appOpenValidityMs,
|
|
128
|
+
undecidedWarningMs
|
|
129
|
+
} = input;
|
|
130
|
+
return {
|
|
131
|
+
load: checkBand('timeouts.load', timeouts?.load ?? DEFAULT_LOAD_TIMEOUT_MS, LOAD_TIMEOUT_BOUNDS),
|
|
132
|
+
show: checkBand('timeouts.show', timeouts?.show ?? DEFAULT_SHOW_TIMEOUT_MS, SHOW_TIMEOUT_BOUNDS),
|
|
133
|
+
adValidity: checkBand('adValidityMs', adValidityMs ?? DEFAULT_AD_VALIDITY_MS, AD_VALIDITY_BOUNDS),
|
|
134
|
+
appOpenValidity: checkBand('appOpenValidityMs', appOpenValidityMs ?? DEFAULT_APP_OPEN_VALIDITY_MS, APP_OPEN_VALIDITY_BOUNDS),
|
|
135
|
+
undecidedWarning: checkBand('undecidedWarningMs', undecidedWarningMs ?? DEFAULT_UNDECIDED_WARNING_MS, UNDECIDED_WARNING_BOUNDS)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* How timers are scheduled, and the set that tracks them so `dispose()` can prove
|
|
141
|
+
* it released every one (SC-008): rn-core's, injectable so a test drives retry
|
|
142
|
+
* backoff, app-open expiry and the undecided warning by moving a clock.
|
|
143
|
+
*/
|
|
144
|
+
export { createTimerSet } from '@chipmobilesdk/rn-core';
|
|
145
|
+
|
|
146
|
+
/** A loaded ad past its validity window must never be reported ready (FR-034). */
|
|
147
|
+
export function isStale(loadedAtMs, nowMs, adValidityMs) {
|
|
148
|
+
return nowMs - loadedAtMs >= adValidityMs;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=timers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["checkRange","AdsConfigError","DEFAULT_LOAD_TIMEOUT_MS","DEFAULT_SHOW_TIMEOUT_MS","DEFAULT_AD_VALIDITY_MS","DEFAULT_APP_OPEN_VALIDITY_MS","DEFAULT_UNDECIDED_WARNING_MS","LOAD_TIMEOUT_BOUNDS","min","max","SHOW_TIMEOUT_BOUNDS","AD_VALIDITY_BOUNDS","APP_OPEN_VALIDITY_BOUNDS","UNDECIDED_WARNING_BOUNDS","DEFAULT_RETRY_POLICY","maxRetries","initialDelayMs","maxDelayMs","RETRY_BOUNDS","AD_CLICK_WINDOW_MS","AD_RETURN_MAX_AWAY_MS","AD_RETURN_GRACE_MS","checkBand","label","value","bounds","code","unit","message","resolveTimeouts","input","timeouts","adValidityMs","appOpenValidityMs","undecidedWarningMs","load","show","adValidity","appOpenValidity","undecidedWarning","createTimerSet","isStale","loadedAtMs","nowMs"],"sourceRoot":"../../../src","sources":["core/timers.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Correlation identifiers (FR-052).
|
|
5
|
+
*
|
|
6
|
+
* One value is minted when a load begins and carried by every event of that
|
|
7
|
+
* load/show cycle through its terminal event. It is what lets a consumer
|
|
8
|
+
* reconstruct a single ad's life from an event stream alone (SC-009) without the
|
|
9
|
+
* package having to store any history of its own.
|
|
10
|
+
*
|
|
11
|
+
* Opaque and monotonic per instance. Not a UUID, and deliberately not derived
|
|
12
|
+
* from anything about the device or the user — it exists to group events, and
|
|
13
|
+
* anything with more meaning than that would be a payload the package has
|
|
14
|
+
* promised not to carry (FR-021).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export function createCorrelationIssuer(prefix = 'ad') {
|
|
18
|
+
let counter = 0;
|
|
19
|
+
// Distinguishes cycles from two instances in one process, which otherwise
|
|
20
|
+
// both start at 1 and would collide in a merged log.
|
|
21
|
+
const instance = Math.random().toString(36).slice(2, 8);
|
|
22
|
+
return {
|
|
23
|
+
next() {
|
|
24
|
+
counter += 1;
|
|
25
|
+
return `${prefix}-${instance}-${counter}`;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=correlation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createCorrelationIssuer","prefix","counter","instance","Math","random","toString","slice","next"],"sourceRoot":"../../../src","sources":["diagnostics/correlation.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA,OAAO,SAASA,uBAAuBA,CAACC,MAAM,GAAG,IAAI,EAAqB;EACzE,IAAIC,OAAO,GAAG,CAAC;EACf;EACA;EACA,MAAMC,QAAQ,GAAGC,IAAI,CAACC,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;EAEvD,OAAO;IACNC,IAAIA,CAAA,EAAG;MACNN,OAAO,IAAI,CAAC;MACZ,OAAO,GAAGD,MAAM,IAAIE,QAAQ,IAAID,OAAO,EAAE;IAC1C;EACD,CAAC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalized error model (FR-053) and redaction (NFR-006).
|
|
5
|
+
*
|
|
6
|
+
* Codes are stable public API: renaming one is a breaking change under LIB-008.
|
|
7
|
+
* They exist so a consuming app branches on `code` and `retryable` rather than
|
|
8
|
+
* string-matching a provider message that may change under it.
|
|
9
|
+
*
|
|
10
|
+
* `cause` is a redacted string, never the provider's error object. A provider
|
|
11
|
+
* object reaching a consumer would be a contract leak (FR-002) and a potential
|
|
12
|
+
* carrier for identifiers the package promises never to emit (FR-021).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { SdkError, createRedactor } from '@chipmobilesdk/rn-core';
|
|
16
|
+
/**
|
|
17
|
+
* "Retrying this operation could plausibly succeed" — not "retry immediately".
|
|
18
|
+
*
|
|
19
|
+
* 0.2.0 added an opt-in retry policy, and this set is what it is allowed to act
|
|
20
|
+
* on. Everything outside it is excluded deliberately: configuration and consent
|
|
21
|
+
* errors, an unsupported platform, and a disabled or undecided instance are all
|
|
22
|
+
* states another attempt cannot change, so retrying them would spend a billable
|
|
23
|
+
* request on a certainty (FR-135).
|
|
24
|
+
*/
|
|
25
|
+
const RETRYABLE = new Set(['no_fill', 'network_error', 'load_timeout', 'show_timeout', 'ad_expired', 'not_ready', 'busy', 'consumed', 'app_inactive', 'provider_error']);
|
|
26
|
+
/** The package's error; an `SdkError` (`@chipmobilesdk/rn-core`) with `pkg: 'rn-ads'`. */
|
|
27
|
+
export class AdsError extends SdkError {
|
|
28
|
+
/** Redacted provider detail. Never a provider object. */
|
|
29
|
+
|
|
30
|
+
constructor(code, options = {}) {
|
|
31
|
+
const cause = options.cause === undefined ? undefined : redact(options.cause);
|
|
32
|
+
super('rn-ads', code, {
|
|
33
|
+
message: options.message,
|
|
34
|
+
retryable: RETRYABLE.has(code),
|
|
35
|
+
redactedCause: cause
|
|
36
|
+
});
|
|
37
|
+
this.name = 'AdsError';
|
|
38
|
+
this.operation = options.operation;
|
|
39
|
+
this.placementKey = options.placementKey;
|
|
40
|
+
this.format = options.format;
|
|
41
|
+
this.cause = cause;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Configuration faults are thrown rather than returned, because they mean the
|
|
47
|
+
* app is wired wrong and no runtime result could describe a usable outcome.
|
|
48
|
+
* Every other failure in the package is a typed result (FR-004).
|
|
49
|
+
*/
|
|
50
|
+
export class AdsConfigError extends AdsError {
|
|
51
|
+
constructor(code, options = {}) {
|
|
52
|
+
super(code, {
|
|
53
|
+
...options,
|
|
54
|
+
operation: options.operation ?? 'configure'
|
|
55
|
+
});
|
|
56
|
+
this.name = 'AdsConfigError';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function isAdsError(value) {
|
|
60
|
+
return value instanceof AdsError;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** An AdMob unit or app id. Redacted so a log never carries a live identifier. */
|
|
64
|
+
const AD_UNIT_PATTERN = /ca-app-pub-\d+[~/]\d+/g;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Keys dropped wholesale rather than pattern-matched, because their values are
|
|
68
|
+
* sensitive regardless of shape — a bare advertising id has no separator for a
|
|
69
|
+
* pattern to catch.
|
|
70
|
+
*/
|
|
71
|
+
const SENSITIVE_KEYS = ['adid', 'adUnitId', 'advertisingId', 'consent', 'consentString', 'gaid', 'idfa', 'tcString', 'token', 'userId'];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* rn-core's pattern redaction (URLs, JWTs, e-mail addresses, UUIDs, payload-sized
|
|
75
|
+
* runs) plus ad unit ids, with the keys above dropped. Provider messages are kept
|
|
76
|
+
* readable: they describe the failure, and every identifier in them is shaped.
|
|
77
|
+
*/
|
|
78
|
+
const redactor = createRedactor({
|
|
79
|
+
text: 'patterns',
|
|
80
|
+
patterns: [AD_UNIT_PATTERN],
|
|
81
|
+
dropKeys: SENSITIVE_KEYS,
|
|
82
|
+
maxDepth: 2
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Reduces an arbitrary provider value to a safe string (FR-053, NFR-006).
|
|
87
|
+
*
|
|
88
|
+
* Returns a string rather than a structure on purpose: a redacted object still
|
|
89
|
+
* hands the consumer a reference into provider-owned memory, and the contract
|
|
90
|
+
* promises no provider object crosses the boundary. An `AdsError` reduces to its
|
|
91
|
+
* code.
|
|
92
|
+
*/
|
|
93
|
+
export function redact(value) {
|
|
94
|
+
return redactor.text(value);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Maps a provider failure onto the normalized taxonomy.
|
|
99
|
+
*
|
|
100
|
+
* The adapter's classification wins when it gave one (ADS-08). Otherwise the
|
|
101
|
+
* match is on substrings that have been stable across provider releases, and
|
|
102
|
+
* anything unrecognized becomes a retryable `provider_error` rather than being
|
|
103
|
+
* reshaped into a code that means something specific.
|
|
104
|
+
*/
|
|
105
|
+
export function normalizeProviderError(value, options = {}, kind) {
|
|
106
|
+
switch (kind) {
|
|
107
|
+
case 'no_fill':
|
|
108
|
+
return new AdsError('no_fill', {
|
|
109
|
+
...options,
|
|
110
|
+
cause: value
|
|
111
|
+
});
|
|
112
|
+
case 'network':
|
|
113
|
+
return new AdsError('network_error', {
|
|
114
|
+
...options,
|
|
115
|
+
cause: value
|
|
116
|
+
});
|
|
117
|
+
case 'rejected':
|
|
118
|
+
return new AdsError('provider_rejected', {
|
|
119
|
+
...options,
|
|
120
|
+
cause: value
|
|
121
|
+
});
|
|
122
|
+
default:
|
|
123
|
+
}
|
|
124
|
+
const text = value instanceof Error ? value.message : String(value ?? '');
|
|
125
|
+
const lowered = text.toLowerCase();
|
|
126
|
+
if (lowered.includes('no-fill') || lowered.includes('no fill')) {
|
|
127
|
+
return new AdsError('no_fill', {
|
|
128
|
+
...options,
|
|
129
|
+
cause: value
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (lowered.includes('network')) {
|
|
133
|
+
return new AdsError('network_error', {
|
|
134
|
+
...options,
|
|
135
|
+
cause: value
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return new AdsError('provider_error', {
|
|
139
|
+
...options,
|
|
140
|
+
cause: value
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["SdkError","createRedactor","RETRYABLE","Set","AdsError","constructor","code","options","cause","undefined","redact","message","retryable","has","redactedCause","name","operation","placementKey","format","AdsConfigError","isAdsError","value","AD_UNIT_PATTERN","SENSITIVE_KEYS","redactor","text","patterns","dropKeys","maxDepth","normalizeProviderError","kind","Error","String","lowered","toLowerCase","includes"],"sourceRoot":"../../../src","sources":["diagnostics/errors.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,QAAQ,EAAEC,cAAc,QAAQ,wBAAwB;AA4DjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,SAAoC,GAAG,IAAIC,GAAG,CAAe,CAClE,SAAS,EACT,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,WAAW,EACX,MAAM,EACN,UAAU,EACV,cAAc,EACd,gBAAgB,CAChB,CAAC;AAUF;AACA,OAAO,MAAMC,QAAQ,SAASJ,QAAQ,CAAe;EAIpD;;EAGAK,WAAWA,CAACC,IAAkB,EAAEC,OAAwB,GAAG,CAAC,CAAC,EAAE;IAC9D,MAAMC,KAAK,GAAGD,OAAO,CAACC,KAAK,KAAKC,SAAS,GAAGA,SAAS,GAAGC,MAAM,CAACH,OAAO,CAACC,KAAK,CAAC;IAC7E,KAAK,CAAC,QAAQ,EAAEF,IAAI,EAAE;MACrBK,OAAO,EAAEJ,OAAO,CAACI,OAAO;MACxBC,SAAS,EAAEV,SAAS,CAACW,GAAG,CAACP,IAAI,CAAC;MAC9BQ,aAAa,EAAEN;IAChB,CAAC,CAAC;IACF,IAAI,CAACO,IAAI,GAAG,UAAU;IACtB,IAAI,CAACC,SAAS,GAAGT,OAAO,CAACS,SAAS;IAClC,IAAI,CAACC,YAAY,GAAGV,OAAO,CAACU,YAAY;IACxC,IAAI,CAACC,MAAM,GAAGX,OAAO,CAACW,MAAM;IAC5B,IAAI,CAACV,KAAK,GAAGA,KAAK;EACnB;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMW,cAAc,SAASf,QAAQ,CAAC;EAC5CC,WAAWA,CAACC,IAAkB,EAAEC,OAAwB,GAAG,CAAC,CAAC,EAAE;IAC9D,KAAK,CAACD,IAAI,EAAE;MAAE,GAAGC,OAAO;MAAES,SAAS,EAAET,OAAO,CAACS,SAAS,IAAI;IAAY,CAAC,CAAC;IACxE,IAAI,CAACD,IAAI,GAAG,gBAAgB;EAC7B;AACD;AAEA,OAAO,SAASK,UAAUA,CAACC,KAAc,EAAqB;EAC7D,OAAOA,KAAK,YAAYjB,QAAQ;AACjC;;AAEA;AACA,MAAMkB,eAAe,GAAG,wBAAwB;;AAEhD;AACA;AACA;AACA;AACA;AACA,MAAMC,cAAc,GAAG,CACtB,MAAM,EACN,UAAU,EACV,eAAe,EACf,SAAS,EACT,eAAe,EACf,MAAM,EACN,MAAM,EACN,UAAU,EACV,OAAO,EACP,QAAQ,CACR;;AAED;AACA;AACA;AACA;AACA;AACA,MAAMC,QAAQ,GAAGvB,cAAc,CAAC;EAC/BwB,IAAI,EAAE,UAAU;EAChBC,QAAQ,EAAE,CAACJ,eAAe,CAAC;EAC3BK,QAAQ,EAAEJ,cAAc;EACxBK,QAAQ,EAAE;AACX,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASlB,MAAMA,CAACW,KAAc,EAAU;EAC9C,OAAOG,QAAQ,CAACC,IAAI,CAACJ,KAAK,CAAC;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASQ,sBAAsBA,CACrCR,KAAc,EACdd,OAAwB,GAAG,CAAC,CAAC,EAC7BuB,IAAyC,EAC9B;EACX,QAAQA,IAAI;IACX,KAAK,SAAS;MACb,OAAO,IAAI1B,QAAQ,CAAC,SAAS,EAAE;QAAE,GAAGG,OAAO;QAAEC,KAAK,EAAEa;MAAM,CAAC,CAAC;IAC7D,KAAK,SAAS;MACb,OAAO,IAAIjB,QAAQ,CAAC,eAAe,EAAE;QAAE,GAAGG,OAAO;QAAEC,KAAK,EAAEa;MAAM,CAAC,CAAC;IACnE,KAAK,UAAU;MACd,OAAO,IAAIjB,QAAQ,CAAC,mBAAmB,EAAE;QAAE,GAAGG,OAAO;QAAEC,KAAK,EAAEa;MAAM,CAAC,CAAC;IACvE;EACD;EACA,MAAMI,IAAI,GAAGJ,KAAK,YAAYU,KAAK,GAAGV,KAAK,CAACV,OAAO,GAAGqB,MAAM,CAACX,KAAK,IAAI,EAAE,CAAC;EACzE,MAAMY,OAAO,GAAGR,IAAI,CAACS,WAAW,CAAC,CAAC;EAElC,IAAID,OAAO,CAACE,QAAQ,CAAC,SAAS,CAAC,IAAIF,OAAO,CAACE,QAAQ,CAAC,SAAS,CAAC,EAAE;IAC/D,OAAO,IAAI/B,QAAQ,CAAC,SAAS,EAAE;MAAE,GAAGG,OAAO;MAAEC,KAAK,EAAEa;IAAM,CAAC,CAAC;EAC7D;EACA,IAAIY,OAAO,CAACE,QAAQ,CAAC,SAAS,CAAC,EAAE;IAChC,OAAO,IAAI/B,QAAQ,CAAC,eAAe,EAAE;MAAE,GAAGG,OAAO;MAAEC,KAAK,EAAEa;IAAM,CAAC,CAAC;EACnE;EACA,OAAO,IAAIjB,QAAQ,CAAC,gBAAgB,EAAE;IAAE,GAAGG,OAAO;IAAEC,KAAK,EAAEa;EAAM,CAAC,CAAC;AACpE","ignoreList":[]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalized event model and emitter (FR-051, FR-052, FR-054, FR-056).
|
|
5
|
+
*
|
|
6
|
+
* Events are the package's only observability surface. They carry no provider
|
|
7
|
+
* object, no advertising identifier, no consent payload, and nothing that
|
|
8
|
+
* identifies a user — a consuming app forwards them to whatever logging or
|
|
9
|
+
* analytics it already has, and the package depends on none (FR-055).
|
|
10
|
+
*
|
|
11
|
+
* Dispatch iterates a snapshot of the listener set so subscribing or
|
|
12
|
+
* unsubscribing during a dispatch neither skips a listener nor double-invokes
|
|
13
|
+
* one. A listener that throws is caught and reported once; it cannot corrupt a
|
|
14
|
+
* state machine or starve another listener (FR-056).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createDiagnosticChannel, createEmitter } from '@chipmobilesdk/rn-core';
|
|
18
|
+
import { AdsError } from "./errors.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* `source` records whether the provider reported a true impression or the
|
|
22
|
+
* package derived one. Banners get a real impression callback; full-screen
|
|
23
|
+
* formats have none in the provider's event enum, so theirs is derived from the
|
|
24
|
+
* ad opening. Flattening that away would make the model quietly wrong for anyone
|
|
25
|
+
* reconciling these events against revenue reporting.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Configuration problems worth telling the app about, all under one event type.
|
|
30
|
+
*
|
|
31
|
+
* One type rather than three because FR-132 forbids a parallel vocabulary, and
|
|
32
|
+
* because a consumer already routing `config_warning` into its logging should
|
|
33
|
+
* not have to subscribe again to keep seeing everything.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/** Events that may occur at most once within one correlated cycle (FR-054). */
|
|
37
|
+
const ONCE_PER_CYCLE = new Set(['loaded', 'display_started', 'impression', 'dismissed', 'reward_earned']);
|
|
38
|
+
/**
|
|
39
|
+
* How many once-per-cycle keys the emitter remembers. A cycle's duplicates arrive
|
|
40
|
+
* within that cycle, so forgetting the oldest keys past this bound loses nothing,
|
|
41
|
+
* and memory stays flat however long the instance lives (CORE-12, ADS-05).
|
|
42
|
+
*/
|
|
43
|
+
const DEDUPE_CAPACITY = 256;
|
|
44
|
+
|
|
45
|
+
/** Every delivered event also goes to the app's SDK sinks (`installSdkSink`, CORE-08). */
|
|
46
|
+
const channel = createDiagnosticChannel('rn-ads');
|
|
47
|
+
function severityOf(event) {
|
|
48
|
+
switch (event.type) {
|
|
49
|
+
case 'internal_error':
|
|
50
|
+
return 'error';
|
|
51
|
+
case 'load_failed':
|
|
52
|
+
case 'display_failed':
|
|
53
|
+
case 'config_warning':
|
|
54
|
+
return 'warn';
|
|
55
|
+
default:
|
|
56
|
+
return 'info';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** What a sink may see: where and which cycle, and an error's code. Never a payload. */
|
|
61
|
+
function contextOf(event) {
|
|
62
|
+
return {
|
|
63
|
+
...(event.placementKey === undefined ? {} : {
|
|
64
|
+
placementKey: event.placementKey
|
|
65
|
+
}),
|
|
66
|
+
...(event.format === undefined ? {} : {
|
|
67
|
+
format: event.format
|
|
68
|
+
}),
|
|
69
|
+
...('error' in event ? {
|
|
70
|
+
code: event.error.code,
|
|
71
|
+
retryable: event.error.retryable
|
|
72
|
+
} : {})
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function createEventEmitter() {
|
|
76
|
+
// The event whose listeners are running, so a listener's failure is reported
|
|
77
|
+
// against the placement and cycle it broke (FR-056).
|
|
78
|
+
let dispatching = null;
|
|
79
|
+
const emitter = createEmitter({
|
|
80
|
+
onListenerError(error) {
|
|
81
|
+
emitter.emit({
|
|
82
|
+
type: 'internal_error',
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
placementKey: dispatching?.placementKey,
|
|
85
|
+
format: dispatching?.format,
|
|
86
|
+
correlationId: dispatching?.correlationId,
|
|
87
|
+
error: new AdsError('internal_error', {
|
|
88
|
+
message: 'consumer event listener threw',
|
|
89
|
+
cause: error
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
dedupe: {
|
|
94
|
+
key: event => event.correlationId && ONCE_PER_CYCLE.has(event.type) ? `${event.correlationId}:${event.type}` : undefined,
|
|
95
|
+
capacity: DEDUPE_CAPACITY
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return {
|
|
99
|
+
emit(event) {
|
|
100
|
+
// After dispose, a late provider callback updates nothing and emits
|
|
101
|
+
// nothing (FR-035, SC-008); the rn-core emitter enforces both.
|
|
102
|
+
const previous = dispatching;
|
|
103
|
+
dispatching = event;
|
|
104
|
+
try {
|
|
105
|
+
if (emitter.emit(event)) {
|
|
106
|
+
channel.emit(event.type, severityOf(event), contextOf(event), event.correlationId);
|
|
107
|
+
}
|
|
108
|
+
} finally {
|
|
109
|
+
dispatching = previous;
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
// Idempotent unsubscribe (FR-005).
|
|
113
|
+
subscribe: listener => emitter.subscribe(listener),
|
|
114
|
+
dispose: () => emitter.dispose(),
|
|
115
|
+
listenerCount: () => emitter.listenerCount()
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Normalizes a provider reward descriptor. No provider object crosses this (FR-047). */
|
|
120
|
+
export function normalizeReward(value) {
|
|
121
|
+
const source = value ?? {};
|
|
122
|
+
const amount = Number(source.amount);
|
|
123
|
+
return {
|
|
124
|
+
type: typeof source.type === 'string' ? source.type : 'reward',
|
|
125
|
+
amount: Number.isFinite(amount) ? amount : 0
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createDiagnosticChannel","createEmitter","AdsError","ONCE_PER_CYCLE","Set","DEDUPE_CAPACITY","channel","severityOf","event","type","contextOf","placementKey","undefined","format","code","error","retryable","createEventEmitter","dispatching","emitter","onListenerError","emit","timestamp","Date","now","correlationId","message","cause","dedupe","key","has","capacity","previous","subscribe","listener","dispose","listenerCount","normalizeReward","value","source","amount","Number","isFinite"],"sourceRoot":"../../../src","sources":["diagnostics/events.ts"],"mappings":"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","ignoreList":[]}
|