@optimystic/db-core 0.5.1 → 0.6.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.
Files changed (97) hide show
  1. package/dist/src/btree/btree.d.ts +2 -0
  2. package/dist/src/btree/btree.d.ts.map +1 -1
  3. package/dist/src/btree/btree.js +72 -52
  4. package/dist/src/btree/btree.js.map +1 -1
  5. package/dist/src/cluster/structs.d.ts +13 -0
  6. package/dist/src/cluster/structs.d.ts.map +1 -1
  7. package/dist/src/collection/collection.d.ts +3 -0
  8. package/dist/src/collection/collection.d.ts.map +1 -1
  9. package/dist/src/collection/collection.js +6 -0
  10. package/dist/src/collection/collection.js.map +1 -1
  11. package/dist/src/index.d.ts +1 -0
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/index.js +1 -0
  14. package/dist/src/index.js.map +1 -1
  15. package/dist/src/log/log.js +1 -1
  16. package/dist/src/log/log.js.map +1 -1
  17. package/dist/src/logger.d.ts +4 -0
  18. package/dist/src/logger.d.ts.map +1 -0
  19. package/dist/src/logger.js +8 -0
  20. package/dist/src/logger.js.map +1 -0
  21. package/dist/src/transaction/actions-engine.d.ts +1 -13
  22. package/dist/src/transaction/actions-engine.d.ts.map +1 -1
  23. package/dist/src/transaction/actions-engine.js +0 -7
  24. package/dist/src/transaction/actions-engine.js.map +1 -1
  25. package/dist/src/transaction/coordinator.d.ts +9 -1
  26. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  27. package/dist/src/transaction/coordinator.js +77 -11
  28. package/dist/src/transaction/coordinator.js.map +1 -1
  29. package/dist/src/transaction/index.d.ts +4 -5
  30. package/dist/src/transaction/index.d.ts.map +1 -1
  31. package/dist/src/transaction/index.js +2 -2
  32. package/dist/src/transaction/index.js.map +1 -1
  33. package/dist/src/transaction/session.d.ts +7 -3
  34. package/dist/src/transaction/session.d.ts.map +1 -1
  35. package/dist/src/transaction/session.js +23 -10
  36. package/dist/src/transaction/session.js.map +1 -1
  37. package/dist/src/transaction/transaction.d.ts +21 -3
  38. package/dist/src/transaction/transaction.d.ts.map +1 -1
  39. package/dist/src/transaction/transaction.js +21 -7
  40. package/dist/src/transaction/transaction.js.map +1 -1
  41. package/dist/src/transaction/validator.d.ts +9 -2
  42. package/dist/src/transaction/validator.d.ts.map +1 -1
  43. package/dist/src/transaction/validator.js +26 -6
  44. package/dist/src/transaction/validator.js.map +1 -1
  45. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  46. package/dist/src/transactor/network-transactor.js +84 -9
  47. package/dist/src/transactor/network-transactor.js.map +1 -1
  48. package/dist/src/transactor/transactor-source.d.ts +4 -0
  49. package/dist/src/transactor/transactor-source.d.ts.map +1 -1
  50. package/dist/src/transactor/transactor-source.js +25 -9
  51. package/dist/src/transactor/transactor-source.js.map +1 -1
  52. package/dist/src/transform/atomic-proxy.d.ts +26 -0
  53. package/dist/src/transform/atomic-proxy.d.ts.map +1 -0
  54. package/dist/src/transform/atomic-proxy.js +47 -0
  55. package/dist/src/transform/atomic-proxy.js.map +1 -0
  56. package/dist/src/transform/cache-source.d.ts +3 -2
  57. package/dist/src/transform/cache-source.d.ts.map +1 -1
  58. package/dist/src/transform/cache-source.js +15 -3
  59. package/dist/src/transform/cache-source.js.map +1 -1
  60. package/dist/src/transform/index.d.ts +1 -0
  61. package/dist/src/transform/index.d.ts.map +1 -1
  62. package/dist/src/transform/index.js +1 -0
  63. package/dist/src/transform/index.js.map +1 -1
  64. package/dist/src/utility/batch-coordinator.d.ts.map +1 -1
  65. package/dist/src/utility/batch-coordinator.js +6 -1
  66. package/dist/src/utility/batch-coordinator.js.map +1 -1
  67. package/dist/src/utility/hash-string.d.ts +3 -6
  68. package/dist/src/utility/hash-string.d.ts.map +1 -1
  69. package/dist/src/utility/hash-string.js +8 -11
  70. package/dist/src/utility/hash-string.js.map +1 -1
  71. package/dist/src/utility/lru-map.d.ts +18 -0
  72. package/dist/src/utility/lru-map.d.ts.map +1 -0
  73. package/dist/src/utility/lru-map.js +52 -0
  74. package/dist/src/utility/lru-map.js.map +1 -0
  75. package/package.json +15 -8
  76. package/src/btree/btree.ts +71 -50
  77. package/src/cluster/structs.ts +11 -0
  78. package/src/collection/collection.ts +9 -0
  79. package/src/index.ts +1 -0
  80. package/src/log/log.ts +1 -1
  81. package/src/logger.ts +10 -0
  82. package/src/transaction/actions-engine.ts +0 -17
  83. package/src/transaction/coordinator.ts +87 -12
  84. package/src/transaction/index.ts +7 -6
  85. package/src/transaction/session.ts +34 -10
  86. package/src/transaction/transaction.ts +39 -10
  87. package/src/transaction/validator.ts +34 -7
  88. package/src/transactor/network-transactor.ts +92 -11
  89. package/src/transactor/transactor-source.ts +28 -9
  90. package/src/transform/atomic-proxy.ts +49 -0
  91. package/src/transform/cache-source.ts +18 -4
  92. package/src/transform/index.ts +1 -0
  93. package/src/utility/batch-coordinator.ts +7 -1
  94. package/src/utility/hash-string.ts +14 -17
  95. package/src/utility/lru-map.ts +55 -0
  96. package/dist/index.min.js +0 -9
  97. package/dist/index.min.js.map +0 -7
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/transaction/actions-engine.ts", "../src/index.ts", "../src/blocks/block-types.ts", "../src/transform/helpers.ts", "../src/blocks/helpers.ts", "../src/utility/nameof.ts", "../src/btree/nodes.ts", "../src/btree/btree.ts", "../src/btree/key-range.ts", "../src/btree/keyset.ts", "../src/btree/path.ts", "../src/chain/chain-nodes.ts", "../src/chain/chain.ts", "../node_modules/@noble/hashes/src/utils.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base10.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bytes.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/vendor/base-x.js", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base16.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base2.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base256emoji.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base32.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base36.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base58.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base64.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/base8.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/bases/identity.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/codecs/json.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/hashes/identity.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/vendor/varint.js", "../node_modules/uint8arrays/node_modules/multiformats/src/varint.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/hashes/digest.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/hashes/sha2-browser.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/hashes/hasher.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/cid.ts", "../node_modules/uint8arrays/node_modules/multiformats/src/basics.ts", "../node_modules/uint8arrays/src/alloc.ts", "../node_modules/uint8arrays/src/util/bases.ts", "../node_modules/uint8arrays/src/to-string.ts", "../src/utility/latches.ts", "../src/collection/collection.ts", "../src/collections/diary/diary.ts", "../src/collections/diary/struct.ts", "../src/collections/tree/struct.ts", "../src/collections/tree/collection-trunk.ts", "../src/collections/tree/tree.ts", "../node_modules/multiformats/src/bytes.ts", "../node_modules/multiformats/src/vendor/varint.js", "../node_modules/multiformats/src/varint.ts", "../node_modules/multiformats/src/hashes/digest.ts", "../node_modules/multiformats/src/hashes/hasher.ts", "../node_modules/multiformats/src/hashes/sha2-browser.ts", "../src/log/log.ts", "../src/log/struct.ts", "../src/network/types.ts", "../src/utility/hash-string.ts", "../src/transaction/transaction.ts", "../src/transaction/index.ts", "../src/transaction/coordinator.ts", "../src/transaction/context.ts", "../src/transaction/session.ts", "../src/transaction/validator.ts", "../src/utility/block-id-to-bytes.ts", "../src/utility/is-record-empty.ts", "../src/utility/pending.ts", "../src/utility/batch-coordinator.ts", "../src/transactor/network-transactor.ts", "../src/transactor/transactor-source.ts", "../src/transform/tracker.ts", "../src/transform/atomic.ts", "../src/transform/cache-source.ts", "../src/utility/groupby.ts", "../src/utility/ensured.ts"],
4
- "sourcesContent": ["import type { ITransactionEngine, Transaction, ExecutionResult, CollectionActions } from './transaction.js';\r\nimport type { TransactionCoordinator } from './coordinator.js';\r\n\r\nexport const ACTIONS_ENGINE_ID = \"actions@1.0.0\";\r\n\r\n/**\r\n * Built-in action-based transaction engine for testing.\r\n *\r\n * This engine treats each statement as a JSON-encoded CollectionActions object.\r\n * It's useful for testing the transaction infrastructure without needing SQL.\r\n *\r\n * Each statement format:\r\n * ```json\r\n * {\r\n * \"collectionId\": \"users\",\r\n * \"actions\": [\r\n * { \"type\": \"insert\", \"data\": { \"id\": 1, \"name\": \"Alice\" } }\r\n * ]\r\n * }\r\n * ```\r\n */\r\nexport class ActionsEngine implements ITransactionEngine {\r\n\tconstructor(private coordinator: TransactionCoordinator) {}\r\n\r\n\tasync execute(transaction: Transaction): Promise<ExecutionResult> {\r\n\t\ttry {\r\n\t\t\t// Parse each statement as a CollectionActions object\r\n\t\t\tconst allActions: CollectionActions[] = [];\r\n\r\n\t\t\tfor (const statement of transaction.statements) {\r\n\t\t\t\tconst collectionActions = JSON.parse(statement) as CollectionActions;\r\n\r\n\t\t\t\t// Validate structure\r\n\t\t\t\tif (!collectionActions.collectionId || typeof collectionActions.collectionId !== 'string') {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\t\terror: 'Invalid statement: missing collectionId'\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!collectionActions.actions || !Array.isArray(collectionActions.actions)) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\t\terror: `Invalid statement: collection ${collectionActions.collectionId} missing or invalid actions array`\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tallActions.push(collectionActions);\r\n\r\n\t\t\t\t// Apply actions through coordinator (for validation/replay)\r\n\t\t\t\tawait this.coordinator.applyActions([collectionActions], transaction.stamp.id);\r\n\t\t\t}\r\n\r\n\t\t\t// Return success (actions already applied)\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: true,\r\n\t\t\t\tactions: allActions\r\n\t\t\t};\r\n\t\t} catch (error) {\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: `Failed to execute transaction: ${error instanceof Error ? error.message : String(error)}`\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Statement format for the actions engine (array of CollectionActions).\r\n * @deprecated Use CollectionActions[] directly\r\n */\r\nexport type ActionsStatement = {\r\n\tcollections: CollectionActions[];\r\n};\r\n\r\n/**\r\n * Helper to create an actions-based transaction statements array.\r\n * Each CollectionActions becomes a separate statement.\r\n */\r\nexport function createActionsStatements(collections: CollectionActions[]): string[] {\r\n\treturn collections.map(c => JSON.stringify(c));\r\n}\r\n\r\n", "export * from \"./blocks/index.js\";\r\nexport * from \"./btree/index.js\";\r\nexport * from \"./chain/index.js\";\r\nexport * from \"./cluster/index.js\";\r\nexport * from \"./collection/index.js\";\r\nexport * from \"./collections/index.js\";\r\nexport * from \"./log/index.js\";\r\nexport * from \"./network/index.js\";\r\nexport * from \"./transaction/index.js\";\r\nexport * from \"./transactor/index.js\";\r\nexport * from \"./transform/index.js\";\r\nexport * from \"./utility/groupby.js\";\r\nexport * from \"./utility/hash-string.js\";\r\nexport * from \"./utility/latches.js\";\r\nexport * from \"./utility/nameof.js\";\r\nexport * from \"./utility/ensured.js\";\r\nexport * from \"./utility/pending.js\";\r\nexport * from \"./utility/block-id-to-bytes.js\";\r\n", "import type { BlockType } from \"./index.js\";\r\n\r\nconst blockTypes = new Map<BlockType, string>();\r\n\r\nexport function registerBlockType(blockType: BlockType, name: string) {\r\n\tif (blockTypes.has(blockType)) {\r\n\t\tthrow new Error(`Block type ${blockType} (${name}) already registered (${blockTypes.get(blockType)})`);\r\n\t}\r\n\tblockTypes.set(blockType, name);\r\n\treturn blockType;\r\n}\r\n", "import type { BlockId, BlockOperation, BlockOperations, BlockStore, IBlock, Transform, Transforms } from \"../index.js\";\n\n/**\n * Mutates the given block with a copy of the given operation.\n *\n * @warning **MUTATES IN PLACE** - Callers must clone the block first if the original needs preservation.\n * Storage implementations must clone on get/save to prevent cross-revision contamination.\n * @see docs/internals.md for mutation contracts\n */\nexport function applyOperation(block: IBlock, [entity, index, deleteCount, inserted]: BlockOperation) {\n\tif (Array.isArray(inserted)) {\n\t\t(block as unknown as any)[entity].splice(index, deleteCount, ...structuredClone(inserted));\n\t} else {\n\t\t(block as unknown as any)[entity] = structuredClone(inserted);\n\t}\n}\n\n/**\n * Mutates the given block with the given set of operations.\n *\n * @warning **MUTATES IN PLACE** - Callers must clone the block first if the original needs preservation.\n * @see docs/internals.md for mutation contracts\n */\nexport function applyOperations(block: IBlock, operations: BlockOperations) {\n\tfor (const op of operations) {\n\t\tapplyOperation(block, op);\n\t}\n}\n\n/** Returns a copy of the block with the given operation applied */\nexport function withOperation(block: IBlock, [entity, index, deleteCount, inserted]: BlockOperation) {\n\tif (Array.isArray(inserted)) {\n\t\tconst source = (block as any)[entity];\n\t\treturn { ...block, [entity]: [...source.slice(0, index), ...structuredClone(inserted), ...source.slice(index + deleteCount)] };\n\t} else {\n\t\treturn { ...block, [entity]: structuredClone(inserted) };\n\t}\n}\n\n/** The set of distinct block ids affected by the transform */\nexport function blockIdsForTransforms(transforms: Transforms | undefined) {\n\tif (!transforms) return [];\n\tconst insertIds = Object.keys(transforms.inserts ?? {});\n\tconst updateIds = Object.keys(transforms.updates ?? {});\n\tconst deleteIds = transforms.deletes ?? [];\n\treturn [...new Set([...insertIds, ...updateIds, ...deleteIds])];\n}\n\n/** Returns an empty transform */\nexport function emptyTransforms(): Transforms {\n\treturn { inserts: {}, updates: {}, deletes: [] };\n}\n\n/**\n * Creates a deep copy of a Transforms object.\n *\n * @pitfall Updates arrays MUST be deep cloned - a shallow copy like `{ ...transform.updates }`\n * shares array references, causing mutations in one consumer to affect others.\n * @see docs/internals.md \"Shallow Copy of Transforms\" pitfall\n */\nexport function copyTransforms(transform: Transforms): Transforms {\n\t// Deep clone updates arrays to prevent shared references\n\tconst updates = transform.updates\n\t\t? Object.fromEntries(Object.entries(transform.updates).map(([k, v]) => [k, structuredClone(v)]))\n\t\t: undefined;\n\treturn { inserts: { ...transform.inserts }, updates, deletes: transform.deletes ? [...transform.deletes] : undefined };\n}\n\nexport function mergeTransforms(a: Transforms, b: Transforms): Transforms {\n\treturn {\n\t\tinserts: { ...a.inserts, ...b.inserts },\n\t\tupdates: { ...a.updates, ...b.updates },\n\t\tdeletes: [...(a.deletes ?? []), ...(b.deletes ?? [])]\n\t};\n}\n\nexport function isTransformsEmpty(transform: Transforms): boolean {\n\treturn Object.keys(transform.inserts ?? {}).length === 0\n\t\t&& Object.keys(transform.updates ?? {}).length === 0\n\t\t&& (transform.deletes?.length ?? 0) === 0;\n}\n\nexport function concatTransforms(...transforms: Transforms[]): Transforms {\n\treturn transforms.reduce((acc, m) => mergeTransforms(acc, m), emptyTransforms());\n}\n\n\n/**\n * Extracts the transform for a specific block from a Transforms object.\n *\n * @pitfall Updates array MUST be deep cloned - extracting without cloning shares\n * the array reference, causing mutations to affect the original Transforms.\n * @see docs/internals.md \"Shallow Copy of Transforms\" pitfall\n */\nexport function transformForBlockId(transform: Transforms, blockId: BlockId): Transform {\n\treturn {\n\t\t...(transform.inserts && blockId in transform.inserts ? { insert: transform.inserts[blockId] } : {}),\n\t\t// Clone updates array to prevent shared references\n\t\t...(transform.updates && blockId in transform.updates ? { updates: structuredClone(transform.updates[blockId]) } : {}),\n\t\t...(transform.deletes?.includes(blockId) ? { delete: true } : {})\n\t};\n}\n\nexport function transformsFromTransform(transform: Transform, blockId: BlockId): Transforms {\n\treturn {\n\t\tinserts: transform.insert ? { [blockId]: transform.insert } : {},\n\t\tupdates: transform.updates ? { [blockId]: transform.updates } : {},\n\t\tdeletes: transform.delete ? [blockId] : []\n\t};\n}\n\nexport function applyTransformToStore<T extends IBlock>(transform: Transforms, store: BlockStore<T>) {\n\tfor (const blockId of transform.deletes ?? []) {\n\t\tstore.delete(blockId);\n\t}\n\tfor (const [, block] of Object.entries(transform.inserts ?? {})) {\n\t\tstore.insert(block as T);\n\t}\n\tfor (const [blockId, operations] of Object.entries(transform.updates ?? {})) {\n\t\tfor (const op of operations) {\n\t\t\tstore.update(blockId, op);\n\t\t}\n\t}\n}\n\n/** Applies a transform to the given block */\nexport function applyTransform(block: IBlock | undefined, transform: Transform): IBlock | undefined {\n\tif (transform.insert) {\n\t\tblock = transform.insert;\n\t}\n\tif (block && transform.updates) {\n\t\tapplyOperations(block, transform.updates);\n\t}\n\tif (transform.delete) {\n\t\treturn undefined;\n\t}\n\treturn block;\n}\n\n/** Concatenates a transform to the given transforms */\nexport function concatTransform(transforms: Transforms, blockId: BlockId, transform: Transform): Transforms {\n\treturn {\n\t\tinserts: { ...transforms.inserts, ...(transform.insert ? { [blockId]: transform.insert } : {}) },\n\t\tupdates: { ...transforms.updates, ...(transform.updates ? { [blockId]: transform.updates } : {}) },\n\t\tdeletes: [...(transforms.deletes ?? []), ...(transform.delete ? [blockId] : [])]\n\t};\n}\n", "import type { BlockOperation, IBlock, BlockId, BlockStore } from \"../index.js\";\r\nimport { applyOperation } from \"../transform/helpers.js\";\r\n\r\nexport async function get<T extends IBlock>(store: BlockStore<T>, id: BlockId): Promise<T> {\r\n\tconst block = await store.tryGet(id);\r\n\tif (!block) throw Error(`Missing block (${id})`);\r\n\treturn block;\r\n}\r\n\r\nexport function apply<T extends IBlock>(store: BlockStore<T>, block: IBlock, op: BlockOperation) {\r\n\tapplyOperation(block, op);\r\n\tstore.update(block.header.id, op);\r\n}\r\n", "/* eslint-disable no-redeclare, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any */\r\nexport function nameof<TObject>(obj: TObject, key: keyof TObject): string;\r\nexport function nameof<TObject>(key: keyof TObject): string;\r\nexport function nameof(key1: any, key2?: any): any {\r\n return key2 ?? key1;\r\n}\r\n/* eslint-enable */\r\n", "import type { BlockId, IBlock } from \"../blocks/index.js\";\r\nimport { registerBlockType } from \"../blocks/index.js\";\r\nimport { nameof } from \"../utility/nameof.js\";\r\n\r\nexport const TreeLeafBlockType = registerBlockType('TL', \"TreeLeaf\");\r\nexport const TreeBranchBlockType = registerBlockType('TB', \"TreeBranch\");\r\n\r\nexport interface ITreeNode extends IBlock { }\r\n\r\nexport interface LeafNode<TEntry> extends ITreeNode {\r\n\tentries: TEntry[]; // Entries stored in order by key\r\n}\r\n\r\nexport interface BranchNode<TKey> extends ITreeNode {\r\n\tpartitions: TKey[];\t// partition[0] refers to the lowest key in nodes[1]\r\n\tnodes: BlockId[]; // has one more entry than partitions, since partitions split nodes\r\n}\r\n\r\n// Entities\r\n\r\nexport const entries$ = nameof<LeafNode<any>>(\"entries\");\r\n\r\nexport const partitions$ = nameof<BranchNode<any>>(\"partitions\");\r\nexport const nodes$ = nameof<BranchNode<any>>(\"nodes\");\r\n\r\n", "import { Path, PathBranch, type ITreeTrunk, type KeyRange, type getTrunkFunc } from \"./index.js\";\r\nimport type { BlockId, BlockStore } from \"../blocks/index.js\";\r\nimport { apply, get } from \"../blocks/index.js\";\r\nimport { TreeLeafBlockType, TreeBranchBlockType, entries$, nodes$, partitions$ } from \"./nodes.js\";\r\nimport type { BranchNode, ITreeNode, LeafNode } from \"./nodes.js\";\r\nimport type { TreeBlock } from \"./tree-block.js\";\r\n\r\nexport const NodeCapacity = 64;\r\n\r\n/**\r\n * Represents a lightweight B+(ish)Tree (data at leaves, but no linked list of leaves).\r\n * Allows for efficient storage and retrieval of data in a sorted manner.\r\n * @template TEntry The type of entries stored in the B-tree.\r\n * @template TKey The type of keys used for indexing the entries. This might be an element of TEntry, or TEntry itself.\r\n */\r\nexport class BTree<TKey, TEntry> {\r\n\tprotected _version = 0;\t// only for path invalidation\r\n\r\n\t/**\r\n\t * @param [compare=(a: TKey, b: TKey) => a < b ? -1 : a > b ? 1 : 0] a comparison function for keys. The default uses < and > operators.\r\n\t * @param [keyFromEntry=(entry: TEntry) => entry as unknown as TKey] a function to extract the key from an entry. The default assumes the key is the entry itself.\r\n\t */\r\n\tconstructor(\r\n\t\tpublic readonly store: BlockStore<ITreeNode>,\r\n\t\tpublic readonly trunk: ITreeTrunk,\r\n\t\tpublic readonly keyFromEntry = (entry: TEntry) => entry as unknown as TKey,\r\n\t\tpublic readonly compare = (a: TKey, b: TKey) => a < b ? -1 : a > b ? 1 : 0 as number,\r\n\t) {\r\n\t}\r\n\r\n\tstatic createRoot(\r\n\t\tstore: BlockStore<ITreeNode>\r\n\t) {\r\n\t\treturn newLeafNode(store, []);\r\n\t}\r\n\r\n\tstatic create<TKey, TEntry>(\r\n\t\tstore: BlockStore<ITreeNode | TreeBlock>,\r\n\t\tcreateTrunk: getTrunkFunc,\r\n\t\tkeyFromEntry = (entry: TEntry) => entry as unknown as TKey,\r\n\t\tcompare = (a: TKey, b: TKey) => a < b ? -1 : a > b ? 1 : 0,\r\n\t\tnewId?: BlockId,\r\n\t) {\r\n\t\tconst root = BTree.createRoot(store as BlockStore<TreeBlock>);\r\n\t\tstore.insert(root);\r\n\t\tconst trunk = createTrunk(store as BlockStore<TreeBlock>, root.header.id, newId);\r\n\t\treturn new BTree(store, trunk, keyFromEntry, compare);\r\n\t}\r\n\r\n\t/** @returns a path to the first entry (on = false if no entries) */\r\n\tasync first(): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.getFirst(await this.trunk.get());\r\n\t}\r\n\r\n\t/** @returns a path to the last entry (on = false if no entries) */\r\n\tasync last(): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.getLast(await this.trunk.get());\r\n\t}\r\n\r\n\t/** Attempts to find the given key\r\n\t * @returns Path to the key or the \"crack\" before it. If `on` is true on the resulting path, the key was found.\r\n\t * \tIf `on` is false, next() and prior() can attempt to move to the nearest match. */\r\n\tasync find(key: TKey): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.getPath(await this.trunk.get(), key);\r\n\t}\r\n\r\n\t/** Retrieves the entry for the given key.\r\n\t * Use find instead for a path to the key, the nearest match, or as a basis for navigation.\r\n\t * @returns the entry for the given key if found; undefined otherwise. */\r\n\tasync get(key: TKey): Promise<TEntry | undefined> {\r\n\t\treturn this.at(await this.find(key));\r\n\t}\r\n\r\n\t/** @returns the entry for the given path if on an entry; undefined otherwise. */\r\n\tat(path: Path<TKey, TEntry>): TEntry | undefined {\r\n\t\tthis.validatePath(path);\r\n\t\treturn path.on ? this.getEntry(path) : undefined;\r\n\t}\r\n\r\n\t/** Iterates based on the given range\r\n\t * WARNING: mutation during iteration will result in an exception\r\n\t*/\r\n\tasync *range(range: KeyRange<TKey>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\tconst startPath = range.first\r\n\t\t\t? await this.findFirst(range)\r\n\t\t\t: (range.isAscending ? await this.first() : await this.last());\r\n\t\tconst endPath = range.last\r\n\t\t\t? await this.findLast(range)\r\n\t\t\t: (range.isAscending ? await this.last() : await this.first());\r\n\t\t// If the tree is empty or endPath is not on an entry, return early\r\n\t\tif (!endPath.on) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst endKey = this.keyFromPath(endPath);\r\n\t\tconst iterable = range.isAscending\r\n\t\t\t? this.internalAscending(startPath)\r\n\t\t\t: this.internalDescending(startPath);\r\n\t\tconst iter = iterable[Symbol.asyncIterator]();\r\n\t\tconst ascendingFactor = range.isAscending ? 1 : -1;\r\n\t\tfor await (let path of iter) {\r\n\t\t\tif (!path.on || this.compare(\r\n\t\t\t\tthis.keyFromPath(path),\r\n\t\t\t\tendKey\r\n\t\t\t) * ascendingFactor > 0) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tyield path;\r\n\t\t}\r\n\t}\r\n\r\n\t/** @returns true if the given path remains valid; false if the tree has been mutated, invalidating the path. */\r\n\tisValid(path: Path<TKey, TEntry>) {\r\n\t\treturn path.version === this._version;\r\n\t}\r\n\r\n\t/**\r\n\t * Adds a value to the tree. Be sure to check the result, as the tree does not allow duplicate keys.\r\n\t * Added entries are frozen to ensure immutability\r\n\t * @returns path to the new (on = true) or conflicting (on = false) row. */\r\n\tasync insert(entry: TEntry): Promise<Path<TKey, TEntry>> {\r\n\t\tObject.freeze(entry);\t// Ensure immutability\r\n\t\tconst path = await this.internalInsert(entry);\r\n\t\tif (path.on) {\r\n\t\t\tpath.version = ++this._version;\r\n\t\t}\r\n\t\treturn path;\r\n\t}\r\n\r\n\t/** Updates the entry at the given path to the given value. Deletes and inserts if the key changes.\r\n\t * @returns path to resulting entry and whether it was an update (as opposed to an insert).\r\n\t * \t* on = true if update/insert succeeded.\r\n\t * \t\t* wasUpdate = true if updated; false if inserted.\r\n\t * \t\t* Returned path is on entry\r\n\t * \t* on = false if update/insert failed.\r\n\t * \t\t* wasUpdate = true, given path is not on an entry\r\n\t * \t\t* else newEntry's new key already present; returned path is \"near\" existing entry */\r\n\tasync updateAt(path: Path<TKey, TEntry>, newEntry: TEntry): Promise<[path: Path<TKey, TEntry>, wasUpdate: boolean]> {\r\n\t\tthis.validatePath(path);\r\n\t\tif (path.on) {\r\n\t\t\tObject.freeze(newEntry);\r\n\t\t}\r\n\t\tconst result = await this.internalUpdate(path, newEntry);\r\n\t\tif (result[0].on) {\r\n\t\t\tresult[0].version = ++this._version;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\t/** Inserts the entry if it doesn't exist, or updates it if it does.\r\n\t * The entry is frozen to ensure immutability.\r\n\t * @returns path to the new entry. on = true if existing; on = false if new. */\r\n\tasync upsert(entry: TEntry): Promise<Path<TKey, TEntry>> {\r\n\t\tconst path = await this.find(this.keyFromEntry(entry));\r\n\t\tObject.freeze(entry);\r\n\t\tif (path.on) {\r\n\t\t\tthis.updateEntry(path, entry);\r\n\t\t} else {\r\n\t\t\tawait this.internalInsertAt(path, entry);\r\n\t\t}\r\n\t\tpath.version = ++this._version;\r\n\t\treturn path;\r\n\t}\r\n\r\n\t/** Inserts or updates depending on the existence of the given key, using callbacks to generate the new value.\r\n\t * @param newEntry the new entry to insert if the key doesn't exist.\r\n\t * @param getUpdated a callback to generate an updated entry if the key does exist. WARNING: mutation in this callback will cause merge to error.\r\n\t * @returns path to new entry and whether an update or insert attempted.\r\n\t * If getUpdated callback returns a row that is already present, the resulting path will not be on. */\r\n\tasync merge(newEntry: TEntry, getUpdated: (existing: TEntry) => TEntry): Promise<[path: Path<TKey, TEntry>, wasUpdate: boolean]> {\r\n\t\tconst newKey = await this.keyFromEntry(newEntry);\r\n\t\tconst path = await this.find(newKey);\r\n\t\tif (path.on) {\r\n\t\t\tconst result = await this.updateAt(path, getUpdated(this.getEntry(path)));\t// Don't use internalUpdate - need to freeze and check for mutation\r\n\t\t\t// Note: updateAt already increments version, so don't double-increment here\r\n\t\t\treturn result;\r\n\t\t} else {\r\n\t\t\tawait this.internalInsertAt(path, Object.freeze(newEntry));\r\n\t\t\tpath.on = true;\r\n\t\t\tpath.version = ++this._version;\r\n\t\t\treturn [path, false];\r\n\t\t}\r\n\t}\r\n\r\n\t/** Deletes the entry at the given path.\r\n\t * The on property of the path will be cleared.\r\n\t * @returns true if the delete succeeded (the key was found); false otherwise.\r\n\t*/\r\n\tasync deleteAt(path: Path<TKey, TEntry>): Promise<boolean> {\r\n\t\tthis.validatePath(path);\r\n\t\tconst result = await this.internalDelete(path);\r\n\t\tif (result) {\r\n\t\t\t++this._version;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\tasync drop() {\t// Node: only when a root treeBlock\r\n\t\tconst root = await this.trunk.get();\r\n\t\tfor await (const id of this.nodeIds(root)) {\r\n\t\t\tthis.store.delete(id);\r\n\t\t}\r\n\t}\r\n\r\n\t/** Iterates forward starting from the path location (inclusive) to the end.\r\n\t * WARNING: mutation during iteration will result in an exception.\r\n\t*/\r\n\tascending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\tthis.validatePath(path);\r\n\t\treturn this.internalAscending(path.clone());\r\n\t}\r\n\r\n\t/** Iterates backward starting from the path location (inclusive) to the end.\r\n\t * WARNING: mutation during iteration will result in an exception\r\n\t*/\r\n\tdescending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\tthis.validatePath(path);\r\n\t\treturn this.internalDescending(path.clone());\r\n\t}\r\n\r\n\t/** Computed (not stored) count. Computes the sum using leaf-node lengths. O(n/af) where af is average fill.\r\n\t * @param from if provided, the count will start from the given path (inclusive). If ascending is false,\r\n\t * \tthe count will start from the end of the tree. Ascending is true by default.\r\n\t */\r\n\tasync getCount(from?: { path: Path<TKey, TEntry>, ascending?: boolean }): Promise<number> {\r\n\t\tlet result = 0;\r\n\t\tconst path = from ? from.path.clone() : await this.first();\r\n\t\tif (from?.ascending ?? true) {\r\n\t\t\twhile (path.on) {\r\n\t\t\t\tresult += path.leafNode.entries.length - path.leafIndex;\r\n\t\t\t\tpath.leafIndex = path.leafNode.entries.length - 1;\r\n\t\t\t\tawait this.internalNext(path);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\twhile (path.on) {\r\n\t\t\t\tresult += path.leafIndex + 1;\r\n\t\t\t\tpath.leafIndex = 0;\r\n\t\t\t\tawait this.internalPrior(path);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\t/** @returns a path one step forward. on will be true if the path hasn't hit the end. */\r\n\tasync next(path: Path<TKey, TEntry>): Promise<Path<TKey, TEntry>> {\r\n\t\tconst newPath = path.clone();\r\n\t\tawait this.moveNext(newPath);\r\n\t\treturn newPath;\r\n\t}\r\n\r\n\t/** Attempts to advance the given path one step forward. (mutates the path) */\r\n\tasync moveNext(path: Path<TKey, TEntry>) {\r\n\t\tthis.validatePath(path);\r\n\t\tawait this.internalNext(path);\r\n\t}\r\n\r\n\t/** @returns a path one step backward. on will be true if the path hasn't hit the end. */\r\n\tasync prior(path: Path<TKey, TEntry>): Promise<Path<TKey, TEntry>> {\r\n\t\tconst newPath = path.clone();\r\n\t\tthis.movePrior(newPath);\r\n\t\treturn newPath;\r\n\t}\r\n\r\n\t/** Attempts to advance the given path one step backwards. (mutates the path) */\r\n\tasync movePrior(path: Path<TKey, TEntry>) {\r\n\t\tthis.validatePath(path);\r\n\t\tawait this.internalPrior(path);\r\n\t}\r\n\r\n\t/** @remarks Assumes the path is \"on\" */\r\n\tprotected keyFromPath(path: Path<TKey, TEntry>): TKey {\r\n\t\treturn this.keyFromEntry(path.leafNode.entries[path.leafIndex]!);\r\n\t}\r\n\r\n\tprivate async *internalAscending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\tthis.validatePath(path);\r\n\t\twhile (path.on) {\r\n\t\t\tyield path;\r\n\t\t\tawait this.moveNext(path);\t// Not internal - re-check after yield\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async *internalDescending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\tthis.validatePath(path);\r\n\t\twhile (path.on) {\r\n\t\t\tyield path;\r\n\t\t\tawait this.movePrior(path);\t// Not internal - re-check after yield\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async findFirst(range: KeyRange<TKey>) {\t// Assumes range.first is defined\r\n\t\tconst startPath = await this.find(range.first!.key)\r\n\t\tif (!startPath.on || (range.first && !range.first.inclusive)) {\r\n\t\t\tif (range.isAscending) {\r\n\t\t\t\tawait this.internalNext(startPath);\r\n\t\t\t} else {\r\n\t\t\t\tawait this.internalPrior(startPath);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn startPath;\r\n\t}\r\n\r\n\tprivate async findLast(range: KeyRange<TKey>) {\t// Assumes range.last is defined\r\n\t\tconst endPath = await this.find(range.last!.key)\r\n\t\tif (!endPath.on || (range.last && !range.last.inclusive)) {\r\n\t\t\tif (range.isAscending) {\r\n\t\t\t\tawait this.internalPrior(endPath);\r\n\t\t\t} else {\r\n\t\t\t\tawait this.internalNext(endPath);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn endPath;\r\n\t}\r\n\r\n\tprotected async getPath(node: ITreeNode, key: TKey): Promise<Path<TKey, TEntry>> {\r\n\t\tif (node.header.type === TreeLeafBlockType) {\r\n\t\t\tconst leaf = node as LeafNode<TEntry>;\r\n\t\t\tconst [on, index] = this.indexOfEntry(leaf.entries, key);\r\n\t\t\treturn new Path<TKey, TEntry>([], leaf, index, on, this._version);\r\n\t\t} else {\r\n\t\t\tconst branch = node as BranchNode<TKey>;\r\n\t\t\tconst index = this.indexOfKey(branch.partitions, key);\r\n\t\t\tconst path = await this.getPath(await get(this.store, branch.nodes[index]!), key);\r\n\t\t\tpath.branches.unshift(new PathBranch(branch, index));\r\n\t\t\treturn path;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate indexOfEntry(entries: TEntry[], key: TKey): [on: boolean, index: number] {\r\n\t\tlet lo = 0;\r\n\t\tlet hi = entries.length - 1;\r\n\t\tlet split = 0;\r\n\t\tlet result = -1;\r\n\r\n\t\twhile (lo <= hi) {\r\n\t\t\tsplit = (lo + hi) >>> 1;\r\n\t\t\tresult = this.compare(key, this.keyFromEntry(entries[split]!));\r\n\r\n\t\t\tif (result === 0)\r\n\t\t\t\treturn [true, split];\r\n\t\t\telse if (result < 0)\r\n\t\t\t\thi = split - 1;\r\n\t\t\telse\r\n\t\t\t\tlo = split + 1;\r\n\t\t}\r\n\r\n\t\treturn [false, lo];\r\n\t}\r\n\r\n\tprotected indexOfKey(keys: TKey[], key: TKey): number {\r\n\t\tlet lo = 0;\r\n\t\tlet hi = keys.length - 1;\r\n\t\tlet split = 0;\r\n\t\tlet result = -1;\r\n\r\n\t\twhile (lo <= hi) {\r\n\t\t\tsplit = (lo + hi) >>> 1;\r\n\t\t\tresult = this.compare(key, keys[split]!);\r\n\r\n\t\t\tif (result === 0)\r\n\t\t\t\treturn split + 1;\t// +1 because taking right partition\r\n\t\t\telse if (result < 0)\r\n\t\t\t\thi = split - 1;\r\n\t\t\telse\r\n\t\t\t\tlo = split + 1;\r\n\t\t}\r\n\r\n\t\treturn lo;\r\n\t}\r\n\r\n\tprivate async internalNext(path: Path<TKey, TEntry>) {\r\n\t\tif (!path.on) {\t// Attempt to move off of crack\r\n\t\t\tpath.on = path.branches.every(branch => branch.index >= 0 && branch.index < branch.node.nodes.length)\r\n\t\t\t\t&& path.leafIndex >= 0 && path.leafIndex < path.leafNode.entries.length;\r\n\t\t\tif (path.on) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t} else if (path.leafIndex >= path.leafNode.entries.length - 1) {\r\n\t\t\tlet popCount = 0;\r\n\t\t\tlet found = false;\r\n\t\t\tconst last = path.branches.length - 1;\r\n\t\t\twhile (popCount <= last && !found) {\r\n\t\t\t\tconst branch = path.branches[last - popCount]!;\r\n\t\t\t\tif (branch.index === branch.node.partitions.length)\t// last node in branch\r\n\t\t\t\t\t++popCount;\r\n\t\t\t\telse\r\n\t\t\t\t\tfound = true;\r\n\t\t\t}\r\n\r\n\t\t\tif (!found) {\r\n\t\t\t\tpath.leafIndex = path.leafNode.entries.length;\t// after last row = end crack\r\n\t\t\t\tpath.on = false;\r\n\t\t\t} else {\r\n\t\t\t\tpath.branches.splice(-popCount, popCount);\r\n\t\t\t\tconst branch = path.branches.at(-1)!;\r\n\t\t\t\t++branch.index;\r\n\t\t\t\tthis.moveToFirst(await get(this.store, branch.node.nodes[branch.index]!), path);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse {\r\n\t\t\t++path.leafIndex;\r\n\t\t\tpath.on = true;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async internalPrior(path: Path<TKey, TEntry>) {\r\n\t\tthis.validatePath(path);\r\n\t\tif (path.leafIndex <= 0) {\r\n\t\t\tlet popCount = 0;\r\n\t\t\tlet opening = false;\r\n\t\t\tconst last = path.branches.length - 1;\r\n\t\t\twhile (popCount <= last && !opening) {\r\n\t\t\t\tconst branch = path.branches[last - popCount]!;\r\n\t\t\t\tif (branch.index === 0)\t// first node in branch\r\n\t\t\t\t\t++popCount;\r\n\t\t\t\telse\r\n\t\t\t\t\topening = true;\r\n\t\t\t}\r\n\r\n\t\t\tif (!opening) {\r\n\t\t\t\tpath.leafIndex = 0;\r\n\t\t\t\tpath.on = false;\r\n\t\t\t} else {\r\n\t\t\t\tpath.branches.splice(-popCount, popCount);\r\n\t\t\t\tconst branch = path.branches.at(-1)!;\r\n\t\t\t\t--branch.index;\r\n\t\t\t\tawait this.moveToLast(await get(this.store, branch.node.nodes[branch.index]!), path);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse {\r\n\t\t\t--path.leafIndex;\r\n\t\t\tpath.on = true;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async internalUpdate(path: Path<TKey, TEntry>, newEntry: TEntry): Promise<[path: Path<TKey, TEntry>, wasUpdate: boolean]> {\r\n\t\tif (path.on) {\r\n\t\t\tconst oldKey = this.keyFromPath(path);\r\n\t\t\tconst newKey = this.keyFromEntry(newEntry);\r\n\t\t\tif (this.compare(oldKey, newKey) !== 0) {\t// if key changed, delete and re-insert\r\n\t\t\t\tlet newPath = await this.internalInsert(newEntry)\r\n\t\t\t\tif (newPath.on) {\t// insert succeeded\r\n\t\t\t\t\tthis.internalDelete(await this.find(oldKey));\t// Re-find - the prior insert invalidated the path\r\n\t\t\t\t\tnewPath = await this.find(newKey);\t// Re-find- delete invalidated path\r\n\t\t\t\t}\r\n\t\t\t\treturn [newPath, false];\r\n\t\t\t} else {\r\n\t\t\t\tthis.updateEntry(path, newEntry);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn [path, true];\r\n\t}\r\n\r\n\tprotected async internalDelete(path: Path<TKey, TEntry>): Promise<boolean> {\r\n\t\tif (path.on) {\r\n\t\t\tapply(this.store, path.leafNode, [entries$, path.leafIndex, 1, []]);\r\n\t\t\tif (path.branches.length > 0) { // Only worry about underflows, balancing, etc. if not root\r\n\t\t\t\tif (path.leafIndex === 0 && path.leafNode.entries.length > 0) { // If we deleted index 0 and leaf is not empty, update branches with new key\r\n\t\t\t\t\tconst pathBranch = path.branches.at(-1)!;\r\n\t\t\t\t\tthis.updatePartition(pathBranch.index, path, path.branches.length - 1,\r\n\t\t\t\t\t\tthis.keyFromPath(path));\r\n\t\t\t\t}\r\n\t\t\t\tconst newRoot = await this.rebalanceLeaf(path, path.branches.length);\r\n\t\t\t\tif (newRoot) {\r\n\t\t\t\t\tawait this.trunk.set(newRoot);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tpath.on = false;\r\n\t\t\treturn true;\r\n\t\t} else {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async internalInsert(entry: TEntry): Promise<Path<TKey, TEntry>> {\r\n\t\tconst path = await this.find(this.keyFromEntry(entry));\r\n\t\tif (path.on) {\r\n\t\t\tpath.on = false;\r\n\t\t\treturn path;\r\n\t\t}\r\n\t\tawait this.internalInsertAt(path, entry);\r\n\t\tpath.on = true;\r\n\t\treturn path;\r\n\t}\r\n\r\n\tprivate async internalInsertAt(path: Path<TKey, TEntry>, entry: TEntry) {\r\n\t\tlet split = this.leafInsert(path, entry);\r\n\t\tlet branchIndex = path.branches.length - 1;\r\n\t\twhile (split && branchIndex >= 0) {\r\n\t\t\tsplit = await this.branchInsert(path, branchIndex, split);\r\n\t\t\t--branchIndex;\r\n\t\t}\r\n\t\tif (split) {\r\n\t\t\tconst newBranch = newBranchNode(this.store, [split.key], [await this.trunk.getId(), split.right.header.id]);\r\n\t\t\tawait this.store.insert(newBranch);\r\n\t\t\tawait this.trunk.set(newBranch);\r\n\t\t\tpath.branches.unshift(new PathBranch(newBranch, split.indexDelta));\r\n\t\t}\r\n\t}\r\n\r\n\t/** Starting from the given node, recursively working down to the leaf, build onto the path based on the beginning-most entry. */\r\n\tprivate async moveToFirst(node: ITreeNode, path: Path<TKey, TEntry>) {\r\n\t\tif (node.header.type === TreeLeafBlockType) {\r\n\t\t\tconst leaf = node as LeafNode<TEntry>;\r\n\t\t\tpath.leafNode = leaf;\r\n\t\t\tpath.leafIndex = 0;\r\n\t\t\tpath.on = leaf.entries.length > 0;\r\n\t\t} else {\r\n\t\t\tpath.branches.push(new PathBranch(node as BranchNode<TKey>, 0));\r\n\t\t\tawait this.moveToFirst(await get(this.store, (node as BranchNode<TKey>).nodes[0]!), path);\r\n\t\t}\r\n\t}\r\n\r\n\t/** Starting from the given node, recursively working down to the leaf, build onto the path based on the end-most entry. */\r\n\tprivate async moveToLast(node: ITreeNode, path: Path<TKey, TEntry>) {\r\n\t\tif (node.header.type === TreeLeafBlockType) {\r\n\t\t\tconst leaf = node as LeafNode<TEntry>;\r\n\t\t\tconst count = leaf.entries.length;\r\n\t\t\tpath.leafNode = leaf;\r\n\t\t\tpath.on = count > 0;\r\n\t\t\tpath.leafIndex = count > 0 ? count - 1 : 0;\r\n\t\t} else {\r\n\t\t\tconst branch = node as BranchNode<TKey>;\r\n\t\t\tconst pathBranch = new PathBranch(branch, branch.partitions.length);\r\n\t\t\tpath.branches.push(pathBranch);\r\n\t\t\tawait this.moveToLast(await get(this.store, branch.nodes[pathBranch.index]!), path);\r\n\t\t}\r\n\t}\r\n\r\n\t/** Construct a path based on the first-most edge of the given. */\r\n\tprivate async getFirst(node: ITreeNode): Promise<Path<TKey, TEntry>> {\r\n\t\tif (node.header.type === TreeLeafBlockType) {\r\n\t\t\tconst leaf = node as LeafNode<TEntry>;\r\n\t\t\treturn new Path<TKey, TEntry>([], leaf, 0, leaf.entries.length > 0, this._version)\r\n\t\t} else {\r\n\t\t\tconst branch = node as BranchNode<TKey>;\r\n\t\t\tconst path = await this.getFirst(await get(this.store, branch.nodes[0]!));\r\n\t\t\tpath.branches.unshift(new PathBranch(branch, 0));\r\n\t\t\treturn path;\r\n\t\t}\r\n\t}\r\n\r\n\t/** Construct a path based on the last-most edge of the given node */\r\n\tprivate async getLast(node: ITreeNode): Promise<Path<TKey, TEntry>> {\r\n\t\tif (node.header.type === TreeLeafBlockType) {\r\n\t\t\tconst leaf = node as LeafNode<TEntry>;\r\n\t\t\tconst count = leaf.entries.length;\r\n\t\t\treturn new Path<TKey, TEntry>([], leaf, count > 0 ? count - 1 : 0, count > 0, this._version);\r\n\t\t} else {\r\n\t\t\tconst branch = node as BranchNode<TKey>;\r\n\t\t\tconst index = branch.nodes.length - 1;\r\n\t\t\tconst path = await this.getLast(await get(this.store, branch.nodes[index]!));\r\n\t\t\tpath.branches.unshift(new PathBranch(branch, index));\r\n\t\t\treturn path;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate leafInsert(path: Path<TKey, TEntry>, entry: TEntry): Split<TKey> | undefined {\r\n\t\tconst { leafNode: leaf, leafIndex: index } = path;\r\n\t\tif (leaf.entries.length < NodeCapacity) { // No split needed\r\n\t\t\tapply(this.store, leaf, [entries$, index, 0, [entry]]);\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\t// Full. Split needed\r\n\r\n\t\tconst midIndex = (leaf.entries.length + 1) >>> 1;\r\n\t\tconst newEntries = leaf.entries.slice(midIndex);\r\n\r\n\t\t// New node\r\n\t\tif (index >= midIndex) {\t// Put the new entry directly rather than log an insert\r\n\t\t\tnewEntries.splice(index - midIndex, 0, entry);\r\n\t\t}\r\n\t\tconst newLeaf = newLeafNode(this.store, newEntries);\r\n\t\tthis.store.insert(newLeaf);\r\n\r\n\t\t// Delete entries from old node\r\n\t\tapply(this.store, leaf, [entries$, midIndex, leaf.entries.length - midIndex, []]);\r\n\r\n\t\tif (index < midIndex) {\t// Insert new entry into old node\r\n\t\t\tapply(this.store, leaf, [entries$, index, 0, [entry]]);\r\n\t\t} else {\r\n\t\t\tpath.leafNode = newLeaf;\r\n\t\t\tpath.leafIndex -= midIndex;\r\n\t\t}\r\n\r\n\t\treturn new Split<TKey>(this.keyFromEntry(newEntries[0]!), newLeaf, index < midIndex ? 0 : 1);\r\n\t}\r\n\r\n\tprivate async branchInsert(path: Path<TKey, TEntry>, branchIndex: number, split: Split<TKey>): Promise<Split<TKey> | undefined> {\r\n\t\tconst pathBranch = path.branches[branchIndex]!;\r\n\t\tconst { index: splitIndex, node } = pathBranch;\r\n\t\tpathBranch.index += split.indexDelta;\r\n\t\tif (node.nodes.length < NodeCapacity) { // no split needed\r\n\t\t\tapply(this.store, node, [partitions$, splitIndex, 0, [split.key]]);\r\n\t\t\tapply(this.store, node, [nodes$, splitIndex + 1, 0, [split.right.header.id]]);\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\t// Full. Split needed\r\n\r\n\t\tconst midIndex = (node.nodes.length + 1) >>> 1;\r\n\t\tconst newPartitions = node.partitions.slice(midIndex);\r\n\t\tconst newNodes = node.nodes.slice(midIndex);\r\n\t\tconst delta = pathBranch.index < midIndex ? 0 : 1;\r\n\r\n\t\t// New node\r\n\t\tif (delta) {\t// If split is on new, add it before the split to avoid logging an insert\r\n\t\t\tpathBranch.index -= midIndex;\r\n\t\t\tnewPartitions.splice(pathBranch.index, 0, split.key);\r\n\t\t\tnewNodes.splice(pathBranch.index + 1, 0, split.right.header.id);\r\n\t\t}\r\n\t\tconst newBranch = newBranchNode(this.store, newPartitions, newNodes);\r\n\r\n\t\t// Delete partitions and nodes\r\n\t\tconst newPartition = node.partitions[midIndex - 1]!;\r\n\t\tapply(this.store, node, [partitions$, midIndex - 1, newPartitions.length + 1, []]);\r\n\t\tapply(this.store, node, [nodes$, midIndex, newNodes.length, []]);\r\n\r\n\t\tif (pathBranch.index < midIndex) {\t// Insert into old node\r\n\t\t\tapply(this.store, node, [partitions$, splitIndex, 0, [split.key]]);\r\n\t\t\tapply(this.store, node, [nodes$, splitIndex + 1, 0, [split.right.header.id]]);\r\n\t\t}\r\n\r\n\t\treturn new Split<TKey>(newPartition, newBranch, delta);\r\n\t}\r\n\r\n\tprotected async rebalanceLeaf(path: Path<TKey, TEntry>, depth: number): Promise<ITreeNode | undefined> {\r\n\t\tif (depth === 0 || path.leafNode.entries.length >= (NodeCapacity >>> 1)) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tconst leaf = path.leafNode;\r\n\t\tconst parent = path.branches.at(depth - 1)!;\r\n\t\tconst pIndex = parent.index;\r\n\t\tconst pNode = parent.node;\r\n\r\n\t\tconst rightSibId = pNode.nodes[pIndex + 1]!;\r\n\t\tconst rightSib = rightSibId ? (await get(this.store, rightSibId)) as LeafNode<TEntry> : undefined;\r\n\t\tif (rightSib && rightSib.entries.length > (NodeCapacity >>> 1)) { // Attempt to borrow from right sibling\r\n\t\t\tconst entry = rightSib.entries[0]!;\r\n\t\t\tapply(this.store, rightSib, [entries$, 0, 1, []]);\r\n\t\t\tapply(this.store, leaf, [entries$, leaf.entries.length, 0, [entry]]);\r\n\t\t\tthis.updatePartition(pIndex + 1, path, depth - 1, this.keyFromEntry(entry));\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tconst leftSibId = pNode.nodes[pIndex - 1]!;\r\n\t\tconst leftSib = leftSibId ? (await get(this.store, leftSibId)) as LeafNode<TEntry> : undefined;\r\n\t\tif (leftSib && leftSib.entries.length > (NodeCapacity >>> 1)) { // Attempt to borrow from left sibling\r\n\t\t\tconst entry = leftSib.entries[leftSib.entries.length - 1]!;\r\n\t\t\tapply(this.store, leftSib, [entries$, leftSib.entries.length - 1, 1, []]);\r\n\t\t\tapply(this.store, leaf, [entries$, 0, 0, [entry]]);\r\n\t\t\tthis.updatePartition(pIndex, path, depth - 1, this.keyFromEntry(entry));\r\n\t\t\tpath.leafIndex += 1;\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tif (rightSib && rightSib.entries.length + leaf.entries.length <= NodeCapacity) { // Attempt to merge right sibling into leaf (right sib deleted)\r\n\t\t\tapply(this.store, leaf, [entries$, leaf.entries.length, 0, rightSib.entries]);\r\n\t\t\tthis.deletePartition(pNode, pIndex);\r\n\t\t\tif (pIndex === 0) { // 0th node of parent, update parent key\r\n\t\t\t\tthis.updatePartition(pIndex, path, depth - 1, this.keyFromEntry(leaf.entries[0]!));\r\n\t\t\t}\r\n\t\t\tthis.store.delete(rightSib.header.id);\r\n\t\t\treturn await this.rebalanceBranch(path, depth - 1);\r\n\t\t}\r\n\r\n\t\tif (leftSib && leftSib.entries.length + leaf.entries.length <= NodeCapacity) { // Attempt to merge into left sibling (leaf deleted)\r\n\t\t\tpath.leafNode = leftSib;\r\n\t\t\tpath.leafIndex += leftSib.entries.length;\r\n\t\t\tapply(this.store, leftSib, [entries$, leftSib.entries.length, 0, leaf.entries]);\r\n\t\t\tthis.deletePartition(pNode, pIndex - 1);\r\n\t\t\tthis.store.delete(leaf.header.id);\r\n\t\t\treturn await this.rebalanceBranch(path, depth - 1);\r\n\t\t}\r\n\t}\r\n\r\n\tprotected async rebalanceBranch(path: Path<TKey, TEntry>, depth: number): Promise<ITreeNode | undefined> {\r\n\t\tconst pathBranch = path.branches[depth]!;\r\n\t\tconst branch = pathBranch.node;\r\n\t\tif (depth === 0 && branch.partitions.length === 0) { // last node... collapse child into root\r\n\t\t\treturn path.branches[depth + 1]?.node ?? path.leafNode;\r\n\t\t}\r\n\r\n\t\tif (depth === 0 || (branch.nodes.length >= NodeCapacity >>> 1)) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tconst parent = path.branches.at(depth - 1)!;\r\n\t\tconst pIndex = parent.index;\r\n\t\tconst pNode = parent.node;\r\n\r\n\t\tconst rightSibId = pNode.nodes[pIndex + 1]!;\r\n\t\tconst rightSib = rightSibId ? (await get(this.store, rightSibId)) as BranchNode<TKey> : undefined;\r\n\t\tif (rightSib && rightSib.nodes.length > (NodeCapacity >>> 1)) { // Attempt to borrow from right sibling\r\n\t\t\tconst node = rightSib.nodes[0]!;\r\n\t\t\tconst rightKey = rightSib.partitions[0]!;\r\n\t\t\tthis.insertPartition(branch, branch.partitions.length, pNode.partitions[pIndex]!, node);\r\n\t\t\tthis.deletePartition(rightSib, 0, 0);\r\n\t\t\tthis.updatePartition(pIndex + 1, path, depth - 1, rightKey);\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tconst leftSibId = pNode.nodes[pIndex - 1];\r\n\t\tconst leftSib = leftSibId ? (await get(this.store, leftSibId)) as BranchNode<TKey> : undefined;\r\n\t\tif (leftSib && leftSib.nodes.length > (NodeCapacity >>> 1)) { // Attempt to borrow from left sibling\r\n\t\t\tconst node = leftSib.nodes[leftSib.nodes.length - 1]!;\r\n\t\t\tconst pKey = leftSib.partitions[leftSib.partitions.length - 1]!;\r\n\t\t\tthis.insertPartition(branch, 0, pNode.partitions[pIndex - 1]!, node, 0);\r\n\t\t\tthis.deletePartition(leftSib, leftSib.partitions.length - 1);\r\n\t\t\tpathBranch.index += 1;\r\n\t\t\tthis.updatePartition(pIndex, path, depth - 1, pKey);\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\tif (rightSib && rightSib.nodes.length + branch.nodes.length <= NodeCapacity) { // Attempt to merge right sibling into self\r\n\t\t\tconst pKey = pNode.partitions[pIndex]!;\r\n\t\t\tthis.deletePartition(pNode, pIndex);\r\n\t\t\tapply(this.store, branch, [partitions$, branch.partitions.length, 0, [pKey]]);\r\n\t\t\tapply(this.store, branch, [partitions$, branch.partitions.length, 0, rightSib.partitions]);\r\n\t\t\tapply(this.store, branch, [nodes$, branch.nodes.length, 0, rightSib.nodes]);\r\n\t\t\tif (pIndex === 0 && pNode.partitions.length > 0) {\t// if parent is left edge, new right sibling is now the first partition\r\n\t\t\t\tthis.updatePartition(pIndex, path, depth - 1, pNode.partitions[0]!);\r\n\t\t\t}\r\n\t\t\tthis.store.delete(rightSib.header.id);\r\n\t\t\treturn this.rebalanceBranch(path, depth - 1);\r\n\t\t}\r\n\r\n\t\tif (leftSib && leftSib.nodes.length + branch.nodes.length <= NodeCapacity) { // Attempt to merge self into left sibling\r\n\t\t\tconst pKey = pNode.partitions[pIndex - 1]!;\r\n\t\t\tthis.deletePartition(pNode, pIndex - 1);\r\n\t\t\tapply(this.store, leftSib, [partitions$, leftSib.partitions.length, 0, [pKey]]);\r\n\t\t\tapply(this.store, leftSib, [partitions$, leftSib.partitions.length, 0, branch.partitions]);\r\n\t\t\tapply(this.store, leftSib, [nodes$, leftSib.nodes.length, 0, branch.nodes]);\r\n\t\t\tpathBranch.node = leftSib;\r\n\t\t\tpathBranch.index += leftSib.nodes.length;\r\n\t\t\tthis.store.delete(branch.header.id);\r\n\t\t\treturn this.rebalanceBranch(path, depth - 1);\r\n\t\t}\r\n\t}\r\n\r\n\tprotected updatePartition(nodeIndex: number, path: Path<TKey, TEntry>, depth: number, newKey: TKey) {\r\n\t\tconst pathBranch = path.branches[depth]!;\r\n\t\tif (nodeIndex > 0) { // Only affects this branch; just update the partition key\r\n\t\t\tapply(this.store, pathBranch.node, [partitions$, nodeIndex - 1, 1, [newKey]]);\r\n\t\t} else if (depth !== 0) {\r\n\t\t\tthis.updatePartition(path.branches[depth - 1]!.index, path, depth - 1, newKey);\r\n\t\t}\r\n\t}\r\n\r\n\tprotected insertPartition(branch: BranchNode<TKey>, index: number, key: TKey, node: BlockId, nodeOffset = 1) {\r\n\t\tapply(this.store, branch, [partitions$, index, 0, [key]]);\r\n\t\tapply(this.store, branch, [nodes$, index + nodeOffset, 0, [node]]);\r\n\t}\r\n\r\n\tprotected deletePartition(branch: BranchNode<TKey>, index: number, nodeOffset = 1) {\r\n\t\tapply(this.store, branch, [partitions$, index, 1, []]);\r\n\t\tapply(this.store, branch, [nodes$, index + nodeOffset, 1, []]);\r\n\t}\r\n\r\n\tprivate validatePath(path: Path<TKey, TEntry>) {\r\n\t\tif (!this.isValid(path)) {\r\n\t\t\tthrow new Error(\"Path is invalid due to mutation of the tree\");\r\n\t\t}\r\n\t}\r\n\r\n\t/** Iterates every node ID below and including the given node. */\r\n\tprivate async *nodeIds(node: ITreeNode): AsyncIterableIterator<BlockId> {\r\n\t\t// TODO: This would be much more efficient if we avoided iterating into leaf nodes\r\n\t\tif (node.header.type === TreeBranchBlockType) {\r\n\t\t\tconst subNodes = await Promise.all((node as BranchNode<TKey>).nodes.map(id => get(this.store, id)));\r\n\t\t\tfor (let subNode of subNodes) {\r\n\t\t\t\tyield* this.nodeIds(subNode);\r\n\t\t\t}\r\n\t\t}\r\n\t\tyield node.header.id;\r\n\t}\r\n\r\n\tprotected getEntry(path: Path<TKey, TEntry>): TEntry {\r\n\t\treturn path.leafNode.entries[path.leafIndex]!;\r\n\t}\r\n\r\n\tprotected updateEntry(path: Path<TKey, TEntry>, entry: TEntry) {\r\n\t\tapply(this.store, path.leafNode, [entries$, path.leafIndex, 1, [entry]]);\r\n\t}\r\n}\r\n\r\nclass Split<TKey> {\r\n\tconstructor(\r\n\t\tpublic key: TKey,\r\n\t\tpublic right: ITreeNode,\r\n\t\tpublic indexDelta: number\r\n\t) { }\r\n}\r\n\r\nfunction newLeafNode<TEntry>(store: BlockStore<ITreeNode>, entries: TEntry[]): LeafNode<TEntry> {\r\n\tconst header = store.createBlockHeader(TreeLeafBlockType);\r\n\treturn { header, entries };\r\n}\r\n\r\nfunction newBranchNode<TKey>(store: BlockStore<ITreeNode>, partitions: TKey[], nodes: BlockId[]): BranchNode<TKey> {\r\n\tconst header = store.createBlockHeader(TreeBranchBlockType);\r\n\treturn { header, partitions, nodes };\r\n}\r\n", "export class KeyBound<TKey> {\r\n\tconstructor (\r\n\t\t\tpublic key: TKey,\r\n\t\t\tpublic inclusive = true,\r\n\t) {}\r\n}\r\n\r\n/** Used for range scans. Omitting first or last implies the end of the tree. */\r\nexport class KeyRange<TKey> {\r\n\tconstructor (\r\n\t\t\tpublic first?: KeyBound<TKey>,\r\n\t\t\tpublic last?: KeyBound<TKey>,\r\n\t\t\tpublic isAscending = true,\r\n\t) {}\r\n}\r\n", "import { BTree } from \"./btree.js\";\r\n\r\nexport class Keyset<TKey> extends BTree<TKey, TKey> {\r\n\r\n}\r\n\r\n", "import type { BranchNode, LeafNode } from \"./nodes.js\";\r\n\r\nexport class PathBranch<TKey> {\r\n\tconstructor (\r\n\t\t\tpublic node: BranchNode<TKey>,\r\n\t\t\tpublic index: number,\r\n\t) {}\r\n\r\n\tclone() {\r\n\t\t\treturn new PathBranch(this.node, this.index);\r\n\t}\r\n}\r\n\r\n/** Represents a cursor in a BTree. Invalid once mutation has occurred (unless it is the results of a mutation method).\r\n * Do not change the properties of this object directly. Use the methods of the BTree class to manipulate it.\r\n * @member on - true if the cursor is on an entry, false if it is between entries.\r\n */\r\nexport class Path<TKey, TEntry> {\r\n\tconstructor(\r\n\t\t\tpublic branches: PathBranch<TKey>[],\r\n\t\t\tpublic leafNode: LeafNode<TEntry>,\r\n\t\t\tpublic leafIndex: number,\r\n\t\t\tpublic on: boolean,\r\n\t\t\tpublic version: number,\r\n\t) { }\r\n\r\n\tisEqual(path: Path<TKey, TEntry>) {\r\n\t\t\treturn this.leafNode === path.leafNode\r\n\t\t\t\t\t&& this.leafIndex === path.leafIndex\r\n\t\t\t\t\t&& this.on === path.on\r\n\t\t\t\t\t&& this.version === path.version;\r\n\t}\r\n\r\n\tclone() {\r\n\t\t\treturn new Path(this.branches.map(b => b.clone()), this.leafNode, this.leafIndex, this.on, this.version);\r\n\t}\r\n}\r\n", "import { type IBlock, type BlockId, registerBlockType } from \"../blocks/index.js\";\r\nimport { nameof } from \"../utility/nameof.js\";\r\n\r\nexport type ChainDataNode<TEntry> = IBlock & {\r\n\tentries: TEntry[];\r\n\tpriorId: BlockId | undefined;\r\n\tnextId: BlockId | undefined;\r\n};\r\n\r\nexport const entries$ = nameof<ChainDataNode<any>>(\"entries\");\r\nexport const priorId$ = nameof<ChainDataNode<any>>(\"priorId\");\r\nexport const nextId$ = nameof<ChainDataNode<any>>(\"nextId\");\r\n\r\nexport const ChainDataBlockType = registerBlockType('CHD', 'ChainDataBlock');\r\n\r\nexport type ChainHeaderNode = IBlock & {\r\n\theadId: BlockId;\r\n\ttailId: BlockId;\r\n};\r\n\r\nexport const headId$ = nameof<ChainHeaderNode>(\"headId\");\r\nexport const tailId$ = nameof<ChainHeaderNode>(\"tailId\");\r\n\r\nexport const ChainHeaderBlockType = registerBlockType('CHH', 'ChainHeaderBlock');\r\n", "import { Atomic, type BlockStore, type BlockId, type IBlock } from \"../index.js\";\r\nimport { ChainDataBlockType, ChainHeaderBlockType, entries$, headId$, nextId$, priorId$, tailId$ } from \"./chain-nodes.js\";\r\nimport type { ChainDataNode, ChainHeaderNode } from \"./chain-nodes.js\";\r\nimport { apply } from \"../blocks/index.js\";\r\n\r\nexport const EntriesPerBlock = 32;\r\n\r\nexport type ChainPath<TEntry> = {\r\n\theaderBlock: ChainHeaderNode;\r\n\tblock: ChainDataNode<TEntry>;\r\n\tindex: number; // Index of the entry in the block\r\n};\r\n\r\nexport type ChainNodeInit<T> = IBlock & {\r\n\t[K in keyof Omit<T, keyof IBlock>]?: T[K];\r\n};\r\n\r\nexport type ChainInitOptions<TEntry> = {\r\n\tcreateDataBlock?: () => ChainNodeInit<ChainDataNode<TEntry>>;\r\n\tcreateHeaderBlock?: (id?: BlockId) => ChainNodeInit<ChainHeaderNode>;\r\n\tnewBlock?: (newTail: ChainDataNode<TEntry>, oldTail: ChainDataNode<TEntry> | undefined) => Promise<void>;\r\n}\r\n\r\nexport type ChainCreateOptions<TEntry> = ChainInitOptions<TEntry> & {\r\n\tnewId?: BlockId;\r\n};\r\n\r\n// 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\r\n\r\n/** Represents a chain of blocks, forming a stack, queue, or log. */\r\nexport class Chain<TEntry> {\r\n\tprivate constructor(\r\n\t\treadonly store: BlockStore<IBlock>,\r\n\t\tpublic readonly id: BlockId,\r\n\t\tprivate readonly options?: ChainInitOptions<TEntry>,\r\n\t) {\r\n\t}\r\n\r\n\t/** Creates a new queue, with an optional given id. */\r\n\tstatic async create<TEntry>(store: BlockStore<IBlock>, options?: ChainCreateOptions<TEntry>) {\r\n\t\tconst tailBlock = Chain.createTailBlock<TEntry>(store, options);\r\n\t\tconst headerBlock = {\r\n\t\t\t...(options?.createHeaderBlock?.(options?.newId) ?? { header: store.createBlockHeader(ChainHeaderBlockType, options?.newId) }),\r\n\t\t\theadId: tailBlock.header.id,\r\n\t\t\ttailId: tailBlock.header.id,\r\n\t\t} as ChainHeaderNode;\r\n\t\tstore.insert(headerBlock);\r\n\t\tstore.insert(tailBlock);\r\n\t\treturn new Chain<TEntry>(store, headerBlock.header.id, options);\r\n\t}\r\n\r\n\tprivate static createTailBlock<TEntry>(store: BlockStore<IBlock>, options: ChainCreateOptions<TEntry> | undefined) {\r\n\t\treturn {\r\n\t\t\t...(options?.createDataBlock?.() ?? { header: store.createBlockHeader(ChainDataBlockType) }),\r\n\t\t\tentries: [] as TEntry[],\r\n\t\t\tpriorId: undefined,\r\n\t\t\tnextId: undefined,\r\n\t\t} as ChainDataNode<TEntry>;\r\n\t}\r\n\r\n\t/** Opens an existing chain, verifying and potentially initializing the header. */\r\n\tstatic async open<TEntry>(store: BlockStore<IBlock>, id: BlockId, options?: ChainInitOptions<TEntry>): Promise<Chain<TEntry> | undefined> {\r\n\t\tconst headerBlock = await store.tryGet(id) as ChainHeaderNode | undefined;\r\n\t\tif (!headerBlock) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\r\n\t\t// If the header block is missing headId or tailId, create a tail block and update the header\r\n\t\tconst headerAny = headerBlock as any; // Use 'any' for easier property checking/setting\r\n\t\tif (!Object.hasOwn(headerAny, 'headId') || !Object.hasOwn(headerAny, 'tailId')) {\r\n\t\t\tconst tailBlock = Chain.createTailBlock<TEntry>(store, options);\r\n\t\t\tstore.insert(tailBlock);\r\n\t\t\tapply(store, headerBlock, [headId$, 0, 0, tailBlock.header.id]);\r\n\t\t\tapply(store, headerBlock, [tailId$, 0, 0, tailBlock.header.id]);\r\n\t\t}\r\n\r\n\t\treturn new Chain<TEntry>(store, id, options);\r\n\t}\r\n\r\n\t/**\r\n\t * Adds entries to the tail (last-in end) of the chain. Equivalent of enqueue or push.\r\n\t * @param entries - The entries to add.\r\n\t * @returns Path to the new tail of the chain (entry just past the end).\r\n\t */\r\n\tasync add(...entries: TEntry[]): Promise<ChainPath<TEntry>> {\r\n\t\tconst path = await this.getTail();\r\n\t\tif (!path) {\r\n\t\t\tthrow new Error(\"Cannot add to non-existent chain\");\r\n\t\t}\r\n\r\n\t\tconst { headerBlock, block: oldTail } = path;\r\n\t\tlet tail = oldTail;\r\n\r\n\t\tconst trx = new Atomic(this.store);\r\n\r\n\t\t// Attempt to fit in current block\r\n\t\tconst copied = entries.slice(0, EntriesPerBlock - tail.entries.length);\r\n\t\tif (copied.length > 0) {\r\n\t\t\tapply(trx, tail, [entries$, tail.entries.length, 0, copied]);\r\n\t\t\tentries = entries.slice(copied.length);\r\n\t\t}\r\n\r\n\t\twhile (entries.length > 0) {\r\n\t\t\tconst newTail = {\r\n\t\t\t\t...(this.options?.createDataBlock?.() ?? { header: this.store.createBlockHeader(ChainDataBlockType) }),\r\n\t\t\t\tentries: entries.splice(0, Math.min(EntriesPerBlock, entries.length)),\r\n\t\t\t\tpriorId: tail.header.id,\r\n\t\t\t\tnextId: undefined,\r\n\t\t\t} as ChainDataNode<TEntry>;\r\n\t\t\tawait this.options?.newBlock?.(newTail, oldTail);\r\n\t\t\ttrx.insert(newTail);\r\n\t\t\tapply(trx, tail, [nextId$, 0, 0, newTail.header.id]);\r\n\t\t\ttail = newTail;\r\n\t\t}\r\n\r\n\t\tif (tail !== oldTail) {\r\n\t\t\tapply(trx, headerBlock, [tailId$, 0, 0, tail.header.id]);\r\n\t\t}\r\n\r\n\t\ttrx.commit();\r\n\r\n\t\treturn { headerBlock, block: tail, index: tail.entries.length - 1 };\r\n\t}\r\n\r\n\t/** Updates the entry at the given path. */\r\n\tupdateAt(path: ChainPath<TEntry>, entry: TEntry) {\r\n\t\tif (!pathValid(path)) {\r\n\t\t\tthrow new Error(\"Invalid path\");\r\n\t\t}\r\n\t\tconst { index, block } = path;\r\n\t\tapply(this.store, block, [entries$, index, 1, [entry]]);\r\n\t}\r\n\r\n\t/**\r\n\t * Removes up to n entries from the tail (last-in end) of the chain.\r\n\t * @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.\r\n\t * @returns An array of the removed entries. May be less than n if the chain is exhausted.\r\n\t */\r\n\tasync pop(n = 1) {\r\n\t\tif (n <= 0) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\r\n\t\tconst path = await this.getTail();\r\n\t\tif (!path) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\r\n\t\tconst { headerBlock, block: oldTail } = path;\r\n\t\tlet tail = oldTail;\r\n\t\tconst result = [];\r\n\r\n\t\tconst trx = new Atomic(this.store);\r\n\r\n\t\twhile (n > 0) {\r\n\t\t\tif (tail.entries.length > n) { // Partial removal\r\n\t\t\t\tconst removed = tail.entries.slice(-n);\r\n\t\t\t\tresult.unshift(...removed);\r\n\t\t\t\tapply(trx, tail, [entries$, tail.entries.length - n, n, []]);\r\n\t\t\t\tbreak;\r\n\t\t\t} else {\t// Entire block removal\r\n\t\t\t\tresult.unshift(...tail.entries);\r\n\t\t\t\tn -= tail.entries.length;\r\n\t\t\t\tif (tail.priorId) {\r\n\t\t\t\t\ttrx.delete(tail.header.id);\r\n\t\t\t\t\ttail = await trx.tryGet(tail.priorId) as ChainDataNode<TEntry>;\r\n\t\t\t\t\tapply(trx, tail, [nextId$, 0, 0, undefined]);\r\n\t\t\t\t} else {\t// No more blocks... just empty what's left\r\n\t\t\t\t\tapply(trx, tail, [entries$, 0, tail.entries.length, []]);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (tail !== oldTail) {\r\n\t\t\tapply(trx, headerBlock, [tailId$, 0, 0, tail.header.id]);\r\n\t\t}\r\n\r\n\t\ttrx.commit();\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\t/**\r\n\t * Removes up to n entries from the head (first-in end) of the queue.\r\n\t * @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.\r\n\t * @returns An array of the removed entries. May be less than n if the queue is exhausted.\r\n\t */\r\n\tasync dequeue(n = 1) {\r\n\t\tif (n <= 0) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\r\n\t\tconst trx = new Atomic(this.store);\r\n\r\n\t\tconst path = await this.getHead();\r\n\t\tif (!path) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\r\n\t\tconst { headerBlock, block: oldHead } = path;\r\n\t\tlet head = oldHead;\r\n\t\tconst result = [];\r\n\r\n\t\twhile (n > 0) {\r\n\t\t\tif (head.entries.length > n) {\t// Consumes part of block\r\n\t\t\t\tresult.push(...head.entries.slice(0, n));\r\n\t\t\t\tapply(trx, head, [entries$, 0, n, []]);\r\n\t\t\t\tbreak;\r\n\t\t\t} else {\t// Consumes entire block\r\n\t\t\t\tresult.push(...head.entries);\r\n\t\t\t\tn -= head.entries.length;\r\n\t\t\t\tif (head.nextId) {\r\n\t\t\t\t\ttrx.delete(head.header.id);\r\n\t\t\t\t\thead = await trx.tryGet(head.nextId) as ChainDataNode<TEntry>;\r\n\t\t\t\t\tapply(trx, head, [priorId$, 0, 0, undefined]);\r\n\t\t\t\t} else {\t// No more blocks... just empty what's left\r\n\t\t\t\t\tapply(trx, head, [entries$, 0, head.entries.length, []]);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (head !== oldHead) {\r\n\t\t\tapply(trx, headerBlock, [headId$, 0, 0, head.header.id]);\r\n\t\t}\r\n\r\n\t\ttrx.commit();\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\t/** Iterates over the chain, starting at the given path, or the head or tail if not given.\r\n\t * If forward is true (default), the iteration is from head (oldest) to tail (latest); otherwise, it is from tail to head.\r\n\t */\r\n\tasync *select(starting?: ChainPath<TEntry>, forward = true): AsyncIterableIterator<ChainPath<TEntry>> {\r\n\t\tconst path = starting ?? (forward ? await this.getHead() : await this.getTail());\r\n\t\tif (!path) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tlet block: ChainDataNode<TEntry> | undefined = path.block;\r\n\r\n\t\tlet index = path.index;\r\n\t\tif (forward) {\r\n\t\t\twhile (block) {\r\n\t\t\t\tfor (; index < block.entries.length; ++index) {\r\n\t\t\t\t\tyield { headerBlock: path.headerBlock, block, index };\r\n\t\t\t\t}\r\n\t\t\t\tblock = block.nextId ? await this.store.tryGet(block.nextId) as ChainDataNode<TEntry> : undefined;\r\n\t\t\t\tindex = 0;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\twhile (block) {\r\n\t\t\t\tfor (; index >= 0; --index) {\r\n\t\t\t\t\tyield { headerBlock: path.headerBlock, block, index };\r\n\t\t\t\t}\r\n\t\t\t\tblock = block.priorId ? await this.store.tryGet(block.priorId) as ChainDataNode<TEntry> : undefined;\r\n\t\t\t\tindex = (block?.entries.length ?? 0) - 1;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/** Returns the next entry in the chain; returns an off-the-end path if the end is reached. */\r\n\tasync next(path: ChainPath<TEntry>) {\r\n\t\tconst { headerBlock, block, index } = path;\r\n\t\tif (index < block.entries.length - 1 || !block.nextId) {\r\n\t\t\treturn { headerBlock, block, index: index + 1 };\r\n\t\t}\r\n\t\treturn {\r\n\t\t\theaderBlock,\r\n\t\t\tblock: await this.store.tryGet(block.nextId) as ChainDataNode<TEntry>,\r\n\t\t\tindex: 0,\r\n\t\t};\r\n\t}\r\n\r\n\t/** Returns the previous entry in the chain; returns an off-the-start path if the start is reached. */\r\n\tasync prev(path: ChainPath<TEntry>) {\r\n\t\tconst { headerBlock, block, index } = path;\r\n\t\tif (index > 0 || !block.priorId) {\r\n\t\t\treturn { headerBlock, block, index: index - 1 };\r\n\t\t}\r\n\t\tconst priorBlock = await this.store.tryGet(block.priorId) as ChainDataNode<TEntry>;\r\n\t\treturn {\r\n\t\t\theaderBlock,\r\n\t\t\tblock: priorBlock,\r\n\t\t\tindex: priorBlock.entries.length - 1,\r\n\t\t};\r\n\t}\r\n\r\n\tasync getTail(header?: ChainHeaderNode): Promise<ChainPath<TEntry> | undefined> {\r\n\t\tconst headerBlock = header ?? await this.getHeader();\r\n\t\tlet tail = headerBlock ? await this.store.tryGet(headerBlock.tailId) as ChainDataNode<TEntry> : undefined;\r\n\t\t// Possible that the block has filled between reading the header and reading the block... follow nextId links to find true end\r\n\t\twhile (tail?.nextId) {\r\n\t\t\ttail = await this.store.tryGet(tail.nextId) as ChainDataNode<TEntry>;\r\n\t\t}\r\n\t\treturn tail ? { headerBlock, block: tail, index: tail.entries.length - 1 } as ChainPath<TEntry> : undefined;\r\n\t}\r\n\r\n\r\n\tasync getHead(header?: ChainHeaderNode): Promise<ChainPath<TEntry> | undefined> {\r\n\t\tconst headerBlock = header ?? await this.getHeader();\r\n\t\tlet head = headerBlock ? await this.store.tryGet(headerBlock.headId) as ChainDataNode<TEntry> : undefined;\r\n\t\t// Possible that the block has filled between reading the header and reading the block... follow priorId links to find true start\r\n\t\twhile (head?.priorId) {\r\n\t\t\thead = await this.store.tryGet(head.priorId) as ChainDataNode<TEntry>;\r\n\t\t}\r\n\t\treturn head ? { headerBlock, block: head, index: 0 } as ChainPath<TEntry> : undefined;\r\n\t}\r\n\r\n\r\n\tasync getHeader() {\r\n\t\treturn await this.store.tryGet(this.id) as ChainHeaderNode | undefined;\r\n\t}\r\n}\r\n\r\n/** Returns true if the given path is located on an entry (not a crack). */\r\nexport function pathValid<TEntry>(path: ChainPath<TEntry>) {\r\n\treturn path.block.entries.length > path.index && path.index >= 0;\r\n}\r\n\r\n/** Gets the entry at the given path; undefined if the path is not valid. */\r\nexport function entryAt<TEntry>(path: ChainPath<TEntry>): TEntry | undefined {\r\n\treturn path.block.entries[path.index];\r\n}\r\n", "/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a: unknown): a is Uint8Array {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n\n/** Asserts something is positive integer. */\nexport function anumber(n: number, title: string = ''): void {\n if (!Number.isSafeInteger(n) || n < 0) {\n const prefix = title && `\"${title}\" `;\n throw new Error(`${prefix}expected integer >= 0, got ${n}`);\n }\n}\n\n/** Asserts something is Uint8Array. */\nexport function abytes(value: Uint8Array, length?: number, title: string = ''): Uint8Array {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);\n }\n return value;\n}\n\n/** Asserts something is hash */\nexport function ahash(h: CHash): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new Error('Hash must wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n}\n\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'digestInto() output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error('\"digestInto() output\" expected to be of length >=' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte arrays - but not 64-byte. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr: TypedArray): Uint8Array {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr: TypedArray): Uint32Array {\n return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays: TypedArray[]): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr: TypedArray): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/** The rotate left (circular left shift) operation for uint32 */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/** The byte swap operation for uint32 */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n);\n\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr: Uint32Array): Uint32Array {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr;\n}\n\nexport const swap32IfBE: (u: Uint32Array) => Uint32Array = isLE\n ? (u: Uint32Array) => u\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // @ts-ignore\n if (hasHexBuiltin) return Uint8Array.fromHex(hex);\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' + hi);\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * Call of async fn will return Promise, which will be fullfiled only on\n * next scheduler queue processing step and this is exactly what we need.\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/** Returns control to thread each 'tick' ms to avoid blocking. */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * Built-in doesn't validate input to be string: we do the check.\n * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n\n/**\n * Helper for KDFs: consumes uint8array or string.\n * When string is passed, does utf8 decoding, using TextDecoder.\n */\nexport function kdfInputToBytes(data: KDFInput, errorTitle = ''): Uint8Array {\n if (typeof data === 'string') return utf8ToBytes(data);\n return abytes(data, undefined, errorTitle);\n}\n\n/** Copies several Uint8Arrays into one. */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\n/** Merges default options and passed options. */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new Error('options must be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Common interface for all hashes. */\nexport interface Hash<T> {\n blockLen: number; // Bytes per block\n outputLen: number; // Bytes in output\n update(buf: Uint8Array): this;\n digestInto(buf: Uint8Array): void;\n digest(): Uint8Array;\n destroy(): void;\n _cloneInto(to?: T): T;\n clone(): T;\n}\n\n/** PseudoRandom (number) Generator */\nexport interface PRG {\n addEntropy(seed: Uint8Array): void;\n randomBytes(length: number): Uint8Array;\n clean(): void;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\n/** Hash constructor */\nexport type HasherCons<T, Opts = undefined> = Opts extends undefined ? () => T : (opts?: Opts) => T;\n/** Optional hash params. */\nexport type HashInfo = {\n oid?: Uint8Array; // DER encoded OID in bytes\n};\n/** Hash function */\nexport type CHash<T extends Hash<T> = Hash<any>, Opts = undefined> = {\n outputLen: number;\n blockLen: number;\n} & HashInfo &\n (Opts extends undefined\n ? {\n (msg: Uint8Array): Uint8Array;\n create(): T;\n }\n : {\n (msg: Uint8Array, opts?: Opts): Uint8Array;\n create(opts?: Opts): T;\n });\n/** XOF with output */\nexport type CHashXOF<T extends HashXOF<T> = HashXOF<any>, Opts = undefined> = CHash<T, Opts>;\n\n/** Creates function with outputLen, blockLen, create properties from a class constructor. */\nexport function createHasher<T extends Hash<T>, Opts = undefined>(\n hashCons: HasherCons<T, Opts>,\n info: HashInfo = {}\n): CHash<T, Opts> {\n const hashC: any = (msg: Uint8Array, opts?: Opts) => hashCons(opts).update(msg).digest();\n const tmp = hashCons(undefined);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts?: Opts) => hashCons(opts);\n Object.assign(hashC, info);\n return Object.freeze(hashC);\n}\n\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/** Creates OID opts for NIST hashes, with prefix 06 09 60 86 48 01 65 03 04 02. */\nexport const oidNist = (suffix: number): Required<HashInfo> => ({\n oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),\n});\n", "import { baseX } from './base.js'\n\nexport const base10 = baseX({\n prefix: '9',\n name: 'base10',\n alphabet: '0123456789'\n})\n", "export const empty = new Uint8Array(0)\n\nexport function toHex (d: Uint8Array): string {\n return d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '')\n}\n\nexport function fromHex (hex: string): Uint8Array {\n const hexes = hex.match(/../g)\n return hexes != null ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty\n}\n\nexport function equals (aa: Uint8Array, bb: Uint8Array): boolean {\n if (aa === bb) { return true }\n if (aa.byteLength !== bb.byteLength) {\n return false\n }\n\n for (let ii = 0; ii < aa.byteLength; ii++) {\n if (aa[ii] !== bb[ii]) {\n return false\n }\n }\n\n return true\n}\n\nexport function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array {\n if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') { return o }\n if (o instanceof ArrayBuffer) { return new Uint8Array(o) }\n if (ArrayBuffer.isView(o)) {\n return new Uint8Array(o.buffer, o.byteOffset, o.byteLength)\n }\n throw new Error('Unknown type, must be binary type')\n}\n\nexport function isBinary (o: unknown): o is ArrayBuffer | ArrayBufferView {\n return o instanceof ArrayBuffer || ArrayBuffer.isView(o)\n}\n\nexport function fromString (str: string): Uint8Array {\n return new TextEncoder().encode(str)\n}\n\nexport function toString (b: Uint8Array): string {\n return new TextDecoder().decode(b)\n}\n", "/* eslint-disable */\n// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\n/**\n * @param {string} ALPHABET\n * @param {any} name\n */\nfunction base (ALPHABET, name) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n var BASE_MAP = new Uint8Array(256);\n for (var j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255;\n }\n for (var i = 0; i < ALPHABET.length; i++) {\n var x = ALPHABET.charAt(i);\n var xc = x.charCodeAt(0);\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i;\n }\n var BASE = ALPHABET.length;\n var LEADER = ALPHABET.charAt(0);\n var FACTOR = Math.log(BASE) / Math.log(256); // log(BASE) / log(256), rounded up\n var iFACTOR = Math.log(256) / Math.log(BASE); // log(256) / log(BASE), rounded up\n /**\n * @param {any[] | Iterable<number>} source\n */\n function encode (source) {\n // @ts-ignore\n if (source instanceof Uint8Array) ; else if (ArrayBuffer.isView(source)) {\n source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n } else if (Array.isArray(source)) {\n source = Uint8Array.from(source);\n }\n if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n var zeroes = 0;\n var length = 0;\n var pbegin = 0;\n var pend = source.length;\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++;\n zeroes++;\n }\n // Allocate enough space in big-endian base58 representation.\n var size = ((pend - pbegin) * iFACTOR + 1) >>> 0;\n var b58 = new Uint8Array(size);\n // Process the bytes.\n while (pbegin !== pend) {\n var carry = source[pbegin];\n // Apply \"b58 = b58 * 256 + ch\".\n var i = 0;\n for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0;\n b58[it1] = (carry % BASE) >>> 0;\n carry = (carry / BASE) >>> 0;\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i;\n pbegin++;\n }\n // Skip leading zeroes in base58 result.\n var it2 = size - length;\n while (it2 !== size && b58[it2] === 0) {\n it2++;\n }\n // Translate the result into a string.\n var str = LEADER.repeat(zeroes);\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]); }\n return str\n }\n /**\n * @param {string | string[]} source\n */\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return new Uint8Array() }\n var psz = 0;\n // Skip leading spaces.\n if (source[psz] === ' ') { return }\n // Skip and count leading '1's.\n var zeroes = 0;\n var length = 0;\n while (source[psz] === LEADER) {\n zeroes++;\n psz++;\n }\n // Allocate enough space in big-endian base256 representation.\n var size = (((source.length - psz) * FACTOR) + 1) >>> 0; // log(58) / log(256), rounded up.\n var b256 = new Uint8Array(size);\n // Process the characters.\n while (source[psz]) {\n // Decode character\n var carry = BASE_MAP[source.charCodeAt(psz)];\n // Invalid character\n if (carry === 255) { return }\n var i = 0;\n for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0;\n b256[it3] = (carry % 256) >>> 0;\n carry = (carry / 256) >>> 0;\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i;\n psz++;\n }\n // Skip trailing spaces.\n if (source[psz] === ' ') { return }\n // Skip leading zeroes in b256.\n var it4 = size - length;\n while (it4 !== size && b256[it4] === 0) {\n it4++;\n }\n var vch = new Uint8Array(zeroes + (size - it4));\n var j = zeroes;\n while (it4 !== size) {\n vch[j++] = b256[it4++];\n }\n return vch\n }\n /**\n * @param {string | string[]} string\n */\n function decode (string) {\n var buffer = decodeUnsafe(string);\n if (buffer) { return buffer }\n throw new Error(`Non-${name} character`)\n }\n return {\n encode: encode,\n decodeUnsafe: decodeUnsafe,\n decode: decode\n }\n}\nvar src = base;\n\nvar _brrp__multiformats_scope_baseX = src;\n\nexport default _brrp__multiformats_scope_baseX;\n", "import { coerce } from '../bytes.js'\nimport basex from '../vendor/base-x.js'\nimport type { BaseCodec, BaseDecoder, BaseEncoder, CombobaseDecoder, Multibase, MultibaseCodec, MultibaseDecoder, MultibaseEncoder, UnibaseDecoder } from './interface.js'\n\ninterface EncodeFn { (bytes: Uint8Array): string }\ninterface DecodeFn { (text: string): Uint8Array }\n\n/**\n * Class represents both BaseEncoder and MultibaseEncoder meaning it\n * can be used to encode to multibase or base encode without multibase\n * prefix.\n */\nclass Encoder<Base extends string, Prefix extends string> implements MultibaseEncoder<Prefix>, BaseEncoder {\n readonly name: Base\n readonly prefix: Prefix\n readonly baseEncode: EncodeFn\n\n constructor (name: Base, prefix: Prefix, baseEncode: EncodeFn) {\n this.name = name\n this.prefix = prefix\n this.baseEncode = baseEncode\n }\n\n encode (bytes: Uint8Array): Multibase<Prefix> {\n if (bytes instanceof Uint8Array) {\n return `${this.prefix}${this.baseEncode(bytes)}`\n } else {\n throw Error('Unknown type, must be binary type')\n }\n }\n}\n\n/**\n * Class represents both BaseDecoder and MultibaseDecoder so it could be used\n * to decode multibases (with matching prefix) or just base decode strings\n * with corresponding base encoding.\n */\nclass Decoder<Base extends string, Prefix extends string> implements MultibaseDecoder<Prefix>, UnibaseDecoder<Prefix>, BaseDecoder {\n readonly name: Base\n readonly prefix: Prefix\n readonly baseDecode: DecodeFn\n private readonly prefixCodePoint: number\n\n constructor (name: Base, prefix: Prefix, baseDecode: DecodeFn) {\n this.name = name\n this.prefix = prefix\n const prefixCodePoint = prefix.codePointAt(0)\n /* c8 ignore next 3 */\n if (prefixCodePoint === undefined) {\n throw new Error('Invalid prefix character')\n }\n this.prefixCodePoint = prefixCodePoint\n this.baseDecode = baseDecode\n }\n\n decode (text: string): Uint8Array {\n if (typeof text === 'string') {\n if (text.codePointAt(0) !== this.prefixCodePoint) {\n throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`)\n }\n return this.baseDecode(text.slice(this.prefix.length))\n } else {\n throw Error('Can only multibase decode strings')\n }\n }\n\n or<OtherPrefix extends string> (decoder: UnibaseDecoder<OtherPrefix> | ComposedDecoder<OtherPrefix>): ComposedDecoder<Prefix | OtherPrefix> {\n return or(this, decoder)\n }\n}\n\ntype Decoders<Prefix extends string> = Record<Prefix, UnibaseDecoder<Prefix>>\n\nclass ComposedDecoder<Prefix extends string> implements MultibaseDecoder<Prefix>, CombobaseDecoder<Prefix> {\n readonly decoders: Decoders<Prefix>\n\n constructor (decoders: Decoders<Prefix>) {\n this.decoders = decoders\n }\n\n or <OtherPrefix extends string> (decoder: UnibaseDecoder<OtherPrefix> | ComposedDecoder<OtherPrefix>): ComposedDecoder<Prefix | OtherPrefix> {\n return or(this, decoder)\n }\n\n decode (input: string): Uint8Array {\n const prefix = input[0] as Prefix\n const decoder = this.decoders[prefix]\n if (decoder != null) {\n return decoder.decode(input)\n } else {\n throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`)\n }\n }\n}\n\nexport function or <L extends string, R extends string> (left: UnibaseDecoder<L> | CombobaseDecoder<L>, right: UnibaseDecoder<R> | CombobaseDecoder<R>): ComposedDecoder<L | R> {\n return new ComposedDecoder({\n ...(left.decoders ?? { [(left as UnibaseDecoder<L>).prefix]: left }),\n ...(right.decoders ?? { [(right as UnibaseDecoder<R>).prefix]: right })\n } as Decoders<L | R>)\n}\n\nexport class Codec<Base extends string, Prefix extends string> implements MultibaseCodec<Prefix>, MultibaseEncoder<Prefix>, MultibaseDecoder<Prefix>, BaseCodec, BaseEncoder, BaseDecoder {\n readonly name: Base\n readonly prefix: Prefix\n readonly baseEncode: EncodeFn\n readonly baseDecode: DecodeFn\n readonly encoder: Encoder<Base, Prefix>\n readonly decoder: Decoder<Base, Prefix>\n\n constructor (name: Base, prefix: Prefix, baseEncode: EncodeFn, baseDecode: DecodeFn) {\n this.name = name\n this.prefix = prefix\n this.baseEncode = baseEncode\n this.baseDecode = baseDecode\n this.encoder = new Encoder(name, prefix, baseEncode)\n this.decoder = new Decoder(name, prefix, baseDecode)\n }\n\n encode (input: Uint8Array): string {\n return this.encoder.encode(input)\n }\n\n decode (input: string): Uint8Array {\n return this.decoder.decode(input)\n }\n}\n\nexport function from <Base extends string, Prefix extends string> ({ name, prefix, encode, decode }: { name: Base, prefix: Prefix, encode: EncodeFn, decode: DecodeFn }): Codec<Base, Prefix> {\n return new Codec(name, prefix, encode, decode)\n}\n\nexport function baseX <Base extends string, Prefix extends string> ({ name, prefix, alphabet }: { name: Base, prefix: Prefix, alphabet: string }): Codec<Base, Prefix> {\n const { encode, decode } = basex(alphabet, name)\n return from({\n prefix,\n name,\n encode,\n decode: (text: string): Uint8Array => coerce(decode(text))\n })\n}\n\nfunction decode (string: string, alphabetIdx: Record<string, number>, bitsPerChar: number, name: string): Uint8Array {\n // Count the padding bytes:\n let end = string.length\n while (string[end - 1] === '=') {\n --end\n }\n\n // Allocate the output:\n const out = new Uint8Array((end * bitsPerChar / 8) | 0)\n\n // Parse the data:\n let bits = 0 // Number of bits currently in the buffer\n let buffer = 0 // Bits waiting to be written out, MSB first\n let written = 0 // Next byte to write\n for (let i = 0; i < end; ++i) {\n // Read one character from the string:\n const value = alphabetIdx[string[i]]\n if (value === undefined) {\n throw new SyntaxError(`Non-${name} character`)\n }\n\n // Append the bits to the buffer:\n buffer = (buffer << bitsPerChar) | value\n bits += bitsPerChar\n\n // Write out some bits if the buffer has a byte's worth:\n if (bits >= 8) {\n bits -= 8\n out[written++] = 0xff & (buffer >> bits)\n }\n }\n\n // Verify that we have received just enough bits:\n if (bits >= bitsPerChar || (0xff & (buffer << (8 - bits))) !== 0) {\n throw new SyntaxError('Unexpected end of data')\n }\n\n return out\n}\n\nfunction encode (data: Uint8Array, alphabet: string, bitsPerChar: number): string {\n const pad = alphabet[alphabet.length - 1] === '='\n const mask = (1 << bitsPerChar) - 1\n let out = ''\n\n let bits = 0 // Number of bits currently in the buffer\n let buffer = 0 // Bits waiting to be written out, MSB first\n for (let i = 0; i < data.length; ++i) {\n // Slurp data into the buffer:\n buffer = (buffer << 8) | data[i]\n bits += 8\n\n // Write out as much as we can:\n while (bits > bitsPerChar) {\n bits -= bitsPerChar\n out += alphabet[mask & (buffer >> bits)]\n }\n }\n\n // Partial character:\n if (bits !== 0) {\n out += alphabet[mask & (buffer << (bitsPerChar - bits))]\n }\n\n // Add padding characters until we hit a byte boundary:\n if (pad) {\n while (((out.length * bitsPerChar) & 7) !== 0) {\n out += '='\n }\n }\n\n return out\n}\n\nfunction createAlphabetIdx (alphabet: string): Record<string, number> {\n // Build the character lookup table:\n const alphabetIdx: Record<string, number> = {}\n for (let i = 0; i < alphabet.length; ++i) {\n alphabetIdx[alphabet[i]] = i\n }\n return alphabetIdx\n}\n\n/**\n * RFC4648 Factory\n */\nexport function rfc4648 <Base extends string, Prefix extends string> ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec<Base, Prefix> {\n const alphabetIdx = createAlphabetIdx(alphabet)\n return from({\n prefix,\n name,\n encode (input: Uint8Array): string {\n return encode(input, alphabet, bitsPerChar)\n },\n decode (input: string): Uint8Array {\n return decode(input, alphabetIdx, bitsPerChar, name)\n }\n })\n}\n", "import { rfc4648 } from './base.js'\n\nexport const base16 = rfc4648({\n prefix: 'f',\n name: 'base16',\n alphabet: '0123456789abcdef',\n bitsPerChar: 4\n})\n\nexport const base16upper = rfc4648({\n prefix: 'F',\n name: 'base16upper',\n alphabet: '0123456789ABCDEF',\n bitsPerChar: 4\n})\n", "import { rfc4648 } from './base.js'\n\nexport const base2 = rfc4648({\n prefix: '0',\n name: 'base2',\n alphabet: '01',\n bitsPerChar: 1\n})\n", "import { from } from './base.js'\n\nconst alphabet = Array.from('\uD83D\uDE80\uD83E\uDE90\u2604\uD83D\uDEF0\uD83C\uDF0C\uD83C\uDF11\uD83C\uDF12\uD83C\uDF13\uD83C\uDF14\uD83C\uDF15\uD83C\uDF16\uD83C\uDF17\uD83C\uDF18\uD83C\uDF0D\uD83C\uDF0F\uD83C\uDF0E\uD83D\uDC09\u2600\uD83D\uDCBB\uD83D\uDDA5\uD83D\uDCBE\uD83D\uDCBF\uD83D\uDE02\u2764\uD83D\uDE0D\uD83E\uDD23\uD83D\uDE0A\uD83D\uDE4F\uD83D\uDC95\uD83D\uDE2D\uD83D\uDE18\uD83D\uDC4D\uD83D\uDE05\uD83D\uDC4F\uD83D\uDE01\uD83D\uDD25\uD83E\uDD70\uD83D\uDC94\uD83D\uDC96\uD83D\uDC99\uD83D\uDE22\uD83E\uDD14\uD83D\uDE06\uD83D\uDE44\uD83D\uDCAA\uD83D\uDE09\u263A\uD83D\uDC4C\uD83E\uDD17\uD83D\uDC9C\uD83D\uDE14\uD83D\uDE0E\uD83D\uDE07\uD83C\uDF39\uD83E\uDD26\uD83C\uDF89\uD83D\uDC9E\u270C\u2728\uD83E\uDD37\uD83D\uDE31\uD83D\uDE0C\uD83C\uDF38\uD83D\uDE4C\uD83D\uDE0B\uD83D\uDC97\uD83D\uDC9A\uD83D\uDE0F\uD83D\uDC9B\uD83D\uDE42\uD83D\uDC93\uD83E\uDD29\uD83D\uDE04\uD83D\uDE00\uD83D\uDDA4\uD83D\uDE03\uD83D\uDCAF\uD83D\uDE48\uD83D\uDC47\uD83C\uDFB6\uD83D\uDE12\uD83E\uDD2D\u2763\uD83D\uDE1C\uD83D\uDC8B\uD83D\uDC40\uD83D\uDE2A\uD83D\uDE11\uD83D\uDCA5\uD83D\uDE4B\uD83D\uDE1E\uD83D\uDE29\uD83D\uDE21\uD83E\uDD2A\uD83D\uDC4A\uD83E\uDD73\uD83D\uDE25\uD83E\uDD24\uD83D\uDC49\uD83D\uDC83\uD83D\uDE33\u270B\uD83D\uDE1A\uD83D\uDE1D\uD83D\uDE34\uD83C\uDF1F\uD83D\uDE2C\uD83D\uDE43\uD83C\uDF40\uD83C\uDF37\uD83D\uDE3B\uD83D\uDE13\u2B50\u2705\uD83E\uDD7A\uD83C\uDF08\uD83D\uDE08\uD83E\uDD18\uD83D\uDCA6\u2714\uD83D\uDE23\uD83C\uDFC3\uD83D\uDC90\u2639\uD83C\uDF8A\uD83D\uDC98\uD83D\uDE20\u261D\uD83D\uDE15\uD83C\uDF3A\uD83C\uDF82\uD83C\uDF3B\uD83D\uDE10\uD83D\uDD95\uD83D\uDC9D\uD83D\uDE4A\uD83D\uDE39\uD83D\uDDE3\uD83D\uDCAB\uD83D\uDC80\uD83D\uDC51\uD83C\uDFB5\uD83E\uDD1E\uD83D\uDE1B\uD83D\uDD34\uD83D\uDE24\uD83C\uDF3C\uD83D\uDE2B\u26BD\uD83E\uDD19\u2615\uD83C\uDFC6\uD83E\uDD2B\uD83D\uDC48\uD83D\uDE2E\uD83D\uDE46\uD83C\uDF7B\uD83C\uDF43\uD83D\uDC36\uD83D\uDC81\uD83D\uDE32\uD83C\uDF3F\uD83E\uDDE1\uD83C\uDF81\u26A1\uD83C\uDF1E\uD83C\uDF88\u274C\u270A\uD83D\uDC4B\uD83D\uDE30\uD83E\uDD28\uD83D\uDE36\uD83E\uDD1D\uD83D\uDEB6\uD83D\uDCB0\uD83C\uDF53\uD83D\uDCA2\uD83E\uDD1F\uD83D\uDE41\uD83D\uDEA8\uD83D\uDCA8\uD83E\uDD2C\u2708\uD83C\uDF80\uD83C\uDF7A\uD83E\uDD13\uD83D\uDE19\uD83D\uDC9F\uD83C\uDF31\uD83D\uDE16\uD83D\uDC76\uD83E\uDD74\u25B6\u27A1\u2753\uD83D\uDC8E\uD83D\uDCB8\u2B07\uD83D\uDE28\uD83C\uDF1A\uD83E\uDD8B\uD83D\uDE37\uD83D\uDD7A\u26A0\uD83D\uDE45\uD83D\uDE1F\uD83D\uDE35\uD83D\uDC4E\uD83E\uDD32\uD83E\uDD20\uD83E\uDD27\uD83D\uDCCC\uD83D\uDD35\uD83D\uDC85\uD83E\uDDD0\uD83D\uDC3E\uD83C\uDF52\uD83D\uDE17\uD83E\uDD11\uD83C\uDF0A\uD83E\uDD2F\uD83D\uDC37\u260E\uD83D\uDCA7\uD83D\uDE2F\uD83D\uDC86\uD83D\uDC46\uD83C\uDFA4\uD83D\uDE47\uD83C\uDF51\u2744\uD83C\uDF34\uD83D\uDCA3\uD83D\uDC38\uD83D\uDC8C\uD83D\uDCCD\uD83E\uDD40\uD83E\uDD22\uD83D\uDC45\uD83D\uDCA1\uD83D\uDCA9\uD83D\uDC50\uD83D\uDCF8\uD83D\uDC7B\uD83E\uDD10\uD83E\uDD2E\uD83C\uDFBC\uD83E\uDD75\uD83D\uDEA9\uD83C\uDF4E\uD83C\uDF4A\uD83D\uDC7C\uD83D\uDC8D\uD83D\uDCE3\uD83E\uDD42')\nconst alphabetBytesToChars: string[] = (alphabet.reduce<string[]>((p, c, i) => { p[i] = c; return p }, ([])))\nconst alphabetCharsToBytes: number[] = (alphabet.reduce<number[]>((p, c, i) => {\n const codePoint = c.codePointAt(0)\n if (codePoint == null) {\n throw new Error(`Invalid character: ${c}`)\n }\n p[codePoint] = i\n return p\n}, ([])))\n\nfunction encode (data: Uint8Array): string {\n return data.reduce((p, c) => {\n p += alphabetBytesToChars[c]\n return p\n }, '')\n}\n\nfunction decode (str: string): Uint8Array {\n const byts = []\n for (const char of str) {\n const codePoint = char.codePointAt(0)\n if (codePoint == null) {\n throw new Error(`Invalid character: ${char}`)\n }\n const byt = alphabetCharsToBytes[codePoint]\n if (byt == null) {\n throw new Error(`Non-base256emoji character: ${char}`)\n }\n byts.push(byt)\n }\n return new Uint8Array(byts)\n}\n\nexport const base256emoji = from({\n prefix: '\uD83D\uDE80',\n name: 'base256emoji',\n encode,\n decode\n})\n", "import { rfc4648 } from './base.js'\n\nexport const base32 = rfc4648({\n prefix: 'b',\n name: 'base32',\n alphabet: 'abcdefghijklmnopqrstuvwxyz234567',\n bitsPerChar: 5\n})\n\nexport const base32upper = rfc4648({\n prefix: 'B',\n name: 'base32upper',\n alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',\n bitsPerChar: 5\n})\n\nexport const base32pad = rfc4648({\n prefix: 'c',\n name: 'base32pad',\n alphabet: 'abcdefghijklmnopqrstuvwxyz234567=',\n bitsPerChar: 5\n})\n\nexport const base32padupper = rfc4648({\n prefix: 'C',\n name: 'base32padupper',\n alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=',\n bitsPerChar: 5\n})\n\nexport const base32hex = rfc4648({\n prefix: 'v',\n name: 'base32hex',\n alphabet: '0123456789abcdefghijklmnopqrstuv',\n bitsPerChar: 5\n})\n\nexport const base32hexupper = rfc4648({\n prefix: 'V',\n name: 'base32hexupper',\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV',\n bitsPerChar: 5\n})\n\nexport const base32hexpad = rfc4648({\n prefix: 't',\n name: 'base32hexpad',\n alphabet: '0123456789abcdefghijklmnopqrstuv=',\n bitsPerChar: 5\n})\n\nexport const base32hexpadupper = rfc4648({\n prefix: 'T',\n name: 'base32hexpadupper',\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV=',\n bitsPerChar: 5\n})\n\nexport const base32z = rfc4648({\n prefix: 'h',\n name: 'base32z',\n alphabet: 'ybndrfg8ejkmcpqxot1uwisza345h769',\n bitsPerChar: 5\n})\n", "import { baseX } from './base.js'\n\nexport const base36 = baseX({\n prefix: 'k',\n name: 'base36',\n alphabet: '0123456789abcdefghijklmnopqrstuvwxyz'\n})\n\nexport const base36upper = baseX({\n prefix: 'K',\n name: 'base36upper',\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n})\n", "import { baseX } from './base.js'\n\nexport const base58btc = baseX({\n name: 'base58btc',\n prefix: 'z',\n alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\n})\n\nexport const base58flickr = baseX({\n name: 'base58flickr',\n prefix: 'Z',\n alphabet: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'\n})\n", "import { rfc4648 } from './base.js'\n\nexport const base64 = rfc4648({\n prefix: 'm',\n name: 'base64',\n alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n bitsPerChar: 6\n})\n\nexport const base64pad = rfc4648({\n prefix: 'M',\n name: 'base64pad',\n alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',\n bitsPerChar: 6\n})\n\nexport const base64url = rfc4648({\n prefix: 'u',\n name: 'base64url',\n alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',\n bitsPerChar: 6\n})\n\nexport const base64urlpad = rfc4648({\n prefix: 'U',\n name: 'base64urlpad',\n alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=',\n bitsPerChar: 6\n})\n", "import { rfc4648 } from './base.js'\n\nexport const base8 = rfc4648({\n prefix: '7',\n name: 'base8',\n alphabet: '01234567',\n bitsPerChar: 3\n})\n", "import { fromString, toString } from '../bytes.js'\nimport { from } from './base.js'\n\nexport const identity = from({\n prefix: '\\x00',\n name: 'identity',\n encode: (buf) => toString(buf),\n decode: (str) => fromString(str)\n})\n", "import type { ArrayBufferView, ByteView } from './interface.js'\n\nconst textEncoder = new TextEncoder()\nconst textDecoder = new TextDecoder()\n\nexport const name = 'json'\nexport const code = 0x0200\n\nexport function encode <T> (node: T): ByteView<T> {\n return textEncoder.encode(JSON.stringify(node))\n}\n\nexport function decode <T> (data: ByteView<T> | ArrayBufferView<T>): T {\n return JSON.parse(textDecoder.decode(data))\n}\n", "import { coerce } from '../bytes.js'\nimport * as Digest from './digest.js'\nimport type { DigestOptions } from './hasher.js'\n\nconst code: 0x0 = 0x0\nconst name = 'identity'\n\nconst encode: (input: Uint8Array) => Uint8Array = coerce\n\nfunction digest (input: Uint8Array, options?: DigestOptions): Digest.Digest<typeof code, number> {\n if (options?.truncate != null && options.truncate !== input.byteLength) {\n if (options.truncate < 0 || options.truncate > input.byteLength) {\n throw new Error(`Invalid truncate option, must be less than or equal to ${input.byteLength}`)\n }\n\n input = input.subarray(0, options.truncate)\n }\n\n return Digest.create(code, encode(input))\n}\n\nexport const identity = { code, name, encode, digest }\n", "/* eslint-disable */\nvar encode_1 = encode;\n\nvar MSB = 0x80\n , REST = 0x7F\n , MSBALL = ~REST\n , INT = Math.pow(2, 31);\n\n/**\n * @param {number} num\n * @param {number[]} out\n * @param {number} offset\n */\nfunction encode(num, out, offset) {\n out = out || [];\n offset = offset || 0;\n var oldOffset = offset;\n\n while(num >= INT) {\n out[offset++] = (num & 0xFF) | MSB;\n num /= 128;\n }\n while(num & MSBALL) {\n out[offset++] = (num & 0xFF) | MSB;\n num >>>= 7;\n }\n out[offset] = num | 0;\n \n // @ts-ignore\n encode.bytes = offset - oldOffset + 1;\n \n return out\n}\n\nvar decode = read;\n\nvar MSB$1 = 0x80\n , REST$1 = 0x7F;\n\n/**\n * @param {string | any[]} buf\n * @param {number} offset\n */\nfunction read(buf, offset) {\n var res = 0\n , offset = offset || 0\n , shift = 0\n , counter = offset\n , b\n , l = buf.length;\n\n do {\n if (counter >= l) {\n // @ts-ignore\n read.bytes = 0;\n throw new RangeError('Could not decode varint')\n }\n b = buf[counter++];\n res += shift < 28\n ? (b & REST$1) << shift\n : (b & REST$1) * Math.pow(2, shift);\n shift += 7;\n } while (b >= MSB$1)\n\n // @ts-ignore\n read.bytes = counter - offset;\n\n return res\n}\n\nvar N1 = Math.pow(2, 7);\nvar N2 = Math.pow(2, 14);\nvar N3 = Math.pow(2, 21);\nvar N4 = Math.pow(2, 28);\nvar N5 = Math.pow(2, 35);\nvar N6 = Math.pow(2, 42);\nvar N7 = Math.pow(2, 49);\nvar N8 = Math.pow(2, 56);\nvar N9 = Math.pow(2, 63);\n\nvar length = function (/** @type {number} */ value) {\n return (\n value < N1 ? 1\n : value < N2 ? 2\n : value < N3 ? 3\n : value < N4 ? 4\n : value < N5 ? 5\n : value < N6 ? 6\n : value < N7 ? 7\n : value < N8 ? 8\n : value < N9 ? 9\n : 10\n )\n};\n\nvar varint = {\n encode: encode_1\n , decode: decode\n , encodingLength: length\n};\n\nvar _brrp_varint = varint;\n\nexport default _brrp_varint;\n", "import varint from './vendor/varint.js'\n\nexport function decode (data: Uint8Array, offset = 0): [number, number] {\n const code = varint.decode(data, offset)\n return [code, varint.decode.bytes]\n}\n\nexport function encodeTo (int: number, target: Uint8Array, offset = 0): Uint8Array {\n varint.encode(int, target, offset)\n return target\n}\n\nexport function encodingLength (int: number): number {\n return varint.encodingLength(int)\n}\n", "import { coerce, equals as equalBytes } from '../bytes.js'\nimport * as varint from '../varint.js'\nimport type { MultihashDigest } from './interface.js'\n\n/**\n * Creates a multihash digest.\n */\nexport function create <Code extends number> (code: Code, digest: Uint8Array): Digest<Code, number> {\n const size = digest.byteLength\n const sizeOffset = varint.encodingLength(code)\n const digestOffset = sizeOffset + varint.encodingLength(size)\n\n const bytes = new Uint8Array(digestOffset + size)\n varint.encodeTo(code, bytes, 0)\n varint.encodeTo(size, bytes, sizeOffset)\n bytes.set(digest, digestOffset)\n\n return new Digest(code, size, digest, bytes)\n}\n\n/**\n * Turns bytes representation of multihash digest into an instance.\n */\nexport function decode (multihash: Uint8Array): MultihashDigest {\n const bytes = coerce(multihash)\n const [code, sizeOffset] = varint.decode(bytes)\n const [size, digestOffset] = varint.decode(bytes.subarray(sizeOffset))\n const digest = bytes.subarray(sizeOffset + digestOffset)\n\n if (digest.byteLength !== size) {\n throw new Error('Incorrect length')\n }\n\n return new Digest(code, size, digest, bytes)\n}\n\nexport function equals (a: MultihashDigest, b: unknown): b is MultihashDigest {\n if (a === b) {\n return true\n } else {\n const data = b as { code?: unknown, size?: unknown, bytes?: unknown }\n\n return (\n a.code === data.code &&\n a.size === data.size &&\n data.bytes instanceof Uint8Array &&\n equalBytes(a.bytes, data.bytes)\n )\n }\n}\n\n/**\n * Represents a multihash digest which carries information about the\n * hashing algorithm and an actual hash digest.\n */\nexport class Digest<Code extends number, Size extends number> implements MultihashDigest {\n readonly code: Code\n readonly size: Size\n readonly digest: Uint8Array\n readonly bytes: Uint8Array\n\n /**\n * Creates a multihash digest.\n */\n constructor (code: Code, size: Size, digest: Uint8Array, bytes: Uint8Array) {\n this.code = code\n this.size = size\n this.digest = digest\n this.bytes = bytes\n }\n}\n\n/**\n * Used to check that the passed multihash has the passed code\n */\nexport function hasCode <T extends number> (digest: MultihashDigest, code: T): digest is MultihashDigest<T> {\n return digest.code === code\n}\n", "/* global crypto */\n\nimport { from } from './hasher.js'\n\nfunction sha (name: AlgorithmIdentifier): (data: Uint8Array) => Promise<Uint8Array> {\n return async data => new Uint8Array(await crypto.subtle.digest(name, data))\n}\n\nexport const sha256 = from({\n name: 'sha2-256',\n code: 0x12,\n encode: sha('SHA-256')\n})\n\nexport const sha512 = from({\n name: 'sha2-512',\n code: 0x13,\n encode: sha('SHA-512')\n})\n", "import * as Digest from './digest.js'\nimport type { MultihashHasher } from './interface.js'\n\ntype Await<T> = Promise<T> | T\n\nconst DEFAULT_MIN_DIGEST_LENGTH = 20\n\nexport interface HasherInit <Name extends string, Code extends number> {\n name: Name\n code: Code\n encode(input: Uint8Array): Await<Uint8Array>\n\n /**\n * The minimum length a hash is allowed to be truncated to in bytes\n *\n * @default 20\n */\n minDigestLength?: number\n\n /**\n * The maximum length a hash is allowed to be truncated to in bytes. If not\n * specified it will be inferred from the length of the digest.\n */\n maxDigestLength?: number\n}\n\nexport function from <Name extends string, Code extends number> ({ name, code, encode, minDigestLength, maxDigestLength }: HasherInit<Name, Code>): Hasher<Name, Code> {\n return new Hasher(name, code, encode, minDigestLength, maxDigestLength)\n}\n\nexport interface DigestOptions {\n /**\n * Truncate the returned digest to this number of bytes.\n *\n * This may cause the digest method to throw/reject if the passed value is\n * greater than the digest length or below a threshold under which the risk of\n * hash collisions is significant.\n *\n * The actual value of this threshold can depend on the hashing algorithm in\n * use.\n */\n truncate?: number\n}\n\n/**\n * Hasher represents a hashing algorithm implementation that produces as\n * `MultihashDigest`.\n */\nexport class Hasher<Name extends string, Code extends number> implements MultihashHasher<Code> {\n readonly name: Name\n readonly code: Code\n readonly encode: (input: Uint8Array) => Await<Uint8Array>\n readonly minDigestLength: number\n readonly maxDigestLength?: number\n\n constructor (name: Name, code: Code, encode: (input: Uint8Array) => Await<Uint8Array>, minDigestLength?: number, maxDigestLength?: number) {\n this.name = name\n this.code = code\n this.encode = encode\n this.minDigestLength = minDigestLength ?? DEFAULT_MIN_DIGEST_LENGTH\n this.maxDigestLength = maxDigestLength\n }\n\n digest (input: Uint8Array, options?: DigestOptions): Await<Digest.Digest<Code, number>> {\n if (options?.truncate != null) {\n if (options.truncate < this.minDigestLength) {\n throw new Error(`Invalid truncate option, must be greater than or equal to ${this.minDigestLength}`)\n }\n\n if (this.maxDigestLength != null && options.truncate > this.maxDigestLength) {\n throw new Error(`Invalid truncate option, must be less than or equal to ${this.maxDigestLength}`)\n }\n }\n\n if (input instanceof Uint8Array) {\n const result = this.encode(input)\n\n if (result instanceof Uint8Array) {\n return createDigest(result, this.code, options?.truncate)\n }\n\n return result.then(digest => createDigest(digest, this.code, options?.truncate))\n } else {\n throw Error('Unknown type, must be binary type')\n /* c8 ignore next 1 */\n }\n }\n}\n\n/**\n * Create a Digest from the passed uint8array and code, optionally truncating it\n * first.\n */\nfunction createDigest <Code extends number> (digest: Uint8Array, code: Code, truncate?: number): Digest.Digest<Code, number> {\n if (truncate != null && truncate !== digest.byteLength) {\n if (truncate > digest.byteLength) {\n throw new Error(`Invalid truncate option, must be less than or equal to ${digest.byteLength}`)\n }\n\n digest = digest.subarray(0, truncate)\n }\n\n return Digest.create(code, digest)\n}\n", "import { base32 } from './bases/base32.js'\nimport { base36 } from './bases/base36.js'\nimport { base58btc } from './bases/base58.js'\nimport { coerce } from './bytes.js'\nimport * as Digest from './hashes/digest.js'\nimport * as varint from './varint.js'\nimport type * as API from './link/interface.js'\n\n// This way TS will also expose all the types from module\nexport * from './link/interface.js'\n\nexport function format <T extends API.Link<unknown, number, number, API.Version>, Prefix extends string> (link: T, base?: API.MultibaseEncoder<Prefix>): API.ToString<T, Prefix> {\n const { bytes, version } = link\n switch (version) {\n case 0:\n return toStringV0(\n bytes,\n baseCache(link),\n base as API.MultibaseEncoder<'z'> ?? base58btc.encoder\n )\n default:\n return toStringV1(\n bytes,\n baseCache(link),\n (base ?? base32.encoder) as API.MultibaseEncoder<Prefix>\n )\n }\n}\n\nexport function toJSON <Link extends API.UnknownLink> (link: Link): API.LinkJSON<Link> {\n return {\n '/': format(link)\n }\n}\n\nexport function fromJSON <Link extends API.UnknownLink> (json: API.LinkJSON<Link>): CID<unknown, number, number, API.Version> {\n return CID.parse(json['/'])\n}\n\nconst cache = new WeakMap<API.UnknownLink, Map<string, string>>()\n\nfunction baseCache (cid: API.UnknownLink): Map<string, string> {\n const baseCache = cache.get(cid)\n if (baseCache == null) {\n const baseCache = new Map()\n cache.set(cid, baseCache)\n return baseCache\n }\n return baseCache\n}\n\nexport class CID<Data = unknown, Format extends number = number, Alg extends number = number, Version extends API.Version = API.Version> implements API.Link<Data, Format, Alg, Version> {\n readonly code: Format\n readonly version: Version\n readonly multihash: API.MultihashDigest<Alg>\n readonly bytes: Uint8Array\n readonly '/': Uint8Array\n\n /**\n * @param version - Version of the CID\n * @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv\n * @param multihash - (Multi)hash of the of the content.\n */\n constructor (version: Version, code: Format, multihash: API.MultihashDigest<Alg>, bytes: Uint8Array) {\n this.code = code\n this.version = version\n this.multihash = multihash\n this.bytes = bytes\n\n // flag to serializers that this is a CID and\n // should be treated specially\n this['/'] = bytes\n }\n\n /**\n * Signalling `cid.asCID === cid` has been replaced with `cid['/'] === cid.bytes`\n * please either use `CID.asCID(cid)` or switch to new signalling mechanism\n *\n * @deprecated\n */\n get asCID (): this {\n return this\n }\n\n // ArrayBufferView\n get byteOffset (): number {\n return this.bytes.byteOffset\n }\n\n // ArrayBufferView\n get byteLength (): number {\n return this.bytes.byteLength\n }\n\n toV0 (): CID<Data, API.DAG_PB, API.SHA_256, 0> {\n switch (this.version) {\n case 0: {\n return this as CID<Data, API.DAG_PB, API.SHA_256, 0>\n }\n case 1: {\n const { code, multihash } = this\n\n if (code !== DAG_PB_CODE) {\n throw new Error('Cannot convert a non dag-pb CID to CIDv0')\n }\n\n // sha2-256\n if (multihash.code !== SHA_256_CODE) {\n throw new Error('Cannot convert non sha2-256 multihash CID to CIDv0')\n }\n\n return (\n CID.createV0(\n multihash as API.MultihashDigest<API.SHA_256>\n )\n )\n }\n default: {\n throw Error(\n `Can not convert CID version ${this.version} to version 0. This is a bug please report`\n )\n }\n }\n }\n\n toV1 (): CID<Data, Format, Alg, 1> {\n switch (this.version) {\n case 0: {\n const { code, digest } = this.multihash\n const multihash = Digest.create(code, digest)\n return (\n CID.createV1(this.code, multihash)\n )\n }\n case 1: {\n return this as CID<Data, Format, Alg, 1>\n }\n default: {\n throw Error(\n `Can not convert CID version ${this.version} to version 1. This is a bug please report`\n )\n }\n }\n }\n\n equals (other: unknown): other is CID<Data, Format, Alg, Version> {\n return CID.equals(this, other)\n }\n\n static equals <Data, Format extends number, Alg extends number, Version extends API.Version>(self: API.Link<Data, Format, Alg, Version>, other: unknown): other is CID {\n const unknown = other as { code?: unknown, version?: unknown, multihash?: unknown }\n return (\n unknown != null &&\n self.code === unknown.code &&\n self.version === unknown.version &&\n Digest.equals(self.multihash, unknown.multihash)\n )\n }\n\n toString (base?: API.MultibaseEncoder<string>): string {\n return format(this, base)\n }\n\n toJSON (): API.LinkJSON<this> {\n return { '/': format(this) }\n }\n\n link (): this {\n return this\n }\n\n readonly [Symbol.toStringTag] = 'CID';\n\n // Legacy\n\n [Symbol.for('nodejs.util.inspect.custom')] (): string {\n return `CID(${this.toString()})`\n }\n\n /**\n * Takes any input `value` and returns a `CID` instance if it was\n * a `CID` otherwise returns `null`. If `value` is instanceof `CID`\n * it will return value back. If `value` is not instance of this CID\n * class, but is compatible CID it will return new instance of this\n * `CID` class. Otherwise returns null.\n *\n * This allows two different incompatible versions of CID library to\n * co-exist and interop as long as binary interface is compatible.\n */\n static asCID <Data, Format extends number, Alg extends number, Version extends API.Version, U>(input: API.Link<Data, Format, Alg, Version> | U): CID<Data, Format, Alg, Version> | null {\n if (input == null) {\n return null\n }\n\n const value = input as any\n if (value instanceof CID) {\n // If value is instance of CID then we're all set.\n return value\n } else if ((value['/'] != null && value['/'] === value.bytes) || value.asCID === value) {\n // If value isn't instance of this CID class but `this.asCID === this` or\n // `value['/'] === value.bytes` is true it is CID instance coming from a\n // different implementation (diff version or duplicate). In that case we\n // rebase it to this `CID` implementation so caller is guaranteed to get\n // instance with expected API.\n const { version, code, multihash, bytes } = value\n return new CID(\n version,\n code,\n multihash as API.MultihashDigest<Alg>,\n bytes ?? encodeCID(version, code, multihash.bytes)\n )\n } else if (value[cidSymbol] === true) {\n // If value is a CID from older implementation that used to be tagged via\n // symbol we still rebase it to the this `CID` implementation by\n // delegating that to a constructor.\n const { version, multihash, code } = value\n const digest = Digest.decode(multihash) as API.MultihashDigest<Alg>\n return CID.create(version, code, digest)\n } else {\n // Otherwise value is not a CID (or an incompatible version of it) in\n // which case we return `null`.\n return null\n }\n }\n\n /**\n * @param version - Version of the CID\n * @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv\n * @param digest - (Multi)hash of the of the content.\n */\n static create <Data, Format extends number, Alg extends number, Version extends API.Version>(version: Version, code: Format, digest: API.MultihashDigest<Alg>): CID<Data, Format, Alg, Version> {\n if (typeof code !== 'number') {\n throw new Error('String codecs are no longer supported')\n }\n\n if (!(digest.bytes instanceof Uint8Array)) {\n throw new Error('Invalid digest')\n }\n\n switch (version) {\n case 0: {\n if (code !== DAG_PB_CODE) {\n throw new Error(\n `Version 0 CID must use dag-pb (code: ${DAG_PB_CODE}) block encoding`\n )\n } else {\n return new CID(version, code, digest, digest.bytes)\n }\n }\n case 1: {\n const bytes = encodeCID(version, code, digest.bytes)\n return new CID(version, code, digest, bytes)\n }\n default: {\n throw new Error('Invalid version')\n }\n }\n }\n\n /**\n * Simplified version of `create` for CIDv0.\n */\n static createV0 <T = unknown>(digest: API.MultihashDigest<typeof SHA_256_CODE>): CID<T, typeof DAG_PB_CODE, typeof SHA_256_CODE, 0> {\n return CID.create(0, DAG_PB_CODE, digest)\n }\n\n /**\n * Simplified version of `create` for CIDv1.\n *\n * @param code - Content encoding format code.\n * @param digest - Multihash of the content.\n */\n static createV1 <Data, Code extends number, Alg extends number>(code: Code, digest: API.MultihashDigest<Alg>): CID<Data, Code, Alg, 1> {\n return CID.create(1, code, digest)\n }\n\n /**\n * Decoded a CID from its binary representation. The byte array must contain\n * only the CID with no additional bytes.\n *\n * An error will be thrown if the bytes provided do not contain a valid\n * binary representation of a CID.\n */\n static decode <Data, Code extends number, Alg extends number, Version extends API.Version>(bytes: API.ByteView<API.Link<Data, Code, Alg, Version>>): CID<Data, Code, Alg, Version> {\n const [cid, remainder] = CID.decodeFirst(bytes)\n if (remainder.length !== 0) {\n throw new Error('Incorrect length')\n }\n return cid\n }\n\n /**\n * Decoded a CID from its binary representation at the beginning of a byte\n * array.\n *\n * Returns an array with the first element containing the CID and the second\n * element containing the remainder of the original byte array. The remainder\n * will be a zero-length byte array if the provided bytes only contained a\n * binary CID representation.\n */\n static decodeFirst <T, C extends number, A extends number, V extends API.Version>(bytes: API.ByteView<API.Link<T, C, A, V>>): [CID<T, C, A, V>, Uint8Array] {\n const specs = CID.inspectBytes(bytes)\n const prefixSize = specs.size - specs.multihashSize\n const multihashBytes = coerce(\n bytes.subarray(prefixSize, prefixSize + specs.multihashSize)\n )\n if (multihashBytes.byteLength !== specs.multihashSize) {\n throw new Error('Incorrect length')\n }\n const digestBytes = multihashBytes.subarray(\n specs.multihashSize - specs.digestSize\n )\n const digest = new Digest.Digest(\n specs.multihashCode,\n specs.digestSize,\n digestBytes,\n multihashBytes\n )\n const cid =\n specs.version === 0\n ? CID.createV0(digest as API.MultihashDigest<API.SHA_256>)\n : CID.createV1(specs.codec, digest)\n return [cid as CID<T, C, A, V>, bytes.subarray(specs.size)]\n }\n\n /**\n * Inspect the initial bytes of a CID to determine its properties.\n *\n * Involves decoding up to 4 varints. Typically this will require only 4 to 6\n * bytes but for larger multicodec code values and larger multihash digest\n * lengths these varints can be quite large. It is recommended that at least\n * 10 bytes be made available in the `initialBytes` argument for a complete\n * inspection.\n */\n static inspectBytes <T, C extends number, A extends number, V extends API.Version>(initialBytes: API.ByteView<API.Link<T, C, A, V>>): { version: V, codec: C, multihashCode: A, digestSize: number, multihashSize: number, size: number } {\n let offset = 0\n const next = (): number => {\n const [i, length] = varint.decode(initialBytes.subarray(offset))\n offset += length\n return i\n }\n\n let version = next() as V\n let codec = DAG_PB_CODE as C\n if (version as number === 18) {\n // CIDv0\n version = 0 as V\n offset = 0\n } else {\n codec = next() as C\n }\n\n if (version !== 0 && version !== 1) {\n throw new RangeError(`Invalid CID version ${version}`)\n }\n\n const prefixSize = offset\n const multihashCode = next() as A // multihash code\n const digestSize = next() // multihash length\n const size = offset + digestSize\n const multihashSize = size - prefixSize\n\n return { version, codec, multihashCode, digestSize, multihashSize, size }\n }\n\n /**\n * Takes cid in a string representation and creates an instance. If `base`\n * decoder is not provided will use a default from the configuration. It will\n * throw an error if encoding of the CID is not compatible with supplied (or\n * a default decoder).\n */\n static parse <Prefix extends string, Data, Code extends number, Alg extends number, Version extends API.Version>(source: API.ToString<API.Link<Data, Code, Alg, Version>, Prefix>, base?: API.MultibaseDecoder<Prefix>): CID<Data, Code, Alg, Version> {\n const [prefix, bytes] = parseCIDtoBytes(source, base)\n\n const cid = CID.decode(bytes)\n\n if (cid.version === 0 && source[0] !== 'Q') {\n throw Error('Version 0 CID string must not include multibase prefix')\n }\n\n // Cache string representation to avoid computing it on `this.toString()`\n baseCache(cid).set(prefix, source)\n\n return cid\n }\n}\n\nfunction parseCIDtoBytes <Prefix extends string, Data, Code extends number, Alg extends number, Version extends API.Version> (source: API.ToString<API.Link<Data, Code, Alg, Version>, Prefix>, base?: API.MultibaseDecoder<Prefix>): [Prefix, API.ByteView<API.Link<Data, Code, Alg, Version>>] {\n switch (source[0]) {\n // CIDv0 is parsed differently\n case 'Q': {\n const decoder = base ?? base58btc\n return [\n base58btc.prefix as Prefix,\n decoder.decode(`${base58btc.prefix}${source}`)\n ]\n }\n case base58btc.prefix: {\n const decoder = base ?? base58btc\n return [base58btc.prefix as Prefix, decoder.decode(source)]\n }\n case base32.prefix: {\n const decoder = base ?? base32\n return [base32.prefix as Prefix, decoder.decode(source)]\n }\n case base36.prefix: {\n const decoder = base ?? base36\n return [base36.prefix as Prefix, decoder.decode(source)]\n }\n default: {\n if (base == null) {\n throw Error(\n 'To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided'\n )\n }\n return [source[0] as Prefix, base.decode(source)]\n }\n }\n}\n\nfunction toStringV0 (bytes: Uint8Array, cache: Map<string, string>, base: API.MultibaseEncoder<'z'>): string {\n const { prefix } = base\n if (prefix !== base58btc.prefix) {\n throw Error(`Cannot string encode V0 in ${base.name} encoding`)\n }\n\n const cid = cache.get(prefix)\n if (cid == null) {\n const cid = base.encode(bytes).slice(1)\n cache.set(prefix, cid)\n return cid\n } else {\n return cid\n }\n}\n\nfunction toStringV1 <Prefix extends string> (bytes: Uint8Array, cache: Map<string, string>, base: API.MultibaseEncoder<Prefix>): string {\n const { prefix } = base\n const cid = cache.get(prefix)\n if (cid == null) {\n const cid = base.encode(bytes)\n cache.set(prefix, cid)\n return cid\n } else {\n return cid\n }\n}\n\nconst DAG_PB_CODE = 0x70\nconst SHA_256_CODE = 0x12\n\nfunction encodeCID (version: API.Version, code: number, multihash: Uint8Array): Uint8Array {\n const codeOffset = varint.encodingLength(version)\n const hashOffset = codeOffset + varint.encodingLength(code)\n const bytes = new Uint8Array(hashOffset + multihash.byteLength)\n varint.encodeTo(version, bytes, 0)\n varint.encodeTo(code, bytes, codeOffset)\n bytes.set(multihash, hashOffset)\n return bytes\n}\n\nconst cidSymbol = Symbol.for('@ipld/js-cid/CID')\n", "import * as base10 from './bases/base10.js'\nimport * as base16 from './bases/base16.js'\nimport * as base2 from './bases/base2.js'\nimport * as base256emoji from './bases/base256emoji.js'\nimport * as base32 from './bases/base32.js'\nimport * as base36 from './bases/base36.js'\nimport * as base58 from './bases/base58.js'\nimport * as base64 from './bases/base64.js'\nimport * as base8 from './bases/base8.js'\nimport * as identityBase from './bases/identity.js'\nimport * as json from './codecs/json.js'\nimport * as raw from './codecs/raw.js'\nimport * as identity from './hashes/identity.js'\nimport * as sha2 from './hashes/sha2.js'\nimport { CID, hasher, digest, varint, bytes } from './index.js'\n\nexport const bases = { ...identityBase, ...base2, ...base8, ...base10, ...base16, ...base32, ...base36, ...base58, ...base64, ...base256emoji }\nexport const hashes = { ...sha2, ...identity }\nexport const codecs = { raw, json }\n\nexport { CID, hasher, digest, varint, bytes }\n", "/**\n * Returns a `Uint8Array` of the requested size. Referenced memory will\n * be initialized to 0.\n */\nexport function alloc (size: number = 0): Uint8Array {\n return new Uint8Array(size)\n}\n\n/**\n * Where possible returns a Uint8Array of the requested size that references\n * uninitialized memory. Only use if you are certain you will immediately\n * overwrite every value in the returned `Uint8Array`.\n */\nexport function allocUnsafe (size: number = 0): Uint8Array {\n return new Uint8Array(size)\n}\n", "import { bases } from 'multiformats/basics'\nimport type { MultibaseCodec } from 'multiformats'\nimport { allocUnsafe } from '#alloc'\n\nfunction createCodec (name: string, prefix: string, encode: (buf: Uint8Array) => string, decode: (str: string) => Uint8Array): MultibaseCodec<any> {\n return {\n name,\n prefix,\n encoder: {\n name,\n prefix,\n encode\n },\n decoder: {\n decode\n }\n }\n}\n\nconst string = createCodec('utf8', 'u', (buf) => {\n const decoder = new TextDecoder('utf8')\n return 'u' + decoder.decode(buf)\n}, (str) => {\n const encoder = new TextEncoder()\n return encoder.encode(str.substring(1))\n})\n\nconst ascii = createCodec('ascii', 'a', (buf) => {\n let string = 'a'\n\n for (let i = 0; i < buf.length; i++) {\n string += String.fromCharCode(buf[i])\n }\n return string\n}, (str) => {\n str = str.substring(1)\n const buf = allocUnsafe(str.length)\n\n for (let i = 0; i < str.length; i++) {\n buf[i] = str.charCodeAt(i)\n }\n\n return buf\n})\n\nexport type SupportedEncodings = 'utf8' | 'utf-8' | 'hex' | 'latin1' | 'ascii' | 'binary' | keyof typeof bases\n\nconst BASES: Record<SupportedEncodings, MultibaseCodec<any>> = {\n utf8: string,\n 'utf-8': string,\n hex: bases.base16,\n latin1: ascii,\n ascii,\n binary: ascii,\n\n ...bases\n}\n\nexport default BASES\n", "import bases, { type SupportedEncodings } from './util/bases.js'\n\nexport type { SupportedEncodings }\n\n/**\n * Turns a `Uint8Array` into a string.\n *\n * Supports `utf8`, `utf-8` and any encoding supported by the multibase module.\n *\n * Also `ascii` which is similar to node's 'binary' encoding.\n */\nexport function toString (array: Uint8Array, encoding: SupportedEncodings = 'utf8'): string {\n const base = bases[encoding]\n\n if (base == null) {\n throw new Error(`Unsupported encoding \"${encoding}\"`)\n }\n\n // strip multibase prefix\n return base.encoder.encode(array).substring(1)\n}\n", "/** Lightweight implementation of a mutex lock queue. */\r\nexport class Latches {\r\n // Stores the promise representing the completion of the last queued operation for a key.\r\n private static lockQueues = new Map<string, Promise<void>>();\r\n\r\n /**\r\n * Acquires a lock for the given key. Waits if another operation holds the lock.\r\n * Returns a release function that must be called to release the lock.\r\n\t\t * WARNING: The key scope is global to the entire process, so follow the convention of using `ClassName.methodName:${id}` to avoid conflicts.\r\n */\r\n static async acquire(key: string): Promise<() => void> {\r\n // Get the promise the current operation needs to wait for (if any)\r\n const currentTail = this.lockQueues.get(key) ?? Promise.resolve();\r\n\r\n let resolveNewTail: () => void;\r\n // Create the promise that the *next* operation will wait for\r\n const newTail = new Promise<void>(resolve => {\r\n resolveNewTail = resolve;\r\n });\r\n\r\n // Immediately set the new promise as the tail for this key\r\n this.lockQueues.set(key, newTail);\r\n\r\n // Wait for the previous operation (if any) to complete\r\n await currentTail;\r\n\r\n // Lock acquired. Return the function to release *this* lock.\r\n const release = () => {\r\n // Signal that this operation is complete, allowing the next awaiter (if any)\r\n resolveNewTail();\r\n\r\n // Optimization: If this promise is still the current tail in the map,\r\n // it means no other operation queued up behind this one while it was running.\r\n // We can safely remove the entry from the map to prevent unbounded growth.\r\n if (this.lockQueues.get(key) === newTail) {\r\n this.lockQueues.delete(key);\r\n }\r\n };\r\n\r\n return release;\r\n }\r\n}\r\n", "import type { IBlock, Action, ActionType, ActionHandler, BlockId, ITransactor, BlockStore } from \"../index.js\";\r\nimport { Log, Atomic, Tracker, copyTransforms, CacheSource, isTransformsEmpty, TransactorSource } from \"../index.js\";\r\nimport type { CollectionHeaderBlock, CollectionId, ICollection } from \"./index.js\";\r\nimport { randomBytes } from '@noble/hashes/utils.js';\r\nimport { toString as uint8ArrayToString } from 'uint8arrays/to-string';\r\nimport { Latches } from \"../utility/latches.js\";\r\n\r\nconst PendingRetryDelayMs = 100;\r\n\r\nexport type CollectionInitOptions<TAction> = {\r\n\tmodules: Record<ActionType, ActionHandler<TAction>>;\r\n\tcreateHeaderBlock: (id: BlockId, store: BlockStore<IBlock>) => IBlock;\r\n\t/** Called for each local action that is potentially in conflict with a remote action.\r\n\t * @param action - The local action to check\r\n\t * @param potential - The remote action that is potentially in conflict\r\n\t * @returns The original action, a replacement action (return a new instance; will be\r\n\t * \tapplied through act()), or undefined to discard this action\r\n\t */\r\n\tfilterConflict?: (action: Action<TAction>, potential: Action<TAction>[]) => Action<TAction> | undefined\r\n}\r\n\r\nexport class Collection<TAction> implements ICollection<TAction> {\r\n\tprivate pending: Action<TAction>[] = [];\r\n\tprivate readonly latchId: string;\r\n\r\n\tprotected constructor(\r\n\t\tpublic readonly id: CollectionId,\r\n\t\tpublic readonly transactor: ITransactor,\r\n\t\tprivate readonly handlers: Record<ActionType, ActionHandler<TAction>>,\r\n\t\tprivate readonly source: TransactorSource<IBlock>,\r\n\t\t/** Cache of unmodified blocks from the source */\r\n\t\tprivate readonly sourceCache: CacheSource<IBlock>,\r\n\t\t/** Tracked Changes */\r\n\t\tpublic readonly tracker: Tracker<IBlock>,\r\n\t\tprivate readonly filterConflict?: (action: Action<TAction>, potential: Action<TAction>[]) => Action<TAction> | undefined,\r\n\t) {\r\n\t\tthis.latchId = `Collection:${this.id}`;\r\n\t}\r\n\r\n\tstatic async createOrOpen<TAction>(transactor: ITransactor, id: CollectionId, init: CollectionInitOptions<TAction>) {\r\n\t\t// Start with a context that has an infinite revision number to ensure that we always fetch the latest log information\r\n\t\tconst source = new TransactorSource(id, transactor, undefined);\r\n\t\tconst sourceCache = new CacheSource(source);\r\n\t\tconst tracker = new Tracker(sourceCache);\r\n\t\tconst header = await source.tryGet(id) as CollectionHeaderBlock | undefined;\r\n\r\n\t\tif (header) {\t// Collection already exists\r\n\t\t\tconst log = (await Log.open<Action<TAction>>(tracker, id))!;\r\n\t\t\tsource.actionContext = await log.getActionContext();\r\n\t\t} else {\t// Collection does not exist\r\n\t\t\tconst headerBlock = init.createHeaderBlock(id, tracker);\r\n\t\t\ttracker.insert(headerBlock);\r\n\t\t\tsource.actionContext = undefined;\r\n\t\t\tawait Log.open<Action<TAction>>(tracker, id);\r\n\t\t}\r\n\r\n\t\treturn new Collection(id, transactor, init.modules, source, sourceCache, tracker, init.filterConflict);\r\n\t}\r\n\r\n\tasync act(...actions: Action<TAction>[]) {\r\n\t\tconst release = await Latches.acquire(this.latchId);\r\n\t\ttry {\r\n\t\t\tawait this.actInternal(...actions);\r\n\t\t} finally {\r\n\t\t\trelease();\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async actInternal(...actions: Action<TAction>[]) {\r\n\t\tawait this.internalTransact(...actions);\r\n\t\tthis.pending.push(...actions);\r\n\t}\r\n\r\n\tprivate async internalTransact(...actions: Action<TAction>[]) {\r\n\t\tconst atomic = new Atomic(this.tracker);\r\n\r\n\t\tfor (const action of actions) {\r\n\t\t\tconst handler = this.handlers[action.type];\r\n\t\t\tif (!handler) {\r\n\t\t\t\tthrow new Error(`No handler for action type ${action.type}`);\r\n\t\t\t}\r\n\t\t\tawait handler(action, atomic);\r\n\t\t}\r\n\r\n\t\tatomic.commit();\r\n\t}\r\n\r\n\t/** Load external changes and update our context to the latest log revision - resolve any conflicts with our pending actions. */\r\n\tasync update() {\r\n\t\tconst release = await Latches.acquire(this.latchId);\r\n\t\ttry {\r\n\t\t\tawait this.updateInternal();\r\n\t\t} finally {\r\n\t\t\trelease();\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async updateInternal() {\r\n\t\t// Start with a context that can see to the end of the log\r\n\t\tconst source = new TransactorSource(this.id, this.transactor, undefined);\r\n\t\tconst tracker = new Tracker(source);\r\n\r\n\t\t// Get the latest entries from the log, starting from where we left off\r\n\t\tconst actionContext = this.source.actionContext;\r\n\t\tconst log = await Log.open<Action<TAction>>(tracker, this.id);\r\n\t\tconst latest = log ? await log.getFrom(actionContext?.rev ?? 0) : undefined;\r\n\r\n\t\t// Process the entries and track the blocks they affect\r\n\t\tlet anyConflicts = false;\r\n\t\tfor (const entry of latest?.entries ?? []) {\r\n\t\t\t// Filter any pending actions that conflict with the remote actions\r\n\t\t\tthis.pending = this.pending.map(p => this.doFilterConflict(p, entry.actions) ? p : undefined)\r\n\t\t\t\t.filter(Boolean) as Action<TAction>[];\r\n\t\t\tthis.sourceCache.clear(entry.blockIds);\r\n\t\t\tanyConflicts = anyConflicts || this.tracker.conflicts(new Set(entry.blockIds)).length > 0;\r\n\t\t}\r\n\r\n\t\t// On conflicts, clear related caching and block-tracking and replay logical operations\r\n\t\tif (anyConflicts) {\r\n\t\t\tawait this.replayActions();\r\n\t\t}\r\n\r\n\t\t// Update our context to the latest\r\n\t\tthis.source.actionContext = latest?.context;\r\n\t}\r\n\r\n\t/** Push our pending actions to the transactor */\r\n\tasync sync() {\r\n\t\tconst release = await Latches.acquire(this.latchId);\r\n\t\ttry {\r\n\t\t\tawait this.syncInternal();\r\n\t\t} finally {\r\n\t\t\trelease();\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async syncInternal() {\r\n\t\tconst bytes = randomBytes(16);\r\n\t\tconst actionId = uint8ArrayToString(bytes, 'base64url');\r\n\r\n\t\twhile (this.pending.length || !isTransformsEmpty(this.tracker.transforms)) {\r\n\t\t\t// Snapshot the pending actions so that any new actions aren't assumed to be part of this action\r\n\t\t\tconst pending = [...this.pending];\r\n\r\n\t\t\t// Create a snapshot tracker for the action, so that we can ditch the log changes if we have to retry the action\r\n\t\t\tconst snapshot = copyTransforms(this.tracker.transforms);\r\n\t\t\tconst tracker = new Tracker(this.sourceCache, snapshot);\r\n\r\n\t\t\t// Add the action to the log (in local tracking space)\r\n\t\t\tconst log = await Log.open<Action<TAction>>(tracker, this.id);\r\n\t\t\tif (!log) {\r\n\t\t\t\tthrow new Error(`Log not found for collection ${this.id}`);\r\n\t\t\t}\r\n\t\t\tconst newRev = (this.source.actionContext?.rev ?? 0) + 1;\r\n\t\t\tconst addResult = await log.addActions(pending, actionId, newRev, () => tracker.transformedBlockIds());\r\n\r\n\t\t\t// Commit the action to the transactor\r\n\t\t\tconst staleFailure = await this.source.transact(tracker.transforms, actionId, newRev, this.id, addResult.tailPath.block.header.id);\r\n\t\t\tif (staleFailure) {\r\n\t\t\t\tif (staleFailure.pending) {\r\n\t\t\t\t\t// Wait for short time to allow the pending actions to commit (bounded backoff)\r\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, PendingRetryDelayMs));\r\n\t\t\t\t}\r\n\t\t\t\t// Fetch latest state - updateInternal() will call replayActions() if there are conflicts\r\n\t\t\t\tawait this.updateInternal();\r\n\t\t\t} else {\r\n\t\t\t\t// Clear the pending actions that were part of this action\r\n\t\t\t\tthis.pending = this.pending.slice(pending.length);\r\n\t\t\t\t// Reset cache and replay any actions that were added during the action\r\n\t\t\t\tconst transforms = tracker.reset();\r\n\t\t\t\tawait this.replayActions();\r\n\t\t\t\tthis.sourceCache.transformCache(transforms);\r\n\t\t\t\tthis.source.actionContext = this.source.actionContext\r\n\t\t\t\t\t? { committed: [...this.source.actionContext.committed, { actionId, rev: newRev }], rev: newRev }\r\n\t\t\t\t\t: { committed: [{ actionId, rev: newRev }], rev: newRev };\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tasync updateAndSync() {\r\n\t\tconst release = await Latches.acquire(this.latchId);\r\n\t\ttry {\r\n\t\t\tawait this.updateInternal();\r\n\t\t\tawait this.syncInternal();\r\n\t\t} finally {\r\n\t\t\trelease();\r\n\t\t}\r\n\t}\r\n\r\n\tasync *selectLog(forward = true): AsyncIterableIterator<Action<TAction>> {\r\n\t\tconst log = await Log.open<Action<TAction>>(this.tracker, this.id);\r\n\t\tif (!log) {\r\n\t\t\tthrow new Error(`Log not found for collection ${this.id}`);\r\n\t\t}\r\n\t\tfor await (const entry of log.select(undefined, forward)) {\r\n\t\t\tif (entry.action) {\r\n\t\t\t\tyield* forward ? entry.action.actions : entry.action.actions.reverse();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate async replayActions() {\r\n\t\tthis.tracker.reset();\r\n\t\t// Replay pending actions against the fresh tracker state (always called under latch)\r\n\t\tfor (const action of this.pending) {\r\n\t\t\tawait this.internalTransact(action);\r\n\t\t}\r\n\t}\r\n\r\n\t/** Called for each local action that may be in conflict with a remote action (always called under latch).\r\n\t * @param action - The local action to check\r\n\t * @param potential - The remote action that is potentially in conflict\r\n\t * @returns true if the action should be kept, false to discard it\r\n\t */\r\n\tprotected doFilterConflict(action: Action<TAction>, potential: Action<TAction>[]) {\r\n\t\tif (this.filterConflict) {\r\n\t\t\tconst replacement = this.filterConflict(action, potential);\r\n\t\t\tif (!replacement) {\r\n\t\t\t\treturn false;\r\n\t\t\t} else if (replacement !== action) {\r\n\t\t\t\t// Queue replacement - it will be applied in replayActions()\r\n\t\t\t\tthis.pending.push(replacement);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n}\r\n", "import { Collection } from \"../../index.js\";\r\nimport type { ITransactor, Action, BlockId, BlockStore, IBlock, CollectionInitOptions, CollectionId } from \"../../index.js\";\r\nimport { DiaryHeaderBlockType } from \"./index.js\";\r\n\r\nexport class Diary<TEntry> {\r\n private constructor(\r\n\t\t\tprivate readonly collection: Collection<TEntry>\r\n\t\t) {\r\n }\r\n\r\n static async create<TEntry>(network: ITransactor, id: CollectionId): Promise<Diary<TEntry>> {\r\n const init: CollectionInitOptions<TEntry> = {\r\n modules: {\r\n\t\t\t\t\t\t\t\"append\": async (action, trx) => {\r\n\t\t\t\t\t\t\t\t// Append-only diary doesn't need to modify any blocks\r\n\t\t\t\t\t\t\t\t// All entries are stored in the log\r\n\t\t\t\t\t\t\t}\r\n },\r\n createHeaderBlock: (id: BlockId, store: BlockStore<IBlock>) => ({\r\n header: store.createBlockHeader(DiaryHeaderBlockType, id)\r\n })\r\n };\r\n\r\n const collection = await Collection.createOrOpen(network, id, init);\r\n return new Diary<TEntry>(collection);\r\n }\r\n\r\n async append(data: TEntry): Promise<void> {\r\n const action: Action<TEntry> = {\r\n type: \"append\",\r\n data: data\r\n };\r\n\r\n await this.collection.act(action);\r\n await this.collection.updateAndSync();\r\n }\r\n\r\n /** Fetch the latest state from the network */\r\n async update(): Promise<void> {\r\n await this.collection.update();\r\n }\r\n\r\n async *select(forward = true): AsyncIterableIterator<TEntry> {\r\n for await (const entry of this.collection.selectLog(forward)) {\r\n yield entry.data;\r\n }\r\n }\r\n}\r\n", "import { registerBlockType } from \"../../index.js\";\r\n\r\nexport const DiaryHeaderBlockType = registerBlockType(\"DIH\", \"DiaryHeaderBlock\");\r\n", "import { type BlockId, type CollectionHeaderBlock, registerBlockType } from \"../../index.js\";\r\nimport { nameof } from \"../../utility/nameof.js\";\r\n\r\nexport const TreeHeaderBlockType = registerBlockType(\"TRE\", \"TreeHeaderBlock\");\r\n\r\nexport type TreeCollectionHeaderBlock = CollectionHeaderBlock & {\r\n\trootId: BlockId;\r\n};\r\n\r\nexport const rootId$ = nameof<TreeCollectionHeaderBlock>(\"rootId\");\r\n\r\n/** Represents a unit of change to a tree collection. */\r\nexport type TreeReplaceAction<TKey, TEntry> = [\r\n\t// The key to replace\r\n\tkey: TKey,\r\n\t// The new entry to replace the old entry with (if not provided, the key is deleted)\r\n\tentry?: TEntry,\r\n][];\r\n\r\n", "import { apply, get } from \"../../index.js\";\r\nimport type { BlockId, BlockStore, IBlock, ITreeTrunk } from \"../../index.js\";\r\nimport type { ITreeNode } from \"../../btree/nodes.js\";\r\nimport { rootId$, type TreeCollectionHeaderBlock } from \"./struct.js\";\r\n\r\nexport class CollectionTrunk implements ITreeTrunk {\r\n constructor(\r\n private readonly store: BlockStore<IBlock>,\r\n private readonly collectionId: BlockId,\r\n ) {}\r\n\r\n async get(): Promise<ITreeNode> {\r\n return await get(this.store, await this.getId());\r\n }\r\n\r\n async set(node: ITreeNode): Promise<void> {\r\n\t\t\t\tconst header = await get(this.store, this.collectionId) as TreeCollectionHeaderBlock;\r\n\t\t\t\tapply(this.store, header, [rootId$, 0, 1, node.header.id]);\r\n }\r\n\r\n async getId(): Promise<BlockId> {\r\n\t\t\t\tconst header = await get(this.store, this.collectionId) as TreeCollectionHeaderBlock;\r\n return header.rootId;\r\n }\r\n}\r\n", "import { Collection, type CollectionInitOptions, type CollectionId } from \"../../collection/index.js\";\r\nimport type { ITransactor, BlockId, BlockStore, IBlock } from \"../../index.js\";\r\nimport { BTree, type Path, type KeyRange } from \"../../btree/index.js\";\r\nimport { CollectionTrunk } from \"./collection-trunk.js\";\r\nimport { TreeHeaderBlockType, type TreeReplaceAction } from \"./struct.js\";\r\n\r\nexport class Tree<TKey, TEntry> {\r\n\r\n\tprivate constructor(\r\n\t\tprivate readonly collection: Collection<TreeReplaceAction<TKey, TEntry>>,\r\n\t\tprivate readonly btree: BTree<TKey, TEntry>,\r\n\t) {\r\n\t}\r\n\r\n\tstatic async createOrOpen<TKey, TEntry>(\r\n\t\tnetwork: ITransactor,\r\n\t\tid: CollectionId,\r\n\t\tkeyFromEntry = (entry: TEntry) => entry as unknown as TKey,\r\n\t\tcompare = (a: TKey, b: TKey) => a < b ? -1 : a > b ? 1 : 0,\r\n\t): Promise<Tree<TKey, TEntry>> {\r\n\t\t// Tricky bootstrapping here:\r\n\t\t// We need the root id to initialize the collection header, so we create the btree in the create collection header callback.\r\n\t\tlet btree: BTree<TKey, TEntry> | undefined;\r\n\t\tconst init: CollectionInitOptions<TreeReplaceAction<TKey, TEntry>> = {\r\n\t\t\tmodules: {\r\n\t\t\t\t\"replace\": async ({ data: actions }, trx) => {\r\n\t\t\t\t\tfor (const [key, entry] of actions) {\r\n\t\t\t\t\t\tif (entry) {\r\n\t\t\t\t\t\t\tawait btree!.upsert(entry);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tawait btree!.deleteAt((await btree!.find(key)));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tcreateHeaderBlock: (id: BlockId, store: BlockStore<IBlock>) => {\t// Only called if the collection does not exist\r\n\t\t\t\tlet rootId: BlockId;\r\n\t\t\t\tbtree = BTree.create<TKey, TEntry>(store, (s, r) => {\r\n\t\t\t\t\t\trootId = r;\r\n\t\t\t\t\t\treturn new CollectionTrunk(store, id);\r\n\t\t\t\t\t}, keyFromEntry, compare);\r\n\t\t\t\treturn {\r\n\t\t\t\t\theader: store.createBlockHeader(TreeHeaderBlockType, id),\r\n\t\t\t\t\trootId: rootId!,\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tconst collection = await Collection.createOrOpen<TreeReplaceAction<TKey, TEntry>>(network, id, init);\r\n\t\tbtree = btree ?? new BTree<TKey, TEntry>(collection.tracker, new CollectionTrunk(collection.tracker, collection.id), keyFromEntry, compare);\r\n\t\treturn new Tree<TKey, TEntry>(collection, btree);\r\n\t}\r\n\r\n\tasync replace(data: TreeReplaceAction<TKey, TEntry>): Promise<void> {\r\n\t\t\tawait this.collection.act({ type: \"replace\", data });\r\n\t\t\tawait this.collection.updateAndSync();\r\n\t}\r\n\r\n\t/**\r\n\t * Update the local state from the network.\r\n\t * Call this before reading to ensure you have the latest data.\r\n\t */\r\n\tasync update(): Promise<void> {\r\n\t\tawait this.collection.update();\r\n\t}\r\n\r\n\t// Read actions\r\n\r\n\tasync first(): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.btree.first();\r\n\t}\r\n\r\n\tasync last(): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.btree.last();\r\n\t}\r\n\r\n\tasync find(key: TKey): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.btree.find(key);\r\n\t}\r\n\r\n\tasync get(key: TKey): Promise<TEntry | undefined> {\r\n\t\treturn await this.btree.get(key);\r\n\t}\r\n\r\n\tat(path: Path<TKey, TEntry>): TEntry | undefined {\r\n\t\treturn this.btree.at(path);\r\n\t}\r\n\r\n\trange(range: KeyRange<TKey>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\treturn this.btree.range(range);\r\n\t}\r\n\r\n\tascending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\treturn this.btree.ascending(path);\r\n\t}\r\n\r\n\tdescending(path: Path<TKey, TEntry>): AsyncIterableIterator<Path<TKey, TEntry>> {\r\n\t\treturn this.btree.descending(path);\r\n\t}\r\n\r\n\tasync getCount(from?: { path: Path<TKey, TEntry>, ascending?: boolean }): Promise<number> {\r\n\t\treturn await this.btree.getCount(from);\r\n\t}\r\n\r\n\tasync next(path: Path<TKey, TEntry>): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.btree.next(path);\r\n\t}\r\n\r\n\tasync moveNext(path: Path<TKey, TEntry>): Promise<void> {\r\n\t\tawait this.btree.moveNext(path);\r\n\t}\r\n\r\n\tasync prior(path: Path<TKey, TEntry>): Promise<Path<TKey, TEntry>> {\r\n\t\treturn await this.btree.prior(path);\r\n\t}\r\n\r\n\tasync movePrior(path: Path<TKey, TEntry>): Promise<void> {\r\n\t\tawait this.btree.movePrior(path);\r\n\t}\r\n\r\n\tisValid(path: Path<TKey, TEntry>): boolean {\r\n\t\treturn this.btree.isValid(path);\r\n\t}\r\n}\r\n", "export const empty = new Uint8Array(0)\n\nexport function toHex (d: Uint8Array): string {\n return d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '')\n}\n\nexport function fromHex (hex: string): Uint8Array {\n const hexes = hex.match(/../g)\n return hexes != null ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty\n}\n\nexport function equals (aa: Uint8Array, bb: Uint8Array): boolean {\n if (aa === bb) { return true }\n if (aa.byteLength !== bb.byteLength) {\n return false\n }\n\n for (let ii = 0; ii < aa.byteLength; ii++) {\n if (aa[ii] !== bb[ii]) {\n return false\n }\n }\n\n return true\n}\n\nexport function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array {\n if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') { return o }\n if (o instanceof ArrayBuffer) { return new Uint8Array(o) }\n if (ArrayBuffer.isView(o)) {\n return new Uint8Array(o.buffer, o.byteOffset, o.byteLength)\n }\n throw new Error('Unknown type, must be binary type')\n}\n\nexport function isBinary (o: unknown): o is ArrayBuffer | ArrayBufferView {\n return o instanceof ArrayBuffer || ArrayBuffer.isView(o)\n}\n\nexport function fromString (str: string): Uint8Array {\n return new TextEncoder().encode(str)\n}\n\nexport function toString (b: Uint8Array): string {\n return new TextDecoder().decode(b)\n}\n", "/* eslint-disable */\nvar encode_1 = encode;\n\nvar MSB = 0x80\n , REST = 0x7F\n , MSBALL = ~REST\n , INT = Math.pow(2, 31);\n\n/**\n * @param {number} num\n * @param {number[]} out\n * @param {number} offset\n */\nfunction encode(num, out, offset) {\n out = out || [];\n offset = offset || 0;\n var oldOffset = offset;\n\n while(num >= INT) {\n out[offset++] = (num & 0xFF) | MSB;\n num /= 128;\n }\n while(num & MSBALL) {\n out[offset++] = (num & 0xFF) | MSB;\n num >>>= 7;\n }\n out[offset] = num | 0;\n \n // @ts-ignore\n encode.bytes = offset - oldOffset + 1;\n \n return out\n}\n\nvar decode = read;\n\nvar MSB$1 = 0x80\n , REST$1 = 0x7F;\n\n/**\n * @param {string | any[]} buf\n * @param {number} offset\n */\nfunction read(buf, offset) {\n var res = 0\n , offset = offset || 0\n , shift = 0\n , counter = offset\n , b\n , l = buf.length;\n\n do {\n if (counter >= l) {\n // @ts-ignore\n read.bytes = 0;\n throw new RangeError('Could not decode varint')\n }\n b = buf[counter++];\n res += shift < 28\n ? (b & REST$1) << shift\n : (b & REST$1) * Math.pow(2, shift);\n shift += 7;\n } while (b >= MSB$1)\n\n // @ts-ignore\n read.bytes = counter - offset;\n\n return res\n}\n\nvar N1 = Math.pow(2, 7);\nvar N2 = Math.pow(2, 14);\nvar N3 = Math.pow(2, 21);\nvar N4 = Math.pow(2, 28);\nvar N5 = Math.pow(2, 35);\nvar N6 = Math.pow(2, 42);\nvar N7 = Math.pow(2, 49);\nvar N8 = Math.pow(2, 56);\nvar N9 = Math.pow(2, 63);\n\nvar length = function (/** @type {number} */ value) {\n return (\n value < N1 ? 1\n : value < N2 ? 2\n : value < N3 ? 3\n : value < N4 ? 4\n : value < N5 ? 5\n : value < N6 ? 6\n : value < N7 ? 7\n : value < N8 ? 8\n : value < N9 ? 9\n : 10\n )\n};\n\nvar varint = {\n encode: encode_1\n , decode: decode\n , encodingLength: length\n};\n\nvar _brrp_varint = varint;\n\nexport default _brrp_varint;\n", "import varint from './vendor/varint.js'\n\nexport function decode (data: Uint8Array, offset = 0): [number, number] {\n const code = varint.decode(data, offset)\n return [code, varint.decode.bytes]\n}\n\nexport function encodeTo (int: number, target: Uint8Array, offset = 0): Uint8Array {\n varint.encode(int, target, offset)\n return target\n}\n\nexport function encodingLength (int: number): number {\n return varint.encodingLength(int)\n}\n", "import { coerce, equals as equalBytes } from '../bytes.js'\nimport * as varint from '../varint.js'\nimport type { MultihashDigest } from './interface.js'\n\n/**\n * Creates a multihash digest.\n */\nexport function create <Code extends number> (code: Code, digest: Uint8Array): Digest<Code, number> {\n const size = digest.byteLength\n const sizeOffset = varint.encodingLength(code)\n const digestOffset = sizeOffset + varint.encodingLength(size)\n\n const bytes = new Uint8Array(digestOffset + size)\n varint.encodeTo(code, bytes, 0)\n varint.encodeTo(size, bytes, sizeOffset)\n bytes.set(digest, digestOffset)\n\n return new Digest(code, size, digest, bytes)\n}\n\n/**\n * Turns bytes representation of multihash digest into an instance.\n */\nexport function decode (multihash: Uint8Array): MultihashDigest {\n const bytes = coerce(multihash)\n const [code, sizeOffset] = varint.decode(bytes)\n const [size, digestOffset] = varint.decode(bytes.subarray(sizeOffset))\n const digest = bytes.subarray(sizeOffset + digestOffset)\n\n if (digest.byteLength !== size) {\n throw new Error('Incorrect length')\n }\n\n return new Digest(code, size, digest, bytes)\n}\n\nexport function equals (a: MultihashDigest, b: unknown): b is MultihashDigest {\n if (a === b) {\n return true\n } else {\n const data = b as { code?: unknown, size?: unknown, bytes?: unknown }\n\n return (\n a.code === data.code &&\n a.size === data.size &&\n data.bytes instanceof Uint8Array &&\n equalBytes(a.bytes, data.bytes)\n )\n }\n}\n\n/**\n * Represents a multihash digest which carries information about the\n * hashing algorithm and an actual hash digest.\n */\nexport class Digest<Code extends number, Size extends number> implements MultihashDigest {\n readonly code: Code\n readonly size: Size\n readonly digest: Uint8Array\n readonly bytes: Uint8Array\n\n /**\n * Creates a multihash digest.\n */\n constructor (code: Code, size: Size, digest: Uint8Array, bytes: Uint8Array) {\n this.code = code\n this.size = size\n this.digest = digest\n this.bytes = bytes\n }\n}\n\n/**\n * Used to check that the passed multihash has the passed code\n */\nexport function hasCode <T extends number> (digest: MultihashDigest, code: T): digest is MultihashDigest<T> {\n return digest.code === code\n}\n", "import * as Digest from './digest.js'\nimport type { MultihashHasher } from './interface.js'\n\ntype Await<T> = Promise<T> | T\n\nconst DEFAULT_MIN_DIGEST_LENGTH = 20\n\nexport interface HasherInit <Name extends string, Code extends number> {\n name: Name\n code: Code\n encode(input: Uint8Array): Await<Uint8Array>\n\n /**\n * The minimum length a hash is allowed to be truncated to in bytes\n *\n * @default 20\n */\n minDigestLength?: number\n\n /**\n * The maximum length a hash is allowed to be truncated to in bytes. If not\n * specified it will be inferred from the length of the digest.\n */\n maxDigestLength?: number\n}\n\nexport function from <Name extends string, Code extends number> ({ name, code, encode, minDigestLength, maxDigestLength }: HasherInit<Name, Code>): Hasher<Name, Code> {\n return new Hasher(name, code, encode, minDigestLength, maxDigestLength)\n}\n\nexport interface DigestOptions {\n /**\n * Truncate the returned digest to this number of bytes.\n *\n * This may cause the digest method to throw/reject if the passed value is\n * greater than the digest length or below a threshold under which the risk of\n * hash collisions is significant.\n *\n * The actual value of this threshold can depend on the hashing algorithm in\n * use.\n */\n truncate?: number\n}\n\n/**\n * Hasher represents a hashing algorithm implementation that produces as\n * `MultihashDigest`.\n */\nexport class Hasher<Name extends string, Code extends number> implements MultihashHasher<Code> {\n readonly name: Name\n readonly code: Code\n readonly encode: (input: Uint8Array) => Await<Uint8Array>\n readonly minDigestLength: number\n readonly maxDigestLength?: number\n\n constructor (name: Name, code: Code, encode: (input: Uint8Array) => Await<Uint8Array>, minDigestLength?: number, maxDigestLength?: number) {\n this.name = name\n this.code = code\n this.encode = encode\n this.minDigestLength = minDigestLength ?? DEFAULT_MIN_DIGEST_LENGTH\n this.maxDigestLength = maxDigestLength\n }\n\n digest (input: Uint8Array, options?: DigestOptions): Await<Digest.Digest<Code, number>> {\n if (options?.truncate != null) {\n if (options.truncate < this.minDigestLength) {\n throw new Error(`Invalid truncate option, must be greater than or equal to ${this.minDigestLength}`)\n }\n\n if (this.maxDigestLength != null && options.truncate > this.maxDigestLength) {\n throw new Error(`Invalid truncate option, must be less than or equal to ${this.maxDigestLength}`)\n }\n }\n\n if (input instanceof Uint8Array) {\n const result = this.encode(input)\n\n if (result instanceof Uint8Array) {\n return createDigest(result, this.code, options?.truncate)\n }\n\n return result.then(digest => createDigest(digest, this.code, options?.truncate))\n } else {\n throw Error('Unknown type, must be binary type')\n /* c8 ignore next 1 */\n }\n }\n}\n\n/**\n * Create a Digest from the passed uint8array and code, optionally truncating it\n * first.\n */\nfunction createDigest <Code extends number> (digest: Uint8Array, code: Code, truncate?: number): Digest.Digest<Code, number> {\n if (truncate != null && truncate !== digest.byteLength) {\n if (truncate > digest.byteLength) {\n throw new Error(`Invalid truncate option, must be less than or equal to ${digest.byteLength}`)\n }\n\n digest = digest.subarray(0, truncate)\n }\n\n return Digest.create(code, digest)\n}\n", "/* global crypto */\n\nimport { from } from './hasher.js'\n\nfunction sha (name: AlgorithmIdentifier): (data: Uint8Array) => Promise<Uint8Array> {\n return async data => new Uint8Array(await crypto.subtle.digest(name, data))\n}\n\nexport const sha256 = from({\n name: 'sha2-256',\n code: 0x12,\n encode: sha('SHA-256')\n})\n\nexport const sha512 = from({\n name: 'sha2-512',\n code: 0x13,\n encode: sha('SHA-512')\n})\n", "import { sha256 } from 'multiformats/hashes/sha2'\r\nimport { Chain, entryAt } from \"../index.js\";\r\nimport { nameof } from \"../utility/nameof.js\";\r\nimport type { IBlock, BlockId, ActionId, CollectionId, ChainPath, ActionRev, ActionContext, ChainInitOptions, BlockStore } from \"../index.js\";\r\nimport type { ChainHeaderBlockType, ChainDataNode } from '../chain/chain-nodes.js';\r\nimport type { LogEntry, ActionEntry } from \"./index.js\";\r\nimport { LogDataBlockType, LogHeaderBlockType } from \"./index.js\";\r\nimport { toString as uint8ArrayToString } from 'uint8arrays/to-string'\r\nimport type { GetFromResult } from './struct.js';\r\n\r\nexport type LogBlock<TAction> = ChainDataNode<LogEntry<TAction>>\r\n\t& {\r\n\t\t/** Base64url encoded Sha256 hash of the next block - present on every block except the head */\r\n\t\tpriorHash?: string,\r\n\t};\r\n\r\nexport const priorHash$ = nameof<LogBlock<any>>(\"priorHash\");\r\n\r\nexport class Log<TAction> {\r\n\tprotected constructor(\r\n\t\tprivate readonly chain: Chain<LogEntry<TAction>>,\r\n\t) {\r\n\t}\r\n\r\n\tget id() {\r\n\t\treturn this.chain.id;\r\n\t}\r\n\r\n\t/** Opens a presumably existing log. */\r\n\tstatic async open<TAction>(store: BlockStore<IBlock>, id: BlockId): Promise<Log<TAction> | undefined> {\r\n\t\tconst chain = await Chain.open<LogEntry<TAction>>(store, id, Log.getChainOptions(store));\r\n\t\treturn chain ? new Log<TAction>(chain) : undefined;\r\n\t}\r\n\r\n\t/** Creates a new log. */\r\n\tstatic async create<TAction>(store: BlockStore<IBlock>, newId?: BlockId) {\r\n\t\treturn new Log<TAction>(await Chain.create<LogEntry<TAction>>(store, { ...Log.getChainOptions(store), newId }));\r\n\t}\r\n\r\n\t/** Adds a new entry to the log. */\r\n\tasync addActions(actions: TAction[], actionId: ActionId, rev: number, getBlockIds: () => BlockId[], collectionIds: CollectionId[] = [], timestamp: number = Date.now()) {\r\n\t\tconst entry = { timestamp, rev, action: { actionId, actions, blockIds: [], collectionIds } } as LogEntry<TAction>;\r\n\t\tconst tailPath = await this.chain.add(entry);\r\n\t\tconst entryWithBlockIds = { ...entry, action: { ...entry.action!, blockIds: getBlockIds() } };\r\n\t\tthis.chain.updateAt(tailPath, entryWithBlockIds);\r\n\t\treturn { entry: entryWithBlockIds, tailPath };\r\n\t}\r\n\r\n\t/** Adds a checkpoint to the log. */\r\n\tasync addCheckpoint(pendings: ActionRev[], rev: number, timestamp: number = Date.now()) {\r\n\t\tconst entry = { timestamp, rev, checkpoint: { pendings } };\r\n\t\tconst tailPath = await this.chain.add(entry);\r\n\t\treturn { entry, tailPath };\r\n\t}\r\n\r\n\t/** Gets the action context of the log. */\r\n\tasync getActionContext(): Promise<ActionContext | undefined> {\r\n\t\tconst tailPath = await this.chain.getTail();\r\n\t\tif (!tailPath) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\tconst checkpoint = await this.findCheckpoint(tailPath);\r\n\t\treturn {\r\n\t\t\tcommitted:\r\n\t\t\t\tcheckpoint\r\n\r\n\t\t\t\t\t? [...checkpoint.pendings, ...await this.pendingFrom(checkpoint.path)]\r\n\t\t\t\t\t: [],\r\n\t\t\trev: checkpoint?.rev ?? 0,\r\n\t\t};\r\n\t}\r\n\r\n\t/** Gets the actions from startRev (exclusive), to latest in the log. */\r\n\tasync getFrom(startRev: number | undefined): Promise<GetFromResult<TAction>> {\r\n\t\tconst entries: ActionEntry<TAction>[] = [];\r\n\t\tconst pendings: ActionRev[] = [];\r\n\t\tlet rev: number | undefined;\r\n\t\tlet checkpointPath: ChainPath<LogEntry<TAction>> | undefined;\r\n\t\t// Step through collecting both pending and entries until a checkpoint is found\r\n\t\tfor await (const path of this.chain.select(undefined, false)) {\r\n\t\t\tconst entry = entryAt<LogEntry<TAction>>(path)!;\r\n\t\t\trev = rev ?? entry.rev;\r\n\t\t\tif (entry.checkpoint) {\r\n\t\t\t\tcheckpointPath = path;\r\n\t\t\t\tpendings.unshift(...entry.checkpoint.pendings);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tpendings.unshift({ actionId: entry.action!.actionId, rev: entry.rev });\r\n\t\t\tif (startRev !== undefined && entry.rev > startRev) {\r\n\t\t\t\tentries.unshift(entry.action!);\r\n\t\t\t}\t// Can't stop at rev, because we need to collect all pending actions for the context\r\n\t\t}\r\n\t\t// Continue stepping past the checkpoint until the given rev is reached\r\n\t\tif (checkpointPath) {\r\n\t\t\tfor await (const path of this.chain.select(checkpointPath, false)) {\r\n\t\t\t\tconst entry = entryAt<LogEntry<TAction>>(path)!;\r\n\t\t\t\tif (startRev !== undefined && entry.rev > startRev) {\r\n\t\t\t\t\tif (entry.action) {\r\n\t\t\t\t\t\tentries.unshift(entry.action!);\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn { context: rev ? { committed: pendings, rev } : undefined, entries };\r\n\t}\r\n\r\n\t/** Enumerates log entries from the given starting path or end if undefined, in forward (from tail to head) or reverse (from head to tail) order. */\r\n\tasync *select(starting?: ChainPath<LogEntry<TAction>>, forward = true) {\r\n\t\tfor await (const path of this.chain.select(starting, forward)) {\r\n\t\t\tyield entryAt<LogEntry<TAction>>(path)!;\r\n\t\t}\r\n\t}\r\n\r\n\t/** Returns the set of pending transactions in the most recent checkpoint, at or preceding the given path. */\r\n\tprivate async findCheckpoint(starting: ChainPath<LogEntry<TAction>>) {\r\n\t\tlet lastPath: ChainPath<LogEntry<TAction>> | undefined;\r\n\t\tlet rev: number | undefined;\r\n\t\tfor await (const path of this.chain.select(starting, false)) {\r\n\t\t\tconst entry = entryAt<LogEntry<TAction>>(path)!;\r\n\t\t\trev = rev ?? entry.rev;\r\n\t\t\tif (entry.checkpoint) {\r\n\t\t\t\treturn { path, pendings: entry.checkpoint.pendings, rev };\r\n\t\t\t}\r\n\t\t\tlastPath = path;\r\n\t\t}\r\n\t\treturn lastPath ? { path: lastPath, pendings: [], rev } : undefined;\r\n\t}\r\n\r\n\t/** Returns the set of pending actions following, the given checkpoint path. */\r\n\tprivate async pendingFrom(starting: ChainPath<LogEntry<TAction>>) {\r\n\t\tconst pendings: ActionRev[] = [];\r\n\t\tfor await (const actionPath of this.chain.select(starting)) {\r\n\t\t\tconst entry = entryAt<LogEntry<TAction>>(actionPath);\r\n\t\t\tif (entry?.action) {\r\n\t\t\t\tpendings.push({ actionId: entry.action.actionId, rev: entry.rev });\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn pendings;\r\n\t}\r\n\r\n\tprivate static getChainOptions<TAction>(store: BlockStore<IBlock>) {\r\n\t\treturn {\r\n\t\t\tcreateDataBlock: () => ({ header: store.createBlockHeader(LogDataBlockType) }),\r\n\t\t\tcreateHeaderBlock: (id?: BlockId) => ({ header: store.createBlockHeader(LogHeaderBlockType, id) }),\r\n\t\t\tnewBlock: async (newTail: LogBlock<TAction>, oldTail: LogBlock<TAction> | undefined) => {\r\n\t\t\t\tif (oldTail) {\r\n\t\t\t\t\tconst hash = await sha256.digest(new TextEncoder().encode(JSON.stringify(oldTail)));\r\n\t\t\t\t\tnewTail.priorHash = uint8ArrayToString(hash.digest, 'base64url');\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t} as ChainInitOptions<LogEntry<TAction>>;\r\n\r\n\t}\r\n}\r\n", "import type { BlockId, CollectionId, ActionContext, ActionId, ActionRev } from \"../index.js\";\r\n\r\n/** A log entry - either an action or a checkpoint */\r\nexport type LogEntry<TAction> = {\r\n\t/** Linux timestamp of the entry */\r\n\treadonly timestamp: number;\r\n\t/** Revision number - monotonically increasing from the prior entry's rev. Starts at 1. */\r\n\treadonly rev: number;\r\n\treadonly action?: ActionEntry<TAction>;\r\n\treadonly checkpoint?: CheckpointEntry;\r\n};\r\n\r\n/** An action entry represents a unit of work that is atomic */\r\nexport type ActionEntry<TAction> = {\r\n\t/** Generated unique identifier for the action */\r\n\treadonly actionId: ActionId;\r\n\t/** Actions to be applied */\r\n\treadonly actions: TAction[];\r\n\t/** Block ids affected by the action - includes the log related blocks */\r\n\tblockIds: BlockId[]; // NOTE: this is updated after being generated to include the log-related block transforms\r\n\t/** Other collection ids affected by the action - this action is conditional on successful commit in all of these collections */\r\n\treadonly collectionIds?: CollectionId[];\r\n};\r\n\r\n/** A checkpoint entry restates the currently uncheckpointed actions */\r\nexport type CheckpointEntry = {\r\n\t/** The current set of pending action/revs\r\n\t * - actions implicitly increase the set of pending Ids\r\n\t * - this restates the entire current set\r\n\t * - missing from the set are the implicitly checkpointed ones */\r\n\treadonly pendings: ActionRev[];\r\n};\r\n\r\nexport const LogDataBlockType = \"LGD\";\r\nexport const LogHeaderBlockType = \"LGH\";\r\n\r\nexport type GetFromResult<TAction> = {\r\n\tcontext: ActionContext | undefined;\r\n\tentries: ActionEntry<TAction>[];\r\n};\r\n", "/**\n * Portable type aliases for peer networking.\n *\n * These minimal structural types decouple db-core from any concrete\n * networking library (e.g. libp2p). Concrete implementations in\n * transport packages (db-p2p) satisfy these structurally.\n */\n\n/** Minimal peer identifier \u2014 structurally compatible with libp2p's PeerId. */\nexport type PeerId = {\n\ttoString(): string;\n\tequals(other: unknown): boolean;\n};\n\n/** Opaque network stream \u2014 db-core never accesses stream internals. */\nexport type Stream = {\n\tclose(): Promise<void>;\n};\n\n/** Options for abortable operations. */\nexport type AbortOptions = {\n\tsignal?: AbortSignal;\n};\n\n/** Create a lightweight PeerId from its string representation. */\nexport function peerIdFromString(id: string): PeerId {\n\treturn {\n\t\ttoString: () => id,\n\t\tequals: (other: unknown) =>\n\t\t\tother != null\n\t\t\t&& typeof other === 'object'\n\t\t\t&& 'toString' in other\n\t\t\t&& typeof (other as PeerId).toString === 'function'\n\t\t\t&& (other as PeerId).toString() === id,\n\t};\n}\n\n", "/**\n * Simple djb2 string hash function.\n * \n * This is a non-cryptographic hash suitable for generating short identifiers.\n * For security-critical hashing, use SHA-256 from multiformats/hashes/sha2.\n * \n * @param str - The string to hash\n * @returns A base-36 encoded hash string\n */\nexport function hashString(str: string): string {\n\tlet hash = 5381;\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n\t}\n\treturn Math.abs(hash).toString(36);\n}\n\n", "import type { BlockId } from \"../blocks/index.js\";\r\nimport type { CollectionId } from \"../collection/index.js\";\r\nimport { hashString } from \"../utility/hash-string.js\";\r\n\r\n/**\r\n * Transaction Stamp: Created at BEGIN, stable throughout transaction lifecycle.\r\n *\r\n * The stamp contains metadata about the transaction's origin and context.\r\n * The id is computed as a hash of these fields.\r\n */\r\nexport type TransactionStamp = {\r\n\t/** Peer that initiated the transaction */\r\n\tpeerId: string;\r\n\r\n\t/** When transaction started (milliseconds since epoch) */\r\n\ttimestamp: number;\r\n\r\n\t/** Hash of schema version(s) for validation */\r\n\tschemaHash: string;\r\n\r\n\t/** Which engine (e.g., 'quereus@0.5.3', 'actions@1.0.0') */\r\n\tengineId: string;\r\n\r\n\t/** Hash of the stamp fields (computed) - stable identifier throughout transaction */\r\n\tid: string;\r\n};\r\n\r\n/**\r\n * Transaction: Finalized at COMMIT with complete statement history.\r\n *\r\n * Transactions span multiple collections and use pluggable engines for interpreting the statements.\r\n * The engine re-executes the statements to verify the resulting operations match what was proposed.\r\n */\r\nexport type Transaction = {\r\n\t/** The transaction stamp (includes stable id) */\r\n\tstamp: TransactionStamp;\r\n\r\n\t/** Engine-specific statements (for replay/validation)\r\n\t * Array of statements executed during the transaction.\r\n\t * - For Quereus: SQL statements\r\n\t * - For ActionsEngine: JSON-encoded actions\r\n\t */\r\n\tstatements: string[];\r\n\r\n\t/** Read dependencies for optimistic concurrency control */\r\n\treads: ReadDependency[];\r\n\r\n\t/** Transaction identifier (hash of stamp.id + statements + reads)\r\n\t * Final transaction identity, used in logs\r\n\t */\r\n\tid: string;\r\n};\r\n\r\n/**\r\n * Read dependency for optimistic concurrency control.\r\n * Tracks which block revisions were read during transaction execution.\r\n */\r\nexport type ReadDependency = {\r\n\tblockId: BlockId;\r\n\t/** Expected revision number at time of read */\r\n\trevision: number;\r\n};\r\n\r\n/**\r\n * Transaction reference embedded in actions.\r\n * Just the transaction ID - full transaction can be looked up separately if needed.\r\n */\r\nexport type TransactionRef = string; // The transaction ID\r\n\r\n/**\r\n * Create a transaction stamp with computed id.\r\n * The id is a hash of the stamp fields.\r\n */\r\nexport function createTransactionStamp(\r\n\tpeerId: string,\r\n\ttimestamp: number,\r\n\tschemaHash: string,\r\n\tengineId: string\r\n): TransactionStamp {\r\n\tconst stampData = JSON.stringify({ peerId, timestamp, schemaHash, engineId });\r\n\tconst id = `stamp:${hashString(stampData)}`;\r\n\treturn { peerId, timestamp, schemaHash, engineId, id };\r\n}\r\n\r\n/**\r\n * Create a transaction id from stamp id, statements, and reads.\r\n * This is the final transaction identity used in logs.\r\n */\r\nexport function createTransactionId(\r\n\tstampId: string,\r\n\tstatements: string[],\r\n\treads: ReadDependency[]\r\n): string {\r\n\tconst txData = JSON.stringify({ stampId, statements, reads });\r\n\treturn `tx:${hashString(txData)}`;\r\n}\r\n\r\n\r\n\r\n/**\r\n * Transaction engine interface.\r\n * Pluggable engines implement this to process transaction statements.\r\n *\r\n * Engines are responsible for:\r\n * 1. Parsing the engine-specific statements\r\n * 2. Executing/re-executing to produce actions\r\n * 3. Returning the resulting actions per collection\r\n */\r\nexport interface ITransactionEngine {\r\n\t/**\r\n\t * Process a transaction statements to produce actions.\r\n\t *\r\n\t * Used both for:\r\n\t * - Initial execution (client creating transaction)\r\n\t * - Re-execution (validators verifying transaction)\r\n\t *\r\n\t * @param transaction - The transaction to process\r\n\t * @returns The resulting actions from execution\r\n\t */\r\n\texecute(transaction: Transaction): Promise<ExecutionResult>;\r\n}\r\n\r\n/**\r\n * Result of transaction execution.\r\n */\r\nexport type ExecutionResult = {\r\n\t/** Whether execution succeeded */\r\n\tsuccess: boolean;\r\n\t/** Actions produced by executing the transaction */\r\n\tactions?: CollectionActions[];\r\n\t/** Results from executing actions (e.g., return values from reads) */\r\n\tresults?: Map<CollectionId, any[]>;\r\n\t/** Error message if execution failed */\r\n\terror?: string;\r\n};\r\n\r\n/**\r\n * Actions for a specific collection resulting from transaction execution.\r\n */\r\nexport type CollectionActions = {\r\n\t/** Collection identifier */\r\n\tcollectionId: string;\r\n\t/** Actions to apply to this collection */\r\n\tactions: unknown[];\r\n};\r\n\r\n/**\r\n * Result of transaction validation.\r\n */\r\nexport type ValidationResult = {\r\n\t/** Whether validation succeeded */\r\n\tvalid: boolean;\r\n\t/** Reason for validation failure (if valid=false) */\r\n\treason?: string;\r\n\t/** The operations hash computed during validation (for debugging) */\r\n\tcomputedHash?: string;\r\n};\r\n\r\n/**\r\n * Transaction validator interface.\r\n * Pluggable validators implement this to verify transaction integrity.\r\n *\r\n * Validators are invoked when a node receives a PendRequest with a transaction.\r\n * They re-execute the transaction and verify the operations match.\r\n */\r\nexport interface ITransactionValidator {\r\n\t/**\r\n\t * Validate a transaction by re-executing and comparing operations hash.\r\n\t *\r\n\t * Validation steps:\r\n\t * 1. Verify stamp.engineId matches a known engine\r\n\t * 2. Verify stamp.schemaHash matches local schema\r\n\t * 3. Verify read dependencies (no stale reads)\r\n\t * 4. Re-execute transaction.statements through engine (isolated state)\r\n\t * 5. Collect operations from re-execution\r\n\t * 6. Compute hash of operations\r\n\t * 7. Compare with sender's operationsHash\r\n\t *\r\n\t * @param transaction - The transaction to validate\r\n\t * @param operationsHash - The hash to compare against\r\n\t * @returns Validation result\r\n\t */\r\n\tvalidate(transaction: Transaction, operationsHash: string): Promise<ValidationResult>;\r\n\r\n\t/**\r\n\t * Get the schema hash for a given engine.\r\n\t * Used to verify the sender's schema matches local schema.\r\n\t *\r\n\t * @param engineId - The engine identifier\r\n\t * @returns The schema hash, or undefined if engine not found\r\n\t */\r\n\tgetSchemaHash(engineId: string): Promise<string | undefined>;\r\n}\r\n\r\n", "export type {\r\n\tTransaction,\r\n\tTransactionStamp,\r\n\tReadDependency,\r\n\tTransactionRef,\r\n\tITransactionEngine,\r\n\tExecutionResult,\r\n\tCollectionActions,\r\n\tValidationResult,\r\n\tITransactionValidator\r\n} from './transaction.js';\r\n\r\nexport {\r\n\tcreateTransactionStamp,\r\n\tcreateTransactionId\r\n} from './transaction.js';\r\n\r\nexport {\r\n\tActionsEngine,\r\n\tACTIONS_ENGINE_ID,\r\n\tcreateActionsStatements\r\n} from './actions-engine.js';\r\n\r\nexport type { ActionsStatement } from './actions-engine.js';\r\n\r\nexport { TransactionCoordinator } from './coordinator.js';\r\nexport { TransactionContext } from './context.js';\r\nexport { TransactionSession } from './session.js';\r\nexport { TransactionValidator } from './validator.js';\r\nexport type { EngineRegistration, ValidationCoordinatorFactory } from './validator.js';\r\n", "import type { ITransactor, BlockId, CollectionId, Transforms, PendRequest, CommitRequest, ActionId, IBlock, BlockOperations } from \"../index.js\";\r\nimport type { Transaction, ExecutionResult, ITransactionEngine, CollectionActions } from \"./transaction.js\";\r\nimport type { PeerId } from \"../network/types.js\";\r\nimport type { Collection } from \"../collection/collection.js\";\r\nimport { TransactionContext } from \"./context.js\";\r\nimport { createActionsStatements } from \"./actions-engine.js\";\r\nimport { createTransactionStamp, createTransactionId } from \"./transaction.js\";\r\nimport { Log, blockIdsForTransforms, transformsFromTransform, hashString } from \"../index.js\";\r\n\r\n/**\r\n * Represents an operation on a block within a collection.\r\n */\r\ntype Operation =\r\n\t| { readonly type: 'insert'; readonly collectionId: CollectionId; readonly blockId: BlockId; readonly block: IBlock }\r\n\t| { readonly type: 'update'; readonly collectionId: CollectionId; readonly blockId: BlockId; readonly operations: BlockOperations }\r\n\t| { readonly type: 'delete'; readonly collectionId: CollectionId; readonly blockId: BlockId };\r\n\r\n/**\r\n * Coordinates multi-collection transactions.\r\n *\r\n * This is the ONLY interface for all mutations (single or multi-collection).\r\n *\r\n * Responsibilities:\r\n * - Manage collections (create as needed)\r\n * - Apply actions to collections (run handlers, write to logs)\r\n * - Commit transactions by running consensus phases (GATHER, PEND, COMMIT)\r\n */\r\nexport class TransactionCoordinator {\r\n\tconstructor(\r\n\t\tprivate readonly transactor: ITransactor,\r\n\t\tprivate readonly collections: Map<CollectionId, Collection<any>>\r\n\t) {}\r\n\r\n\t/**\r\n\t * Apply actions to collections (called by engines during statement execution).\r\n\t *\r\n\t * This is the core method that engines call to apply actions to collections.\r\n\t * Actions are tagged with the stamp ID and executed immediately through collections\r\n\t * to update the local snapshot.\r\n\t *\r\n\t * @param actions - The actions to apply (per collection)\r\n\t * @param stampId - The transaction stamp ID to tag actions with\r\n\t */\r\n\tasync applyActions(\r\n\t\tactions: CollectionActions[],\r\n\t\tstampId: string\r\n\t): Promise<void> {\r\n\t\tfor (const { collectionId, actions: collectionActions } of actions) {\r\n\t\t\t// Get collection\r\n\t\t\tconst collection = this.collections.get(collectionId);\r\n\t\t\tif (!collection) {\r\n\t\t\t\tthrow new Error(`Collection not found: ${collectionId}`);\r\n\t\t\t}\r\n\r\n\t\t\t// Apply each action (tagged with stampId)\r\n\t\t\tfor (const action of collectionActions) {\r\n\t\t\t\tconst taggedAction = { ...(action as any), transaction: stampId };\r\n\t\t\t\tawait collection.act(taggedAction);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Commit a transaction (actions already applied, orchestrate PEND/COMMIT).\r\n\t *\r\n\t * This is called by TransactionSession.commit() after all statements have been executed.\r\n\t * Actions have already been applied to collections via applyActions(), so this method\r\n\t * just orchestrates the distributed consensus.\r\n\t *\r\n\t * @param transaction - The transaction to commit\r\n\t */\r\n\tasync commit(transaction: Transaction): Promise<void> {\r\n\t\t// Collect transforms and determine critical blocks for each affected collection\r\n\t\tconst collectionData = Array.from(this.collections.entries())\r\n\t\t\t.map(([collectionId, collection]) => ({\r\n\t\t\t\tcollectionId,\r\n\t\t\t\tcollection,\r\n\t\t\t\ttransforms: collection.tracker.transforms\r\n\t\t\t}))\r\n\t\t\t.filter(({ transforms }) =>\r\n\t\t\t\tObject.keys(transforms.inserts ?? {}).length +\r\n\t\t\t\tObject.keys(transforms.updates ?? {}).length +\r\n\t\t\t\t(transforms.deletes?.length ?? 0) > 0\r\n\t\t\t);\r\n\r\n\t\tif (collectionData.length === 0) {\r\n\t\t\treturn; // Nothing to commit\r\n\t\t}\r\n\r\n\t\t// Get critical block IDs (log tail) for each affected collection\r\n\t\t// The critical block is the current log tail that must participate in consensus\r\n\t\tconst collectionTransforms = new Map<CollectionId, Transforms>();\r\n\t\tconst criticalBlocks = new Map<CollectionId, BlockId>();\r\n\r\n\t\tfor (const { collectionId, collection, transforms } of collectionData) {\r\n\t\t\tcollectionTransforms.set(collectionId, transforms);\r\n\r\n\t\t\t// Get the current log tail block ID (critical block)\r\n\t\t\tconst log = await Log.open(collection.tracker, collectionId);\r\n\t\t\tif (!log) {\r\n\t\t\t\tthrow new Error(`Log not found for collection ${collectionId}`);\r\n\t\t\t}\r\n\r\n\t\t\tconst tailPath = await (log as unknown as { chain: { getTail: () => Promise<{ block: { header: { id: BlockId } } } | undefined> } }).chain.getTail();\r\n\t\t\tif (tailPath) {\r\n\t\t\t\tcriticalBlocks.set(collectionId, tailPath.block.header.id);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Compute hash of ALL operations across ALL collections\r\n\t\t// This hash is used for validation - validators re-execute the transaction\r\n\t\t// and compare their computed operations hash with this one\r\n\t\tconst allOperations = collectionData.flatMap(({ collectionId, transforms }) => [\r\n\t\t\t...Object.entries(transforms.inserts ?? {}).map(([blockId, block]) =>\r\n\t\t\t\t({ type: 'insert' as const, collectionId, blockId, block })\r\n\t\t\t),\r\n\t\t\t...Object.entries(transforms.updates ?? {}).map(([blockId, operations]) =>\r\n\t\t\t\t({ type: 'update' as const, collectionId, blockId, operations })\r\n\t\t\t),\r\n\t\t\t...(transforms.deletes ?? []).map(blockId =>\r\n\t\t\t\t({ type: 'delete' as const, collectionId, blockId })\r\n\t\t\t)\r\n\t\t]);\r\n\r\n\t\tconst operationsHash = this.hashOperations(allOperations);\r\n\r\n\t\t// Execute consensus phases (GATHER, PEND, COMMIT)\r\n\t\tconst coordResult = await this.coordinateTransaction(\r\n\t\t\ttransaction,\r\n\t\t\toperationsHash,\r\n\t\t\tcollectionTransforms,\r\n\t\t\tcriticalBlocks\r\n\t\t);\r\n\r\n\t\tif (!coordResult.success) {\r\n\t\t\tthrow new Error(`Transaction commit failed: ${coordResult.error}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Rollback a transaction (undo applied actions).\r\n\t *\r\n\t * This is called by TransactionSession.rollback() to undo all actions\r\n\t * that were applied via applyActions().\r\n\t *\r\n\t * @param _stampId - The transaction stamp ID to rollback (currently unused - we clear all trackers)\r\n\t */\r\n\tasync rollback(_stampId: string): Promise<void> {\r\n\t\t// Clear trackers for all collections\r\n\t\t// This discards all pending changes that were applied via applyActions()\r\n\t\t// TODO: In the future, we may want to track which collections were affected by\r\n\t\t// a specific stampId and only reset those trackers\r\n\t\tfor (const collection of this.collections.values()) {\r\n\t\t\t// Reset the tracker to discard all pending transforms\r\n\t\t\tcollection.tracker.reset();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Get current transforms from all collections.\r\n\t *\r\n\t * This collects transforms from each collection's tracker. Useful for\r\n\t * validation scenarios where transforms need to be extracted after\r\n\t * engine execution.\r\n\t */\r\n\tgetTransforms(): Map<CollectionId, Transforms> {\r\n\t\tconst transforms = new Map<CollectionId, Transforms>();\r\n\t\tfor (const [collectionId, collection] of this.collections.entries()) {\r\n\t\t\tconst collectionTransforms = collection.tracker.transforms;\r\n\t\t\tconst hasChanges =\r\n\t\t\t\tObject.keys(collectionTransforms.inserts ?? {}).length > 0 ||\r\n\t\t\t\tObject.keys(collectionTransforms.updates ?? {}).length > 0 ||\r\n\t\t\t\t(collectionTransforms.deletes?.length ?? 0) > 0;\r\n\t\t\tif (hasChanges) {\r\n\t\t\t\ttransforms.set(collectionId, collectionTransforms);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn transforms;\r\n\t}\r\n\r\n\t/**\r\n\t * Reset all collection trackers.\r\n\t *\r\n\t * This clears pending transforms from all collections. Useful for\r\n\t * cleaning up after validation or when starting a new transaction.\r\n\t */\r\n\tresetTransforms(): void {\r\n\t\tfor (const collection of this.collections.values()) {\r\n\t\t\tcollection.tracker.reset();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Compute hash of all operations in a transaction.\r\n\t * This hash is used for validation - validators re-execute the transaction\r\n\t * and compare their computed operations hash with this one.\r\n\t */\r\n\tprivate hashOperations(operations: readonly Operation[]): string {\r\n\t\tconst operationsData = JSON.stringify(operations);\r\n\t\treturn `ops:${hashString(operationsData)}`;\r\n\t}\r\n\r\n\t/**\r\n\t * Commit a transaction context.\r\n\t *\r\n\t * @deprecated Use TransactionSession instead of TransactionContext\r\n\t * This is called by TransactionContext.commit().\r\n\t *\r\n\t * @param context - The transaction context to commit\r\n\t * @returns Execution result with actions and results\r\n\t */\r\n\tasync commitTransaction(context: TransactionContext): Promise<ExecutionResult> {\r\n\t\tconst collectionActions = Array.from(context.getCollectionActions().entries()).map(\r\n\t\t\t([collectionId, actions]) => ({ collectionId, actions })\r\n\t\t);\r\n\r\n\t\tif (collectionActions.length === 0) {\r\n\t\t\treturn { success: true }; // Nothing to commit\r\n\t\t}\r\n\r\n\t\t// Create transaction statements\r\n\t\tconst statements = createActionsStatements(collectionActions);\r\n\t\tconst reads = context.getReads();\r\n\r\n\t\t// Create stamp from context\r\n\t\tconst stamp = createTransactionStamp(\r\n\t\t\t'local', // TODO: Get from context or coordinator\r\n\t\t\tDate.now(),\r\n\t\t\t'', // TODO: Get from engine\r\n\t\t\tcontext.engine\r\n\t\t);\r\n\r\n\t\tconst transaction: Transaction = {\r\n\t\t\tstamp,\r\n\t\t\tstatements,\r\n\t\t\treads,\r\n\t\t\tid: createTransactionId(stamp.id, statements, reads)\r\n\t\t};\r\n\r\n\t\t// Create ActionsEngine for execution (TransactionContext only supports actions)\r\n\t\tconst { ActionsEngine } = await import('./actions-engine.js');\r\n\t\tconst engine = new ActionsEngine(this);\r\n\r\n\t\t// Execute through standard path\r\n\t\treturn await this.execute(transaction, engine);\r\n\t}\r\n\r\n\t/**\r\n\t * Execute a fully-formed transaction.\r\n\t *\r\n\t * This can be called directly with a complete transaction (e.g., from Quereus),\r\n\t * or indirectly via commitTransaction().\r\n\t *\r\n\t * @param transaction - The transaction to execute\r\n\t * @param engine - The engine to use for executing the transaction\r\n\t * @returns Execution result with actions and results\r\n\t */\r\n\tasync execute(transaction: Transaction, engine: ITransactionEngine): Promise<ExecutionResult> {\r\n\t\t// 1. Validate engine matches transaction\r\n\t\t// Note: We don't enforce this strictly since the engine is passed in explicitly\r\n\t\t// The caller is responsible for ensuring the correct engine is used\r\n\r\n\t\tconst result = await engine.execute(transaction);\r\n\t\tif (!result.success) {\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\tif (!result.actions || result.actions.length === 0) {\r\n\t\t\treturn { success: true }; // Nothing to do\r\n\t\t}\r\n\r\n\t\t// 2. Apply actions to collections and collect transforms\r\n\t\tconst collectionTransforms = new Map<CollectionId, Transforms>();\r\n\t\tconst criticalBlocks = new Map<CollectionId, BlockId>();\r\n\t\tconst actionResults = new Map<CollectionId, any[]>();\r\n\t\tconst allCollectionIds = result.actions.map(ca => ca.collectionId);\r\n\r\n\t\tfor (const collectionActions of result.actions) {\r\n\t\t\tconst applyResult = await this.applyActionsToCollection(\r\n\t\t\t\tcollectionActions,\r\n\t\t\t\ttransaction,\r\n\t\t\t\tallCollectionIds\r\n\t\t\t);\r\n\r\n\t\t\tif (!applyResult.success) {\r\n\t\t\t\treturn { success: false, error: applyResult.error };\r\n\t\t\t}\r\n\r\n\t\t\tcollectionTransforms.set(collectionActions.collectionId, applyResult.transforms!);\r\n\t\t\tcriticalBlocks.set(collectionActions.collectionId, applyResult.logTailBlockId!);\r\n\t\t\tactionResults.set(collectionActions.collectionId, applyResult.results!);\r\n\t\t}\r\n\r\n\t\t// 3. Compute operations hash for validation\r\n\t\tconst allOperations = Array.from(collectionTransforms.entries()).flatMap(([collectionId, transforms]) => [\r\n\t\t\t...Object.entries(transforms.inserts ?? {}).map(([blockId, block]) =>\r\n\t\t\t\t({ type: 'insert' as const, collectionId, blockId, block })\r\n\t\t\t),\r\n\t\t\t...Object.entries(transforms.updates ?? {}).map(([blockId, operations]) =>\r\n\t\t\t\t({ type: 'update' as const, collectionId, blockId, operations })\r\n\t\t\t),\r\n\t\t\t...(transforms.deletes ?? []).map(blockId =>\r\n\t\t\t\t({ type: 'delete' as const, collectionId, blockId })\r\n\t\t\t)\r\n\t\t]);\r\n\t\tconst operationsHash = this.hashOperations(allOperations);\r\n\r\n\t\t// 4. Coordinate (GATHER if multi-collection)\r\n\t\tconst coordResult = await this.coordinateTransaction(\r\n\t\t\ttransaction,\r\n\t\t\toperationsHash,\r\n\t\t\tcollectionTransforms,\r\n\t\t\tcriticalBlocks\r\n\t\t);\r\n\r\n\t\tif (!coordResult.success) {\r\n\t\t\treturn coordResult;\r\n\t\t}\r\n\r\n\t\t// 4. Return results from actions\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\tactions: result.actions,\r\n\t\t\tresults: actionResults\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * Apply actions to a collection.\r\n\t *\r\n\t * This runs the action handlers, writes to the log, and collects transforms.\r\n\t */\r\n\tprivate async applyActionsToCollection(\r\n\t\tcollectionActions: CollectionActions,\r\n\t\ttransaction: Transaction,\r\n\t\tallCollectionIds: CollectionId[]\r\n\t): Promise<{\r\n\t\tsuccess: boolean;\r\n\t\ttransforms?: Transforms;\r\n\t\tlogTailBlockId?: BlockId;\r\n\t\tresults?: any[];\r\n\t\terror?: string;\r\n\t}> {\r\n\t\tconst collection = this.collections.get(collectionActions.collectionId);\r\n\t\tif (!collection) {\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: `Collection not found: ${collectionActions.collectionId}`\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\t// At this point, actions have already been executed through collection.act()\r\n\t\t// when they were added to the TransactionContext. The collection's tracker\r\n\t\t// already has the transforms, and the actions are in the pending buffer.\r\n\r\n\t\t// Get transforms from the collection's tracker\r\n\t\tconst transforms = collection.tracker.transforms;\r\n\r\n\t\t// Write actions to the collection's log to get the log tail block ID\r\n\t\tconst log = await Log.open(collection.tracker, collectionActions.collectionId);\r\n\t\tif (!log) {\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: `Log not found for collection ${collectionActions.collectionId}`\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\t// Generate action ID from transaction ID\r\n\t\tconst actionId = transaction.id;\r\n\t\tconst newRev = (collection['source'].actionContext?.rev ?? 0) + 1;\r\n\r\n\t\t// Add actions to log (this updates the tracker with log block changes)\r\n\t\tconst addResult = await log.addActions(\r\n\t\t\tcollectionActions.actions,\r\n\t\t\tactionId,\r\n\t\t\tnewRev,\r\n\t\t\t() => blockIdsForTransforms(transforms),\r\n\t\t\tallCollectionIds\r\n\t\t);\r\n\r\n\t\t// Return the transforms and log tail block ID\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\ttransforms,\r\n\t\t\tlogTailBlockId: addResult.tailPath.block.header.id,\r\n\t\t\tresults: [] // TODO: Collect results from action handlers when we support read operations\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * Coordinate a transaction across multiple collections.\r\n\t *\r\n\t * @param transaction - The transaction to coordinate\r\n\t * @param operationsHash - Hash of all operations for validation\r\n\t * @param collectionTransforms - Map of collectionId to its transforms\r\n\t * @param criticalBlocks - Map of collectionId to its log tail blockId\r\n\t */\r\n\tprivate async coordinateTransaction(\r\n\t\ttransaction: Transaction,\r\n\t\toperationsHash: string,\r\n\t\tcollectionTransforms: Map<CollectionId, Transforms>,\r\n\t\tcriticalBlocks: Map<CollectionId, BlockId>\r\n\t): Promise<{ success: boolean; error?: string }> {\r\n\t\t// 1. GATHER phase: collect critical cluster nominees (skip if single collection)\r\n\t\tconst criticalBlockIds = Array.from(criticalBlocks.values());\r\n\t\tconst superclusterNominees = await this.gatherPhase(criticalBlockIds);\r\n\r\n\t\t// 2. PEND phase: distribute to all block clusters\r\n\t\tconst pendResult = await this.pendPhase(\r\n\t\t\ttransaction,\r\n\t\t\toperationsHash,\r\n\t\t\tcollectionTransforms,\r\n\t\t\tsuperclusterNominees\r\n\t\t);\r\n\t\tif (!pendResult.success) {\r\n\t\t\treturn pendResult;\r\n\t\t}\r\n\r\n\t\t// 3. COMMIT phase: commit to all critical blocks\r\n\t\tconst commitResult = await this.commitPhase(\r\n\t\t\ttransaction.id as ActionId,\r\n\t\t\tcriticalBlockIds,\r\n\t\t\tpendResult.pendedBlockIds!\r\n\t\t);\r\n\t\tif (!commitResult.success) {\r\n\t\t\t// Cancel pending actions on failure\r\n\t\t\tawait this.cancelPhase(transaction.id as ActionId, collectionTransforms);\r\n\t\t\treturn commitResult;\r\n\t\t}\r\n\r\n\t\t// 4. PROPAGATE and CHECKPOINT phases are handled by clusters automatically\r\n\t\t// (as per user's note: \"managed by each cluster, the client doesn't have to worry about them\")\r\n\r\n\t\treturn { success: true };\r\n\t}\r\n\r\n\t/**\r\n\t * GATHER phase: Collect nominees from critical clusters.\r\n\t *\r\n\t * Skip if only one collection affected (single-collection consensus).\r\n\t *\r\n\t * @param criticalBlockIds - Block IDs of all log tails\r\n\t * @returns Set of peer IDs to use for consensus, or null for single-collection\r\n\t */\r\n\tprivate async gatherPhase(\r\n\t\tcriticalBlockIds: readonly BlockId[]\r\n\t): Promise<ReadonlySet<PeerId> | null> {\r\n\t\t// Skip GATHER if only one collection affected\r\n\t\tif (criticalBlockIds.length === 1) {\r\n\t\t\treturn null; // Use normal single-collection consensus\r\n\t\t}\r\n\r\n\t\t// Check if transactor supports cluster queries (optional method)\r\n\t\tif (!this.transactor.queryClusterNominees) {\r\n\t\t\t// Transactor doesn't support cluster queries - proceed without supercluster\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Query each critical cluster for their nominees and merge into supercluster\r\n\t\tconst nomineePromises = criticalBlockIds.map(blockId =>\r\n\t\t\tthis.transactor.queryClusterNominees!(blockId)\r\n\t\t);\r\n\t\tconst results = await Promise.all(nomineePromises);\r\n\r\n\t\t// Merge all nominees into a single set\r\n\t\tconst supercluster = results.reduce(\r\n\t\t\t(acc, result) => {\r\n\t\t\t\tresult.nominees.forEach(nominee => acc.add(nominee));\r\n\t\t\t\treturn acc;\r\n\t\t\t},\r\n\t\t\tnew Set<PeerId>()\r\n\t\t);\r\n\r\n\t\treturn supercluster;\r\n\t}\r\n\r\n\t/**\r\n\t * PEND phase: Distribute transaction to all affected block clusters.\r\n\t *\r\n\t * @param transaction - The full transaction for replay/validation\r\n\t * @param operationsHash - Hash of all operations for validation\r\n\t * @param collectionTransforms - Map of collectionId to its transforms\r\n\t * @param superclusterNominees - Nominees for multi-collection consensus (null for single-collection)\r\n\t */\r\n\tprivate async pendPhase(\r\n\t\ttransaction: Transaction,\r\n\t\toperationsHash: string,\r\n\t\tcollectionTransforms: ReadonlyMap<CollectionId, Transforms>,\r\n\t\tsuperclusterNominees: ReadonlySet<PeerId> | null\r\n\t): Promise<{ success: boolean; error?: string; pendedBlockIds?: Map<CollectionId, BlockId[]> }> {\r\n\t\tif (collectionTransforms.size === 0) {\r\n\t\t\treturn { success: false, error: 'No transforms to pend' };\r\n\t\t}\r\n\r\n\t\tconst pendedBlockIds = new Map<CollectionId, BlockId[]>();\r\n\t\tconst actionId = transaction.id as ActionId;\r\n\t\tconst nominees = superclusterNominees ? Array.from(superclusterNominees) : undefined;\r\n\r\n\t\t// Pend each collection's transforms\r\n\t\tfor (const [collectionId, transforms] of collectionTransforms.entries()) {\r\n\t\t\tconst collection = this.collections.get(collectionId);\r\n\t\t\tif (!collection) {\r\n\t\t\t\treturn { success: false, error: `Collection not found: ${collectionId}` };\r\n\t\t\t}\r\n\r\n\t\t\t// Get revision from the collection's source\r\n\t\t\tconst rev = (collection['source'].actionContext?.rev ?? 0) + 1;\r\n\r\n\t\t\t// Create pend request with transaction and operations hash for validation\r\n\t\t\tconst pendRequest: PendRequest = {\r\n\t\t\t\tactionId,\r\n\t\t\t\trev,\r\n\t\t\t\ttransforms,\r\n\t\t\t\tpolicy: 'r', // Return policy: fail but return pending actions\r\n\t\t\t\ttransaction,\r\n\t\t\t\toperationsHash,\r\n\t\t\t\tsuperclusterNominees: nominees\r\n\t\t\t};\r\n\r\n\t\t\t// Pend the transaction\r\n\t\t\tconst pendResult = await this.transactor.pend(pendRequest);\r\n\t\t\tif (!pendResult.success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: `Pend failed for collection ${collectionId}: ${pendResult.reason}`\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\t// Store the pended block IDs for commit phase\r\n\t\t\tpendedBlockIds.set(collectionId, pendResult.blockIds);\r\n\t\t}\r\n\r\n\t\treturn { success: true, pendedBlockIds };\r\n\t}\r\n\r\n\t/**\r\n\t * COMMIT phase: Commit to all critical blocks.\r\n\t */\r\n\tprivate async commitPhase(\r\n\t\tactionId: ActionId,\r\n\t\tcriticalBlockIds: BlockId[],\r\n\t\tpendedBlockIds: Map<CollectionId, BlockId[]>\r\n\t): Promise<{ success: boolean; error?: string }> {\r\n\t\t// Commit each collection's transaction\r\n\t\tfor (const [collectionId, blockIds] of pendedBlockIds.entries()) {\r\n\t\t\tconst collection = this.collections.get(collectionId);\r\n\t\t\tif (!collection) {\r\n\t\t\t\treturn { success: false, error: `Collection not found: ${collectionId}` };\r\n\t\t\t}\r\n\r\n\t\t\t// Get revision\r\n\t\t\tconst rev = (collection['source'].actionContext?.rev ?? 0) + 1;\r\n\r\n\t\t\t// Find the critical block (log tail) for this collection\r\n\t\t\tconst logTailBlockId = criticalBlockIds.find(blockId =>\r\n\t\t\t\tblockIds.includes(blockId)\r\n\t\t\t);\r\n\r\n\t\t\tif (!logTailBlockId) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: `Log tail block not found for collection ${collectionId}`\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\t// Create commit request\r\n\t\t\tconst commitRequest: CommitRequest = {\r\n\t\t\t\tactionId,\r\n\t\t\t\tblockIds,\r\n\t\t\t\ttailId: logTailBlockId,\r\n\t\t\t\trev\r\n\t\t\t};\r\n\r\n\t\t\t// Commit the transaction\r\n\t\t\tconst commitResult = await this.transactor.commit(commitRequest);\r\n\t\t\tif (!commitResult.success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: `Commit failed for collection ${collectionId}`\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn { success: true };\r\n\t}\r\n\r\n\t/**\r\n\t * CANCEL phase: Cancel pending actions on all affected blocks.\r\n\t */\r\n\tprivate async cancelPhase(\r\n\t\tactionId: ActionId,\r\n\t\tcollectionTransforms: Map<CollectionId, Transforms>\r\n\t): Promise<void> {\r\n\t\t// Cancel each collection's pending transaction\r\n\t\tfor (const [collectionId, transforms] of collectionTransforms.entries()) {\r\n\t\t\tconst collection = this.collections.get(collectionId);\r\n\t\t\tif (!collection) {\r\n\t\t\t\tcontinue; // Skip if collection not found\r\n\t\t\t}\r\n\r\n\t\t\t// Get the block IDs from transforms\r\n\t\t\tconst blockIds = blockIdsForTransforms(transforms);\r\n\r\n\t\t\t// Cancel the transaction\r\n\t\t\tawait this.transactor.cancel({\r\n\t\t\t\tactionId,\r\n\t\t\t\tblockIds\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n}\r\n\r\n", "import type { CollectionId, ActionId } from \"../index.js\";\r\nimport type { TransactionCoordinator } from \"./coordinator.js\";\r\nimport type { ReadDependency, ExecutionResult } from \"./transaction.js\";\r\nimport type { Action } from \"../collection/action.js\";\r\n\r\n/**\r\n * Transaction context for accumulating actions and reads.\r\n *\r\n * Usage:\r\n * const txn = coordinator.begin();\r\n * txn.addAction('users', { type: 'insert', data: {...} });\r\n * txn.addAction('users', { type: 'get', data: { key: 1 } });\r\n * const result = await txn.commit();\r\n */\r\nexport class TransactionContext {\r\n\tprivate readonly collectionActions: Map<CollectionId, Action<any>[]> = new Map();\r\n\tprivate readonly reads: ReadDependency[] = [];\r\n\r\n\tconstructor(\r\n\t\tprivate readonly coordinator: TransactionCoordinator,\r\n\t\tpublic readonly transactionId: string,\r\n\t\tpublic readonly engine: string\r\n\t) {}\r\n\r\n\t/**\r\n\t * Add an action to a collection.\r\n\t *\r\n\t * Actions are collection-specific:\r\n\t * - Tree: 'insert', 'delete', 'get', 'scan'\r\n\t * - Diary: 'append', 'read'\r\n\t * - etc.\r\n\t */\r\n\tasync addAction(collectionId: CollectionId, action: Action<any>): Promise<void> {\r\n\t\t// Tag action with transaction reference\r\n\t\tconst taggedAction = {\r\n\t\t\t...action,\r\n\t\t\ttransaction: this.transactionId\r\n\t\t};\r\n\r\n\t\t// Get the collection and immediately execute the action to update local snapshot\r\n\t\tconst collection = this.coordinator['collections'].get(collectionId);\r\n\t\tif (collection) {\r\n\t\t\t// Execute through collection to update tracker and pending buffer\r\n\t\t\tawait collection.act(taggedAction);\r\n\t\t}\r\n\t\t// If no collection registered, just buffer the action (for testing or deferred collection creation)\r\n\r\n\t\t// Record in transaction context\r\n\t\tif (!this.collectionActions.has(collectionId)) {\r\n\t\t\tthis.collectionActions.set(collectionId, []);\r\n\t\t}\r\n\t\tthis.collectionActions.get(collectionId)!.push(taggedAction);\r\n\t}\r\n\r\n\t/**\r\n\t * Add a read dependency for optimistic concurrency control.\r\n\t */\r\n\taddRead(read: ReadDependency): void {\r\n\t\tthis.reads.push(read);\r\n\t}\r\n\r\n\t/**\r\n\t * Commit the transaction.\r\n\t *\r\n\t * This executes all accumulated actions across all affected collections,\r\n\t * coordinating with the network as needed.\r\n\t */\r\n\tasync commit(): Promise<ExecutionResult> {\r\n\t\treturn await this.coordinator.commitTransaction(this);\r\n\t}\r\n\r\n\t/**\r\n\t * Rollback the transaction (just discard accumulated state).\r\n\t */\r\n\trollback(): void {\r\n\t\tthis.collectionActions.clear();\r\n\t\tthis.reads.length = 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Get all accumulated actions by collection.\r\n\t * Used by coordinator during commit.\r\n\t */\r\n\tgetCollectionActions(): Map<CollectionId, Action<any>[]> {\r\n\t\treturn this.collectionActions;\r\n\t}\r\n\r\n\t/**\r\n\t * Get all accumulated read dependencies.\r\n\t * Used by coordinator during commit.\r\n\t */\r\n\tgetReads(): ReadDependency[] {\r\n\t\treturn this.reads;\r\n\t}\r\n\r\n\t/**\r\n\t * Get the set of affected collection IDs.\r\n\t */\r\n\tgetAffectedCollections(): Set<CollectionId> {\r\n\t\treturn new Set(this.collectionActions.keys());\r\n\t}\r\n}\r\n\r\n", "import type { TransactionCoordinator } from \"./coordinator.js\";\r\nimport type { Transaction, ExecutionResult, ITransactionEngine, TransactionStamp, CollectionActions } from \"./transaction.js\";\r\nimport { createTransactionStamp, createTransactionId } from \"./transaction.js\";\r\n\r\n/**\r\n * TransactionSession manages incremental transaction building.\r\n *\r\n * This is the high-level API for building transactions incrementally:\r\n * - Stamp is created at BEGIN (stable throughout transaction)\r\n * - Execute statements one at a time\r\n * - Engine translates statements to actions (if not already provided)\r\n * - Actions are immediately applied to collections via coordinator.applyActions()\r\n * - On commit, all statements are compiled into a complete Transaction\r\n * - The Transaction is then committed through coordinator.commit() for PEND/COMMIT orchestration\r\n *\r\n * Usage:\r\n * const session = new TransactionSession(coordinator, engine);\r\n * await session.execute('INSERT INTO users (id, name) VALUES (?, ?)', [1, 'Alice']);\r\n * await session.execute('SELECT * FROM orders WHERE user_id = ?', [1]);\r\n * const result = await session.commit();\r\n *\r\n * For validation/replay, use engine.execute() directly with a complete Transaction.\r\n */\r\nexport class TransactionSession {\r\n\tprivate readonly statements: string[] = [];\r\n\tprivate readonly stamp: TransactionStamp;\r\n\tprivate committed = false;\r\n\tprivate rolledBack = false;\r\n\r\n\tconstructor(\r\n\t\tprivate readonly coordinator: TransactionCoordinator,\r\n\t\tprivate readonly engine: ITransactionEngine,\r\n\t\tpeerId: string = 'local', // TODO: Get from coordinator or config\r\n\t\tschemaHash: string = '' // TODO: Get from engine\r\n\t) {\r\n\t\t// Create stamp at BEGIN (stable throughout transaction)\r\n\t\tthis.stamp = createTransactionStamp(\r\n\t\t\tpeerId,\r\n\t\t\tDate.now(),\r\n\t\t\tschemaHash,\r\n\t\t\t'unknown' // TODO: Get engine ID from engine\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Execute a statement.\r\n\t *\r\n\t * If actions are provided, they are applied directly.\r\n\t * Otherwise, the engine translates the statement to actions.\r\n\t *\r\n\t * @param statement - The statement to execute (engine-specific, e.g., SQL statement)\r\n\t * @param actions - Optional pre-computed actions (for Quereus module case)\r\n\t * @returns Execution result with any returned values\r\n\t */\r\n\tasync execute(statement: string, actions?: CollectionActions[]): Promise<{ success: boolean; error?: string }> {\r\n\t\tif (this.committed) {\r\n\t\t\treturn { success: false, error: 'Transaction already committed' };\r\n\t\t}\r\n\t\tif (this.rolledBack) {\r\n\t\t\treturn { success: false, error: 'Transaction already rolled back' };\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\t// If actions not provided, enlist engine to translate statement\r\n\t\t\tlet actionsToApply: CollectionActions[];\r\n\t\t\tif (actions) {\r\n\t\t\t\tactionsToApply = actions;\r\n\t\t\t} else {\r\n\t\t\t\t// Create a temporary transaction with just this statement for translation\r\n\t\t\t\tconst tempTransaction: Transaction = {\r\n\t\t\t\t\tstamp: this.stamp,\r\n\t\t\t\t\tstatements: [statement],\r\n\t\t\t\t\treads: [],\r\n\t\t\t\t\tid: 'temp' // Temporary ID for translation only\r\n\t\t\t\t};\r\n\t\t\t\tconst result = await this.engine.execute(tempTransaction);\r\n\t\t\t\tif (!result.success || !result.actions) {\r\n\t\t\t\t\treturn { success: false, error: result.error || 'Failed to translate statement' };\r\n\t\t\t\t}\r\n\t\t\t\tactionsToApply = result.actions;\r\n\t\t\t}\r\n\r\n\t\t\t// Apply actions through coordinator\r\n\t\t\tawait this.coordinator.applyActions(actionsToApply, this.stamp.id);\r\n\r\n\t\t\t// Accumulate the statement for later compilation\r\n\t\t\tthis.statements.push(statement);\r\n\r\n\t\t\treturn { success: true };\r\n\t\t} catch (error) {\r\n\t\t\treturn {\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: `Failed to execute statement: ${error instanceof Error ? error.message : String(error)}`\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Commit the transaction.\r\n\t *\r\n\t * Compiles all statements into a complete Transaction and commits through coordinator.\r\n\t */\r\n\tasync commit(): Promise<ExecutionResult> {\r\n\t\tif (this.committed) {\r\n\t\t\treturn { success: false, error: 'Transaction already committed' };\r\n\t\t}\r\n\t\tif (this.rolledBack) {\r\n\t\t\treturn { success: false, error: 'Transaction already rolled back' };\r\n\t\t}\r\n\r\n\t\t// Create the complete transaction\r\n\t\tconst transaction: Transaction = {\r\n\t\t\tstamp: this.stamp,\r\n\t\t\tstatements: this.statements,\r\n\t\t\treads: [], // TODO: Track reads during statement execution\r\n\t\t\tid: createTransactionId(this.stamp.id, this.statements, [])\r\n\t\t};\r\n\r\n\t\t// Commit through coordinator (which will orchestrate PEND/COMMIT)\r\n\t\tawait this.coordinator.commit(transaction);\r\n\r\n\t\tthis.committed = true;\r\n\t\treturn { success: true };\r\n\t}\r\n\r\n\t/**\r\n\t * Rollback the transaction (discard local state).\r\n\t *\r\n\t * Note: Actions have already been applied to collections' trackers.\r\n\t * Rollback just prevents commit and clears session state.\r\n\t * Collections will discard tracker state when they sync or update.\r\n\t */\r\n\tasync rollback(): Promise<void> {\r\n\t\tif (this.committed) {\r\n\t\t\tthrow new Error('Cannot rollback: transaction already committed');\r\n\t\t}\r\n\t\tif (this.rolledBack) {\r\n\t\t\tthrow new Error('Transaction already rolled back');\r\n\t\t}\r\n\r\n\t\t// Rollback through coordinator\r\n\t\tawait this.coordinator.rollback(this.stamp.id);\r\n\t\tthis.rolledBack = true;\r\n\t\tthis.statements.length = 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Get the transaction stamp ID (stable throughout transaction).\r\n\t */\r\n\tgetStampId(): string {\r\n\t\treturn this.stamp.id;\r\n\t}\r\n\r\n\t/**\r\n\t * Get the transaction stamp (full metadata).\r\n\t */\r\n\tgetStamp(): TransactionStamp {\r\n\t\treturn this.stamp;\r\n\t}\r\n\r\n\t/**\r\n\t * Get the list of accumulated statements.\r\n\t */\r\n\tgetStatements(): readonly string[] {\r\n\t\treturn this.statements;\r\n\t}\r\n\r\n\t/**\r\n\t * Check if the transaction has been committed.\r\n\t */\r\n\tisCommitted(): boolean {\r\n\t\treturn this.committed;\r\n\t}\r\n\r\n\t/**\r\n\t * Check if the transaction has been rolled back.\r\n\t */\r\n\tisRolledBack(): boolean {\r\n\t\treturn this.rolledBack;\r\n\t}\r\n}\r\n\r\n", "import type { BlockId, CollectionId, IBlock, BlockOperations, Transforms, ITransactor } from '../index.js';\r\nimport type { Transaction, ITransactionEngine, ITransactionValidator, ValidationResult, CollectionActions } from './transaction.js';\r\nimport type { Collection } from '../collection/collection.js';\r\nimport { Tracker } from '../transform/tracker.js';\r\nimport { hashString } from '../utility/hash-string.js';\r\n\r\n/**\r\n * Represents an operation on a block within a collection.\r\n * Must match the Operation type in coordinator.ts for consistent hashing.\r\n */\r\ntype Operation =\r\n\t| { readonly type: 'insert'; readonly collectionId: CollectionId; readonly blockId: BlockId; readonly block: IBlock }\r\n\t| { readonly type: 'update'; readonly collectionId: CollectionId; readonly blockId: BlockId; readonly operations: BlockOperations }\r\n\t| { readonly type: 'delete'; readonly collectionId: CollectionId; readonly blockId: BlockId };\r\n\r\n/**\r\n * Engine registration for validation.\r\n */\r\nexport type EngineRegistration = {\r\n\t/** The transaction engine instance */\r\n\tengine: ITransactionEngine;\r\n\t/** Get the current schema hash for this engine */\r\n\tgetSchemaHash: () => Promise<string>;\r\n};\r\n\r\n/**\r\n * Factory function to create a validation coordinator.\r\n * This allows isolated execution of transactions for validation.\r\n */\r\nexport type ValidationCoordinatorFactory = () => {\r\n\t/** Apply actions to collections in isolated state */\r\n\tapplyActions(actions: CollectionActions[], stampId: string): Promise<void>;\r\n\t/** Get all transforms from the validation state */\r\n\tgetTransforms(): Map<CollectionId, Transforms>;\r\n\t/** Dispose of the validation coordinator */\r\n\tdispose(): void;\r\n};\r\n\r\n/**\r\n * Transaction validator implementation.\r\n *\r\n * Validates transactions by re-executing them and comparing operations hash.\r\n * Used by cluster participants when receiving PendRequests.\r\n */\r\nexport class TransactionValidator implements ITransactionValidator {\r\n\tconstructor(\r\n\t\tprivate readonly engines: Map<string, EngineRegistration>,\r\n\t\tprivate readonly createValidationCoordinator: ValidationCoordinatorFactory\r\n\t) {}\r\n\r\n\tasync validate(transaction: Transaction, operationsHash: string): Promise<ValidationResult> {\r\n\t\tconst { stamp, statements } = transaction;\r\n\r\n\t\t// 1. Verify engine exists\r\n\t\tconst registration = this.engines.get(stamp.engineId);\r\n\t\tif (!registration) {\r\n\t\t\treturn {\r\n\t\t\t\tvalid: false,\r\n\t\t\t\treason: `Unknown engine: ${stamp.engineId}`\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\t// 2. Verify schema hash matches\r\n\t\tconst localSchemaHash = await registration.getSchemaHash();\r\n\t\tif (localSchemaHash !== stamp.schemaHash) {\r\n\t\t\treturn {\r\n\t\t\t\tvalid: false,\r\n\t\t\t\treason: `Schema mismatch: local=${localSchemaHash}, sender=${stamp.schemaHash}`\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\t// 3. Verify read dependencies (optimistic concurrency)\r\n\t\t// TODO: Implement read dependency validation\r\n\t\t// For now, we skip this check - will be implemented with proper block versioning\r\n\r\n\t\t// 4. Create isolated validation coordinator\r\n\t\tconst validationCoordinator = this.createValidationCoordinator();\r\n\r\n\t\ttry {\r\n\t\t\t// 5. Re-execute transaction through engine\r\n\t\t\tconst result = await registration.engine.execute(transaction);\r\n\t\t\tif (!result.success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tvalid: false,\r\n\t\t\t\t\treason: `Re-execution failed: ${result.error}`\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\t// 6. Apply actions to validation coordinator (builds transforms)\r\n\t\t\tif (result.actions && result.actions.length > 0) {\r\n\t\t\t\tawait validationCoordinator.applyActions(result.actions, stamp.id);\r\n\t\t\t}\r\n\r\n\t\t\t// 7. Collect operations from validation coordinator\r\n\t\t\tconst transforms = validationCoordinator.getTransforms();\r\n\t\t\tconst allOperations = this.collectOperations(transforms);\r\n\r\n\t\t\t// 8. Compute hash\r\n\t\t\tconst computedHash = this.hashOperations(allOperations);\r\n\r\n\t\t\t// 9. Compare with sender's hash\r\n\t\t\tif (computedHash !== operationsHash) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tvalid: false,\r\n\t\t\t\t\treason: `Operations hash mismatch`,\r\n\t\t\t\t\tcomputedHash\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn { valid: true, computedHash };\r\n\t\t} finally {\r\n\t\t\tvalidationCoordinator.dispose();\r\n\t\t}\r\n\t}\r\n\r\n\tasync getSchemaHash(engineId: string): Promise<string | undefined> {\r\n\t\tconst registration = this.engines.get(engineId);\r\n\t\treturn registration ? await registration.getSchemaHash() : undefined;\r\n\t}\r\n\r\n\t/**\r\n\t * Collect all operations from transforms.\r\n\t */\r\n\tprivate collectOperations(transforms: Map<CollectionId, Transforms>): readonly Operation[] {\r\n\t\treturn Array.from(transforms.entries()).flatMap(([collectionId, t]) => [\r\n\t\t\t...Object.entries(t.inserts ?? {}).map(([blockId, block]) =>\r\n\t\t\t\t({ type: 'insert' as const, collectionId, blockId, block })\r\n\t\t\t),\r\n\t\t\t...Object.entries(t.updates ?? {}).map(([blockId, operations]) =>\r\n\t\t\t\t({ type: 'update' as const, collectionId, blockId, operations })\r\n\t\t\t),\r\n\t\t\t...(t.deletes ?? []).map(blockId =>\r\n\t\t\t\t({ type: 'delete' as const, collectionId, blockId })\r\n\t\t\t)\r\n\t\t]);\r\n\t}\r\n\r\n\t/**\r\n\t * Compute hash of all operations.\r\n\t * Must match TransactionCoordinator.hashOperations for consistent validation.\r\n\t */\r\n\tprivate hashOperations(operations: readonly Operation[]): string {\r\n\t\tconst operationsData = JSON.stringify(operations);\r\n\t\treturn `ops:${hashString(operationsData)}`;\r\n\t}\r\n}\r\n\r\n", "import { sha256 } from 'multiformats/hashes/sha2'\r\nimport type { BlockId } from '../index.js'\r\n\r\nexport async function blockIdToBytes(blockId: BlockId): Promise<Uint8Array> {\r\n const input = new TextEncoder().encode(blockId)\r\n const mh = await sha256.digest(input)\r\n return mh.digest\r\n}\r\n", "/** True if the given object has no keys. This should not be used for classes or objects with proto fields. */\r\nexport function isRecordEmpty<T>(record: Record<string, T>): boolean {\r\n\tfor (const key in record) return false;\r\n\treturn true;\r\n}\r\n", "export class Pending<T> {\r\n\tresponse?: T;\r\n\terror?: unknown;\r\n\tt1 = Date.now();\r\n\tduration?: number;\r\n\r\n\tget isResponse(): boolean {\r\n\t\treturn this.response !== undefined;\r\n\t}\r\n\r\n\tget isError(): boolean {\r\n\t\treturn this.error !== undefined;\r\n\t}\r\n\r\n\tget isComplete(): boolean {\r\n\t\treturn this.isResponse || this.isError;\r\n\t}\r\n\r\n\tasync result(): Promise<T> {\r\n\t\tif (this.isResponse) {\r\n\t\t\treturn this.response!;\r\n\t\t}\r\n\t\tif (this.isError) {\r\n\t\t\tthrow this.error!;\r\n\t\t}\r\n\t\treturn await this.promise;\r\n\t}\r\n\r\n\tconstructor(\r\n\t\tpublic promise: Promise<T>\r\n\t) {\r\n\t\tpromise.then(response => {\r\n\t\t\tthis.duration = Date.now() - this.t1;\r\n\t\t\tthis.response = response;\r\n\t\t\treturn response;\r\n\t\t}, error => {\r\n\t\t\tthis.duration = Date.now() - this.t1;\r\n\t\t\tthis.error = error;\r\n\t\t});\r\n\t}\r\n}\r\n", "import type { PeerId } from \"../network/types.js\";\nimport type { BlockId } from \"../index.js\";\nimport { Pending } from \"./pending.js\";\n\n/**\n * Represents a batch of operations for a specific block coordinated by a peer\n */\nexport type CoordinatorBatch<TPayload, TResponse> = {\n\tpeerId: PeerId;\n\tblockId: BlockId;\n\tpayload: TPayload;\n\trequest?: Pending<TResponse>;\n\t/** Whether this batch has been subsumed by other successful batches */\n\tsubsumedBy?: CoordinatorBatch<TPayload, TResponse>[];\n\t/** Peers that have already been tried (and failed) */\n\texcludedPeers?: PeerId[];\n}\n\n/**\n * Creates batches for a given payload, grouped by the coordinating peer for each block id\n */\nexport function makeBatchesByPeer<TPayload, TResponse>(\n\tblockPeers: (readonly [BlockId, PeerId])[],\n\tpayload: TPayload,\n\tgetBlockPayload: (payload: TPayload, blockId: BlockId, mergeWithPayload: TPayload | undefined) => TPayload,\n\texcludedPeers?: PeerId[]\n): CoordinatorBatch<TPayload, TResponse>[] {\n\tconst groups = blockPeers.reduce((acc, [blockId, peerId]) => {\n\t\tconst peerId_str = peerId.toString();\n\t\tconst coordinator = acc.get(peerId_str) ?? { peerId, blockId, excludedPeers } as Partial<CoordinatorBatch<TPayload, TResponse>>;\n\t\tacc.set(peerId_str, { ...coordinator, payload: getBlockPayload(payload, blockId, coordinator.payload) } as CoordinatorBatch<TPayload, TResponse>);\n\t\treturn acc;\n\t}, new Map<string, CoordinatorBatch<TPayload, TResponse>>());\n\treturn Array.from(groups.values());\n}\n\n/**\n * Iterates over all batches that have not completed, whether subsumed or not\n */\nexport function* incompleteBatches<TPayload, TResponse>(batches: CoordinatorBatch<TPayload, TResponse>[]): IterableIterator<CoordinatorBatch<TPayload, TResponse>> {\n const stack: CoordinatorBatch<TPayload, TResponse>[] = [...batches];\n while (stack.length > 0) {\n const batch = stack.pop()!;\n if (!batch.request || !batch.request.isResponse) {\n yield batch;\n }\n if (batch.subsumedBy && batch.subsumedBy.length) {\n stack.push(...batch.subsumedBy);\n }\n }\n}\n\n/**\n * Checks if all completed batches (ignoring failures) satisfy a predicate\n */\nexport function everyBatch<TPayload, TResponse>(batches: CoordinatorBatch<TPayload, TResponse>[], predicate: (batch: CoordinatorBatch<TPayload, TResponse>) => boolean): boolean {\n // For each root batch require that SOME node in its retry tree satisfies the predicate.\n // Use iterative DFS to avoid recursion depth and minimize allocations.\n for (const root of batches) {\n let found = false;\n const stack: CoordinatorBatch<TPayload, TResponse>[] = [root];\n while (stack.length > 0) {\n const node = stack.pop()!;\n if (predicate(node)) { found = true; break; }\n if (node.subsumedBy && node.subsumedBy.length) {\n for (let i = 0; i < node.subsumedBy.length; i++) stack.push(node.subsumedBy[i]!);\n }\n }\n if (!found) return false;\n }\n return true;\n}\n\n/**\n * Iterates over all batches that satisfy an optional predicate, whether subsumed or not\n */\nexport function* allBatches<TPayload, TResponse>(batches: CoordinatorBatch<TPayload, TResponse>[], predicate?: (batch: CoordinatorBatch<TPayload, TResponse>) => boolean): IterableIterator<CoordinatorBatch<TPayload, TResponse>> {\n const stack: CoordinatorBatch<TPayload, TResponse>[] = [...batches];\n while (stack.length > 0) {\n const batch = stack.pop()!;\n if (!predicate || predicate(batch)) {\n yield batch;\n }\n if (batch.subsumedBy && batch.subsumedBy.length) {\n stack.push(...batch.subsumedBy);\n }\n }\n}\n\n/**\n * Returns a new blockId list payload with the given block id appended\n */\nexport function mergeBlocks(payload: BlockId[], blockId: BlockId, mergeWithPayload: BlockId[] | undefined): BlockId[] {\n\treturn [...(mergeWithPayload ?? []), blockId];\n}\n\n/**\n * Processes a set of batches, retrying any failures until success or expiration\n * @param batches - The batches to process - each represents a group of blocks centered on a coordinating peer\n * @param process - The function to call for a given batch\n * @param getBlockIds - The function to call to get the block ids for a given batch\n * @param getBlockPayload - The function to call to get the payload given a parent payload and block id, and optionally merge with an existing payload\n * @param expiration - The expiration time for the operation\n * @param findCoordinator - The function to call to find a coordinator for a block id\n */\nexport async function processBatches<TPayload, TResponse>(\n\tbatches: CoordinatorBatch<TPayload, TResponse>[],\n\tprocess: (batch: CoordinatorBatch<TPayload, TResponse>) => Promise<TResponse>,\n\tgetBlockIds: (batch: CoordinatorBatch<TPayload, TResponse>) => BlockId[],\n\tgetBlockPayload: (payload: TPayload, blockId: BlockId, mergeWithPayload: TPayload | undefined) => TPayload,\n\texpiration: number,\n\tfindCoordinator: (blockId: BlockId, options: { excludedPeers: PeerId[] }) => Promise<PeerId>\n): Promise<void> {\n // Root-map ensures retries are recorded on the original batch to avoid deep trees\n const rootOf = new WeakMap<CoordinatorBatch<TPayload, TResponse>, CoordinatorBatch<TPayload, TResponse>>();\n for (const b of batches) rootOf.set(b, b);\n\n // Process a set of batches concurrently and enqueue retries flatly onto the root's subsumedBy list\n const processSet = async (set: CoordinatorBatch<TPayload, TResponse>[]) => {\n await Promise.all(set.map(async (batch) => {\n batch.request = new Pending(process(batch)\n .catch(async e => {\n if (expiration > Date.now()) {\n const excludedPeers = [batch.peerId, ...(batch.excludedPeers ?? [])];\n const retries = await createBatchesForPayload<TPayload, TResponse>(\n getBlockIds(batch),\n batch.payload,\n getBlockPayload,\n excludedPeers,\n findCoordinator\n );\n if (retries.length > 0 && expiration > Date.now()) {\n const root = rootOf.get(batch) ?? batch;\n root.subsumedBy = [...(root.subsumedBy ?? []), ...retries];\n for (const r of retries) rootOf.set(r, root);\n // Process retries, but ensure further failures also attach to the same root\n await processSet(retries);\n }\n }\n throw e;\n }));\n }));\n\n // Wait for all in this set to settle\n await Promise.all(set.map(b => b.request?.result().catch(() => { /* ignore */ })));\n };\n\n await processSet(batches);\n}\n\n/**\n * Creates batches for a given payload, grouped by the coordinating peer for each block id\n * This is a placeholder function that will be implemented by the caller\n */\nexport async function createBatchesForPayload<TPayload, TResponse>(\n\tblockIds: BlockId[],\n\tpayload: TPayload,\n\tgetBlockPayload: (payload: TPayload, blockId: BlockId, mergeWithPayload: TPayload | undefined) => TPayload,\n\texcludedPeers: PeerId[],\n\tfindCoordinator: (blockId: BlockId, options: { excludedPeers: PeerId[] }) => Promise<PeerId>\n): Promise<CoordinatorBatch<TPayload, TResponse>[]> {\n\t// Group by block id\n\tconst distinctBlockIds = new Set(blockIds);\n\n\t// Find coordinator for each key\n\tconst blockIdPeerId = await Promise.all(\n\t\tArray.from(distinctBlockIds).map(async (bid) =>\n\t\t\t[bid, await findCoordinator(bid, { excludedPeers })] as const\n\t\t)\n\t);\n\n\t// Group blocks around their coordinating peers\n\treturn makeBatchesByPeer<TPayload, TResponse>(blockIdPeerId, payload, getBlockPayload, excludedPeers);\n}\n", "import { peerIdFromString } from \"../network/types.js\";\r\nimport type { PeerId } from \"../network/types.js\";\r\nimport type { ActionTransforms, ActionBlocks, BlockActionStatus, ITransactor, PendSuccess, StaleFailure, IKeyNetwork, BlockId, GetBlockResults, PendResult, CommitResult, PendRequest, IRepo, BlockGets, Transforms, CommitRequest, ActionId, RepoCommitRequest, ClusterNomineesResult } from \"../index.js\";\r\nimport { transformForBlockId, groupBy, concatTransforms, concatTransform, transformsFromTransform, blockIdsForTransforms } from \"../index.js\";\r\nimport { blockIdToBytes } from \"../utility/block-id-to-bytes.js\";\r\nimport { isRecordEmpty } from \"../utility/is-record-empty.js\";\r\nimport { type CoordinatorBatch, makeBatchesByPeer, incompleteBatches, everyBatch, allBatches, mergeBlocks, processBatches, createBatchesForPayload } from \"../utility/batch-coordinator.js\";\r\n\r\ntype NetworkTransactorInit = {\r\n\ttimeoutMs: number;\r\n\tabortOrCancelTimeoutMs: number;\r\n\tkeyNetwork: IKeyNetwork;\r\n\tgetRepo: (peerId: PeerId) => IRepo;\r\n}\r\n\r\nexport class NetworkTransactor implements ITransactor {\r\n\tprivate readonly keyNetwork: IKeyNetwork;\r\n\tprivate readonly timeoutMs: number;\r\n\tprivate readonly abortOrCancelTimeoutMs: number;\r\n\tprivate readonly getRepo: (peerId: PeerId) => IRepo;\r\n\r\n\tconstructor(\r\n\t\tinit: NetworkTransactorInit,\r\n\t) {\r\n\t\tthis.keyNetwork = init.keyNetwork;\r\n\t\tthis.timeoutMs = init.timeoutMs;\r\n\t\tthis.abortOrCancelTimeoutMs = init.abortOrCancelTimeoutMs;\r\n\t\tthis.getRepo = init.getRepo;\r\n\t}\r\n\r\n\tasync get(blockGets: BlockGets): Promise<GetBlockResults> {\r\n\t\t// Group by block id\r\n\t\tconst distinctBlockIds = Array.from(new Set(blockGets.blockIds));\r\n\r\n\t\tconst batches = await this.batchesForPayload<BlockId[], GetBlockResults>(\r\n\t\t\tdistinctBlockIds,\r\n\t\t\tdistinctBlockIds,\r\n\t\t\t(gets, blockId, mergeWithGets) => [...(mergeWithGets ?? []), ...gets.filter(bid => bid === blockId)],\r\n\t\t\t[]\r\n\t\t);\r\n\r\n\t\tconst expiration = Date.now() + this.timeoutMs;\r\n\r\n\t\tlet error: Error | undefined;\r\n\t\ttry {\r\n\t\t\tawait processBatches(\r\n\t\t\t\tbatches,\r\n\t\t\t\t(batch) => this.getRepo(batch.peerId).get({ blockIds: batch.payload, context: blockGets.context }, { expiration }),\r\n\t\t\t\tbatch => batch.payload,\r\n\t\t\t\t(gets, blockId, mergeWithGets) => [...(mergeWithGets ?? []), ...gets.filter(bid => bid === blockId)],\r\n\t\t\t\texpiration,\r\n\t\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t\t);\r\n\t\t} catch (e) {\r\n\t\t\terror = e as Error;\r\n\t\t}\r\n\r\n\t\t// Second-chance retry: if batch failed to respond OR responded with \"not found\"\r\n\t\t// Different cluster members may have different views; retry with other coordinators\r\n\t\tconst hasValidResponse = (b: CoordinatorBatch<BlockId[], GetBlockResults>) => {\r\n\t\t\treturn b.request?.isResponse === true && b.request.response != null;\r\n\t\t};\r\n\r\n\t\tconst hasBlockInResponse = (b: CoordinatorBatch<BlockId[], GetBlockResults>) => {\r\n\t\t\tif (!hasValidResponse(b)) return false;\r\n\t\t\tconst resp = b.request!.response! as GetBlockResults;\r\n\t\t\treturn b.payload.some(bid => {\r\n\t\t\t\tconst entry = resp[bid];\r\n\t\t\t\treturn entry && typeof entry === 'object' && 'block' in entry && entry.block != null;\r\n\t\t\t});\r\n\t\t};\r\n\r\n\t\t// Retry batches that either failed to respond OR responded with \"not found\"\r\n\t\t// This provides tolerance for different cluster member views\r\n\t\tconst retryable = Array.from(allBatches(batches)).filter(b =>\r\n\t\t\t!hasValidResponse(b as any) || !hasBlockInResponse(b as any)\r\n\t\t) as CoordinatorBatch<BlockId[], GetBlockResults>[];\r\n\r\n\t\tif (retryable.length > 0 && Date.now() < expiration) {\r\n\t\t\ttry {\r\n\t\t\t\tconst excludedByRoot = new Map<CoordinatorBatch<BlockId[], GetBlockResults>, Set<PeerId>>();\r\n\t\t\t\tfor (const b of retryable) {\r\n\t\t\t\t\tconst excluded = new Set<PeerId>([b.peerId, ...((b.excludedPeers ?? []) as PeerId[])]);\r\n\t\t\t\t\texcludedByRoot.set(b, excluded);\r\n\t\t\t\t\tconst retries = await createBatchesForPayload<BlockId[], GetBlockResults>(\r\n\t\t\t\t\t\tb.payload,\r\n\t\t\t\t\t\tb.payload,\r\n\t\t\t\t\t\t(gets, blockId, mergeWithGets) => [...(mergeWithGets ?? []), ...gets.filter(id => id === blockId)],\r\n\t\t\t\t\t\tArray.from(excluded),\r\n\t\t\t\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (retries.length > 0) {\r\n\t\t\t\t\t\tb.subsumedBy = [...(b.subsumedBy ?? []), ...retries];\r\n\t\t\t\t\t\tawait processBatches(\r\n\t\t\t\t\t\t\tretries,\r\n\t\t\t\t\t\t\t(batch) => this.getRepo(batch.peerId).get({ blockIds: batch.payload, context: blockGets.context }, { expiration }),\r\n\t\t\t\t\t\t\tbatch => batch.payload,\r\n\t\t\t\t\t\t\t(gets, blockId, mergeWithGets) => [...(mergeWithGets ?? []), ...gets.filter(id => id === blockId)],\r\n\t\t\t\t\t\t\texpiration,\r\n\t\t\t\t\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\t// keep original error if any\r\n\t\t\t\tif (!error) error = e as Error;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t// Cache the completed batches that had actual responses (not just coordinator not found)\r\n\t\tconst completedBatches = Array.from(allBatches(batches, b => b.request?.isResponse as boolean && !isRecordEmpty(b.request!.response!)));\r\n\r\n\t\t// Create a lookup map from successful responses only\r\n\t\tconst resultEntries = new Map<string, any>();\r\n\t\tfor (const batch of completedBatches) {\r\n\t\t\tconst resp = batch.request!.response! as any;\r\n\t\t\tfor (const [bid, res] of Object.entries(resp)) {\r\n\t\t\t\tconst existing = resultEntries.get(bid);\r\n\t\t\t\t// Prefer responses that include a materialized block\r\n\t\t\t\tconst resHasBlock = res && typeof res === 'object' && 'block' in (res as any) && (res as any).block != null;\r\n\t\t\t\tconst existingHasBlock = existing && typeof existing === 'object' && 'block' in (existing as any) && (existing as any).block != null;\r\n\t\t\t\tif (!existing || (resHasBlock && !existingHasBlock)) {\r\n\t\t\t\t\tresultEntries.set(bid, res);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Ensure we have at least one response per requested block id\r\n\t\tconst missingIds = distinctBlockIds.filter(bid => !resultEntries.has(bid));\r\n\t\tif (missingIds.length > 0) {\r\n\t\t\tconst details = this.formatBatchStatuses(batches,\r\n\t\t\t\tb => (b.request?.isResponse as boolean) ?? false,\r\n\t\t\t\tb => {\r\n\t\t\t\t\tconst status = b.request == null ? 'no-response' : (b.request.isResponse ? 'response' : 'in-flight')\r\n\t\t\t\t\treturn `${b.peerId.toString()}[block:${b.blockId}](${status})`\r\n\t\t\t\t});\r\n\t\t\tconst aggregate = new Error(`Some peers did not complete: ${details}${error ? `; root: ${error.message}` : ''}`);\r\n\t\t\t(aggregate as any).cause = error;\r\n\t\t\tthrow aggregate;\r\n\t\t}\r\n\r\n\t\treturn Object.fromEntries(resultEntries) as GetBlockResults;\r\n\t}\r\n\r\n\tasync getStatus(blockActions: ActionBlocks[]): Promise<BlockActionStatus[]> {\r\n\t\t// Collect all unique block IDs across all action refs\r\n\t\tconst allBlockIds = [...new Set(blockActions.flatMap(ref => ref.blockIds))];\r\n\r\n\t\tif (allBlockIds.length === 0) {\r\n\t\t\treturn blockActions.map(ref => ({ ...ref, statuses: [] }));\r\n\t\t}\r\n\r\n\t\t// Get block states from repos\r\n\t\tconst blockStates = await this.get({ blockIds: allBlockIds });\r\n\r\n\t\t// Determine status for each action ref\r\n\t\treturn blockActions.map(ref => ({\r\n\t\t\t...ref,\r\n\t\t\tstatuses: ref.blockIds.map(blockId => {\r\n\t\t\t\tconst result = blockStates[blockId];\r\n\t\t\t\tif (!result) {\r\n\t\t\t\t\treturn 'aborted';\r\n\t\t\t\t}\r\n\t\t\t\tconst { state } = result;\r\n\t\t\t\tif (state.pendings?.includes(ref.actionId)) {\r\n\t\t\t\t\treturn 'pending';\r\n\t\t\t\t}\r\n\t\t\t\tif (state.latest?.actionId === ref.actionId) {\r\n\t\t\t\t\treturn 'committed';\r\n\t\t\t\t}\r\n\t\t\t\t// Action is neither pending nor the latest committed - consider it aborted\r\n\t\t\t\t// Note: This doesn't check historical commits; a more complete implementation\r\n\t\t\t\t// would need to query the revision history\r\n\t\t\t\treturn 'aborted';\r\n\t\t\t})\r\n\t\t}));\r\n\t}\r\n\r\n\tprivate async consolidateCoordinators(\r\n\t\tblockIds: BlockId[],\r\n\t\ttransforms: Transforms,\r\n\t\ttransformForBlock: (payload: Transforms, blockId: BlockId, mergeWith?: Transforms) => Transforms\r\n\t): Promise<CoordinatorBatch<Transforms, PendResult>[]> {\r\n\t\tconst blockCoordinators = await Promise.all(\r\n\t\t\tblockIds.map(async bid => ({\r\n\t\t\t\tblockId: bid,\r\n\t\t\t\tcoordinator: await this.keyNetwork.findCoordinator(await blockIdToBytes(bid), { excludedPeers: [] })\r\n\t\t\t}))\r\n\t\t);\r\n\r\n\t\tconst byCoordinator = new Map<string, BlockId[]>();\r\n\t\tfor (const { blockId, coordinator } of blockCoordinators) {\r\n\t\t\tconst key = coordinator.toString();\r\n\t\t\tconst blocks = byCoordinator.get(key) ?? [];\r\n\t\t\tblocks.push(blockId);\r\n\t\t\tbyCoordinator.set(key, blocks);\r\n\t\t}\r\n\r\n\t\tconst batches: CoordinatorBatch<Transforms, PendResult>[] = [];\r\n\t\tfor (const [coordinatorStr, consolidatedBlocks] of byCoordinator) {\r\n\t\t\tconst coordinator = blockCoordinators.find(bc => bc.coordinator.toString() === coordinatorStr)!.coordinator;\r\n\r\n\t\t\tlet batchTransforms: Transforms = { inserts: {}, updates: {}, deletes: [] };\r\n\t\t\tfor (const bid of consolidatedBlocks) {\r\n\t\t\t\tconst blockTransforms = transformForBlock(transforms, bid, batchTransforms);\r\n\t\t\t\tbatchTransforms = blockTransforms;\r\n\t\t\t}\r\n\r\n\t\t\tbatches.push({\r\n\t\t\t\tpeerId: coordinator,\r\n\t\t\t\tpayload: batchTransforms,\r\n\t\t\t\tblockId: consolidatedBlocks[0]!,\r\n\t\t\t\tcoordinatingBlockIds: consolidatedBlocks,\r\n\t\t\t\texcludedPeers: []\r\n\t\t\t} as any);\r\n\t\t}\r\n\r\n\t\treturn batches;\r\n\t}\r\n\r\n\tasync pend(blockAction: PendRequest): Promise<PendResult> {\r\n\t\tconst transformForBlock = (payload: Transforms, blockId: BlockId, mergeWithPayload: Transforms | undefined): Transforms => {\r\n\t\t\tconst filteredTransform = transformForBlockId(payload, blockId);\r\n\t\t\treturn mergeWithPayload\r\n\t\t\t\t? concatTransform(mergeWithPayload, blockId, filteredTransform)\r\n\t\t\t\t: transformsFromTransform(filteredTransform, blockId);\r\n\t\t};\r\n\t\tconst blockIds = blockIdsForTransforms(blockAction.transforms);\r\n\t\tconst batches = await this.consolidateCoordinators(blockIds, blockAction.transforms, transformForBlock);\r\n\t\tconst expiration = Date.now() + this.timeoutMs;\r\n\r\n\t\tlet error: Error | undefined;\r\n\t\ttry {\r\n\t\t\t// Process all batches, noting all outstanding peers\r\n\t\t\tawait processBatches(\r\n\t\t\t\tbatches,\r\n\t\t\t\t(batch) => this.getRepo(batch.peerId).pend(\r\n\t\t\t\t\t{ ...blockAction, transforms: batch.payload },\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\texpiration,\r\n\t\t\t\t\t\tcoordinatingBlockIds: (batch as any).coordinatingBlockIds\r\n\t\t\t\t\t} as any\r\n\t\t\t\t),\r\n\t\t\t\tbatch => blockIdsForTransforms(batch.payload),\r\n\t\t\t\ttransformForBlock,\r\n\t\t\t\texpiration,\r\n\t\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t\t);\r\n\t\t\t// Cache resolved coordinators for follow-up commit to hit the same peers\r\n\t\t\ttry {\r\n\t\t\t\tconst pn: any = this.keyNetwork as any;\r\n\t\t\t\tif (typeof pn?.recordCoordinator === 'function') {\r\n\t\t\t\t\tfor (const b of Array.from(allBatches(batches))) {\r\n\t\t\t\t\t\tpn.recordCoordinator(await blockIdToBytes(b.blockId), b.peerId);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} catch (e) { console.warn('Failed to record coordinator hint', e); }\r\n\t\t} catch (e) {\r\n\t\t\terror = e as Error;\r\n\t\t}\r\n\r\n\t\tif (!everyBatch(batches, b => b.request?.isResponse as boolean && b.request!.response!.success)) {\r\n\t\t\tconst details = this.formatBatchStatuses(batches,\r\n\t\t\t\tb => (b.request?.isResponse as boolean && (b.request as any).response?.success) ?? false,\r\n\t\t\t\tb => {\r\n\t\t\t\t\tconst status = b.request == null ? 'no-response' : (b.request.isResponse ? 'non-success' : 'in-flight')\r\n\t\t\t\t\treturn `${b.peerId.toString()}[block:${b.blockId}](${status})`\r\n\t\t\t\t});\r\n\t\t\tconst aggregate = new Error(`Some peers did not complete: ${details}${error ? `; root: ${error.message}` : ''}`);\r\n\t\t\tconst prior = error;\r\n\t\t\t(aggregate as any).cause = prior;\r\n\t\t\t(aggregate as AggregateError).errors = prior ? [prior] : [];\r\n\t\t\terror = aggregate;\r\n\t\t}\r\n\r\n\t\tif (error) { // If any failures, cancel all pending actions as background microtask\r\n\t\t\tvoid Promise.resolve().then(() => this.cancelBatch(batches, { blockIds, actionId: blockAction.actionId }));\r\n\t\t\tconst stale = Array.from(allBatches(batches, b => b.request?.isResponse as boolean && !b.request!.response!.success));\r\n\t\t\tif (stale.length > 0) {\t// Any active stale failures should preempt reporting connection or other potential transient errors (we have information)\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\tmissing: distinctBlockActionTransforms(stale.flatMap(b => (b.request!.response! as StaleFailure).missing).filter((x): x is ActionTransforms => x !== undefined)),\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\tthrow error;\t// No stale failures, report the original error\r\n\t\t}\r\n\r\n\t\t// Collect replies back into result structure\r\n\t\tconst completed = Array.from(allBatches(batches, b => b.request?.isResponse as boolean && b.request!.response!.success));\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\tpending: completed.flatMap(b => (b.request!.response! as PendSuccess).pending),\r\n\t\t\tblockIds: blockIdsForTransforms(blockAction.transforms)\r\n\t\t};\r\n\t}\r\n\r\n\tasync cancel(actionRef: ActionBlocks): Promise<void> {\r\n\t\tconst batches = await this.batchesForPayload<BlockId[], void>(\r\n\t\t\tactionRef.blockIds,\r\n\t\t\tactionRef.blockIds,\r\n\t\t\tmergeBlocks,\r\n\t\t\t[]\r\n\t\t);\r\n\t\tconst expiration = Date.now() + this.abortOrCancelTimeoutMs;\r\n\t\tawait processBatches(\r\n\t\t\tbatches,\r\n\t\t\t(batch) => this.getRepo(batch.peerId).cancel({ actionId: actionRef.actionId, blockIds: batch.payload }, { expiration }),\r\n\t\t\tbatch => batch.payload,\r\n\t\t\tmergeBlocks,\r\n\t\t\texpiration,\r\n\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t);\r\n\t}\r\n\r\n\tasync queryClusterNominees(blockId: BlockId): Promise<ClusterNomineesResult> {\r\n\t\tconst blockIdBytes = await blockIdToBytes(blockId);\r\n\t\tconst clusterPeers = await this.keyNetwork.findCluster(blockIdBytes);\r\n\t\tconst nominees = Object.keys(clusterPeers).map(idStr => peerIdFromString(idStr));\r\n\t\treturn { nominees };\r\n\t}\r\n\r\n\tasync commit(request: CommitRequest): Promise<CommitResult> {\r\n\t\tconst allBlockIds = [...new Set([...request.blockIds, request.tailId])];\r\n\r\n\t\t// Commit the header block if provided and not already in blockIds\r\n\t\tif (request.headerId && !request.blockIds.includes(request.headerId)) {\r\n\t\t\tconst headerResult = await this.commitBlock(request.headerId, allBlockIds, request.actionId, request.rev);\r\n\t\t\tif (!headerResult.success) {\r\n\t\t\t\treturn headerResult;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Commit the tail block\r\n\t\tconst tailResult = await this.commitBlock(request.tailId, allBlockIds, request.actionId, request.rev);\r\n\t\tif (!tailResult.success) {\r\n\t\t\treturn tailResult;\r\n\t\t}\r\n\r\n\t\t// Commit all remaining block ids (excluding tail and header if it was already handled)\r\n\t\tconst remainingBlocks = request.blockIds.filter(bid =>\r\n\t\t\tbid !== request.tailId &&\r\n\t\t\t!(request.headerId && bid === request.headerId && !request.blockIds.includes(request.headerId))\r\n\t\t);\r\n\t\tif (remainingBlocks.length > 0) {\r\n\t\t\tconst { batches, error } = await this.commitBlocks({ blockIds: remainingBlocks, actionId: request.actionId, rev: request.rev });\r\n\t\t\tif (error) {\r\n\t\t\t\t// Non-tail block commit failures should not fail the overall action once the tail has committed.\r\n\t\t\t\t// Proceed and rely on reconciliation paths (e.g. reads with context) to finalize state on lagging peers.\r\n\t\t\t\ttry { console.warn('[NetworkTransactor] non-tail commit had errors; proceeding after tail commit:', error.message); } catch { /* ignore */ }\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn { success: true };\r\n\t}\r\n\r\n\tprivate async commitBlock(blockId: BlockId, blockIds: BlockId[], actionId: ActionId, rev: number): Promise<CommitResult> {\r\n\t\tconst { batches: tailBatches, error: tailError } = await this.commitBlocks({ blockIds: [blockId], actionId, rev });\r\n\t\tif (tailError) {\r\n\t\t\t// Cancel all pending actions as background microtask\r\n\t\t\tPromise.resolve().then(() => this.cancel({ blockIds, actionId }));\r\n\t\t\t// Collect and return any active stale failures\r\n\t\t\tconst stale = Array.from(allBatches(tailBatches, b => b.request?.isResponse as boolean && !b.request!.response!.success));\r\n\t\t\tif (stale.length > 0) {\r\n\t\t\t\treturn { missing: distinctBlockActionTransforms(stale.flatMap(b => (b.request!.response! as StaleFailure).missing!)), success: false as const };\r\n\t\t\t}\r\n\t\t\tthrow tailError;\r\n\t\t}\r\n\t\treturn { success: true };\r\n\t}\r\n\r\n\t/** Attempts to commit a set of blocks, and handles failures and errors */\r\n\tprivate async commitBlocks({ blockIds, actionId, rev }: RepoCommitRequest) {\r\n\t\tconst expiration = Date.now() + this.timeoutMs;\r\n\t\tconst batches = await this.batchesForPayload<BlockId[], CommitResult>(blockIds, blockIds, mergeBlocks, []);\r\n\t\tlet error: Error | undefined;\r\n\t\ttry {\r\n\t\t\tawait processBatches(\r\n\t\t\t\tbatches,\r\n\t\t\t\t(batch) => this.getRepo(batch.peerId).commit({ actionId, blockIds: batch.payload, rev }, { expiration }),\r\n\t\t\t\tbatch => batch.payload,\r\n\t\t\t\tmergeBlocks,\r\n\t\t\t\texpiration,\r\n\t\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t\t);\r\n\t\t} catch (e) {\r\n\t\t\terror = e as Error;\r\n\t\t}\r\n\r\n\t\tif (!everyBatch(batches, b => b.request?.isResponse as boolean && b.request!.response!.success)) {\r\n\t\t\tconst details = this.formatBatchStatuses(batches,\r\n\t\t\t\tb => (b.request?.isResponse as boolean && (b.request as any).response?.success) ?? false,\r\n\t\t\t\tb => {\r\n\t\t\t\t\tconst status = b.request == null ? 'no-response' : (b.request.isResponse ? 'non-success' : 'in-flight')\r\n\t\t\t\t\tconst resp: any = (b.request as any)?.response;\r\n\t\t\t\t\tconst extra = resp && resp.success === false ? (Array.isArray(resp.missing) ? ` missing=${resp.missing.length}` : ' success=false') : '';\r\n\t\t\t\t\treturn `${b.peerId.toString()}[blocks:${b.payload instanceof Array ? (b.payload as any[]).length : 1}](${status})${extra ? ' ' + extra : ''}`\r\n\t\t\t\t});\r\n\t\t\tconst aggregate = new Error(`Some peers did not complete: ${details}${error ? `; root: ${error.message}` : ''}`);\r\n\t\t\t(aggregate as any).cause = error;\r\n\t\t\terror = aggregate;\r\n\t\t}\r\n\t\treturn { batches, error };\r\n\t};\r\n\r\n\t/** Creates batches for a given payload, grouped by the coordinating peer for each block id */\r\n\tprivate async batchesForPayload<TPayload, TResponse>(\r\n\t\tblockIds: BlockId[],\r\n\t\tpayload: TPayload,\r\n\t\tgetBlockPayload: (payload: TPayload, blockId: BlockId, mergeWithPayload: TPayload | undefined) => TPayload,\r\n\t\texcludedPeers: PeerId[]\r\n\t): Promise<CoordinatorBatch<TPayload, TResponse>[]> {\r\n\t\treturn createBatchesForPayload<TPayload, TResponse>(\r\n\t\t\tblockIds,\r\n\t\t\tpayload,\r\n\t\t\tgetBlockPayload,\r\n\t\t\texcludedPeers,\r\n\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t);\r\n\t}\r\n\r\n\t/** Cancels a pending transaction by canceling all blocks associated with the transaction, including failed peers */\r\n\tprivate async cancelBatch<TPayload, TResponse>(\r\n\t\tbatches: CoordinatorBatch<TPayload, TResponse>[],\r\n\t\tactionRef: ActionBlocks,\r\n\t) {\r\n\t\tconst expiration = Date.now() + this.abortOrCancelTimeoutMs;\r\n\t\tconst operationBatches = makeBatchesByPeer(\r\n\t\t\tArray.from(allBatches(batches)).map(b => [b.blockId, b.peerId] as const),\r\n\t\t\tactionRef.blockIds,\r\n\t\t\tmergeBlocks,\r\n\t\t\t[]\r\n\t\t);\r\n\t\tawait processBatches(\r\n\t\t\toperationBatches,\r\n\t\t\t(batch) => this.getRepo(batch.peerId).cancel({ actionId: actionRef.actionId, blockIds: batch.payload }, { expiration }),\r\n\t\t\tbatch => batch.payload,\r\n\t\t\tmergeBlocks,\r\n\t\t\texpiration,\r\n\t\t\tasync (blockId, options) => this.keyNetwork.findCoordinator(await blockIdToBytes(blockId), options)\r\n\t\t);\r\n\t}\r\n\r\n\tprivate formatBatchStatuses<TPayload, TResponse>(\r\n\t\tbatches: CoordinatorBatch<TPayload, TResponse>[],\r\n\t\tisSuccess: (b: CoordinatorBatch<TPayload, TResponse>) => boolean,\r\n\t\tformatter: (b: CoordinatorBatch<TPayload, TResponse>) => string\r\n\t): string {\r\n\t\tconst incompletes = Array.from(incompleteBatches(batches))\r\n\t\tlet details = incompletes.map(formatter).join(', ')\r\n\t\tif (details.length === 0) {\r\n\t\t\tdetails = Array.from(allBatches(batches)).map(formatter).join(', ')\r\n\t\t}\r\n\t\treturn details\r\n\t}\r\n}\r\n\r\n\r\n/**\r\n * Returns the block actions grouped by action id and concatenated transforms\r\n */\r\nexport function distinctBlockActionTransforms(blockActions: ActionTransforms[]): ActionTransforms[] {\r\n\tconst grouped = groupBy(blockActions, ({ actionId }) => actionId);\r\n\treturn Object.entries(grouped).map(([actionId, actions]) =>\r\n\t\t({ actionId, transforms: concatTransforms(...actions.map(t => t.transforms)) } as ActionTransforms));\r\n}\r\n", "import { randomBytes } from '@noble/hashes/utils.js'\r\nimport { toString as uint8ArrayToString } from 'uint8arrays/to-string'\r\nimport type { IBlock, BlockId, BlockHeader, ITransactor, ActionId, StaleFailure, ActionContext, BlockType, BlockSource, Transforms } from \"../index.js\";\r\n\r\nexport class TransactorSource<TBlock extends IBlock> implements BlockSource<TBlock> {\r\n\tconstructor(\r\n\t\tprivate readonly collectionId: BlockId,\r\n\t\tprivate readonly transactor: ITransactor,\r\n\t\tpublic actionContext: ActionContext | undefined,\r\n\t) { }\r\n\r\n\tcreateBlockHeader(type: BlockType, newId?: BlockId): BlockHeader {\r\n\t\treturn {\r\n\t\t\ttype,\r\n\t\t\tid: newId ?? this.generateId(),\r\n\t\t\tcollectionId: this.collectionId,\r\n\t\t};\r\n\t}\r\n\r\n\tgenerateId(): BlockId {\r\n\t\t// 256-bits to fully utilize DHT address space\r\n\t\treturn uint8ArrayToString(randomBytes(32), 'base64url')\r\n\t}\r\n\r\n\tasync tryGet(id: BlockId): Promise<TBlock | undefined> {\r\n\t\tconst result = await this.transactor.get({ blockIds: [id], context: this.actionContext });\r\n\t\tif (result) {\r\n\t\t\tconst { block, state } = result[id]!;\r\n\t\t\t// TODO: if the state reports that there is a pending action, record this so that we are sure to update before syncing\r\n\t\t\t//state.pendings\r\n\t\t\treturn block as TBlock;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Attempts to apply the given transforms in a transactional manner.\r\n\t * @param transform - The transforms to apply.\r\n\t * @param actionId - The action id.\r\n\t * @param rev - The revision number.\r\n\t * @param headerId - The Id of the collection's header block. If specified, this block's transform is performed first,\r\n\t * in the event that there is a race to create the collection itself, or in the event that the tail block is full and\r\n\t * is transitioning to a new block. Ignored if the given headerId is not present in the transforms.\r\n\t * @param tailId - The Id of the collection's log tail block. If specified, this block's transform is performed next\r\n\t * (prior to the rest of the block operations), to resolve the \"winner\" of a race to commit to the collection.\r\n\t * @returns A promise that resolves to undefined if the action is successful, or a StaleFailure if the action is stale.\r\n\t */\r\n\tasync transact(transform: Transforms, actionId: ActionId, rev: number, headerId: BlockId, tailId: BlockId): Promise<undefined | StaleFailure> {\r\n\t\tconst pendResult = await this.transactor.pend({ transforms: transform, actionId, rev, policy: 'r' });\r\n\t\tif (!pendResult.success) {\r\n\t\t\treturn pendResult;\r\n\t\t}\r\n\t\tconst isNew = transform.inserts && Object.hasOwn(transform.inserts, headerId);\r\n\t\tconst commitResult = await this.transactor.commit({\r\n\t\t\theaderId: isNew ? headerId : undefined,\r\n\t\t\ttailId,\r\n\t\t\tblockIds: pendResult.blockIds,\r\n\t\t\tactionId,\r\n\t\t\trev\r\n\t\t});\r\n\t\tif (!commitResult.success) {\r\n\t\t\treturn commitResult;\r\n\t\t}\r\n\t}\r\n}\r\n\r\n", "import type { IBlock, BlockId, BlockStore as IBlockStore, BlockHeader, BlockOperation, BlockType, BlockSource as IBlockSource } from \"../index.js\";\r\nimport { applyOperation, emptyTransforms, blockIdsForTransforms, ensured } from \"../index.js\";\r\n\r\n/** A block store that collects transformations, without applying them to the underlying source.\r\n * Transformations are also applied to the retrieved blocks, making it seem like the source has been modified.\r\n */\r\nexport class Tracker<T extends IBlock> implements IBlockStore<T> {\r\n\tconstructor(\r\n\t\tprivate readonly source: IBlockSource<T>,\r\n\t\t/** The collected set of transformations to be applied. Treat as immutable */\r\n\t\tpublic transforms = emptyTransforms(),\r\n\t) { }\r\n\r\n\tasync tryGet(id: BlockId): Promise<T | undefined> {\r\n\t\tconst block = await this.source.tryGet(id);\r\n\t\tif (block) {\r\n\t\t\tconst ops = this.transforms.updates?.[id] ?? [];\r\n\t\t\tops.forEach(op => applyOperation(block!, op));\r\n\t\t\tif (this.transforms.deletes?.includes(id)) {\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\t\t} else if (this.transforms.inserts && Object.hasOwn(this.transforms.inserts, id)) {\r\n\t\t\treturn structuredClone(this.transforms.inserts[id]) as T;\r\n\t\t}\r\n\r\n\t\treturn block;\r\n\t}\r\n\r\n\tgenerateId(): BlockId {\r\n\t\treturn this.source.generateId();\r\n\t}\r\n\r\n\tcreateBlockHeader(type: BlockType, newId?: BlockId): BlockHeader {\r\n\t\treturn this.source.createBlockHeader(type, newId);\r\n\t}\r\n\r\n\tinsert(block: T) {\r\n\t\tconst inserts = this.transforms.inserts ??= {};\r\n\t\tinserts[block.header.id] = structuredClone(block);\r\n\t\tconst deletes = this.transforms.deletes;\r\n\t\tconst deleteIndex = deletes?.indexOf(block.header.id) ?? -1;\r\n\t\tif (deleteIndex >= 0) {\r\n\t\t\tdeletes!.splice(deleteIndex, 1);\r\n\t\t}\r\n\t}\r\n\r\n\tupdate(blockId: BlockId, op: BlockOperation) {\r\n\t\tconst inserted = this.transforms.inserts?.[blockId];\r\n\t\tif (inserted) {\r\n\t\t\tapplyOperation(inserted, op);\r\n\t\t} else {\r\n\t\t\tconst updates = this.transforms.updates ??= {};\r\n\t\t\tensured(updates, blockId, () => []).push(structuredClone(op));\r\n\t\t}\r\n\t}\r\n\r\n\tdelete(blockId: BlockId) {\r\n\t\tif (this.transforms.inserts) delete this.transforms.inserts[blockId];\r\n\t\tif (this.transforms.updates) delete this.transforms.updates[blockId];\r\n\t\tconst deletes = this.transforms.deletes ??= [];\r\n\t\tdeletes.push(blockId);\r\n\t}\r\n\r\n\treset(newTransform = emptyTransforms()) {\r\n\t\tconst oldTransform = this.transforms;\r\n\t\tthis.transforms = newTransform;\r\n\t\treturn oldTransform;\r\n\t}\r\n\r\n\ttransformedBlockIds(): BlockId[] {\r\n\t\treturn Array.from(new Set(blockIdsForTransforms(this.transforms)));\r\n\t}\r\n\r\n\tconflicts(blockIds: Set<BlockId>) {\r\n\t\treturn this.transformedBlockIds().filter(id => blockIds.has(id));\r\n\t}\r\n}\r\n", "import { Tracker } from \"./tracker.js\";\r\nimport type { IBlock, BlockStore } from \"../index.js\";\r\nimport { applyTransformToStore } from \"./helpers.js\";\r\n\r\nexport class Atomic<TBlock extends IBlock> extends Tracker<TBlock> {\r\n\tconstructor(public readonly store: BlockStore<TBlock>) {\r\n\t\tsuper(store);\r\n\t}\r\n\r\n\tcommit() {\r\n\t\tconst transform = this.reset();\r\n\t\tapplyTransformToStore(transform, this.store);\r\n\t}\r\n\r\n\t// rollback = reset\r\n}\r\n", "import type { IBlock, BlockHeader, BlockId, BlockSource, BlockType, Transforms } from \"../index.js\";\r\nimport { applyOperation } from \"../index.js\";\r\n\r\nexport class CacheSource<T extends IBlock> implements BlockSource<T> {\r\n\tprotected cache = new Map<BlockId, T>();\r\n\r\n\tconstructor(\r\n\t\tprotected readonly source: BlockSource<T>\r\n\t) { }\r\n\r\n\tasync tryGet(id: BlockId): Promise<T | undefined> {\r\n\t\tlet block = this.cache.get(id);\r\n\t\tif (!block) {\r\n\t\t\tblock = await this.source.tryGet(id);\r\n\t\t\tif (block) {\r\n\t\t\t\tthis.cache.set(id, block);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn structuredClone(block);\r\n\t}\r\n\r\n\tgenerateId(): BlockId {\r\n\t\treturn this.source.generateId();\r\n\t}\r\n\r\n\tcreateBlockHeader(type: BlockType, newId?: BlockId): BlockHeader {\r\n\t\treturn this.source.createBlockHeader(type, newId);\r\n\t}\r\n\r\n\tclear(blockIds: BlockId[] | undefined = undefined) {\r\n\t\tif (blockIds) {\r\n\t\t\tfor (const id of blockIds) {\r\n\t\t\t\tthis.cache.delete(id);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.cache.clear();\r\n\t\t}\r\n\t}\r\n\r\n\t/** Mutates the cache without affecting the source */\r\n\ttransformCache(transform: Transforms) {\r\n\t\tfor (const blockId of transform.deletes ?? []) {\r\n\t\t\tthis.cache.delete(blockId);\r\n\t\t}\r\n\t\tfor (const [, block] of Object.entries(transform.inserts ?? {})) {\r\n\t\t\tthis.cache.set(block.header.id, structuredClone(block) as T);\r\n\t\t}\r\n\t\tfor (const [blockId, operations] of Object.entries(transform.updates ?? {})) {\r\n\t\t\tfor (const op of operations) {\r\n\t\t\t\tconst block = this.cache.get(blockId);\r\n\t\t\t\tif (block) {\r\n\t\t\t\t\tapplyOperation(block, op);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n", "// TODO: replace the usage of this with Object.groupBy in newer ES once more pervasive\r\n\r\n/**\r\n * Groups an array of items by a key selector function.\r\n * @param array - The array of items to group.\r\n * @param keySelector - The function that selects the key for each item.\r\n * @returns An object where each key is a unique value from the key selector function, and each value is an array of items that have that key.\r\n */\r\nexport function groupBy<T, K extends string | number | symbol>(\r\n\tarray: T[],\r\n\tkeySelector: (item: T) => K\r\n): Record<K, T[]> {\r\n\treturn array.reduce((acc, item) => {\r\n\t\tconst key = keySelector(item);\r\n\t\t(acc[key] ??= []).push(item);\r\n\t\treturn acc;\r\n\t}, {} as Record<K, T[]>);\r\n}\r\n", "// Retrieves a value from a record, generating an entry if none exists\r\nexport function ensured<K extends string | number | symbol, V>(\r\n\tmap: Record<K, V>,\r\n\tkey: K,\r\n\tmakeNew: () => Exclude<V, undefined>,\r\n\texisting?: (existing: Exclude<V, undefined>) => void\r\n): Exclude<V, undefined> {\r\n\tlet v = map[key];\r\n\tif (typeof v === 'undefined') {\r\n\t\tv = makeNew();\r\n\t\tmap[key] = v;\r\n\t} else if (existing) {\r\n\t\texisting(v as Exclude<V, undefined>);\r\n\t}\r\n\treturn v as Exclude<V, undefined>;\r\n}\r\n\r\nexport function ensuredMap<K extends string | number | symbol, V>(\r\n\tmap: Map<K, V>,\r\n\tkey: K,\r\n\tmakeNew: () => Exclude<V, undefined>,\r\n\texisting?: (existing: Exclude<V, undefined>) => void\r\n): Exclude<V, undefined> {\r\n\tlet v = map.get(key);\r\n\tif (typeof v === 'undefined') {\r\n\t\tv = makeNew();\r\n\t\tmap.set(key, v);\r\n\t} else if (existing) {\r\n\t\texisting(v as Exclude<V, undefined>);\r\n\t}\r\n\treturn v as Exclude<V, undefined>;\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["actions_engine_exports", "__export", "ACTIONS_ENGINE_ID", "ActionsEngine", "createActionsStatements", "collections", "c", "init_actions_engine", "__esmMin", "coordinator", "transaction", "allActions", "statement", "collectionActions", "error", "index_exports", "__export", "ACTIONS_ENGINE_ID", "ActionsEngine", "Atomic", "BTree", "CacheSource", "Chain", "Collection", "Diary", "DiaryHeaderBlockType", "EntriesPerBlock", "KeyBound", "KeyRange", "Keyset", "Latches", "Log", "LogDataBlockType", "LogHeaderBlockType", "NetworkTransactor", "NodeCapacity", "Path", "PathBranch", "Pending", "Tracker", "TransactionContext", "TransactionCoordinator", "TransactionSession", "TransactionValidator", "TransactorSource", "Tree", "TreeHeaderBlockType", "apply", "applyOperation", "applyOperations", "applyTransform", "applyTransformToStore", "blockIdToBytes", "blockIdsForTransforms", "concatTransform", "concatTransforms", "copyTransforms", "createActionsStatements", "createTransactionId", "createTransactionStamp", "distinctBlockActionTransforms", "emptyTransforms", "ensured", "ensuredMap", "entryAt", "get", "groupBy", "hashString", "isTransformsEmpty", "mergeTransforms", "nameof", "pathValid", "peerIdFromString", "priorHash$", "registerBlockType", "rootId$", "transformForBlockId", "transformsFromTransform", "withOperation", "blockTypes", "registerBlockType", "blockType", "name", "applyOperation", "block", "entity", "index", "deleteCount", "inserted", "applyOperations", "operations", "op", "withOperation", "source", "blockIdsForTransforms", "transforms", "insertIds", "updateIds", "deleteIds", "emptyTransforms", "copyTransforms", "transform", "updates", "k", "v", "mergeTransforms", "a", "b", "isTransformsEmpty", "concatTransforms", "acc", "m", "transformForBlockId", "blockId", "transformsFromTransform", "applyTransformToStore", "store", "applyTransform", "concatTransform", "get", "store", "id", "block", "apply", "op", "applyOperation", "nameof", "key1", "key2", "TreeLeafBlockType", "registerBlockType", "TreeBranchBlockType", "entries$", "nameof", "partitions$", "nodes$", "NodeCapacity", "BTree", "_BTree", "store", "trunk", "keyFromEntry", "entry", "compare", "a", "b", "newLeafNode", "createTrunk", "newId", "root", "key", "path", "range", "startPath", "endPath", "endKey", "iter", "ascendingFactor", "newEntry", "result", "getUpdated", "newKey", "id", "from", "newPath", "node", "TreeLeafBlockType", "leaf", "on", "index", "Path", "branch", "get", "PathBranch", "entries", "lo", "hi", "split", "keys", "popCount", "found", "last", "opening", "oldKey", "apply", "entries$", "pathBranch", "newRoot", "branchIndex", "newBranch", "newBranchNode", "count", "midIndex", "newEntries", "newLeaf", "Split", "splitIndex", "partitions$", "nodes$", "newPartitions", "newNodes", "delta", "newPartition", "depth", "parent", "pIndex", "pNode", "rightSibId", "rightSib", "leftSibId", "leftSib", "rightKey", "pKey", "nodeIndex", "nodeOffset", "TreeBranchBlockType", "subNodes", "subNode", "right", "indexDelta", "partitions", "nodes", "KeyBound", "key", "inclusive", "KeyRange", "first", "last", "isAscending", "Keyset", "BTree", "PathBranch", "_PathBranch", "node", "index", "Path", "_Path", "branches", "leafNode", "leafIndex", "on", "version", "path", "b", "entries$", "nameof", "priorId$", "nextId$", "ChainDataBlockType", "registerBlockType", "headId$", "tailId$", "ChainHeaderBlockType", "EntriesPerBlock", "Chain", "_Chain", "store", "id", "options", "tailBlock", "headerBlock", "ChainHeaderBlockType", "ChainDataBlockType", "headerAny", "apply", "headId$", "tailId$", "entries", "path", "oldTail", "tail", "trx", "Atomic", "copied", "entries$", "newTail", "nextId$", "entry", "pathValid", "index", "block", "n", "result", "removed", "oldHead", "head", "priorId$", "starting", "forward", "priorBlock", "header", "entryAt", "randomBytes", "bytesLength", "cr", "base10_exports", "__export", "base10", "empty", "equals", "aa", "bb", "ii", "coerce", "o", "fromString", "str", "toString", "b", "base", "ALPHABET", "name", "BASE_MAP", "j", "i", "x", "xc", "BASE", "LEADER", "FACTOR", "iFACTOR", "encode", "source", "zeroes", "length", "pbegin", "pend", "size", "b58", "carry", "it1", "it2", "str", "decodeUnsafe", "psz", "b256", "it3", "it4", "vch", "decode", "string", "buffer", "src", "_brrp__multiformats_scope_baseX", "base_x_default", "Encoder", "name", "prefix", "baseEncode", "bytes", "Decoder", "baseDecode", "prefixCodePoint", "text", "decoder", "or", "ComposedDecoder", "decoders", "input", "left", "right", "Codec", "from", "encode", "decode", "baseX", "alphabet", "base_x_default", "coerce", "string", "alphabetIdx", "bitsPerChar", "end", "out", "bits", "buffer", "written", "i", "value", "data", "pad", "mask", "createAlphabetIdx", "rfc4648", "base10", "baseX", "base16_exports", "__export", "base16", "base16upper", "base16", "rfc4648", "base16upper", "base2_exports", "__export", "base2", "base2", "rfc4648", "base256emoji_exports", "__export", "base256emoji", "alphabet", "alphabetBytesToChars", "p", "c", "i", "alphabetCharsToBytes", "codePoint", "encode", "data", "decode", "str", "byts", "char", "byt", "base256emoji", "from", "base32_exports", "__export", "base32", "base32hex", "base32hexpad", "base32hexpadupper", "base32hexupper", "base32pad", "base32padupper", "base32upper", "base32z", "base32", "rfc4648", "base32upper", "base32pad", "base32padupper", "base32hex", "base32hexupper", "base32hexpad", "base32hexpadupper", "base32z", "base36_exports", "__export", "base36", "base36upper", "base36", "baseX", "base36upper", "base58_exports", "__export", "base58btc", "base58flickr", "base58btc", "baseX", "base58flickr", "base64_exports", "__export", "base64", "base64pad", "base64url", "base64urlpad", "base64", "rfc4648", "base64pad", "base64url", "base64urlpad", "base8_exports", "__export", "base8", "base8", "rfc4648", "identity_exports", "__export", "identity", "identity", "from", "buf", "toString", "str", "fromString", "textEncoder", "textDecoder", "identity_exports", "__export", "identity", "encode_1", "encode", "MSB", "REST", "MSBALL", "INT", "num", "out", "offset", "oldOffset", "decode", "read", "MSB$1", "REST$1", "buf", "res", "shift", "counter", "b", "l", "N1", "N2", "N3", "N4", "N5", "N6", "N7", "N8", "N9", "length", "value", "varint", "_brrp_varint", "varint_default", "decode", "data", "offset", "varint_default", "encodeTo", "int", "target", "encodingLength", "create", "code", "digest", "size", "sizeOffset", "encodingLength", "digestOffset", "bytes", "encodeTo", "Digest", "decode", "multihash", "coerce", "equals", "a", "b", "data", "code", "name", "encode", "coerce", "digest", "input", "options", "create", "identity", "sha2_browser_exports", "__export", "sha256", "sha512", "DEFAULT_MIN_DIGEST_LENGTH", "from", "name", "code", "encode", "minDigestLength", "maxDigestLength", "Hasher", "input", "options", "result", "createDigest", "digest", "truncate", "create", "sha", "name", "data", "sha256", "from", "sha512", "format", "link", "base", "bytes", "version", "toStringV0", "baseCache", "base58btc", "toStringV1", "base32", "cache", "baseCache", "cid", "CID", "_CID", "version", "code", "multihash", "bytes", "DAG_PB_CODE", "SHA_256_CODE", "digest", "create", "other", "self", "unknown", "equals", "base", "format", "input", "value", "encodeCID", "cidSymbol", "decode", "remainder", "specs", "prefixSize", "multihashBytes", "coerce", "digestBytes", "Digest", "initialBytes", "offset", "next", "i", "length", "codec", "multihashCode", "digestSize", "size", "multihashSize", "source", "prefix", "parseCIDtoBytes", "decoder", "base58btc", "base32", "base36", "toStringV0", "toStringV1", "codeOffset", "encodingLength", "hashOffset", "encodeTo", "bases", "identity_exports", "base2_exports", "base8_exports", "base10_exports", "base16_exports", "base32_exports", "base36_exports", "base58_exports", "base64_exports", "base256emoji_exports", "hashes", "sha2_browser_exports", "allocUnsafe", "size", "createCodec", "name", "prefix", "encode", "decode", "string", "buf", "str", "ascii", "i", "allocUnsafe", "BASES", "bases", "bases_default", "toString", "array", "encoding", "base", "bases_default", "Latches", "key", "currentTail", "resolveNewTail", "newTail", "resolve", "PendingRetryDelayMs", "Collection", "_Collection", "id", "transactor", "handlers", "source", "sourceCache", "tracker", "filterConflict", "init", "TransactorSource", "CacheSource", "Tracker", "log", "Log", "headerBlock", "actions", "release", "Latches", "atomic", "Atomic", "action", "handler", "actionContext", "latest", "anyConflicts", "entry", "p", "bytes", "randomBytes", "actionId", "toString", "isTransformsEmpty", "pending", "snapshot", "copyTransforms", "newRev", "addResult", "staleFailure", "resolve", "transforms", "forward", "potential", "replacement", "Diary", "_Diary", "collection", "network", "id", "init", "action", "trx", "store", "DiaryHeaderBlockType", "Collection", "data", "forward", "entry", "DiaryHeaderBlockType", "registerBlockType", "TreeHeaderBlockType", "registerBlockType", "rootId$", "nameof", "CollectionTrunk", "store", "collectionId", "get", "node", "header", "apply", "rootId$", "Tree", "_Tree", "collection", "btree", "network", "id", "keyFromEntry", "entry", "compare", "a", "b", "init", "actions", "trx", "key", "store", "rootId", "BTree", "s", "r", "CollectionTrunk", "TreeHeaderBlockType", "Collection", "data", "path", "range", "from", "empty", "encode_1", "encode", "MSB", "REST", "MSBALL", "INT", "num", "out", "offset", "oldOffset", "decode", "read", "MSB$1", "REST$1", "buf", "res", "shift", "counter", "b", "l", "N1", "N2", "N3", "N4", "N5", "N6", "N7", "N8", "N9", "length", "value", "varint", "_brrp_varint", "varint_default", "encodeTo", "int", "target", "offset", "varint_default", "encodingLength", "create", "code", "digest", "size", "sizeOffset", "encodingLength", "digestOffset", "bytes", "encodeTo", "Digest", "Digest", "code", "size", "digest", "bytes", "DEFAULT_MIN_DIGEST_LENGTH", "from", "name", "code", "encode", "minDigestLength", "maxDigestLength", "Hasher", "input", "options", "result", "createDigest", "digest", "truncate", "create", "sha", "name", "data", "sha256", "from", "sha512", "priorHash$", "nameof", "Log", "_Log", "chain", "store", "id", "Chain", "newId", "actions", "actionId", "rev", "getBlockIds", "collectionIds", "timestamp", "entry", "tailPath", "entryWithBlockIds", "pendings", "checkpoint", "startRev", "entries", "checkpointPath", "path", "entryAt", "starting", "forward", "lastPath", "actionPath", "newTail", "oldTail", "hash", "sha256", "toString", "LogDataBlockType", "LogHeaderBlockType", "peerIdFromString", "id", "other", "hashString", "str", "hash", "i", "createTransactionStamp", "peerId", "timestamp", "schemaHash", "engineId", "stampData", "id", "hashString", "createTransactionId", "stampId", "statements", "reads", "txData", "init_actions_engine", "init_actions_engine", "TransactionCoordinator", "transactor", "collections", "actions", "stampId", "collectionId", "collectionActions", "collection", "action", "taggedAction", "transaction", "collectionData", "transforms", "collectionTransforms", "criticalBlocks", "log", "Log", "tailPath", "allOperations", "blockId", "block", "operations", "operationsHash", "coordResult", "_stampId", "operationsData", "hashString", "context", "statements", "createActionsStatements", "reads", "stamp", "createTransactionStamp", "createTransactionId", "ActionsEngine", "engine", "result", "actionResults", "allCollectionIds", "ca", "applyResult", "actionId", "newRev", "addResult", "blockIdsForTransforms", "criticalBlockIds", "superclusterNominees", "pendResult", "commitResult", "nomineePromises", "acc", "nominee", "pendedBlockIds", "nominees", "rev", "pendRequest", "blockIds", "logTailBlockId", "commitRequest", "TransactionContext", "coordinator", "transactionId", "engine", "collectionId", "action", "taggedAction", "collection", "read", "TransactionSession", "coordinator", "engine", "peerId", "schemaHash", "createTransactionStamp", "statement", "actions", "actionsToApply", "tempTransaction", "result", "error", "transaction", "createTransactionId", "TransactionValidator", "engines", "createValidationCoordinator", "transaction", "operationsHash", "stamp", "statements", "registration", "localSchemaHash", "validationCoordinator", "result", "transforms", "allOperations", "computedHash", "engineId", "collectionId", "t", "blockId", "block", "operations", "operationsData", "hashString", "blockIdToBytes", "blockId", "input", "sha256", "isRecordEmpty", "record", "key", "Pending", "promise", "response", "error", "makeBatchesByPeer", "blockPeers", "payload", "getBlockPayload", "excludedPeers", "groups", "acc", "blockId", "peerId", "peerId_str", "coordinator", "incompleteBatches", "batches", "stack", "batch", "everyBatch", "predicate", "root", "found", "node", "allBatches", "mergeBlocks", "mergeWithPayload", "processBatches", "process", "getBlockIds", "expiration", "findCoordinator", "rootOf", "b", "processSet", "set", "Pending", "e", "retries", "createBatchesForPayload", "r", "blockIds", "distinctBlockIds", "blockIdPeerId", "bid", "NetworkTransactor", "init", "blockGets", "distinctBlockIds", "batches", "gets", "blockId", "mergeWithGets", "bid", "expiration", "error", "processBatches", "batch", "options", "blockIdToBytes", "e", "hasValidResponse", "b", "hasBlockInResponse", "resp", "entry", "retryable", "allBatches", "excludedByRoot", "excluded", "retries", "createBatchesForPayload", "id", "completedBatches", "isRecordEmpty", "resultEntries", "res", "existing", "resHasBlock", "existingHasBlock", "details", "status", "aggregate", "blockActions", "allBlockIds", "ref", "blockStates", "result", "state", "blockIds", "transforms", "transformForBlock", "blockCoordinators", "byCoordinator", "coordinator", "key", "blocks", "coordinatorStr", "consolidatedBlocks", "bc", "batchTransforms", "blockAction", "payload", "mergeWithPayload", "filteredTransform", "transformForBlockId", "concatTransform", "transformsFromTransform", "blockIdsForTransforms", "pn", "everyBatch", "prior", "stale", "distinctBlockActionTransforms", "x", "actionRef", "mergeBlocks", "blockIdBytes", "clusterPeers", "idStr", "peerIdFromString", "request", "headerResult", "tailResult", "remainingBlocks", "actionId", "rev", "tailBatches", "tailError", "extra", "getBlockPayload", "excludedPeers", "operationBatches", "makeBatchesByPeer", "isSuccess", "formatter", "incompleteBatches", "grouped", "groupBy", "actions", "concatTransforms", "t", "TransactorSource", "collectionId", "transactor", "actionContext", "type", "newId", "toString", "randomBytes", "id", "result", "block", "state", "transform", "actionId", "rev", "headerId", "tailId", "pendResult", "isNew", "commitResult", "Tracker", "source", "transforms", "emptyTransforms", "id", "block", "op", "applyOperation", "type", "newId", "inserts", "deletes", "deleteIndex", "blockId", "inserted", "updates", "ensured", "newTransform", "oldTransform", "blockIdsForTransforms", "blockIds", "Atomic", "Tracker", "store", "transform", "applyTransformToStore", "CacheSource", "source", "id", "block", "type", "newId", "blockIds", "transform", "blockId", "operations", "op", "applyOperation", "groupBy", "array", "keySelector", "acc", "item", "key", "ensured", "map", "key", "makeNew", "existing", "v", "ensuredMap"]
7
- }