@optimystic/db-core 0.0.1
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 +328 -0
- package/dist/index.min.js +18 -0
- package/dist/index.min.js.map +7 -0
- package/dist/src/blocks/block-store.d.ts +12 -0
- package/dist/src/blocks/block-store.d.ts.map +1 -0
- package/dist/src/blocks/block-store.js +2 -0
- package/dist/src/blocks/block-store.js.map +1 -0
- package/dist/src/blocks/block-types.d.ts +3 -0
- package/dist/src/blocks/block-types.d.ts.map +1 -0
- package/dist/src/blocks/block-types.js +9 -0
- package/dist/src/blocks/block-types.js.map +1 -0
- package/dist/src/blocks/helpers.d.ts +4 -0
- package/dist/src/blocks/helpers.d.ts.map +1 -0
- package/dist/src/blocks/helpers.js +12 -0
- package/dist/src/blocks/helpers.js.map +1 -0
- package/dist/src/blocks/index.d.ts +5 -0
- package/dist/src/blocks/index.d.ts.map +1 -0
- package/dist/src/blocks/index.js +5 -0
- package/dist/src/blocks/index.js.map +1 -0
- package/dist/src/blocks/structs.d.ts +14 -0
- package/dist/src/blocks/structs.d.ts.map +1 -0
- package/dist/src/blocks/structs.js +2 -0
- package/dist/src/blocks/structs.js.map +1 -0
- package/dist/src/btree/btree.d.ts +135 -0
- package/dist/src/btree/btree.d.ts.map +1 -0
- package/dist/src/btree/btree.js +727 -0
- package/dist/src/btree/btree.js.map +1 -0
- package/dist/src/btree/independent-trunk.d.ts +17 -0
- package/dist/src/btree/independent-trunk.d.ts.map +1 -0
- package/dist/src/btree/independent-trunk.js +41 -0
- package/dist/src/btree/independent-trunk.js.map +1 -0
- package/dist/src/btree/index.d.ts +6 -0
- package/dist/src/btree/index.d.ts.map +1 -0
- package/dist/src/btree/index.js +6 -0
- package/dist/src/btree/index.js.map +1 -0
- package/dist/src/btree/key-range.d.ts +13 -0
- package/dist/src/btree/key-range.d.ts.map +1 -0
- package/dist/src/btree/key-range.js +20 -0
- package/dist/src/btree/key-range.js.map +1 -0
- package/dist/src/btree/keyset.d.ts +4 -0
- package/dist/src/btree/keyset.d.ts.map +1 -0
- package/dist/src/btree/keyset.js +4 -0
- package/dist/src/btree/keyset.js.map +1 -0
- package/dist/src/btree/nodes.d.ts +16 -0
- package/dist/src/btree/nodes.d.ts.map +1 -0
- package/dist/src/btree/nodes.js +9 -0
- package/dist/src/btree/nodes.js.map +1 -0
- package/dist/src/btree/path.d.ts +22 -0
- package/dist/src/btree/path.d.ts.map +1 -0
- package/dist/src/btree/path.js +39 -0
- package/dist/src/btree/path.js.map +1 -0
- package/dist/src/btree/tree-block.d.ts +7 -0
- package/dist/src/btree/tree-block.d.ts.map +1 -0
- package/dist/src/btree/tree-block.js +5 -0
- package/dist/src/btree/tree-block.js.map +1 -0
- package/dist/src/btree/trunk.d.ts +13 -0
- package/dist/src/btree/trunk.d.ts.map +1 -0
- package/dist/src/btree/trunk.js +2 -0
- package/dist/src/btree/trunk.js.map +1 -0
- package/dist/src/chain/chain-nodes.d.ts +18 -0
- package/dist/src/chain/chain-nodes.d.ts.map +1 -0
- package/dist/src/chain/chain-nodes.js +10 -0
- package/dist/src/chain/chain-nodes.js.map +1 -0
- package/dist/src/chain/chain.d.ts +75 -0
- package/dist/src/chain/chain.d.ts.map +1 -0
- package/dist/src/chain/chain.js +268 -0
- package/dist/src/chain/chain.js.map +1 -0
- package/dist/src/chain/index.d.ts +2 -0
- package/dist/src/chain/index.d.ts.map +1 -0
- package/dist/src/chain/index.js +2 -0
- package/dist/src/chain/index.js.map +1 -0
- package/dist/src/cluster/i-cluster.d.ts +5 -0
- package/dist/src/cluster/i-cluster.d.ts.map +1 -0
- package/dist/src/cluster/i-cluster.js +2 -0
- package/dist/src/cluster/i-cluster.js.map +1 -0
- package/dist/src/cluster/index.d.ts +3 -0
- package/dist/src/cluster/index.d.ts.map +1 -0
- package/dist/src/cluster/index.js +3 -0
- package/dist/src/cluster/index.js.map +1 -0
- package/dist/src/cluster/structs.d.ts +47 -0
- package/dist/src/cluster/structs.d.ts.map +1 -0
- package/dist/src/cluster/structs.js +2 -0
- package/dist/src/cluster/structs.js.map +1 -0
- package/dist/src/collection/action.d.ts +26 -0
- package/dist/src/collection/action.d.ts.map +1 -0
- package/dist/src/collection/action.js +2 -0
- package/dist/src/collection/action.js.map +1 -0
- package/dist/src/collection/collection.d.ts +48 -0
- package/dist/src/collection/collection.d.ts.map +1 -0
- package/dist/src/collection/collection.js +175 -0
- package/dist/src/collection/collection.js.map +1 -0
- package/dist/src/collection/index.d.ts +4 -0
- package/dist/src/collection/index.d.ts.map +1 -0
- package/dist/src/collection/index.js +4 -0
- package/dist/src/collection/index.js.map +1 -0
- package/dist/src/collection/struct.d.ts +16 -0
- package/dist/src/collection/struct.d.ts.map +1 -0
- package/dist/src/collection/struct.js +2 -0
- package/dist/src/collection/struct.js.map +1 -0
- package/dist/src/collections/diary/diary.d.ts +9 -0
- package/dist/src/collections/diary/diary.d.ts.map +1 -0
- package/dist/src/collections/diary/diary.js +37 -0
- package/dist/src/collections/diary/diary.js.map +1 -0
- package/dist/src/collections/diary/index.d.ts +3 -0
- package/dist/src/collections/diary/index.d.ts.map +1 -0
- package/dist/src/collections/diary/index.js +3 -0
- package/dist/src/collections/diary/index.js.map +1 -0
- package/dist/src/collections/diary/struct.d.ts +2 -0
- package/dist/src/collections/diary/struct.d.ts.map +1 -0
- package/dist/src/collections/diary/struct.js +3 -0
- package/dist/src/collections/diary/struct.js.map +1 -0
- package/dist/src/collections/index.d.ts +3 -0
- package/dist/src/collections/index.d.ts.map +1 -0
- package/dist/src/collections/index.js +3 -0
- package/dist/src/collections/index.js.map +1 -0
- package/dist/src/collections/tree/collection-trunk.d.ts +11 -0
- package/dist/src/collections/tree/collection-trunk.d.ts.map +1 -0
- package/dist/src/collections/tree/collection-trunk.js +22 -0
- package/dist/src/collections/tree/collection-trunk.js.map +1 -0
- package/dist/src/collections/tree/index.d.ts +3 -0
- package/dist/src/collections/tree/index.d.ts.map +1 -0
- package/dist/src/collections/tree/index.js +3 -0
- package/dist/src/collections/tree/index.js.map +1 -0
- package/dist/src/collections/tree/struct.d.ts +12 -0
- package/dist/src/collections/tree/struct.d.ts.map +1 -0
- package/dist/src/collections/tree/struct.js +4 -0
- package/dist/src/collections/tree/struct.js.map +1 -0
- package/dist/src/collections/tree/tree.d.ts +34 -0
- package/dist/src/collections/tree/tree.d.ts.map +1 -0
- package/dist/src/collections/tree/tree.js +100 -0
- package/dist/src/collections/tree/tree.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/log/index.d.ts +3 -0
- package/dist/src/log/index.d.ts.map +1 -0
- package/dist/src/log/index.js +3 -0
- package/dist/src/log/index.js.map +1 -0
- package/dist/src/log/log.d.ts +57 -0
- package/dist/src/log/log.d.ts.map +1 -0
- package/dist/src/log/log.js +131 -0
- package/dist/src/log/log.js.map +1 -0
- package/dist/src/log/struct.d.ts +36 -0
- package/dist/src/log/struct.d.ts.map +1 -0
- package/dist/src/log/struct.js +3 -0
- package/dist/src/log/struct.js.map +1 -0
- package/dist/src/network/i-key-network.d.ts +21 -0
- package/dist/src/network/i-key-network.d.ts.map +1 -0
- package/dist/src/network/i-key-network.js +2 -0
- package/dist/src/network/i-key-network.js.map +1 -0
- package/dist/src/network/i-peer-network.d.ts +8 -0
- package/dist/src/network/i-peer-network.d.ts.map +1 -0
- package/dist/src/network/i-peer-network.js +2 -0
- package/dist/src/network/i-peer-network.js.map +1 -0
- package/dist/src/network/i-repo.d.ts +17 -0
- package/dist/src/network/i-repo.d.ts.map +1 -0
- package/dist/src/network/i-repo.js +2 -0
- package/dist/src/network/i-repo.js.map +1 -0
- package/dist/src/network/index.d.ts +6 -0
- package/dist/src/network/index.d.ts.map +1 -0
- package/dist/src/network/index.js +6 -0
- package/dist/src/network/index.js.map +1 -0
- package/dist/src/network/repo-protocol.d.ts +19 -0
- package/dist/src/network/repo-protocol.d.ts.map +1 -0
- package/dist/src/network/repo-protocol.js +2 -0
- package/dist/src/network/repo-protocol.js.map +1 -0
- package/dist/src/network/struct.d.ts +115 -0
- package/dist/src/network/struct.d.ts.map +1 -0
- package/dist/src/network/struct.js +2 -0
- package/dist/src/network/struct.js.map +1 -0
- package/dist/src/transaction/actions-engine.d.ts +37 -0
- package/dist/src/transaction/actions-engine.d.ts.map +1 -0
- package/dist/src/transaction/actions-engine.js +67 -0
- package/dist/src/transaction/actions-engine.js.map +1 -0
- package/dist/src/transaction/context.d.ts +60 -0
- package/dist/src/transaction/context.d.ts.map +1 -0
- package/dist/src/transaction/context.js +91 -0
- package/dist/src/transaction/context.js.map +1 -0
- package/dist/src/transaction/coordinator.d.ts +118 -0
- package/dist/src/transaction/coordinator.d.ts.map +1 -0
- package/dist/src/transaction/coordinator.js +417 -0
- package/dist/src/transaction/coordinator.js.map +1 -0
- package/dist/src/transaction/index.d.ts +10 -0
- package/dist/src/transaction/index.d.ts.map +1 -0
- package/dist/src/transaction/index.js +7 -0
- package/dist/src/transaction/index.js.map +1 -0
- package/dist/src/transaction/session.d.ts +80 -0
- package/dist/src/transaction/session.d.ts.map +1 -0
- package/dist/src/transaction/session.js +161 -0
- package/dist/src/transaction/session.js.map +1 -0
- package/dist/src/transaction/transaction.d.ts +156 -0
- package/dist/src/transaction/transaction.d.ts.map +1 -0
- package/dist/src/transaction/transaction.js +31 -0
- package/dist/src/transaction/transaction.js.map +1 -0
- package/dist/src/transaction/validator.d.ts +46 -0
- package/dist/src/transaction/validator.d.ts.map +1 -0
- package/dist/src/transaction/validator.js +97 -0
- package/dist/src/transaction/validator.js.map +1 -0
- package/dist/src/transactor/index.d.ts +4 -0
- package/dist/src/transactor/index.d.ts.map +1 -0
- package/dist/src/transactor/index.js +4 -0
- package/dist/src/transactor/index.js.map +1 -0
- package/dist/src/transactor/network-transactor.d.ts +36 -0
- package/dist/src/transactor/network-transactor.d.ts.map +1 -0
- package/dist/src/transactor/network-transactor.js +297 -0
- package/dist/src/transactor/network-transactor.js.map +1 -0
- package/dist/src/transactor/transactor-source.d.ts +24 -0
- package/dist/src/transactor/transactor-source.d.ts.map +1 -0
- package/dist/src/transactor/transactor-source.js +62 -0
- package/dist/src/transactor/transactor-source.js.map +1 -0
- package/dist/src/transactor/transactor.d.ts +38 -0
- package/dist/src/transactor/transactor.d.ts.map +1 -0
- package/dist/src/transactor/transactor.js +2 -0
- package/dist/src/transactor/transactor.js.map +1 -0
- package/dist/src/transform/atomic.d.ts +8 -0
- package/dist/src/transform/atomic.d.ts.map +1 -0
- package/dist/src/transform/atomic.js +14 -0
- package/dist/src/transform/atomic.js.map +1 -0
- package/dist/src/transform/cache-source.d.ts +13 -0
- package/dist/src/transform/cache-source.d.ts.map +1 -0
- package/dist/src/transform/cache-source.js +52 -0
- package/dist/src/transform/cache-source.js.map +1 -0
- package/dist/src/transform/helpers.d.ts +25 -0
- package/dist/src/transform/helpers.d.ts.map +1 -0
- package/dist/src/transform/helpers.js +105 -0
- package/dist/src/transform/helpers.js.map +1 -0
- package/dist/src/transform/index.d.ts +6 -0
- package/dist/src/transform/index.d.ts.map +1 -0
- package/dist/src/transform/index.js +6 -0
- package/dist/src/transform/index.js.map +1 -0
- package/dist/src/transform/struct.d.ts +19 -0
- package/dist/src/transform/struct.d.ts.map +1 -0
- package/dist/src/transform/struct.js +2 -0
- package/dist/src/transform/struct.js.map +1 -0
- package/dist/src/transform/tracker.d.ts +22 -0
- package/dist/src/transform/tracker.d.ts.map +1 -0
- package/dist/src/transform/tracker.js +64 -0
- package/dist/src/transform/tracker.js.map +1 -0
- package/dist/src/utility/actor.d.ts +11 -0
- package/dist/src/utility/actor.d.ts.map +1 -0
- package/dist/src/utility/actor.js +39 -0
- package/dist/src/utility/actor.js.map +1 -0
- package/dist/src/utility/batch-coordinator.d.ts +56 -0
- package/dist/src/utility/batch-coordinator.d.ts.map +1 -0
- package/dist/src/utility/batch-coordinator.js +127 -0
- package/dist/src/utility/batch-coordinator.js.map +1 -0
- package/dist/src/utility/block-id-to-bytes.d.ts +3 -0
- package/dist/src/utility/block-id-to-bytes.d.ts.map +1 -0
- package/dist/src/utility/block-id-to-bytes.js +7 -0
- package/dist/src/utility/block-id-to-bytes.js.map +1 -0
- package/dist/src/utility/ensured.d.ts +3 -0
- package/dist/src/utility/ensured.d.ts.map +1 -0
- package/dist/src/utility/ensured.js +24 -0
- package/dist/src/utility/ensured.js.map +1 -0
- package/dist/src/utility/groupby.d.ts +8 -0
- package/dist/src/utility/groupby.d.ts.map +1 -0
- package/dist/src/utility/groupby.js +15 -0
- package/dist/src/utility/groupby.js.map +1 -0
- package/dist/src/utility/is-record-empty.d.ts +3 -0
- package/dist/src/utility/is-record-empty.d.ts.map +1 -0
- package/dist/src/utility/is-record-empty.js +7 -0
- package/dist/src/utility/is-record-empty.js.map +1 -0
- package/dist/src/utility/latches.d.ts +11 -0
- package/dist/src/utility/latches.d.ts.map +1 -0
- package/dist/src/utility/latches.js +36 -0
- package/dist/src/utility/latches.js.map +1 -0
- package/dist/src/utility/nameof.d.ts +3 -0
- package/dist/src/utility/nameof.d.ts.map +1 -0
- package/dist/src/utility/nameof.js +5 -0
- package/dist/src/utility/nameof.js.map +1 -0
- package/dist/src/utility/pending.d.ts +13 -0
- package/dist/src/utility/pending.d.ts.map +1 -0
- package/dist/src/utility/pending.js +37 -0
- package/dist/src/utility/pending.js.map +1 -0
- package/package.json +56 -0
- package/src/blocks/block-store.ts +13 -0
- package/src/blocks/block-types.ts +11 -0
- package/src/blocks/helpers.ts +13 -0
- package/src/blocks/index.ts +5 -0
- package/src/blocks/structs.ts +17 -0
- package/src/btree/btree.ts +804 -0
- package/src/btree/independent-trunk.ts +54 -0
- package/src/btree/index.ts +5 -0
- package/src/btree/key-range.ts +15 -0
- package/src/btree/keyset.ts +6 -0
- package/src/btree/nodes.ts +25 -0
- package/src/btree/path.ts +37 -0
- package/src/btree/tree-block.ts +11 -0
- package/src/btree/trunk.ts +14 -0
- package/src/chain/chain-nodes.ts +24 -0
- package/src/chain/chain.ts +324 -0
- package/src/chain/index.ts +2 -0
- package/src/cluster/i-cluster.ts +6 -0
- package/src/cluster/index.ts +2 -0
- package/src/cluster/structs.ts +46 -0
- package/src/collection/action.ts +31 -0
- package/src/collection/collection.ts +200 -0
- package/src/collection/index.ts +3 -0
- package/src/collection/struct.ts +20 -0
- package/src/collections/diary/diary.ts +43 -0
- package/src/collections/diary/index.ts +2 -0
- package/src/collections/diary/struct.ts +3 -0
- package/src/collections/index.ts +2 -0
- package/src/collections/tree/collection-trunk.ts +25 -0
- package/src/collections/tree/index.ts +2 -0
- package/src/collections/tree/readme.md +19 -0
- package/src/collections/tree/struct.ts +18 -0
- package/src/collections/tree/tree.ts +124 -0
- package/src/index.ts +17 -0
- package/src/log/index.ts +2 -0
- package/src/log/log.ts +155 -0
- package/src/log/struct.ts +40 -0
- package/src/network/i-key-network.ts +24 -0
- package/src/network/i-peer-network.ts +8 -0
- package/src/network/i-repo.ts +19 -0
- package/src/network/index.ts +5 -0
- package/src/network/repo-protocol.ts +12 -0
- package/src/network/struct.ts +137 -0
- package/src/transaction/actions-engine.ts +83 -0
- package/src/transaction/context.ts +103 -0
- package/src/transaction/coordinator.ts +583 -0
- package/src/transaction/index.ts +30 -0
- package/src/transaction/session.ts +182 -0
- package/src/transaction/transaction.ts +205 -0
- package/src/transaction/validator.ts +150 -0
- package/src/transactor/index.ts +4 -0
- package/src/transactor/network-transactor.ts +435 -0
- package/src/transactor/transactor-source.ts +65 -0
- package/src/transactor/transactor.ts +44 -0
- package/src/transform/atomic.ts +16 -0
- package/src/transform/cache-source.ts +57 -0
- package/src/transform/helpers.ts +117 -0
- package/src/transform/index.ts +5 -0
- package/src/transform/struct.ts +22 -0
- package/src/transform/tracker.ts +70 -0
- package/src/utility/actor.ts +62 -0
- package/src/utility/batch-coordinator.ts +174 -0
- package/src/utility/block-id-to-bytes.ts +8 -0
- package/src/utility/ensured.ts +32 -0
- package/src/utility/groupby.ts +18 -0
- package/src/utility/is-record-empty.ts +5 -0
- package/src/utility/latches.ts +42 -0
- package/src/utility/nameof.ts +7 -0
- package/src/utility/pending.ts +41 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ITreeTrunk } from './trunk'
|
|
2
|
+
import type { BlockId, BlockStore } from "../blocks";
|
|
3
|
+
import type { ITreeNode } from "./nodes";
|
|
4
|
+
import type { TreeBlock } from "./tree-block";
|
|
5
|
+
import { apply, get } from "../blocks";
|
|
6
|
+
import { TreeRootBlockType, rootId$ } from "./tree-block";
|
|
7
|
+
|
|
8
|
+
export class IndependentTrunk implements ITreeTrunk {
|
|
9
|
+
protected constructor(
|
|
10
|
+
public readonly treeId: BlockId,
|
|
11
|
+
public readonly store: BlockStore<TreeBlock>,
|
|
12
|
+
) { }
|
|
13
|
+
|
|
14
|
+
static create(
|
|
15
|
+
store: BlockStore<TreeBlock>,
|
|
16
|
+
rootId: BlockId,
|
|
17
|
+
newId?: BlockId,
|
|
18
|
+
) {
|
|
19
|
+
const trunkBlock = {
|
|
20
|
+
header: store.createBlockHeader(TreeRootBlockType, newId),
|
|
21
|
+
rootId,
|
|
22
|
+
};
|
|
23
|
+
store.insert(trunkBlock);
|
|
24
|
+
return new IndependentTrunk(trunkBlock.header.id, store);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static async from(store: BlockStore<TreeBlock>, id: BlockId) {
|
|
28
|
+
const block = get(store, id);
|
|
29
|
+
return new IndependentTrunk(id, store);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
block() {
|
|
33
|
+
return get(this.store, this.treeId);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async get(): Promise<ITreeNode> {
|
|
37
|
+
return await get(this.store, await this.getId());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async set(node: ITreeNode): Promise<void> {
|
|
41
|
+
const block = await get(this.store, this.treeId);
|
|
42
|
+
apply(this.store, block, [rootId$, 0, 1, node.header.id]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async getId(): Promise<BlockId> {
|
|
46
|
+
const block = await get(this.store, this.treeId);
|
|
47
|
+
return block.rootId;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Warning: only removes trunk. Use BTree.drop for full tree removal
|
|
51
|
+
drop() {
|
|
52
|
+
this.store.delete(this.treeId);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class KeyBound<TKey> {
|
|
2
|
+
constructor (
|
|
3
|
+
public key: TKey,
|
|
4
|
+
public inclusive = true,
|
|
5
|
+
) {}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Used for range scans. Omitting first or last implies the end of the tree. */
|
|
9
|
+
export class KeyRange<TKey> {
|
|
10
|
+
constructor (
|
|
11
|
+
public first?: KeyBound<TKey>,
|
|
12
|
+
public last?: KeyBound<TKey>,
|
|
13
|
+
public isAscending = true,
|
|
14
|
+
) {}
|
|
15
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BlockId, IBlock } from "../blocks/index.js";
|
|
2
|
+
import { registerBlockType } from "../blocks/index.js";
|
|
3
|
+
import { nameof } from "../utility/nameof.js";
|
|
4
|
+
|
|
5
|
+
export const TreeLeafBlockType = registerBlockType('TL', "TreeLeaf");
|
|
6
|
+
export const TreeBranchBlockType = registerBlockType('TB', "TreeBranch");
|
|
7
|
+
|
|
8
|
+
export interface ITreeNode extends IBlock { }
|
|
9
|
+
|
|
10
|
+
export interface LeafNode<TEntry> extends ITreeNode {
|
|
11
|
+
entries: TEntry[]; // Entries stored in order by key
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface BranchNode<TKey> extends ITreeNode {
|
|
15
|
+
partitions: TKey[]; // partition[0] refers to the lowest key in nodes[1]
|
|
16
|
+
nodes: BlockId[]; // has one more entry than partitions, since partitions split nodes
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Entities
|
|
20
|
+
|
|
21
|
+
export const entries$ = nameof<LeafNode<any>>("entries");
|
|
22
|
+
|
|
23
|
+
export const partitions$ = nameof<BranchNode<any>>("partitions");
|
|
24
|
+
export const nodes$ = nameof<BranchNode<any>>("nodes");
|
|
25
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { BranchNode, LeafNode } from "./nodes";
|
|
2
|
+
|
|
3
|
+
export class PathBranch<TKey> {
|
|
4
|
+
constructor (
|
|
5
|
+
public node: BranchNode<TKey>,
|
|
6
|
+
public index: number,
|
|
7
|
+
) {}
|
|
8
|
+
|
|
9
|
+
clone() {
|
|
10
|
+
return new PathBranch(this.node, this.index);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Represents a cursor in a BTree. Invalid once mutation has occurred (unless it is the results of a mutation method).
|
|
15
|
+
* Do not change the properties of this object directly. Use the methods of the BTree class to manipulate it.
|
|
16
|
+
* @member on - true if the cursor is on an entry, false if it is between entries.
|
|
17
|
+
*/
|
|
18
|
+
export class Path<TKey, TEntry> {
|
|
19
|
+
constructor(
|
|
20
|
+
public branches: PathBranch<TKey>[],
|
|
21
|
+
public leafNode: LeafNode<TEntry>,
|
|
22
|
+
public leafIndex: number,
|
|
23
|
+
public on: boolean,
|
|
24
|
+
public version: number,
|
|
25
|
+
) { }
|
|
26
|
+
|
|
27
|
+
isEqual(path: Path<TKey, TEntry>) {
|
|
28
|
+
return this.leafNode === path.leafNode
|
|
29
|
+
&& this.leafIndex === path.leafIndex
|
|
30
|
+
&& this.on === path.on
|
|
31
|
+
&& this.version === path.version;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
clone() {
|
|
35
|
+
return new Path(this.branches.map(b => b.clone()), this.leafNode, this.leafIndex, this.on, this.version);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockId, IBlock } from "../blocks";
|
|
2
|
+
import { registerBlockType } from "../blocks";
|
|
3
|
+
import { nameof } from "../utility/nameof";
|
|
4
|
+
|
|
5
|
+
export const TreeRootBlockType = registerBlockType("TR", "TreeRoot");
|
|
6
|
+
|
|
7
|
+
export interface TreeBlock extends IBlock {
|
|
8
|
+
rootId: BlockId;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const rootId$ = nameof<TreeBlock>("rootId");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BlockId, BlockStore } from "../blocks";
|
|
2
|
+
import type { ITreeNode } from "./nodes";
|
|
3
|
+
import type { TreeBlock } from "./tree-block";
|
|
4
|
+
|
|
5
|
+
export interface ITreeTrunk {
|
|
6
|
+
/** Gets the root node of the tree */
|
|
7
|
+
get(): Promise<ITreeNode>;
|
|
8
|
+
/** Sets the root node of the tree */
|
|
9
|
+
set(node: ITreeNode): Promise<void>;
|
|
10
|
+
/** Gets the root node id of the tree */
|
|
11
|
+
getId(): Promise<BlockId>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type getTrunkFunc = (store: BlockStore<TreeBlock>, rootId: BlockId, newId?: BlockId) => ITreeTrunk;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type IBlock, type BlockId, registerBlockType } from "../blocks/index.js";
|
|
2
|
+
import { nameof } from "../utility/nameof.js";
|
|
3
|
+
|
|
4
|
+
export type ChainDataNode<TEntry> = IBlock & {
|
|
5
|
+
entries: TEntry[];
|
|
6
|
+
priorId: BlockId | undefined;
|
|
7
|
+
nextId: BlockId | undefined;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const entries$ = nameof<ChainDataNode<any>>("entries");
|
|
11
|
+
export const priorId$ = nameof<ChainDataNode<any>>("priorId");
|
|
12
|
+
export const nextId$ = nameof<ChainDataNode<any>>("nextId");
|
|
13
|
+
|
|
14
|
+
export const ChainDataBlockType = registerBlockType('CHD', 'ChainDataBlock');
|
|
15
|
+
|
|
16
|
+
export type ChainHeaderNode = IBlock & {
|
|
17
|
+
headId: BlockId;
|
|
18
|
+
tailId: BlockId;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const headId$ = nameof<ChainHeaderNode>("headId");
|
|
22
|
+
export const tailId$ = nameof<ChainHeaderNode>("tailId");
|
|
23
|
+
|
|
24
|
+
export const ChainHeaderBlockType = registerBlockType('CHH', 'ChainHeaderBlock');
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { Atomic, type BlockStore, type BlockId, type IBlock } from "../index.js";
|
|
2
|
+
import { ChainDataBlockType, ChainHeaderBlockType, entries$, headId$, nextId$, priorId$, tailId$ } from "./chain-nodes.js";
|
|
3
|
+
import type { ChainDataNode, ChainHeaderNode } from "./chain-nodes.js";
|
|
4
|
+
import { apply } from "../blocks/index.js";
|
|
5
|
+
|
|
6
|
+
export const EntriesPerBlock = 32;
|
|
7
|
+
|
|
8
|
+
export type ChainPath<TEntry> = {
|
|
9
|
+
headerBlock: ChainHeaderNode;
|
|
10
|
+
block: ChainDataNode<TEntry>;
|
|
11
|
+
index: number; // Index of the entry in the block
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ChainNodeInit<T> = IBlock & {
|
|
15
|
+
[K in keyof Omit<T, keyof IBlock>]?: T[K];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type ChainInitOptions<TEntry> = {
|
|
19
|
+
createDataBlock?: () => ChainNodeInit<ChainDataNode<TEntry>>;
|
|
20
|
+
createHeaderBlock?: (id?: BlockId) => ChainNodeInit<ChainHeaderNode>;
|
|
21
|
+
newBlock?: (newTail: ChainDataNode<TEntry>, oldTail: ChainDataNode<TEntry> | undefined) => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type ChainCreateOptions<TEntry> = ChainInitOptions<TEntry> & {
|
|
25
|
+
newId?: BlockId;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// TODO: Generalize the header access so that it can be merged with upstream header (e.g. collection header) and thus avoid another level of indirection
|
|
29
|
+
|
|
30
|
+
/** Represents a chain of blocks, forming a stack, queue, or log. */
|
|
31
|
+
export class Chain<TEntry> {
|
|
32
|
+
private constructor(
|
|
33
|
+
readonly store: BlockStore<IBlock>,
|
|
34
|
+
public readonly id: BlockId,
|
|
35
|
+
private readonly options?: ChainInitOptions<TEntry>,
|
|
36
|
+
) {
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Creates a new queue, with an optional given id. */
|
|
40
|
+
static async create<TEntry>(store: BlockStore<IBlock>, options?: ChainCreateOptions<TEntry>) {
|
|
41
|
+
const tailBlock = Chain.createTailBlock<TEntry>(store, options);
|
|
42
|
+
const headerBlock = {
|
|
43
|
+
...(options?.createHeaderBlock?.(options?.newId) ?? { header: store.createBlockHeader(ChainHeaderBlockType, options?.newId) }),
|
|
44
|
+
headId: tailBlock.header.id,
|
|
45
|
+
tailId: tailBlock.header.id,
|
|
46
|
+
} as ChainHeaderNode;
|
|
47
|
+
store.insert(headerBlock);
|
|
48
|
+
store.insert(tailBlock);
|
|
49
|
+
return new Chain<TEntry>(store, headerBlock.header.id, options);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private static createTailBlock<TEntry>(store: BlockStore<IBlock>, options: ChainCreateOptions<TEntry> | undefined) {
|
|
53
|
+
return {
|
|
54
|
+
...(options?.createDataBlock?.() ?? { header: store.createBlockHeader(ChainDataBlockType) }),
|
|
55
|
+
entries: [] as TEntry[],
|
|
56
|
+
priorId: undefined,
|
|
57
|
+
nextId: undefined,
|
|
58
|
+
} as ChainDataNode<TEntry>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Opens an existing chain, verifying and potentially initializing the header. */
|
|
62
|
+
static async open<TEntry>(store: BlockStore<IBlock>, id: BlockId, options?: ChainInitOptions<TEntry>): Promise<Chain<TEntry> | undefined> {
|
|
63
|
+
const headerBlock = await store.tryGet(id) as ChainHeaderNode | undefined;
|
|
64
|
+
if (!headerBlock) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If the header block is missing headId or tailId, create a tail block and update the header
|
|
69
|
+
const headerAny = headerBlock as any; // Use 'any' for easier property checking/setting
|
|
70
|
+
if (!Object.hasOwn(headerAny, 'headId') || !Object.hasOwn(headerAny, 'tailId')) {
|
|
71
|
+
const tailBlock = Chain.createTailBlock<TEntry>(store, options);
|
|
72
|
+
store.insert(tailBlock);
|
|
73
|
+
apply(store, headerBlock, [headId$, 0, 0, tailBlock.header.id]);
|
|
74
|
+
apply(store, headerBlock, [tailId$, 0, 0, tailBlock.header.id]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return new Chain<TEntry>(store, id, options);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Adds entries to the tail (last-in end) of the chain. Equivalent of enqueue or push.
|
|
82
|
+
* @param entries - The entries to add.
|
|
83
|
+
* @returns Path to the new tail of the chain (entry just past the end).
|
|
84
|
+
*/
|
|
85
|
+
async add(...entries: TEntry[]): Promise<ChainPath<TEntry>> {
|
|
86
|
+
const path = await this.getTail();
|
|
87
|
+
if (!path) {
|
|
88
|
+
throw new Error("Cannot add to non-existent chain");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const { headerBlock, block: oldTail } = path;
|
|
92
|
+
let tail = oldTail;
|
|
93
|
+
|
|
94
|
+
const trx = new Atomic(this.store);
|
|
95
|
+
|
|
96
|
+
// Attempt to fit in current block
|
|
97
|
+
const copied = entries.slice(0, EntriesPerBlock - tail.entries.length);
|
|
98
|
+
if (copied.length > 0) {
|
|
99
|
+
apply(trx, tail, [entries$, tail.entries.length, 0, copied]);
|
|
100
|
+
entries = entries.slice(copied.length);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
while (entries.length > 0) {
|
|
104
|
+
const newTail = {
|
|
105
|
+
...(this.options?.createDataBlock?.() ?? { header: this.store.createBlockHeader(ChainDataBlockType) }),
|
|
106
|
+
entries: entries.splice(0, Math.min(EntriesPerBlock, entries.length)),
|
|
107
|
+
priorId: tail.header.id,
|
|
108
|
+
nextId: undefined,
|
|
109
|
+
} as ChainDataNode<TEntry>;
|
|
110
|
+
await this.options?.newBlock?.(newTail, oldTail);
|
|
111
|
+
trx.insert(newTail);
|
|
112
|
+
apply(trx, tail, [nextId$, 0, 0, newTail.header.id]);
|
|
113
|
+
tail = newTail;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (tail !== oldTail) {
|
|
117
|
+
apply(trx, headerBlock, [tailId$, 0, 0, tail.header.id]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
trx.commit();
|
|
121
|
+
|
|
122
|
+
return { headerBlock, block: tail, index: tail.entries.length - 1 };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Updates the entry at the given path. */
|
|
126
|
+
updateAt(path: ChainPath<TEntry>, entry: TEntry) {
|
|
127
|
+
if (!pathValid(path)) {
|
|
128
|
+
throw new Error("Invalid path");
|
|
129
|
+
}
|
|
130
|
+
const { index, block } = path;
|
|
131
|
+
apply(this.store, block, [entries$, index, 1, [entry]]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Removes up to n entries from the tail (last-in end) of the chain.
|
|
136
|
+
* @param n - The number of entries to remove. If n is greater than the number of entries in the chain, the chain is emptied with no error.
|
|
137
|
+
* @returns An array of the removed entries. May be less than n if the chain is exhausted.
|
|
138
|
+
*/
|
|
139
|
+
async pop(n = 1) {
|
|
140
|
+
if (n <= 0) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const path = await this.getTail();
|
|
145
|
+
if (!path) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const { headerBlock, block: oldTail } = path;
|
|
150
|
+
let tail = oldTail;
|
|
151
|
+
const result = [];
|
|
152
|
+
|
|
153
|
+
const trx = new Atomic(this.store);
|
|
154
|
+
|
|
155
|
+
while (n > 0) {
|
|
156
|
+
if (tail.entries.length > n) { // Partial removal
|
|
157
|
+
const removed = tail.entries.slice(-n);
|
|
158
|
+
result.unshift(...removed);
|
|
159
|
+
apply(trx, tail, [entries$, tail.entries.length - n, n, []]);
|
|
160
|
+
break;
|
|
161
|
+
} else { // Entire block removal
|
|
162
|
+
result.unshift(...tail.entries);
|
|
163
|
+
n -= tail.entries.length;
|
|
164
|
+
if (tail.priorId) {
|
|
165
|
+
trx.delete(tail.header.id);
|
|
166
|
+
tail = await trx.tryGet(tail.priorId) as ChainDataNode<TEntry>;
|
|
167
|
+
apply(trx, tail, [nextId$, 0, 0, undefined]);
|
|
168
|
+
} else { // No more blocks... just empty what's left
|
|
169
|
+
apply(trx, tail, [entries$, 0, tail.entries.length, []]);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (tail !== oldTail) {
|
|
176
|
+
apply(trx, headerBlock, [tailId$, 0, 0, tail.header.id]);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
trx.commit();
|
|
180
|
+
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Removes up to n entries from the head (first-in end) of the queue.
|
|
186
|
+
* @param n - The number of entries to remove. If n is greater than the number of entries in the chain, the chain is emptied with no error.
|
|
187
|
+
* @returns An array of the removed entries. May be less than n if the queue is exhausted.
|
|
188
|
+
*/
|
|
189
|
+
async dequeue(n = 1) {
|
|
190
|
+
if (n <= 0) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const trx = new Atomic(this.store);
|
|
195
|
+
|
|
196
|
+
const path = await this.getHead();
|
|
197
|
+
if (!path) {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const { headerBlock, block: oldHead } = path;
|
|
202
|
+
let head = oldHead;
|
|
203
|
+
const result = [];
|
|
204
|
+
|
|
205
|
+
while (n > 0) {
|
|
206
|
+
if (head.entries.length > n) { // Consumes part of block
|
|
207
|
+
result.push(...head.entries.slice(0, n));
|
|
208
|
+
apply(trx, head, [entries$, 0, n, []]);
|
|
209
|
+
break;
|
|
210
|
+
} else { // Consumes entire block
|
|
211
|
+
result.push(...head.entries);
|
|
212
|
+
n -= head.entries.length;
|
|
213
|
+
if (head.nextId) {
|
|
214
|
+
trx.delete(head.header.id);
|
|
215
|
+
head = await trx.tryGet(head.nextId) as ChainDataNode<TEntry>;
|
|
216
|
+
apply(trx, head, [priorId$, 0, 0, undefined]);
|
|
217
|
+
} else { // No more blocks... just empty what's left
|
|
218
|
+
apply(trx, head, [entries$, 0, head.entries.length, []]);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (head !== oldHead) {
|
|
224
|
+
apply(trx, headerBlock, [headId$, 0, 0, head.header.id]);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
trx.commit();
|
|
228
|
+
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Iterates over the chain, starting at the given path, or the head or tail if not given.
|
|
233
|
+
* If forward is true (default), the iteration is from head (oldest) to tail (latest); otherwise, it is from tail to head.
|
|
234
|
+
*/
|
|
235
|
+
async *select(starting?: ChainPath<TEntry>, forward = true): AsyncIterableIterator<ChainPath<TEntry>> {
|
|
236
|
+
const path = starting ?? (forward ? await this.getHead() : await this.getTail());
|
|
237
|
+
if (!path) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
let block: ChainDataNode<TEntry> | undefined = path.block;
|
|
241
|
+
|
|
242
|
+
let index = path.index;
|
|
243
|
+
if (forward) {
|
|
244
|
+
while (block) {
|
|
245
|
+
for (; index < block.entries.length; ++index) {
|
|
246
|
+
yield { headerBlock: path.headerBlock, block, index };
|
|
247
|
+
}
|
|
248
|
+
block = block.nextId ? await this.store.tryGet(block.nextId) as ChainDataNode<TEntry> : undefined;
|
|
249
|
+
index = 0;
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
while (block) {
|
|
253
|
+
for (; index >= 0; --index) {
|
|
254
|
+
yield { headerBlock: path.headerBlock, block, index };
|
|
255
|
+
}
|
|
256
|
+
block = block.priorId ? await this.store.tryGet(block.priorId) as ChainDataNode<TEntry> : undefined;
|
|
257
|
+
index = (block?.entries.length ?? 0) - 1;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Returns the next entry in the chain; returns an off-the-end path if the end is reached. */
|
|
263
|
+
async next(path: ChainPath<TEntry>) {
|
|
264
|
+
const { headerBlock, block, index } = path;
|
|
265
|
+
if (index < block.entries.length - 1 || !block.nextId) {
|
|
266
|
+
return { headerBlock, block, index: index + 1 };
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
headerBlock,
|
|
270
|
+
block: await this.store.tryGet(block.nextId) as ChainDataNode<TEntry>,
|
|
271
|
+
index: 0,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** Returns the previous entry in the chain; returns an off-the-start path if the start is reached. */
|
|
276
|
+
async prev(path: ChainPath<TEntry>) {
|
|
277
|
+
const { headerBlock, block, index } = path;
|
|
278
|
+
if (index > 0 || !block.priorId) {
|
|
279
|
+
return { headerBlock, block, index: index - 1 };
|
|
280
|
+
}
|
|
281
|
+
const priorBlock = await this.store.tryGet(block.priorId) as ChainDataNode<TEntry>;
|
|
282
|
+
return {
|
|
283
|
+
headerBlock,
|
|
284
|
+
block: priorBlock,
|
|
285
|
+
index: priorBlock.entries.length - 1,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async getTail(header?: ChainHeaderNode): Promise<ChainPath<TEntry> | undefined> {
|
|
290
|
+
const headerBlock = header ?? await this.getHeader();
|
|
291
|
+
let tail = headerBlock ? await this.store.tryGet(headerBlock.tailId) as ChainDataNode<TEntry> : undefined;
|
|
292
|
+
// Possible that the block has filled between reading the header and reading the block... follow nextId links to find true end
|
|
293
|
+
while (tail?.nextId) {
|
|
294
|
+
tail = await this.store.tryGet(tail.nextId) as ChainDataNode<TEntry>;
|
|
295
|
+
}
|
|
296
|
+
return tail ? { headerBlock, block: tail, index: tail.entries.length - 1 } as ChainPath<TEntry> : undefined;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
async getHead(header?: ChainHeaderNode): Promise<ChainPath<TEntry> | undefined> {
|
|
301
|
+
const headerBlock = header ?? await this.getHeader();
|
|
302
|
+
let head = headerBlock ? await this.store.tryGet(headerBlock.headId) as ChainDataNode<TEntry> : undefined;
|
|
303
|
+
// Possible that the block has filled between reading the header and reading the block... follow priorId links to find true start
|
|
304
|
+
while (head?.priorId) {
|
|
305
|
+
head = await this.store.tryGet(head.priorId) as ChainDataNode<TEntry>;
|
|
306
|
+
}
|
|
307
|
+
return head ? { headerBlock, block: head, index: 0 } as ChainPath<TEntry> : undefined;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
async getHeader() {
|
|
312
|
+
return await this.store.tryGet(this.id) as ChainHeaderNode | undefined;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** Returns true if the given path is located on an entry (not a crack). */
|
|
317
|
+
export function pathValid<TEntry>(path: ChainPath<TEntry>) {
|
|
318
|
+
return path.block.entries.length > path.index && path.index >= 0;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/** Gets the entry at the given path; undefined if the path is not valid. */
|
|
322
|
+
export function entryAt<TEntry>(path: ChainPath<TEntry>): TEntry | undefined {
|
|
323
|
+
return path.block.entries[path.index];
|
|
324
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Multiaddr } from "@multiformats/multiaddr";
|
|
2
|
+
import type { RepoMessage } from "../network/repo-protocol.js";
|
|
3
|
+
|
|
4
|
+
export type Signature = {
|
|
5
|
+
type: 'approve' | 'reject';
|
|
6
|
+
signature: string;
|
|
7
|
+
rejectReason?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ClusterPeers = {
|
|
11
|
+
[id: string]: {
|
|
12
|
+
multiaddrs: Multiaddr[];
|
|
13
|
+
publicKey: Uint8Array;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type ClusterRecord = {
|
|
18
|
+
messageHash: string; // Serves as a unique identifier for the clustered transaction record
|
|
19
|
+
peers: ClusterPeers;
|
|
20
|
+
message: RepoMessage;
|
|
21
|
+
coordinatingBlockIds?: string[];
|
|
22
|
+
promises: { [peerId: string]: Signature };
|
|
23
|
+
commits: { [peerId: string]: Signature };
|
|
24
|
+
/** Sender's recommended cluster size: min(estimated network size, configured cluster size) */
|
|
25
|
+
suggestedClusterSize?: number;
|
|
26
|
+
minRequiredSize?: number;
|
|
27
|
+
/** Sender's current network size estimate */
|
|
28
|
+
networkSizeHint?: number;
|
|
29
|
+
/** Confidence in the network size estimate (0-1) */
|
|
30
|
+
networkSizeConfidence?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ClusterConsensusConfig {
|
|
34
|
+
/** Super-majority threshold for promises (default 0.75 = 3/4) */
|
|
35
|
+
superMajorityThreshold: number;
|
|
36
|
+
/** Simple majority threshold for commits (default 0.51 = >50%) */
|
|
37
|
+
simpleMajorityThreshold: number;
|
|
38
|
+
/** Minimum absolute cluster size (default 3) */
|
|
39
|
+
minAbsoluteClusterSize: number;
|
|
40
|
+
/** Allow cluster to operate below configured size (default false) */
|
|
41
|
+
allowClusterDownsize: boolean;
|
|
42
|
+
/** Tolerance for cluster size variance as fraction (default 0.5 = 50%) */
|
|
43
|
+
clusterSizeTolerance: number;
|
|
44
|
+
/** Window for detecting partition in milliseconds (default 60000 = 1 min) */
|
|
45
|
+
partitionDetectionWindow: number;
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { BlockStore } from "../index.js";
|
|
2
|
+
import type { IBlock } from "../index.js";
|
|
3
|
+
import type { TransactionRef } from "../transaction/index.js";
|
|
4
|
+
|
|
5
|
+
export type ActionId = string;
|
|
6
|
+
|
|
7
|
+
export type ActionType = string;
|
|
8
|
+
|
|
9
|
+
export type Action<T> = {
|
|
10
|
+
type: ActionType;
|
|
11
|
+
data: T;
|
|
12
|
+
/** Optional reference to the transaction this action came from */
|
|
13
|
+
transaction?: TransactionRef;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type ActionHandler<T, TResult = void> = (action: Action<T>, store: BlockStore<IBlock>) => Promise<TResult>;
|
|
17
|
+
|
|
18
|
+
export type ActionRev = {
|
|
19
|
+
actionId: ActionId;
|
|
20
|
+
rev: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** Situational awareness of the action state */
|
|
24
|
+
export type ActionContext = {
|
|
25
|
+
/** Actions that may not have been checkpointed */
|
|
26
|
+
committed: ActionRev[];
|
|
27
|
+
/** The latest known revision number */
|
|
28
|
+
rev: number;
|
|
29
|
+
/** Optional uncommitted pending action ID */
|
|
30
|
+
actionId?: ActionId;
|
|
31
|
+
};
|