@chipmobilesdk/rn-payment 0.6.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 (295) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +1 -1
  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
@@ -0,0 +1,325 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createFinalizer = createFinalizer;
7
+ var _retry = require("../core/retry.js");
8
+ var _mutex = require("../core/mutex.js");
9
+ var _errors = require("../diagnostics/errors.js");
10
+ var _snapshot = require("../persistence/snapshot.js");
11
+ /**
12
+ * The finalization queue — the package's hardest invariant (FR-041, FR-042).
13
+ *
14
+ * Google auto-refunds and revokes a purchase that is not acknowledged within
15
+ * **three days**. So finalization cannot be a step the app might forget, and it
16
+ * cannot live only in memory: the failure case FR-042 names is the app being
17
+ * force-killed in the instant between payment and acknowledgement.
18
+ *
19
+ * The ordering that makes this work is: **write the intent, then call the store.**
20
+ * A crash before the write means the purchase is still owned and the next sync
21
+ * re-queues it from `queryOwned`. A crash after the write means the queue has a
22
+ * record and the next startup drains it. There is no window where a paid
23
+ * transaction is forgotten.
24
+ *
25
+ * Consumption stays app-triggered (FR-043), because only the app knows whether
26
+ * the item was actually banked in its own data.
27
+ */
28
+
29
+ /** A Node `Timeout` and a browser numeric id are both valid here. */
30
+
31
+ function createFinalizer(deps) {
32
+ const setTimeoutFn = deps.setTimeoutFn ?? setTimeout;
33
+ const clearTimeoutFn = deps.clearTimeoutFn ?? clearTimeout;
34
+
35
+ /** One timer per transaction, so two transactions retry independently. */
36
+ const timers = new Map();
37
+ /** Guards against two drains racing the same transaction. */
38
+ const inFlight = new Set();
39
+ const find = transactionId => deps.snapshot().purchases.find(p => p.transactionId === transactionId);
40
+ const patch = (transactionId, changes) => {
41
+ const snapshot = deps.snapshot();
42
+ deps.commit({
43
+ ...snapshot,
44
+ purchases: snapshot.purchases.map(p => p.transactionId === transactionId ? {
45
+ ...p,
46
+ ...changes
47
+ } : p)
48
+ });
49
+ };
50
+
51
+ /**
52
+ * One store call under `attemptTimeoutMs`. A call that never settles used to
53
+ * hold this transaction's in-flight guard and, through `drain`, the sync that
54
+ * awaited it. Timing out counts as a failed attempt, so the retry schedule and
55
+ * the next-session drain both still apply.
56
+ */
57
+ const bounded = (call, operation) => (0, _mutex.withTimeout)(call, deps.attemptTimeoutMs, () => new _errors.PaymentError({
58
+ code: 'PAYMENT_TIMEOUT',
59
+ message: `The store did not answer the ${operation} call in time`,
60
+ operation,
61
+ retryable: true
62
+ }));
63
+ const clearTimer = transactionId => {
64
+ const timer = timers.get(transactionId);
65
+ if (timer !== undefined) {
66
+ clearTimeoutFn(timer);
67
+ timers.delete(transactionId);
68
+ }
69
+ };
70
+
71
+ /**
72
+ * Attempts one finalize call.
73
+ *
74
+ * A consumable is **not** acknowledged here: it waits for the app's explicit
75
+ * `consume`. Acknowledging it now would tell the store the entitlement was
76
+ * delivered before the app has recorded the item, and a crash in between would
77
+ * lose a paid item with no way to recover it.
78
+ */
79
+ const attempt = async transactionId => {
80
+ if (deps.disposed()) {
81
+ return {
82
+ kind: 'failed',
83
+ code: 'PAYMENT_NOT_CONFIGURED'
84
+ };
85
+ }
86
+ const record = find(transactionId);
87
+ if (!record) {
88
+ return {
89
+ kind: 'unknown_transaction'
90
+ };
91
+ }
92
+ if (record.finalizeState === 'done') {
93
+ // Idempotent by design: calling twice is a success, not an error (FR-044).
94
+ return {
95
+ kind: 'already_finalized'
96
+ };
97
+ }
98
+ if (record.productType === 'one_time_consumable') {
99
+ // The app owns this moment. Nothing to do until it calls consume().
100
+ return {
101
+ kind: 'already_finalized'
102
+ };
103
+ }
104
+ if (inFlight.has(transactionId)) {
105
+ return {
106
+ kind: 'retry_scheduled',
107
+ attempts: record.attempts
108
+ };
109
+ }
110
+ inFlight.add(transactionId);
111
+ patch(transactionId, {
112
+ finalizeState: 'in_flight'
113
+ });
114
+ let failed = false;
115
+ try {
116
+ await bounded(deps.provider.acknowledge(record.token), 'finalize');
117
+ } catch {
118
+ failed = true;
119
+ } finally {
120
+ // Released before scheduling the retry, deliberately. The guard exists to
121
+ // stop two concurrent store calls for one transaction, nothing more — if
122
+ // it were still held here, the next scheduled attempt would be refused by
123
+ // our own lock and the retry schedule would silently stall after one try.
124
+ inFlight.delete(transactionId);
125
+ }
126
+ const attempts = record.attempts + 1;
127
+ if (!failed) {
128
+ clearTimer(transactionId);
129
+ patch(transactionId, {
130
+ finalizeState: 'done',
131
+ state: 'purchased',
132
+ attempts
133
+ });
134
+ deps.emit({
135
+ type: 'transaction_finalized',
136
+ productKey: record.productKey,
137
+ attempts
138
+ });
139
+ return {
140
+ kind: 'finalized'
141
+ };
142
+ }
143
+ patch(transactionId, {
144
+ finalizeState: 'failed',
145
+ attempts
146
+ });
147
+ return scheduleRetry(transactionId, record.productKey, attempts, 'acknowledge');
148
+ };
149
+
150
+ /**
151
+ * One consume call for a consumable the app has banked (FR-043).
152
+ *
153
+ * Refuses anything that is not a settled consumable. Consuming a subscription
154
+ * or a permanent unlock would tell the store the user used it up, and a
155
+ * pending purchase has nothing to consume yet.
156
+ */
157
+ const consumeAttempt = async transactionId => {
158
+ if (deps.disposed()) {
159
+ return {
160
+ kind: 'failed',
161
+ code: 'PAYMENT_NOT_CONFIGURED'
162
+ };
163
+ }
164
+ const record = find(transactionId);
165
+ if (!record) {
166
+ return {
167
+ kind: 'unknown_transaction'
168
+ };
169
+ }
170
+ if (record.productType !== 'one_time_consumable') {
171
+ return {
172
+ kind: 'failed',
173
+ code: 'PAYMENT_NOT_CONSUMABLE'
174
+ };
175
+ }
176
+ if (record.state === 'pending') {
177
+ return {
178
+ kind: 'failed',
179
+ code: 'PAYMENT_PENDING'
180
+ };
181
+ }
182
+ if (record.state === 'consumed') {
183
+ // Consuming twice must grant the item once (FR-044).
184
+ return {
185
+ kind: 'already_finalized'
186
+ };
187
+ }
188
+ if (inFlight.has(transactionId)) {
189
+ // Concurrent consume calls collapse to one, for the same reason.
190
+ return {
191
+ kind: 'already_finalized'
192
+ };
193
+ }
194
+ inFlight.add(transactionId);
195
+ patch(transactionId, {
196
+ finalizeState: 'in_flight'
197
+ });
198
+ let failed = false;
199
+ try {
200
+ await bounded(deps.provider.consume(record.token), 'consume');
201
+ } catch {
202
+ failed = true;
203
+ } finally {
204
+ // Released before scheduling, for the same reason as in `attempt`.
205
+ inFlight.delete(transactionId);
206
+ }
207
+ const attempts = record.attempts + 1;
208
+ if (failed) {
209
+ patch(transactionId, {
210
+ finalizeState: 'failed',
211
+ attempts
212
+ });
213
+ return scheduleRetry(transactionId, record.productKey, attempts, 'consume');
214
+ }
215
+ clearTimer(transactionId);
216
+ // `consumed` is what stops it being an entitlement source, so a
217
+ // consumable never becomes a permanent unlock.
218
+ patch(transactionId, {
219
+ state: 'consumed',
220
+ finalizeState: 'done',
221
+ attempts
222
+ });
223
+ deps.emit({
224
+ type: 'transaction_consumed',
225
+ productKey: record.productKey
226
+ });
227
+ return {
228
+ kind: 'finalized'
229
+ };
230
+ };
231
+
232
+ /**
233
+ * Schedules the next attempt inside the per-session budget.
234
+ *
235
+ * Exhausting the budget is **not** giving up. The record stays `failed`, which
236
+ * `pendingFinalizations` still returns, so the next startup or foreground drain
237
+ * picks it up again. That is what keeps the package inside Play's three-day
238
+ * window without hammering a store that is currently refusing.
239
+ */
240
+ const scheduleRetry = (transactionId, productKey, attempts, operation) => {
241
+ if (deps.disposed()) {
242
+ return {
243
+ kind: 'failed',
244
+ code: 'PAYMENT_FINALIZE_FAILED'
245
+ };
246
+ }
247
+ if (attempts >= deps.retry.finalize.maxAttempts) {
248
+ // Left queued deliberately — resumed next session, never abandoned.
249
+ return {
250
+ kind: 'failed',
251
+ code: 'PAYMENT_FINALIZE_FAILED'
252
+ };
253
+ }
254
+ const delayMs = (0, _retry.backoffDelayMs)(attempts + 1, deps.retry.finalize);
255
+ clearTimer(transactionId);
256
+ timers.set(transactionId, setTimeoutFn(() => {
257
+ timers.delete(transactionId);
258
+ const retry = operation === 'consume' ? consumeAttempt : attempt;
259
+ retry(transactionId).catch(() => undefined);
260
+ }, delayMs));
261
+ deps.emit({
262
+ type: 'finalize_retry_scheduled',
263
+ productKey,
264
+ attempt: attempts + 1,
265
+ delayMs
266
+ });
267
+ return {
268
+ kind: 'retry_scheduled',
269
+ attempts
270
+ };
271
+ };
272
+ return {
273
+ async enqueue(transactionId) {
274
+ const record = find(transactionId);
275
+ if (!record) {
276
+ return {
277
+ kind: 'unknown_transaction'
278
+ };
279
+ }
280
+ if (record.finalizeState === 'done') {
281
+ return {
282
+ kind: 'already_finalized'
283
+ };
284
+ }
285
+
286
+ // The write happens BEFORE the store call. This single ordering is what
287
+ // makes a kill between payment and acknowledgement recoverable.
288
+ if (record.finalizeState !== 'in_flight') {
289
+ patch(transactionId, {
290
+ finalizeState: 'queued'
291
+ });
292
+ }
293
+ return attempt(transactionId);
294
+ },
295
+ async drain() {
296
+ // Runs regardless of whether a purchase happened this session: the record
297
+ // it is looking for was probably written by a session that died.
298
+ for (const record of (0, _snapshot.pendingFinalizations)(deps.snapshot())) {
299
+ if (deps.disposed()) {
300
+ return;
301
+ }
302
+ await attempt(record.transactionId).catch(() => undefined);
303
+ }
304
+ },
305
+ consume(ref) {
306
+ return consumeAttempt(ref.transactionId);
307
+ },
308
+ unfinalized() {
309
+ return (0, _snapshot.pendingFinalizations)(deps.snapshot()).map(p => ({
310
+ productKey: p.productKey,
311
+ transactionId: p.transactionId,
312
+ attempts: p.attempts,
313
+ purchasedAt: p.purchasedAt
314
+ }));
315
+ },
316
+ dispose() {
317
+ for (const timer of timers.values()) {
318
+ clearTimeoutFn(timer);
319
+ }
320
+ timers.clear();
321
+ inFlight.clear();
322
+ }
323
+ };
324
+ }
325
+ //# sourceMappingURL=finalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_retry","require","_mutex","_errors","_snapshot","createFinalizer","deps","setTimeoutFn","setTimeout","clearTimeoutFn","clearTimeout","timers","Map","inFlight","Set","find","transactionId","snapshot","purchases","p","patch","changes","commit","map","bounded","call","operation","withTimeout","attemptTimeoutMs","PaymentError","code","message","retryable","clearTimer","timer","get","undefined","delete","attempt","disposed","kind","record","finalizeState","productType","has","attempts","add","failed","provider","acknowledge","token","state","emit","type","productKey","scheduleRetry","consumeAttempt","consume","retry","finalize","maxAttempts","delayMs","backoffDelayMs","set","catch","enqueue","drain","pendingFinalizations","ref","unfinalized","purchasedAt","dispose","values","clear"],"sourceRoot":"../../../src","sources":["engine/finalize.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.syncOnForeground = syncOnForeground;
7
+ var _rnCore = require("@chipmobilesdk/rn-core");
8
+ /**
9
+ * Opt-in foreground sync over rn-core's shared lifecycle port (PERF-07, FR-059).
10
+ *
11
+ * `handleForeground()` stays the app's to call: the engine does not decide what a
12
+ * foreground return is. An app that is happy with "back from the background" calls
13
+ * this once instead of wiring `AppState` itself, and shares the one native
14
+ * subscription every package uses. A trip through `inactive` alone (a biometric
15
+ * prompt, iOS Control Center) is not a return. On Android the Play purchase sheet
16
+ * does send the app to the background, so a purchase is followed by a sync; the
17
+ * engine's foreground rate limit keeps that to one request per interval.
18
+ */
19
+
20
+ function syncOnForeground(engine, lifecycle = (0, _rnCore.appLifecycle)()) {
21
+ return (0, _rnCore.onForeground)(() => {
22
+ // Sync reports its own failures through status and diagnostics.
23
+ engine.handleForeground().catch(() => undefined);
24
+ }, lifecycle);
25
+ }
26
+ //# sourceMappingURL=foreground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_rnCore","require","syncOnForeground","engine","lifecycle","appLifecycle","onForeground","handleForeground","catch","undefined"],"sourceRoot":"../../../src","sources":["engine/foreground.ts"],"mappings":";;;;;;AAWA,IAAAA,OAAA,GAAAC,OAAA;AAXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUO,SAASC,gBAAgBA,CAC/BC,MAA+C,EAC/CC,SAA2B,GAAG,IAAAC,oBAAY,EAAC,CAAC,EAC9B;EACd,OAAO,IAAAC,oBAAY,EAAC,MAAM;IACzB;IACAH,MAAM,CAACI,gBAAgB,CAAC,CAAC,CAACC,KAAK,CAAC,MAAMC,SAAS,CAAC;EACjD,CAAC,EAAEL,SAAS,CAAC;AACd","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.attachEngineInternals = attachEngineInternals;
7
+ exports.engineInternals = engineInternals;
8
+ /**
9
+ * What tests and diagnostics need from an engine, off its public type (PAY-11).
10
+ *
11
+ * Until 0.6.0 these were methods of `PaymentEngine`, so any consumer could commit
12
+ * a snapshot of its own and grant itself an entitlement the store never sold,
13
+ * and a hand-written engine double had to implement all of them. They live in a
14
+ * WeakMap keyed by the engine now, and this module is not exported from the
15
+ * package entrypoint.
16
+ */
17
+
18
+ const registry = new WeakMap();
19
+ function attachEngineInternals(engine, internals) {
20
+ registry.set(engine, internals);
21
+ }
22
+
23
+ /** The internals of an engine `createEngine` made. Throws for any other object. */
24
+ function engineInternals(engine) {
25
+ const internals = registry.get(engine);
26
+ if (!internals) {
27
+ throw new Error('engineInternals: this engine was not created by createEngine');
28
+ }
29
+ return internals;
30
+ }
31
+ //# sourceMappingURL=internals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["registry","WeakMap","attachEngineInternals","engine","internals","set","engineInternals","get","Error"],"sourceRoot":"../../../src","sources":["engine/internals.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBA,MAAMA,QAAQ,GAAG,IAAIC,OAAO,CAAiC,CAAC;AAEvD,SAASC,qBAAqBA,CAACC,MAAqB,EAAEC,SAA0B,EAAQ;EAC9FJ,QAAQ,CAACK,GAAG,CAACF,MAAM,EAAEC,SAAS,CAAC;AAChC;;AAEA;AACO,SAASE,eAAeA,CAACH,MAAqB,EAAmB;EACvE,MAAMC,SAAS,GAAGJ,QAAQ,CAACO,GAAG,CAACJ,MAAM,CAAC;EACtC,IAAI,CAACC,SAAS,EAAE;IACf,MAAM,IAAII,KAAK,CAAC,8DAA8D,CAAC;EAChF;EACA,OAAOJ,SAAS;AACjB","ignoreList":[]}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.UNKNOWN_PENDING = void 0;
7
+ exports.derivePending = derivePending;
8
+ exports.pendingTransitions = pendingTransitions;
9
+ exports.samePending = samePending;
10
+ var _aggregate = require("../entitlements/aggregate.js");
11
+ /**
12
+ * The pending set, and how a pending purchase ends (FR-101 – FR-104), added in
13
+ * 0.2.0.
14
+ *
15
+ * 0.1.0 handled pending purchases correctly on the grant side — pending never
16
+ * grants, a settled one is granted at the next sync, an abandoned one is removed
17
+ * — but an app could only *see* one in the session it started in. The record
18
+ * was already persisted with a `pending` state; this module is the read side of
19
+ * it, and nothing more. It decides nothing about granting: that stays in
20
+ * `entitlements/aggregate.ts`, where pending is refused unconditionally.
21
+ *
22
+ * Pure: no provider, no I/O, no React. The engine calls it from `commit`.
23
+ */
24
+
25
+ const UNKNOWN_PENDING = exports.UNKNOWN_PENDING = {
26
+ status: 'unknown',
27
+ purchases: [],
28
+ isStale: false
29
+ };
30
+
31
+ /**
32
+ * Derives the pending set from the snapshot.
33
+ *
34
+ * Read from the persisted record, so it survives an app kill and an offline
35
+ * restart, and judged by the very staleness rule entitlements use (FR-103).
36
+ * Products no longer in the catalog are left out: an app cannot render a row,
37
+ * or withhold a Buy button, for a product key it no longer has.
38
+ */
39
+ function derivePending(input) {
40
+ const {
41
+ config,
42
+ snapshot
43
+ } = input;
44
+ const {
45
+ isStale,
46
+ undetermined
47
+ } = (0, _aggregate.snapshotCertainty)(input);
48
+ const earliest = new Map();
49
+ for (const purchase of snapshot.purchases) {
50
+ if (purchase.state !== 'pending' || !config.entries.has(purchase.productKey)) {
51
+ continue;
52
+ }
53
+ const known = earliest.get(purchase.productKey);
54
+ if (known === undefined || purchase.purchasedAt < known) {
55
+ earliest.set(purchase.productKey, purchase.purchasedAt);
56
+ }
57
+ }
58
+ const purchases = [...earliest].map(([productKey, since]) => ({
59
+ productKey,
60
+ since
61
+ })).sort((a, b) => a.since - b.since || a.productKey.localeCompare(b.productKey));
62
+ return {
63
+ status: undetermined ? 'unknown' : 'known',
64
+ purchases,
65
+ isStale
66
+ };
67
+ }
68
+ /**
69
+ * Every pending transaction that stopped being pending between two snapshots.
70
+ *
71
+ * Computed from the commit itself rather than at each call site that might end
72
+ * a pending purchase — sync, a store push, a purchase — which is what makes
73
+ * "exactly once" structural (FR-104, FR-079). A store push and a sync racing on
74
+ * one settling purchase both commit, but only the first commit sees it leave
75
+ * the pending set.
76
+ *
77
+ * A record that disappeared ended without payment. Why is the store's to say;
78
+ * when it says nothing, `cancelled` (see `PendingResolution`).
79
+ */
80
+ function pendingTransitions(previous, next, config, endReason) {
81
+ const transitions = [];
82
+ for (const before of previous.purchases) {
83
+ if (before.state !== 'pending' || !config.entries.has(before.productKey)) {
84
+ continue;
85
+ }
86
+ const after = next.purchases.find(p => p.transactionId === before.transactionId);
87
+ if (after?.state === 'pending') {
88
+ continue;
89
+ }
90
+ transitions.push({
91
+ productKey: before.productKey,
92
+ outcome: after ? 'settled' : endReason(before.transactionId) ?? 'cancelled'
93
+ });
94
+ }
95
+ return transitions;
96
+ }
97
+
98
+ /** Whether a listener has anything new to hear. */
99
+ function samePending(a, b) {
100
+ return a.status === b.status && a.isStale === b.isStale && a.purchases.length === b.purchases.length && a.purchases.every((purchase, index) => purchase.productKey === b.purchases[index].productKey && purchase.since === b.purchases[index].since);
101
+ }
102
+ //# sourceMappingURL=pending.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_aggregate","require","UNKNOWN_PENDING","exports","status","purchases","isStale","derivePending","input","config","snapshot","undetermined","snapshotCertainty","earliest","Map","purchase","state","entries","has","productKey","known","get","undefined","purchasedAt","set","map","since","sort","a","b","localeCompare","pendingTransitions","previous","next","endReason","transitions","before","after","find","p","transactionId","push","outcome","samePending","length","every","index"],"sourceRoot":"../../../src","sources":["engine/pending.ts"],"mappings":"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","ignoreList":[]}