@chipmobilesdk/rn-payment 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,29 @@ product keys, error codes, event names, state values, message keys, and the
7
7
  public API shape are this package's contract: renaming any of them is a breaking
8
8
  change.
9
9
 
10
+ ## [0.2.1] — 2026-10-12
11
+
12
+ Patch release. **Upgrade before shipping**: on a device, `0.2.0` and earlier persisted
13
+ nothing.
14
+
15
+ ### Fixed
16
+
17
+ - **The purchase snapshot never reached the device's storage.** The store opened MMKV
18
+ with `new MMKV()`, the react-native-mmkv **v3** constructor. In v4 — the only major the
19
+ peer range (`>=4.0.0`) allows — `MMKV` is a type, not a value, so the call threw and the
20
+ store fell back to memory on every device. Consequences: entitlements read `unknown`
21
+ after every cold start until a sync, an owner with no connection stayed `unknown`, and a
22
+ pending purchase was forgotten after an app kill. The store now uses v4's `createMMKV`
23
+ and `remove`. Found on an emulator: the app's `files/mmkv` held no
24
+ `chipmobilesdk.payment` instance.
25
+ - The engine did report the fallback, as a `config_warning` ("Local storage
26
+ unavailable"), but nothing in the tests could trigger it: the repository's test double
27
+ exported a v3 `MMKV` class. The double now mirrors v4 exactly, and the persistence suite
28
+ fails against the old code.
29
+
30
+ No API, storage format or behaviour change otherwise. Records written by a working
31
+ install are read as before; there were none from `0.2.0` on a device to migrate.
32
+
10
33
  ## [0.2.0] — 2026-10-12
11
34
 
12
35
  Additive minor release closing one gap that surfaced when `0.1.0` met an app that
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chipmobilesdk/rn-payment",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "description": "Reusable in-app payment and entitlement capability for ChipMobileSdk React Native apps",
@@ -3,7 +3,7 @@ name: sdk-rn-payment
3
3
  description: "In-app payments via @chipmobilesdk/rn-payment: Play Billing one-time/consumable/subscription behind a store-neutral contract, entitlement keys with a required unknown state, pending purchases visible across sessions, guaranteed transaction finalization, per-environment production-transaction blocking. Use when selling a feature, gating on an entitlement, showing a payment still pending after a restart, debugging a purchase that returns environment_blocked or an entitlement stuck at unknown, mapping Play products to entitlement keys, or answering a Data safety question about purchases."
4
4
  metadata:
5
5
  package: "@chipmobilesdk/rn-payment"
6
- packageVersion: "0.2.0"
6
+ packageVersion: "0.2.1"
7
7
  user-invocable: true
8
8
  disable-model-invocation: false
9
9
  ---
@@ -23,10 +23,11 @@ import {
23
23
  const INSTANCE_ID = 'chipmobilesdk.payment';
24
24
  const KEY_PREFIX = 'snapshot';
25
25
 
26
+ /** The slice of a react-native-mmkv v4 instance this store uses (v4 names). */
26
27
  interface MmkvLike {
27
28
  getString(key: string): string | undefined;
28
29
  set(key: string, value: string): void;
29
- delete(key: string): void;
30
+ remove(key: string): unknown;
30
31
  clearAll(): void;
31
32
  getAllKeys(): string[];
32
33
  }
@@ -54,21 +55,28 @@ function createMemoryBacking(): MmkvLike {
54
55
  set(key, value) {
55
56
  map.set(key, value);
56
57
  },
57
- delete(key) {
58
- map.delete(key);
59
- },
58
+ remove: key => map.delete(key),
60
59
  clearAll: () => map.clear(),
61
60
  getAllKeys: () => [...map.keys()],
62
61
  };
63
62
  }
64
63
 
64
+ /**
65
+ * Opens the MMKV instance through v4's `createMMKV`.
66
+ *
67
+ * Up to 0.2.0 this called `new MMKV()`, the v3 constructor. In v4 — the only
68
+ * major the peer range allows — `MMKV` is a type, not a value, so the call threw
69
+ * and the store fell back to memory on every device: entitlements read `unknown`
70
+ * after each cold start, and a pending purchase was forgotten after an app kill.
71
+ * Tests could not see it, because the test double still exported a v3 class.
72
+ */
65
73
  function resolveBacking(): { backing: MmkvLike; durable: boolean } {
66
74
  try {
67
75
  // Required lazily so the package loads where the native module is absent.
68
- const mod = require('react-native-mmkv') as {
69
- MMKV: new (config?: { id?: string }) => MmkvLike;
76
+ const { createMMKV } = require('react-native-mmkv') as {
77
+ createMMKV: (config?: { id?: string }) => MmkvLike;
70
78
  };
71
- return { backing: new mod.MMKV({ id: INSTANCE_ID }), durable: true };
79
+ return { backing: createMMKV({ id: INSTANCE_ID }), durable: true };
72
80
  } catch {
73
81
  return { backing: createMemoryBacking(), durable: false };
74
82
  }
@@ -132,7 +140,7 @@ export function createSnapshotStore(
132
140
  try {
133
141
  for (const key of backing.getAllKeys()) {
134
142
  if (key.startsWith(`${KEY_PREFIX}:`)) {
135
- backing.delete(key);
143
+ backing.remove(key);
136
144
  }
137
145
  }
138
146
  } catch {