@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 @@
1
+ {"version":3,"names":["PaymentError","productKeyForStoreId","createRateLimiter","createSingleFlight","withTimeout","resolveFinalizeState","toPersistedRecord","resolved","purchase","productKey","existing","transactionId","productType","entries","get","token","state","purchasedAt","finalizeState","attempts","validationState","expiresAt","willAutoRenew","toPersisted","purchases","known","records","storeProductId","has","find","p","push","purchasedIds","Set","filter","map","createSync","settle","provider","now","syncFlight","settleFlight","foregroundLimiter","foregroundSyncMinIntervalMs","querySnapshot","trigger","owned","queryOwned","timeouts","syncMs","code","message","operation","retryable","before","snapshot","after","revokedCount","id","length","restoredCount","hasSynced","commit","lastSyncedAt","emit","type","ok","error","paymentError","sync","disposed","enabled","tryAcquire","outcome","run"],"sourceRoot":"../../../src","sources":["engine/sync.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Entitlement aggregation — the package's primary output.
5
+ *
6
+ * Everything else exists to make this one answer correct. The most damaging
7
+ * defect class in a payment SDK lives here: collapsing "not yet synced" into "not
8
+ * entitled" makes a paying user watch ads flash on cold start or see a purchased
9
+ * feature sit locked.
10
+ *
11
+ * Two rules do most of the work:
12
+ *
13
+ * - **A pending purchase is never a source** (FR-037). Enforced here, in
14
+ * aggregation, rather than at each call site, so no future code path can grant
15
+ * on money that has not arrived.
16
+ * - **Uncertainty resolves to `unknown`, never `not_entitled`** (FR-047,
17
+ * FR-055a). Never synced, stale, or scope-changed all mean "we do not know",
18
+ * and the package says so rather than asserting the user did not pay.
19
+ */
20
+
21
+ import { shallowEqual } from '@chipmobilesdk/rn-core';
22
+ import { entitlementsFor } from "./mapping.js";
23
+ import { deriveRenewalState, grantsUnderPolicy, hasExpired } from "./policy.js";
24
+ /** A purchase that currently confers its entitlements. */
25
+ function isValidSource(purchase, input) {
26
+ // Only a purchase the store confirmed grants. Pending money is not money, and a
27
+ // state this version does not know is no basis for a grant either (PAY-13).
28
+ if (purchase.state !== 'purchased') {
29
+ return false;
30
+ }
31
+ // A backend that said no is final (FR-071). A queued re-validation still
32
+ // grants, which is the documented `grant_and_queue` fallback (FR-072).
33
+ if (purchase.validationState === 'rejected') {
34
+ return false;
35
+ }
36
+ if (purchase.productType === 'subscription') {
37
+ if (hasExpired(purchase.expiresAt, input.now)) {
38
+ return false;
39
+ }
40
+ const renewalState = deriveRenewalState({
41
+ expiresAt: purchase.expiresAt,
42
+ willAutoRenew: purchase.willAutoRenew,
43
+ reportsGraceAndHoldDistinctly: input.reportsGraceAndHoldDistinctly
44
+ });
45
+ return grantsUnderPolicy(renewalState, {
46
+ gracePolicy: input.config.gracePolicy,
47
+ holdPolicy: input.config.holdPolicy
48
+ });
49
+ }
50
+
51
+ // A consumable that has not been consumed yet is owned, but it must never
52
+ // become a permanent entitlement — consumption flips it to `consumed` above.
53
+ return true;
54
+ }
55
+ function subscriptionDetailFor(purchases, input) {
56
+ const subs = purchases.filter(p => p.productType === 'subscription');
57
+ if (subs.length === 0) {
58
+ return undefined;
59
+ }
60
+
61
+ // Where several subscriptions grant one entitlement, the one running longest
62
+ // is what the user experiences, so report that one.
63
+ const furthest = subs.reduce((best, candidate) => {
64
+ const bestAt = best.expiresAt ?? Number.MAX_SAFE_INTEGER;
65
+ const candidateAt = candidate.expiresAt ?? Number.MAX_SAFE_INTEGER;
66
+ return candidateAt > bestAt ? candidate : best;
67
+ });
68
+ const renewalState = deriveRenewalState({
69
+ expiresAt: furthest.expiresAt,
70
+ willAutoRenew: furthest.willAutoRenew,
71
+ reportsGraceAndHoldDistinctly: input.reportsGraceAndHoldDistinctly
72
+ });
73
+ return {
74
+ expiresAt: furthest.expiresAt,
75
+ willAutoRenew: furthest.willAutoRenew === true,
76
+ isCancelledButValid: renewalState === 'cancelled_valid',
77
+ renewalState
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Computes the full entitlement map.
83
+ *
84
+ * Pure and synchronous by design: it runs on render paths, so it must never
85
+ * touch I/O (PERF-001). The engine calls it after any state change and caches the
86
+ * result.
87
+ */
88
+ /**
89
+ * How far the snapshot can be trusted right now.
90
+ *
91
+ * Shared by entitlements and the pending set (FR-103) so the two can never
92
+ * disagree about whether the package knows anything — a paywall that showed
93
+ * "not entitled" next to "nothing pending" from one stale snapshot would offer
94
+ * Buy to a user whose payment is in flight.
95
+ */
96
+ export function snapshotCertainty(input) {
97
+ const {
98
+ config,
99
+ snapshot,
100
+ hasSynced,
101
+ now
102
+ } = input;
103
+ const isStale = snapshot.lastSyncedAt !== undefined && now - snapshot.lastSyncedAt > config.staleAfterMs;
104
+
105
+ // Both roads lead to `unknown`, never to a confident "no". Never having synced
106
+ // and having synced too long ago are the same epistemic state: we cannot
107
+ // currently support a claim either way.
108
+ return {
109
+ isStale,
110
+ undetermined: !hasSynced || isStale
111
+ };
112
+ }
113
+ export function aggregate(input) {
114
+ const {
115
+ config,
116
+ snapshot
117
+ } = input;
118
+ const {
119
+ isStale,
120
+ undetermined
121
+ } = snapshotCertainty(input);
122
+ const valid = snapshot.purchases.filter(p => isValidSource(p, input));
123
+ const result = {};
124
+ for (const key of config.entitlementKeys) {
125
+ const granting = valid.filter(p => entitlementsFor(config, p.productKey).includes(key));
126
+ const sources = [...new Set(granting.map(p => p.productKey))];
127
+ result[key] = {
128
+ key,
129
+ // An entitlement stays valid while at least one source remains (FR-052).
130
+ status: undetermined ? 'unknown' : sources.length > 0 ? 'entitled' : 'not_entitled',
131
+ sources,
132
+ subscription: subscriptionDetailFor(granting, input),
133
+ lastSyncedAt: snapshot.lastSyncedAt,
134
+ isStale
135
+ };
136
+ }
137
+ return result;
138
+ }
139
+
140
+ /** The initial map, before anything is known. Every key starts at `unknown` (FR-047). */
141
+ export function initialEntitlements(config) {
142
+ const result = {};
143
+ for (const key of config.entitlementKeys) {
144
+ result[key] = {
145
+ key,
146
+ status: 'unknown',
147
+ sources: [],
148
+ lastSyncedAt: undefined,
149
+ isStale: false
150
+ };
151
+ }
152
+ return result;
153
+ }
154
+ /**
155
+ * Diffs two maps to produce change signals.
156
+ *
157
+ * Emitting from a diff rather than from grant call sites is what makes the
158
+ * exactly-once guarantees structural (FR-079): a successful subscription renewal
159
+ * changes no status, so it produces no event and cannot double-signal (FR-068);
160
+ * and an entitlement with three sources fires once on transition, not once per
161
+ * source.
162
+ */
163
+ export function diffEntitlements(previous, next) {
164
+ const changes = [];
165
+ for (const key of Object.keys(next)) {
166
+ const before = previous[key]?.status ?? 'unknown';
167
+ const after = next[key].status;
168
+ if (before !== after) {
169
+ changes.push({
170
+ key,
171
+ previous: before,
172
+ next: after,
173
+ sources: next[key].sources
174
+ });
175
+ }
176
+ }
177
+ return changes;
178
+ }
179
+ function sameEntitlement(a, b) {
180
+ return a.status === b.status && a.isStale === b.isStale && a.lastSyncedAt === b.lastSyncedAt && a.sources.length === b.sources.length && a.sources.every((source, index) => source === b.sources[index]) && shallowEqual(a.subscription, b.subscription);
181
+ }
182
+
183
+ /**
184
+ * `next`, with every entitlement that did not change replaced by the object it
185
+ * replaces, and `previous` itself when nothing changed (PERF-03, PAY-08). A hook
186
+ * selecting one entitlement then sees the same object and does not re-render.
187
+ */
188
+ export function shareUnchanged(previous, next) {
189
+ const keys = Object.keys(next);
190
+ let changed = keys.length !== Object.keys(previous).length;
191
+ const shared = {};
192
+ for (const key of keys) {
193
+ const before = previous[key];
194
+ const after = next[key];
195
+ if (before && sameEntitlement(before, after)) {
196
+ shared[key] = before;
197
+ } else {
198
+ shared[key] = after;
199
+ changed = true;
200
+ }
201
+ }
202
+ return changed ? shared : previous;
203
+ }
204
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["shallowEqual","entitlementsFor","deriveRenewalState","grantsUnderPolicy","hasExpired","isValidSource","purchase","input","state","validationState","productType","expiresAt","now","renewalState","willAutoRenew","reportsGraceAndHoldDistinctly","gracePolicy","config","holdPolicy","subscriptionDetailFor","purchases","subs","filter","p","length","undefined","furthest","reduce","best","candidate","bestAt","Number","MAX_SAFE_INTEGER","candidateAt","isCancelledButValid","snapshotCertainty","snapshot","hasSynced","isStale","lastSyncedAt","staleAfterMs","undetermined","aggregate","valid","result","key","entitlementKeys","granting","productKey","includes","sources","Set","map","status","subscription","initialEntitlements","diffEntitlements","previous","next","changes","Object","keys","before","after","push","sameEntitlement","a","b","every","source","index","shareUnchanged","changed","shared"],"sourceRoot":"../../../src","sources":["entitlements/aggregate.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Product ↔ entitlement indexing.
5
+ *
6
+ * The relation is many-to-many (FR-010): monthly, yearly, and lifetime products
7
+ * may all grant `no_ads`, and one bundle product may grant several entitlements.
8
+ *
9
+ * Both directions are indexed once at configure time. The reverse direction is
10
+ * what makes two requirements cheap on hot paths: naming which product currently
11
+ * grants an entitlement (FR-051), and keeping an entitlement valid while *any*
12
+ * source remains (FR-052).
13
+ */
14
+
15
+ /** Entitlements a product confers. Empty for an unknown key rather than throwing. */
16
+ export function entitlementsFor(config, productKey) {
17
+ return config.grants.get(productKey) ?? [];
18
+ }
19
+
20
+ /**
21
+ * Translates a store product id back to the app's own product key.
22
+ *
23
+ * Needed because store callbacks and `queryOwned` speak in store ids, while
24
+ * everything above the adapter speaks in product keys (FR-003). Returns
25
+ * `undefined` for an id absent from the catalog — which happens legitimately when
26
+ * a user owns something from a build whose catalog has since changed, so it must
27
+ * be handled rather than treated as impossible.
28
+ */
29
+ export function productKeyForStoreId(config, storeProductId) {
30
+ return config.byStoreId.get(storeProductId);
31
+ }
32
+ export function storeIdForProductKey(config, productKey) {
33
+ return config.entries.get(productKey)?.storeProductIds[config.platform];
34
+ }
35
+ //# sourceMappingURL=mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["entitlementsFor","config","productKey","grants","get","productKeyForStoreId","storeProductId","byStoreId","storeIdForProductKey","entries","storeProductIds","platform"],"sourceRoot":"../../../src","sources":["entitlements/mapping.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA,OAAO,SAASA,eAAeA,CAC9BC,MAAsB,EACtBC,UAAsB,EACM;EAC5B,OAAOD,MAAM,CAACE,MAAM,CAACC,GAAG,CAACF,UAAU,CAAC,IAAI,EAAE;AAC3C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,oBAAoBA,CACnCJ,MAAsB,EACtBK,cAAsB,EACG;EACzB,OAAOL,MAAM,CAACM,SAAS,CAACH,GAAG,CAACE,cAAc,CAAC;AAC5C;AAEA,OAAO,SAASE,oBAAoBA,CACnCP,MAAsB,EACtBC,UAAsB,EACD;EACrB,OAAOD,MAAM,CAACQ,OAAO,CAACL,GAAG,CAACF,UAAU,CAAC,EAAEQ,eAAe,CAACT,MAAM,CAACU,QAAQ,CAAC;AACxE","ignoreList":[]}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Grace and hold entitlement policy.
5
+ *
6
+ * This is a **business decision, not a technical constant** (FR-049), so it is
7
+ * configurable with documented defaults.
8
+ *
9
+ * ## The defaults, and why
10
+ *
11
+ * `gracePolicy: 'grant'` — a grace period means the store is still retrying a
12
+ * payment method that failed for reasons usually outside the user's control: an
13
+ * expired card, a bank decline, a temporary hold. Revoking immediately punishes a
14
+ * paying customer for a billing hiccup they may not know about yet.
15
+ *
16
+ * `holdPolicy: 'withhold'` — account hold means the store has given up retrying.
17
+ * The subscription is effectively unpaid, and continuing to serve paid features
18
+ * indefinitely is giving away the product.
19
+ *
20
+ * ## What Android can actually tell us
21
+ *
22
+ * Client-side Play Billing **cannot** separate grace from hold: a grace-period
23
+ * subscription is still returned as active, and one in account hold stops being
24
+ * returned at all — indistinguishable from expired, cancelled, or refunded.
25
+ *
26
+ * Fortunately the platform's own behavior matches the defaults above. Play keeps
27
+ * returning a grace-period purchase, so the entitlement holds. Play stops
28
+ * returning a held one, so it lapses at the next sync. **The default policy is
29
+ * therefore correct with no backend at all.**
30
+ *
31
+ * What is *not* achievable client-side is a non-default policy — withholding
32
+ * during grace, or granting during hold — because that needs the state the client
33
+ * cannot see. Such an app supplies it through the validation hook (FR-069). This
34
+ * limitation is documented rather than papered over (FR-058).
35
+ */
36
+
37
+ /**
38
+ * A subscription's renewal state as far as the package can honestly tell.
39
+ *
40
+ * `indeterminate` is not a failure — it is the truthful answer when the platform
41
+ * reports a subscription as active but cannot say whether that is a healthy
42
+ * renewal, a cancelled-but-still-paid period, or a grace period.
43
+ */
44
+
45
+ /**
46
+ * Derives the renewal state without inventing information.
47
+ *
48
+ * The temptation is to read `willAutoRenew === false` as "grace period", but that
49
+ * same value is what a deliberate cancellation looks like. Guessing would mean
50
+ * showing "there's a problem with your payment method" to someone who simply
51
+ * chose not to renew — so when the provider cannot distinguish, neither do we.
52
+ */
53
+ export function deriveRenewalState(facts) {
54
+ if (facts.reportsGraceAndHoldDistinctly && facts.providerRenewalState) {
55
+ switch (facts.providerRenewalState) {
56
+ case 'grace':
57
+ return 'grace';
58
+ case 'hold':
59
+ return 'hold';
60
+ case 'active':
61
+ return facts.willAutoRenew === false ? 'cancelled_valid' : 'active';
62
+ }
63
+ }
64
+ if (facts.willAutoRenew === false) {
65
+ // Still inside a paid period with auto-renew off. Genuinely ambiguous
66
+ // between "cancelled" and "in grace", so report the one that is certainly
67
+ // true — the period is paid for — and let the app decide how to present it.
68
+ return 'cancelled_valid';
69
+ }
70
+ if (facts.willAutoRenew === true) {
71
+ return 'active';
72
+ }
73
+ return 'indeterminate';
74
+ }
75
+
76
+ /**
77
+ * Whether a subscription in this state should confer its entitlement.
78
+ *
79
+ * `hold` reaching this function at all requires a provider that reports it,
80
+ * which Android does not. On Android a held subscription simply stops being
81
+ * returned, so it never becomes a source and the entitlement lapses — the same
82
+ * result the `withhold` default expresses.
83
+ */
84
+ export function grantsUnderPolicy(state, policy) {
85
+ switch (state) {
86
+ case 'active':
87
+ case 'cancelled_valid':
88
+ return true;
89
+ case 'grace':
90
+ return policy.gracePolicy === 'grant';
91
+ case 'hold':
92
+ return policy.holdPolicy === 'grant';
93
+ case 'indeterminate':
94
+ // The store is still reporting the purchase as owned. Withholding here
95
+ // would revoke from a paying user because of our own uncertainty.
96
+ return true;
97
+ }
98
+ }
99
+
100
+ /** True once a subscription's paid period has genuinely elapsed (FR-048). */
101
+ export function hasExpired(expiresAt, now) {
102
+ return expiresAt !== undefined && expiresAt <= now;
103
+ }
104
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["deriveRenewalState","facts","reportsGraceAndHoldDistinctly","providerRenewalState","willAutoRenew","grantsUnderPolicy","state","policy","gracePolicy","holdPolicy","hasExpired","expiresAt","now","undefined"],"sourceRoot":"../../../src","sources":["entitlements/policy.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,kBAAkBA,CAACC,KAAwB,EAAgB;EAC1E,IAAIA,KAAK,CAACC,6BAA6B,IAAID,KAAK,CAACE,oBAAoB,EAAE;IACtE,QAAQF,KAAK,CAACE,oBAAoB;MACjC,KAAK,OAAO;QACX,OAAO,OAAO;MACf,KAAK,MAAM;QACV,OAAO,MAAM;MACd,KAAK,QAAQ;QACZ,OAAOF,KAAK,CAACG,aAAa,KAAK,KAAK,GAAG,iBAAiB,GAAG,QAAQ;IACrE;EACD;EAEA,IAAIH,KAAK,CAACG,aAAa,KAAK,KAAK,EAAE;IAClC;IACA;IACA;IACA,OAAO,iBAAiB;EACzB;EAEA,IAAIH,KAAK,CAACG,aAAa,KAAK,IAAI,EAAE;IACjC,OAAO,QAAQ;EAChB;EAEA,OAAO,eAAe;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAACC,KAAmB,EAAEC,MAAyB,EAAW;EAC1F,QAAQD,KAAK;IACZ,KAAK,QAAQ;IACb,KAAK,iBAAiB;MACrB,OAAO,IAAI;IACZ,KAAK,OAAO;MACX,OAAOC,MAAM,CAACC,WAAW,KAAK,OAAO;IACtC,KAAK,MAAM;MACV,OAAOD,MAAM,CAACE,UAAU,KAAK,OAAO;IACrC,KAAK,eAAe;MACnB;MACA;MACA,OAAO,IAAI;EACb;AACD;;AAEA;AACA,OAAO,SAASC,UAAUA,CAACC,SAA6B,EAAEC,GAAW,EAAW;EAC/E,OAAOD,SAAS,KAAKE,SAAS,IAAIF,SAAS,IAAIC,GAAG;AACnD","ignoreList":[]}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * `@chipmobilesdk/rn-payment` — reusable in-app payment and entitlement
5
+ * capability for ChipMobileSdk-family React Native apps.
6
+ *
7
+ * This is the public entrypoint (LIB-003). Modules under `config/`, `core/`,
8
+ * `engine/`, `entitlements/`, `persistence/`, `adapter/`, `diagnostics/`, and
9
+ * `react/` are private; import them only through this file. The fake store lives
10
+ * behind `@chipmobilesdk/rn-payment/testing` so test doubles cannot reach a
11
+ * production bundle.
12
+ *
13
+ * Nothing exported here names Google, Play Billing, or `react-native-iap`
14
+ * (FR-002). `src/__tests__/public-api.test.ts` asserts that mechanically.
15
+ *
16
+ * The package owns **capability**: a safe, consistent way to sell, finalize,
17
+ * restore, and report entitlements. The consuming app owns **policy** — what is
18
+ * sold, at what price, on which screen, at which moment, what each entitlement
19
+ * unlocks, and how generous the grace policy is. There is no product identifier,
20
+ * no screen name, and no business rule in this package (FR-016).
21
+ *
22
+ * The one output that matters most is the **entitlement key**: an app-chosen key
23
+ * such as `no_ads`. Business logic asks about entitlement keys and never about
24
+ * store product identifiers, product types, or which store sold the thing.
25
+ */
26
+
27
+ // --- Configuration and catalog ---------------------------------------------
28
+
29
+ // --- Policy defaults and bounds --------------------------------------------
30
+ // Exported so a consumer can read the values it is bound by rather than
31
+ // discovering them from a timeout in production.
32
+ export { BACKOFF_ATTEMPT_BOUNDS, BACKOFF_MAX_DELAY_BOUNDS, CONNECT_TIMEOUT_BOUNDS, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_FINALIZE_ATTEMPT_TIMEOUT_MS, DEFAULT_FINALIZE_BACKOFF, DEFAULT_FOREGROUND_SYNC_MIN_INTERVAL_MS, DEFAULT_PRODUCT_CACHE_TTL_MS, DEFAULT_PRODUCT_QUERY_TIMEOUT_MS, DEFAULT_PURCHASE_LAUNCH_TIMEOUT_MS, DEFAULT_RECONNECT_BACKOFF, DEFAULT_STALE_AFTER_MS, DEFAULT_SYNC_TIMEOUT_MS, FINALIZE_ATTEMPT_TIMEOUT_BOUNDS, FOREGROUND_SYNC_MIN_INTERVAL_BOUNDS, PRODUCT_CACHE_TTL_BOUNDS, PRODUCT_QUERY_TIMEOUT_BOUNDS, PURCHASE_LAUNCH_TIMEOUT_BOUNDS, STALE_AFTER_BOUNDS, SYNC_TIMEOUT_BOUNDS } from "./core/timers.js";
33
+
34
+ // --- Products, pricing, and offers -----------------------------------------
35
+
36
+ // --- Subscriptions ---------------------------------------------------------
37
+
38
+ // --- Entitlements ----------------------------------------------------------
39
+
40
+ // --- Store provider --------------------------------------------------------
41
+ // Named for the concept, not the store: the same call returns the StoreKit
42
+ // adapter once iOS exists, so no consumer line changes (FR-004, FR-007). On a
43
+ // platform with no adapter it returns a stub that reports `unavailable` rather
44
+ // than throwing, so a host app still starts and runs (FR-021, FR-023).
45
+ export { createStoreProvider } from "./adapter/createStoreProvider.js";
46
+ // --- Engine ----------------------------------------------------------------
47
+ export { createEngine } from "./engine/engine.js";
48
+ export { syncOnForeground } from "./engine/foreground.js";
49
+
50
+ // --- React -----------------------------------------------------------------
51
+ export { PaymentProvider, usePaymentEngine } from "./react/PaymentProvider.js";
52
+ export { useEntitlement, useEntitlements, usePaymentStatus, usePendingPurchases, useProducts, usePurchase, useSync } from "./react/hooks.js";
53
+ // --- Diagnostics -----------------------------------------------------------
54
+ export { PaymentConfigError, PaymentError, PAYMENT_ERROR_CODES } from "./diagnostics/errors.js";
55
+ // --- Localizable copy ------------------------------------------------------
56
+ // Keys and English defaults only. The package takes no i18n dependency and
57
+ // resolves nothing itself; apps map these through their own i18n (FR-085).
58
+ export { DEFAULT_DEVELOPER_MESSAGES, DEFAULT_MESSAGES, paymentMessages, DEFAULT_USER_MESSAGES, DEVELOPER_MESSAGE_KEYS, USER_MESSAGE_KEYS, isUserMessageKey } from "./diagnostics/messageKeys.js";
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BACKOFF_ATTEMPT_BOUNDS","BACKOFF_MAX_DELAY_BOUNDS","CONNECT_TIMEOUT_BOUNDS","DEFAULT_CONNECT_TIMEOUT_MS","DEFAULT_FINALIZE_ATTEMPT_TIMEOUT_MS","DEFAULT_FINALIZE_BACKOFF","DEFAULT_FOREGROUND_SYNC_MIN_INTERVAL_MS","DEFAULT_PRODUCT_CACHE_TTL_MS","DEFAULT_PRODUCT_QUERY_TIMEOUT_MS","DEFAULT_PURCHASE_LAUNCH_TIMEOUT_MS","DEFAULT_RECONNECT_BACKOFF","DEFAULT_STALE_AFTER_MS","DEFAULT_SYNC_TIMEOUT_MS","FINALIZE_ATTEMPT_TIMEOUT_BOUNDS","FOREGROUND_SYNC_MIN_INTERVAL_BOUNDS","PRODUCT_CACHE_TTL_BOUNDS","PRODUCT_QUERY_TIMEOUT_BOUNDS","PURCHASE_LAUNCH_TIMEOUT_BOUNDS","STALE_AFTER_BOUNDS","SYNC_TIMEOUT_BOUNDS","createStoreProvider","createEngine","syncOnForeground","PaymentProvider","usePaymentEngine","useEntitlement","useEntitlements","usePaymentStatus","usePendingPurchases","useProducts","usePurchase","useSync","PaymentConfigError","PaymentError","PAYMENT_ERROR_CODES","DEFAULT_DEVELOPER_MESSAGES","DEFAULT_MESSAGES","paymentMessages","DEFAULT_USER_MESSAGES","DEVELOPER_MESSAGE_KEYS","USER_MESSAGE_KEYS","isUserMessageKey"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAiCA;AACA;AACA;AACA,SACCA,sBAAsB,EACtBC,wBAAwB,EACxBC,sBAAsB,EACtBC,0BAA0B,EAC1BC,mCAAmC,EACnCC,wBAAwB,EACxBC,uCAAuC,EACvCC,4BAA4B,EAC5BC,gCAAgC,EAChCC,kCAAkC,EAClCC,yBAAyB,EACzBC,sBAAsB,EACtBC,uBAAuB,EACvBC,+BAA+B,EAC/BC,mCAAmC,EACnCC,wBAAwB,EACxBC,4BAA4B,EAC5BC,8BAA8B,EAC9BC,kBAAkB,EAClBC,mBAAmB,QACb,kBAAe;;AAEtB;;AASA;;AAGA;;AASA;AACA;AACA;AACA;AACA;AACA,SAASC,mBAAmB,QAAQ,kCAA+B;AAGnE;AACA,SAASC,YAAY,QAAQ,oBAAiB;AAS9C,SAASC,gBAAgB,QAAQ,wBAAqB;;AAEtD;AACA,SAASC,eAAe,EAAEC,gBAAgB,QAAQ,4BAAyB;AAE3E,SACCC,cAAc,EACdC,eAAe,EACfC,gBAAgB,EAChBC,mBAAmB,EACnBC,WAAW,EACXC,WAAW,EACXC,OAAO,QACD,kBAAe;AAGtB;AACA,SAASC,kBAAkB,EAAEC,YAAY,EAAEC,mBAAmB,QAAQ,yBAAsB;AAS5F;AACA;AACA;AACA,SACCC,0BAA0B,EAC1BC,gBAAgB,EAChBC,eAAe,EACfC,qBAAqB,EACrBC,sBAAsB,EACtBC,iBAAiB,EACjBC,gBAAgB,QACV,8BAA2B","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * MMKV-backed snapshot store.
5
+ *
6
+ * Every MMKV import is confined to this file, so the rest of the package stays
7
+ * testable without a native module.
8
+ *
9
+ * MMKV is chosen because it is **synchronous**, which is what lets
10
+ * `getEntitlement` be an in-memory read with no I/O on render paths (PERF-001).
11
+ * An async store would force either an async entitlement read or a hidden
12
+ * hydration race on every call.
13
+ *
14
+ * Records are partitioned by cache-scope token (FR-057a). The token is a
15
+ * partition key and nothing more: never interpreted, never transmitted, never
16
+ * attached to a transaction.
17
+ */
18
+
19
+ import { createMemoryKeyValue, lazyPeer, openDurable } from '@chipmobilesdk/rn-core';
20
+ import { emptySnapshot, migrateSnapshot } from "./snapshot.js";
21
+ const INSTANCE_ID = 'chipmobilesdk.payment';
22
+ const KEY_PREFIX = 'snapshot';
23
+ const mmkv = lazyPeer('react-native-mmkv', () => {
24
+ // Inside `try`, so Metro bundles an app that leaves this optional peer out.
25
+ try {
26
+ return require('react-native-mmkv');
27
+ } catch (cause) {
28
+ throw cause;
29
+ }
30
+ });
31
+ function scopeKey(scopeToken) {
32
+ // An explicit sentinel rather than an empty segment, so the unscoped record
33
+ // can never collide with a scope whose token happens to be empty.
34
+ return `${KEY_PREFIX}:${scopeToken ?? '__default__'}`;
35
+ }
36
+
37
+ /**
38
+ * Opens the MMKV instance through v4's `createMMKV`.
39
+ *
40
+ * Up to 0.2.0 this called `new MMKV()`, the v3 constructor. In v4 — the only
41
+ * major the peer range allows — `MMKV` is a type, not a value, so the call threw
42
+ * and the store fell back to memory on every device: entitlements read `unknown`
43
+ * after each cold start, and a pending purchase was forgotten after an app kill.
44
+ * Tests could not see it, because the test double still exported a v3 class.
45
+ */
46
+ function resolveBacking() {
47
+ // rn-core's port: MMKV when it opens, otherwise memory with `durable: false`.
48
+ const port = openDurable(() => mmkv.require(peer => new Error(`${peer} is not installed`)).createMMKV({
49
+ id: INSTANCE_ID
50
+ }));
51
+ return {
52
+ backing: {
53
+ getString: key => port.getString(key),
54
+ set: (key, value) => port.set(key, value),
55
+ remove: key => port.remove(key),
56
+ clearAll: () => port.clearAll(),
57
+ getAllKeys: () => port.keys()
58
+ },
59
+ durable: port.durable
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Creates the store.
65
+ *
66
+ * The memory fallback is a **documented degradation**, not a silent one: without
67
+ * MMKV the snapshot does not survive a cold start, so entitlements read `unknown`
68
+ * until the first sync. That is safe by construction — `unknown`, never
69
+ * `not_entitled` (FR-047) — and FR-059's startup sync repairs it. `isDurable()`
70
+ * lets the engine warn, so the condition is visible rather than mysterious.
71
+ */
72
+ export function createSnapshotStore(injected) {
73
+ const {
74
+ backing,
75
+ durable
76
+ } = injected ?? resolveBacking();
77
+ return {
78
+ load(scopeToken) {
79
+ const raw = backing.getString(scopeKey(scopeToken));
80
+ if (raw === undefined) {
81
+ return emptySnapshot(scopeToken);
82
+ }
83
+ let parsed;
84
+ try {
85
+ parsed = JSON.parse(raw);
86
+ } catch {
87
+ // Corrupt JSON is discarded rather than repaired: the store is the
88
+ // authoritative source and the next sync rebuilds from it.
89
+ return emptySnapshot(scopeToken);
90
+ }
91
+ const outcome = migrateSnapshot(parsed);
92
+ if (!outcome.ok) {
93
+ return emptySnapshot(scopeToken);
94
+ }
95
+
96
+ // A record whose stored token disagrees with the requested scope must not
97
+ // be served: that is precisely the account-switch inheritance FR-057a
98
+ // exists to prevent.
99
+ if (outcome.snapshot.scopeToken !== scopeToken) {
100
+ return emptySnapshot(scopeToken);
101
+ }
102
+ return outcome.snapshot;
103
+ },
104
+ save(snapshot) {
105
+ try {
106
+ backing.set(scopeKey(snapshot.scopeToken), JSON.stringify(snapshot));
107
+ return true;
108
+ } catch {
109
+ // A failed write must never take down a purchase flow. The in-memory
110
+ // state stays correct for this session and the next sync re-derives it;
111
+ // the engine reports it (PAY-13).
112
+ return false;
113
+ }
114
+ },
115
+ clearAll() {
116
+ try {
117
+ for (const key of backing.getAllKeys()) {
118
+ if (key.startsWith(`${KEY_PREFIX}:`)) {
119
+ backing.remove(key);
120
+ }
121
+ }
122
+ } catch {
123
+ // Best effort; a failure here must not throw into a logout flow.
124
+ }
125
+ },
126
+ isDurable: () => durable
127
+ };
128
+ }
129
+
130
+ /** Test seam for driving the store without the native module. */
131
+ export function createMemorySnapshotStore() {
132
+ const memory = createMemoryKeyValue();
133
+ return createSnapshotStore({
134
+ backing: {
135
+ getString: key => memory.getString(key),
136
+ set: (key, value) => memory.set(key, value),
137
+ remove: key => memory.remove(key),
138
+ clearAll: () => memory.clearAll(),
139
+ getAllKeys: () => memory.keys()
140
+ },
141
+ durable: false
142
+ });
143
+ }
144
+ //# sourceMappingURL=mmkv-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createMemoryKeyValue","lazyPeer","openDurable","emptySnapshot","migrateSnapshot","INSTANCE_ID","KEY_PREFIX","mmkv","require","cause","scopeKey","scopeToken","resolveBacking","port","peer","Error","createMMKV","id","backing","getString","key","set","value","remove","clearAll","getAllKeys","keys","durable","createSnapshotStore","injected","load","raw","undefined","parsed","JSON","parse","outcome","ok","snapshot","save","stringify","startsWith","isDurable","createMemorySnapshotStore","memory"],"sourceRoot":"../../../src","sources":["persistence/mmkv-store.ts"],"mappings":"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","ignoreList":[]}