@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 +23 -0
- package/package.json +1 -1
- package/skills/sdk-rn-payment/SKILL.md +1 -1
- package/src/persistence/mmkv-store.ts +16 -8
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
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
69
|
-
|
|
76
|
+
const { createMMKV } = require('react-native-mmkv') as {
|
|
77
|
+
createMMKV: (config?: { id?: string }) => MmkvLike;
|
|
70
78
|
};
|
|
71
|
-
return { backing:
|
|
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.
|
|
143
|
+
backing.remove(key);
|
|
136
144
|
}
|
|
137
145
|
}
|
|
138
146
|
} catch {
|