@alanshaw/pail
Advanced tools
Comparing version 0.3.1 to 0.3.2
{ | ||
"name": "@alanshaw/pail", | ||
"version": "0.3.1", | ||
"version": "0.3.2", | ||
"description": "DAG based key value store.", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -14,2 +14,11 @@ import { parse } from 'multiformats/link' | ||
/** | ||
* @param {Array<AnyBlock>} [blocks] | ||
*/ | ||
constructor (blocks) { | ||
if (blocks) { | ||
this.#blocks = new Map(blocks.map(b => [b.cid.toString(), b.bytes])) | ||
} | ||
} | ||
/** | ||
* @param {import('./link').AnyLink} cid | ||
@@ -16,0 +25,0 @@ * @returns {Promise<AnyBlock | undefined>} |
@@ -61,3 +61,5 @@ import * as Clock from './clock.js' | ||
const sorted = await findSortedEvents(events, head, ancestor) | ||
/** @type {Map<string, import('./shard').ShardBlockView>} */ | ||
const additions = new Map() | ||
/** @type {Map<string, import('./shard').ShardBlockView>} */ | ||
const removals = new Map() | ||
@@ -98,6 +100,14 @@ | ||
// filter blocks that were added _and_ removed | ||
for (const k of removals.keys()) { | ||
if (additions.has(k)) { | ||
additions.delete(k) | ||
removals.delete(k) | ||
} | ||
} | ||
return { | ||
root: result.root, | ||
additions: Array.from(additions.values()), | ||
removals: Array.from(removals.values()), | ||
additions: [...additions.values()], | ||
removals: [...removals.values()], | ||
head, | ||
@@ -125,7 +135,11 @@ event | ||
* | ||
* Clocks with multiple head events may return blocks that were added or | ||
* removed while playing forward events from their common ancestor. | ||
* | ||
* @param {import('./block').BlockFetcher} blocks Bucket block storage. | ||
* @param {import('./clock').EventLink<EventData>[]} head Merkle clock head. | ||
* @returns {Promise<{ root: import('./shard').ShardLink } & import('./index').ShardDiff>} | ||
*/ | ||
export async function root (blocks, head) { | ||
if (!head.length) return | ||
if (!head.length) throw new Error('cannot determine root of headless clock') | ||
@@ -135,3 +149,11 @@ const mblocks = new MemoryBlockstore() | ||
/** @type {EventFetcher<EventData>} */ | ||
const events = new EventFetcher(blocks) | ||
if (head.length === 1) { | ||
const event = await events.get(head[0]) | ||
const { root } = event.value.data | ||
return { root, additions: [], removals: [] } | ||
} | ||
const ancestor = await findCommonAncestor(events, head) | ||
@@ -144,2 +166,7 @@ if (!ancestor) throw new Error('failed to find common ancestor event') | ||
const sorted = await findSortedEvents(events, head, ancestor) | ||
/** @type {Map<string, import('./shard').ShardBlockView>} */ | ||
const additions = new Map() | ||
/** @type {Map<string, import('./shard').ShardBlockView>} */ | ||
const removals = new Map() | ||
for (const { value: event } of sorted) { | ||
@@ -156,6 +183,22 @@ if (!['put', 'del'].includes(event.data.type)) { | ||
mblocks.putSync(a.cid, a.bytes) | ||
additions.set(a.cid.toString(), a) | ||
} | ||
for (const r of result.removals) { | ||
removals.set(r.cid.toString(), r) | ||
} | ||
} | ||
return root | ||
// filter blocks that were added _and_ removed | ||
for (const k of removals.keys()) { | ||
if (additions.has(k)) { | ||
additions.delete(k) | ||
removals.delete(k) | ||
} | ||
} | ||
return { | ||
root, | ||
additions: [...additions.values()], | ||
removals: [...removals.values()] | ||
} | ||
} | ||
@@ -169,3 +212,8 @@ | ||
export async function get (blocks, head, key) { | ||
return Pail.get(blocks, await root(blocks, head), key) | ||
if (!head.length) return | ||
const result = await root(blocks, head) | ||
if (result.additions.length) { | ||
blocks = new MultiBlockFetcher(new MemoryBlockstore(result.additions), blocks) | ||
} | ||
return Pail.get(blocks, result.root, key) | ||
} | ||
@@ -180,3 +228,8 @@ | ||
export async function * entries (blocks, head, options) { | ||
yield * Pail.entries(blocks, await root(blocks, head), options) | ||
if (!head.length) return | ||
const result = await root(blocks, head) | ||
if (result.additions.length) { | ||
blocks = new MultiBlockFetcher(new MemoryBlockstore(result.additions), blocks) | ||
} | ||
yield * Pail.entries(blocks, result.root, options) | ||
} | ||
@@ -183,0 +236,0 @@ |
@@ -215,3 +215,3 @@ import { | ||
* @param {string} [options.prefix] | ||
* @returns {AsyncIterableIterator<import('./shard').ShardEntry>} | ||
* @returns {AsyncIterableIterator<import('./shard').ShardValueEntry>} | ||
*/ | ||
@@ -224,3 +224,3 @@ export async function * entries (blocks, root, options = {}) { | ||
yield * ( | ||
/** @returns {AsyncIterableIterator<import('./shard').ShardEntry>} */ | ||
/** @returns {AsyncIterableIterator<import('./shard').ShardValueEntry>} */ | ||
async function * ents (shard) { | ||
@@ -227,0 +227,0 @@ for (const entry of shard.value) { |
99690
1735