@optimystic/db-p2p 0.24.2 → 0.25.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 → README.md} +688 -668
- package/dist/src/cluster/block-transfer-service.d.ts +133 -10
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +155 -9
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/block-transfer.d.ts +67 -7
- package/dist/src/cluster/block-transfer.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer.js +127 -24
- package/dist/src/cluster/block-transfer.js.map +1 -1
- package/dist/src/cluster/certified-claims.d.ts +170 -0
- package/dist/src/cluster/certified-claims.d.ts.map +1 -0
- package/dist/src/cluster/certified-claims.js +200 -0
- package/dist/src/cluster/certified-claims.js.map +1 -0
- package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
- package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
- package/dist/src/cluster/client-signature-verifier.js +33 -0
- package/dist/src/cluster/client-signature-verifier.js.map +1 -0
- package/dist/src/cluster/cluster-policy.d.ts +9 -3
- package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
- package/dist/src/cluster/cluster-policy.js +111 -27
- package/dist/src/cluster/cluster-policy.js.map +1 -1
- package/dist/src/cluster/cluster-repo.d.ts +140 -11
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +485 -29
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-proof.d.ts +134 -0
- package/dist/src/cluster/commit-proof.d.ts.map +1 -0
- package/dist/src/cluster/commit-proof.js +263 -0
- package/dist/src/cluster/commit-proof.js.map +1 -0
- package/dist/src/cluster/quorum-restore.d.ts +95 -8
- package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
- package/dist/src/cluster/quorum-restore.js +113 -14
- package/dist/src/cluster/quorum-restore.js.map +1 -1
- package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
- package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
- package/dist/src/cluster/rebalance-monitor.js +207 -5
- package/dist/src/cluster/rebalance-monitor.js.map +1 -1
- package/dist/src/cluster/reconcile-block.d.ts +27 -7
- package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
- package/dist/src/cluster/reconcile-block.js +179 -38
- package/dist/src/cluster/reconcile-block.js.map +1 -1
- package/dist/src/cluster/service.d.ts +13 -4
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +17 -18
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +8 -2
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +7 -7
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/host.d.ts.map +1 -1
- package/dist/src/cohort-topic/host.js +8 -7
- package/dist/src/cohort-topic/host.js.map +1 -1
- package/dist/src/cohort-topic/stream-util.d.ts +7 -6
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
- package/dist/src/cohort-topic/stream-util.js +14 -41
- package/dist/src/cohort-topic/stream-util.js.map +1 -1
- package/dist/src/dispute/cascade.d.ts +7 -8
- package/dist/src/dispute/cascade.d.ts.map +1 -1
- package/dist/src/dispute/cascade.js +24 -7
- package/dist/src/dispute/cascade.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +5 -0
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +13 -3
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +33 -15
- package/dist/src/dispute/invalidation.d.ts.map +1 -1
- package/dist/src/dispute/invalidation.js +127 -34
- package/dist/src/dispute/invalidation.js.map +1 -1
- package/dist/src/dispute/service.d.ts.map +1 -1
- package/dist/src/dispute/service.js +2 -1
- package/dist/src/dispute/service.js.map +1 -1
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +14 -10
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +28 -58
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +38 -7
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +148 -63
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/network/open-protocol-stream.d.ts +56 -0
- package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
- package/dist/src/network/open-protocol-stream.js +60 -0
- package/dist/src/network/open-protocol-stream.js.map +1 -0
- package/dist/src/network/register-protocol-handler.d.ts +66 -0
- package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
- package/dist/src/network/register-protocol-handler.js +51 -0
- package/dist/src/network/register-protocol-handler.js.map +1 -0
- package/dist/src/peer-address-book.d.ts +60 -2
- package/dist/src/peer-address-book.d.ts.map +1 -1
- package/dist/src/peer-address-book.js +89 -1
- package/dist/src/peer-address-book.js.map +1 -1
- package/dist/src/pend-validation.d.ts +65 -0
- package/dist/src/pend-validation.d.ts.map +1 -0
- package/dist/src/pend-validation.js +69 -0
- package/dist/src/pend-validation.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
- package/dist/src/reactivity/notify-transport.js +2 -1
- package/dist/src/reactivity/notify-transport.js.map +1 -1
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
- package/dist/src/reactivity/push-state-gossip.js +2 -1
- package/dist/src/reactivity/push-state-gossip.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +32 -6
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +44 -10
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +181 -25
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +650 -62
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/served-repo-proxy.d.ts +30 -0
- package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
- package/dist/src/repo/served-repo-proxy.js +50 -0
- package/dist/src/repo/served-repo-proxy.js.map +1 -0
- package/dist/src/repo/service.d.ts +16 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +18 -16
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/reputation/types.d.ts +3 -1
- package/dist/src/reputation/types.d.ts.map +1 -1
- package/dist/src/reputation/types.js +3 -1
- package/dist/src/reputation/types.js.map +1 -1
- package/dist/src/rn.d.ts +24 -2
- package/dist/src/rn.d.ts.map +1 -1
- package/dist/src/rn.js +33 -4
- package/dist/src/rn.js.map +1 -1
- package/dist/src/storage/block-archive.d.ts +153 -0
- package/dist/src/storage/block-archive.d.ts.map +1 -0
- package/dist/src/storage/block-archive.js +194 -0
- package/dist/src/storage/block-archive.js.map +1 -0
- package/dist/src/storage/block-latch.d.ts +92 -0
- package/dist/src/storage/block-latch.d.ts.map +1 -0
- package/dist/src/storage/block-latch.js +132 -0
- package/dist/src/storage/block-latch.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +169 -12
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +415 -152
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/cached-raw-storage.d.ts +5 -1
- package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/cached-raw-storage.js +16 -1
- package/dist/src/storage/cached-raw-storage.js.map +1 -1
- package/dist/src/storage/cached-store-driver.d.ts +14 -4
- package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
- package/dist/src/storage/cached-store-driver.js +39 -5
- package/dist/src/storage/cached-store-driver.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +70 -19
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/i-block-storage.js +21 -1
- package/dist/src/storage/i-block-storage.js.map +1 -1
- package/dist/src/storage/i-raw-storage.d.ts +38 -0
- package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.d.ts +14 -8
- package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
- package/dist/src/storage/kv-raw-storage.js +29 -9
- package/dist/src/storage/kv-raw-storage.js.map +1 -1
- package/dist/src/storage/memory-store-driver.d.ts +4 -1
- package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
- package/dist/src/storage/memory-store-driver.js +22 -2
- package/dist/src/storage/memory-store-driver.js.map +1 -1
- package/dist/src/storage/raw-store-codec.js +2 -2
- package/dist/src/storage/raw-store-driver.d.ts +44 -3
- package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.d.ts +60 -3
- package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
- package/dist/src/storage/shared-cache-pool.js +68 -4
- package/dist/src/storage/shared-cache-pool.js.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +204 -26
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +422 -119
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/storage/store-identity.d.ts +21 -0
- package/dist/src/storage/store-identity.d.ts.map +1 -0
- package/dist/src/storage/store-identity.js +33 -0
- package/dist/src/storage/store-identity.js.map +1 -0
- package/dist/src/storage/struct.d.ts +15 -0
- package/dist/src/storage/struct.d.ts.map +1 -1
- package/dist/src/storage/with-read-cache.d.ts +92 -0
- package/dist/src/storage/with-read-cache.d.ts.map +1 -0
- package/dist/src/storage/with-read-cache.js +132 -0
- package/dist/src/storage/with-read-cache.js.map +1 -0
- package/dist/src/sync/service.d.ts +13 -3
- package/dist/src/sync/service.d.ts.map +1 -1
- package/dist/src/sync/service.js +7 -30
- package/dist/src/sync/service.js.map +1 -1
- package/dist/src/testing/mesh-harness.d.ts +75 -2
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +193 -81
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
- package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
- package/dist/src/testing/raw-storage-conformance.js +97 -2
- package/dist/src/testing/raw-storage-conformance.js.map +1 -1
- package/package.json +5 -6
- package/src/cluster/block-transfer-service.ts +528 -312
- package/src/cluster/block-transfer.ts +547 -424
- package/src/cluster/certified-claims.ts +319 -0
- package/src/cluster/client-signature-verifier.ts +34 -0
- package/src/cluster/cluster-policy.ts +294 -203
- package/src/cluster/cluster-repo.ts +2501 -2034
- package/src/cluster/commit-proof.ts +344 -0
- package/src/cluster/quorum-restore.ts +348 -223
- package/src/cluster/rebalance-monitor.ts +539 -254
- package/src/cluster/reconcile-block.ts +404 -203
- package/src/cluster/service.ts +23 -20
- package/src/cluster/spread-on-churn.ts +352 -346
- package/src/cohort-topic/host.ts +8 -7
- package/src/cohort-topic/stream-util.ts +14 -43
- package/src/dispute/cascade.ts +31 -15
- package/src/dispute/dispute-service.ts +706 -696
- package/src/dispute/invalidation.ts +162 -52
- package/src/dispute/service.ts +126 -125
- package/src/index.ts +7 -0
- package/src/libp2p-key-network.ts +1204 -1235
- package/src/libp2p-node-base.ts +185 -70
- package/src/network/open-protocol-stream.ts +87 -0
- package/src/network/register-protocol-handler.ts +85 -0
- package/src/peer-address-book.ts +96 -2
- package/src/pend-validation.ts +89 -0
- package/src/reactivity/notify-transport.ts +2 -1
- package/src/reactivity/push-state-gossip.ts +2 -1
- package/src/repo/cluster-coordinator.ts +65 -11
- package/src/repo/coordinator-repo.ts +729 -71
- package/src/repo/served-repo-proxy.ts +55 -0
- package/src/repo/service.ts +25 -16
- package/src/reputation/types.ts +3 -1
- package/src/rn.ts +34 -4
- package/src/storage/block-archive.ts +242 -0
- package/src/storage/block-latch.ts +144 -0
- package/src/storage/block-storage.ts +787 -498
- package/src/storage/cached-raw-storage.ts +21 -1
- package/src/storage/cached-store-driver.ts +898 -859
- package/src/storage/i-block-storage.ts +172 -116
- package/src/storage/i-raw-storage.ts +40 -0
- package/src/storage/kv-raw-storage.ts +34 -9
- package/src/storage/memory-store-driver.ts +26 -2
- package/src/storage/raw-store-codec.ts +42 -42
- package/src/storage/raw-store-driver.ts +45 -3
- package/src/storage/shared-cache-pool.ts +516 -452
- package/src/storage/storage-repo.ts +1421 -1014
- package/src/storage/store-identity.ts +41 -0
- package/src/storage/struct.ts +52 -34
- package/src/storage/with-read-cache.ts +182 -0
- package/src/sync/service.ts +178 -198
- package/src/testing/mesh-harness.ts +524 -344
- package/src/testing/raw-storage-conformance.ts +114 -2
|
@@ -1,43 +1,84 @@
|
|
|
1
|
-
import type { IBlock, Transform, ActionId, ActionRev } from "@optimystic/db-core";
|
|
2
|
-
|
|
1
|
+
import type { BlockId, IBlock, Transform, ActionId, ActionRev } from "@optimystic/db-core";
|
|
2
|
+
import type { BlockCommitProof } from "../cluster/commit-proof.js";
|
|
3
|
+
import type { BlockWriteLatch } from "./block-latch.js";
|
|
4
|
+
/**
|
|
5
|
+
* Thrown by {@link IBlockStorage.getBlock} when the block has metadata here but the target revision
|
|
6
|
+
* lies outside the locally held revision ranges — this node holds no local records that can serve
|
|
7
|
+
* it. Not a fault: it is the signal a caller that is allowed to heal (only `StorageRepo.get`, under
|
|
8
|
+
* the block's write latch) turns into a {@link IBlockStorage.restoreRevision}; every other caller
|
|
9
|
+
* treats it like any other unreadable-base condition.
|
|
10
|
+
*
|
|
11
|
+
* It lives beside the interface rather than beside `BlockStorage` because it is part of the
|
|
12
|
+
* `getBlock` contract: an alternate `IBlockStorage` implementation must be able to throw it, and
|
|
13
|
+
* `StorageRepo` must be able to catch it, without either depending on the concrete implementation.
|
|
14
|
+
*/
|
|
15
|
+
export declare class RevisionNotCoveredError extends Error {
|
|
16
|
+
readonly blockId: BlockId;
|
|
17
|
+
readonly rev: number;
|
|
18
|
+
constructor(blockId: BlockId, rev: number);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Interface for block-level storage operations.
|
|
22
|
+
*
|
|
23
|
+
* **One block, one write lock.** Every method that writes — metadata, revision records, action
|
|
24
|
+
* transforms, pending records, materializations, proofs — takes a {@link BlockWriteLatch} token as
|
|
25
|
+
* its LAST parameter. The token is proof the caller holds this block's write latch
|
|
26
|
+
* (`blockWriteLatchKey(blockId)`, see `block-latch.ts`), which is the only thing that keeps two
|
|
27
|
+
* writers' read-modify-writes of the metadata blob from silently undoing each other. Only
|
|
28
|
+
* `acquireBlockWriteLatch` / `withBlockWriteLatch` can mint a token, and an implementation must
|
|
29
|
+
* reject a token minted for a different block.
|
|
30
|
+
*/
|
|
3
31
|
export interface IBlockStorage {
|
|
4
32
|
/** Gets the latest revision information for this block */
|
|
5
33
|
getLatest(): Promise<ActionRev | undefined>;
|
|
6
34
|
/**
|
|
7
|
-
* Gets a materialized block at the given revision
|
|
8
|
-
* Returns undefined when
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
35
|
+
* Gets a materialized block at the given revision, from LOCAL records only — this never fetches
|
|
36
|
+
* from a peer. Returns `undefined` when this node has never seen the block (no metadata) or when
|
|
37
|
+
* it is pending-only (metadata seeded by a pending transaction, nothing committed) and no `rev`
|
|
38
|
+
* was named. Throws {@link RevisionNotCoveredError} when the target revision (`rev`, or `latest.rev`)
|
|
39
|
+
* lies outside `meta.ranges` — the caller decides whether to heal that gap with
|
|
40
|
+
* {@link restoreRevision} under the block's write latch (`StorageRepo.get` does; the commit path
|
|
41
|
+
* deliberately does not). Throws a plain `Error` when the revision is covered but cannot be
|
|
42
|
+
* materialized from the records held (truncated history — genuine corruption).
|
|
12
43
|
*/
|
|
13
44
|
getBlock(rev?: number): Promise<{
|
|
14
45
|
block: IBlock;
|
|
15
46
|
actionRev: ActionRev;
|
|
16
47
|
} | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* Fill a gap in local revision history by fetching `rev` from a peer (the restore wire) and
|
|
50
|
+
* recording the vetted coverage. No-op when `rev` is already covered. Throws when the block has
|
|
51
|
+
* no metadata here (a never-seen block is not restored at this layer — see the note in
|
|
52
|
+
* `BlockStorage.getBlock`) or when no peer could supply an acceptable archive.
|
|
53
|
+
*/
|
|
54
|
+
restoreRevision(rev: number, latch: BlockWriteLatch): Promise<void>;
|
|
17
55
|
/** Gets an action by ID */
|
|
18
56
|
getTransaction(actionId: ActionId): Promise<Transform | undefined>;
|
|
57
|
+
/** The commit proof stored for a revision, if one was retained (see IRawStorage.getBlockProof). */
|
|
58
|
+
getBlockProof(rev: number): Promise<BlockCommitProof | undefined>;
|
|
59
|
+
/** Persists the commit proof for a revision (see IRawStorage.saveBlockProof). */
|
|
60
|
+
saveBlockProof(rev: number, proof: BlockCommitProof, latch: BlockWriteLatch): Promise<void>;
|
|
19
61
|
/** Gets a pending action by ID */
|
|
20
62
|
getPendingTransaction(actionId: ActionId): Promise<Transform | undefined>;
|
|
21
63
|
/** Lists all pending action IDs */
|
|
22
64
|
listPendingTransactions(): AsyncIterable<ActionId>;
|
|
23
|
-
/** Saves a pending action */
|
|
24
|
-
savePendingTransaction(actionId: ActionId, transform: Transform): Promise<void>;
|
|
65
|
+
/** Saves a pending action (seeding this block's metadata when it has none). */
|
|
66
|
+
savePendingTransaction(actionId: ActionId, transform: Transform, latch: BlockWriteLatch): Promise<void>;
|
|
25
67
|
/** Deletes a pending action */
|
|
26
|
-
deletePendingTransaction(actionId: ActionId): Promise<void>;
|
|
68
|
+
deletePendingTransaction(actionId: ActionId, latch: BlockWriteLatch): Promise<void>;
|
|
27
69
|
/** Lists revisions in ascending or descending order between startRev and endRev (inclusive) */
|
|
28
70
|
listRevisions(startRev: number, endRev: number): AsyncIterable<ActionRev>;
|
|
29
71
|
/** Saves a materialized block */
|
|
30
|
-
saveMaterializedBlock(actionId: ActionId, block: IBlock | undefined): Promise<void>;
|
|
72
|
+
saveMaterializedBlock(actionId: ActionId, block: IBlock | undefined, latch: BlockWriteLatch): Promise<void>;
|
|
31
73
|
/**
|
|
32
74
|
* Delete the materialized copy at `prior` if it is now redundant under the checkpoint
|
|
33
75
|
* retention policy (not the tip, not its range floor, not a checkpoint rev). The forward
|
|
34
76
|
* transform for `prior.rev` is retained, so the rev stays reconstructible by replay.
|
|
35
77
|
* No-op if `prior.rev` must be retained or has no materialization (e.g. a tombstone rev).
|
|
36
|
-
* Must be called under the per-block commit latch (serialized against concurrent commit).
|
|
37
78
|
*/
|
|
38
|
-
pruneSupersededMaterialization(prior: ActionRev): Promise<void>;
|
|
79
|
+
pruneSupersededMaterialization(prior: ActionRev, latch: BlockWriteLatch): Promise<void>;
|
|
39
80
|
/** Saves a revision */
|
|
40
|
-
saveRevision(rev: number, actionId: ActionId): Promise<void>;
|
|
81
|
+
saveRevision(rev: number, actionId: ActionId, latch: BlockWriteLatch): Promise<void>;
|
|
41
82
|
/**
|
|
42
83
|
* Promotes a pending action to committed, MOVING the record from the pending namespace to the
|
|
43
84
|
* committed one in a single atomic step.
|
|
@@ -50,9 +91,9 @@ export interface IBlockStorage {
|
|
|
50
91
|
* and is reported as a phantom conflicting action by `StorageRepo.pend` on every later write to
|
|
51
92
|
* the block.
|
|
52
93
|
*/
|
|
53
|
-
promotePendingTransaction(actionId: ActionId): Promise<void>;
|
|
94
|
+
promotePendingTransaction(actionId: ActionId, latch: BlockWriteLatch): Promise<void>;
|
|
54
95
|
/** Sets the latest revision information */
|
|
55
|
-
setLatest(latest: ActionRev): Promise<void>;
|
|
96
|
+
setLatest(latest: ActionRev, latch: BlockWriteLatch): Promise<void>;
|
|
56
97
|
/**
|
|
57
98
|
* Persist a replica of a block received out-of-band (churn re-replication).
|
|
58
99
|
*
|
|
@@ -70,8 +111,18 @@ export interface IBlockStorage {
|
|
|
70
111
|
* No-op (still durable) when an equal-or-newer revision is already present: `latest`
|
|
71
112
|
* is never downgraded. Idempotent for a fixed `(rev, actionId)`. Returns the
|
|
72
113
|
* effective latest `ActionRev`.
|
|
114
|
+
*
|
|
115
|
+
* `proof` is persisted for `source.rev` and MUST already be verified by the caller against
|
|
116
|
+
* these exact bytes (`verifyBlockCommitProofContent` — the digest check is what binds a proof
|
|
117
|
+
* to the block content). An unverified proof passed here would be re-served onward as evidence
|
|
118
|
+
* this node never checked. The monotonic no-op persists nothing, proof included — a proof for an
|
|
119
|
+
* already-held revision is back-filled one layer up, by `StorageRepo.saveReplicatedBlock`, which
|
|
120
|
+
* first checks the declared digest against LOCAL content (these bytes may not be the held bytes).
|
|
121
|
+
*
|
|
122
|
+
* `source` and `proof` are positional-but-optional (pass `undefined` when absent) so the latch
|
|
123
|
+
* token can stay in the last position like every other writer.
|
|
73
124
|
*/
|
|
74
|
-
saveReplica(block: IBlock, source
|
|
125
|
+
saveReplica(block: IBlock, source: ActionRev | undefined, proof: BlockCommitProof | undefined, latch: BlockWriteLatch): Promise<ActionRev>;
|
|
75
126
|
/**
|
|
76
127
|
* Writes a forward TOMBSTONE revision that reverses a block creation: persists `rev → actionId`,
|
|
77
128
|
* a `{ delete: true }` transform, and NO materialized block, then merges `[rev, rev+1]` into
|
|
@@ -85,7 +136,7 @@ export interface IBlockStorage {
|
|
|
85
136
|
* Idempotent for a fixed `(rev, actionId)`; never downgrades `latest` (a no-op — still durable —
|
|
86
137
|
* when an equal-or-newer revision is already present). Returns the effective latest `ActionRev`.
|
|
87
138
|
*/
|
|
88
|
-
saveDeletion(source: ActionRev): Promise<ActionRev>;
|
|
139
|
+
saveDeletion(source: ActionRev, latch: BlockWriteLatch): Promise<ActionRev>;
|
|
89
140
|
/**
|
|
90
141
|
* Reconciles `metadata.latest` with the highest contiguous fully-promoted revision in
|
|
91
142
|
* the revisions table. Intended for post-crash recovery of the Crash-D3 gap, where
|
|
@@ -99,7 +150,7 @@ export interface IBlockStorage {
|
|
|
99
150
|
*
|
|
100
151
|
* Idempotent and monotonic (latest only advances forward).
|
|
101
152
|
*/
|
|
102
|
-
recover(): Promise<{
|
|
153
|
+
recover(latch: BlockWriteLatch): Promise<{
|
|
103
154
|
reconciled: boolean;
|
|
104
155
|
latest?: ActionRev;
|
|
105
156
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i-block-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"i-block-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Thrown by {@link IBlockStorage.getBlock} when the block has metadata here but the target revision
|
|
3
|
+
* lies outside the locally held revision ranges — this node holds no local records that can serve
|
|
4
|
+
* it. Not a fault: it is the signal a caller that is allowed to heal (only `StorageRepo.get`, under
|
|
5
|
+
* the block's write latch) turns into a {@link IBlockStorage.restoreRevision}; every other caller
|
|
6
|
+
* treats it like any other unreadable-base condition.
|
|
7
|
+
*
|
|
8
|
+
* It lives beside the interface rather than beside `BlockStorage` because it is part of the
|
|
9
|
+
* `getBlock` contract: an alternate `IBlockStorage` implementation must be able to throw it, and
|
|
10
|
+
* `StorageRepo` must be able to catch it, without either depending on the concrete implementation.
|
|
11
|
+
*/
|
|
12
|
+
export class RevisionNotCoveredError extends Error {
|
|
13
|
+
blockId;
|
|
14
|
+
rev;
|
|
15
|
+
constructor(blockId, rev) {
|
|
16
|
+
super(`Block ${blockId} revision ${rev} is not covered by local records`);
|
|
17
|
+
this.blockId = blockId;
|
|
18
|
+
this.rev = rev;
|
|
19
|
+
this.name = 'RevisionNotCoveredError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
2
22
|
//# sourceMappingURL=i-block-storage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i-block-storage.js","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"i-block-storage.js","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC5B;IAA2B;IAAhD,YAAqB,OAAgB,EAAW,GAAW;QAC1D,KAAK,CAAC,SAAS,OAAO,aAAa,GAAG,kCAAkC,CAAC,CAAC;QADtD,YAAO,GAAP,OAAO,CAAS;QAAW,QAAG,GAAH,GAAG,CAAQ;QAE1D,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACvC,CAAC;CACD"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { BlockId, ActionId, ActionRev, Transform, IBlock } from "@optimystic/db-core";
|
|
2
|
+
import type { BlockCommitProof } from "../cluster/commit-proof.js";
|
|
2
3
|
import type { BlockMetadata } from "./struct.js";
|
|
4
|
+
import type { StoreIdentity } from "./store-identity.js";
|
|
3
5
|
export interface IRawStorage {
|
|
4
6
|
getMetadata(blockId: BlockId): Promise<BlockMetadata | undefined>;
|
|
5
7
|
saveMetadata(blockId: BlockId, metadata: BlockMetadata): Promise<void>;
|
|
@@ -13,9 +15,45 @@ export interface IRawStorage {
|
|
|
13
15
|
listPendingTransactions(blockId: BlockId): AsyncIterable<ActionId>;
|
|
14
16
|
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
|
|
15
17
|
saveTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* The commit proof stored for a revision, if one was retained. Keyed by revision: the proof lives
|
|
20
|
+
* and dies with the REVISION record, not the materialization, so the checkpoint sweep
|
|
21
|
+
* (`pruneSupersededMaterialization`) never touches it — that is what lets it outlive the
|
|
22
|
+
* 60-second in-memory commit-cert TTL. Whatever deletes a revision record must delete its proof;
|
|
23
|
+
* no such site exists today (`RawStoreDriver` has no revision delete at all — invalidations write
|
|
24
|
+
* compensating FORWARD revisions), so this is a contract note, not a wired path.
|
|
25
|
+
*/
|
|
26
|
+
getBlockProof(blockId: BlockId, rev: number): Promise<BlockCommitProof | undefined>;
|
|
27
|
+
saveBlockProof(blockId: BlockId, rev: number, proof: BlockCommitProof): Promise<void>;
|
|
16
28
|
getMaterializedBlock(blockId: BlockId, actionId: ActionId): Promise<IBlock | undefined>;
|
|
17
29
|
saveMaterializedBlock(blockId: BlockId, actionId: ActionId, block?: IBlock): Promise<void>;
|
|
18
30
|
promotePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* A stable, process-scoped string naming what this storage is ultimately backed by (a
|
|
33
|
+
* resolved directory, an open database handle). Wrappers pass it through from whatever they
|
|
34
|
+
* wrap, so a cache and the storage it fronts name the same store — e.g.
|
|
35
|
+
* `new CachedRawStorage(new FileRawStorage(dir)).getStoreIdentity()` is `'file:<resolved dir>'`.
|
|
36
|
+
*
|
|
37
|
+
* Contract — note it is ONE-DIRECTIONAL; read both halves before consuming it:
|
|
38
|
+
* - Two storages over DIFFERENT locations MUST NOT return equal strings. So **equality
|
|
39
|
+
* proves sameness**, and a consumer may merge on it. (The fs backend documents one exotic
|
|
40
|
+
* Windows exception at its own site.)
|
|
41
|
+
* - Two storages over the SAME location SHOULD return equal strings, but this is
|
|
42
|
+
* best-effort and several backends knowingly under-approximate: two handles opened over
|
|
43
|
+
* one database, or two spellings of one directory that cannot be collapsed synchronously,
|
|
44
|
+
* read as two identities. So **inequality proves nothing** — never treat it as evidence
|
|
45
|
+
* that two storages are distinct stores. Each backend's `NOTE:` states its own gaps.
|
|
46
|
+
* - Every string is scheme-prefixed so backends cannot collide: `file:`, `sqlite-handle:`,
|
|
47
|
+
* `idb-handle:`, `leveldb-handle:`. Compared for equality only — never parsed.
|
|
48
|
+
* - Stable for the storage object's whole life; fixed at construction.
|
|
49
|
+
* - OPTIONAL BY DESIGN. A backend that cannot honour the contract omits the method entirely
|
|
50
|
+
* and callers fall back to per-object behavior. Never install a stub that returns
|
|
51
|
+
* `undefined` — feature-detection (`typeof storage.getStoreIdentity === 'function'`) must
|
|
52
|
+
* see the backend's true capability, the same trap `KvRawStorage`'s class doc calls out
|
|
53
|
+
* for `listBlockIds`.
|
|
54
|
+
* - It identifies the STORE, not its contents.
|
|
55
|
+
*/
|
|
56
|
+
getStoreIdentity?(): StoreIdentity;
|
|
19
57
|
/**
|
|
20
58
|
* Approximate bytes currently stored by this backend.
|
|
21
59
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i-raw-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-raw-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"i-raw-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-raw-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,WAAW;IAE3B,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAClE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGvE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC1E,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,4HAA4H;IAC5H,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAG5F,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAC5F,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEnE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACrF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3F;;;;;;;OAOG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IACpF,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGtF,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxF,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG3F,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/E;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAAgB,CAAC,IAAI,aAAa,CAAC;IAEnC;;;;;;;OAOG;IACH,uBAAuB,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;CACxC"}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import type { BlockId, ActionId, ActionRev, Transform, IBlock } from "@optimystic/db-core";
|
|
2
|
+
import type { BlockCommitProof } from "../cluster/commit-proof.js";
|
|
2
3
|
import type { BlockMetadata } from "./struct.js";
|
|
3
4
|
import type { IRawStorage } from "./i-raw-storage.js";
|
|
4
5
|
import type { RawStoreDriver } from "./raw-store-driver.js";
|
|
6
|
+
import type { StoreIdentity } from "./store-identity.js";
|
|
5
7
|
/**
|
|
6
8
|
* Shared ordered-KV storage kernel. Implements the full {@link IRawStorage}
|
|
7
9
|
* surface over a {@link RawStoreDriver}, owning all value (de)serialization and
|
|
8
|
-
* call orchestration so each backend only has to expose its
|
|
10
|
+
* call orchestration so each backend only has to expose its six logical stores
|
|
9
11
|
* as bytes-valued maps over its native mechanism.
|
|
10
12
|
*
|
|
11
13
|
* The genuinely-shared logic lives ABOVE the storage primitive: the JSON/string
|
|
12
|
-
* codec for the
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* directory tree.
|
|
14
|
+
* codec for the value types, `listRevisions`' lo/hi/reverse bound computation,
|
|
15
|
+
* `saveMaterializedBlock`'s put-or-delete branch, and the passthroughs. Key
|
|
16
|
+
* layout / storage topology stays in the driver, because the backends do NOT
|
|
17
|
+
* share one — LevelDB is a single ordered byte keyspace, SQLite six relational
|
|
18
|
+
* tables, IndexedDB six object stores, the filesystem a directory tree.
|
|
18
19
|
*/
|
|
19
20
|
export declare class KvRawStorage implements IRawStorage {
|
|
20
21
|
private readonly driver;
|
|
@@ -22,10 +23,13 @@ export declare class KvRawStorage implements IRawStorage {
|
|
|
22
23
|
* Optional passthroughs are wired in the constructor ONLY when the driver
|
|
23
24
|
* provides them, so a `StorageMonitor` / owned-block seed that feature-detects
|
|
24
25
|
* (`typeof storage.listBlockIds === 'function'`) sees the driver's true
|
|
25
|
-
* capability instead of a stub that silently reports 0 / no seed.
|
|
26
|
+
* capability instead of a stub that silently reports 0 / no seed. The same rule
|
|
27
|
+
* governs `getStoreIdentity`: a stub returning `undefined` would make every store
|
|
28
|
+
* look identity-less to consumers that dedupe on it.
|
|
26
29
|
*/
|
|
27
30
|
listBlockIds?: () => AsyncIterable<BlockId>;
|
|
28
31
|
getApproximateBytesUsed?: () => Promise<number>;
|
|
32
|
+
getStoreIdentity?: () => StoreIdentity;
|
|
29
33
|
constructor(driver: RawStoreDriver);
|
|
30
34
|
getMetadata(blockId: BlockId): Promise<BlockMetadata | undefined>;
|
|
31
35
|
saveMetadata(blockId: BlockId, metadata: BlockMetadata): Promise<void>;
|
|
@@ -38,6 +42,8 @@ export declare class KvRawStorage implements IRawStorage {
|
|
|
38
42
|
listPendingTransactions(blockId: BlockId): AsyncIterable<ActionId>;
|
|
39
43
|
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Transform | undefined>;
|
|
40
44
|
saveTransaction(blockId: BlockId, actionId: ActionId, transform: Transform): Promise<void>;
|
|
45
|
+
getBlockProof(blockId: BlockId, rev: number): Promise<BlockCommitProof | undefined>;
|
|
46
|
+
saveBlockProof(blockId: BlockId, rev: number, proof: BlockCommitProof): Promise<void>;
|
|
41
47
|
getMaterializedBlock(blockId: BlockId, actionId: ActionId): Promise<IBlock | undefined>;
|
|
42
48
|
saveMaterializedBlock(blockId: BlockId, actionId: ActionId, block?: IBlock): Promise<void>;
|
|
43
49
|
promotePendingTransaction(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv-raw-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/kv-raw-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"kv-raw-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/kv-raw-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAa,YAAW,WAAW;IAanC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZnC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5C,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,gBAAgB,CAAC,EAAE,MAAM,aAAa,CAAC;gBAEV,MAAM,EAAE,cAAc;IAc7C,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAejE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAKzE,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;IAc5F,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAK3F,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;IAMnE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAKpF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1F,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAKnF,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrF,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAKvF,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1F,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpF"}
|
|
@@ -2,16 +2,15 @@ import { encodeJson, decodeJson, encodeActionId, decodeActionId } from "./raw-st
|
|
|
2
2
|
/**
|
|
3
3
|
* Shared ordered-KV storage kernel. Implements the full {@link IRawStorage}
|
|
4
4
|
* surface over a {@link RawStoreDriver}, owning all value (de)serialization and
|
|
5
|
-
* call orchestration so each backend only has to expose its
|
|
5
|
+
* call orchestration so each backend only has to expose its six logical stores
|
|
6
6
|
* as bytes-valued maps over its native mechanism.
|
|
7
7
|
*
|
|
8
8
|
* The genuinely-shared logic lives ABOVE the storage primitive: the JSON/string
|
|
9
|
-
* codec for the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* directory tree.
|
|
9
|
+
* codec for the value types, `listRevisions`' lo/hi/reverse bound computation,
|
|
10
|
+
* `saveMaterializedBlock`'s put-or-delete branch, and the passthroughs. Key
|
|
11
|
+
* layout / storage topology stays in the driver, because the backends do NOT
|
|
12
|
+
* share one — LevelDB is a single ordered byte keyspace, SQLite six relational
|
|
13
|
+
* tables, IndexedDB six object stores, the filesystem a directory tree.
|
|
15
14
|
*/
|
|
16
15
|
export class KvRawStorage {
|
|
17
16
|
driver;
|
|
@@ -19,12 +18,18 @@ export class KvRawStorage {
|
|
|
19
18
|
* Optional passthroughs are wired in the constructor ONLY when the driver
|
|
20
19
|
* provides them, so a `StorageMonitor` / owned-block seed that feature-detects
|
|
21
20
|
* (`typeof storage.listBlockIds === 'function'`) sees the driver's true
|
|
22
|
-
* capability instead of a stub that silently reports 0 / no seed.
|
|
21
|
+
* capability instead of a stub that silently reports 0 / no seed. The same rule
|
|
22
|
+
* governs `getStoreIdentity`: a stub returning `undefined` would make every store
|
|
23
|
+
* look identity-less to consumers that dedupe on it.
|
|
23
24
|
*/
|
|
24
25
|
listBlockIds;
|
|
25
26
|
getApproximateBytesUsed;
|
|
27
|
+
getStoreIdentity;
|
|
26
28
|
constructor(driver) {
|
|
27
29
|
this.driver = driver;
|
|
30
|
+
if (driver.storeIdentity) {
|
|
31
|
+
this.getStoreIdentity = () => driver.storeIdentity();
|
|
32
|
+
}
|
|
28
33
|
if (driver.listBlockIds) {
|
|
29
34
|
this.listBlockIds = () => driver.listBlockIds();
|
|
30
35
|
}
|
|
@@ -39,7 +44,7 @@ export class KvRawStorage {
|
|
|
39
44
|
}
|
|
40
45
|
// NOTE: every value write funnels through the driver put/delete calls in the
|
|
41
46
|
// methods below (saveMetadata / saveRevision / save*Transaction /
|
|
42
|
-
// saveMaterializedBlock). This is the single choke point where an incremental
|
|
47
|
+
// saveBlockProof / saveMaterializedBlock). This is the single choke point where an incremental
|
|
43
48
|
// byte counter would hook in, replacing the per-driver full-scan
|
|
44
49
|
// getApproximateBytesUsed. The chosen capacity-estimate mechanism is instead a
|
|
45
50
|
// short-TTL cache over the full scan in StorageMonitor (see storage-monitor.ts
|
|
@@ -91,6 +96,21 @@ export class KvRawStorage {
|
|
|
91
96
|
async saveTransaction(blockId, actionId, transform) {
|
|
92
97
|
await this.driver.putTransaction(blockId, actionId, encodeJson(transform));
|
|
93
98
|
}
|
|
99
|
+
// --- Commit proofs (their OWN (blockId, rev)-keyed store — see RawStoreDriver.getProof) ---
|
|
100
|
+
//
|
|
101
|
+
// Proofs deliberately do NOT share the transactions keyspace. Action ids are
|
|
102
|
+
// chosen by whoever originates a write and are never re-derived or format-checked
|
|
103
|
+
// by the storing node, so no reserved action-id prefix can be relied on: a client
|
|
104
|
+
// pending an action literally named `~proof:5`, or a peer's restore archive naming
|
|
105
|
+
// one, used to land on the same key as revision 5's proof and silently overwrite it
|
|
106
|
+
// (or be overwritten by it). Separate stores make that collision unrepresentable.
|
|
107
|
+
async getBlockProof(blockId, rev) {
|
|
108
|
+
const bytes = await this.driver.getProof(blockId, rev);
|
|
109
|
+
return bytes === undefined ? undefined : decodeJson(bytes);
|
|
110
|
+
}
|
|
111
|
+
async saveBlockProof(blockId, rev, proof) {
|
|
112
|
+
await this.driver.putProof(blockId, rev, encodeJson(proof));
|
|
113
|
+
}
|
|
94
114
|
// --- Materialized blocks ---
|
|
95
115
|
async getMaterializedBlock(blockId, actionId) {
|
|
96
116
|
const bytes = await this.driver.getMaterialized(blockId, actionId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv-raw-storage.js","sourceRoot":"","sources":["../../../src/storage/kv-raw-storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kv-raw-storage.js","sourceRoot":"","sources":["../../../src/storage/kv-raw-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BlockId, ActionId } from "@optimystic/db-core";
|
|
2
2
|
import type { RawStoreDriver } from "./raw-store-driver.js";
|
|
3
3
|
/**
|
|
4
|
-
* In-memory {@link RawStoreDriver}: the
|
|
4
|
+
* In-memory {@link RawStoreDriver}: the six logical block-storage stores as
|
|
5
5
|
* `Map`s of `Uint8Array` values. `KvRawStorage` hands this driver bytes produced
|
|
6
6
|
* by `JSON`-encode and reads them back via `JSON`-decode, so every get yields a
|
|
7
7
|
* fresh object and every save stored an independent byte snapshot BY
|
|
@@ -15,6 +15,7 @@ export declare class MemoryStoreDriver implements RawStoreDriver {
|
|
|
15
15
|
private readonly revisions;
|
|
16
16
|
private readonly pending;
|
|
17
17
|
private readonly transactions;
|
|
18
|
+
private readonly proofs;
|
|
18
19
|
private readonly materialized;
|
|
19
20
|
private revisionKey;
|
|
20
21
|
private actionKey;
|
|
@@ -29,6 +30,8 @@ export declare class MemoryStoreDriver implements RawStoreDriver {
|
|
|
29
30
|
listPendingActionIds(blockId: BlockId): AsyncIterable<ActionId>;
|
|
30
31
|
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
31
32
|
putTransaction(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
33
|
+
getProof(blockId: BlockId, rev: number): Promise<Uint8Array | undefined>;
|
|
34
|
+
putProof(blockId: BlockId, rev: number, value: Uint8Array): Promise<void>;
|
|
32
35
|
getMaterialized(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
33
36
|
putMaterialized(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
34
37
|
deleteMaterialized(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store-driver.d.ts","sourceRoot":"","sources":["../../../src/storage/memory-store-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAE9D,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,SAAS;IAMX,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI9D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI3E,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3E,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAqBhH,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIjF,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlF,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC;IAiBhE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIrF,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAItF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-store-driver.d.ts","sourceRoot":"","sources":["../../../src/storage/memory-store-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAE9D,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,SAAS;IAMX,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI9D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI3E,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3E,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAqBhH,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIjF,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlF,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC;IAiBhE,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIrF,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtF,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAItF,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3D,YAAY,IAAI,aAAa,CAAC,OAAO,CAAC;IAUvC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CAY7C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* In-memory {@link RawStoreDriver}: the
|
|
2
|
+
* In-memory {@link RawStoreDriver}: the six logical block-storage stores as
|
|
3
3
|
* `Map`s of `Uint8Array` values. `KvRawStorage` hands this driver bytes produced
|
|
4
4
|
* by `JSON`-encode and reads them back via `JSON`-decode, so every get yields a
|
|
5
5
|
* fresh object and every save stored an independent byte snapshot BY
|
|
@@ -13,6 +13,7 @@ export class MemoryStoreDriver {
|
|
|
13
13
|
revisions = new Map(); // `${blockId}:${rev}` -> actionId bytes
|
|
14
14
|
pending = new Map(); // `${blockId}:${actionId}` -> transform bytes
|
|
15
15
|
transactions = new Map();
|
|
16
|
+
proofs = new Map(); // `${blockId}:${rev}` -> proof bytes
|
|
16
17
|
materialized = new Map();
|
|
17
18
|
revisionKey(blockId, rev) {
|
|
18
19
|
return `${blockId}:${rev}`;
|
|
@@ -83,6 +84,13 @@ export class MemoryStoreDriver {
|
|
|
83
84
|
async putTransaction(blockId, actionId, value) {
|
|
84
85
|
this.transactions.set(this.actionKey(blockId, actionId), value);
|
|
85
86
|
}
|
|
87
|
+
// --- proofs (keyed like revisions, NOT like actions — see RawStoreDriver.getProof) ---
|
|
88
|
+
async getProof(blockId, rev) {
|
|
89
|
+
return this.proofs.get(this.revisionKey(blockId, rev));
|
|
90
|
+
}
|
|
91
|
+
async putProof(blockId, rev, value) {
|
|
92
|
+
this.proofs.set(this.revisionKey(blockId, rev), value);
|
|
93
|
+
}
|
|
86
94
|
// --- materialized ---
|
|
87
95
|
async getMaterialized(blockId, actionId) {
|
|
88
96
|
return this.materialized.get(this.actionKey(blockId, actionId));
|
|
@@ -104,6 +112,18 @@ export class MemoryStoreDriver {
|
|
|
104
112
|
this.pending.delete(key);
|
|
105
113
|
}
|
|
106
114
|
// --- optional passthroughs ---
|
|
115
|
+
// Deliberately NO storeIdentity(): two MemoryStoreDrivers hold two independent Maps and are
|
|
116
|
+
// genuinely two different stores, so there is no shared "location" for them to name.
|
|
117
|
+
//
|
|
118
|
+
// NOTE: one driver object shared by two `KvRawStorage` wrappers is NOT covered. `withReadCache`
|
|
119
|
+
// falls back to keying on the STORAGE object, not the driver, so those two wrappers are two
|
|
120
|
+
// keys and get two read caches over one Map — the divergence dedupe exists to remove. Harmless
|
|
121
|
+
// today: this driver is a test fixture and every shipping backend's driver reports an identity,
|
|
122
|
+
// so the identity-less path only ever sees genuinely distinct stores. If a host ever wires
|
|
123
|
+
// `rawStorageFactory: () => new KvRawStorage(oneSharedDriver)` for two consumers, give this
|
|
124
|
+
// driver `identityForHandle('memory', this)` (store-identity.ts) — that makes the two wrappers
|
|
125
|
+
// name one store — and re-premise `local-transactor-read-cache.spec.ts`, which currently
|
|
126
|
+
// asserts the non-dedupe.
|
|
107
127
|
async *listBlockIds() {
|
|
108
128
|
// Snapshot the keys before yielding so a concurrent putMetadata during the scan
|
|
109
129
|
// doesn't invalidate a live map iterator. Fresh in-memory storage is empty, so at
|
|
@@ -118,7 +138,7 @@ export class MemoryStoreDriver {
|
|
|
118
138
|
for (const [blockId, value] of this.metadata) {
|
|
119
139
|
total += blockId.length + value.byteLength;
|
|
120
140
|
}
|
|
121
|
-
for (const store of [this.revisions, this.pending, this.transactions, this.materialized]) {
|
|
141
|
+
for (const store of [this.revisions, this.pending, this.transactions, this.proofs, this.materialized]) {
|
|
122
142
|
for (const [key, value] of store) {
|
|
123
143
|
total += key.length + value.byteLength;
|
|
124
144
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store-driver.js","sourceRoot":"","sources":["../../../src/storage/memory-store-driver.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"memory-store-driver.js","sourceRoot":"","sources":["../../../src/storage/memory-store-driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Value codec shared by every `KvRawStorage`-backed store. Values cross the
|
|
3
3
|
* `RawStoreDriver` boundary as `Uint8Array`, so this module is the single place
|
|
4
|
-
* that turns `BlockMetadata`/`Transform`/`IBlock` (via JSON)
|
|
5
|
-
* string (via UTF-8) into bytes and back.
|
|
4
|
+
* that turns `BlockMetadata`/`Transform`/`IBlock`/`BlockCommitProof` (via JSON)
|
|
5
|
+
* and the `ActionId` string (via UTF-8) into bytes and back.
|
|
6
6
|
*
|
|
7
7
|
* Because a get always decodes fresh bytes into a NEW object and a save always
|
|
8
8
|
* encodes an independent byte copy, the clone-on-store / clone-on-read invariant
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { BlockId, ActionId } from "@optimystic/db-core";
|
|
2
|
+
import type { StoreIdentity } from "./store-identity.js";
|
|
2
3
|
/**
|
|
3
4
|
* Bytes-valued, per-logical-store driver surface. Each backend implements the
|
|
4
|
-
*
|
|
5
|
-
* materialized) over its native mechanism (LevelDB tag-ranges,
|
|
6
|
-
* tables,
|
|
5
|
+
* six block-storage stores (metadata, revisions, pending, transactions,
|
|
6
|
+
* materialized, proofs) over its native mechanism (LevelDB tag-ranges, six SQLite
|
|
7
|
+
* tables, six IndexedDB object stores, six filesystem subdirectories, six
|
|
7
8
|
* in-memory maps). `KvRawStorage` layers all JSON serialization and call
|
|
8
9
|
* orchestration on top — drivers never (de)serialize values and never see the
|
|
9
10
|
* `BlockMetadata`/`Transform`/`IBlock` types. Drivers speak only
|
|
@@ -47,6 +48,22 @@ export interface RawStoreDriver {
|
|
|
47
48
|
listPendingActionIds(blockId: BlockId): AsyncIterable<ActionId>;
|
|
48
49
|
getTransaction(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
49
50
|
putTransaction(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* proofs store — keyed by (blockId, rev), the same key shape as the revisions
|
|
53
|
+
* store. A revision's `BlockCommitProof` lives here and NOWHERE in the
|
|
54
|
+
* transactions store: an action id is chosen by whoever originates a write
|
|
55
|
+
* (a client's `pend`, a peer's restore archive) and is never re-derived or
|
|
56
|
+
* format-checked, so any reserved action-id convention could be collided with
|
|
57
|
+
* by an ordinary write. Separate keyspaces make the collision unrepresentable.
|
|
58
|
+
*
|
|
59
|
+
* There is deliberately NO `deleteProof`: a proof lives and dies with its
|
|
60
|
+
* REVISION record, and no revision-delete site exists today (`RawStoreDriver`
|
|
61
|
+
* has no revision delete at all — invalidations write compensating FORWARD
|
|
62
|
+
* revisions). Whatever ever deletes a revision record must delete its proof;
|
|
63
|
+
* until such a site exists this is a contract note, not a wired path.
|
|
64
|
+
*/
|
|
65
|
+
getProof(blockId: BlockId, rev: number): Promise<Uint8Array | undefined>;
|
|
66
|
+
putProof(blockId: BlockId, rev: number, value: Uint8Array): Promise<void>;
|
|
50
67
|
getMaterialized(blockId: BlockId, actionId: ActionId): Promise<Uint8Array | undefined>;
|
|
51
68
|
putMaterialized(blockId: BlockId, actionId: ActionId, value: Uint8Array): Promise<void>;
|
|
52
69
|
deleteMaterialized(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
@@ -59,6 +76,30 @@ export interface RawStoreDriver {
|
|
|
59
76
|
* entry exists. This is the ONLY cross-key atomic operation the kernel requires.
|
|
60
77
|
*/
|
|
61
78
|
promote(blockId: BlockId, actionId: ActionId): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Optional — a stable, process-scoped string naming what this driver is backed by (a
|
|
81
|
+
* resolved directory, an open database handle). Passed through by the kernel and by every
|
|
82
|
+
* wrapper, so a cache and the storage it fronts name the same store.
|
|
83
|
+
*
|
|
84
|
+
* Contract — note it is ONE-DIRECTIONAL; read both halves before consuming it:
|
|
85
|
+
* - Two drivers over DIFFERENT locations MUST NOT return equal strings. So **equality
|
|
86
|
+
* proves sameness**, and a consumer may merge on it. (The fs driver documents one exotic
|
|
87
|
+
* Windows exception at its own site.)
|
|
88
|
+
* - Two drivers over the SAME location SHOULD return equal strings, but this is
|
|
89
|
+
* best-effort and several backends knowingly under-approximate: two handles opened over
|
|
90
|
+
* one database, or two spellings of one directory that cannot be collapsed synchronously,
|
|
91
|
+
* read as two identities. So **inequality proves nothing** — never treat it as evidence
|
|
92
|
+
* that two drivers are distinct stores. Each backend's `NOTE:` states its own gaps.
|
|
93
|
+
* - Every string is scheme-prefixed so backends cannot collide: `file:`, `sqlite-handle:`,
|
|
94
|
+
* `idb-handle:`, `leveldb-handle:`. Compared for equality only — never parsed.
|
|
95
|
+
* - Stable for the driver object's whole life; fixed at construction.
|
|
96
|
+
* - OPTIONAL BY DESIGN. A driver that cannot honour the contract omits the method entirely
|
|
97
|
+
* and callers fall back to per-object behavior. Never install a stub that returns
|
|
98
|
+
* `undefined` — feature-detection (`typeof driver.storeIdentity === 'function'`) must see
|
|
99
|
+
* the driver's true capability.
|
|
100
|
+
* - It identifies the STORE, not its contents.
|
|
101
|
+
*/
|
|
102
|
+
storeIdentity?(): StoreIdentity;
|
|
62
103
|
/** Optional — enumerate block ids with durable metadata (startup seed). Passed through by the kernel. */
|
|
63
104
|
listBlockIds?(): AsyncIterable<BlockId>;
|
|
64
105
|
/** Optional — best cheap byte estimate. Passed through by the kernel. */
|