@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.
Files changed (340) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +4 -2
  3. package/lib/commonjs/config/resolveAdUnit.js +80 -0
  4. package/lib/commonjs/config/resolveAdUnit.js.map +1 -0
  5. package/lib/commonjs/config/types.js +138 -0
  6. package/lib/commonjs/config/types.js.map +1 -0
  7. package/lib/commonjs/config/validate.js +150 -0
  8. package/lib/commonjs/config/validate.js.map +1 -0
  9. package/lib/commonjs/core/adOriginatedReturn.js +119 -0
  10. package/lib/commonjs/core/adOriginatedReturn.js.map +1 -0
  11. package/lib/commonjs/core/adsInstance.js +129 -0
  12. package/lib/commonjs/core/adsInstance.js.map +1 -0
  13. package/lib/commonjs/core/consentFlow.js +154 -0
  14. package/lib/commonjs/core/consentFlow.js.map +1 -0
  15. package/lib/commonjs/core/enablement.js +64 -0
  16. package/lib/commonjs/core/enablement.js.map +1 -0
  17. package/lib/commonjs/core/fullScreenLock.js +48 -0
  18. package/lib/commonjs/core/fullScreenLock.js.map +1 -0
  19. package/lib/commonjs/core/gates.js +95 -0
  20. package/lib/commonjs/core/gates.js.map +1 -0
  21. package/lib/commonjs/core/initMachine.js +159 -0
  22. package/lib/commonjs/core/initMachine.js.map +1 -0
  23. package/lib/commonjs/core/instance/consent.js +155 -0
  24. package/lib/commonjs/core/instance/consent.js.map +1 -0
  25. package/lib/commonjs/core/instance/context.js +217 -0
  26. package/lib/commonjs/core/instance/context.js.map +1 -0
  27. package/lib/commonjs/core/instance/gate.js +194 -0
  28. package/lib/commonjs/core/instance/gate.js.map +1 -0
  29. package/lib/commonjs/core/instance/init.js +326 -0
  30. package/lib/commonjs/core/instance/init.js.map +1 -0
  31. package/lib/commonjs/core/instance/internals.js +115 -0
  32. package/lib/commonjs/core/instance/internals.js.map +1 -0
  33. package/lib/commonjs/core/instance/load.js +458 -0
  34. package/lib/commonjs/core/instance/load.js.map +1 -0
  35. package/lib/commonjs/core/instance/show.js +243 -0
  36. package/lib/commonjs/core/instance/show.js.map +1 -0
  37. package/lib/commonjs/core/instance/types.js +6 -0
  38. package/lib/commonjs/core/instance/types.js.map +1 -0
  39. package/lib/commonjs/core/placementMachine.js +116 -0
  40. package/lib/commonjs/core/placementMachine.js.map +1 -0
  41. package/lib/commonjs/core/privacyGate.js +93 -0
  42. package/lib/commonjs/core/privacyGate.js.map +1 -0
  43. package/lib/commonjs/core/requestThrottle.js +152 -0
  44. package/lib/commonjs/core/requestThrottle.js.map +1 -0
  45. package/lib/commonjs/core/retryPolicy.js +120 -0
  46. package/lib/commonjs/core/retryPolicy.js.map +1 -0
  47. package/lib/commonjs/core/rewardedSession.js +65 -0
  48. package/lib/commonjs/core/rewardedSession.js.map +1 -0
  49. package/lib/commonjs/core/timers.js +162 -0
  50. package/lib/commonjs/core/timers.js.map +1 -0
  51. package/lib/commonjs/diagnostics/correlation.js +33 -0
  52. package/lib/commonjs/diagnostics/correlation.js.map +1 -0
  53. package/lib/commonjs/diagnostics/errors.js +152 -0
  54. package/lib/commonjs/diagnostics/errors.js.map +1 -0
  55. package/lib/commonjs/diagnostics/events.js +132 -0
  56. package/lib/commonjs/diagnostics/events.js.map +1 -0
  57. package/lib/commonjs/engine/admobBanner.js +58 -0
  58. package/lib/commonjs/engine/admobBanner.js.map +1 -0
  59. package/lib/commonjs/engine/admobEngine.js +343 -0
  60. package/lib/commonjs/engine/admobEngine.js.map +1 -0
  61. package/lib/commonjs/engine/admobErrors.js +45 -0
  62. package/lib/commonjs/engine/admobErrors.js.map +1 -0
  63. package/lib/commonjs/engine/port.js +6 -0
  64. package/lib/commonjs/engine/port.js.map +1 -0
  65. package/lib/commonjs/engine/testAdUnits.js +61 -0
  66. package/lib/commonjs/engine/testAdUnits.js.map +1 -0
  67. package/lib/commonjs/index.js +218 -0
  68. package/lib/commonjs/index.js.map +1 -0
  69. package/lib/commonjs/package.json +1 -0
  70. package/lib/commonjs/react/AdsBanner.js +317 -0
  71. package/lib/commonjs/react/AdsBanner.js.map +1 -0
  72. package/lib/commonjs/react/AdsProvider.js +54 -0
  73. package/lib/commonjs/react/AdsProvider.js.map +1 -0
  74. package/lib/commonjs/react/hooks.js +63 -0
  75. package/lib/commonjs/react/hooks.js.map +1 -0
  76. package/lib/commonjs/testing/clock.js +76 -0
  77. package/lib/commonjs/testing/clock.js.map +1 -0
  78. package/lib/commonjs/testing/conformance.js +99 -0
  79. package/lib/commonjs/testing/conformance.js.map +1 -0
  80. package/lib/commonjs/testing/index.js +389 -0
  81. package/lib/commonjs/testing/index.js.map +1 -0
  82. package/lib/module/config/resolveAdUnit.js +75 -0
  83. package/lib/module/config/resolveAdUnit.js.map +1 -0
  84. package/lib/module/config/types.js +134 -0
  85. package/lib/module/config/types.js.map +1 -0
  86. package/lib/module/config/validate.js +146 -0
  87. package/lib/module/config/validate.js.map +1 -0
  88. package/lib/module/core/adOriginatedReturn.js +115 -0
  89. package/lib/module/core/adOriginatedReturn.js.map +1 -0
  90. package/lib/module/core/adsInstance.js +121 -0
  91. package/lib/module/core/adsInstance.js.map +1 -0
  92. package/lib/module/core/consentFlow.js +143 -0
  93. package/lib/module/core/consentFlow.js.map +1 -0
  94. package/lib/module/core/enablement.js +58 -0
  95. package/lib/module/core/enablement.js.map +1 -0
  96. package/lib/module/core/fullScreenLock.js +44 -0
  97. package/lib/module/core/fullScreenLock.js.map +1 -0
  98. package/lib/module/core/gates.js +91 -0
  99. package/lib/module/core/gates.js.map +1 -0
  100. package/lib/module/core/initMachine.js +152 -0
  101. package/lib/module/core/initMachine.js.map +1 -0
  102. package/lib/module/core/instance/consent.js +151 -0
  103. package/lib/module/core/instance/consent.js.map +1 -0
  104. package/lib/module/core/instance/context.js +212 -0
  105. package/lib/module/core/instance/context.js.map +1 -0
  106. package/lib/module/core/instance/gate.js +183 -0
  107. package/lib/module/core/instance/gate.js.map +1 -0
  108. package/lib/module/core/instance/init.js +321 -0
  109. package/lib/module/core/instance/init.js.map +1 -0
  110. package/lib/module/core/instance/internals.js +109 -0
  111. package/lib/module/core/instance/internals.js.map +1 -0
  112. package/lib/module/core/instance/load.js +452 -0
  113. package/lib/module/core/instance/load.js.map +1 -0
  114. package/lib/module/core/instance/show.js +238 -0
  115. package/lib/module/core/instance/show.js.map +1 -0
  116. package/lib/module/core/instance/types.js +4 -0
  117. package/lib/module/core/instance/types.js.map +1 -0
  118. package/lib/module/core/placementMachine.js +109 -0
  119. package/lib/module/core/placementMachine.js.map +1 -0
  120. package/lib/module/core/privacyGate.js +86 -0
  121. package/lib/module/core/privacyGate.js.map +1 -0
  122. package/lib/module/core/requestThrottle.js +146 -0
  123. package/lib/module/core/requestThrottle.js.map +1 -0
  124. package/lib/module/core/retryPolicy.js +113 -0
  125. package/lib/module/core/retryPolicy.js.map +1 -0
  126. package/lib/module/core/rewardedSession.js +61 -0
  127. package/lib/module/core/rewardedSession.js.map +1 -0
  128. package/lib/module/core/timers.js +150 -0
  129. package/lib/module/core/timers.js.map +1 -0
  130. package/lib/module/diagnostics/correlation.js +29 -0
  131. package/lib/module/diagnostics/correlation.js.map +1 -0
  132. package/lib/module/diagnostics/errors.js +143 -0
  133. package/lib/module/diagnostics/errors.js.map +1 -0
  134. package/lib/module/diagnostics/events.js +128 -0
  135. package/lib/module/diagnostics/events.js.map +1 -0
  136. package/lib/module/engine/admobBanner.js +52 -0
  137. package/lib/module/engine/admobBanner.js.map +1 -0
  138. package/lib/module/engine/admobEngine.js +334 -0
  139. package/lib/module/engine/admobEngine.js.map +1 -0
  140. package/lib/module/engine/admobErrors.js +41 -0
  141. package/lib/module/engine/admobErrors.js.map +1 -0
  142. package/lib/module/engine/port.js +4 -0
  143. package/lib/module/engine/port.js.map +1 -0
  144. package/lib/module/engine/testAdUnits.js +56 -0
  145. package/lib/module/engine/testAdUnits.js.map +1 -0
  146. package/lib/module/index.js +59 -0
  147. package/lib/module/index.js.map +1 -0
  148. package/lib/module/package.json +1 -0
  149. package/lib/module/react/AdsBanner.js +312 -0
  150. package/lib/module/react/AdsBanner.js.map +1 -0
  151. package/lib/module/react/AdsProvider.js +48 -0
  152. package/lib/module/react/AdsProvider.js.map +1 -0
  153. package/lib/module/react/hooks.js +58 -0
  154. package/lib/module/react/hooks.js.map +1 -0
  155. package/lib/module/testing/clock.js +72 -0
  156. package/lib/module/testing/clock.js.map +1 -0
  157. package/lib/module/testing/conformance.js +93 -0
  158. package/lib/module/testing/conformance.js.map +1 -0
  159. package/lib/module/testing/index.js +366 -0
  160. package/lib/module/testing/index.js.map +1 -0
  161. package/lib/typescript/commonjs/config/resolveAdUnit.d.ts +43 -0
  162. package/lib/typescript/commonjs/config/resolveAdUnit.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/config/types.d.ts +280 -0
  164. package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/config/validate.d.ts +49 -0
  166. package/lib/typescript/commonjs/config/validate.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/core/adOriginatedReturn.d.ts +61 -0
  168. package/lib/typescript/commonjs/core/adOriginatedReturn.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/core/adsInstance.d.ts +33 -0
  170. package/lib/typescript/commonjs/core/adsInstance.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/core/consentFlow.d.ts +84 -0
  172. package/lib/typescript/commonjs/core/consentFlow.d.ts.map +1 -0
  173. package/lib/typescript/commonjs/core/enablement.d.ts +74 -0
  174. package/lib/typescript/commonjs/core/enablement.d.ts.map +1 -0
  175. package/lib/typescript/commonjs/core/fullScreenLock.d.ts +25 -0
  176. package/lib/typescript/commonjs/core/fullScreenLock.d.ts.map +1 -0
  177. package/lib/typescript/commonjs/core/gates.d.ts +76 -0
  178. package/lib/typescript/commonjs/core/gates.d.ts.map +1 -0
  179. package/lib/typescript/commonjs/core/initMachine.d.ts +66 -0
  180. package/lib/typescript/commonjs/core/initMachine.d.ts.map +1 -0
  181. package/lib/typescript/commonjs/core/instance/consent.d.ts +4 -0
  182. package/lib/typescript/commonjs/core/instance/consent.d.ts.map +1 -0
  183. package/lib/typescript/commonjs/core/instance/context.d.ts +118 -0
  184. package/lib/typescript/commonjs/core/instance/context.d.ts.map +1 -0
  185. package/lib/typescript/commonjs/core/instance/gate.d.ts +38 -0
  186. package/lib/typescript/commonjs/core/instance/gate.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/core/instance/init.d.ts +13 -0
  188. package/lib/typescript/commonjs/core/instance/init.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/core/instance/internals.d.ts +60 -0
  190. package/lib/typescript/commonjs/core/instance/internals.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/core/instance/load.d.ts +9 -0
  192. package/lib/typescript/commonjs/core/instance/load.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/core/instance/show.d.ts +7 -0
  194. package/lib/typescript/commonjs/core/instance/show.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/core/instance/types.d.ts +240 -0
  196. package/lib/typescript/commonjs/core/instance/types.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/core/placementMachine.d.ts +55 -0
  198. package/lib/typescript/commonjs/core/placementMachine.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/core/privacyGate.d.ts +40 -0
  200. package/lib/typescript/commonjs/core/privacyGate.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/core/requestThrottle.d.ts +99 -0
  202. package/lib/typescript/commonjs/core/requestThrottle.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/core/retryPolicy.d.ts +66 -0
  204. package/lib/typescript/commonjs/core/retryPolicy.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/core/rewardedSession.d.ts +37 -0
  206. package/lib/typescript/commonjs/core/rewardedSession.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/core/timers.d.ts +135 -0
  208. package/lib/typescript/commonjs/core/timers.d.ts.map +1 -0
  209. package/lib/typescript/commonjs/diagnostics/correlation.d.ts +18 -0
  210. package/lib/typescript/commonjs/diagnostics/correlation.d.ts.map +1 -0
  211. package/lib/typescript/commonjs/diagnostics/errors.d.ts +59 -0
  212. package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
  213. package/lib/typescript/commonjs/diagnostics/events.d.ts +126 -0
  214. package/lib/typescript/commonjs/diagnostics/events.d.ts.map +1 -0
  215. package/lib/typescript/commonjs/engine/admobBanner.d.ts +10 -0
  216. package/lib/typescript/commonjs/engine/admobBanner.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/engine/admobEngine.d.ts +71 -0
  218. package/lib/typescript/commonjs/engine/admobEngine.d.ts.map +1 -0
  219. package/lib/typescript/commonjs/engine/admobErrors.d.ts +9 -0
  220. package/lib/typescript/commonjs/engine/admobErrors.d.ts.map +1 -0
  221. package/lib/typescript/commonjs/engine/port.d.ts +171 -0
  222. package/lib/typescript/commonjs/engine/port.d.ts.map +1 -0
  223. package/lib/typescript/commonjs/engine/testAdUnits.d.ts +33 -0
  224. package/lib/typescript/commonjs/engine/testAdUnits.d.ts.map +1 -0
  225. package/lib/typescript/commonjs/index.d.ts +42 -0
  226. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  227. package/lib/typescript/commonjs/package.json +1 -0
  228. package/lib/typescript/commonjs/react/AdsBanner.d.ts +29 -0
  229. package/lib/typescript/commonjs/react/AdsBanner.d.ts.map +1 -0
  230. package/lib/typescript/commonjs/react/AdsProvider.d.ts +36 -0
  231. package/lib/typescript/commonjs/react/AdsProvider.d.ts.map +1 -0
  232. package/lib/typescript/commonjs/react/hooks.d.ts +27 -0
  233. package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
  234. package/lib/typescript/commonjs/testing/clock.d.ts +29 -0
  235. package/lib/typescript/commonjs/testing/clock.d.ts.map +1 -0
  236. package/lib/typescript/commonjs/testing/conformance.d.ts +26 -0
  237. package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
  238. package/lib/typescript/commonjs/testing/index.d.ts +133 -0
  239. package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
  240. package/lib/typescript/module/config/resolveAdUnit.d.ts +43 -0
  241. package/lib/typescript/module/config/resolveAdUnit.d.ts.map +1 -0
  242. package/lib/typescript/module/config/types.d.ts +280 -0
  243. package/lib/typescript/module/config/types.d.ts.map +1 -0
  244. package/lib/typescript/module/config/validate.d.ts +49 -0
  245. package/lib/typescript/module/config/validate.d.ts.map +1 -0
  246. package/lib/typescript/module/core/adOriginatedReturn.d.ts +61 -0
  247. package/lib/typescript/module/core/adOriginatedReturn.d.ts.map +1 -0
  248. package/lib/typescript/module/core/adsInstance.d.ts +33 -0
  249. package/lib/typescript/module/core/adsInstance.d.ts.map +1 -0
  250. package/lib/typescript/module/core/consentFlow.d.ts +84 -0
  251. package/lib/typescript/module/core/consentFlow.d.ts.map +1 -0
  252. package/lib/typescript/module/core/enablement.d.ts +74 -0
  253. package/lib/typescript/module/core/enablement.d.ts.map +1 -0
  254. package/lib/typescript/module/core/fullScreenLock.d.ts +25 -0
  255. package/lib/typescript/module/core/fullScreenLock.d.ts.map +1 -0
  256. package/lib/typescript/module/core/gates.d.ts +76 -0
  257. package/lib/typescript/module/core/gates.d.ts.map +1 -0
  258. package/lib/typescript/module/core/initMachine.d.ts +66 -0
  259. package/lib/typescript/module/core/initMachine.d.ts.map +1 -0
  260. package/lib/typescript/module/core/instance/consent.d.ts +4 -0
  261. package/lib/typescript/module/core/instance/consent.d.ts.map +1 -0
  262. package/lib/typescript/module/core/instance/context.d.ts +118 -0
  263. package/lib/typescript/module/core/instance/context.d.ts.map +1 -0
  264. package/lib/typescript/module/core/instance/gate.d.ts +38 -0
  265. package/lib/typescript/module/core/instance/gate.d.ts.map +1 -0
  266. package/lib/typescript/module/core/instance/init.d.ts +13 -0
  267. package/lib/typescript/module/core/instance/init.d.ts.map +1 -0
  268. package/lib/typescript/module/core/instance/internals.d.ts +60 -0
  269. package/lib/typescript/module/core/instance/internals.d.ts.map +1 -0
  270. package/lib/typescript/module/core/instance/load.d.ts +9 -0
  271. package/lib/typescript/module/core/instance/load.d.ts.map +1 -0
  272. package/lib/typescript/module/core/instance/show.d.ts +7 -0
  273. package/lib/typescript/module/core/instance/show.d.ts.map +1 -0
  274. package/lib/typescript/module/core/instance/types.d.ts +240 -0
  275. package/lib/typescript/module/core/instance/types.d.ts.map +1 -0
  276. package/lib/typescript/module/core/placementMachine.d.ts +55 -0
  277. package/lib/typescript/module/core/placementMachine.d.ts.map +1 -0
  278. package/lib/typescript/module/core/privacyGate.d.ts +40 -0
  279. package/lib/typescript/module/core/privacyGate.d.ts.map +1 -0
  280. package/lib/typescript/module/core/requestThrottle.d.ts +99 -0
  281. package/lib/typescript/module/core/requestThrottle.d.ts.map +1 -0
  282. package/lib/typescript/module/core/retryPolicy.d.ts +66 -0
  283. package/lib/typescript/module/core/retryPolicy.d.ts.map +1 -0
  284. package/lib/typescript/module/core/rewardedSession.d.ts +37 -0
  285. package/lib/typescript/module/core/rewardedSession.d.ts.map +1 -0
  286. package/lib/typescript/module/core/timers.d.ts +135 -0
  287. package/lib/typescript/module/core/timers.d.ts.map +1 -0
  288. package/lib/typescript/module/diagnostics/correlation.d.ts +18 -0
  289. package/lib/typescript/module/diagnostics/correlation.d.ts.map +1 -0
  290. package/lib/typescript/module/diagnostics/errors.d.ts +59 -0
  291. package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
  292. package/lib/typescript/module/diagnostics/events.d.ts +126 -0
  293. package/lib/typescript/module/diagnostics/events.d.ts.map +1 -0
  294. package/lib/typescript/module/engine/admobBanner.d.ts +10 -0
  295. package/lib/typescript/module/engine/admobBanner.d.ts.map +1 -0
  296. package/lib/typescript/module/engine/admobEngine.d.ts +71 -0
  297. package/lib/typescript/module/engine/admobEngine.d.ts.map +1 -0
  298. package/lib/typescript/module/engine/admobErrors.d.ts +9 -0
  299. package/lib/typescript/module/engine/admobErrors.d.ts.map +1 -0
  300. package/lib/typescript/module/engine/port.d.ts +171 -0
  301. package/lib/typescript/module/engine/port.d.ts.map +1 -0
  302. package/lib/typescript/module/engine/testAdUnits.d.ts +33 -0
  303. package/lib/typescript/module/engine/testAdUnits.d.ts.map +1 -0
  304. package/lib/typescript/module/index.d.ts +42 -0
  305. package/lib/typescript/module/index.d.ts.map +1 -0
  306. package/lib/typescript/module/package.json +1 -0
  307. package/lib/typescript/module/react/AdsBanner.d.ts +29 -0
  308. package/lib/typescript/module/react/AdsBanner.d.ts.map +1 -0
  309. package/lib/typescript/module/react/AdsProvider.d.ts +36 -0
  310. package/lib/typescript/module/react/AdsProvider.d.ts.map +1 -0
  311. package/lib/typescript/module/react/hooks.d.ts +27 -0
  312. package/lib/typescript/module/react/hooks.d.ts.map +1 -0
  313. package/lib/typescript/module/testing/clock.d.ts +29 -0
  314. package/lib/typescript/module/testing/clock.d.ts.map +1 -0
  315. package/lib/typescript/module/testing/conformance.d.ts +26 -0
  316. package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
  317. package/lib/typescript/module/testing/index.d.ts +133 -0
  318. package/lib/typescript/module/testing/index.d.ts.map +1 -0
  319. package/package.json +48 -12
  320. package/skills/sdk-rn-ads/SKILL.md +2 -1
  321. package/src/core/adsInstance.ts +72 -1829
  322. package/src/core/consentFlow.ts +1 -20
  323. package/src/core/instance/consent.ts +162 -0
  324. package/src/core/instance/context.ts +328 -0
  325. package/src/core/instance/gate.ts +147 -0
  326. package/src/core/instance/init.ts +262 -0
  327. package/src/core/instance/internals.ts +138 -0
  328. package/src/core/instance/load.ts +426 -0
  329. package/src/core/instance/show.ts +202 -0
  330. package/src/core/instance/types.ts +198 -0
  331. package/src/core/requestThrottle.ts +11 -17
  332. package/src/diagnostics/errors.ts +24 -5
  333. package/src/engine/admobBanner.tsx +55 -0
  334. package/src/engine/admobEngine.ts +21 -12
  335. package/src/engine/admobErrors.ts +44 -0
  336. package/src/engine/port.ts +46 -1
  337. package/src/engine/testAdUnits.ts +0 -5
  338. package/src/react/AdsBanner.tsx +81 -80
  339. package/src/testing/clock.ts +75 -0
  340. package/src/testing/index.ts +43 -68
@@ -16,14 +16,15 @@
16
16
  * a banner through the load/show handle model, which does not fit it.
17
17
  */
18
18
 
19
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
19
+ import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
20
20
  import { View, type LayoutChangeEvent, type ViewStyle } from 'react-native';
21
21
 
22
22
  import type { PlacementState } from '../config/types';
23
- import { AdsError, normalizeProviderError } from '../diagnostics/errors';
24
- import { admobProvider } from '../engine/admobEngine';
23
+ import { normalizeProviderError } from '../diagnostics/errors';
24
+ import type { AdEvent } from '../diagnostics/events';
25
+ import type { EngineFailureKind } from '../engine/port';
25
26
  import { useAds } from './AdsProvider';
26
- import type { ThrottledResult } from '../core/adsInstance';
27
+ import { getInternals, type ThrottledResult } from '../core/adsInstance';
27
28
  import { useAdsStatus } from './hooks';
28
29
 
29
30
  export interface AdsBannerProps {
@@ -34,20 +35,14 @@ export interface AdsBannerProps {
34
35
  readonly style?: ViewStyle;
35
36
  }
36
37
 
37
- interface ProviderBannerModule {
38
- BannerAd: React.ComponentType<Record<string, unknown>>;
39
- BannerAdSize: Record<string, string>;
40
- }
41
-
42
- // The engine's lazy loader, so the bridge is required in one place (ADS-12 still
43
- // tracks giving the banner its own seam on the engine port).
44
- function loadBannerModule(): ProviderBannerModule | null {
45
- const result = admobProvider.get();
46
- return result.ok ? (result.module as unknown as ProviderBannerModule) : null;
47
- }
48
-
49
38
  export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps) {
50
39
  const ads = useAds();
40
+ // The instance's banner wiring (ADS-13). An instance the app wrote by hand has
41
+ // none, and is treated like a missing one.
42
+ const internals = useMemo(() => (ads ? getInternals(ads) : null), [ads]);
43
+ // The throttle token for this mount: stable across renders and minted by React
44
+ // rather than by a counter, so a render that runs twice charges one slot.
45
+ const mountToken = useId();
51
46
  // The reported state lives in a ref rather than in component state: the host
52
47
  // itself renders the same tree for every state, so storing it would only
53
48
  // force re-renders the PERF-002 budget does not need to spend. The instance
@@ -69,23 +64,29 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
69
64
  decided: boolean;
70
65
  refusal: ThrottledResult | null;
71
66
  }>({ decided: false, refusal: null });
67
+ // Which attempt this mount is on. A refused mount asks again once the window
68
+ // passes (ADS-06), and each attempt needs its own token: the throttle replays
69
+ // the stored verdict for a token it has seen.
70
+ const throttleAttemptRef = useRef(0);
72
71
 
73
- const provider = useMemo(loadBannerModule, []);
72
+ // The engine's banner component (ADS-12): the host never names the provider.
73
+ const banner = useMemo(() => internals?.banner() ?? null, [internals]);
74
74
  // Initialization is asynchronous and a banner is almost always mounted before
75
75
  // it finishes. Without this the resolution below would be computed once, while
76
76
  // the instance was still `not_started`, be refused, and never be retried — the
77
77
  // banner would sit at `unavailable` forever on a perfectly healthy app.
78
78
  const status = useAdsStatus();
79
79
 
80
- // Keyed on `cycle` so a genuine width change mints a fresh correlation id and
81
- // starts a new, separately traceable load (FR-038, FR-052), and on `status` so
82
- // the banner recovers the moment the instance becomes able to request.
80
+ // Keyed on `cycle` so a genuine width change starts a new, separately traceable
81
+ // load (FR-038, FR-052), and on `status` so the banner recovers the moment the
82
+ // instance becomes able to request. Pure: the cycle's correlation id is minted
83
+ // in the effect that starts it, not here (ADS-20).
83
84
  const resolved = useMemo(
84
85
  () =>
85
- ads && status === 'ready'
86
- ? { cycle, value: ads.internals.resolveBanner(placementKey) }
86
+ internals && status === 'ready'
87
+ ? { cycle, value: internals.resolveBanner(placementKey) }
87
88
  : null,
88
- [ads, placementKey, cycle, status],
89
+ [internals, placementKey, cycle, status],
89
90
  );
90
91
  const resolution = resolved?.value ?? null;
91
92
 
@@ -95,10 +96,10 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
95
96
  return;
96
97
  }
97
98
  stateRef.current = next;
98
- ads?.internals.setPlacementState(placementKey, next);
99
+ internals?.setPlacementState(placementKey, next);
99
100
  onStateChange?.(next);
100
101
  },
101
- [ads, onStateChange, placementKey],
102
+ [internals, onStateChange, placementKey],
102
103
  );
103
104
 
104
105
  // FR-140. Decided **during render**, not in the effect below, because the
@@ -111,20 +112,23 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
111
112
  // out), while a later cycle in the *same* mount is a width re-adaptation —
112
113
  // rotation — which must not be refused or a rotated screen loses its banner
113
114
  // for up to a minute.
114
- if (ads && resolution?.ok && containerWidth > 0 && !throttleRef.current.decided) {
115
+ if (internals && resolution?.ok && containerWidth > 0 && !throttleRef.current.decided) {
115
116
  throttleRef.current = {
116
117
  decided: true,
117
- refusal: ads.internals.commitBannerRequest(placementKey, resolution.correlationId),
118
+ refusal: internals.commitBannerRequest(
119
+ placementKey,
120
+ `${mountToken}:${throttleAttemptRef.current}`,
121
+ ),
118
122
  };
119
123
  }
120
124
  const throttleRefusal = throttleRef.current.refusal;
121
125
 
122
126
  const usable = Boolean(
123
- ads && provider && resolution?.ok && containerWidth > 0 && !throttleRefusal,
127
+ internals && banner && resolution?.ok && containerWidth > 0 && !throttleRefusal,
124
128
  );
125
129
 
126
130
  useEffect(() => {
127
- if (!ads || !provider) {
131
+ if (!internals || !banner) {
128
132
  move('unavailable');
129
133
  return;
130
134
  }
@@ -168,31 +172,39 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
168
172
  // collapse the space for both, but only one is worth investigating.
169
173
  if (throttleRefusal) {
170
174
  move('throttled');
171
- ads.internals.emit({
175
+ internals.emit({
172
176
  type: 'request_throttled',
173
- timestamp: Date.now(),
177
+ timestamp: internals.now(),
174
178
  placementKey,
175
179
  format: 'banner',
176
180
  retryAfterMs: throttleRefusal.retryAfterMs,
177
- minRequestIntervalMs: ads.internals.throttleFloorFor(placementKey),
181
+ minRequestIntervalMs: internals.throttleFloorFor(placementKey),
182
+ });
183
+ // ADS-06: ask again in this same mount once the window has passed. Until
184
+ // 0.7.0 a refused banner stayed empty until it was remounted, so a banner
185
+ // pinned to a screen the user returned to within a minute never filled.
186
+ return internals.schedule(throttleRefusal.retryAfterMs, () => {
187
+ throttleRef.current = { decided: false, refusal: null };
188
+ throttleAttemptRef.current += 1;
189
+ setCycle(value => value + 1);
178
190
  });
179
- return;
180
191
  }
181
- correlationRef.current = resolution.correlationId;
192
+ const correlationId = internals.nextCorrelationId();
193
+ correlationRef.current = correlationId;
182
194
  loadedInCycleRef.current = false;
183
- startedAtRef.current = Date.now();
195
+ startedAtRef.current = internals.now();
184
196
  move('loading');
185
- ads.internals.emit({
197
+ internals.emit({
186
198
  type: 'load_started',
187
- timestamp: Date.now(),
199
+ timestamp: startedAtRef.current,
188
200
  placementKey,
189
201
  format: 'banner',
190
- correlationId: resolution.correlationId,
202
+ correlationId,
191
203
  });
192
204
  // Deliberately keyed on `cycle`, not on every render: FR-041 forbids a
193
205
  // re-render from producing a second uncontrolled request.
194
206
  // eslint-disable-next-line react-hooks/exhaustive-deps
195
- }, [ads, provider, status, resolution, containerWidth, cycle]);
207
+ }, [internals, banner, status, resolution, containerWidth, cycle]);
196
208
 
197
209
  const onLayout = useCallback((event: LayoutChangeEvent) => {
198
210
  const width = Math.round(event.nativeEvent.layout.width);
@@ -210,22 +222,23 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
210
222
  }, []);
211
223
 
212
224
  const emit = useCallback(
213
- (event: Parameters<NonNullable<typeof ads>['internals']['emit']>[0]) => {
214
- ads?.internals.emit(event);
225
+ (event: AdEvent) => {
226
+ internals?.emit(event);
215
227
  },
216
- [ads],
228
+ [internals],
217
229
  );
230
+ const clock = useCallback(() => internals?.now() ?? Date.now(), [internals]);
218
231
 
219
232
  const handleLoaded = useCallback(() => {
220
233
  // A second load in one correlation is the provider's auto-refresh: a new
221
234
  // ad, so a new cycle. Under the old correlation its `loaded` and
222
235
  // `impression` were deduplicated away and revenue went uncounted (ADS-05).
223
236
  // For a refresh, `durationMs` is the time since the previous load.
224
- if (loadedInCycleRef.current && ads) {
225
- correlationRef.current = ads.internals.nextCorrelationId();
237
+ if (loadedInCycleRef.current && internals) {
238
+ correlationRef.current = internals.nextCorrelationId();
226
239
  }
227
240
  loadedInCycleRef.current = true;
228
- const loadedAt = Date.now();
241
+ const loadedAt = clock();
229
242
  move('ready');
230
243
  emit({
231
244
  type: 'loaded',
@@ -236,32 +249,32 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
236
249
  durationMs: loadedAt - startedAtRef.current,
237
250
  });
238
251
  startedAtRef.current = loadedAt;
239
- }, [ads, emit, move, placementKey]);
252
+ }, [internals, clock, emit, move, placementKey]);
240
253
 
241
254
  const handleFailed = useCallback(
242
- (error: unknown) => {
243
- const normalized = normalizeProviderError(error, {
244
- operation: 'load',
245
- placementKey,
246
- format: 'banner',
247
- });
255
+ (error: unknown, kind?: EngineFailureKind) => {
256
+ const normalized = normalizeProviderError(
257
+ error,
258
+ { operation: 'load', placementKey, format: 'banner' },
259
+ kind,
260
+ );
248
261
  move('failed');
249
262
  emit({
250
263
  type: 'load_failed',
251
- timestamp: Date.now(),
264
+ timestamp: clock(),
252
265
  placementKey,
253
266
  format: 'banner',
254
267
  correlationId: correlationRef.current ?? undefined,
255
268
  error: normalized,
256
269
  });
257
270
  },
258
- [emit, move, placementKey],
271
+ [clock, emit, move, placementKey],
259
272
  );
260
273
 
261
274
  const handleImpression = useCallback(() => {
262
275
  emit({
263
276
  type: 'impression',
264
- timestamp: Date.now(),
277
+ timestamp: clock(),
265
278
  placementKey,
266
279
  format: 'banner',
267
280
  correlationId: correlationRef.current ?? undefined,
@@ -270,17 +283,17 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
270
283
  // reconciliation, so it is recorded rather than flattened (R5).
271
284
  source: 'provider',
272
285
  });
273
- }, [emit, placementKey]);
286
+ }, [clock, emit, placementKey]);
274
287
 
275
288
  const handleClicked = useCallback(() => {
276
289
  emit({
277
290
  type: 'click',
278
- timestamp: Date.now(),
291
+ timestamp: clock(),
279
292
  placementKey,
280
293
  format: 'banner',
281
294
  correlationId: correlationRef.current ?? undefined,
282
295
  });
283
- }, [emit, placementKey]);
296
+ }, [clock, emit, placementKey]);
284
297
 
285
298
  // FR-041: nothing survives unmount. No retained native view, no dangling
286
299
  // correlation, no state written into a disposed instance.
@@ -290,7 +303,7 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
290
303
  };
291
304
  }, []);
292
305
 
293
- if (!ads || !provider) {
306
+ if (!internals || !banner) {
294
307
  // FR-042, UX-003 — out of the tree entirely, blocking no touch.
295
308
  return null;
296
309
  }
@@ -318,34 +331,22 @@ export function AdsBanner({ placementKey, onStateChange, style }: AdsBannerProps
318
331
  }
319
332
  }
320
333
 
321
- const { BannerAd, BannerAdSize } = provider;
334
+ const BannerComponent = banner.Component;
322
335
  const adUnitId = resolution?.ok ? resolution.adUnitId : null;
323
- // The provider's polarity is the inverse of the consumer-facing option.
324
- const requestNonPersonalizedAdsOnly = resolution?.ok ? !resolution.personalizedAds : false;
325
336
 
326
337
  return (
327
338
  <View style={style} onLayout={onLayout} testID={`ads-banner-${placementKey}`}>
328
- {usable && adUnitId ? (
329
- <BannerAd
339
+ {usable && adUnitId && resolution?.ok ? (
340
+ <BannerComponent
330
341
  key={`${placementKey}-${cycle}`}
331
- unitId={adUnitId}
332
- size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
333
- requestOptions={{ requestNonPersonalizedAdsOnly }}
334
- onAdLoaded={handleLoaded}
335
- onAdFailedToLoad={handleFailed}
336
- onAdImpression={handleImpression}
337
- onAdClicked={handleClicked}
342
+ adUnitId={adUnitId}
343
+ personalizedAds={resolution.personalizedAds}
344
+ onLoaded={handleLoaded}
345
+ onFailed={handleFailed}
346
+ onImpression={handleImpression}
347
+ onClicked={handleClicked}
338
348
  />
339
349
  ) : null}
340
350
  </View>
341
351
  );
342
352
  }
343
-
344
- /** Exposed for tests that assert the failure taxonomy without a renderer. */
345
- export function bannerUnavailableError(placementKey: string): AdsError {
346
- return new AdsError('unsupported_platform', {
347
- operation: 'load',
348
- placementKey,
349
- format: 'banner',
350
- });
351
- }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * A clock the test drives (ADS-11).
3
+ *
4
+ * Every bounded wait in this package — retry backoff, the request throttle, a
5
+ * consent form that never answers — is measured against a clock. Injecting this
6
+ * one is what lets a suite assert the behaviour at the boundary instead of
7
+ * sleeping and hoping.
8
+ */
9
+ import type { Scheduler } from '../core/timers';
10
+
11
+ /**
12
+ * A clock a test can move by hand.
13
+ *
14
+ * Retry backoff, app-open expiry, the undecided-state warning, and the
15
+ * ad-originated-return windows are all time-dependent, and all four must be
16
+ * assertable exactly rather than approximately. Advancing a clock makes "two
17
+ * retries, 2s then 4s" a precise assertion; sleeping would make it a flaky one.
18
+ *
19
+ * Callbacks fire in due order, and a callback scheduled *during* an advance is
20
+ * honored within the same advance if its deadline has also passed — matching how
21
+ * real timers behave when work chains.
22
+ */
23
+ export interface TestClock {
24
+ now(): number;
25
+ advance(ms: number): void;
26
+ readonly scheduler: Scheduler;
27
+ pending(): number;
28
+ }
29
+
30
+ export function createTestClock(startMs = 1_000_000): TestClock {
31
+ let current = startMs;
32
+ let sequence = 0;
33
+ const timers = new Map<number, { at: number; callback: () => void }>();
34
+
35
+ const scheduler: Scheduler = {
36
+ setTimeout(callback, ms) {
37
+ sequence += 1;
38
+ timers.set(sequence, { at: current + ms, callback });
39
+ return sequence;
40
+ },
41
+ clearTimeout(handle) {
42
+ timers.delete(handle as number);
43
+ },
44
+ };
45
+
46
+ return {
47
+ now: () => current,
48
+ advance(ms) {
49
+ const target = current + ms;
50
+ // Loop rather than iterate once: a fired callback may schedule another
51
+ // timer that is also due before `target`, which is exactly what a retry
52
+ // chain does.
53
+ for (;;) {
54
+ let nextId: number | null = null;
55
+ let nextAt = Number.POSITIVE_INFINITY;
56
+ for (const [id, timer] of timers) {
57
+ if (timer.at <= target && timer.at < nextAt) {
58
+ nextAt = timer.at;
59
+ nextId = id;
60
+ }
61
+ }
62
+ if (nextId === null) {
63
+ break;
64
+ }
65
+ const timer = timers.get(nextId)!;
66
+ timers.delete(nextId);
67
+ current = timer.at;
68
+ timer.callback();
69
+ }
70
+ current = target;
71
+ },
72
+ scheduler,
73
+ pending: () => timers.size,
74
+ };
75
+ }
@@ -16,85 +16,26 @@
16
16
  * so test doubles cannot reach a production bundle.
17
17
  */
18
18
 
19
- import type { FullScreenFormat, Reward, Unsubscribe } from '../config/types';
20
- import type { Scheduler } from '../core/timers';
19
+ import React from 'react';
20
+ import { View } from 'react-native';
21
+
22
+ import type { AdFormat, FullScreenFormat, Reward, Unsubscribe } from '../config/types';
23
+ export { createTestClock, type TestClock } from './clock';
24
+ import { createTestClock, type TestClock } from './clock';
25
+
26
+ import { testAdUnitFor } from '../engine/testAdUnits';
21
27
  import type {
22
28
  AdsEngine,
23
29
  ConsentPort,
24
30
  EngineAdEvent,
25
31
  EngineAdHandle,
32
+ EngineBannerProps,
26
33
  EngineConsentInfo,
27
34
  EngineConsentOptions,
28
35
  EnginePrivacy,
29
36
  EngineRequestOptions,
30
37
  } from '../engine/port';
31
38
 
32
- /**
33
- * A clock a test can move by hand.
34
- *
35
- * Retry backoff, app-open expiry, the undecided-state warning, and the
36
- * ad-originated-return windows are all time-dependent, and all four must be
37
- * assertable exactly rather than approximately. Advancing a clock makes "two
38
- * retries, 2s then 4s" a precise assertion; sleeping would make it a flaky one.
39
- *
40
- * Callbacks fire in due order, and a callback scheduled *during* an advance is
41
- * honored within the same advance if its deadline has also passed — matching how
42
- * real timers behave when work chains.
43
- */
44
- export interface TestClock {
45
- now(): number;
46
- advance(ms: number): void;
47
- readonly scheduler: Scheduler;
48
- pending(): number;
49
- }
50
-
51
- export function createTestClock(startMs = 1_000_000): TestClock {
52
- let current = startMs;
53
- let sequence = 0;
54
- const timers = new Map<number, { at: number; callback: () => void }>();
55
-
56
- const scheduler: Scheduler = {
57
- setTimeout(callback, ms) {
58
- sequence += 1;
59
- timers.set(sequence, { at: current + ms, callback });
60
- return sequence;
61
- },
62
- clearTimeout(handle) {
63
- timers.delete(handle as number);
64
- },
65
- };
66
-
67
- return {
68
- now: () => current,
69
- advance(ms) {
70
- const target = current + ms;
71
- // Loop rather than iterate once: a fired callback may schedule another
72
- // timer that is also due before `target`, which is exactly what a retry
73
- // chain does.
74
- for (;;) {
75
- let nextId: number | null = null;
76
- let nextAt = Number.POSITIVE_INFINITY;
77
- for (const [id, timer] of timers) {
78
- if (timer.at <= target && timer.at < nextAt) {
79
- nextAt = timer.at;
80
- nextId = id;
81
- }
82
- }
83
- if (nextId === null) {
84
- break;
85
- }
86
- const timer = timers.get(nextId)!;
87
- timers.delete(nextId);
88
- current = timer.at;
89
- timer.callback();
90
- }
91
- current = target;
92
- },
93
- scheduler,
94
- pending: () => timers.size,
95
- };
96
- }
97
-
98
39
  export type FakeConsentCall =
99
40
  | { readonly kind: 'requestInfoUpdate'; readonly options: EngineConsentOptions }
100
41
  | { readonly kind: 'showFormIfRequired' }
@@ -212,6 +153,22 @@ function nextMicrotask(task: () => void): void {
212
153
  Promise.resolve().then(task);
213
154
  }
214
155
 
156
+ /** The testID the fake banner renders under, for a test to find it by. */
157
+ export const FAKE_BANNER_TEST_ID = 'ads-fake-banner';
158
+
159
+ /**
160
+ * The fake engine's banner component.
161
+ *
162
+ * It renders a host view carrying the props the package handed it, so a test
163
+ * can read them and call the callbacks: `getByTestId(FAKE_BANNER_TEST_ID)`.
164
+ * It used to render `null`, which left the props reachable only on the
165
+ * component instance — something `@testing-library/react-native` cannot see,
166
+ * since a host element is all a consumer's own tests can query.
167
+ */
168
+ function FakeBanner(props: EngineBannerProps): React.ReactElement {
169
+ return React.createElement(View, { ...props, testID: FAKE_BANNER_TEST_ID });
170
+ }
171
+
215
172
  export function createFakeAdsEngine(options: FakeEngineOptions = {}): FakeAdsEngine {
216
173
  const calls: FakeEngineCall[] = [];
217
174
  const consentCalls: FakeConsentCall[] = [];
@@ -353,6 +310,14 @@ export function createFakeAdsEngine(options: FakeEngineOptions = {}): FakeAdsEng
353
310
  return options.available !== false;
354
311
  },
355
312
 
313
+ // Renders nothing. A test finds it in the tree by its `adUnitId` prop and
314
+ // calls `onLoaded`, `onFailed`, `onImpression` or `onClicked` itself, which
315
+ // is how a banner is driven without mocking a native module (ADS-12).
316
+ banner: {
317
+ isAvailable: () => options.available !== false,
318
+ Component: FakeBanner,
319
+ },
320
+
356
321
  async initialize(privacy) {
357
322
  record({ kind: 'initialize', privacy });
358
323
  if (options.failInitialize !== undefined) {
@@ -473,3 +438,13 @@ export function createFakeAdsEngine(options: FakeEngineOptions = {}): FakeAdsEng
473
438
 
474
439
  export { adsEngineChecks, runAdsEngineConformance } from './conformance';
475
440
  export type { AdsEngineHarness, AdsEngineSubject } from './conformance';
441
+
442
+ /** Google's official test ad unit for each format, as the package substitutes them (FR-011). */
443
+ export function allTestAdUnits(): Readonly<Record<AdFormat, string>> {
444
+ return {
445
+ banner: testAdUnitFor('banner'),
446
+ interstitial: testAdUnitFor('interstitial'),
447
+ rewarded: testAdUnitFor('rewarded'),
448
+ app_open: testAdUnitFor('app_open'),
449
+ };
450
+ }