@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.
- package/dist/src/identity.d.ts +18 -0
- package/dist/src/identity.d.ts.map +1 -0
- package/dist/src/identity.js +27 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/keys.d.ts +55 -0
- package/dist/src/keys.d.ts.map +1 -0
- package/dist/src/keys.js +126 -0
- package/dist/src/keys.js.map +1 -0
- package/dist/src/leveldb-kv-store.d.ts +21 -0
- package/dist/src/leveldb-kv-store.d.ts.map +1 -0
- package/dist/src/leveldb-kv-store.js +39 -0
- package/dist/src/leveldb-kv-store.js.map +1 -0
- package/dist/src/leveldb-like.d.ts +68 -0
- package/dist/src/leveldb-like.d.ts.map +1 -0
- package/dist/src/leveldb-like.js +34 -0
- package/dist/src/leveldb-like.js.map +1 -0
- package/dist/src/{mmkv-storage.d.ts → leveldb-storage.d.ts} +19 -32
- package/dist/src/leveldb-storage.d.ts.map +1 -0
- package/dist/src/leveldb-storage.js +138 -0
- package/dist/src/leveldb-storage.js.map +1 -0
- package/dist/src/rn-opener.d.ts +73 -0
- package/dist/src/rn-opener.d.ts.map +1 -0
- package/dist/src/rn-opener.js +200 -0
- package/dist/src/rn-opener.js.map +1 -0
- package/package.json +13 -7
- package/src/identity.ts +33 -0
- package/src/index.ts +14 -3
- package/src/keys.ts +139 -0
- package/src/leveldb-kv-store.ts +43 -0
- package/src/leveldb-like.ts +84 -0
- package/src/leveldb-storage.ts +155 -0
- package/src/rn-opener.ts +274 -0
- package/dist/src/mmkv-kv-store.d.ts +0 -13
- package/dist/src/mmkv-kv-store.d.ts.map +0 -1
- package/dist/src/mmkv-kv-store.js +0 -25
- package/dist/src/mmkv-kv-store.js.map +0 -1
- package/dist/src/mmkv-storage.d.ts.map +0 -1
- package/dist/src/mmkv-storage.js +0 -138
- package/dist/src/mmkv-storage.js.map +0 -1
- package/src/mmkv-kv-store.ts +0 -26
- 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.
|
|
3
|
+
"version": "0.13.5",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "React Native storage backend for @optimystic/db-p2p
|
|
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
|
-
"
|
|
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.
|
|
54
|
-
"@optimystic/db-p2p": "^0.13.
|
|
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
|
-
"
|
|
62
|
+
"@libp2p/crypto": "^5.1.13",
|
|
63
|
+
"@libp2p/interface": "^3.1.0",
|
|
64
|
+
"rn-leveldb": "^3.11.0"
|
|
59
65
|
},
|
|
60
66
|
"peerDependenciesMeta": {
|
|
61
|
-
"
|
|
67
|
+
"rn-leveldb": {
|
|
62
68
|
"optional": false
|
|
63
69
|
}
|
|
64
70
|
}
|
package/src/identity.ts
ADDED
|
@@ -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
|
|
2
|
-
export
|
|
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';
|