OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-overlay commits / 56eeba7

port(0.3.0): adopt overlay-v2 + transfer tests to Ok engine API
- overlay-v2-{fetch,mirror-spool,restart-durability}: fetchFile now returns {destPath,local,size} (streams to disk) not {data} — read bytes from destPath. - transfer: startReceive + finalize are async in Ok engine (journaled resume) — await them. PARTIAL_SUFFIX unchanged (.overlay-partial). - (import repoints protocol-v2->protocol / overlay-v2->overlay already applied.) overlay-v2 trio 6/6, transfer 18/18. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
56eeba7f458ccca5e47079742f091b69163ab140
by plankatron <fleeky@gmail.com> · 2026-07-11T17:43:36.000Z

Changed files (4) +18 -18

test/overlay-v2-fetch.test.js +4 -4
……@@ -52,12 +52,12 @@ test('V2 facade: cross-peer fetch by content hash (multi-chunk, from scratch)',
5252 const got = await bob.fetchFile(oid)
5353 t.ok(got, 'bob resolved the file from a peer')
5454 t.is(got.local, false, 'came from a peer, not local disk')
55 t.is(Buffer.compare(got.data, content), 0, 'bytes match alice’s file')
55 t.is(Buffer.compare(fs.readFileSync(got.destPath), content), 0, 'bytes match alice’s file')
5656
5757 // Alice serves its own copy from the local fast path (no wire).
5858 const localGot = await alice.fetchFile(oid)
5959 t.ok(localGot && localGot.local, 'alice serves its own copy locally')
60 t.is(Buffer.compare(localGot.data, content), 0, 'local bytes match')
60 t.is(Buffer.compare(fs.readFileSync(localGot.destPath), content), 0, 'local bytes match')
6161})
6262
6363test('V2 multi-source: chunks fetched from MULTIPLE peers in parallel', async (t) => {
……@@ -117,7 +117,7 @@ test('V2 re-seed: a fetcher becomes a seeder (multiplication)', async (t) => {
117117 F.attachProtocol(Protomux.from(fa)); S1.attachProtocol(Protomux.from(sa))
118118 await new Promise(r => setTimeout(r, 200))
119119 const got1 = await F.fetchFile(oid)
120 t.ok(got1 && Buffer.compare(got1.data, content) === 0, 'F fetched the blob from S1')
120 t.ok(got1 && Buffer.compare(fs.readFileSync(got1.destPath), content) === 0, 'F fetched the blob from S1')
121121
122122 // After fetching, F serves it from its own local copy.
123123 const localOnF = await F.fetchFile(oid)
……@@ -129,7 +129,7 @@ test('V2 re-seed: a fetcher becomes a seeder (multiplication)', async (t) => {
129129 await new Promise(r => setTimeout(r, 200))
130130 const got2 = await G.fetchFile(oid)
131131 t.ok(got2 && !got2.local, 'G fetched from a peer (F), not local')
132 t.is(got2 && Buffer.compare(got2.data, content), 0, 'G got the blob — F successfully re-seeded it')
132 t.is(got2 && Buffer.compare(fs.readFileSync(got2.destPath), content), 0, 'G got the blob — F successfully re-seeded it')
133133})
134134
135135test('V2 facade: fetch by unknown hash with no peers returns null', async (t) => {
test/overlay-v2-mirror-spool.test.js +1 -1
……@@ -43,7 +43,7 @@ test('mirror fetch stores the blob content-addressed at <mirrorSpool>/<oid> and
4343
4444 const got = await mir.fetchFile(oid, { mirrorSpool, timeout: 6000 })
4545 t.ok(got, 'mirror fetched the file from the publisher')
46 if (got) t.is(Buffer.compare(got.data, content), 0, 'fetched bytes match')
46 if (got) t.is(Buffer.compare(fs.readFileSync(got.destPath), content), 0, 'fetched bytes match')
4747
4848 // KEY: the blob is stored content-addressed in the mirror-spool (durable,
4949 // restart-survivable, re-servable via the 0.2.8 <syncBaseDir>/<oid> fallback).
test/overlay-v2-restart-durability.test.js +1 -1
……@@ -47,5 +47,5 @@ test('RESTART DURABILITY: a cold publisher serves by content hash from the conte
4747
4848 const got = await con.fetchFile(oid, { timeout: 6000 })
4949 t.ok(got, 'consumer fetched from the cold publisher (served via content-addressed spool)')
50 if (got) t.is(Buffer.compare(got.data, content), 0, 'bytes match')
50 if (got) t.is(Buffer.compare(fs.readFileSync(got.destPath), content), 0, 'bytes match')
5151})
test/transfer.test.js +12 -12
……@@ -190,7 +190,7 @@ test('receive flow — small file round-trip', async (t) => {
190190 // Receiver side: start receiving
191191 const receiverDir = tmpDir('receiver')
192192 const targetPath = path.join(receiverDir, 'doc.txt')
193 const state = transfer.startReceive(targetPath, { size: prepared.size, chunks: prepared.chunks })
193 const state = await transfer.startReceive(targetPath, { size: prepared.size, chunks: prepared.chunks })
194194
195195 t.ok(state.partialPath.endsWith('.overlay-partial'))
196196 t.is(state.total, 1)
……@@ -209,7 +209,7 @@ test('receive flow — small file round-trip', async (t) => {
209209 t.is(progress.percentage, 100)
210210
211211 // Finalize
212 const fin = transfer.finalize(targetPath)
212 const fin = await transfer.finalize(targetPath)
213213 t.ok(fin.ok, 'finalized')
214214
215215 // Verify the file on disk
……@@ -234,7 +234,7 @@ test('receive flow — multi-chunk file', async (t) => {
234234
235235 const receiverDir = tmpDir('receiver')
236236 const targetPath = path.join(receiverDir, 'multi.bin')
237 transfer.startReceive(targetPath, { size: prepared.size, chunks: prepared.chunks })
237 await transfer.startReceive(targetPath, { size: prepared.size, chunks: prepared.chunks })
238238
239239 // Transfer all chunks
240240 for (let i = 0; i < prepared.chunks.length; i++) {
……@@ -245,7 +245,7 @@ test('receive flow — multi-chunk file', async (t) => {
245245 }
246246
247247 t.ok(transfer.isComplete(targetPath))
248 transfer.finalize(targetPath)
248 await transfer.finalize(targetPath)
249249
250250 const received = fs.readFileSync(targetPath)
251251 t.alike(received, original, 'content matches')
……@@ -263,7 +263,7 @@ test('receive flow — out-of-order chunks', async (t) => {
263263
264264 const receiverDir = tmpDir('receiver')
265265 const targetPath = path.join(receiverDir, 'ooo.bin')
266 transfer.startReceive(targetPath, { size: prepared.size, chunks: prepared.chunks })
266 await transfer.startReceive(targetPath, { size: prepared.size, chunks: prepared.chunks })
267267
268268 // Send chunks in reverse order
269269 for (let i = prepared.chunks.length - 1; i >= 0; i--) {
……@@ -274,7 +274,7 @@ test('receive flow — out-of-order chunks', async (t) => {
274274 }
275275
276276 t.ok(transfer.isComplete(targetPath))
277 transfer.finalize(targetPath)
277 await transfer.finalize(targetPath)
278278
279279 const received = fs.readFileSync(targetPath)
280280 t.alike(received, original, 'content matches even with out-of-order chunks')
……@@ -290,7 +290,7 @@ test('writeChunk — rejects bad hash', async (t) => {
290290 const receiverDir = tmpDir('receiver')
291291 const targetPath = path.join(receiverDir, 'bad.bin')
292292
293 transfer.startReceive(targetPath, {
293 await transfer.startReceive(targetPath, {
294294 size: 10,
295295 chunks: [{ hash: 'a'.repeat(64), offset: 0, length: 10 }]
296296 })
……@@ -312,7 +312,7 @@ test('cancel removes partial file', async (t) => {
312312 const receiverDir = tmpDir('receiver')
313313 const targetPath = path.join(receiverDir, 'cancel.bin')
314314
315 const state = transfer.startReceive(targetPath, {
315 const state = await transfer.startReceive(targetPath, {
316316 size: 100,
317317 chunks: [{ hash: 'h1', offset: 0, length: 100 }]
318318 })
……@@ -333,7 +333,7 @@ test('finalize rejects incomplete transfer', async (t) => {
333333 const receiverDir = tmpDir('receiver')
334334 const targetPath = path.join(receiverDir, 'incomplete.bin')
335335
336 transfer.startReceive(targetPath, {
336 await transfer.startReceive(targetPath, {
337337 size: 200,
338338 chunks: [
339339 { hash: 'h1', offset: 0, length: 100 },
……@@ -341,7 +341,7 @@ test('finalize rejects incomplete transfer', async (t) => {
341341 ]
342342 })
343343
344 const result = transfer.finalize(targetPath)
344 const result = await transfer.finalize(targetPath)
345345 t.is(result.ok, false)
346346 t.ok(result.error.includes('incomplete'))
347347
……@@ -357,8 +357,8 @@ test('listActive shows active transfers', async (t) => {
357357 t.is(transfer.listActive().length, 0)
358358
359359 const dir = tmpDir('receiver')
360 transfer.startReceive(path.join(dir, 'a.bin'), { size: 100, chunks: [{ hash: 'h1', offset: 0, length: 100 }] })
361 transfer.startReceive(path.join(dir, 'b.bin'), { size: 200, chunks: [{ hash: 'h2', offset: 0, length: 200 }] })
360 await transfer.startReceive(path.join(dir, 'a.bin'), { size: 100, chunks: [{ hash: 'h1', offset: 0, length: 100 }] })
361 await transfer.startReceive(path.join(dir, 'b.bin'), { size: 200, chunks: [{ hash: 'h2', offset: 0, length: 200 }] })
362362
363363 const active = transfer.listActive()
364364 t.is(active.length, 2)