@chipmobilesdk/rn-payment 0.5.0 → 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.
Files changed (317) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/README.md +47 -16
  3. package/lib/commonjs/adapter/createStoreProvider.js +110 -0
  4. package/lib/commonjs/adapter/createStoreProvider.js.map +1 -0
  5. package/lib/commonjs/adapter/iap-adapter.js +393 -0
  6. package/lib/commonjs/adapter/iap-adapter.js.map +1 -0
  7. package/lib/commonjs/adapter/iapShapes.js +169 -0
  8. package/lib/commonjs/adapter/iapShapes.js.map +1 -0
  9. package/lib/commonjs/adapter/port.js +6 -0
  10. package/lib/commonjs/adapter/port.js.map +1 -0
  11. package/lib/commonjs/config/types.js +2 -0
  12. package/lib/commonjs/config/types.js.map +1 -0
  13. package/lib/commonjs/config/validate.js +181 -0
  14. package/lib/commonjs/config/validate.js.map +1 -0
  15. package/lib/commonjs/core/mutex.js +31 -0
  16. package/lib/commonjs/core/mutex.js.map +1 -0
  17. package/lib/commonjs/core/retry.js +37 -0
  18. package/lib/commonjs/core/retry.js.map +1 -0
  19. package/lib/commonjs/core/timers.js +207 -0
  20. package/lib/commonjs/core/timers.js.map +1 -0
  21. package/lib/commonjs/diagnostics/errors.js +83 -0
  22. package/lib/commonjs/diagnostics/errors.js.map +1 -0
  23. package/lib/commonjs/diagnostics/events.js +126 -0
  24. package/lib/commonjs/diagnostics/events.js.map +1 -0
  25. package/lib/commonjs/diagnostics/messageKeys.js +70 -0
  26. package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
  27. package/lib/commonjs/engine/connection.js +189 -0
  28. package/lib/commonjs/engine/connection.js.map +1 -0
  29. package/lib/commonjs/engine/engine.js +279 -0
  30. package/lib/commonjs/engine/engine.js.map +1 -0
  31. package/lib/commonjs/engine/finalize.js +325 -0
  32. package/lib/commonjs/engine/finalize.js.map +1 -0
  33. package/lib/commonjs/engine/foreground.js +26 -0
  34. package/lib/commonjs/engine/foreground.js.map +1 -0
  35. package/lib/commonjs/engine/internals.js +31 -0
  36. package/lib/commonjs/engine/internals.js.map +1 -0
  37. package/lib/commonjs/engine/pending.js +102 -0
  38. package/lib/commonjs/engine/pending.js.map +1 -0
  39. package/lib/commonjs/engine/products.js +198 -0
  40. package/lib/commonjs/engine/products.js.map +1 -0
  41. package/lib/commonjs/engine/purchase.js +395 -0
  42. package/lib/commonjs/engine/purchase.js.map +1 -0
  43. package/lib/commonjs/engine/purchaseFailure.js +77 -0
  44. package/lib/commonjs/engine/purchaseFailure.js.map +1 -0
  45. package/lib/commonjs/engine/receiptValidation.js +90 -0
  46. package/lib/commonjs/engine/receiptValidation.js.map +1 -0
  47. package/lib/commonjs/engine/state.js +201 -0
  48. package/lib/commonjs/engine/state.js.map +1 -0
  49. package/lib/commonjs/engine/subscriptions.js +122 -0
  50. package/lib/commonjs/engine/subscriptions.js.map +1 -0
  51. package/lib/commonjs/engine/sync.js +163 -0
  52. package/lib/commonjs/engine/sync.js.map +1 -0
  53. package/lib/commonjs/entitlements/aggregate.js +212 -0
  54. package/lib/commonjs/entitlements/aggregate.js.map +1 -0
  55. package/lib/commonjs/entitlements/mapping.js +41 -0
  56. package/lib/commonjs/entitlements/mapping.js.map +1 -0
  57. package/lib/commonjs/entitlements/policy.js +110 -0
  58. package/lib/commonjs/entitlements/policy.js.map +1 -0
  59. package/lib/commonjs/index.js +266 -0
  60. package/lib/commonjs/index.js.map +1 -0
  61. package/lib/commonjs/package.json +1 -0
  62. package/lib/commonjs/persistence/mmkv-store.js +149 -0
  63. package/lib/commonjs/persistence/mmkv-store.js.map +1 -0
  64. package/lib/commonjs/persistence/snapshot.js +229 -0
  65. package/lib/commonjs/persistence/snapshot.js.map +1 -0
  66. package/lib/commonjs/react/PaymentProvider.js +96 -0
  67. package/lib/commonjs/react/PaymentProvider.js.map +1 -0
  68. package/lib/commonjs/react/hooks.js +202 -0
  69. package/lib/commonjs/react/hooks.js.map +1 -0
  70. package/lib/commonjs/testing/conformance.js +136 -0
  71. package/lib/commonjs/testing/conformance.js.map +1 -0
  72. package/lib/commonjs/testing/fakeStore.js +281 -0
  73. package/lib/commonjs/testing/fakeStore.js.map +1 -0
  74. package/lib/commonjs/testing/index.js +45 -0
  75. package/lib/commonjs/testing/index.js.map +1 -0
  76. package/lib/module/adapter/createStoreProvider.js +106 -0
  77. package/lib/module/adapter/createStoreProvider.js.map +1 -0
  78. package/lib/module/adapter/iap-adapter.js +383 -0
  79. package/lib/module/adapter/iap-adapter.js.map +1 -0
  80. package/lib/module/adapter/iapShapes.js +160 -0
  81. package/lib/module/adapter/iapShapes.js.map +1 -0
  82. package/lib/module/adapter/port.js +4 -0
  83. package/lib/module/adapter/port.js.map +1 -0
  84. package/lib/module/config/types.js +2 -0
  85. package/lib/module/config/types.js.map +1 -0
  86. package/lib/module/config/validate.js +175 -0
  87. package/lib/module/config/validate.js.map +1 -0
  88. package/lib/module/core/mutex.js +22 -0
  89. package/lib/module/core/mutex.js.map +1 -0
  90. package/lib/module/core/retry.js +33 -0
  91. package/lib/module/core/retry.js.map +1 -0
  92. package/lib/module/core/timers.js +198 -0
  93. package/lib/module/core/timers.js.map +1 -0
  94. package/lib/module/diagnostics/errors.js +76 -0
  95. package/lib/module/diagnostics/errors.js.map +1 -0
  96. package/lib/module/diagnostics/events.js +117 -0
  97. package/lib/module/diagnostics/events.js.map +1 -0
  98. package/lib/module/diagnostics/messageKeys.js +64 -0
  99. package/lib/module/diagnostics/messageKeys.js.map +1 -0
  100. package/lib/module/engine/connection.js +185 -0
  101. package/lib/module/engine/connection.js.map +1 -0
  102. package/lib/module/engine/engine.js +274 -0
  103. package/lib/module/engine/engine.js.map +1 -0
  104. package/lib/module/engine/finalize.js +322 -0
  105. package/lib/module/engine/finalize.js.map +1 -0
  106. package/lib/module/engine/foreground.js +21 -0
  107. package/lib/module/engine/foreground.js.map +1 -0
  108. package/lib/module/engine/internals.js +26 -0
  109. package/lib/module/engine/internals.js.map +1 -0
  110. package/lib/module/engine/pending.js +95 -0
  111. package/lib/module/engine/pending.js.map +1 -0
  112. package/lib/module/engine/products.js +195 -0
  113. package/lib/module/engine/products.js.map +1 -0
  114. package/lib/module/engine/purchase.js +390 -0
  115. package/lib/module/engine/purchase.js.map +1 -0
  116. package/lib/module/engine/purchaseFailure.js +72 -0
  117. package/lib/module/engine/purchaseFailure.js.map +1 -0
  118. package/lib/module/engine/receiptValidation.js +87 -0
  119. package/lib/module/engine/receiptValidation.js.map +1 -0
  120. package/lib/module/engine/state.js +196 -0
  121. package/lib/module/engine/state.js.map +1 -0
  122. package/lib/module/engine/subscriptions.js +119 -0
  123. package/lib/module/engine/subscriptions.js.map +1 -0
  124. package/lib/module/engine/sync.js +158 -0
  125. package/lib/module/engine/sync.js.map +1 -0
  126. package/lib/module/entitlements/aggregate.js +204 -0
  127. package/lib/module/entitlements/aggregate.js.map +1 -0
  128. package/lib/module/entitlements/mapping.js +35 -0
  129. package/lib/module/entitlements/mapping.js.map +1 -0
  130. package/lib/module/entitlements/policy.js +104 -0
  131. package/lib/module/entitlements/policy.js.map +1 -0
  132. package/lib/module/index.js +59 -0
  133. package/lib/module/index.js.map +1 -0
  134. package/lib/module/package.json +1 -0
  135. package/lib/module/persistence/mmkv-store.js +144 -0
  136. package/lib/module/persistence/mmkv-store.js.map +1 -0
  137. package/lib/module/persistence/snapshot.js +221 -0
  138. package/lib/module/persistence/snapshot.js.map +1 -0
  139. package/lib/module/react/PaymentProvider.js +90 -0
  140. package/lib/module/react/PaymentProvider.js.map +1 -0
  141. package/lib/module/react/hooks.js +192 -0
  142. package/lib/module/react/hooks.js.map +1 -0
  143. package/lib/module/testing/conformance.js +130 -0
  144. package/lib/module/testing/conformance.js.map +1 -0
  145. package/lib/module/testing/fakeStore.js +276 -0
  146. package/lib/module/testing/fakeStore.js.map +1 -0
  147. package/lib/module/testing/index.js +13 -0
  148. package/lib/module/testing/index.js.map +1 -0
  149. package/lib/typescript/commonjs/adapter/createStoreProvider.d.ts +45 -0
  150. package/lib/typescript/commonjs/adapter/createStoreProvider.d.ts.map +1 -0
  151. package/lib/typescript/commonjs/adapter/iap-adapter.d.ts +80 -0
  152. package/lib/typescript/commonjs/adapter/iap-adapter.d.ts.map +1 -0
  153. package/lib/typescript/commonjs/adapter/iapShapes.d.ts +94 -0
  154. package/lib/typescript/commonjs/adapter/iapShapes.d.ts.map +1 -0
  155. package/lib/typescript/commonjs/adapter/port.d.ts +184 -0
  156. package/lib/typescript/commonjs/adapter/port.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/config/types.d.ts +326 -0
  158. package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/config/validate.d.ts +63 -0
  160. package/lib/typescript/commonjs/config/validate.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/core/mutex.d.ts +17 -0
  162. package/lib/typescript/commonjs/core/mutex.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/core/retry.d.ts +19 -0
  164. package/lib/typescript/commonjs/core/retry.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/core/timers.d.ts +142 -0
  166. package/lib/typescript/commonjs/core/timers.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/diagnostics/errors.d.ts +55 -0
  168. package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/diagnostics/events.d.ts +158 -0
  170. package/lib/typescript/commonjs/diagnostics/events.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +54 -0
  172. package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
  173. package/lib/typescript/commonjs/engine/connection.d.ts +30 -0
  174. package/lib/typescript/commonjs/engine/connection.d.ts.map +1 -0
  175. package/lib/typescript/commonjs/engine/engine.d.ts +93 -0
  176. package/lib/typescript/commonjs/engine/engine.d.ts.map +1 -0
  177. package/lib/typescript/commonjs/engine/finalize.d.ts +53 -0
  178. package/lib/typescript/commonjs/engine/finalize.d.ts.map +1 -0
  179. package/lib/typescript/commonjs/engine/foreground.d.ts +15 -0
  180. package/lib/typescript/commonjs/engine/foreground.d.ts.map +1 -0
  181. package/lib/typescript/commonjs/engine/internals.d.ts +28 -0
  182. package/lib/typescript/commonjs/engine/internals.d.ts.map +1 -0
  183. package/lib/typescript/commonjs/engine/pending.d.ts +51 -0
  184. package/lib/typescript/commonjs/engine/pending.d.ts.map +1 -0
  185. package/lib/typescript/commonjs/engine/products.d.ts +82 -0
  186. package/lib/typescript/commonjs/engine/products.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/engine/purchase.d.ts +61 -0
  188. package/lib/typescript/commonjs/engine/purchase.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/engine/purchaseFailure.d.ts +15 -0
  190. package/lib/typescript/commonjs/engine/purchaseFailure.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/engine/receiptValidation.d.ts +42 -0
  192. package/lib/typescript/commonjs/engine/receiptValidation.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/engine/state.d.ts +46 -0
  194. package/lib/typescript/commonjs/engine/state.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/engine/subscriptions.d.ts +61 -0
  196. package/lib/typescript/commonjs/engine/subscriptions.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/engine/sync.d.ts +36 -0
  198. package/lib/typescript/commonjs/engine/sync.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/entitlements/aggregate.d.ts +97 -0
  200. package/lib/typescript/commonjs/entitlements/aggregate.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/entitlements/mapping.d.ts +27 -0
  202. package/lib/typescript/commonjs/entitlements/mapping.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/entitlements/policy.d.ts +75 -0
  204. package/lib/typescript/commonjs/entitlements/policy.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/index.d.ts +44 -0
  206. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/package.json +1 -0
  208. package/lib/typescript/commonjs/persistence/mmkv-store.d.ts +45 -0
  209. package/lib/typescript/commonjs/persistence/mmkv-store.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/persistence/snapshot.d.ts +106 -0
  211. package/lib/typescript/commonjs/persistence/snapshot.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/react/PaymentProvider.d.ts +57 -0
  213. package/lib/typescript/commonjs/react/PaymentProvider.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/react/hooks.d.ts +80 -0
  215. package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/testing/conformance.d.ts +41 -0
  217. package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/testing/fakeStore.d.ts +69 -0
  219. package/lib/typescript/commonjs/testing/fakeStore.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/testing/index.d.ts +12 -0
  221. package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
  222. package/lib/typescript/module/adapter/createStoreProvider.d.ts +45 -0
  223. package/lib/typescript/module/adapter/createStoreProvider.d.ts.map +1 -0
  224. package/lib/typescript/module/adapter/iap-adapter.d.ts +80 -0
  225. package/lib/typescript/module/adapter/iap-adapter.d.ts.map +1 -0
  226. package/lib/typescript/module/adapter/iapShapes.d.ts +94 -0
  227. package/lib/typescript/module/adapter/iapShapes.d.ts.map +1 -0
  228. package/lib/typescript/module/adapter/port.d.ts +184 -0
  229. package/lib/typescript/module/adapter/port.d.ts.map +1 -0
  230. package/lib/typescript/module/config/types.d.ts +326 -0
  231. package/lib/typescript/module/config/types.d.ts.map +1 -0
  232. package/lib/typescript/module/config/validate.d.ts +63 -0
  233. package/lib/typescript/module/config/validate.d.ts.map +1 -0
  234. package/lib/typescript/module/core/mutex.d.ts +17 -0
  235. package/lib/typescript/module/core/mutex.d.ts.map +1 -0
  236. package/lib/typescript/module/core/retry.d.ts +19 -0
  237. package/lib/typescript/module/core/retry.d.ts.map +1 -0
  238. package/lib/typescript/module/core/timers.d.ts +142 -0
  239. package/lib/typescript/module/core/timers.d.ts.map +1 -0
  240. package/lib/typescript/module/diagnostics/errors.d.ts +55 -0
  241. package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
  242. package/lib/typescript/module/diagnostics/events.d.ts +158 -0
  243. package/lib/typescript/module/diagnostics/events.d.ts.map +1 -0
  244. package/lib/typescript/module/diagnostics/messageKeys.d.ts +54 -0
  245. package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
  246. package/lib/typescript/module/engine/connection.d.ts +30 -0
  247. package/lib/typescript/module/engine/connection.d.ts.map +1 -0
  248. package/lib/typescript/module/engine/engine.d.ts +93 -0
  249. package/lib/typescript/module/engine/engine.d.ts.map +1 -0
  250. package/lib/typescript/module/engine/finalize.d.ts +53 -0
  251. package/lib/typescript/module/engine/finalize.d.ts.map +1 -0
  252. package/lib/typescript/module/engine/foreground.d.ts +15 -0
  253. package/lib/typescript/module/engine/foreground.d.ts.map +1 -0
  254. package/lib/typescript/module/engine/internals.d.ts +28 -0
  255. package/lib/typescript/module/engine/internals.d.ts.map +1 -0
  256. package/lib/typescript/module/engine/pending.d.ts +51 -0
  257. package/lib/typescript/module/engine/pending.d.ts.map +1 -0
  258. package/lib/typescript/module/engine/products.d.ts +82 -0
  259. package/lib/typescript/module/engine/products.d.ts.map +1 -0
  260. package/lib/typescript/module/engine/purchase.d.ts +61 -0
  261. package/lib/typescript/module/engine/purchase.d.ts.map +1 -0
  262. package/lib/typescript/module/engine/purchaseFailure.d.ts +15 -0
  263. package/lib/typescript/module/engine/purchaseFailure.d.ts.map +1 -0
  264. package/lib/typescript/module/engine/receiptValidation.d.ts +42 -0
  265. package/lib/typescript/module/engine/receiptValidation.d.ts.map +1 -0
  266. package/lib/typescript/module/engine/state.d.ts +46 -0
  267. package/lib/typescript/module/engine/state.d.ts.map +1 -0
  268. package/lib/typescript/module/engine/subscriptions.d.ts +61 -0
  269. package/lib/typescript/module/engine/subscriptions.d.ts.map +1 -0
  270. package/lib/typescript/module/engine/sync.d.ts +36 -0
  271. package/lib/typescript/module/engine/sync.d.ts.map +1 -0
  272. package/lib/typescript/module/entitlements/aggregate.d.ts +97 -0
  273. package/lib/typescript/module/entitlements/aggregate.d.ts.map +1 -0
  274. package/lib/typescript/module/entitlements/mapping.d.ts +27 -0
  275. package/lib/typescript/module/entitlements/mapping.d.ts.map +1 -0
  276. package/lib/typescript/module/entitlements/policy.d.ts +75 -0
  277. package/lib/typescript/module/entitlements/policy.d.ts.map +1 -0
  278. package/lib/typescript/module/index.d.ts +44 -0
  279. package/lib/typescript/module/index.d.ts.map +1 -0
  280. package/lib/typescript/module/package.json +1 -0
  281. package/lib/typescript/module/persistence/mmkv-store.d.ts +45 -0
  282. package/lib/typescript/module/persistence/mmkv-store.d.ts.map +1 -0
  283. package/lib/typescript/module/persistence/snapshot.d.ts +106 -0
  284. package/lib/typescript/module/persistence/snapshot.d.ts.map +1 -0
  285. package/lib/typescript/module/react/PaymentProvider.d.ts +57 -0
  286. package/lib/typescript/module/react/PaymentProvider.d.ts.map +1 -0
  287. package/lib/typescript/module/react/hooks.d.ts +80 -0
  288. package/lib/typescript/module/react/hooks.d.ts.map +1 -0
  289. package/lib/typescript/module/testing/conformance.d.ts +41 -0
  290. package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
  291. package/lib/typescript/module/testing/fakeStore.d.ts +69 -0
  292. package/lib/typescript/module/testing/fakeStore.d.ts.map +1 -0
  293. package/lib/typescript/module/testing/index.d.ts +12 -0
  294. package/lib/typescript/module/testing/index.d.ts.map +1 -0
  295. package/package.json +49 -13
  296. package/skills/sdk-rn-payment/SKILL.md +4 -4
  297. package/src/adapter/iap-adapter.ts +12 -216
  298. package/src/adapter/iapShapes.ts +232 -0
  299. package/src/config/types.ts +8 -0
  300. package/src/config/validate.ts +19 -4
  301. package/src/core/retry.ts +1 -58
  302. package/src/diagnostics/events.ts +1 -1
  303. package/src/engine/connection.ts +194 -0
  304. package/src/engine/engine.ts +140 -700
  305. package/src/engine/internals.ts +40 -0
  306. package/src/engine/products.ts +39 -17
  307. package/src/engine/purchase.ts +22 -130
  308. package/src/engine/purchaseFailure.ts +48 -0
  309. package/src/engine/receiptValidation.ts +101 -0
  310. package/src/engine/state.ts +253 -0
  311. package/src/engine/sync.ts +161 -0
  312. package/src/entitlements/aggregate.ts +3 -5
  313. package/src/entitlements/mapping.ts +0 -22
  314. package/src/persistence/mmkv-store.ts +10 -3
  315. package/src/persistence/snapshot.ts +102 -27
  316. package/src/react/PaymentProvider.tsx +73 -24
  317. package/src/react/hooks.ts +13 -3
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Normalized public errors.
5
+ *
6
+ * Error codes are **public API**: renaming one is a breaking change (FR-078,
7
+ * LIB-008). They are the vocabulary an app branches on, so they must outlive any
8
+ * internal refactor and must never leak a store's own code.
9
+ */
10
+
11
+ import { REDACTED, SdkError, createRedactor } from '@chipmobilesdk/rn-core';
12
+ const identifiers = createRedactor();
13
+ export const PAYMENT_ERROR_CODES = ['PAYMENT_NOT_CONFIGURED', 'PAYMENT_INVALID_CATALOG', 'PAYMENT_NOT_READY', 'PAYMENT_DISABLED', 'PAYMENT_UNAVAILABLE', 'PAYMENT_UNSUPPORTED_PLATFORM', 'PAYMENT_ENVIRONMENT_BLOCKED', 'PAYMENT_PRODUCTION_CONFIG_IN_NON_PRODUCTION_BUILD', 'PAYMENT_PURCHASE_IN_PROGRESS', 'PAYMENT_USER_CANCELLED', 'PAYMENT_PENDING', 'PAYMENT_ALREADY_OWNED', 'PAYMENT_INELIGIBLE', 'PAYMENT_UNKNOWN_PRODUCT', 'PAYMENT_PRODUCT_UNAVAILABLE_IN_REGION', 'PAYMENT_TIMEOUT', 'PAYMENT_NETWORK_ERROR', 'PAYMENT_STORE_ERROR', 'PAYMENT_FINALIZE_FAILED', 'PAYMENT_VALIDATION_REJECTED', 'PAYMENT_VALIDATION_UNAVAILABLE', 'PAYMENT_STORAGE_UNAVAILABLE', /** `consume` on a transaction that is not a consumable, added in 0.3.2. */
14
+ 'PAYMENT_NOT_CONSUMABLE',
15
+ /**
16
+ * A timeout, backoff or interval outside its bounds, added in 0.5.0. These
17
+ * used to be reported as `PAYMENT_INVALID_CATALOG`, which is about products.
18
+ */
19
+ 'PAYMENT_INVALID_CONFIG'];
20
+
21
+ /** Which operation produced an error. Part of the public error shape (FR-078). */
22
+
23
+ /** The package's error; an `SdkError` (`@chipmobilesdk/rn-core`) with `pkg: 'rn-payment'`. */
24
+ export class PaymentError extends SdkError {
25
+ /** Redacted where appropriate — never a raw receipt, token, or store object (FR-074). */
26
+
27
+ constructor(init) {
28
+ super('rn-payment', init.code, {
29
+ message: init.message,
30
+ retryable: init.retryable ?? false,
31
+ redactedCause: init.cause
32
+ });
33
+ this.name = 'PaymentError';
34
+ this.operation = init.operation;
35
+ this.cause = init.cause;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * A configuration problem the app can act on.
41
+ *
42
+ * Separate from `PaymentError` because configuration faults are developer-facing
43
+ * and must never be shown to an end user — the message-key map keeps that
44
+ * separation explicit (FR-085).
45
+ */
46
+ export class PaymentConfigError extends PaymentError {
47
+ /** The offending catalog entries or entitlement keys, named (FR-011). */
48
+
49
+ constructor(init) {
50
+ super({
51
+ ...init,
52
+ retryable: false
53
+ });
54
+ this.name = 'PaymentConfigError';
55
+ this.offenders = init.offenders ?? [];
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Strips anything that must never reach a log or event.
61
+ *
62
+ * Applied at the boundary rather than trusted to call sites: a single forgotten
63
+ * interpolation is how receipts end up in logs (NFR-006).
64
+ *
65
+ * Identifier-only: what survives is what code defined, never what data carried.
66
+ * A `PaymentError` keeps its code and an `Error` its class name; every message
67
+ * and every string is dropped, because a store or consumer message can embed a
68
+ * purchase token or an account id and nothing here can tell which.
69
+ */
70
+ export function redact(value) {
71
+ // An SDK error reduces to its code and any other Error to its class name
72
+ // (rn-core's identifier-only redactor). Strings never survive here, not even
73
+ // a leading constant: a store message is free text from a payments SDK.
74
+ return value instanceof Error ? identifiers.text(value) : REDACTED;
75
+ }
76
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["REDACTED","SdkError","createRedactor","identifiers","PAYMENT_ERROR_CODES","PaymentError","constructor","init","code","message","retryable","redactedCause","cause","name","operation","PaymentConfigError","offenders","redact","value","Error","text"],"sourceRoot":"../../../src","sources":["diagnostics/errors.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,QAAQ,EAAEC,QAAQ,EAAEC,cAAc,QAAQ,wBAAwB;AAE3E,MAAMC,WAAW,GAAGD,cAAc,CAAC,CAAC;AAEpC,OAAO,MAAME,mBAAmB,GAAG,CAClC,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,8BAA8B,EAC9B,6BAA6B,EAC7B,mDAAmD,EACnD,8BAA8B,EAC9B,wBAAwB,EACxB,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,uCAAuC,EACvC,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,6BAA6B,EAC7B,gCAAgC,EAChC,6BAA6B,EAC7B;AACA,wBAAwB;AACxB;AACD;AACA;AACA;AACC,wBAAwB,CACf;;AAIV;;AAcA;AACA,OAAO,MAAMC,YAAY,SAASJ,QAAQ,CAAmB;EAE5D;;EAGAK,WAAWA,CAACC,IAMX,EAAE;IACF,KAAK,CAAC,YAAY,EAAEA,IAAI,CAACC,IAAI,EAAE;MAC9BC,OAAO,EAAEF,IAAI,CAACE,OAAO;MACrBC,SAAS,EAAEH,IAAI,CAACG,SAAS,IAAI,KAAK;MAClCC,aAAa,EAAEJ,IAAI,CAACK;IACrB,CAAC,CAAC;IACF,IAAI,CAACC,IAAI,GAAG,cAAc;IAC1B,IAAI,CAACC,SAAS,GAAGP,IAAI,CAACO,SAAS;IAC/B,IAAI,CAACF,KAAK,GAAGL,IAAI,CAACK,KAAK;EACxB;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,kBAAkB,SAASV,YAAY,CAAC;EACpD;;EAGAC,WAAWA,CAACC,IAKX,EAAE;IACF,KAAK,CAAC;MAAE,GAAGA,IAAI;MAAEG,SAAS,EAAE;IAAM,CAAC,CAAC;IACpC,IAAI,CAACG,IAAI,GAAG,oBAAoB;IAChC,IAAI,CAACG,SAAS,GAAGT,IAAI,CAACS,SAAS,IAAI,EAAE;EACtC;AACD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,MAAMA,CAACC,KAAc,EAAU;EAC9C;EACA;EACA;EACA,OAAOA,KAAK,YAAYC,KAAK,GAAGhB,WAAW,CAACiB,IAAI,CAACF,KAAK,CAAC,GAAGlB,QAAQ;AACnE","ignoreList":[]}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Typed events and the emitter.
5
+ *
6
+ * The bar is FR-077: the event stream **alone** must be enough to reconstruct a
7
+ * transaction's full lifecycle, so that "the user says they paid but has no
8
+ * entitlement" can be investigated from logs without a reproduction.
9
+ *
10
+ * Forbidden in every payload, without exception (FR-076, FR-074): store objects,
11
+ * raw receipts, verification payloads, backend tokens, payment details, the
12
+ * obfuscated account identifier, and the cache-scope token.
13
+ */
14
+
15
+ import { createDiagnosticChannel, createEmitter as createCoreEmitter } from '@chipmobilesdk/rn-core';
16
+
17
+ /** Every delivered event also goes to the app's SDK sinks (`installSdkSink`, CORE-08). */
18
+ const channel = createDiagnosticChannel('rn-payment');
19
+ import { redact } from "./errors.js";
20
+
21
+ /**
22
+ * A `PaymentEvent` with the timestamp left to the emitter.
23
+ *
24
+ * Distributive on purpose: a plain `Omit<PaymentEvent, 'timestamp'>` collapses the
25
+ * discriminated union into one object type with only the shared keys, which would
26
+ * reject every variant-specific field. `T extends unknown` forces the mapping to
27
+ * apply per member and keeps the union discriminated.
28
+ */
29
+
30
+ /**
31
+ * Creates the emitter.
32
+ *
33
+ * Two properties are deliberate:
34
+ *
35
+ * 1. **A throwing listener cannot break anything** (FR-081). Each listener is
36
+ * invoked defensively, the throw is handed to `onListenerError`, and delivery
37
+ * continues to the remaining listeners. One app's broken analytics callback
38
+ * must not stop the package granting an entitlement or stop another listener
39
+ * hearing about it.
40
+ *
41
+ * The failure is **not** re-emitted as an event, deliberately. A consumer's own
42
+ * bug is not a payment-lifecycle event, and reporting it through the channel
43
+ * that just failed would both invite recursion and double event traffic for
44
+ * every event while that listener stays broken. It goes to the logger instead.
45
+ *
46
+ * 2. **After `dispose`, nothing is emitted** (FR-082). A store callback can
47
+ * arrive after cleanup; it must be dropped silently rather than reach a
48
+ * listener whose component is gone.
49
+ */
50
+ export function createEmitter(onListenerError) {
51
+ // The event whose listeners are running, so a failure is reported against it.
52
+ let dispatching = null;
53
+ let isDisposed = false;
54
+ // rn-core's emitter: a snapshot per emit, each listener isolated, idempotent
55
+ // unsubscribe. Even the error reporter is isolated: if it throws, rn-core
56
+ // rethrows that on a fresh task rather than into the emit.
57
+ const emitter = createCoreEmitter({
58
+ onListenerError: error => {
59
+ if (!dispatching) return;
60
+ try {
61
+ onListenerError?.(error, dispatching);
62
+ } catch {
63
+ // The app's own reporter failed: nothing in the app is left to tell, so
64
+ // the failure goes to the SDK sinks rather than becoming an uncaught
65
+ // error on some later tick (FR-080).
66
+ channel.emit('listener_reporter_failed', 'error', {
67
+ eventType: dispatching.type
68
+ });
69
+ }
70
+ }
71
+ });
72
+ return {
73
+ emit(event) {
74
+ if (isDisposed) {
75
+ return;
76
+ }
77
+ const previous = dispatching;
78
+ dispatching = event;
79
+ try {
80
+ if (emitter.emit(event)) {
81
+ // The type and the cycle only: payment events carry product and
82
+ // entitlement keys an app may treat as personal.
83
+ channel.emit(event.type, /failed|error|blocked|rejected|revoked/.test(event.type) ? 'warn' : 'info', undefined, event.correlationId);
84
+ }
85
+ } finally {
86
+ dispatching = previous;
87
+ }
88
+ },
89
+ subscribe(listener) {
90
+ return isDisposed ? () => undefined : emitter.subscribe(listener);
91
+ },
92
+ dispose() {
93
+ isDisposed = true;
94
+ emitter.dispose();
95
+ },
96
+ listenerCount: () => emitter.listenerCount(),
97
+ disposed: () => isDisposed
98
+ };
99
+ }
100
+
101
+ /**
102
+ * Fields that must never appear in an event payload.
103
+ *
104
+ * Used by `__tests__/diagnostics.test.ts` to walk every emitted event across the
105
+ * whole suite. Enumerating the ban here rather than in the test keeps the rule
106
+ * next to the type it constrains.
107
+ */
108
+ export const FORBIDDEN_EVENT_FIELDS = ['verificationPayload', 'receipt', 'purchaseToken', 'transactionReceipt', 'obfuscatedAccountId', 'scopeToken', 'token', 'signature'];
109
+
110
+ /** Correlation ids tie one purchase cycle together; no user data goes into them. */
111
+ export function createCorrelationId(counter, prefix = 'pc') {
112
+ const id = `${prefix}_${counter.next.toString(36)}`;
113
+ counter.next += 1;
114
+ return id;
115
+ }
116
+ export { redact };
117
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createDiagnosticChannel","createEmitter","createCoreEmitter","channel","redact","onListenerError","dispatching","isDisposed","emitter","error","emit","eventType","type","event","previous","test","undefined","correlationId","subscribe","listener","dispose","listenerCount","disposed","FORBIDDEN_EVENT_FIELDS","createCorrelationId","counter","prefix","id","next","toString"],"sourceRoot":"../../../src","sources":["diagnostics/events.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SACCA,uBAAuB,EACvBC,aAAa,IAAIC,iBAAiB,QAC5B,wBAAwB;;AAE/B;AACA,MAAMC,OAAO,GAAGH,uBAAuB,CACtC,YACD,CAAC;AAED,SAASI,MAAM,QAAsD,aAAU;;AAoI/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASH,aAAaA,CAC5BI,eAA+D,EAC9C;EACjB;EACA,IAAIC,WAAgC,GAAG,IAAI;EAC3C,IAAIC,UAAU,GAAG,KAAK;EACtB;EACA;EACA;EACA,MAAMC,OAAO,GAAGN,iBAAiB,CAAe;IAC/CG,eAAe,EAAEI,KAAK,IAAI;MACzB,IAAI,CAACH,WAAW,EAAE;MAClB,IAAI;QACHD,eAAe,GAAGI,KAAK,EAAEH,WAAW,CAAC;MACtC,CAAC,CAAC,MAAM;QACP;QACA;QACA;QACAH,OAAO,CAACO,IAAI,CAAC,0BAA0B,EAAE,OAAO,EAAE;UACjDC,SAAS,EAAEL,WAAW,CAACM;QACxB,CAAC,CAAC;MACH;IACD;EACD,CAAC,CAAC;EAEF,OAAO;IACNF,IAAIA,CAACG,KAAK,EAAE;MACX,IAAIN,UAAU,EAAE;QACf;MACD;MACA,MAAMO,QAAQ,GAAGR,WAAW;MAC5BA,WAAW,GAAGO,KAAK;MACnB,IAAI;QACH,IAAIL,OAAO,CAACE,IAAI,CAACG,KAAK,CAAC,EAAE;UACxB;UACA;UACAV,OAAO,CAACO,IAAI,CACXG,KAAK,CAACD,IAAI,EACV,uCAAuC,CAACG,IAAI,CAACF,KAAK,CAACD,IAAI,CAAC,GAAG,MAAM,GAAG,MAAM,EAC1EI,SAAS,EACTH,KAAK,CAACI,aACP,CAAC;QACF;MACD,CAAC,SAAS;QACTX,WAAW,GAAGQ,QAAQ;MACvB;IACD,CAAC;IACDI,SAASA,CAACC,QAA8B,EAAe;MACtD,OAAOZ,UAAU,GAAG,MAAMS,SAAS,GAAGR,OAAO,CAACU,SAAS,CAACC,QAAQ,CAAC;IAClE,CAAC;IACDC,OAAOA,CAAA,EAAS;MACfb,UAAU,GAAG,IAAI;MACjBC,OAAO,CAACY,OAAO,CAAC,CAAC;IAClB,CAAC;IACDC,aAAa,EAAEA,CAAA,KAAMb,OAAO,CAACa,aAAa,CAAC,CAAC;IAC5CC,QAAQ,EAAEA,CAAA,KAAMf;EACjB,CAAC;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMgB,sBAAyC,GAAG,CACxD,qBAAqB,EACrB,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,OAAO,EACP,WAAW,CACX;;AAED;AACA,OAAO,SAASC,mBAAmBA,CAACC,OAAyB,EAAEC,MAAM,GAAG,IAAI,EAAU;EACrF,MAAMC,EAAE,GAAG,GAAGD,MAAM,IAAID,OAAO,CAACG,IAAI,CAACC,QAAQ,CAAC,EAAE,CAAC,EAAE;EACnDJ,OAAO,CAACG,IAAI,IAAI,CAAC;EACjB,OAAOD,EAAE;AACV;AAEA,SAASvB,MAAM","ignoreList":[]}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Stable, localizable message keys with English default copy (FR-084, FR-085).
5
+ *
6
+ * The package takes no i18n runtime dependency: consuming apps map these keys to
7
+ * localized strings through whatever i18n system they already run. This is plain
8
+ * data, and the package never resolves or renders it.
9
+ *
10
+ * Message keys are **public API**: renaming one is a breaking change, on the
11
+ * same footing as an error code (FR-078).
12
+ *
13
+ * User-actionable copy and developer/configuration copy are kept in separate
14
+ * maps so an app cannot accidentally show "Payment catalog is invalid" to a
15
+ * customer — a configuration fault is a developer's problem, not a user's.
16
+ */
17
+
18
+ /** Copy an end user may reasonably be shown. */
19
+ import { defineMessages } from '@chipmobilesdk/rn-core';
20
+
21
+ /** Copy for developers and operators. **Never** surfaced to an end user. */
22
+
23
+ export const DEFAULT_USER_MESSAGES = {
24
+ 'payment.state.pending': 'Waiting for your payment to complete',
25
+ 'payment.state.alreadyOwned': 'You already own this',
26
+ 'payment.action.restore': 'Restore purchases',
27
+ 'payment.restore.succeeded': 'Your purchases have been restored',
28
+ 'payment.restore.nothingFound': 'No previous purchases found',
29
+ 'payment.error.cancelled': 'Purchase cancelled',
30
+ 'payment.error.network': "Couldn't reach the store. Check your connection and try again.",
31
+ 'payment.error.unavailable': "Purchases aren't available on this device",
32
+ 'payment.error.disabled': 'Purchases are currently unavailable',
33
+ 'payment.subscription.grace': "There's a problem with your payment method",
34
+ 'payment.subscription.hold': 'Your subscription is paused until payment is updated'
35
+ };
36
+ export const DEFAULT_DEVELOPER_MESSAGES = {
37
+ 'payment.config.invalidCatalog': 'Payment catalog is invalid',
38
+ 'payment.config.missingStoreId': 'Product is missing a store identifier for this platform',
39
+ 'payment.config.productionInNonProductionBuild': 'Production payment configuration in a non-production build',
40
+ 'payment.config.storageUnavailable': 'Local storage unavailable; entitlements will not survive restart',
41
+ 'payment.config.environmentBlocked': 'Purchase blocked: this environment may not create a real transaction'
42
+ };
43
+
44
+ /**
45
+ * The catalog as an rn-core message set. Register `paymentMessages.user` with
46
+ * rn-i18n to translate it like app copy; the developer copy stays out of bundles.
47
+ */
48
+ export const paymentMessages = defineMessages({
49
+ user: DEFAULT_USER_MESSAGES,
50
+ developer: DEFAULT_DEVELOPER_MESSAGES
51
+ });
52
+ export const DEFAULT_MESSAGES = paymentMessages.defaults;
53
+
54
+ /** Every user-actionable key, for an app building its translation resource. */
55
+ export const USER_MESSAGE_KEYS = paymentMessages.userKeys;
56
+
57
+ /** Every developer-facing key, so an app can exclude them from user-visible bundles. */
58
+ export const DEVELOPER_MESSAGE_KEYS = paymentMessages.developerKeys;
59
+
60
+ /** True for keys safe to show an end user. Lets an app assert that at its boundary. */
61
+ export function isUserMessageKey(key) {
62
+ return paymentMessages.audienceOf(key) === 'user';
63
+ }
64
+ //# sourceMappingURL=messageKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["defineMessages","DEFAULT_USER_MESSAGES","DEFAULT_DEVELOPER_MESSAGES","paymentMessages","user","developer","DEFAULT_MESSAGES","defaults","USER_MESSAGE_KEYS","userKeys","DEVELOPER_MESSAGE_KEYS","developerKeys","isUserMessageKey","key","audienceOf"],"sourceRoot":"../../../src","sources":["diagnostics/messageKeys.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,SAASA,cAAc,QAAQ,wBAAwB;;AAgBvD;;AAeA,OAAO,MAAMC,qBAA4C,GAAG;EAC3D,uBAAuB,EAAE,sCAAsC;EAC/D,4BAA4B,EAAE,sBAAsB;EACpD,wBAAwB,EAAE,mBAAmB;EAC7C,2BAA2B,EAAE,mCAAmC;EAChE,8BAA8B,EAAE,6BAA6B;EAC7D,yBAAyB,EAAE,oBAAoB;EAC/C,uBAAuB,EAAE,gEAAgE;EACzF,2BAA2B,EAAE,2CAA2C;EACxE,wBAAwB,EAAE,qCAAqC;EAC/D,4BAA4B,EAAE,4CAA4C;EAC1E,2BAA2B,EAAE;AAC9B,CAAC;AAED,OAAO,MAAMC,0BAAsD,GAAG;EACrE,+BAA+B,EAAE,4BAA4B;EAC7D,+BAA+B,EAAE,yDAAyD;EAC1F,+CAA+C,EAC9C,4DAA4D;EAC7D,mCAAmC,EAClC,kEAAkE;EACnE,mCAAmC,EAClC;AACF,CAAC;;AAED;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAAe,GAAGH,cAAc,CAAC;EAC7CI,IAAI,EAAEH,qBAAqB;EAC3BI,SAAS,EAAEH;AACZ,CAAC,CAAC;AAEF,OAAO,MAAMI,gBAAmC,GAAGH,eAAe,CAACI,QAAQ;;AAE3E;AACA,OAAO,MAAMC,iBAAiB,GAAGL,eAAe,CAACM,QAAmC;;AAEpF;AACA,OAAO,MAAMC,sBAAsB,GAAGP,eAAe,CAACQ,aAA6C;;AAEnG;AACA,OAAO,SAASC,gBAAgBA,CAACC,GAAsB,EAAgC;EACtF,OAAOV,eAAe,CAACW,UAAU,CAACD,GAAG,CAAC,KAAK,MAAM;AAClD","ignoreList":[]}
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The billing connection: connecting, watching it, and reconnecting with bounded
5
+ * backoff (FR-018 – FR-024, PAY-10).
6
+ *
7
+ * A reconnect is always a full teardown-then-connect cycle. The upstream
8
+ * binding's own `reconnect()` has reported success without rebuilding anything
9
+ * (openiap#408), so no shortcut is trusted here.
10
+ */
11
+
12
+ import { backoffDelayMs } from "../core/retry.js";
13
+ import { withTimeout } from "../core/mutex.js";
14
+ import { PaymentError } from "../diagnostics/errors.js";
15
+ export function createConnection(state, onPurchase) {
16
+ const {
17
+ provider,
18
+ resolved
19
+ } = state;
20
+ let connectionSub;
21
+ let purchaseSub;
22
+ let reconnectTimer;
23
+ let reconnectAttempts = 0;
24
+ /**
25
+ * Set once a connection succeeded. Recovery after an exhausted budget is only
26
+ * meaningful from there; a first connection that failed is the app's to retry
27
+ * through `initialize`.
28
+ */
29
+ let everConnected = false;
30
+ function scheduleReconnect() {
31
+ if (state.disposed) {
32
+ return;
33
+ }
34
+ if (reconnectAttempts >= resolved.retry.reconnect.maxAttempts) {
35
+ // Out of budget for now, not for good: a retryable failure rather than a
36
+ // `connecting` that promised a reconnect nobody was going to make.
37
+ state.setStatus({
38
+ kind: 'failed',
39
+ retryable: true,
40
+ reconnectAttempts
41
+ });
42
+ return;
43
+ }
44
+ const attempt = reconnectAttempts + 1;
45
+ reconnectTimer = setTimeout(() => {
46
+ reconnectTimer = undefined;
47
+ if (state.disposed) {
48
+ return;
49
+ }
50
+ reconnectAttempts = attempt;
51
+ state.setStatus({
52
+ kind: 'connecting',
53
+ reconnectAttempts
54
+ });
55
+ reconnectOnce().catch(() => undefined);
56
+ }, backoffDelayMs(attempt, resolved.retry.reconnect));
57
+ }
58
+ async function reconnectOnce() {
59
+ try {
60
+ await provider.disconnect();
61
+ } catch {
62
+ // Already down; nothing to tear down.
63
+ }
64
+ const outcome = await provider.connect();
65
+ if (state.disposed) {
66
+ return;
67
+ }
68
+ if (outcome.ok) {
69
+ reconnectAttempts = 0;
70
+ state.setStatus({
71
+ kind: 'ready',
72
+ reconnectAttempts: 0
73
+ });
74
+ } else {
75
+ scheduleReconnect();
76
+ }
77
+ }
78
+
79
+ /** Replaced, never stacked: a second subscription would hear everything twice. */
80
+ function watch() {
81
+ connectionSub?.();
82
+ connectionSub = provider.observeConnection((connected, reason) => {
83
+ if (state.disposed) {
84
+ return;
85
+ }
86
+ state.emit({
87
+ type: 'connection_changed',
88
+ connected,
89
+ reason,
90
+ attempt: reconnectAttempts
91
+ });
92
+ if (!connected && state.status.kind === 'ready') {
93
+ state.setStatus({
94
+ kind: 'connecting'
95
+ });
96
+ scheduleReconnect();
97
+ }
98
+ });
99
+ // Session-long: a pending purchase settling between sessions arrives here
100
+ // (FR-039), not only while a purchase is open.
101
+ purchaseSub?.();
102
+ purchaseSub = provider.observePurchases(purchase => {
103
+ if (!state.disposed) {
104
+ onPurchase(purchase);
105
+ }
106
+ });
107
+ }
108
+ return {
109
+ async connect() {
110
+ const outcome = await withTimeout(provider.connect(), resolved.timeouts.connectMs, () => new PaymentError({
111
+ code: 'PAYMENT_TIMEOUT',
112
+ message: 'Connecting to the billing service timed out',
113
+ operation: 'initialize',
114
+ retryable: true
115
+ })).catch(error => ({
116
+ ok: false,
117
+ reason: 'store_error',
118
+ retryable: error.retryable
119
+ }));
120
+ if (!outcome.ok) {
121
+ if (outcome.reason === 'store_error') {
122
+ state.setStatus({
123
+ kind: 'failed',
124
+ retryable: outcome.retryable
125
+ });
126
+ return {
127
+ ok: false,
128
+ error: new PaymentError({
129
+ code: 'PAYMENT_STORE_ERROR',
130
+ message: 'Could not connect to the billing service',
131
+ operation: 'initialize',
132
+ retryable: outcome.retryable
133
+ })
134
+ };
135
+ }
136
+ // No billing service, an outdated one, or an unsupported platform: each
137
+ // distinguishable, and none of them may break the host app (FR-021, FR-023).
138
+ state.setStatus({
139
+ kind: 'unavailable',
140
+ unavailableReason: outcome.reason,
141
+ retryable: outcome.retryable
142
+ });
143
+ return {
144
+ ok: false,
145
+ error: new PaymentError({
146
+ code: outcome.reason === 'platform_unsupported' ? 'PAYMENT_UNSUPPORTED_PLATFORM' : 'PAYMENT_UNAVAILABLE',
147
+ message: `Billing unavailable: ${outcome.reason}`,
148
+ operation: 'initialize',
149
+ retryable: outcome.retryable
150
+ })
151
+ };
152
+ }
153
+ watch();
154
+ everConnected = true;
155
+ state.setStatus({
156
+ kind: 'ready',
157
+ reconnectAttempts: 0
158
+ });
159
+ return {
160
+ ok: true
161
+ };
162
+ },
163
+ async recover() {
164
+ if (everConnected && !state.disposed && state.status.kind === 'failed' && reconnectTimer === undefined) {
165
+ reconnectAttempts = 0;
166
+ state.setStatus({
167
+ kind: 'connecting',
168
+ reconnectAttempts: 0
169
+ });
170
+ await reconnectOnce().catch(() => undefined);
171
+ }
172
+ },
173
+ dispose() {
174
+ connectionSub?.();
175
+ connectionSub = undefined;
176
+ purchaseSub?.();
177
+ purchaseSub = undefined;
178
+ if (reconnectTimer !== undefined) {
179
+ clearTimeout(reconnectTimer);
180
+ reconnectTimer = undefined;
181
+ }
182
+ }
183
+ };
184
+ }
185
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["backoffDelayMs","withTimeout","PaymentError","createConnection","state","onPurchase","provider","resolved","connectionSub","purchaseSub","reconnectTimer","reconnectAttempts","everConnected","scheduleReconnect","disposed","retry","reconnect","maxAttempts","setStatus","kind","retryable","attempt","setTimeout","undefined","reconnectOnce","catch","disconnect","outcome","connect","ok","watch","observeConnection","connected","reason","emit","type","status","observePurchases","purchase","timeouts","connectMs","code","message","operation","error","unavailableReason","recover","dispose","clearTimeout"],"sourceRoot":"../../../src","sources":["engine/connection.ts"],"mappings":"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","ignoreList":[]}