@dxos/merkle-search-tree 0.8.4-main.67995b8 → 0.8.4-main.72ec0f3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +4 -8
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +4 -8
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/lww-tree.d.ts.map +1 -1
- package/dist/types/src/mirror-multi-map.d.ts +1 -1
- package/dist/types/src/mirror-multi-map.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/forest.test.ts +1 -1
- package/src/lww-tree.test.ts +1 -1
- package/src/lww-tree.ts +1 -1
- package/src/mirror-multi-map.test.ts +1 -0
- package/src/mirror-multi-map.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/common.ts", "../../../src/forest.ts", "../../../src/lww-tree.ts", "../../../src/mirror-multi-map.ts", "../../../src/testing.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { arrayToHex } from '@dxos/util';\n\nexport type ActorID = string & { __ActorID: never };\n\nexport type Item = {\n key: string;\n value: Uint8Array;\n digest: Uint8Array;\n};\n\nexport const makeItem = async (key: string, value: Uint8Array): Promise<Item> => {\n const keyBytes = textEncoder.encode(key);\n const data = new Uint8Array(keyBytes.length + value.length);\n data.set(keyBytes, 0);\n data.set(value, keyBytes.length);\n const digest = await crypto.subtle.digest({ name: 'SHA-256' }, data);\n return {\n key,\n value,\n digest: new Uint8Array(digest),\n };\n};\n\n/**\n * The level the item is placed at is determined as the number of leading zeroes in the item's digest in a given base.\n *\n * This function is hardcoded to use base 16.\n *\n * Example:\n * XXXXXXXX - level 0\n * 0XXXXXXX - level 1\n * 00XXXXXX - level 2\n */\nexport const getLevel = (digest: Uint8Array): number => {\n let level = 0;\n for (let i = 0; i < digest.length; i++) {\n const byte = digest[i];\n // left nibble\n if (byte >> 4 === 0) {\n level++;\n } else {\n break;\n }\n // right nibble\n if ((byte & 0x0f) === 0) {\n level++;\n } else {\n break;\n }\n }\n return level;\n};\n\nexport const formatDigest = (digest: Uint8Array) => {\n return arrayToHex(digest.buffer);\n};\n\nexport const getLevelHex = (digest: string): number => {\n let level = 0;\n for (let i = 0; i < digest.length; i++) {\n if (digest[i] === '0') {\n level++;\n } else {\n break;\n }\n }\n return level;\n};\n\nexport const digestEquals = (a: Uint8Array, b: Uint8Array) => {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\nconst textEncoder = new TextEncoder();\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { arrayToHex, arraysEqual } from '@dxos/util';\n\nimport { formatDigest, getLevelHex } from './common';\n\nexport class Forest {\n #nodes = new Map<DigestHex, Node>();\n\n itemHashOps = 0;\n nodeHashOps = 0;\n\n async createTree(pairs: Iterable<Pair>): Promise<DigestHex> {\n const items = await Promise.all([...pairs].map(([key, value]) => makeItem(key, value)));\n this.itemHashOps += items.length;\n items.sort((a, b) => (a.key < b.key ? -1 : 1));\n // Check for repetition.\n for (let i = 0; i < items.length; i++) {\n if (i + 1 < items.length && items[i].key === items[i + 1].key) {\n throw new Error('Duplicate key');\n }\n }\n\n if (items.length === 0) {\n return this.#makeNode(0, [], []);\n }\n\n // # 0 0 1 0 0 2 1 0 1 0\n // 0 [0 0] 1 [0 0] 2 1 [0] 1 [0]\n // 1 [[0 0] 1 [0 0]] 2 [1 [0] 1 [0]]\n // 2 [[[0 0] 1 [0 0]] 2 [1 [0] 1 [0]]]\n\n const buildLevel = async (level: number, from: number, to: number): Promise<DigestHex> => {\n invariant(level >= 0);\n if (level === 0) {\n return this.#makeNode(0, items.slice(from, to), []);\n }\n\n let rangeBegin = from;\n const childItems: Item[] = [];\n const childNodes: DigestHex[] = [];\n for (let i = from; i < to; i++) {\n if (items[i].level > level) {\n throw new Error('BUG - Node level is higher then expected');\n }\n if (items[i].level === level) {\n const node = await buildLevel(level - 1, rangeBegin, i);\n childNodes.push(node);\n childItems.push(items[i]);\n rangeBegin = i + 1;\n }\n }\n childNodes.push(await buildLevel(level - 1, rangeBegin, to));\n\n return this.#makeNode(level, childItems, childNodes);\n };\n\n const maxLevel = Math.max(...items.map((item) => item.level));\n const root = await buildLevel(maxLevel, 0, items.length);\n return root;\n }\n\n async get(root: DigestHex, key: string): Promise<GetResult<Uint8Array>> {\n const keyLevel = await getKeyLevel(key);\n\n let node = this.#nodes.get(root);\n\n if (node !== undefined && node.level < keyLevel) {\n return { kind: 'missing' };\n }\n\n while (node !== undefined) {\n if (node.level === keyLevel) {\n // TODO(dmaretskyi): Binary search.\n for (let i = 0; i < node.items.length; i++) {\n if (node.items[i].key === key) {\n return { kind: 'present', value: node.items[i].value };\n }\n }\n return { kind: 'missing' };\n } else {\n // TODO(dmaretskyi): Binary search.\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n if (node.items[i].key > key) {\n // Descend down one level.\n node = this.#nodes.get(node.children[i]);\n found = true;\n break;\n }\n }\n if (!found) {\n invariant(node!.level > 0);\n node = this.#nodes.get(node!.children[node!.items.length]);\n }\n }\n }\n return { kind: 'not-available' };\n }\n\n async merge(digest1: DigestHex, digest2: DigestHex, mergeFn: MergeFn): Promise<DigestHex> {\n // console.log(`merge ${digest1.slice(0, 8)} ${digest2.slice(0, 8)}`)\n if (digest1 === digest2) {\n return digest1;\n }\n\n const node1 = this.#requireNode(digest1);\n const node2 = this.#requireNode(digest2);\n\n if (node2.level < node1.level) {\n return await this.merge(digest1, await this.#makeNode(node2.level + 1, [], [digest2]), mergeFn);\n } else if (node1.level < node2.level) {\n return await this.merge(await this.#makeNode(node1.level + 1, [], [digest1]), digest2, mergeFn);\n }\n\n invariant(node1.level === node2.level);\n\n // # B # | D | # E # F # H # | K | #\n // # A # | D | # G # | K | # L #\n //\n\n const resultItems: Item[] = [];\n const resultChildren: DigestHex[] = [];\n\n let carry1: DigestHex | null = null;\n let carry2: DigestHex | null = null;\n\n for (let i1 = 0, i2 = 0; i1 < node1.items.length || i2 < node2.items.length; undefined) {\n invariant(i1 <= node1.items.length);\n invariant(i2 <= node2.items.length);\n\n const key1 = i1 < node1.items.length ? node1.items[i1].key : null;\n const key2 = i2 < node2.items.length ? node2.items[i2].key : null;\n invariant(key1 !== null || key2 !== null);\n\n const child1 = carry1 !== null ? carry1 : node1.children[i1];\n const child2 = carry2 !== null ? carry2 : node2.children[i2];\n if (node1.level > 0) {\n invariant(validDigest(child1));\n invariant(validDigest(child2));\n }\n\n if (key1 === key2) {\n if (node1.level > 0) {\n resultChildren.push(await this.merge(child1, child2, mergeFn));\n }\n resultItems.push(await this.#mergeItem(mergeFn, node1.items[i1], node2.items[i2]));\n carry1 = null;\n carry2 = null;\n i1++;\n i2++;\n } else if (key2 !== null && (key1 === null || key1 > key2)) {\n // Split first.\n invariant(key2 !== null);\n\n resultItems.push(await this.#mergeItem(mergeFn, null, node2.items[i2]));\n\n if (node1.level > 0) {\n const [left, right] = await this.#splitAtKey(child1, key2);\n resultChildren.push(await this.merge(left, child2, mergeFn));\n carry1 = right;\n carry2 = null;\n }\n i2++;\n } else {\n // Split second.\n invariant(key1 !== null);\n\n resultItems.push(await this.#mergeItem(mergeFn, node1.items[i1], null));\n\n if (node1.level > 0) {\n const [left, right] = await this.#splitAtKey(child2, key1);\n resultChildren.push(await this.merge(child1, left, mergeFn));\n carry1 = null;\n carry2 = right;\n }\n i1++;\n }\n }\n if (node1.level > 0) {\n const child1 = carry1 !== null ? carry1 : node1.children[node1.items.length];\n const child2 = carry2 !== null ? carry2 : node2.children[node2.items.length];\n resultChildren.push(await this.merge(child1, child2, mergeFn));\n }\n\n return await this.#makeNode(node1.level, resultItems, resultChildren);\n }\n\n async setBatch(root: DigestHex, pairs: Iterable<Pair>): Promise<DigestHex> {\n const newTree = await this.createTree(pairs);\n return await this.merge(root, newTree, async (key, value1, value2) => (value2 !== null ? value2 : value1!));\n }\n\n async set(root: DigestHex, key: Key, value: Uint8Array): Promise<DigestHex> {\n return this.setBatch(root, [[key, value]]);\n }\n\n *missingNodes(digest: DigestHex): Iterable<DigestHex> {\n const node = this.#nodes.get(digest);\n if (!node) {\n yield digest;\n } else {\n for (const child of node.children) {\n yield* this.missingNodes(child);\n }\n }\n }\n\n async insertNodes(nodes: Iterable<NodeData>): Promise<DigestHex[]> {\n const result: DigestHex[] = [];\n for (const node of nodes) {\n const items = await Promise.all(node.items.map((item) => makeItem(item.key, item.value)));\n // Validation.\n const { digest } = await makeNode(node.level, items, node.children);\n invariant(digest === node.digest);\n\n this.#nodes.set(node.digest, {\n level: node.level,\n digest: node.digest,\n items,\n children: node.children,\n });\n result.push(node.digest);\n }\n return result;\n }\n\n async getNodes(digests: Iterable<DigestHex>): Promise<NodeData[]> {\n const result: NodeData[] = [];\n\n for (const digest of digests) {\n const node = this.#nodes.get(digest);\n if (!node) {\n continue;\n }\n result.push({\n level: node.level,\n digest: node.digest,\n items: node.items.map((item) => ({\n key: item.key,\n value: item.value,\n })),\n children: node.children,\n });\n }\n\n return result;\n }\n\n treeMut(root: DigestHex): TreeMut {\n return new TreeMut(this, root);\n }\n\n formatToString(digest: DigestHex, { pad = 0 }: { pad?: number } = {}): string {\n const padStr = ' '.repeat(pad);\n\n const node = this.#nodes.get(digest);\n if (!node) {\n return `${padStr} o (${digest.slice(0, 8)}) NOT AVAILABLE`;\n }\n\n let string = `${padStr} o (${digest.slice(0, 8)}) level=${node.level} size=${node.items.length}\\n`;\n for (let i = 0; i < node.items.length; i++) {\n if (node.level > 0) {\n string += this.formatToString(node.children[i], { pad: pad + 1 });\n }\n string += `${padStr} - [${node.items[i].itemDigest.slice(0, 8)}] level=${node.items[i].level} ${node.items[i].key.slice(0, 10)} -> ${arrayToHex(node.items[i].value.slice(0, 10).buffer)} \\n`;\n }\n if (node.level > 0) {\n string += this.formatToString(node.children[node.items.length], { pad: pad + 1 });\n }\n return string;\n }\n\n /**\n * Items iterator ordered by key.\n */\n *items(digest: DigestHex): Iterable<Item> {\n const node = this.#requireNode(digest);\n for (let i = 0; i < node.items.length; i++) {\n if (node.level > 0) {\n yield* this.items(node.children[i]);\n }\n yield node.items[i];\n }\n if (node.level > 0) {\n yield* this.items(node.children[node.items.length]);\n }\n }\n\n #requireNode(digest: DigestHex): Node {\n invariant(validDigest(digest));\n const node = this.#nodes.get(digest);\n if (!node) {\n throw new Error(`Node not available: ${digest}`);\n }\n return node;\n }\n\n async #mergeItem(mergeFn: MergeFn, item1: Item | null, item2: Item | null): Promise<Item> {\n invariant(item1 !== null || item2 !== null);\n const key = (item1?.key ?? item2?.key)!;\n\n if (item1 !== null && item2 !== null && arraysEqual(item1.value, item2.value)) {\n return item1;\n } else {\n const mergeResult = await mergeFn(key, item1?.value ?? null, item2?.value ?? null);\n // console.log(\n // `mergeFn ${key.slice(0, 10)} ${String(item1 ? arrayToHex(item1.value).slice(0, 10) : null).padStart(10)} ${String(item2 ? arrayToHex(item2.value).slice(0, 10) : null).padStart(10)} -> ${arrayToHex(mergeResult).slice(0, 10)}`,\n // );\n\n if (item1 !== null && arraysEqual(item1.value, mergeResult)) {\n return item1;\n } else if (item2 !== null && arraysEqual(item2.value, mergeResult)) {\n return item2;\n } else {\n this.itemHashOps++;\n return await makeItem(key, mergeResult);\n }\n }\n }\n\n #emptyNodeCache?: Promise<Node> = undefined;\n async #makeNode(level: number, items: Item[], children: DigestHex[]): Promise<DigestHex> {\n invariant(level > 0 ? items.length + 1 === children.length : children.length === 0);\n\n let node: Node;\n if (level === 0 && items.length === 0) {\n node = await (this.#emptyNodeCache ??= makeNode(0, [], []));\n } else {\n node = await makeNode(level, items, children);\n this.nodeHashOps++;\n }\n if (!this.#nodes.has(node.digest)) {\n this.#nodes.set(node.digest, node);\n }\n return node.digest;\n }\n\n async #splitAtKey(digest: DigestHex, key: Key): Promise<[left: DigestHex, right: DigestHex]> {\n const node = this.#requireNode(digest);\n\n let splitIndex = node.items.length;\n for (let i = 0; i < node.items.length; i++) {\n if (node.items[i].key === key) {\n return [\n await this.#makeNode(node.level, node.items.slice(0, i), node.children.slice(0, i + 1)),\n await this.#makeNode(node.level, node.items.slice(i + 1), node.children.slice(i + 2)),\n ];\n }\n\n if (node.items[i].key > key) {\n splitIndex = i;\n break;\n }\n }\n\n if (node.level === 0) {\n if (splitIndex === 0) {\n return [await this.#makeNode(0, [], []), digest];\n } else if (splitIndex === node.items.length) {\n return [digest, await this.#makeNode(0, [], [])];\n }\n return [\n await this.#makeNode(node.level, node.items.slice(0, splitIndex), []),\n await this.#makeNode(node.level, node.items.slice(splitIndex), []),\n ];\n } else {\n const [left, right] = await this.#splitAtKey(node.children[splitIndex], key);\n\n return [\n await this.#makeNode(node.level, node.items.slice(0, splitIndex), [\n ...node.children.slice(0, splitIndex),\n left,\n ]),\n await this.#makeNode(node.level, node.items.slice(splitIndex), [right, ...node.children.slice(splitIndex + 1)]),\n ];\n }\n }\n}\n\nexport class TreeMut {\n readonly #forest: Forest;\n #root: DigestHex;\n\n constructor(forest: Forest, root: DigestHex) {\n this.#forest = forest;\n this.#root = root;\n }\n\n get root() {\n return this.#root;\n }\n\n async get(key: string): Promise<GetResult<Uint8Array>> {\n return this.#forest.get(this.#root, key);\n }\n\n async setBatch(pairs: Iterable<Pair>): Promise<void> {\n this.#root = await this.#forest.setBatch(this.#root, pairs);\n }\n\n async set(key: Key, value: Uint8Array): Promise<void> {\n this.#root = await this.#forest.set(this.#root, key, value);\n }\n\n items(): Iterable<Item> {\n return this.#forest.items(this.root);\n }\n}\n\nexport type Key = string;\n\nexport type DigestHex = string & { __digestHex: true };\n\nexport type Pair = readonly [key: Key, value: Uint8Array];\n\nexport type GetResult<T> =\n | {\n kind: 'present';\n value: T;\n }\n | {\n kind: 'missing';\n }\n | {\n kind: 'not-available';\n };\n\nexport type MergeFn = (key: string, value1: Uint8Array | null, value2: Uint8Array | null) => Promise<Uint8Array>;\n\nexport type NodeData = {\n readonly level: number;\n\n readonly digest: DigestHex;\n /**\n * Sorted by key\n */\n readonly items: readonly ItemData[];\n /**\n * {items.length + 1} child digests.\n */\n readonly children: readonly DigestHex[];\n};\n\nexport type ItemData = {\n readonly key: string;\n readonly value: Uint8Array;\n};\n\n/**\n * A Merkle-Search Tree node.\n * Contains variable number of items (key-value pairs).\n * Contains {items.length + 1} child nodes.\n * All items, including the ones in interleaving child nodes, are ordered base on the key.\n *\n * Items : (0) (1) (3)\n * Children: [0] [1] [2] [3]\n */\ntype Node = {\n readonly level: number;\n\n readonly digest: DigestHex;\n\n /**\n * Sorted by key\n */\n readonly items: readonly Item[];\n /**\n * {items.length + 1} child digests.\n */\n readonly children: readonly DigestHex[];\n};\n\nconst makeNode = async (level: number, items: readonly Item[], children: readonly DigestHex[]): Promise<Node> => {\n invariant(level > 0 ? items.length + 1 === children.length : children.length === 0);\n\n // TODO(dmaretskyi): Hashing spec.\n const nodeInputData = textEncoder.encode(items.map((item) => item.itemDigest).join('') + children.join(''));\n const digest = await crypto.subtle.digest({ name: 'SHA-256' }, nodeInputData);\n return {\n level,\n digest: formatDigest(new Uint8Array(digest)) as DigestHex,\n items,\n children,\n };\n};\n\ntype Item = {\n readonly level: number;\n readonly key: string;\n readonly value: Uint8Array;\n readonly keyDigest: DigestHex;\n readonly itemDigest: DigestHex;\n};\n\nconst makeItem = async (key: string, value: Uint8Array): Promise<Item> => {\n invariant(typeof key === 'string');\n invariant(value !== null);\n // TODO(dmaretskyi): Hashing spec.\n const keyBytes = textEncoder.encode(key);\n const keyDigest = await crypto.subtle.digest({ name: 'SHA-256' }, keyBytes);\n const keyDigestHex = formatDigest(new Uint8Array(keyDigest)) as DigestHex;\n\n const data = new Uint8Array(keyBytes.length + value.length);\n data.set(keyBytes, 0);\n data.set(value, keyBytes.length);\n const itemDigest = await crypto.subtle.digest({ name: 'SHA-256' }, data);\n return {\n level: getLevelHex(keyDigestHex),\n key,\n value,\n keyDigest: keyDigestHex,\n itemDigest: formatDigest(new Uint8Array(itemDigest)) as DigestHex,\n };\n};\n\nconst getKeyLevel = async (key: string): Promise<number> => {\n const keyBytes = textEncoder.encode(key);\n const keyDigest = await crypto.subtle.digest({ name: 'SHA-256' }, keyBytes);\n\n const keyDigestHex = formatDigest(new Uint8Array(keyDigest)) as DigestHex;\n\n return getLevelHex(keyDigestHex);\n};\n\nconst textEncoder = new TextEncoder();\n\nconst validDigest = (digest: DigestHex) => typeof digest === 'string' && digest.length > 0;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { ActorID } from './common';\nimport { Forest, type DigestHex, type Key, type NodeData } from './forest';\n\nexport type LLWTreeParams = {\n actor: ActorID;\n};\n\n/**\n * Replicated Key-Value Store with Last-Write-Wins semantics.\n */\nexport class LWWTree<T> {\n static async new<T>(params: LLWTreeParams): Promise<LWWTree<T>> {\n const tree = new LWWTree<T>(params);\n tree.#currentRoot = await tree.#forest.createTree([]);\n\n return tree;\n }\n\n #actor: ActorID;\n\n #forest = new Forest();\n\n #currentRoot!: DigestHex;\n\n get currentRoot() {\n return this.#currentRoot;\n }\n\n private constructor(params: LLWTreeParams) {\n this.#actor = params.actor;\n }\n\n async get(key: Key): Promise<T | undefined> {\n const data = await this.#getData(key);\n return data?.value;\n }\n\n async setBatch(pairs: [Key, T][]): Promise<void> {\n const prevDataBatch = await Promise.all(pairs.map(([key]) => this.#getData(key)));\n const updates = pairs.map(([key, value], i) => {\n const prevData = prevDataBatch[i];\n const newClock: VersionClock = !prevData\n ? ([this.#actor, 0] as const)\n : ([this.#actor, prevData.clock[1] + 1] as const);\n const data = this.#encode({ clock: newClock, value });\n\n return [key, data] as const;\n });\n this.#currentRoot = await this.#forest.setBatch(this.#currentRoot, updates);\n }\n\n async set(key: Key, value: T): Promise<void> {\n await this.setBatch([[key, value]]);\n }\n\n async receiveSyncMessage(state: LWWTreeSyncState, message: LWWTreeSyncMessage): Promise<LWWTreeSyncState> {\n await this.#forest.insertNodes(message.nodes);\n\n const remoteRoot = message.root ?? state.remoteRoot;\n\n if (remoteRoot !== null) {\n const missing = [...(await this.#forest.missingNodes(remoteRoot))];\n if (missing.length === 0) {\n this.#currentRoot = await this.#forest.merge(remoteRoot, this.#currentRoot, this.#merge.bind(this));\n } else if (state.remoteRoot !== null && state.remoteRoot !== remoteRoot) {\n // If we're missing nodes from the new remote root, but we have the previous remote root, we can try to merge.\n const missingFromPrevRoot = [...(await this.#forest.missingNodes(state.remoteRoot))];\n if (missingFromPrevRoot.length === 0) {\n await this.#forest.merge(state.remoteRoot, this.#currentRoot, this.#merge.bind(this));\n\n const missing = [...(await this.#forest.missingNodes(remoteRoot))];\n if (missing.length === 0) {\n this.#currentRoot = await this.#forest.merge(remoteRoot, this.#currentRoot, this.#merge.bind(this));\n }\n }\n }\n }\n\n return {\n remoteRoot,\n remoteWant: message.want,\n needsAck: message.nodes.length > 0,\n };\n }\n\n async generateSyncMessage(state: LWWTreeSyncState): Promise<[LWWTreeSyncState, LWWTreeSyncMessage | null]> {\n if (state.remoteRoot === this.#currentRoot && state.remoteWant.length === 0 && !state.needsAck) {\n return [state, null];\n }\n\n const nodes = await this.#forest.getNodes(state.remoteWant);\n const want = state.remoteRoot === null ? [] : [...(await this.#forest.missingNodes(state.remoteRoot))];\n\n return [\n {\n remoteRoot: state.remoteRoot,\n remoteWant: state.remoteWant,\n needsAck: false,\n },\n {\n root: this.#currentRoot,\n want,\n nodes,\n },\n ];\n }\n\n async #getData(key: Key): Promise<ValueData<T> | undefined> {\n const res = await this.#forest.get(this.#currentRoot, key);\n switch (res.kind) {\n case 'present': {\n return this.#decode(res.value);\n }\n\n case 'missing':\n return undefined;\n case 'not-available':\n throw new Error('Key not available');\n }\n }\n\n async #merge(key: Key, left: Uint8Array | null, right: Uint8Array | null): Promise<Uint8Array> {\n if (!left) {\n return right!;\n }\n if (!right) {\n return left!;\n }\n\n const leftData = this.#decode(left);\n const rightData = this.#decode(right);\n\n const cmp =\n leftData.clock[1] === rightData.clock[1]\n ? leftData.clock[0].localeCompare(rightData.clock[0])\n : leftData.clock[1] - rightData.clock[1];\n if (cmp >= 0) {\n return left;\n } else {\n return right;\n }\n }\n\n #decode(value: Uint8Array): ValueData<T> {\n return JSON.parse(textDecoder.decode(value));\n }\n\n #encode(data: ValueData<T>): Uint8Array {\n const { clock, value } = data;\n return textEncoder.encode(JSON.stringify({ clock, value })); // Field order ensures consistent hashing.\n }\n}\n\nexport type LWWTreeSyncMessage = {\n root: DigestHex | null;\n want: DigestHex[];\n nodes: NodeData[];\n};\n\nexport type LWWTreeSyncState = {\n remoteRoot: DigestHex | null;\n remoteWant: DigestHex[];\n needsAck: boolean;\n};\n\nexport const initLWWTreeSyncState = (): LWWTreeSyncState => ({ remoteRoot: null, remoteWant: [], needsAck: false });\n\ntype VersionClock = readonly [actor: ActorID, version: number];\n\ntype ValueData<T> = {\n clock: VersionClock;\n value: T;\n};\n\nconst textDecoder = new TextDecoder();\nconst textEncoder = new TextEncoder();\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { arraysEqual } from '@dxos/util';\n\nimport type { ActorID } from './common';\nimport { Forest, type DigestHex, type Key, type NodeData } from './forest';\n\nexport type MirrorMultiMapParams = {\n actor: ActorID;\n};\n\n/**\n * Replicated tree where each actor's state is tracked separately.\n * Sync is optimized for the case where each actor has a similar state.\n * Actors are expected to eventually converge to the same state.\n */\nexport class MirrorMultiMap<T> {\n static async new<T>(params: MirrorMultiMapParams): Promise<MirrorMultiMap<T>> {\n const tree = new MirrorMultiMap<T>(params);\n tree.#currentRoot = await tree.#forest.createTree([]);\n\n return tree;\n }\n\n #forest = new Forest();\n\n #actor: ActorID;\n #currentRoot!: DigestHex;\n\n #remoteStates = new Map<ActorID, SyncState>();\n\n private constructor(params: MirrorMultiMapParams) {\n this.#actor = params.actor;\n }\n\n get localActorId(): ActorID {\n return this.#actor;\n }\n\n get currentRoot(): DigestHex {\n return this.#currentRoot;\n }\n\n get forest(): Forest {\n return this.#forest;\n }\n\n async getLocal(key: Key): Promise<T | undefined> {\n const entry = await this.#forest.get(this.#currentRoot, key);\n switch (entry?.kind) {\n case 'present':\n return this.#decode(entry.value);\n case 'missing':\n return undefined;\n case 'not-available':\n throw new Error('Unexpected local entry not available');\n }\n }\n\n async setLocalBatch(pairs: (readonly [Key, T])[]): Promise<void> {\n const updates = pairs.map(([key, value]) => [key, this.#encode(value)] as const);\n this.#currentRoot = await this.#forest.setBatch(this.#currentRoot, updates);\n }\n\n async getFor(actorId: ActorID, key: Key): Promise<T | undefined> {\n const state = this.#remoteStates.get(actorId);\n if (!state) {\n throw new Error(`Unknown actorId: ${actorId}`);\n }\n if (!state.remoteRoot) {\n return undefined;\n }\n\n const entry = await this.#forest.get(state.remoteRoot, key);\n switch (entry?.kind) {\n case 'present':\n return this.#decode(entry.value);\n case 'missing':\n return undefined;\n case 'not-available':\n throw new Error('Unexpected remote entry not available');\n }\n }\n\n async setForBatch(actorId: ActorID, pairs: [Key, T][]): Promise<void> {\n const remoteState = this.#remoteStates.get(actorId) ?? initSyncState();\n const updates = pairs.map(([key, value]) => [key, this.#encode(value)] as const);\n const prevRoot = remoteState.remoteRoot ?? (await this.#forest.createTree([]));\n const nextRoot = await this.#forest.setBatch(prevRoot, updates);\n\n this.#remoteStates.set(actorId, {\n remoteRoot: nextRoot,\n myRoot: null,\n remoteWant: remoteState.remoteWant,\n needsAck: remoteState.needsAck,\n });\n }\n\n async getAll(key: Key): Promise<Map<ActorID, T | undefined>> {\n const result = new Map<ActorID, T | undefined>();\n result.set(this.#actor, await this.getLocal(key));\n for (const [actorId, _state] of this.#remoteStates) {\n result.set(actorId, await this.getFor(actorId, key));\n }\n return result;\n }\n\n async getDifferent(): Promise<Map<Key, Map<ActorID, T | undefined>>> {\n // TODO(dmaretskyi): This could be optimized to not traverse nodes that have equal hashes.\n\n const resultByKey = new Map<Key, Map<ActorID, Uint8Array>>();\n\n const actors = new Set<ActorID>([this.#actor, ...this.#remoteStates.keys()]);\n for (const actor of actors) {\n let root;\n if (actor === this.#actor) {\n root = this.#currentRoot;\n } else {\n root = this.#remoteStates.get(actor)?.remoteRoot;\n }\n\n if (!root) {\n continue;\n }\n for (const item of this.#forest.items(root)) {\n let subMap = resultByKey.get(item.key);\n if (!subMap) {\n subMap = new Map();\n resultByKey.set(item.key, subMap);\n }\n subMap.set(actor, item.value);\n }\n }\n\n const result = new Map<Key, Map<ActorID, T | undefined>>();\n\n for (const [key, subMap] of resultByKey) {\n const first = subMap.values().next().value!;\n let allEqual = subMap.size === actors.size;\n if (allEqual) {\n for (const value of subMap.values()) {\n if (!arraysEqual(first, value)) {\n allEqual = false;\n break;\n }\n }\n }\n\n if (!allEqual) {\n const resultSubMap = new Map<ActorID, T | undefined>();\n for (const [actorId, value] of subMap) {\n resultSubMap.set(actorId, this.#decode(value));\n }\n result.set(key, resultSubMap);\n }\n }\n\n return result;\n }\n\n clearActorState(actorId: ActorID): void {\n this.#remoteStates.delete(actorId);\n }\n\n async receiveSyncMessage(actorId: ActorID, message: MirrorMultiMapSyncMessage): Promise<void> {\n await this.#forest.insertNodes(message.nodes);\n\n const state = this.#remoteStates.get(actorId) ?? initSyncState();\n const remoteRoot = message.root ?? state.remoteRoot;\n\n const newState: SyncState = {\n remoteRoot,\n myRoot: message.remoteRoot ?? state.myRoot,\n remoteWant: message.want,\n needsAck: message.nodes.length > 0,\n };\n this.#remoteStates.set(actorId, newState);\n }\n\n async generateSyncMessage(actorId: ActorID): Promise<MirrorMultiMapSyncMessage | null> {\n const state = this.#remoteStates.get(actorId) ?? initSyncState();\n\n if (state.myRoot === this.#currentRoot && state.remoteWant.length === 0 && !state.needsAck) {\n return null;\n }\n\n const nodes = await this.#forest.getNodes(state.remoteWant);\n const want = state.remoteRoot === null ? [] : [...(await this.#forest.missingNodes(state.remoteRoot))];\n\n this.#remoteStates.set(actorId, {\n remoteRoot: state.remoteRoot,\n myRoot: state.myRoot,\n remoteWant: state.remoteWant,\n needsAck: false,\n });\n\n return {\n root: this.#currentRoot,\n remoteRoot: state.remoteRoot,\n want,\n nodes,\n };\n }\n\n #decode(value: Uint8Array): T {\n return JSON.parse(textDecoder.decode(value));\n }\n\n #encode(data: T): Uint8Array {\n return textEncoder.encode(JSON.stringify(data)); // Field order ensures consistent hashing.\n }\n}\n\nexport type MirrorMultiMapSyncMessage = {\n root: DigestHex | null;\n remoteRoot: DigestHex | null;\n want: DigestHex[];\n nodes: NodeData[];\n};\n\ntype SyncState = {\n remoteRoot: DigestHex | null;\n myRoot: DigestHex | null;\n remoteWant: DigestHex[];\n needsAck: boolean;\n};\n\nconst initSyncState = (): SyncState => ({ remoteRoot: null, myRoot: null, remoteWant: [], needsAck: false });\n\nconst textDecoder = new TextDecoder();\nconst textEncoder = new TextEncoder();\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const createValue = (source: string) => new Uint8Array(textEncoder.encode(source));\n\nconst textEncoder = new TextEncoder();\n\nexport const randomKey = () => crypto.randomUUID();\n\nexport const randomSample = <T>(data: T[], count: number) => data.toSorted(() => Math.random() - 0.5).slice(0, count);\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["arrayToHex", "makeItem", "key", "value", "keyBytes", "textEncoder", "encode", "data", "Uint8Array", "length", "set", "digest", "crypto", "subtle", "name", "getLevel", "level", "i", "byte", "formatDigest", "arrayToHex", "buffer", "getLevelHex", "digestEquals", "a", "b", "TextEncoder", "invariant", "arrayToHex", "arraysEqual", "Forest", "Map", "itemHashOps", "nodeHashOps", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { arrayToHex } from '@dxos/util';\n\nexport type ActorID = string & { __ActorID: never };\n\nexport type Item = {\n key: string;\n value: Uint8Array;\n digest: Uint8Array;\n};\n\nexport const makeItem = async (key: string, value: Uint8Array): Promise<Item> => {\n const keyBytes = textEncoder.encode(key);\n const data = new Uint8Array(keyBytes.length + value.length);\n data.set(keyBytes, 0);\n data.set(value, keyBytes.length);\n const digest = await crypto.subtle.digest({ name: 'SHA-256' }, data);\n return {\n key,\n value,\n digest: new Uint8Array(digest),\n };\n};\n\n/**\n * The level the item is placed at is determined as the number of leading zeroes in the item's digest in a given base.\n *\n * This function is hardcoded to use base 16.\n *\n * Example:\n * XXXXXXXX - level 0\n * 0XXXXXXX - level 1\n * 00XXXXXX - level 2\n */\nexport const getLevel = (digest: Uint8Array): number => {\n let level = 0;\n for (let i = 0; i < digest.length; i++) {\n const byte = digest[i];\n // left nibble\n if (byte >> 4 === 0) {\n level++;\n } else {\n break;\n }\n // right nibble\n if ((byte & 0x0f) === 0) {\n level++;\n } else {\n break;\n }\n }\n return level;\n};\n\nexport const formatDigest = (digest: Uint8Array) => {\n return arrayToHex(digest.buffer);\n};\n\nexport const getLevelHex = (digest: string): number => {\n let level = 0;\n for (let i = 0; i < digest.length; i++) {\n if (digest[i] === '0') {\n level++;\n } else {\n break;\n }\n }\n return level;\n};\n\nexport const digestEquals = (a: Uint8Array, b: Uint8Array) => {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\nconst textEncoder = new TextEncoder();\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { arrayToHex, arraysEqual } from '@dxos/util';\n\nimport { formatDigest, getLevelHex } from './common';\n\nexport class Forest {\n #nodes = new Map<DigestHex, Node>();\n\n itemHashOps = 0;\n nodeHashOps = 0;\n\n async createTree(pairs: Iterable<Pair>): Promise<DigestHex> {\n const items = await Promise.all([...pairs].map(([key, value]) => makeItem(key, value)));\n this.itemHashOps += items.length;\n items.sort((a, b) => (a.key < b.key ? -1 : 1));\n // Check for repetition.\n for (let i = 0; i < items.length; i++) {\n if (i + 1 < items.length && items[i].key === items[i + 1].key) {\n throw new Error('Duplicate key');\n }\n }\n\n if (items.length === 0) {\n return this.#makeNode(0, [], []);\n }\n\n // # 0 0 1 0 0 2 1 0 1 0\n // 0 [0 0] 1 [0 0] 2 1 [0] 1 [0]\n // 1 [[0 0] 1 [0 0]] 2 [1 [0] 1 [0]]\n // 2 [[[0 0] 1 [0 0]] 2 [1 [0] 1 [0]]]\n\n const buildLevel = async (level: number, from: number, to: number): Promise<DigestHex> => {\n invariant(level >= 0);\n if (level === 0) {\n return this.#makeNode(0, items.slice(from, to), []);\n }\n\n let rangeBegin = from;\n const childItems: Item[] = [];\n const childNodes: DigestHex[] = [];\n for (let i = from; i < to; i++) {\n if (items[i].level > level) {\n throw new Error('BUG - Node level is higher then expected');\n }\n if (items[i].level === level) {\n const node = await buildLevel(level - 1, rangeBegin, i);\n childNodes.push(node);\n childItems.push(items[i]);\n rangeBegin = i + 1;\n }\n }\n childNodes.push(await buildLevel(level - 1, rangeBegin, to));\n\n return this.#makeNode(level, childItems, childNodes);\n };\n\n const maxLevel = Math.max(...items.map((item) => item.level));\n const root = await buildLevel(maxLevel, 0, items.length);\n return root;\n }\n\n async get(root: DigestHex, key: string): Promise<GetResult<Uint8Array>> {\n const keyLevel = await getKeyLevel(key);\n\n let node = this.#nodes.get(root);\n\n if (node !== undefined && node.level < keyLevel) {\n return { kind: 'missing' };\n }\n\n while (node !== undefined) {\n if (node.level === keyLevel) {\n // TODO(dmaretskyi): Binary search.\n for (let i = 0; i < node.items.length; i++) {\n if (node.items[i].key === key) {\n return { kind: 'present', value: node.items[i].value };\n }\n }\n return { kind: 'missing' };\n } else {\n // TODO(dmaretskyi): Binary search.\n let found = false;\n for (let i = 0; i < node.items.length; i++) {\n if (node.items[i].key > key) {\n // Descend down one level.\n node = this.#nodes.get(node.children[i]);\n found = true;\n break;\n }\n }\n if (!found) {\n invariant(node!.level > 0);\n node = this.#nodes.get(node!.children[node!.items.length]);\n }\n }\n }\n return { kind: 'not-available' };\n }\n\n async merge(digest1: DigestHex, digest2: DigestHex, mergeFn: MergeFn): Promise<DigestHex> {\n // console.log(`merge ${digest1.slice(0, 8)} ${digest2.slice(0, 8)}`)\n if (digest1 === digest2) {\n return digest1;\n }\n\n const node1 = this.#requireNode(digest1);\n const node2 = this.#requireNode(digest2);\n\n if (node2.level < node1.level) {\n return await this.merge(digest1, await this.#makeNode(node2.level + 1, [], [digest2]), mergeFn);\n } else if (node1.level < node2.level) {\n return await this.merge(await this.#makeNode(node1.level + 1, [], [digest1]), digest2, mergeFn);\n }\n\n invariant(node1.level === node2.level);\n\n // # B # | D | # E # F # H # | K | #\n // # A # | D | # G # | K | # L #\n //\n\n const resultItems: Item[] = [];\n const resultChildren: DigestHex[] = [];\n\n let carry1: DigestHex | null = null;\n let carry2: DigestHex | null = null;\n\n for (let i1 = 0, i2 = 0; i1 < node1.items.length || i2 < node2.items.length; undefined) {\n invariant(i1 <= node1.items.length);\n invariant(i2 <= node2.items.length);\n\n const key1 = i1 < node1.items.length ? node1.items[i1].key : null;\n const key2 = i2 < node2.items.length ? node2.items[i2].key : null;\n invariant(key1 !== null || key2 !== null);\n\n const child1 = carry1 !== null ? carry1 : node1.children[i1];\n const child2 = carry2 !== null ? carry2 : node2.children[i2];\n if (node1.level > 0) {\n invariant(validDigest(child1));\n invariant(validDigest(child2));\n }\n\n if (key1 === key2) {\n if (node1.level > 0) {\n resultChildren.push(await this.merge(child1, child2, mergeFn));\n }\n resultItems.push(await this.#mergeItem(mergeFn, node1.items[i1], node2.items[i2]));\n carry1 = null;\n carry2 = null;\n i1++;\n i2++;\n } else if (key2 !== null && (key1 === null || key1 > key2)) {\n // Split first.\n invariant(key2 !== null);\n\n resultItems.push(await this.#mergeItem(mergeFn, null, node2.items[i2]));\n\n if (node1.level > 0) {\n const [left, right] = await this.#splitAtKey(child1, key2);\n resultChildren.push(await this.merge(left, child2, mergeFn));\n carry1 = right;\n carry2 = null;\n }\n i2++;\n } else {\n // Split second.\n invariant(key1 !== null);\n\n resultItems.push(await this.#mergeItem(mergeFn, node1.items[i1], null));\n\n if (node1.level > 0) {\n const [left, right] = await this.#splitAtKey(child2, key1);\n resultChildren.push(await this.merge(child1, left, mergeFn));\n carry1 = null;\n carry2 = right;\n }\n i1++;\n }\n }\n if (node1.level > 0) {\n const child1 = carry1 !== null ? carry1 : node1.children[node1.items.length];\n const child2 = carry2 !== null ? carry2 : node2.children[node2.items.length];\n resultChildren.push(await this.merge(child1, child2, mergeFn));\n }\n\n return await this.#makeNode(node1.level, resultItems, resultChildren);\n }\n\n async setBatch(root: DigestHex, pairs: Iterable<Pair>): Promise<DigestHex> {\n const newTree = await this.createTree(pairs);\n return await this.merge(root, newTree, async (key, value1, value2) => (value2 !== null ? value2 : value1!));\n }\n\n async set(root: DigestHex, key: Key, value: Uint8Array): Promise<DigestHex> {\n return this.setBatch(root, [[key, value]]);\n }\n\n *missingNodes(digest: DigestHex): Iterable<DigestHex> {\n const node = this.#nodes.get(digest);\n if (!node) {\n yield digest;\n } else {\n for (const child of node.children) {\n yield* this.missingNodes(child);\n }\n }\n }\n\n async insertNodes(nodes: Iterable<NodeData>): Promise<DigestHex[]> {\n const result: DigestHex[] = [];\n for (const node of nodes) {\n const items = await Promise.all(node.items.map((item) => makeItem(item.key, item.value)));\n // Validation.\n const { digest } = await makeNode(node.level, items, node.children);\n invariant(digest === node.digest);\n\n this.#nodes.set(node.digest, {\n level: node.level,\n digest: node.digest,\n items,\n children: node.children,\n });\n result.push(node.digest);\n }\n return result;\n }\n\n async getNodes(digests: Iterable<DigestHex>): Promise<NodeData[]> {\n const result: NodeData[] = [];\n\n for (const digest of digests) {\n const node = this.#nodes.get(digest);\n if (!node) {\n continue;\n }\n result.push({\n level: node.level,\n digest: node.digest,\n items: node.items.map((item) => ({\n key: item.key,\n value: item.value,\n })),\n children: node.children,\n });\n }\n\n return result;\n }\n\n treeMut(root: DigestHex): TreeMut {\n return new TreeMut(this, root);\n }\n\n formatToString(digest: DigestHex, { pad = 0 }: { pad?: number } = {}): string {\n const padStr = ' '.repeat(pad);\n\n const node = this.#nodes.get(digest);\n if (!node) {\n return `${padStr} o (${digest.slice(0, 8)}) NOT AVAILABLE`;\n }\n\n let string = `${padStr} o (${digest.slice(0, 8)}) level=${node.level} size=${node.items.length}\\n`;\n for (let i = 0; i < node.items.length; i++) {\n if (node.level > 0) {\n string += this.formatToString(node.children[i], { pad: pad + 1 });\n }\n string += `${padStr} - [${node.items[i].itemDigest.slice(0, 8)}] level=${node.items[i].level} ${node.items[i].key.slice(0, 10)} -> ${arrayToHex(node.items[i].value.slice(0, 10).buffer)} \\n`;\n }\n if (node.level > 0) {\n string += this.formatToString(node.children[node.items.length], { pad: pad + 1 });\n }\n return string;\n }\n\n /**\n * Items iterator ordered by key.\n */\n *items(digest: DigestHex): Iterable<Item> {\n const node = this.#requireNode(digest);\n for (let i = 0; i < node.items.length; i++) {\n if (node.level > 0) {\n yield* this.items(node.children[i]);\n }\n yield node.items[i];\n }\n if (node.level > 0) {\n yield* this.items(node.children[node.items.length]);\n }\n }\n\n #requireNode(digest: DigestHex): Node {\n invariant(validDigest(digest));\n const node = this.#nodes.get(digest);\n if (!node) {\n throw new Error(`Node not available: ${digest}`);\n }\n return node;\n }\n\n async #mergeItem(mergeFn: MergeFn, item1: Item | null, item2: Item | null): Promise<Item> {\n invariant(item1 !== null || item2 !== null);\n const key = (item1?.key ?? item2?.key)!;\n\n if (item1 !== null && item2 !== null && arraysEqual(item1.value, item2.value)) {\n return item1;\n } else {\n const mergeResult = await mergeFn(key, item1?.value ?? null, item2?.value ?? null);\n // console.log(\n // `mergeFn ${key.slice(0, 10)} ${String(item1 ? arrayToHex(item1.value).slice(0, 10) : null).padStart(10)} ${String(item2 ? arrayToHex(item2.value).slice(0, 10) : null).padStart(10)} -> ${arrayToHex(mergeResult).slice(0, 10)}`,\n // );\n\n if (item1 !== null && arraysEqual(item1.value, mergeResult)) {\n return item1;\n } else if (item2 !== null && arraysEqual(item2.value, mergeResult)) {\n return item2;\n } else {\n this.itemHashOps++;\n return await makeItem(key, mergeResult);\n }\n }\n }\n\n #emptyNodeCache?: Promise<Node> = undefined;\n async #makeNode(level: number, items: Item[], children: DigestHex[]): Promise<DigestHex> {\n invariant(level > 0 ? items.length + 1 === children.length : children.length === 0);\n\n let node: Node;\n if (level === 0 && items.length === 0) {\n node = await (this.#emptyNodeCache ??= makeNode(0, [], []));\n } else {\n node = await makeNode(level, items, children);\n this.nodeHashOps++;\n }\n if (!this.#nodes.has(node.digest)) {\n this.#nodes.set(node.digest, node);\n }\n return node.digest;\n }\n\n async #splitAtKey(digest: DigestHex, key: Key): Promise<[left: DigestHex, right: DigestHex]> {\n const node = this.#requireNode(digest);\n\n let splitIndex = node.items.length;\n for (let i = 0; i < node.items.length; i++) {\n if (node.items[i].key === key) {\n return [\n await this.#makeNode(node.level, node.items.slice(0, i), node.children.slice(0, i + 1)),\n await this.#makeNode(node.level, node.items.slice(i + 1), node.children.slice(i + 2)),\n ];\n }\n\n if (node.items[i].key > key) {\n splitIndex = i;\n break;\n }\n }\n\n if (node.level === 0) {\n if (splitIndex === 0) {\n return [await this.#makeNode(0, [], []), digest];\n } else if (splitIndex === node.items.length) {\n return [digest, await this.#makeNode(0, [], [])];\n }\n return [\n await this.#makeNode(node.level, node.items.slice(0, splitIndex), []),\n await this.#makeNode(node.level, node.items.slice(splitIndex), []),\n ];\n } else {\n const [left, right] = await this.#splitAtKey(node.children[splitIndex], key);\n\n return [\n await this.#makeNode(node.level, node.items.slice(0, splitIndex), [\n ...node.children.slice(0, splitIndex),\n left,\n ]),\n await this.#makeNode(node.level, node.items.slice(splitIndex), [right, ...node.children.slice(splitIndex + 1)]),\n ];\n }\n }\n}\n\nexport class TreeMut {\n readonly #forest: Forest;\n #root: DigestHex;\n\n constructor(forest: Forest, root: DigestHex) {\n this.#forest = forest;\n this.#root = root;\n }\n\n get root() {\n return this.#root;\n }\n\n async get(key: string): Promise<GetResult<Uint8Array>> {\n return this.#forest.get(this.#root, key);\n }\n\n async setBatch(pairs: Iterable<Pair>): Promise<void> {\n this.#root = await this.#forest.setBatch(this.#root, pairs);\n }\n\n async set(key: Key, value: Uint8Array): Promise<void> {\n this.#root = await this.#forest.set(this.#root, key, value);\n }\n\n items(): Iterable<Item> {\n return this.#forest.items(this.root);\n }\n}\n\nexport type Key = string;\n\nexport type DigestHex = string & { __digestHex: true };\n\nexport type Pair = readonly [key: Key, value: Uint8Array];\n\nexport type GetResult<T> =\n | {\n kind: 'present';\n value: T;\n }\n | {\n kind: 'missing';\n }\n | {\n kind: 'not-available';\n };\n\nexport type MergeFn = (key: string, value1: Uint8Array | null, value2: Uint8Array | null) => Promise<Uint8Array>;\n\nexport type NodeData = {\n readonly level: number;\n\n readonly digest: DigestHex;\n /**\n * Sorted by key\n */\n readonly items: readonly ItemData[];\n /**\n * {items.length + 1} child digests.\n */\n readonly children: readonly DigestHex[];\n};\n\nexport type ItemData = {\n readonly key: string;\n readonly value: Uint8Array;\n};\n\n/**\n * A Merkle-Search Tree node.\n * Contains variable number of items (key-value pairs).\n * Contains {items.length + 1} child nodes.\n * All items, including the ones in interleaving child nodes, are ordered base on the key.\n *\n * Items : (0) (1) (3)\n * Children: [0] [1] [2] [3]\n */\ntype Node = {\n readonly level: number;\n\n readonly digest: DigestHex;\n\n /**\n * Sorted by key\n */\n readonly items: readonly Item[];\n /**\n * {items.length + 1} child digests.\n */\n readonly children: readonly DigestHex[];\n};\n\nconst makeNode = async (level: number, items: readonly Item[], children: readonly DigestHex[]): Promise<Node> => {\n invariant(level > 0 ? items.length + 1 === children.length : children.length === 0);\n\n // TODO(dmaretskyi): Hashing spec.\n const nodeInputData = textEncoder.encode(items.map((item) => item.itemDigest).join('') + children.join(''));\n const digest = await crypto.subtle.digest({ name: 'SHA-256' }, nodeInputData);\n return {\n level,\n digest: formatDigest(new Uint8Array(digest)) as DigestHex,\n items,\n children,\n };\n};\n\ntype Item = {\n readonly level: number;\n readonly key: string;\n readonly value: Uint8Array;\n readonly keyDigest: DigestHex;\n readonly itemDigest: DigestHex;\n};\n\nconst makeItem = async (key: string, value: Uint8Array): Promise<Item> => {\n invariant(typeof key === 'string');\n invariant(value !== null);\n // TODO(dmaretskyi): Hashing spec.\n const keyBytes = textEncoder.encode(key);\n const keyDigest = await crypto.subtle.digest({ name: 'SHA-256' }, keyBytes);\n const keyDigestHex = formatDigest(new Uint8Array(keyDigest)) as DigestHex;\n\n const data = new Uint8Array(keyBytes.length + value.length);\n data.set(keyBytes, 0);\n data.set(value, keyBytes.length);\n const itemDigest = await crypto.subtle.digest({ name: 'SHA-256' }, data);\n return {\n level: getLevelHex(keyDigestHex),\n key,\n value,\n keyDigest: keyDigestHex,\n itemDigest: formatDigest(new Uint8Array(itemDigest)) as DigestHex,\n };\n};\n\nconst getKeyLevel = async (key: string): Promise<number> => {\n const keyBytes = textEncoder.encode(key);\n const keyDigest = await crypto.subtle.digest({ name: 'SHA-256' }, keyBytes);\n\n const keyDigestHex = formatDigest(new Uint8Array(keyDigest)) as DigestHex;\n\n return getLevelHex(keyDigestHex);\n};\n\nconst textEncoder = new TextEncoder();\n\nconst validDigest = (digest: DigestHex) => typeof digest === 'string' && digest.length > 0;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { ActorID } from './common';\nimport { type DigestHex, Forest, type Key, type NodeData } from './forest';\n\nexport type LLWTreeParams = {\n actor: ActorID;\n};\n\n/**\n * Replicated Key-Value Store with Last-Write-Wins semantics.\n */\nexport class LWWTree<T> {\n static async new<T>(params: LLWTreeParams): Promise<LWWTree<T>> {\n const tree = new LWWTree<T>(params);\n tree.#currentRoot = await tree.#forest.createTree([]);\n\n return tree;\n }\n\n #actor: ActorID;\n\n #forest = new Forest();\n\n #currentRoot!: DigestHex;\n\n get currentRoot() {\n return this.#currentRoot;\n }\n\n private constructor(params: LLWTreeParams) {\n this.#actor = params.actor;\n }\n\n async get(key: Key): Promise<T | undefined> {\n const data = await this.#getData(key);\n return data?.value;\n }\n\n async setBatch(pairs: [Key, T][]): Promise<void> {\n const prevDataBatch = await Promise.all(pairs.map(([key]) => this.#getData(key)));\n const updates = pairs.map(([key, value], i) => {\n const prevData = prevDataBatch[i];\n const newClock: VersionClock = !prevData\n ? ([this.#actor, 0] as const)\n : ([this.#actor, prevData.clock[1] + 1] as const);\n const data = this.#encode({ clock: newClock, value });\n\n return [key, data] as const;\n });\n this.#currentRoot = await this.#forest.setBatch(this.#currentRoot, updates);\n }\n\n async set(key: Key, value: T): Promise<void> {\n await this.setBatch([[key, value]]);\n }\n\n async receiveSyncMessage(state: LWWTreeSyncState, message: LWWTreeSyncMessage): Promise<LWWTreeSyncState> {\n await this.#forest.insertNodes(message.nodes);\n\n const remoteRoot = message.root ?? state.remoteRoot;\n\n if (remoteRoot !== null) {\n const missing = [...(await this.#forest.missingNodes(remoteRoot))];\n if (missing.length === 0) {\n this.#currentRoot = await this.#forest.merge(remoteRoot, this.#currentRoot, this.#merge.bind(this));\n } else if (state.remoteRoot !== null && state.remoteRoot !== remoteRoot) {\n // If we're missing nodes from the new remote root, but we have the previous remote root, we can try to merge.\n const missingFromPrevRoot = [...(await this.#forest.missingNodes(state.remoteRoot))];\n if (missingFromPrevRoot.length === 0) {\n await this.#forest.merge(state.remoteRoot, this.#currentRoot, this.#merge.bind(this));\n\n const missing = [...(await this.#forest.missingNodes(remoteRoot))];\n if (missing.length === 0) {\n this.#currentRoot = await this.#forest.merge(remoteRoot, this.#currentRoot, this.#merge.bind(this));\n }\n }\n }\n }\n\n return {\n remoteRoot,\n remoteWant: message.want,\n needsAck: message.nodes.length > 0,\n };\n }\n\n async generateSyncMessage(state: LWWTreeSyncState): Promise<[LWWTreeSyncState, LWWTreeSyncMessage | null]> {\n if (state.remoteRoot === this.#currentRoot && state.remoteWant.length === 0 && !state.needsAck) {\n return [state, null];\n }\n\n const nodes = await this.#forest.getNodes(state.remoteWant);\n const want = state.remoteRoot === null ? [] : [...(await this.#forest.missingNodes(state.remoteRoot))];\n\n return [\n {\n remoteRoot: state.remoteRoot,\n remoteWant: state.remoteWant,\n needsAck: false,\n },\n {\n root: this.#currentRoot,\n want,\n nodes,\n },\n ];\n }\n\n async #getData(key: Key): Promise<ValueData<T> | undefined> {\n const res = await this.#forest.get(this.#currentRoot, key);\n switch (res.kind) {\n case 'present': {\n return this.#decode(res.value);\n }\n\n case 'missing':\n return undefined;\n case 'not-available':\n throw new Error('Key not available');\n }\n }\n\n async #merge(key: Key, left: Uint8Array | null, right: Uint8Array | null): Promise<Uint8Array> {\n if (!left) {\n return right!;\n }\n if (!right) {\n return left!;\n }\n\n const leftData = this.#decode(left);\n const rightData = this.#decode(right);\n\n const cmp =\n leftData.clock[1] === rightData.clock[1]\n ? leftData.clock[0].localeCompare(rightData.clock[0])\n : leftData.clock[1] - rightData.clock[1];\n if (cmp >= 0) {\n return left;\n } else {\n return right;\n }\n }\n\n #decode(value: Uint8Array): ValueData<T> {\n return JSON.parse(textDecoder.decode(value));\n }\n\n #encode(data: ValueData<T>): Uint8Array {\n const { clock, value } = data;\n return textEncoder.encode(JSON.stringify({ clock, value })); // Field order ensures consistent hashing.\n }\n}\n\nexport type LWWTreeSyncMessage = {\n root: DigestHex | null;\n want: DigestHex[];\n nodes: NodeData[];\n};\n\nexport type LWWTreeSyncState = {\n remoteRoot: DigestHex | null;\n remoteWant: DigestHex[];\n needsAck: boolean;\n};\n\nexport const initLWWTreeSyncState = (): LWWTreeSyncState => ({ remoteRoot: null, remoteWant: [], needsAck: false });\n\ntype VersionClock = readonly [actor: ActorID, version: number];\n\ntype ValueData<T> = {\n clock: VersionClock;\n value: T;\n};\n\nconst textDecoder = new TextDecoder();\nconst textEncoder = new TextEncoder();\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { arraysEqual } from '@dxos/util';\n\nimport type { ActorID } from './common';\nimport { type DigestHex, Forest, type Key, type NodeData } from './forest';\n\nexport type MirrorMultiMapParams = {\n actor: ActorID;\n};\n\n/**\n * Replicated tree where each actor's state is tracked separately.\n * Sync is optimized for the case where each actor has a similar state.\n * Actors are expected to eventually converge to the same state.\n */\nexport class MirrorMultiMap<T> {\n static async new<T>(params: MirrorMultiMapParams): Promise<MirrorMultiMap<T>> {\n const tree = new MirrorMultiMap<T>(params);\n tree.#currentRoot = await tree.#forest.createTree([]);\n\n return tree;\n }\n\n #forest = new Forest();\n\n #actor: ActorID;\n #currentRoot!: DigestHex;\n\n #remoteStates = new Map<ActorID, SyncState>();\n\n private constructor(params: MirrorMultiMapParams) {\n this.#actor = params.actor;\n }\n\n get localActorId(): ActorID {\n return this.#actor;\n }\n\n get currentRoot(): DigestHex {\n return this.#currentRoot;\n }\n\n get forest(): Forest {\n return this.#forest;\n }\n\n async getLocal(key: Key): Promise<T | undefined> {\n const entry = await this.#forest.get(this.#currentRoot, key);\n switch (entry?.kind) {\n case 'present':\n return this.#decode(entry.value);\n case 'missing':\n return undefined;\n case 'not-available':\n throw new Error('Unexpected local entry not available');\n }\n }\n\n async setLocalBatch(pairs: (readonly [Key, T])[]): Promise<void> {\n const updates = pairs.map(([key, value]) => [key, this.#encode(value)] as const);\n this.#currentRoot = await this.#forest.setBatch(this.#currentRoot, updates);\n }\n\n async getFor(actorId: ActorID, key: Key): Promise<T | undefined> {\n const state = this.#remoteStates.get(actorId);\n if (!state) {\n throw new Error(`Unknown actorId: ${actorId}`);\n }\n if (!state.remoteRoot) {\n return undefined;\n }\n\n const entry = await this.#forest.get(state.remoteRoot, key);\n switch (entry?.kind) {\n case 'present':\n return this.#decode(entry.value);\n case 'missing':\n return undefined;\n case 'not-available':\n throw new Error('Unexpected remote entry not available');\n }\n }\n\n async setForBatch(actorId: ActorID, pairs: [Key, T][]): Promise<void> {\n const remoteState = this.#remoteStates.get(actorId) ?? initSyncState();\n const updates = pairs.map(([key, value]) => [key, this.#encode(value)] as const);\n const prevRoot = remoteState.remoteRoot ?? (await this.#forest.createTree([]));\n const nextRoot = await this.#forest.setBatch(prevRoot, updates);\n\n this.#remoteStates.set(actorId, {\n remoteRoot: nextRoot,\n myRoot: null,\n remoteWant: remoteState.remoteWant,\n needsAck: remoteState.needsAck,\n });\n }\n\n async getAll(key: Key): Promise<Map<ActorID, T | undefined>> {\n const result = new Map<ActorID, T | undefined>();\n result.set(this.#actor, await this.getLocal(key));\n for (const [actorId, _state] of this.#remoteStates) {\n result.set(actorId, await this.getFor(actorId, key));\n }\n return result;\n }\n\n async getDifferent(): Promise<Map<Key, Map<ActorID, T | undefined>>> {\n // TODO(dmaretskyi): This could be optimized to not traverse nodes that have equal hashes.\n\n const resultByKey = new Map<Key, Map<ActorID, Uint8Array>>();\n\n const actors = new Set<ActorID>([this.#actor, ...this.#remoteStates.keys()]);\n for (const actor of actors) {\n let root;\n if (actor === this.#actor) {\n root = this.#currentRoot;\n } else {\n root = this.#remoteStates.get(actor)?.remoteRoot;\n }\n\n if (!root) {\n continue;\n }\n for (const item of this.#forest.items(root)) {\n let subMap = resultByKey.get(item.key);\n if (!subMap) {\n subMap = new Map();\n resultByKey.set(item.key, subMap);\n }\n subMap.set(actor, item.value);\n }\n }\n\n const result = new Map<Key, Map<ActorID, T | undefined>>();\n\n for (const [key, subMap] of resultByKey) {\n const first = subMap.values().next().value!;\n let allEqual = subMap.size === actors.size;\n if (allEqual) {\n for (const value of subMap.values()) {\n if (!arraysEqual(first, value)) {\n allEqual = false;\n break;\n }\n }\n }\n\n if (!allEqual) {\n const resultSubMap = new Map<ActorID, T | undefined>();\n for (const [actorId, value] of subMap) {\n resultSubMap.set(actorId, this.#decode(value));\n }\n result.set(key, resultSubMap);\n }\n }\n\n return result;\n }\n\n clearActorState(actorId: ActorID): void {\n this.#remoteStates.delete(actorId);\n }\n\n async receiveSyncMessage(actorId: ActorID, message: MirrorMultiMapSyncMessage): Promise<void> {\n await this.#forest.insertNodes(message.nodes);\n\n const state = this.#remoteStates.get(actorId) ?? initSyncState();\n const remoteRoot = message.root ?? state.remoteRoot;\n\n const newState: SyncState = {\n remoteRoot,\n myRoot: message.remoteRoot ?? state.myRoot,\n remoteWant: message.want,\n needsAck: message.nodes.length > 0,\n };\n this.#remoteStates.set(actorId, newState);\n }\n\n async generateSyncMessage(actorId: ActorID): Promise<MirrorMultiMapSyncMessage | null> {\n const state = this.#remoteStates.get(actorId) ?? initSyncState();\n\n if (state.myRoot === this.#currentRoot && state.remoteWant.length === 0 && !state.needsAck) {\n return null;\n }\n\n const nodes = await this.#forest.getNodes(state.remoteWant);\n const want = state.remoteRoot === null ? [] : [...(await this.#forest.missingNodes(state.remoteRoot))];\n\n this.#remoteStates.set(actorId, {\n remoteRoot: state.remoteRoot,\n myRoot: state.myRoot,\n remoteWant: state.remoteWant,\n needsAck: false,\n });\n\n return {\n root: this.#currentRoot,\n remoteRoot: state.remoteRoot,\n want,\n nodes,\n };\n }\n\n #decode(value: Uint8Array): T {\n return JSON.parse(textDecoder.decode(value));\n }\n\n #encode(data: T): Uint8Array {\n return textEncoder.encode(JSON.stringify(data)); // Field order ensures consistent hashing.\n }\n}\n\nexport type MirrorMultiMapSyncMessage = {\n root: DigestHex | null;\n remoteRoot: DigestHex | null;\n want: DigestHex[];\n nodes: NodeData[];\n};\n\ntype SyncState = {\n remoteRoot: DigestHex | null;\n myRoot: DigestHex | null;\n remoteWant: DigestHex[];\n needsAck: boolean;\n};\n\nconst initSyncState = (): SyncState => ({ remoteRoot: null, myRoot: null, remoteWant: [], needsAck: false });\n\nconst textDecoder = new TextDecoder();\nconst textEncoder = new TextEncoder();\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const createValue = (source: string) => new Uint8Array(textEncoder.encode(source));\n\nconst textEncoder = new TextEncoder();\n\nexport const randomKey = () => crypto.randomUUID();\n\nexport const randomSample = <T>(data: T[], count: number) => data.toSorted(() => Math.random() - 0.5).slice(0, count);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["arrayToHex", "makeItem", "key", "value", "keyBytes", "textEncoder", "encode", "data", "Uint8Array", "length", "set", "digest", "crypto", "subtle", "name", "getLevel", "level", "i", "byte", "formatDigest", "arrayToHex", "buffer", "getLevelHex", "digestEquals", "a", "b", "TextEncoder", "invariant", "arrayToHex", "arraysEqual", "Forest", "Map", "itemHashOps", "nodeHashOps", "createTree", "pairs", "items", "Promise", "all", "map", "key", "value", "makeItem", "length", "sort", "a", "b", "i", "Error", "buildLevel", "level", "from", "to", "invariant", "slice", "rangeBegin", "childItems", "childNodes", "node", "push", "maxLevel", "Math", "max", "item", "root", "get", "keyLevel", "getKeyLevel", "undefined", "kind", "found", "children", "merge", "digest1", "digest2", "mergeFn", "node1", "node2", "resultItems", "resultChildren", "carry1", "carry2", "i1", "i2", "key1", "key2", "child1", "child2", "validDigest", "left", "right", "setBatch", "newTree", "value1", "value2", "set", "missingNodes", "digest", "child", "insertNodes", "nodes", "result", "makeNode", "getNodes", "digests", "treeMut", "TreeMut", "formatToString", "pad", "padStr", "repeat", "string", "itemDigest", "arrayToHex", "buffer", "item1", "item2", "arraysEqual", "mergeResult", "has", "splitIndex", "forest", "nodeInputData", "textEncoder", "encode", "join", "crypto", "subtle", "name", "formatDigest", "Uint8Array", "keyBytes", "keyDigest", "keyDigestHex", "data", "getLevelHex", "TextEncoder", "LWWTree", "new", "params", "tree", "createTree", "Forest", "currentRoot", "actor", "get", "key", "data", "value", "setBatch", "pairs", "prevDataBatch", "Promise", "all", "map", "updates", "i", "prevData", "newClock", "clock", "set", "receiveSyncMessage", "state", "message", "insertNodes", "nodes", "remoteRoot", "root", "missing", "missingNodes", "length", "merge", "bind", "missingFromPrevRoot", "remoteWant", "want", "needsAck", "generateSyncMessage", "getNodes", "res", "kind", "undefined", "Error", "left", "right", "leftData", "rightData", "cmp", "localeCompare", "JSON", "parse", "textDecoder", "decode", "textEncoder", "encode", "stringify", "initLWWTreeSyncState", "TextDecoder", "TextEncoder", "arraysEqual", "MirrorMultiMap", "new", "params", "tree", "createTree", "Forest", "Map", "actor", "localActorId", "currentRoot", "forest", "getLocal", "key", "entry", "get", "kind", "value", "undefined", "Error", "setLocalBatch", "pairs", "updates", "map", "setBatch", "getFor", "actorId", "state", "remoteRoot", "setForBatch", "remoteState", "initSyncState", "prevRoot", "nextRoot", "set", "myRoot", "remoteWant", "needsAck", "getAll", "result", "_state", "getDifferent", "resultByKey", "actors", "Set", "keys", "root", "item", "items", "subMap", "first", "values", "next", "allEqual", "size", "arraysEqual", "resultSubMap", "clearActorState", "delete", "receiveSyncMessage", "message", "insertNodes", "nodes", "newState", "want", "length", "generateSyncMessage", "getNodes", "missingNodes", "JSON", "parse", "textDecoder", "decode", "data", "textEncoder", "encode", "stringify", "TextDecoder", "TextEncoder", "createValue", "source", "Uint8Array", "textEncoder", "encode", "TextEncoder", "randomKey", "crypto", "randomUUID", "randomSample", "data", "count", "toSorted", "Math", "random", "slice"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/common.ts":{"bytes":6479,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"src/forest.ts":{"bytes":61665,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"src/common.ts","kind":"import-statement","original":"./common"}],"format":"esm"},"src/lww-tree.ts":{"bytes":
|
|
1
|
+
{"inputs":{"src/common.ts":{"bytes":6479,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"src/forest.ts":{"bytes":61665,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"src/common.ts","kind":"import-statement","original":"./common"}],"format":"esm"},"src/lww-tree.ts":{"bytes":18601,"imports":[{"path":"src/forest.ts","kind":"import-statement","original":"./forest"}],"format":"esm"},"src/mirror-multi-map.ts":{"bytes":23649,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"src/forest.ts","kind":"import-statement","original":"./forest"}],"format":"esm"},"src/testing.ts":{"bytes":1612,"imports":[],"format":"esm"},"src/index.ts":{"bytes":824,"imports":[{"path":"src/common.ts","kind":"import-statement","original":"./common"},{"path":"src/forest.ts","kind":"import-statement","original":"./forest"},{"path":"src/lww-tree.ts","kind":"import-statement","original":"./lww-tree"},{"path":"src/mirror-multi-map.ts","kind":"import-statement","original":"./mirror-multi-map"},{"path":"src/testing.ts","kind":"import-statement","original":"./testing"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":54511},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Forest","LWWTree","MirrorMultiMap","TreeMut","createValue","digestEquals","formatDigest","getLevel","getLevelHex","initLWWTreeSyncState","makeItem","randomKey","randomSample"],"entryPoint":"src/index.ts","inputs":{"src/common.ts":{"bytesInOutput":1188},"src/index.ts":{"bytesInOutput":0},"src/forest.ts":{"bytesInOutput":15573},"src/lww-tree.ts":{"bytesInOutput":4011},"src/mirror-multi-map.ts":{"bytesInOutput":5352},"src/testing.ts":{"bytesInOutput":250}},"bytes":26804}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lww-tree.d.ts","sourceRoot":"","sources":["../../../src/lww-tree.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"lww-tree.d.ts","sourceRoot":"","sources":["../../../src/lww-tree.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,SAAS,EAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,qBAAa,OAAO,CAAC,CAAC;;WACP,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAa/D,IAAI,WAAW,cAEd;IAED,OAAO;IAID,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAKrC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1C,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA8BnG,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,IAAI,CAAC,CAAC;CAkE3G;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,gBAA2E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror-multi-map.d.ts","sourceRoot":"","sources":["../../../src/mirror-multi-map.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"mirror-multi-map.d.ts","sourceRoot":"","sources":["../../../src/mirror-multi-map.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,EAAE,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,qBAAa,cAAc,CAAC,CAAC;;WACd,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAc7E,OAAO;IAIP,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,WAAW,IAAI,SAAS,CAE3B;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAEK,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAY1C,aAAa,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1D,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAoB1D,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAc/D,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;IAStD,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAqDpE,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIjC,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAevF,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;CAgCvF;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,CAAC"}
|