@chipmobilesdk/rn-ads 0.5.1 → 0.7.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 +178 -0
- package/README.md +12 -3
- package/package.json +5 -2
- package/skills/sdk-rn-ads/SKILL.md +3 -2
- package/src/config/validate.ts +3 -1
- package/src/core/adsInstance.ts +85 -1872
- 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/core/retryPolicy.ts +12 -2
- package/src/core/timers.ts +17 -69
- package/src/diagnostics/errors.ts +52 -63
- package/src/diagnostics/events.ts +77 -66
- package/src/engine/admobBanner.tsx +55 -0
- package/src/engine/admobEngine.ts +38 -18
- package/src/engine/admobErrors.ts +44 -0
- package/src/engine/port.ts +46 -1
- package/src/engine/testAdUnits.ts +0 -5
- package/src/index.ts +19 -1
- package/src/react/AdsBanner.tsx +94 -79
- package/src/react/AdsProvider.tsx +6 -7
- package/src/react/hooks.ts +26 -31
- package/src/testing/clock.ts +75 -0
- package/src/testing/conformance.ts +112 -0
- package/src/testing/index.ts +43 -70
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,183 @@
|
|
|
1
1
|
# @chipmobilesdk/rn-ads
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- The ads instance is split by responsibility, and the banner host's wiring is off the
|
|
8
|
+
public type. ([#19](https://github.com/operationd8979/chip-mobile-sdk/pull/19))
|
|
9
|
+
|
|
10
|
+
- `AdsInstance` no longer has an `internals` field. It was undocumented, but any
|
|
11
|
+
consumer could use it to emit `impression` or `reward_earned` into the event stream
|
|
12
|
+
used for revenue reconciliation. `AdsBanner` now reaches an instance's wiring through
|
|
13
|
+
a private registry, so a banner given an instance the app wrote by hand renders
|
|
14
|
+
nothing instead of throwing.
|
|
15
|
+
- Banner events carry the instance's clock (`createAds({ now })`), like full-screen
|
|
16
|
+
events, and resolving a banner during render no longer mints a correlation id.
|
|
17
|
+
- `allTestAdUnits()` moved from the engine module to `@chipmobilesdk/rn-ads/testing`.
|
|
18
|
+
- Rewards from AdMob go through the one `normalizeReward`; an unused consent port guard
|
|
19
|
+
and the throttle's unused `reset`/`lastRequestAt` are gone.
|
|
20
|
+
- Internally, `createAds` is now a 142-line composition root over `core/instance/`
|
|
21
|
+
(gate, init, load, show, consent, internals), down from one 1,899-line closure. Every
|
|
22
|
+
path that closes the request gate goes through one teardown.
|
|
23
|
+
|
|
24
|
+
- Four fixes to how ads behave around throttling, retries and show timeouts. ([#19](https://github.com/operationd8979/chip-mobile-sdk/pull/19))
|
|
25
|
+
|
|
26
|
+
- A banner refused by the request throttle now tries again by itself once the window
|
|
27
|
+
passes. Before, it stayed empty until it was remounted, so a banner on a screen the
|
|
28
|
+
user returned to within a minute never filled.
|
|
29
|
+
- A load retry waits at least as long as the placement's `minRequestIntervalMs`
|
|
30
|
+
requires, so a retry policy cannot request faster than the floor allows. The
|
|
31
|
+
`retry_scheduled` event reports the wait actually used.
|
|
32
|
+
- A request AdMob refuses outright (an invalid request or ad unit, a missing app id)
|
|
33
|
+
is the new non-retryable `provider_rejected` code instead of a retryable
|
|
34
|
+
`provider_error`, so a retry policy no longer spends billable requests on it. Engines
|
|
35
|
+
may classify a failure with the new optional `kind` on the `failed` event.
|
|
36
|
+
- A show that times out and then opens anyway is reported once, not twice. The late
|
|
37
|
+
ad holds the full-screen lock until it is dismissed, and its reward and dismissal
|
|
38
|
+
still reach the app.
|
|
39
|
+
|
|
40
|
+
- The banner renders through the engine port. `AdsEngine` has an optional `banner`
|
|
41
|
+
capability (`isAvailable()` and a `Component` with neutral props: `adUnitId`,
|
|
42
|
+
`personalizedAds`, `onLoaded`, `onFailed`, `onImpression`, `onClicked`), and the AdMob
|
|
43
|
+
adapter supplies the adaptive `BannerAd` there. `AdsBanner` no longer loads the AdMob
|
|
44
|
+
bridge itself, so a custom or future iOS engine provides its own banner, and the fake
|
|
45
|
+
engine from `./testing` renders one in tests without a mocked native module. An engine
|
|
46
|
+
without `banner` keeps working; its banners report `unavailable`. ([#19](https://github.com/operationd8979/chip-mobile-sdk/pull/19))
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Internal: no module in these packages is over 500 lines any more. The camera controller's session I/O moved to `sessionRuntime` and its contract to `contract.ts`; the Play adapter's shape translation to `iapShapes`; the purchase flow's failure mapping and its receipt-validation hook to modules of their own; the AI client's quota request to `quotaRequest`; the in-memory adapter's attachments and the fake ads engine's clock likewise. Behaviour is unchanged — the splits are by responsibility, and every package's suite passes as it stood. ([#19](https://github.com/operationd8979/chip-mobile-sdk/pull/19))
|
|
51
|
+
|
|
52
|
+
The repository also measures what it promised: `npm run perf` prints the median of nine runs of the deterministic hot paths against written budgets (recurrence expansion, theme construction, translation lookup, chart geometry, filter compilation), the demo app has a Performance screen reporting startup phases, time to interactive and the same benchmarks on Hermes, and `npm run check:file-size` keeps the limit from drifting. The budgets and the measured figures are recorded in `docs/standards.md` §VI.
|
|
53
|
+
|
|
54
|
+
## 0.6.0
|
|
55
|
+
|
|
56
|
+
### Minor Changes
|
|
57
|
+
|
|
58
|
+
- One diagnostic stream: install a sink with `installSdkSink` from
|
|
59
|
+
`@chipmobilesdk/rn-core` and it receives what every package observes (events,
|
|
60
|
+
failures, warnings) as `SdkDiagnostic`s, redacted. Listeners are notified through
|
|
61
|
+
rn-core, so a listener that throws no longer stops the others nor fails the call that
|
|
62
|
+
notified, and its error is reported rather than swallowed. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
63
|
+
|
|
64
|
+
- rn-ads: a banner's auto-refresh is a new cycle, so its `loaded` and `impression`
|
|
65
|
+
events are no longer deduplicated away; the dedupe memory is bounded. A throwing
|
|
66
|
+
status, consent or placement listener is reported as an `internal_error` event.
|
|
67
|
+
- rn-i18n: new `onDiagnostic` config receives every diagnostic (`I18nDiagnostic`,
|
|
68
|
+
with a stable `code`); without it, warnings go to `console.warn` in development
|
|
69
|
+
builds only. The warn-once memory is bounded.
|
|
70
|
+
- rn-chart: now depends on rn-core for its diagnostics.
|
|
71
|
+
- rn-payment: status, entitlement and pending listeners report a throw to the logger
|
|
72
|
+
instead of swallowing it.
|
|
73
|
+
|
|
74
|
+
- The package's errors extend `SdkError` from the new `@chipmobilesdk/rn-core`
|
|
75
|
+
dependency: `isSdkError` recognises them alongside every other package's, and each
|
|
76
|
+
carries `pkg`, `code` and `retryable`. Names and codes are unchanged. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
77
|
+
|
|
78
|
+
- rn-ai and rn-camera: `retryable` is the new name of `recoverable`, which stays as a
|
|
79
|
+
deprecated alias.
|
|
80
|
+
- rn-auth: `retryable` is true for `network-unavailable`. `redact` also removes URLs,
|
|
81
|
+
e-mail addresses and UUIDs.
|
|
82
|
+
- rn-ads: `redact` also removes JWTs and e-mail addresses, and reduces an `AdsError`
|
|
83
|
+
to its code.
|
|
84
|
+
- rn-ai: an error message quoted from the gateway is pattern-redacted.
|
|
85
|
+
- rn-camera: `redact` also removes JWTs, e-mail addresses and UUIDs.
|
|
86
|
+
- rn-theme: `ThemeConfigError` has `code: 'invalid_config'` and `ThemeContrastError`
|
|
87
|
+
`code: 'contrast'` (new `ThemeErrorCode` type).
|
|
88
|
+
- rn-i18n: `I18nConfigError` has `code: 'invalid_config'` and `UnitConversionError`
|
|
89
|
+
`code: 'unit_conversion'` (new `I18nErrorCode` type).
|
|
90
|
+
|
|
91
|
+
- Timers, retries and bounds now come from `@chipmobilesdk/rn-core`, and the drift
|
|
92
|
+
between the copies is fixed. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
93
|
+
|
|
94
|
+
- rn-ads: a retry policy out of bounds throws `retry_out_of_bounds`, as documented,
|
|
95
|
+
instead of `timeout_out_of_bounds`; a placement's `minRequestIntervalMs` out of
|
|
96
|
+
bounds throws `invalid_config`.
|
|
97
|
+
- rn-payment: backoff validates `initialDelayMs` (100 ms to 60 s, not above
|
|
98
|
+
`maxDelayMs`) and `factor` (1 to 10); `factor: 0` used to retry at once, forever.
|
|
99
|
+
Every timeout, backoff or interval out of bounds now throws the new
|
|
100
|
+
`PAYMENT_INVALID_CONFIG` instead of `PAYMENT_INVALID_CATALOG`, which is about
|
|
101
|
+
products.
|
|
102
|
+
- rn-ai: concurrent calls share one behavior-config request, so a cold start makes
|
|
103
|
+
one instead of one per call. A silent retry after a config reload waits
|
|
104
|
+
`recovery.retryBackoffMs`, which was parsed but never applied.
|
|
105
|
+
|
|
106
|
+
- Native peers load through `lazyPeer` from `@chipmobilesdk/rn-core`, on first use,
|
|
107
|
+
and a missing one is each package's own typed error. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
108
|
+
|
|
109
|
+
- rn-auth: creating `auth` no longer loads react-native-app-auth or
|
|
110
|
+
react-native-keychain; each loads on first use. New entrypoints
|
|
111
|
+
`@chipmobilesdk/rn-auth/app-auth` and `/keychain`. The default platform comes from
|
|
112
|
+
rn-core.
|
|
113
|
+
- rn-camera: a preview whose VisionCamera feed cannot load fails the session with
|
|
114
|
+
`cameraUnavailable` (new `controller.reportSurfaceUnavailable()`), instead of
|
|
115
|
+
showing black with no error. A missing VisionCamera module is `cameraUnavailable`.
|
|
116
|
+
- rn-notification: `createMmkvStore` reports a fallback to memory as
|
|
117
|
+
`STATE_STORE_DEGRADED` (to the SDK sinks and a new `onDegraded` option) and
|
|
118
|
+
exposes `durable`.
|
|
119
|
+
- rn-payment: an iOS app validates its catalog against the iOS product ids; the
|
|
120
|
+
default platform used to be Android everywhere. A missing react-native-iap is
|
|
121
|
+
`PAYMENT_UNAVAILABLE`.
|
|
122
|
+
- rn-theme: `buildThemes` runs without React Native (new `hairlineWidth` option) and
|
|
123
|
+
importing the package no longer loads Unistyles; `applyThemeMode` loads it on
|
|
124
|
+
first use.
|
|
125
|
+
- rn-ads, rn-local-db: the same loading, with the same error codes as before.
|
|
126
|
+
|
|
127
|
+
- Hooks read through `useSyncExternalStore` (rn-core's `useExternalStore`) and
|
|
128
|
+
re-render only when what they return changes. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
129
|
+
|
|
130
|
+
- rn-auth: `useProfile` and `useAccessTier` no longer re-render for a status change,
|
|
131
|
+
and the provider's context no longer changes on every transition. New
|
|
132
|
+
`useAuthSelector`. `auth.getState()` returns the same frozen object until the state
|
|
133
|
+
changes, instead of a copy per call.
|
|
134
|
+
- rn-payment: `useEntitlement` re-renders only when its own entitlement changes; the
|
|
135
|
+
engine keeps unchanged entitlement objects across syncs and does not notify for a
|
|
136
|
+
sync that changed nothing.
|
|
137
|
+
- rn-ads: `usePlacementState` and `useAdsStatus` read tear-free; `useAdsEvents` keeps
|
|
138
|
+
one subscription when given an inline listener.
|
|
139
|
+
- rn-i18n: `useTranslation` returns the same `t` until the locale changes, and
|
|
140
|
+
`useLocale`'s `setLocale` is stable.
|
|
141
|
+
- rn-ai: new `useAiBehaviorState`, with `client.subscribe` and a stable
|
|
142
|
+
`client.getBehaviorState()`.
|
|
143
|
+
|
|
144
|
+
- Port conformance suites: one list of checks that a package's fake and its real adapter
|
|
145
|
+
both pass, so a test written against the fake proves something about the device. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
146
|
+
|
|
147
|
+
- rn-core: `@chipmobilesdk/rn-core/testing` adds `runChecks`, `expectConformance`,
|
|
148
|
+
`ensure` and `createFaultRegistry` (deterministic fault injection by named point).
|
|
149
|
+
- rn-camera: a `./testing` entrypoint with `runPermissionPortConformance`,
|
|
150
|
+
`runCameraEngineConformance` and the test adapter, which stays on the main
|
|
151
|
+
entrypoint too until the next major. `createTestCamera(...).prompts()` counts system
|
|
152
|
+
prompts.
|
|
153
|
+
- rn-payment: `runProviderPortConformance` in `./testing`, passed by the fake store and
|
|
154
|
+
the Play adapter.
|
|
155
|
+
- rn-ads: `runAdsEngineConformance` in `./testing`, passed by the fake engine and the
|
|
156
|
+
AdMob adapter.
|
|
157
|
+
- rn-auth: a `./testing` entrypoint with `createMemorySecureStore`,
|
|
158
|
+
`runSecureTokenStoreConformance` and `runOidcAuthClientConformance`, passed by the
|
|
159
|
+
in-memory doubles and the keychain and app-auth adapters.
|
|
160
|
+
|
|
161
|
+
### Patch Changes
|
|
162
|
+
|
|
163
|
+
- One app-lifecycle source, and a startup that needs no extra frame. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
164
|
+
|
|
165
|
+
- rn-core: `appLifecycle()`, a shared, reference-counted `AppState` subscription that
|
|
166
|
+
reports changes only (`active`, `inactive`, `background`), with `onForeground` for a
|
|
167
|
+
return from the background and `createManualLifecycle` in `./testing`.
|
|
168
|
+
- rn-camera, rn-ads and rn-notification hear the lifecycle through it instead of
|
|
169
|
+
subscribing to `AppState` each, so an app holds one native listener. The camera
|
|
170
|
+
controller's core layer no longer imports `react-native`.
|
|
171
|
+
- rn-payment: `syncOnForeground(engine)` and `<PaymentProvider syncOnForeground>` call
|
|
172
|
+
`handleForeground()` on each return from the background. Off by default; calling
|
|
173
|
+
`handleForeground()` yourself works as before.
|
|
174
|
+
- rn-i18n: `i18n.initSync()` resolves the locale before the first render when the
|
|
175
|
+
storage adapter has the new optional `getItemSync`, and returns false otherwise.
|
|
176
|
+
`localeStorageFromKeyValue(port)` builds such an adapter from rn-core's
|
|
177
|
+
`KeyValuePort` (MMKV).
|
|
178
|
+
- Updated dependencies ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17)):
|
|
179
|
+
- @chipmobilesdk/rn-core@0.1.0
|
|
180
|
+
|
|
3
181
|
## 0.5.1
|
|
4
182
|
|
|
5
183
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -268,10 +268,14 @@ ads.subscribeEvents(event => {
|
|
|
268
268
|
|
|
269
269
|
**Ordering and exactly-once** are documented and tested. Within one `correlationId`, `loaded` / `display_started` / `impression` / `dismissed` / `reward_earned` occur at most once; `click` may repeat. After `dispose()`, zero events are emitted — a late provider callback is dropped.
|
|
270
270
|
|
|
271
|
-
**Errors** carry a stable `code`, a log-safe `message`, the `operation`, a `retryable` flag, and a redacted `cause`. Codes are public API; renaming one is a breaking change.
|
|
271
|
+
**Errors** carry a stable `code`, a log-safe `message`, the `operation`, a `retryable` flag, and a redacted `cause`. Codes are public API; renaming one is a breaking change. `AdsError` extends `SdkError` from `@chipmobilesdk/rn-core`, so `isSdkError(error)` recognises it alongside every other package's errors, `error.pkg` names this package, and `error.redactedCause` (when present) is the underlying failure reduced to log-safe text.
|
|
272
|
+
|
|
273
|
+
A config value outside its band names its own field and code: a timeout or validity window is `timeout_out_of_bounds`, a retry policy `retry_out_of_bounds`, a placement's `minRequestIntervalMs` `invalid_config`.
|
|
272
274
|
|
|
273
275
|
Retryable: `no_fill` `network_error` `load_timeout` `show_timeout` `ad_expired` `not_ready` `busy` `consumed` `app_inactive` `provider_error`
|
|
274
|
-
Not retryable: `invalid_config` `duplicate_placement_key` `missing_ad_unit_id` `format_mismatch` `placement_not_found` `production_in_dev_build` `timeout_out_of_bounds` `unsupported_platform` `provider_missing` `disabled` `consent_required` `consent_undetermined` `requires_reinitialization` `internal_error`
|
|
276
|
+
Not retryable: `invalid_config` `duplicate_placement_key` `missing_ad_unit_id` `format_mismatch` `placement_not_found` `production_in_dev_build` `timeout_out_of_bounds` `retry_out_of_bounds` `unsupported_platform` `provider_missing` `disabled` `consent_required` `consent_undetermined` `requires_reinitialization` `provider_rejected` `internal_error`
|
|
277
|
+
|
|
278
|
+
`provider_rejected` (0.7.0) means AdMob refused the request itself — an invalid request or ad unit, a missing app id — so a retry policy does not spend more requests on it. Before, those were `provider_error` and were retried.
|
|
275
279
|
|
|
276
280
|
Attach any logger or analytics you already use. The package depends on none:
|
|
277
281
|
|
|
@@ -741,6 +745,11 @@ engine.failConsentInfoRead(); // the re-read after a failure r
|
|
|
741
745
|
engine.consentCalls // includes 'showPrivacyOptionsForm'
|
|
742
746
|
```
|
|
743
747
|
|
|
748
|
+
`runAdsEngineConformance(harness)` from `./testing` holds the checks every `AdsEngine`
|
|
749
|
+
must pass — initialization, `loaded` reaching a subscriber and nothing after it
|
|
750
|
+
unsubscribes, a reward and a dismissal, one handle per ad, and a dispose that is safe
|
|
751
|
+
twice. The package runs it against the fake engine and the AdMob adapter.
|
|
752
|
+
|
|
744
753
|
On device, verify with Google's official test ads only. `npm run android`, then exercise each `Ads · …` screen in the demo app.
|
|
745
754
|
|
|
746
755
|
---
|
|
@@ -797,7 +806,7 @@ On device, verify with Google's official test ads only. `npm run android`, then
|
|
|
797
806
|
Adding iOS contributes exactly three things and changes **nothing** you have already written:
|
|
798
807
|
|
|
799
808
|
1. **`PlacementDefinition.iosAdUnitId`** — the optional field already exists in v1's type, so existing Android-only catalogs stay valid.
|
|
800
|
-
2. **A second engine adapter** behind the existing `AdsEngine` port. The port names no platform and no provider; that is what makes this additive.
|
|
809
|
+
2. **A second engine adapter** behind the existing `AdsEngine` port. The port names no platform and no provider; that is what makes this additive. The banner is part of the port too (`AdsEngine.banner`, since 0.7.0): an adapter supplies its own banner component, which receives neutral props (`adUnitId`, `personalizedAds`, `onLoaded`, `onFailed`, `onImpression`, `onClicked`), and `AdsBanner` renders whatever the engine offers.
|
|
801
810
|
3. **iOS entries in the private test-ad-unit table.**
|
|
802
811
|
|
|
803
812
|
Your `createAds`, `initialize`, `load`, `show`, `AdsBanner`, and every subscription keep their current signatures. The exported state, event, and error models do not change.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chipmobilesdk/rn-ads",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -31,9 +31,12 @@
|
|
|
31
31
|
],
|
|
32
32
|
"sideEffects": false,
|
|
33
33
|
"scripts": {
|
|
34
|
-
"typecheck": "tsc -p tsconfig.json
|
|
34
|
+
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.test.json",
|
|
35
35
|
"pack:check": "npm pack --dry-run"
|
|
36
36
|
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@chipmobilesdk/rn-core": "^0.1.0"
|
|
39
|
+
},
|
|
37
40
|
"peerDependencies": {
|
|
38
41
|
"react": ">=19",
|
|
39
42
|
"react-native": ">=0.85",
|
|
@@ -173,8 +173,9 @@ policy; everything else returns a typed result rather than throwing) · `AdsProv
|
|
|
173
173
|
`SHOW_TIMEOUT_BOUNDS`, `AD_VALIDITY_BOUNDS`, `APP_OPEN_VALIDITY_BOUNDS`, `RETRY_BOUNDS`,
|
|
174
174
|
`UNDECIDED_WARNING_BOUNDS`, `DEFAULT_BANNER_MIN_REQUEST_INTERVAL_MS`,
|
|
175
175
|
`DEFAULT_FULL_SCREEN_MIN_REQUEST_INTERVAL_MS`, `MIN_REQUEST_INTERVAL_BOUNDS`,
|
|
176
|
-
`defaultMinRequestIntervalMs` · `createFakeAdsEngine`, `createTestClock
|
|
177
|
-
`@chipmobilesdk/rn-ads/testing` (test
|
|
176
|
+
`defaultMinRequestIntervalMs` · `createFakeAdsEngine`, `createTestClock`,
|
|
177
|
+
`runAdsEngineConformance`, `allTestAdUnits` from `@chipmobilesdk/rn-ads/testing` (test
|
|
178
|
+
doubles only).
|
|
178
179
|
|
|
179
180
|
Instance: `initialize`, `updatePrivacy`, `setEnabled`, `setEnablement`, `setAppActive`,
|
|
180
181
|
`consent`, `getStatus`, `subscribeStatus`, `load`, `show`, `getPlacementState`,
|
package/src/config/validate.ts
CHANGED
|
@@ -146,10 +146,12 @@ export function validateConfig(config: AdsConfig, options: ValidateOptions): Res
|
|
|
146
146
|
key,
|
|
147
147
|
placement.minRequestIntervalMs === undefined
|
|
148
148
|
? defaultMinRequestIntervalMs(placement.format)
|
|
149
|
-
:
|
|
149
|
+
: // A request floor, not a timeout: its own code (ADS-16).
|
|
150
|
+
checkBand(
|
|
150
151
|
`placements["${key}"].minRequestIntervalMs`,
|
|
151
152
|
placement.minRequestIntervalMs,
|
|
152
153
|
MIN_REQUEST_INTERVAL_BOUNDS,
|
|
154
|
+
'invalid_config',
|
|
153
155
|
),
|
|
154
156
|
);
|
|
155
157
|
}
|