@optimystic/db-p2p-storage-rn 1.15.0 → 1.16.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.
- package/README.md +110 -0
- package/dist/src/identity.d.ts +3 -1
- package/dist/src/identity.d.ts.map +1 -1
- package/dist/src/identity.js +4 -2
- package/dist/src/identity.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/keys.d.ts +22 -0
- package/dist/src/keys.d.ts.map +1 -1
- package/dist/src/keys.js +47 -0
- package/dist/src/keys.js.map +1 -1
- package/dist/src/leveldb-kv-store.d.ts +24 -2
- package/dist/src/leveldb-kv-store.d.ts.map +1 -1
- package/dist/src/leveldb-kv-store.js +61 -3
- package/dist/src/leveldb-kv-store.js.map +1 -1
- package/dist/src/leveldb-like.d.ts +23 -4
- package/dist/src/leveldb-like.d.ts.map +1 -1
- package/dist/src/leveldb-like.js +6 -0
- package/dist/src/leveldb-like.js.map +1 -1
- package/dist/src/leveldb-storage.d.ts +70 -40
- package/dist/src/leveldb-storage.d.ts.map +1 -1
- package/dist/src/leveldb-storage.js +164 -103
- package/dist/src/leveldb-storage.js.map +1 -1
- package/dist/src/rn-opener.d.ts.map +1 -1
- package/dist/src/rn-opener.js +9 -7
- package/dist/src/rn-opener.js.map +1 -1
- package/package.json +3 -3
- package/src/identity.ts +4 -2
- package/src/index.ts +2 -2
- package/src/keys.ts +57 -0
- package/src/leveldb-kv-store.ts +67 -6
- package/src/leveldb-like.ts +24 -4
- package/src/leveldb-storage.ts +192 -127
- package/src/rn-opener.ts +11 -9
|
@@ -1,61 +1,91 @@
|
|
|
1
1
|
import type { ActionId, BlockId } from '@optimystic/db-core';
|
|
2
|
-
import { KvRawStorage, type
|
|
2
|
+
import { KvRawStorage, type JournalBatchBackendOptions, type JournalContents, type JournalRecord, type JournalStore, type StoreDurability, type StoreIdentity, type StoreKey, type WriteGroupOptions } from '@optimystic/db-p2p';
|
|
3
3
|
import { type LevelDBLike } from './leveldb-like.js';
|
|
4
4
|
/**
|
|
5
|
-
* LevelDB {@link
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* package; the kernel deals in logical keys.
|
|
5
|
+
* LevelDB {@link JournalStore}: the six logical block-storage stores mapped into a single ordered
|
|
6
|
+
* byte keyspace, partitioned by a leading tag byte (see `./keys.ts`), read exactly as the per-write
|
|
7
|
+
* driver before it read them, so data an earlier build wrote reads unchanged; and the journal under
|
|
8
|
+
* its own tag byte, which `JournalBatchBackend` drives.
|
|
10
9
|
*
|
|
11
|
-
* `KvRawStorage`
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* `KvRawStorage` owns all JSON/UTF-8 serialization, so this store only ever reads/writes raw
|
|
11
|
+
* `Uint8Array` values; a journal record is bytes too, through `encodeJournalRecord`. Everything
|
|
12
|
+
* LevelDB-specific stays here: the tag-range scans (drained snapshot-first before yielding, so a
|
|
13
|
+
* native iterator never straddles a consumer's `await`), and the one `WriteBatch` each journal
|
|
14
|
+
* write is.
|
|
15
|
+
*
|
|
16
|
+
* ### Why a group survives, and in order
|
|
17
|
+
*
|
|
18
|
+
* A LevelDB batch is atomic, but LevelDB syncs only its current log file, closes an old one
|
|
19
|
+
* unsynced when it switches, and under default options skips a damaged log record and keeps the
|
|
20
|
+
* ones after it, so a later write can survive a power cut while an earlier one is lost — which is
|
|
21
|
+
* why the backend journals (see `JournalBatchBackend`). Here an append is one unsynced batch
|
|
22
|
+
* putting the record under its sequence, and an apply is one batch over the data tags and the
|
|
23
|
+
* journal — every record's entries in order, the applied-through mark, and the delete of each
|
|
24
|
+
* record applied or discarded — written synced wherever the handle can sync (`canSync`). The apply
|
|
25
|
+
* carries every byte it applies, so its durability depends on no earlier batch, and the backend
|
|
26
|
+
* syncs each apply before the next starts: what a power cut leaves is a prefix of the groups, and
|
|
27
|
+
* `durability` is `'power-loss'`. Nothing this package writes bypasses a batch, so no unsynced
|
|
28
|
+
* direct write can sit in an old log file outside the journal's reach.
|
|
29
|
+
*
|
|
30
|
+
* `rn-leveldb` cannot sync today, so on a phone the store reports `'process-crash'` and the backend
|
|
31
|
+
* applies each group at once as one unsynced batch, never journaling: a group lands whole or not
|
|
32
|
+
* at all, and the ordering half of the contract arrives with the binding change and nothing here.
|
|
33
|
+
*
|
|
34
|
+
* The handle is shared with `LevelDBKVStore` and `loadOrCreateRNPeerKey`, so there is no `close`
|
|
35
|
+
* here: the host closes the handle after `storage.close()` has resolved.
|
|
17
36
|
*/
|
|
18
|
-
export declare class
|
|
37
|
+
export declare class LevelDBJournalStore implements JournalStore {
|
|
19
38
|
private readonly db;
|
|
39
|
+
readonly durability: StoreDurability;
|
|
20
40
|
private readonly identity;
|
|
21
41
|
constructor(db: LevelDBLike);
|
|
22
42
|
storeIdentity(): StoreIdentity;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
putRevision(blockId: BlockId, rev: number, value: Uint8Array): Promise<void>;
|
|
27
|
-
rangeRevisions(blockId: BlockId, lo: number, hi: number, reverse: boolean): AsyncIterable<[number, Uint8Array]>;
|
|
28
|
-
getPending(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
29
|
-
putPending(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
30
|
-
deletePending(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
31
|
-
listPendingActionIds(blockId: BlockId): AsyncIterable<ActionId>;
|
|
32
|
-
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
33
|
-
putTransaction(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
34
|
-
getProof(blockId: BlockId, rev: number): Promise<Uint8Array | undefined>;
|
|
35
|
-
putProof(blockId: BlockId, rev: number, value: Uint8Array): Promise<void>;
|
|
36
|
-
getMaterialized(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
37
|
-
putMaterialized(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
38
|
-
deleteMaterialized(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
39
|
-
promote(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
43
|
+
get(key: StoreKey): Promise<Uint8Array | undefined>;
|
|
44
|
+
rangeRevisions(blockId: BlockId, lo: number, hi: number): Promise<[number, Uint8Array][]>;
|
|
45
|
+
listPendingActionIds(blockId: BlockId): Promise<ActionId[]>;
|
|
40
46
|
listBlockIds(): AsyncIterable<BlockId>;
|
|
41
47
|
approximateBytesUsed(): Promise<number>;
|
|
48
|
+
/** One unsynced batch: the record's bytes under its `seq`. `JournalStore.appendJournal`'s contract. */
|
|
49
|
+
appendJournal(record: JournalRecord): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* One batch over the data tags and the journal, synced wherever the handle can sync: each
|
|
52
|
+
* record's entries in order, then the mark, then the delete of every numbered record. A number
|
|
53
|
+
* with no record present (a strict group's, never appended) deletes nothing.
|
|
54
|
+
* `JournalStore.applyJournal`'s contract.
|
|
55
|
+
*/
|
|
56
|
+
applyJournal(apply: readonly JournalRecord[], appliedThrough: number, discard: readonly number[]): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* One drained scan over the journal's tag: the mark and every numbered record, ascending (the
|
|
59
|
+
* sequence is 8 bytes big-endian, so key order is sequence order). A record that does not
|
|
60
|
+
* decode, or whose decoded number is not the one its key names, is left out, which recovery
|
|
61
|
+
* treats as a gap; a mark that is not 8 bytes reads as 0. `JournalStore.readJournal`'s contract.
|
|
62
|
+
*/
|
|
63
|
+
readJournal(): Promise<JournalContents>;
|
|
64
|
+
private readMark;
|
|
65
|
+
private readRecord;
|
|
42
66
|
}
|
|
67
|
+
/** The write group's and the journal backend's options (`idleFlushMs`, `maxUnsyncedBytes`, the test-only `setTimer` and `now`). */
|
|
68
|
+
export type LevelDBRawStorageOptions = WriteGroupOptions & JournalBatchBackendOptions;
|
|
43
69
|
/**
|
|
44
|
-
* LevelDB-backed {@link IRawStorage} for React Native peers
|
|
45
|
-
* over
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
70
|
+
* LevelDB-backed {@link IRawStorage} for React Native peers: the shared {@link KvRawStorage}
|
|
71
|
+
* kernel over a {@link WriteGroupDriver} over a {@link JournalBatchBackend} over a
|
|
72
|
+
* {@link LevelDBJournalStore}. Every write resolves into the driver's in-memory overlay; `flush()`
|
|
73
|
+
* hands the group to the backend as one LevelDB batch — applied before the flush resolves, or,
|
|
74
|
+
* for a flush with a window on a handle that can sync, appended as one journal record and applied
|
|
75
|
+
* by the deadline. The public name/constructor (`new LevelDBRawStorage(db)`) is unchanged so
|
|
76
|
+
* existing imports keep resolving.
|
|
49
77
|
*
|
|
50
|
-
* `listBlockIds`/`getApproximateBytesUsed` are re-declared here as
|
|
51
|
-
* (the
|
|
52
|
-
*
|
|
53
|
-
* them.
|
|
78
|
+
* `listBlockIds`/`getApproximateBytesUsed`/`getStoreIdentity`/`close` are re-declared here as
|
|
79
|
+
* always-present (the store always implements the first three, so the backend, driver and kernel
|
|
80
|
+
* always wire them, and the driver always has a `close`) — the base declares them optional, but
|
|
81
|
+
* every RN consumer relies on them. `close()` applies what is still held and disarms the timers;
|
|
82
|
+
* it does not close the shared handle, which the host closes afterwards.
|
|
54
83
|
*/
|
|
55
84
|
export declare class LevelDBRawStorage extends KvRawStorage {
|
|
56
85
|
listBlockIds: () => AsyncIterable<BlockId>;
|
|
57
86
|
getApproximateBytesUsed: () => Promise<number>;
|
|
58
87
|
getStoreIdentity: () => StoreIdentity;
|
|
59
|
-
|
|
88
|
+
close: () => Promise<void>;
|
|
89
|
+
constructor(db: LevelDBLike, options?: LevelDBRawStorageOptions);
|
|
60
90
|
}
|
|
61
91
|
//# sourceMappingURL=leveldb-storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leveldb-storage.d.ts","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"leveldb-storage.d.ts","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAGN,YAAY,EAKZ,KAAK,0BAA0B,EAC/B,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAS,KAAK,WAAW,EAA8B,MAAM,mBAAmB,CAAC;AA4CxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IAa3C,OAAO,CAAC,QAAQ,CAAC,EAAE;IAR/B,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAMrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAEZ,EAAE,EAAE,WAAW;IAK5C,aAAa,IAAI,aAAa;IAMxB,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAInD,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;IAYzF,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAM1D,YAAY,IAAI,aAAa,CAAC,OAAO,CAAC;IAgBvC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAsB7C,uGAAuG;IACjG,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;;;;OAKG;IAKG,YAAY,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtH;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAgB7C,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,UAAU;CAkBlB;AAUD,mIAAmI;AACnI,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,GAAG,0BAA0B,CAAC;AAEtF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAC1C,YAAY,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAC3C,uBAAuB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,gBAAgB,EAAE,MAAM,aAAa,CAAC;IACtC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;gBAEvB,EAAE,EAAE,WAAW,EAAE,OAAO,GAAE,wBAA6B;CAGnE"}
|
|
@@ -1,24 +1,65 @@
|
|
|
1
|
-
import { KvRawStorage, identityForHandle } from '@optimystic/db-p2p';
|
|
1
|
+
import { JournalBatchBackend, JournalRecordDecodeError, KvRawStorage, WriteGroupDriver, decodeJournalRecord, encodeJournalRecord, identityForHandle, } from '@optimystic/db-p2p';
|
|
2
2
|
import { drain } from './leveldb-like.js';
|
|
3
|
-
import { TAG_PENDING, actionIdFromKey, blockEnvelopeRange, blockIdFromMetadataKey, materializedKey, metadataKey, metadataRange, pendingKey, proofKey, revisionFromKey, revisionKey, transactionKey, } from './keys.js';
|
|
3
|
+
import { TAG_PENDING, actionIdFromKey, blockEnvelopeRange, blockIdFromMetadataKey, decodeJournalMark, encodeJournalMark, isJournalMarkKey, journalMarkKey, journalRange, journalRecordKey, materializedKey, metadataKey, metadataRange, pendingKey, proofKey, revisionFromKey, revisionKey, seqFromJournalKey, transactionKey, } from './keys.js';
|
|
4
4
|
import { createLogger } from './logger.js';
|
|
5
5
|
const log = createLogger('storage:leveldb');
|
|
6
|
+
/** The LevelDB key a `StoreKey` addresses: the tag-prefixed byte scheme of `keys.ts`, unchanged from the per-write driver before it. */
|
|
7
|
+
function keyBytes(key) {
|
|
8
|
+
switch (key.store) {
|
|
9
|
+
case 'metadata':
|
|
10
|
+
return metadataKey(key.blockId);
|
|
11
|
+
case 'revisions':
|
|
12
|
+
return revisionKey(key.blockId, key.rev);
|
|
13
|
+
case 'proofs':
|
|
14
|
+
return proofKey(key.blockId, key.rev);
|
|
15
|
+
case 'pending':
|
|
16
|
+
return pendingKey(key.blockId, key.actionId);
|
|
17
|
+
case 'transactions':
|
|
18
|
+
return transactionKey(key.blockId, key.actionId);
|
|
19
|
+
case 'materialized':
|
|
20
|
+
return materializedKey(key.blockId, key.actionId);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
6
23
|
/**
|
|
7
|
-
* LevelDB {@link
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
24
|
+
* LevelDB {@link JournalStore}: the six logical block-storage stores mapped into a single ordered
|
|
25
|
+
* byte keyspace, partitioned by a leading tag byte (see `./keys.ts`), read exactly as the per-write
|
|
26
|
+
* driver before it read them, so data an earlier build wrote reads unchanged; and the journal under
|
|
27
|
+
* its own tag byte, which `JournalBatchBackend` drives.
|
|
28
|
+
*
|
|
29
|
+
* `KvRawStorage` owns all JSON/UTF-8 serialization, so this store only ever reads/writes raw
|
|
30
|
+
* `Uint8Array` values; a journal record is bytes too, through `encodeJournalRecord`. Everything
|
|
31
|
+
* LevelDB-specific stays here: the tag-range scans (drained snapshot-first before yielding, so a
|
|
32
|
+
* native iterator never straddles a consumer's `await`), and the one `WriteBatch` each journal
|
|
33
|
+
* write is.
|
|
34
|
+
*
|
|
35
|
+
* ### Why a group survives, and in order
|
|
36
|
+
*
|
|
37
|
+
* A LevelDB batch is atomic, but LevelDB syncs only its current log file, closes an old one
|
|
38
|
+
* unsynced when it switches, and under default options skips a damaged log record and keeps the
|
|
39
|
+
* ones after it, so a later write can survive a power cut while an earlier one is lost — which is
|
|
40
|
+
* why the backend journals (see `JournalBatchBackend`). Here an append is one unsynced batch
|
|
41
|
+
* putting the record under its sequence, and an apply is one batch over the data tags and the
|
|
42
|
+
* journal — every record's entries in order, the applied-through mark, and the delete of each
|
|
43
|
+
* record applied or discarded — written synced wherever the handle can sync (`canSync`). The apply
|
|
44
|
+
* carries every byte it applies, so its durability depends on no earlier batch, and the backend
|
|
45
|
+
* syncs each apply before the next starts: what a power cut leaves is a prefix of the groups, and
|
|
46
|
+
* `durability` is `'power-loss'`. Nothing this package writes bypasses a batch, so no unsynced
|
|
47
|
+
* direct write can sit in an old log file outside the journal's reach.
|
|
48
|
+
*
|
|
49
|
+
* `rn-leveldb` cannot sync today, so on a phone the store reports `'process-crash'` and the backend
|
|
50
|
+
* applies each group at once as one unsynced batch, never journaling: a group lands whole or not
|
|
51
|
+
* at all, and the ordering half of the contract arrives with the binding change and nothing here.
|
|
12
52
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* values, and no `JSON.parse`/`stringify`. A value round-trips as the exact bytes
|
|
16
|
-
* the kernel wrote. Everything LevelDB-specific stays here: the tag-range scans
|
|
17
|
-
* (drained snapshot-first before yielding, so a native iterator never straddles a
|
|
18
|
-
* consumer's `await`), and the single `WriteBatch` that makes `promote` atomic.
|
|
53
|
+
* The handle is shared with `LevelDBKVStore` and `loadOrCreateRNPeerKey`, so there is no `close`
|
|
54
|
+
* here: the host closes the handle after `storage.close()` has resolved.
|
|
19
55
|
*/
|
|
20
|
-
export class
|
|
56
|
+
export class LevelDBJournalStore {
|
|
21
57
|
db;
|
|
58
|
+
// NOTE: `'process-crash'` holds only while the handle cannot sync (flush contract rule 3 is then
|
|
59
|
+
// not kept across a power cut: LevelDB's recovery skips a damaged log record and keeps the ones
|
|
60
|
+
// after it, and no apply is synced). The synced path is built and tested over `classic-level`;
|
|
61
|
+
// `react-native-storage-syncs-once-rn-leveldb-can` is the binding change that turns it on.
|
|
62
|
+
durability;
|
|
22
63
|
// NOTE: identity is the HANDLE object, so two handles opened over the same LevelDB PATH read
|
|
23
64
|
// as two identities. Resolving that would mean naming the underlying on-disk path, which
|
|
24
65
|
// `LevelDBLike` does not expose. The package opener (`rn-opener.ts`) hands out one handle per
|
|
@@ -26,99 +67,32 @@ export class LevelDBStoreDriver {
|
|
|
26
67
|
identity;
|
|
27
68
|
constructor(db) {
|
|
28
69
|
this.db = db;
|
|
70
|
+
this.durability = db.canSync ? 'power-loss' : 'process-crash';
|
|
29
71
|
this.identity = identityForHandle('leveldb-handle', db);
|
|
30
72
|
}
|
|
31
73
|
storeIdentity() {
|
|
32
74
|
return this.identity;
|
|
33
75
|
}
|
|
34
|
-
// ---
|
|
35
|
-
async
|
|
36
|
-
return this.db.get(
|
|
76
|
+
// --- reads: the applied stores ---
|
|
77
|
+
async get(key) {
|
|
78
|
+
return this.db.get(keyBytes(key));
|
|
37
79
|
}
|
|
38
|
-
async
|
|
39
|
-
await this.db.put(metadataKey(blockId), value);
|
|
40
|
-
}
|
|
41
|
-
// --- revisions ---
|
|
42
|
-
async getRevision(blockId, rev) {
|
|
43
|
-
return this.db.get(revisionKey(blockId, rev));
|
|
44
|
-
}
|
|
45
|
-
async putRevision(blockId, rev, value) {
|
|
46
|
-
await this.db.put(revisionKey(blockId, rev), value);
|
|
47
|
-
}
|
|
48
|
-
async *rangeRevisions(blockId, lo, hi, reverse) {
|
|
80
|
+
async rangeRevisions(blockId, lo, hi) {
|
|
49
81
|
// Revs are encoded 8-byte big-endian (`revisionKey`), so byte order == numeric
|
|
50
82
|
// order and `revisionKey(blockId, hi)` is exactly the inclusive upper bound;
|
|
51
83
|
// LevelDB's upper bound is exclusive (`lt`), so use `lt = revisionKey(hi + 1)`.
|
|
52
84
|
const gte = revisionKey(blockId, lo);
|
|
53
85
|
const lt = revisionKey(blockId, hi + 1);
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
const entries = await drain(this.db.iterator({ gte, lt
|
|
57
|
-
|
|
58
|
-
yield [revisionFromKey(key), value];
|
|
59
|
-
}
|
|
86
|
+
// Drained before returning: a native LevelDB iterator must not stay open across the
|
|
87
|
+
// consumer's awaits (the kernel's drain-before-yield contract).
|
|
88
|
+
const entries = await drain(this.db.iterator({ gte, lt }));
|
|
89
|
+
return entries.map(([key, value]) => [revisionFromKey(key), value]);
|
|
60
90
|
}
|
|
61
|
-
|
|
62
|
-
async getPending(blockId, actionId) {
|
|
63
|
-
return this.db.get(pendingKey(blockId, actionId));
|
|
64
|
-
}
|
|
65
|
-
async putPending(blockId, actionId, value) {
|
|
66
|
-
await this.db.put(pendingKey(blockId, actionId), value);
|
|
67
|
-
}
|
|
68
|
-
async deletePending(blockId, actionId) {
|
|
69
|
-
await this.db.delete(pendingKey(blockId, actionId));
|
|
70
|
-
}
|
|
71
|
-
async *listPendingActionIds(blockId) {
|
|
91
|
+
async listPendingActionIds(blockId) {
|
|
72
92
|
const range = blockEnvelopeRange(TAG_PENDING, blockId);
|
|
73
|
-
// Drain before yielding, same rationale as rangeRevisions.
|
|
74
93
|
const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
|
|
75
|
-
|
|
76
|
-
yield actionIdFromKey(key, blockId);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// --- transactions ---
|
|
80
|
-
async getTransaction(blockId, actionId) {
|
|
81
|
-
return this.db.get(transactionKey(blockId, actionId));
|
|
82
|
-
}
|
|
83
|
-
async putTransaction(blockId, actionId, value) {
|
|
84
|
-
await this.db.put(transactionKey(blockId, actionId), value);
|
|
85
|
-
}
|
|
86
|
-
// --- proofs (own tag byte; no delete — see RawStoreDriver.getProof) ---
|
|
87
|
-
async getProof(blockId, rev) {
|
|
88
|
-
return this.db.get(proofKey(blockId, rev));
|
|
89
|
-
}
|
|
90
|
-
async putProof(blockId, rev, value) {
|
|
91
|
-
await this.db.put(proofKey(blockId, rev), value);
|
|
92
|
-
}
|
|
93
|
-
// --- materialized ---
|
|
94
|
-
async getMaterialized(blockId, actionId) {
|
|
95
|
-
return this.db.get(materializedKey(blockId, actionId));
|
|
94
|
+
return entries.map(([key]) => actionIdFromKey(key, blockId));
|
|
96
95
|
}
|
|
97
|
-
async putMaterialized(blockId, actionId, value) {
|
|
98
|
-
await this.db.put(materializedKey(blockId, actionId), value);
|
|
99
|
-
}
|
|
100
|
-
// The kernel owns the put-or-delete branch of `saveMaterializedBlock`, so the
|
|
101
|
-
// driver exposes delete as a separate op.
|
|
102
|
-
async deleteMaterialized(blockId, actionId) {
|
|
103
|
-
await this.db.delete(materializedKey(blockId, actionId));
|
|
104
|
-
}
|
|
105
|
-
// --- promote (the only cross-key atomic op) ---
|
|
106
|
-
async promote(blockId, actionId) {
|
|
107
|
-
const pKey = pendingKey(blockId, actionId);
|
|
108
|
-
const value = await this.db.get(pKey);
|
|
109
|
-
if (!value) {
|
|
110
|
-
throw new Error(`Pending action ${actionId} not found for block ${blockId}`);
|
|
111
|
-
}
|
|
112
|
-
// The single `WriteBatch` IS the atomic move: a crash leaves either the
|
|
113
|
-
// pending or the committed entry, never both/neither.
|
|
114
|
-
const tKey = transactionKey(blockId, actionId);
|
|
115
|
-
await this.db
|
|
116
|
-
.batch()
|
|
117
|
-
.put(tKey, value)
|
|
118
|
-
.delete(pKey)
|
|
119
|
-
.write();
|
|
120
|
-
}
|
|
121
|
-
// --- optional passthroughs ---
|
|
122
96
|
async *listBlockIds() {
|
|
123
97
|
// Scan the whole TAG_METADATA keyspace; each metadata key is one distinct
|
|
124
98
|
// block id (empty suffix). keys:true skips values — we only need the ids.
|
|
@@ -156,22 +130,109 @@ export class LevelDBStoreDriver {
|
|
|
156
130
|
return 0;
|
|
157
131
|
}
|
|
158
132
|
}
|
|
133
|
+
// --- the journal ---
|
|
134
|
+
/** One unsynced batch: the record's bytes under its `seq`. `JournalStore.appendJournal`'s contract. */
|
|
135
|
+
async appendJournal(record) {
|
|
136
|
+
await this.db.batch().put(journalRecordKey(record.seq), encodeJournalRecord(record)).write();
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* One batch over the data tags and the journal, synced wherever the handle can sync: each
|
|
140
|
+
* record's entries in order, then the mark, then the delete of every numbered record. A number
|
|
141
|
+
* with no record present (a strict group's, never appended) deletes nothing.
|
|
142
|
+
* `JournalStore.applyJournal`'s contract.
|
|
143
|
+
*/
|
|
144
|
+
// NOTE: on a handle that cannot sync every group is applied this way, so each flush also puts the
|
|
145
|
+
// mark and deletes a record key that was never appended (a LevelDB tombstone): two small extra
|
|
146
|
+
// operations per flush, unmeasured. If flush cost on phones ever shows in profiles, have the
|
|
147
|
+
// backend hand the store only the numbers it appended, rather than every number applied.
|
|
148
|
+
async applyJournal(apply, appliedThrough, discard) {
|
|
149
|
+
const batch = this.db.batch();
|
|
150
|
+
for (const record of apply) {
|
|
151
|
+
putEntries(batch, record);
|
|
152
|
+
}
|
|
153
|
+
batch.put(journalMarkKey(), encodeJournalMark(appliedThrough));
|
|
154
|
+
for (const { seq } of apply)
|
|
155
|
+
batch.delete(journalRecordKey(seq));
|
|
156
|
+
for (const seq of discard)
|
|
157
|
+
batch.delete(journalRecordKey(seq));
|
|
158
|
+
await batch.write({ sync: this.db.canSync });
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* One drained scan over the journal's tag: the mark and every numbered record, ascending (the
|
|
162
|
+
* sequence is 8 bytes big-endian, so key order is sequence order). A record that does not
|
|
163
|
+
* decode, or whose decoded number is not the one its key names, is left out, which recovery
|
|
164
|
+
* treats as a gap; a mark that is not 8 bytes reads as 0. `JournalStore.readJournal`'s contract.
|
|
165
|
+
*/
|
|
166
|
+
async readJournal() {
|
|
167
|
+
const range = journalRange();
|
|
168
|
+
const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt }));
|
|
169
|
+
let appliedThrough = 0;
|
|
170
|
+
const records = [];
|
|
171
|
+
for (const [key, value] of entries) {
|
|
172
|
+
if (isJournalMarkKey(key)) {
|
|
173
|
+
appliedThrough = this.readMark(value);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const record = this.readRecord(key, value);
|
|
177
|
+
if (record)
|
|
178
|
+
records.push(record);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return { appliedThrough, records };
|
|
182
|
+
}
|
|
183
|
+
readMark(value) {
|
|
184
|
+
const mark = decodeJournalMark(value);
|
|
185
|
+
if (mark === undefined || !Number.isSafeInteger(mark)) {
|
|
186
|
+
log('read-journal: the applied-through mark of %s is not a number this build can read (%d bytes) and reads as 0', this.identity, value.byteLength);
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
return mark;
|
|
190
|
+
}
|
|
191
|
+
readRecord(key, value) {
|
|
192
|
+
const seq = seqFromJournalKey(key);
|
|
193
|
+
try {
|
|
194
|
+
const record = decodeJournalRecord(value);
|
|
195
|
+
if (record.seq === seq)
|
|
196
|
+
return record;
|
|
197
|
+
log('read-journal: a journal record of %s is numbered %d but filed under %s and is left out; recovery treats its number as missing', this.identity, record.seq, String(seq));
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
if (!(err instanceof JournalRecordDecodeError))
|
|
202
|
+
throw err;
|
|
203
|
+
log('read-journal: journal record %s of %s is not one this build can read and is left out (%s); recovery treats its number as missing', String(seq), this.identity, err.message);
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** The record's entries onto the batch, in order: a put stores the value, a delete removes the key. */
|
|
209
|
+
function putEntries(batch, record) {
|
|
210
|
+
for (const { key, value } of record.entries) {
|
|
211
|
+
const encoded = keyBytes(key);
|
|
212
|
+
if (value === undefined)
|
|
213
|
+
batch.delete(encoded);
|
|
214
|
+
else
|
|
215
|
+
batch.put(encoded, value);
|
|
216
|
+
}
|
|
159
217
|
}
|
|
160
218
|
/**
|
|
161
|
-
* LevelDB-backed {@link IRawStorage} for React Native peers
|
|
162
|
-
* over
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
219
|
+
* LevelDB-backed {@link IRawStorage} for React Native peers: the shared {@link KvRawStorage}
|
|
220
|
+
* kernel over a {@link WriteGroupDriver} over a {@link JournalBatchBackend} over a
|
|
221
|
+
* {@link LevelDBJournalStore}. Every write resolves into the driver's in-memory overlay; `flush()`
|
|
222
|
+
* hands the group to the backend as one LevelDB batch — applied before the flush resolves, or,
|
|
223
|
+
* for a flush with a window on a handle that can sync, appended as one journal record and applied
|
|
224
|
+
* by the deadline. The public name/constructor (`new LevelDBRawStorage(db)`) is unchanged so
|
|
225
|
+
* existing imports keep resolving.
|
|
166
226
|
*
|
|
167
|
-
* `listBlockIds`/`getApproximateBytesUsed` are re-declared here as
|
|
168
|
-
* (the
|
|
169
|
-
*
|
|
170
|
-
* them.
|
|
227
|
+
* `listBlockIds`/`getApproximateBytesUsed`/`getStoreIdentity`/`close` are re-declared here as
|
|
228
|
+
* always-present (the store always implements the first three, so the backend, driver and kernel
|
|
229
|
+
* always wire them, and the driver always has a `close`) — the base declares them optional, but
|
|
230
|
+
* every RN consumer relies on them. `close()` applies what is still held and disarms the timers;
|
|
231
|
+
* it does not close the shared handle, which the host closes afterwards.
|
|
171
232
|
*/
|
|
172
233
|
export class LevelDBRawStorage extends KvRawStorage {
|
|
173
|
-
constructor(db) {
|
|
174
|
-
super(new
|
|
234
|
+
constructor(db, options = {}) {
|
|
235
|
+
super(new WriteGroupDriver(new JournalBatchBackend(new LevelDBJournalStore(db), options), options));
|
|
175
236
|
}
|
|
176
237
|
}
|
|
177
238
|
//# sourceMappingURL=leveldb-storage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leveldb-storage.js","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"leveldb-storage.js","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rn-opener.d.ts","sourceRoot":"","sources":["../../src/rn-opener.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGX,WAAW,
|
|
1
|
+
{"version":3,"file":"rn-opener.d.ts","sourceRoot":"","sources":["../../src/rn-opener.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGX,WAAW,EAGX,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"}
|
package/dist/src/rn-opener.js
CHANGED
|
@@ -23,6 +23,10 @@ export function wrapRNLevelDB(native, WriteBatch) {
|
|
|
23
23
|
class RNLevelDBAdapter {
|
|
24
24
|
native;
|
|
25
25
|
WriteBatch;
|
|
26
|
+
// `rn-leveldb` 3.11 writes every batch with LevelDB's default `WriteOptions` (`sync = false`)
|
|
27
|
+
// and offers no way to ask for a sync; `react-native-storage-syncs-once-rn-leveldb-can` is
|
|
28
|
+
// the upstream change that flips this to true.
|
|
29
|
+
canSync = false;
|
|
26
30
|
constructor(native, WriteBatch) {
|
|
27
31
|
this.native = native;
|
|
28
32
|
this.WriteBatch = WriteBatch;
|
|
@@ -31,12 +35,6 @@ class RNLevelDBAdapter {
|
|
|
31
35
|
const result = this.native.getBuf(toArrayBuffer(key));
|
|
32
36
|
return result === null ? undefined : new Uint8Array(result);
|
|
33
37
|
}
|
|
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
38
|
batch() {
|
|
41
39
|
return new RNLevelDBWriteBatchAdapter(this.native, new this.WriteBatch());
|
|
42
40
|
}
|
|
@@ -62,8 +60,12 @@ class RNLevelDBWriteBatchAdapter {
|
|
|
62
60
|
this.batch.delete(toArrayBuffer(key));
|
|
63
61
|
return this;
|
|
64
62
|
}
|
|
65
|
-
|
|
63
|
+
/** Unsynced, as every `rn-leveldb` write is. A sync asked of a handle whose `canSync` is false is a caller bug, refused before anything is written. */
|
|
64
|
+
async write(options) {
|
|
66
65
|
try {
|
|
66
|
+
if (options?.sync) {
|
|
67
|
+
throw new Error('rn-leveldb cannot sync a write: callers check canSync before asking (react-native-storage-syncs-once-rn-leveldb-can)');
|
|
68
|
+
}
|
|
67
69
|
this.native.write(this.batch);
|
|
68
70
|
}
|
|
69
71
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rn-opener.js","sourceRoot":"","sources":["../../src/rn-opener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rn-opener.js","sourceRoot":"","sources":["../../src/rn-opener.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optimystic/db-p2p-storage-rn",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "React Native LevelDB storage backend for @optimystic/db-p2p",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"typescript": "^5.9.3"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@optimystic/db-core": "^1.
|
|
58
|
-
"@optimystic/db-p2p": "^1.
|
|
57
|
+
"@optimystic/db-core": "^1.16.0",
|
|
58
|
+
"@optimystic/db-p2p": "^1.16.0",
|
|
59
59
|
"debug": "^4.4.3"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|