@optimystic/db-p2p-storage-rn 0.13.0 → 0.13.5

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 (45) hide show
  1. package/dist/src/identity.d.ts +18 -0
  2. package/dist/src/identity.d.ts.map +1 -0
  3. package/dist/src/identity.js +27 -0
  4. package/dist/src/identity.js.map +1 -0
  5. package/dist/src/index.d.ts +4 -2
  6. package/dist/src/index.d.ts.map +1 -1
  7. package/dist/src/index.js +4 -2
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/keys.d.ts +55 -0
  10. package/dist/src/keys.d.ts.map +1 -0
  11. package/dist/src/keys.js +126 -0
  12. package/dist/src/keys.js.map +1 -0
  13. package/dist/src/leveldb-kv-store.d.ts +21 -0
  14. package/dist/src/leveldb-kv-store.d.ts.map +1 -0
  15. package/dist/src/leveldb-kv-store.js +39 -0
  16. package/dist/src/leveldb-kv-store.js.map +1 -0
  17. package/dist/src/leveldb-like.d.ts +68 -0
  18. package/dist/src/leveldb-like.d.ts.map +1 -0
  19. package/dist/src/leveldb-like.js +34 -0
  20. package/dist/src/leveldb-like.js.map +1 -0
  21. package/dist/src/{mmkv-storage.d.ts → leveldb-storage.d.ts} +19 -32
  22. package/dist/src/leveldb-storage.d.ts.map +1 -0
  23. package/dist/src/leveldb-storage.js +138 -0
  24. package/dist/src/leveldb-storage.js.map +1 -0
  25. package/dist/src/rn-opener.d.ts +73 -0
  26. package/dist/src/rn-opener.d.ts.map +1 -0
  27. package/dist/src/rn-opener.js +200 -0
  28. package/dist/src/rn-opener.js.map +1 -0
  29. package/package.json +13 -7
  30. package/src/identity.ts +33 -0
  31. package/src/index.ts +14 -3
  32. package/src/keys.ts +139 -0
  33. package/src/leveldb-kv-store.ts +43 -0
  34. package/src/leveldb-like.ts +84 -0
  35. package/src/leveldb-storage.ts +155 -0
  36. package/src/rn-opener.ts +274 -0
  37. package/dist/src/mmkv-kv-store.d.ts +0 -13
  38. package/dist/src/mmkv-kv-store.d.ts.map +0 -1
  39. package/dist/src/mmkv-kv-store.js +0 -25
  40. package/dist/src/mmkv-kv-store.js.map +0 -1
  41. package/dist/src/mmkv-storage.d.ts.map +0 -1
  42. package/dist/src/mmkv-storage.js +0 -138
  43. package/dist/src/mmkv-storage.js.map +0 -1
  44. package/src/mmkv-kv-store.ts +0 -26
  45. package/src/mmkv-storage.ts +0 -181
@@ -0,0 +1,138 @@
1
+ import { drain } from './leveldb-like.js';
2
+ import { TAG_PENDING, actionIdFromKey, blockEnvelopeRange, materializedKey, metadataKey, pendingKey, revisionFromKey, revisionKey, transactionKey, } from './keys.js';
3
+ import { createLogger } from './logger.js';
4
+ const log = createLogger('storage:leveldb');
5
+ const textEncoder = new TextEncoder();
6
+ const textDecoder = new TextDecoder();
7
+ /**
8
+ * LevelDB-backed `IRawStorage` implementation for React Native peers.
9
+ *
10
+ * All data lives in a single LevelDB database; per-store partitioning is by a
11
+ * leading tag byte (see `./keys.ts`). `listRevisions` and
12
+ * `listPendingTransactions` use range iterators with explicit bounds, drained
13
+ * into an array before yielding (same rationale as the IndexedDB / SQLite
14
+ * backends — a native iterator must not stay open across consumer awaits).
15
+ *
16
+ * `promotePendingTransaction` runs as a single `WriteBatch`, making the
17
+ * pending → committed move atomic against crashes.
18
+ */
19
+ export class LevelDBRawStorage {
20
+ db;
21
+ constructor(db) {
22
+ this.db = db;
23
+ }
24
+ async getMetadata(blockId) {
25
+ const bytes = await this.db.get(metadataKey(blockId));
26
+ if (!bytes)
27
+ return undefined;
28
+ return JSON.parse(textDecoder.decode(bytes));
29
+ }
30
+ async saveMetadata(blockId, metadata) {
31
+ await this.db.put(metadataKey(blockId), textEncoder.encode(JSON.stringify(metadata)));
32
+ }
33
+ async getRevision(blockId, rev) {
34
+ const bytes = await this.db.get(revisionKey(blockId, rev));
35
+ if (!bytes)
36
+ return undefined;
37
+ return textDecoder.decode(bytes);
38
+ }
39
+ async saveRevision(blockId, rev, actionId) {
40
+ await this.db.put(revisionKey(blockId, rev), textEncoder.encode(actionId));
41
+ }
42
+ async *listRevisions(blockId, startRev, endRev) {
43
+ const ascending = startRev <= endRev;
44
+ const lo = ascending ? startRev : endRev;
45
+ const hi = ascending ? endRev : startRev;
46
+ // `revisionKey(blockId, hi)` is exactly the inclusive upper bound; LevelDB
47
+ // uses exclusive `lt`, so request `lte` via `lt = key(hi)+0x01` would
48
+ // require an extra byte. Easier: use `lt = revisionKey(blockId, hi+1)`.
49
+ const gte = revisionKey(blockId, lo);
50
+ const lt = revisionKey(blockId, hi + 1);
51
+ const entries = await drain(this.db.iterator({ gte, lt, reverse: !ascending }));
52
+ for (const [key, value] of entries) {
53
+ yield {
54
+ rev: revisionFromKey(key),
55
+ actionId: textDecoder.decode(value),
56
+ };
57
+ }
58
+ }
59
+ async getPendingTransaction(blockId, actionId) {
60
+ const bytes = await this.db.get(pendingKey(blockId, actionId));
61
+ if (!bytes)
62
+ return undefined;
63
+ return JSON.parse(textDecoder.decode(bytes));
64
+ }
65
+ async savePendingTransaction(blockId, actionId, transform) {
66
+ await this.db.put(pendingKey(blockId, actionId), textEncoder.encode(JSON.stringify(transform)));
67
+ }
68
+ async deletePendingTransaction(blockId, actionId) {
69
+ await this.db.delete(pendingKey(blockId, actionId));
70
+ }
71
+ async *listPendingTransactions(blockId) {
72
+ const range = blockEnvelopeRange(TAG_PENDING, blockId);
73
+ const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
74
+ for (const [key] of entries) {
75
+ yield actionIdFromKey(key, blockId);
76
+ }
77
+ }
78
+ async getTransaction(blockId, actionId) {
79
+ const bytes = await this.db.get(transactionKey(blockId, actionId));
80
+ if (!bytes)
81
+ return undefined;
82
+ return JSON.parse(textDecoder.decode(bytes));
83
+ }
84
+ async saveTransaction(blockId, actionId, transform) {
85
+ await this.db.put(transactionKey(blockId, actionId), textEncoder.encode(JSON.stringify(transform)));
86
+ }
87
+ async getMaterializedBlock(blockId, actionId) {
88
+ const bytes = await this.db.get(materializedKey(blockId, actionId));
89
+ if (!bytes)
90
+ return undefined;
91
+ return JSON.parse(textDecoder.decode(bytes));
92
+ }
93
+ async saveMaterializedBlock(blockId, actionId, block) {
94
+ const key = materializedKey(blockId, actionId);
95
+ if (block) {
96
+ await this.db.put(key, textEncoder.encode(JSON.stringify(block)));
97
+ }
98
+ else {
99
+ await this.db.delete(key);
100
+ }
101
+ }
102
+ async getApproximateBytesUsed() {
103
+ try {
104
+ let total = 0;
105
+ const iter = this.db.iterator();
106
+ try {
107
+ while (true) {
108
+ const entry = await iter.next();
109
+ if (!entry)
110
+ break;
111
+ total += entry[0].byteLength + entry[1].byteLength;
112
+ }
113
+ }
114
+ finally {
115
+ await iter.close();
116
+ }
117
+ return total;
118
+ }
119
+ catch (err) {
120
+ log('getApproximateBytesUsed iterator failed: %o', err);
121
+ return 0;
122
+ }
123
+ }
124
+ async promotePendingTransaction(blockId, actionId) {
125
+ const pKey = pendingKey(blockId, actionId);
126
+ const value = await this.db.get(pKey);
127
+ if (!value) {
128
+ throw new Error(`Pending action ${actionId} not found for block ${blockId}`);
129
+ }
130
+ const tKey = transactionKey(blockId, actionId);
131
+ await this.db
132
+ .batch()
133
+ .put(tKey, value)
134
+ .delete(pKey)
135
+ .write();
136
+ }
137
+ }
138
+ //# sourceMappingURL=leveldb-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leveldb-storage.js","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { LevelDBLike } from './leveldb-like.js';
2
+ /**
3
+ * Minimal subset of `rn-leveldb`'s `LevelDB` we depend on. Re-declared
4
+ * locally so this module's *types* don't pull in the plugin's declarations
5
+ * (the plugin is a peer dependency that may not be installed at typecheck
6
+ * time on non-RN consumers).
7
+ *
8
+ * Matches the shape used by `@quereus/plugin-react-native-leveldb` so apps
9
+ * embedding both Optimystic and Quereus can share one native module.
10
+ */
11
+ export interface RNLevelDBNative {
12
+ put(key: ArrayBuffer | string, value: ArrayBuffer | string): void;
13
+ getBuf(key: ArrayBuffer | string): ArrayBuffer | null;
14
+ delete(key: ArrayBuffer | string): void;
15
+ close(): void;
16
+ newIterator(): RNLevelDBIteratorNative;
17
+ write(batch: RNLevelDBWriteBatchNative): void;
18
+ }
19
+ export interface RNLevelDBWriteBatchNative {
20
+ put(key: ArrayBuffer | string, value: ArrayBuffer | string): void;
21
+ delete(key: ArrayBuffer | string): void;
22
+ close(): void;
23
+ }
24
+ export interface RNLevelDBIteratorNative {
25
+ valid(): boolean;
26
+ seek(target: ArrayBuffer | string): RNLevelDBIteratorNative;
27
+ seekToFirst(): RNLevelDBIteratorNative;
28
+ seekLast(): RNLevelDBIteratorNative;
29
+ next(): void;
30
+ prev(): void;
31
+ keyBuf(): ArrayBuffer;
32
+ valueBuf(): ArrayBuffer;
33
+ close(): void;
34
+ }
35
+ /** Constructor type for `rn-leveldb`'s `LevelDBWriteBatch`. */
36
+ export type RNLevelDBWriteBatchCtor = new () => RNLevelDBWriteBatchNative;
37
+ /**
38
+ * Open function shape — typically `(name, createIfMissing, errorIfExists) =>
39
+ * new LevelDB(name, createIfMissing, errorIfExists)`. The caller controls
40
+ * how `rn-leveldb` is imported so this package never directly imports it,
41
+ * which keeps the unit tests runnable under Node.
42
+ */
43
+ export type RNLevelDBOpenFn = (name: string, createIfMissing: boolean, errorIfExists: boolean) => RNLevelDBNative;
44
+ export declare const DEFAULT_DB_NAME = "optimystic";
45
+ export interface OpenOptimysticRNDbOptions {
46
+ /** `rn-leveldb`'s `LevelDB` constructor wrapped as an open function. */
47
+ openFn: RNLevelDBOpenFn;
48
+ /** `rn-leveldb`'s `LevelDBWriteBatch` constructor. */
49
+ WriteBatch: RNLevelDBWriteBatchCtor;
50
+ /** Database name (LevelDB directory). Default `optimystic`. */
51
+ name?: string;
52
+ /** Whether to create the database if it doesn't exist. Default `true`. */
53
+ createIfMissing?: boolean;
54
+ /** Whether to error if the database already exists. Default `false`. */
55
+ errorIfExists?: boolean;
56
+ }
57
+ /**
58
+ * Opens (creating if needed) the Optimystic LevelDB database used by
59
+ * `LevelDBRawStorage`, `LevelDBKVStore`, and `loadOrCreateRNPeerKey`.
60
+ *
61
+ * The caller passes the `rn-leveldb` constructors in; this keeps the
62
+ * native module out of the package's static import graph. Apps embedding
63
+ * both Optimystic and Quereus can pass the same constructors to both —
64
+ * one native module, one Podfile entry.
65
+ */
66
+ export declare function openOptimysticRNDb(options: OpenOptimysticRNDbOptions): LevelDBLike;
67
+ /**
68
+ * Wraps an already-open `rn-leveldb` `LevelDB` instance to satisfy the
69
+ * `LevelDBLike` interface. Exported for callers that already hold a handle
70
+ * (rare — usually `openOptimysticRNDb` is the right entry point).
71
+ */
72
+ export declare function wrapRNLevelDB(native: RNLevelDBNative, WriteBatch: RNLevelDBWriteBatchCtor): LevelDBLike;
73
+ //# sourceMappingURL=rn-opener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rn-opener.d.ts","sourceRoot":"","sources":["../../src/rn-opener.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGX,WAAW,EAEX,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC/B,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;IAClE,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACtD,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;IACxC,KAAK,IAAI,IAAI,CAAC;IACd,WAAW,IAAI,uBAAuB,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,yBAAyB;IACzC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;IAClE,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;IACxC,KAAK,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACvC,KAAK,IAAI,OAAO,CAAC;IACjB,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,uBAAuB,CAAC;IAC5D,WAAW,IAAI,uBAAuB,CAAC;IACvC,QAAQ,IAAI,uBAAuB,CAAC;IACpC,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,IAAI,WAAW,CAAC;IACtB,QAAQ,IAAI,WAAW,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACd;AAED,+DAA+D;AAC/D,MAAM,MAAM,uBAAuB,GAAG,UAAU,yBAAyB,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,KAAK,eAAe,CAAC;AAElH,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C,MAAM,WAAW,yBAAyB;IACzC,wEAAwE;IACxE,MAAM,EAAE,eAAe,CAAC;IACxB,sDAAsD;IACtD,UAAU,EAAE,uBAAuB,CAAC;IACpC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wEAAwE;IACxE,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,WAAW,CAOlF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,uBAAuB,GAAG,WAAW,CAEvG"}
@@ -0,0 +1,200 @@
1
+ export const DEFAULT_DB_NAME = 'optimystic';
2
+ /**
3
+ * Opens (creating if needed) the Optimystic LevelDB database used by
4
+ * `LevelDBRawStorage`, `LevelDBKVStore`, and `loadOrCreateRNPeerKey`.
5
+ *
6
+ * The caller passes the `rn-leveldb` constructors in; this keeps the
7
+ * native module out of the package's static import graph. Apps embedding
8
+ * both Optimystic and Quereus can pass the same constructors to both —
9
+ * one native module, one Podfile entry.
10
+ */
11
+ export function openOptimysticRNDb(options) {
12
+ const native = options.openFn(options.name ?? DEFAULT_DB_NAME, options.createIfMissing ?? true, options.errorIfExists ?? false);
13
+ return wrapRNLevelDB(native, options.WriteBatch);
14
+ }
15
+ /**
16
+ * Wraps an already-open `rn-leveldb` `LevelDB` instance to satisfy the
17
+ * `LevelDBLike` interface. Exported for callers that already hold a handle
18
+ * (rare — usually `openOptimysticRNDb` is the right entry point).
19
+ */
20
+ export function wrapRNLevelDB(native, WriteBatch) {
21
+ return new RNLevelDBAdapter(native, WriteBatch);
22
+ }
23
+ class RNLevelDBAdapter {
24
+ native;
25
+ WriteBatch;
26
+ constructor(native, WriteBatch) {
27
+ this.native = native;
28
+ this.WriteBatch = WriteBatch;
29
+ }
30
+ async get(key) {
31
+ const result = this.native.getBuf(toArrayBuffer(key));
32
+ return result === null ? undefined : new Uint8Array(result);
33
+ }
34
+ async put(key, value) {
35
+ this.native.put(toArrayBuffer(key), toArrayBuffer(value));
36
+ }
37
+ async delete(key) {
38
+ this.native.delete(toArrayBuffer(key));
39
+ }
40
+ batch() {
41
+ return new RNLevelDBWriteBatchAdapter(this.native, new this.WriteBatch());
42
+ }
43
+ iterator(options = {}) {
44
+ return new RNLevelDBIteratorAdapter(this.native.newIterator(), options);
45
+ }
46
+ async close() {
47
+ this.native.close();
48
+ }
49
+ }
50
+ class RNLevelDBWriteBatchAdapter {
51
+ native;
52
+ batch;
53
+ constructor(native, batch) {
54
+ this.native = native;
55
+ this.batch = batch;
56
+ }
57
+ put(key, value) {
58
+ this.batch.put(toArrayBuffer(key), toArrayBuffer(value));
59
+ return this;
60
+ }
61
+ delete(key) {
62
+ this.batch.delete(toArrayBuffer(key));
63
+ return this;
64
+ }
65
+ async write() {
66
+ try {
67
+ this.native.write(this.batch);
68
+ }
69
+ finally {
70
+ this.batch.close();
71
+ }
72
+ }
73
+ }
74
+ class RNLevelDBIteratorAdapter {
75
+ iter;
76
+ opts;
77
+ positioned = false;
78
+ yielded = 0;
79
+ done = false;
80
+ constructor(iter, opts) {
81
+ this.iter = iter;
82
+ this.opts = opts;
83
+ }
84
+ async next() {
85
+ if (this.done)
86
+ return undefined;
87
+ if (this.opts.limit !== undefined && this.yielded >= this.opts.limit) {
88
+ this.done = true;
89
+ return undefined;
90
+ }
91
+ if (!this.positioned) {
92
+ this.positionInitial();
93
+ this.positioned = true;
94
+ }
95
+ else if (this.opts.reverse) {
96
+ this.iter.prev();
97
+ }
98
+ else {
99
+ this.iter.next();
100
+ }
101
+ if (!this.iter.valid()) {
102
+ this.done = true;
103
+ return undefined;
104
+ }
105
+ const key = new Uint8Array(this.iter.keyBuf());
106
+ // Range bounds: bail out as soon as we cross.
107
+ if (this.opts.reverse) {
108
+ if (this.opts.gte && compareBytes(key, this.opts.gte) < 0) {
109
+ this.done = true;
110
+ return undefined;
111
+ }
112
+ if (this.opts.gt && compareBytes(key, this.opts.gt) <= 0) {
113
+ this.done = true;
114
+ return undefined;
115
+ }
116
+ }
117
+ else {
118
+ if (this.opts.lt && compareBytes(key, this.opts.lt) >= 0) {
119
+ this.done = true;
120
+ return undefined;
121
+ }
122
+ if (this.opts.lte && compareBytes(key, this.opts.lte) > 0) {
123
+ this.done = true;
124
+ return undefined;
125
+ }
126
+ }
127
+ // `keys: true` means caller wants only keys; skip the `valueBuf` native call.
128
+ const value = this.opts.keys ? new Uint8Array(0) : new Uint8Array(this.iter.valueBuf());
129
+ this.yielded++;
130
+ return [key, value];
131
+ }
132
+ async close() {
133
+ this.iter.close();
134
+ }
135
+ positionInitial() {
136
+ if (this.opts.reverse) {
137
+ if (this.opts.lte !== undefined) {
138
+ this.iter.seek(toArrayBuffer(this.opts.lte));
139
+ if (!this.iter.valid()) {
140
+ this.iter.seekLast();
141
+ }
142
+ else {
143
+ const key = new Uint8Array(this.iter.keyBuf());
144
+ if (compareBytes(key, this.opts.lte) > 0)
145
+ this.iter.prev();
146
+ }
147
+ }
148
+ else if (this.opts.lt !== undefined) {
149
+ this.iter.seek(toArrayBuffer(this.opts.lt));
150
+ if (this.iter.valid()) {
151
+ this.iter.prev();
152
+ }
153
+ else {
154
+ this.iter.seekLast();
155
+ }
156
+ }
157
+ else {
158
+ this.iter.seekLast();
159
+ }
160
+ }
161
+ else {
162
+ if (this.opts.gte !== undefined) {
163
+ this.iter.seek(toArrayBuffer(this.opts.gte));
164
+ }
165
+ else if (this.opts.gt !== undefined) {
166
+ this.iter.seek(toArrayBuffer(this.opts.gt));
167
+ if (this.iter.valid()) {
168
+ const key = new Uint8Array(this.iter.keyBuf());
169
+ if (compareBytes(key, this.opts.gt) === 0)
170
+ this.iter.next();
171
+ }
172
+ }
173
+ else {
174
+ this.iter.seekToFirst();
175
+ }
176
+ }
177
+ }
178
+ }
179
+ function toArrayBuffer(bytes) {
180
+ const buffer = bytes.buffer;
181
+ if (buffer instanceof ArrayBuffer
182
+ && bytes.byteOffset === 0
183
+ && bytes.byteLength === buffer.byteLength) {
184
+ return buffer;
185
+ }
186
+ const copy = new ArrayBuffer(bytes.byteLength);
187
+ new Uint8Array(copy).set(bytes);
188
+ return copy;
189
+ }
190
+ function compareBytes(a, b) {
191
+ const minLength = Math.min(a.length, b.length);
192
+ for (let i = 0; i < minLength; i++) {
193
+ const av = a[i];
194
+ const bv = b[i];
195
+ if (av !== bv)
196
+ return av - bv;
197
+ }
198
+ return a.length - b.length;
199
+ }
200
+ //# sourceMappingURL=rn-opener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rn-opener.js","sourceRoot":"","sources":["../../src/rn-opener.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@optimystic/db-p2p-storage-rn",
3
- "version": "0.13.0",
3
+ "version": "0.13.5",
4
4
  "type": "module",
5
- "description": "React Native storage backend for @optimystic/db-p2p using MMKV",
5
+ "description": "React Native LevelDB storage backend for @optimystic/db-p2p",
6
6
  "main": "dist/src/index.js",
7
7
  "types": "./dist/src/index.d.ts",
8
8
  "files": [
@@ -30,7 +30,7 @@
30
30
  "p2p",
31
31
  "storage",
32
32
  "react-native",
33
- "mmkv"
33
+ "leveldb"
34
34
  ],
35
35
  "scripts": {
36
36
  "clean": "rimraf dist",
@@ -39,26 +39,32 @@
39
39
  "test:verbose": "node --import ./register.mjs node_modules/mocha/bin/mocha.js \"test/**/*.spec.ts\" --colors --reporter spec"
40
40
  },
41
41
  "devDependencies": {
42
+ "@libp2p/crypto": "^5.1.13",
43
+ "@libp2p/interface": "^3.1.0",
44
+ "@libp2p/peer-id": "^6.0.4",
42
45
  "@types/chai": "^5.2.3",
43
46
  "@types/debug": "^4.1.12",
44
47
  "@types/mocha": "^10.0.10",
45
48
  "@types/node": "^25.1.0",
46
49
  "chai": "^6.2.2",
50
+ "classic-level": "^3.0.0",
47
51
  "mocha": "^11.7.5",
48
52
  "rimraf": "^6.1.2",
49
53
  "ts-node": "^10.9.2",
50
54
  "typescript": "^5.9.3"
51
55
  },
52
56
  "dependencies": {
53
- "@optimystic/db-core": "^0.13.0",
54
- "@optimystic/db-p2p": "^0.13.0",
57
+ "@optimystic/db-core": "^0.13.5",
58
+ "@optimystic/db-p2p": "^0.13.5",
55
59
  "debug": "^4.4.3"
56
60
  },
57
61
  "peerDependencies": {
58
- "react-native-mmkv": "^4.0.0"
62
+ "@libp2p/crypto": "^5.1.13",
63
+ "@libp2p/interface": "^3.1.0",
64
+ "rn-leveldb": "^3.11.0"
59
65
  },
60
66
  "peerDependenciesMeta": {
61
- "react-native-mmkv": {
67
+ "rn-leveldb": {
62
68
  "optional": false
63
69
  }
64
70
  }
@@ -0,0 +1,33 @@
1
+ import { generateKeyPair, privateKeyFromProtobuf, privateKeyToProtobuf } from '@libp2p/crypto/keys';
2
+ import type { PrivateKey } from '@libp2p/interface';
3
+ import type { LevelDBLike } from './leveldb-like.js';
4
+ import { identityKey } from './keys.js';
5
+
6
+ export const DEFAULT_PEER_KEY_NAME = 'peer-private-key';
7
+
8
+ /**
9
+ * Loads the persisted React Native peer's libp2p private key, or generates a
10
+ * fresh Ed25519 key on first call and persists it.
11
+ *
12
+ * The key is stored as raw protobuf bytes under a dedicated identity tag —
13
+ * LevelDB stores arbitrary byte sequences natively, so there is no base64
14
+ * round-trip (unlike a text-only KV store). Mirrors the shape of
15
+ * `loadOrCreateBrowserPeerKey` and `loadOrCreateNSPeerKey`.
16
+ *
17
+ * The returned `PrivateKey` can be passed directly to
18
+ * `createLibp2pNode({ privateKey })`, giving a React Native peer a stable,
19
+ * restart-surviving identity.
20
+ */
21
+ export async function loadOrCreateRNPeerKey(
22
+ db: LevelDBLike,
23
+ keyName: string = DEFAULT_PEER_KEY_NAME,
24
+ ): Promise<PrivateKey> {
25
+ const stored = await db.get(identityKey(keyName));
26
+ if (stored && stored.byteLength > 0) {
27
+ return privateKeyFromProtobuf(stored);
28
+ }
29
+ const key = await generateKeyPair('Ed25519');
30
+ const bytes = privateKeyToProtobuf(key);
31
+ await db.put(identityKey(keyName), bytes);
32
+ return key;
33
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,14 @@
1
- export * from './mmkv-storage.js';
2
- export * from './mmkv-kv-store.js';
3
-
1
+ export { LevelDBRawStorage } from './leveldb-storage.js';
2
+ export { LevelDBKVStore } from './leveldb-kv-store.js';
3
+ export { loadOrCreateRNPeerKey, DEFAULT_PEER_KEY_NAME } from './identity.js';
4
+ export {
5
+ openOptimysticRNDb,
6
+ wrapRNLevelDB,
7
+ DEFAULT_DB_NAME,
8
+ type OpenOptimysticRNDbOptions,
9
+ type RNLevelDBNative,
10
+ type RNLevelDBWriteBatchNative,
11
+ type RNLevelDBIteratorNative,
12
+ type RNLevelDBWriteBatchCtor,
13
+ type RNLevelDBOpenFn,
14
+ } from './rn-opener.js';