@optimystic/db-p2p-storage-rn 0.12.0 → 0.13.4

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 +20 -8
  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,18 @@
1
+ import type { PrivateKey } from '@libp2p/interface';
2
+ import type { LevelDBLike } from './leveldb-like.js';
3
+ export declare const DEFAULT_PEER_KEY_NAME = "peer-private-key";
4
+ /**
5
+ * Loads the persisted React Native peer's libp2p private key, or generates a
6
+ * fresh Ed25519 key on first call and persists it.
7
+ *
8
+ * The key is stored as raw protobuf bytes under a dedicated identity tag —
9
+ * LevelDB stores arbitrary byte sequences natively, so there is no base64
10
+ * round-trip (unlike a text-only KV store). Mirrors the shape of
11
+ * `loadOrCreateBrowserPeerKey` and `loadOrCreateNSPeerKey`.
12
+ *
13
+ * The returned `PrivateKey` can be passed directly to
14
+ * `createLibp2pNode({ privateKey })`, giving a React Native peer a stable,
15
+ * restart-surviving identity.
16
+ */
17
+ export declare function loadOrCreateRNPeerKey(db: LevelDBLike, keyName?: string): Promise<PrivateKey>;
18
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAC1C,EAAE,EAAE,WAAW,EACf,OAAO,GAAE,MAA8B,GACrC,OAAO,CAAC,UAAU,CAAC,CASrB"}
@@ -0,0 +1,27 @@
1
+ import { generateKeyPair, privateKeyFromProtobuf, privateKeyToProtobuf } from '@libp2p/crypto/keys';
2
+ import { identityKey } from './keys.js';
3
+ export const DEFAULT_PEER_KEY_NAME = 'peer-private-key';
4
+ /**
5
+ * Loads the persisted React Native peer's libp2p private key, or generates a
6
+ * fresh Ed25519 key on first call and persists it.
7
+ *
8
+ * The key is stored as raw protobuf bytes under a dedicated identity tag —
9
+ * LevelDB stores arbitrary byte sequences natively, so there is no base64
10
+ * round-trip (unlike a text-only KV store). Mirrors the shape of
11
+ * `loadOrCreateBrowserPeerKey` and `loadOrCreateNSPeerKey`.
12
+ *
13
+ * The returned `PrivateKey` can be passed directly to
14
+ * `createLibp2pNode({ privateKey })`, giving a React Native peer a stable,
15
+ * restart-surviving identity.
16
+ */
17
+ export async function loadOrCreateRNPeerKey(db, keyName = DEFAULT_PEER_KEY_NAME) {
18
+ const stored = await db.get(identityKey(keyName));
19
+ if (stored && stored.byteLength > 0) {
20
+ return privateKeyFromProtobuf(stored);
21
+ }
22
+ const key = await generateKeyPair('Ed25519');
23
+ const bytes = privateKeyToProtobuf(key);
24
+ await db.put(identityKey(keyName), bytes);
25
+ return key;
26
+ }
27
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGpG,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,EAAe,EACf,UAAkB,qBAAqB;IAEvC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,IAAI,MAAM,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,GAAG,CAAC;AACZ,CAAC"}
@@ -1,3 +1,5 @@
1
- export * from './mmkv-storage.js';
2
- export * from './mmkv-kv-store.js';
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 { openOptimysticRNDb, wrapRNLevelDB, DEFAULT_DB_NAME, type OpenOptimysticRNDbOptions, type RNLevelDBNative, type RNLevelDBWriteBatchNative, type RNLevelDBIteratorNative, type RNLevelDBWriteBatchCtor, type RNLevelDBOpenFn, } from './rn-opener.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACN,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,3 +1,5 @@
1
- export * from './mmkv-storage.js';
2
- export * from './mmkv-kv-store.js';
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 { openOptimysticRNDb, wrapRNLevelDB, DEFAULT_DB_NAME, } from './rn-opener.js';
3
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACN,kBAAkB,EAClB,aAAa,EACb,eAAe,GAOf,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Key encoding for the LevelDB-backed storage. All keys live in a single
3
+ * database and are sorted lexicographically by byte order. A leading tag
4
+ * byte partitions the keyspace per logical store; a 4-byte big-endian
5
+ * length prefix on the `blockId` ensures prefix scans cannot be confused
6
+ * by the variable-length `actionId` suffix of the previous store.
7
+ *
8
+ * Layout:
9
+ * `tag (1)` || `len(blockId) (4 BE)` || `blockId UTF-8` || `suffix`
10
+ *
11
+ * Per-store suffix encoding:
12
+ * - metadata: (empty)
13
+ * - revisions: rev (8-byte big-endian unsigned via DataView.setBigUint64)
14
+ * - pending: actionId UTF-8 (terminal)
15
+ * - transactions: actionId UTF-8 (terminal)
16
+ * - materialized: actionId UTF-8 (terminal)
17
+ *
18
+ * `kv` and `identity` keys are flat — no `blockId` envelope — under their
19
+ * own tag bytes (`TAG_KV`, `TAG_IDENTITY`) and use UTF-8 of the full key.
20
+ *
21
+ * The tag bytes are deliberately spaced (`0x01`, `0x02`, …, `0x10`, `0x20`)
22
+ * so a future logical store can slot in between without colliding with
23
+ * existing prefix scans.
24
+ */
25
+ export declare const TAG_METADATA = 1;
26
+ export declare const TAG_REVISIONS = 2;
27
+ export declare const TAG_PENDING = 3;
28
+ export declare const TAG_TRANSACTIONS = 4;
29
+ export declare const TAG_MATERIALIZED = 5;
30
+ export declare const TAG_KV = 16;
31
+ export declare const TAG_IDENTITY = 32;
32
+ export declare function metadataKey(blockId: string): Uint8Array;
33
+ export declare function revisionKey(blockId: string, rev: number): Uint8Array;
34
+ /** Decode the trailing 8-byte big-endian rev from a `revisionKey`-encoded key. */
35
+ export declare function revisionFromKey(key: Uint8Array): number;
36
+ export declare function pendingKey(blockId: string, actionId: string): Uint8Array;
37
+ export declare function transactionKey(blockId: string, actionId: string): Uint8Array;
38
+ export declare function materializedKey(blockId: string, actionId: string): Uint8Array;
39
+ /** Returns the inclusive lower / exclusive upper range covering every key for `(tag, blockId, *)`. */
40
+ export declare function blockEnvelopeRange(tag: number, blockId: string): {
41
+ gte: Uint8Array;
42
+ lt: Uint8Array;
43
+ };
44
+ /** Decode the `actionId` suffix from a `pendingKey` / `transactionKey` / `materializedKey`. */
45
+ export declare function actionIdFromKey(key: Uint8Array, blockId: string): string;
46
+ export declare function kvKey(key: string): Uint8Array;
47
+ /** Returns the inclusive lower / exclusive upper range covering every kv key starting with `prefix`. */
48
+ export declare function kvPrefixRange(prefix: string): {
49
+ gte: Uint8Array;
50
+ lt: Uint8Array;
51
+ };
52
+ /** Strip the leading `TAG_KV` byte from a key, returning the UTF-8 string portion. */
53
+ export declare function kvKeyToString(raw: Uint8Array): string;
54
+ export declare function identityKey(keyName: string): Uint8Array;
55
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,eAAO,MAAM,YAAY,IAAO,CAAC;AACjC,eAAO,MAAM,aAAa,IAAO,CAAC;AAClC,eAAO,MAAM,WAAW,IAAO,CAAC;AAChC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AACrC,eAAO,MAAM,MAAM,KAAO,CAAC;AAC3B,eAAO,MAAM,YAAY,KAAO,CAAC;AA0BjC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAMpE;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAGvD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAExE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE5E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE7E;AAED,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAapG;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIxE;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAE7C;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAcjF;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvD"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Key encoding for the LevelDB-backed storage. All keys live in a single
3
+ * database and are sorted lexicographically by byte order. A leading tag
4
+ * byte partitions the keyspace per logical store; a 4-byte big-endian
5
+ * length prefix on the `blockId` ensures prefix scans cannot be confused
6
+ * by the variable-length `actionId` suffix of the previous store.
7
+ *
8
+ * Layout:
9
+ * `tag (1)` || `len(blockId) (4 BE)` || `blockId UTF-8` || `suffix`
10
+ *
11
+ * Per-store suffix encoding:
12
+ * - metadata: (empty)
13
+ * - revisions: rev (8-byte big-endian unsigned via DataView.setBigUint64)
14
+ * - pending: actionId UTF-8 (terminal)
15
+ * - transactions: actionId UTF-8 (terminal)
16
+ * - materialized: actionId UTF-8 (terminal)
17
+ *
18
+ * `kv` and `identity` keys are flat — no `blockId` envelope — under their
19
+ * own tag bytes (`TAG_KV`, `TAG_IDENTITY`) and use UTF-8 of the full key.
20
+ *
21
+ * The tag bytes are deliberately spaced (`0x01`, `0x02`, …, `0x10`, `0x20`)
22
+ * so a future logical store can slot in between without colliding with
23
+ * existing prefix scans.
24
+ */
25
+ export const TAG_METADATA = 0x01;
26
+ export const TAG_REVISIONS = 0x02;
27
+ export const TAG_PENDING = 0x03;
28
+ export const TAG_TRANSACTIONS = 0x04;
29
+ export const TAG_MATERIALIZED = 0x05;
30
+ export const TAG_KV = 0x10;
31
+ export const TAG_IDENTITY = 0x20;
32
+ const textEncoder = new TextEncoder();
33
+ const textDecoder = new TextDecoder();
34
+ function encodeBlockEnvelope(tag, blockId) {
35
+ const blockIdBytes = textEncoder.encode(blockId);
36
+ const out = new Uint8Array(1 + 4 + blockIdBytes.length);
37
+ out[0] = tag;
38
+ new DataView(out.buffer, out.byteOffset).setUint32(1, blockIdBytes.length, false);
39
+ out.set(blockIdBytes, 5);
40
+ return out;
41
+ }
42
+ function concat(...parts) {
43
+ let total = 0;
44
+ for (const p of parts)
45
+ total += p.length;
46
+ const out = new Uint8Array(total);
47
+ let off = 0;
48
+ for (const p of parts) {
49
+ out.set(p, off);
50
+ off += p.length;
51
+ }
52
+ return out;
53
+ }
54
+ export function metadataKey(blockId) {
55
+ return encodeBlockEnvelope(TAG_METADATA, blockId);
56
+ }
57
+ export function revisionKey(blockId, rev) {
58
+ const envelope = encodeBlockEnvelope(TAG_REVISIONS, blockId);
59
+ const out = new Uint8Array(envelope.length + 8);
60
+ out.set(envelope, 0);
61
+ new DataView(out.buffer, out.byteOffset).setBigUint64(envelope.length, BigInt(rev), false);
62
+ return out;
63
+ }
64
+ /** Decode the trailing 8-byte big-endian rev from a `revisionKey`-encoded key. */
65
+ export function revisionFromKey(key) {
66
+ const view = new DataView(key.buffer, key.byteOffset, key.byteLength);
67
+ return Number(view.getBigUint64(key.byteLength - 8, false));
68
+ }
69
+ export function pendingKey(blockId, actionId) {
70
+ return concat(encodeBlockEnvelope(TAG_PENDING, blockId), textEncoder.encode(actionId));
71
+ }
72
+ export function transactionKey(blockId, actionId) {
73
+ return concat(encodeBlockEnvelope(TAG_TRANSACTIONS, blockId), textEncoder.encode(actionId));
74
+ }
75
+ export function materializedKey(blockId, actionId) {
76
+ return concat(encodeBlockEnvelope(TAG_MATERIALIZED, blockId), textEncoder.encode(actionId));
77
+ }
78
+ /** Returns the inclusive lower / exclusive upper range covering every key for `(tag, blockId, *)`. */
79
+ export function blockEnvelopeRange(tag, blockId) {
80
+ const gte = encodeBlockEnvelope(tag, blockId);
81
+ const lt = new Uint8Array(gte.length);
82
+ lt.set(gte);
83
+ // Increment the last byte to get the exclusive upper bound. The envelope
84
+ // ends in the last byte of the blockId (UTF-8); since the longest possible
85
+ // UTF-8 lead byte is 0xF4 and continuation bytes are <= 0xBF, no envelope
86
+ // byte is ever 0xFF — incrementing the last byte is always well-defined.
87
+ const lastIndex = lt.length - 1;
88
+ const lastByte = lt[lastIndex];
89
+ if (lastByte === undefined)
90
+ throw new Error('empty blockId envelope');
91
+ lt[lastIndex] = lastByte + 1;
92
+ return { gte, lt };
93
+ }
94
+ /** Decode the `actionId` suffix from a `pendingKey` / `transactionKey` / `materializedKey`. */
95
+ export function actionIdFromKey(key, blockId) {
96
+ const blockIdLen = textEncoder.encode(blockId).length;
97
+ const suffixOffset = 1 + 4 + blockIdLen;
98
+ return textDecoder.decode(key.subarray(suffixOffset));
99
+ }
100
+ export function kvKey(key) {
101
+ return concat(Uint8Array.of(TAG_KV), textEncoder.encode(key));
102
+ }
103
+ /** Returns the inclusive lower / exclusive upper range covering every kv key starting with `prefix`. */
104
+ export function kvPrefixRange(prefix) {
105
+ const prefixBytes = textEncoder.encode(prefix);
106
+ const gte = new Uint8Array(1 + prefixBytes.length);
107
+ gte[0] = TAG_KV;
108
+ gte.set(prefixBytes, 1);
109
+ // Upper bound: any string whose UTF-8 bytes start with `prefixBytes` sorts
110
+ // strictly below `[TAG_KV, ...prefixBytes, 0xFF]`. UTF-8 never produces a
111
+ // 0xFF byte (the maximum valid lead byte is 0xF4 and continuation bytes
112
+ // top out at 0xBF), so appending 0xFF yields an exact exclusive upper bound.
113
+ const lt = new Uint8Array(1 + prefixBytes.length + 1);
114
+ lt[0] = TAG_KV;
115
+ lt.set(prefixBytes, 1);
116
+ lt[lt.length - 1] = 0xff;
117
+ return { gte, lt };
118
+ }
119
+ /** Strip the leading `TAG_KV` byte from a key, returning the UTF-8 string portion. */
120
+ export function kvKeyToString(raw) {
121
+ return textDecoder.decode(raw.subarray(1));
122
+ }
123
+ export function identityKey(keyName) {
124
+ return concat(Uint8Array.of(TAG_IDENTITY), textEncoder.encode(keyName));
125
+ }
126
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { IKVStore } from '@optimystic/db-p2p';
2
+ import { type LevelDBLike } from './leveldb-like.js';
3
+ /**
4
+ * LevelDB-backed `IKVStore` adapter for React Native peers.
5
+ *
6
+ * Shares one `LevelDBLike` database with `LevelDBRawStorage` and the identity
7
+ * helper. KV keys are tagged with `TAG_KV` (and identity with `TAG_IDENTITY`),
8
+ * so the three subsystems can't collide regardless of the user-chosen
9
+ * `prefix`. `list(prefix)` is a range-bounded scan — never a full-database
10
+ * iteration plus JS-side filter — so listing latency stays bounded.
11
+ */
12
+ export declare class LevelDBKVStore implements IKVStore {
13
+ private readonly db;
14
+ private readonly prefix;
15
+ constructor(db: LevelDBLike, prefix?: string);
16
+ get(key: string): Promise<string | undefined>;
17
+ set(key: string, value: string): Promise<void>;
18
+ delete(key: string): Promise<void>;
19
+ list(prefix: string): Promise<string[]>;
20
+ }
21
+ //# sourceMappingURL=leveldb-kv-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leveldb-kv-store.d.ts","sourceRoot":"","sources":["../../src/leveldb-kv-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAS,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAM5D;;;;;;;;GAQG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAGlC,OAAO,CAAC,QAAQ,CAAC,EAAE;IAF/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEH,EAAE,EAAE,WAAW,EAAE,MAAM,GAAE,MAA0B;IAI1E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAM7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAK7C"}
@@ -0,0 +1,39 @@
1
+ import { drain } from './leveldb-like.js';
2
+ import { kvKey, kvKeyToString, kvPrefixRange } from './keys.js';
3
+ const textEncoder = new TextEncoder();
4
+ const textDecoder = new TextDecoder();
5
+ /**
6
+ * LevelDB-backed `IKVStore` adapter for React Native peers.
7
+ *
8
+ * Shares one `LevelDBLike` database with `LevelDBRawStorage` and the identity
9
+ * helper. KV keys are tagged with `TAG_KV` (and identity with `TAG_IDENTITY`),
10
+ * so the three subsystems can't collide regardless of the user-chosen
11
+ * `prefix`. `list(prefix)` is a range-bounded scan — never a full-database
12
+ * iteration plus JS-side filter — so listing latency stays bounded.
13
+ */
14
+ export class LevelDBKVStore {
15
+ db;
16
+ prefix;
17
+ constructor(db, prefix = 'optimystic:txn:') {
18
+ this.db = db;
19
+ this.prefix = prefix;
20
+ }
21
+ async get(key) {
22
+ const bytes = await this.db.get(kvKey(this.prefix + key));
23
+ if (!bytes)
24
+ return undefined;
25
+ return textDecoder.decode(bytes);
26
+ }
27
+ async set(key, value) {
28
+ await this.db.put(kvKey(this.prefix + key), textEncoder.encode(value));
29
+ }
30
+ async delete(key) {
31
+ await this.db.delete(kvKey(this.prefix + key));
32
+ }
33
+ async list(prefix) {
34
+ const range = kvPrefixRange(this.prefix + prefix);
35
+ const entries = await drain(this.db.iterator({ gte: range.gte, lt: range.lt, keys: true }));
36
+ return entries.map(([rawKey]) => kvKeyToString(rawKey).slice(this.prefix.length));
37
+ }
38
+ }
39
+ //# sourceMappingURL=leveldb-kv-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leveldb-kv-store.js","sourceRoot":"","sources":["../../src/leveldb-kv-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAoB,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC;;;;;;;;GAQG;AACH,MAAM,OAAO,cAAc;IAGG;IAFZ,MAAM,CAAS;IAEhC,YAA6B,EAAe,EAAE,SAAiB,iBAAiB;QAAnD,OAAE,GAAF,EAAE,CAAa;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACpB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;QACnC,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACvB,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc;QACxB,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC5F,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,CAAC;CACD"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Package-private LevelDB driver surface.
3
+ *
4
+ * The storage classes (`LevelDBRawStorage`, `LevelDBKVStore`) and the identity
5
+ * helper (`loadOrCreateRNPeerKey`) only depend on the interfaces declared here
6
+ * — never on `rn-leveldb` directly. That lets the suite run under Node mocha
7
+ * against `classic-level`, matching the pattern `db-p2p-storage-ns` uses with
8
+ * `node:sqlite` and `db-p2p-storage-web` uses with `fake-indexeddb`.
9
+ *
10
+ * Only `openOptimysticRNDb`, the user-facing constructors, and the identity
11
+ * helper are exported from `index.ts`; the interfaces in this file are
12
+ * internal — consumers never see them.
13
+ */
14
+ /** Range options for a `LevelDBLike.iterator` scan. */
15
+ export interface LevelDBIteratorOptions {
16
+ /** Inclusive lower bound. */
17
+ gte?: Uint8Array;
18
+ /** Exclusive lower bound. */
19
+ gt?: Uint8Array;
20
+ /** Inclusive upper bound. */
21
+ lte?: Uint8Array;
22
+ /** Exclusive upper bound. */
23
+ lt?: Uint8Array;
24
+ /** Reverse iteration order. */
25
+ reverse?: boolean;
26
+ /** Maximum number of entries to yield. */
27
+ limit?: number;
28
+ /** Skip values (return zero-length Uint8Array for value). Used by `getApproximateBytesUsed`. */
29
+ keys?: boolean;
30
+ }
31
+ /** Cursor over a `LevelDBLike` range scan. Caller must `close()` exactly once. */
32
+ export interface LevelDBIteratorLike {
33
+ /** Return the next entry, or `undefined` when the range is exhausted. */
34
+ next(): Promise<[Uint8Array, Uint8Array] | undefined>;
35
+ /** Release any native resources held by the iterator. */
36
+ close(): Promise<void>;
37
+ }
38
+ /** Atomic batch of `put` / `delete` operations against a single database. */
39
+ export interface LevelDBWriteBatchLike {
40
+ put(key: Uint8Array, value: Uint8Array): this;
41
+ delete(key: Uint8Array): this;
42
+ /** Commit the batch atomically. */
43
+ write(): Promise<void>;
44
+ }
45
+ /**
46
+ * Minimal LevelDB driver surface used by this package.
47
+ *
48
+ * Wraps either `rn-leveldb` (in production) or `classic-level` (in tests).
49
+ * The interface is `Promise`-returning on every method so the rn-leveldb
50
+ * adapter — which forwards to a synchronous native module — can stay
51
+ * uniform with `classic-level`'s native async API.
52
+ */
53
+ export interface LevelDBLike {
54
+ get(key: Uint8Array): Promise<Uint8Array | undefined>;
55
+ put(key: Uint8Array, value: Uint8Array): Promise<void>;
56
+ delete(key: Uint8Array): Promise<void>;
57
+ batch(): LevelDBWriteBatchLike;
58
+ iterator(options?: LevelDBIteratorOptions): LevelDBIteratorLike;
59
+ /** Release the underlying database handle. */
60
+ close(): Promise<void>;
61
+ }
62
+ /**
63
+ * Drain an iterator into an array. Used by storage classes so a native
64
+ * iterator never stays open across consumer awaits — same rationale as the
65
+ * IndexedDB and SQLite backends.
66
+ */
67
+ export declare function drain(iter: LevelDBIteratorLike): Promise<Array<[Uint8Array, Uint8Array]>>;
68
+ //# sourceMappingURL=leveldb-like.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leveldb-like.d.ts","sourceRoot":"","sources":["../../src/leveldb-like.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uDAAuD;AACvD,MAAM,WAAW,sBAAsB;IACtC,6BAA6B;IAC7B,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6BAA6B;IAC7B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,6BAA6B;IAC7B,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6BAA6B;IAC7B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IACnC,yEAAyE;IACzE,IAAI,IAAI,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,CAAC;IACtD,yDAAyD;IACzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,6EAA6E;AAC7E,MAAM,WAAW,qBAAqB;IACrC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9C,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,mCAAmC;IACnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC3B,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,IAAI,qBAAqB,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,mBAAmB,CAAC;IAChE,8CAA8C;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAY/F"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Package-private LevelDB driver surface.
3
+ *
4
+ * The storage classes (`LevelDBRawStorage`, `LevelDBKVStore`) and the identity
5
+ * helper (`loadOrCreateRNPeerKey`) only depend on the interfaces declared here
6
+ * — never on `rn-leveldb` directly. That lets the suite run under Node mocha
7
+ * against `classic-level`, matching the pattern `db-p2p-storage-ns` uses with
8
+ * `node:sqlite` and `db-p2p-storage-web` uses with `fake-indexeddb`.
9
+ *
10
+ * Only `openOptimysticRNDb`, the user-facing constructors, and the identity
11
+ * helper are exported from `index.ts`; the interfaces in this file are
12
+ * internal — consumers never see them.
13
+ */
14
+ /**
15
+ * Drain an iterator into an array. Used by storage classes so a native
16
+ * iterator never stays open across consumer awaits — same rationale as the
17
+ * IndexedDB and SQLite backends.
18
+ */
19
+ export async function drain(iter) {
20
+ const out = [];
21
+ try {
22
+ while (true) {
23
+ const entry = await iter.next();
24
+ if (!entry)
25
+ break;
26
+ out.push(entry);
27
+ }
28
+ }
29
+ finally {
30
+ await iter.close();
31
+ }
32
+ return out;
33
+ }
34
+ //# sourceMappingURL=leveldb-like.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leveldb-like.js","sourceRoot":"","sources":["../../src/leveldb-like.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsDH;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAyB;IACpD,MAAM,GAAG,GAAoC,EAAE,CAAC;IAChD,IAAI,CAAC;QACJ,OAAO,IAAI,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK;gBAAE,MAAM;YAClB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;YAAS,CAAC;QACV,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}
@@ -1,48 +1,35 @@
1
- import type { BlockId, IBlock, Transform, ActionId, ActionRev } from '@optimystic/db-core';
1
+ import type { ActionId, ActionRev, BlockId, IBlock, Transform } from '@optimystic/db-core';
2
2
  import type { BlockMetadata, IRawStorage } from '@optimystic/db-p2p';
3
- /** MMKV storage interface matching react-native-mmkv */
4
- export interface MMKV {
5
- getString(key: string): string | undefined;
6
- set(key: string, value: string): void;
7
- delete(key: string): void;
8
- getAllKeys(): string[];
9
- contains(key: string): boolean;
10
- }
11
- export interface MMKVStorageOptions {
12
- /** The MMKV instance to use */
13
- mmkv: MMKV;
14
- /** Optional prefix for all keys to namespace this storage */
15
- prefix?: string;
16
- }
17
- export declare class MMKVRawStorage implements IRawStorage {
18
- private readonly mmkv;
19
- private readonly prefix;
20
- constructor(options: MMKVStorageOptions);
3
+ import { type LevelDBLike } from './leveldb-like.js';
4
+ /**
5
+ * LevelDB-backed `IRawStorage` implementation for React Native peers.
6
+ *
7
+ * All data lives in a single LevelDB database; per-store partitioning is by a
8
+ * leading tag byte (see `./keys.ts`). `listRevisions` and
9
+ * `listPendingTransactions` use range iterators with explicit bounds, drained
10
+ * into an array before yielding (same rationale as the IndexedDB / SQLite
11
+ * backends — a native iterator must not stay open across consumer awaits).
12
+ *
13
+ * `promotePendingTransaction` runs as a single `WriteBatch`, making the
14
+ * pending → committed move atomic against crashes.
15
+ */
16
+ export declare class LevelDBRawStorage implements IRawStorage {
17
+ private readonly db;
18
+ constructor(db: LevelDBLike);
21
19
  getMetadata(blockId: BlockId): Promise<BlockMetadata | undefined>;
22
20
  saveMetadata(blockId: BlockId, metadata: BlockMetadata): Promise<void>;
23
21
  getRevision(blockId: BlockId, rev: number): Promise<ActionId | undefined>;
24
22
  saveRevision(blockId: BlockId, rev: number, actionId: ActionId): Promise<void>;
23
+ listRevisions(blockId: BlockId, startRev: number, endRev: number): AsyncIterable<ActionRev>;
25
24
  getPendingTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
26
25
  savePendingTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
27
26
  deletePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
28
27
  listPendingTransactions(blockId: BlockId): AsyncIterable<ActionId>;
29
28
  getTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
30
29
  saveTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
31
- listRevisions(blockId: BlockId, startRev: number, endRev: number): AsyncIterable<ActionRev>;
32
30
  getMaterializedBlock(blockId: BlockId, actionId: ActionId): Promise<IBlock | undefined>;
33
31
  saveMaterializedBlock(blockId: BlockId, actionId: ActionId, block?: IBlock): Promise<void>;
34
32
  getApproximateBytesUsed(): Promise<number>;
35
33
  promotePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
36
- private metadataKey;
37
- private revisionKey;
38
- private pendingKey;
39
- private transactionKey;
40
- private materializedKey;
41
- private pendingIndexKey;
42
- private getJson;
43
- private setJson;
44
- private getPendingIndex;
45
- private addToPendingIndex;
46
- private removeFromPendingIndex;
47
34
  }
48
- //# sourceMappingURL=mmkv-storage.d.ts.map
35
+ //# sourceMappingURL=leveldb-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leveldb-storage.d.ts","sourceRoot":"","sources":["../../src/leveldb-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAS,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAmB5D;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,YAAW,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,WAAW;IAEtC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAMjE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAMzE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7E,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC;IAkB5F,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAM3F,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjG,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5E,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC;IAQnE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAMpF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1F,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAMvF,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1F,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAoB1C,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAapF"}