chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
// Shared contract for the ActorStoragePort methods that let commits drop the
// blocks they leave unreachable. Every adapter that has them runs this suite.
import { describe, expect, it } from 'vitest';
/** @typedef {Required<import('@pdsjs/core/ports').ActorStoragePort>} BlockStorage */
/**
* @param {string} name
* @param {() => Promise<BlockStorage>} open
*/
export function runBlockStorageConformance(name, open) {
describe(`${name}: blocks`, () => {
it('list in CID order a page at a time, and delete', async () => {
const storage = await open();
for (const cid of ['c', 'a', 'b']) {
await storage.putBlock(cid, new Uint8Array([cid.charCodeAt(0)]));
}
const first = await storage.listBlocks(null, 2);
expect(first.blocks.map((b) => b.cid)).toEqual(['a', 'b']);
expect(first.cursor).toBe('b');
const rest = await storage.listBlocks(first.cursor, 2);
expect(rest.blocks.map((b) => [b.cid, [...b.data]])).toEqual([
['c', [99]],
]);
expect(rest.cursor).toBeNull();
await storage.deleteBlocks(['a', 'c']);
const left = await storage.listBlocks(null, 10);
expect(left.blocks.map((b) => b.cid)).toEqual(['b']);
});
it('delete and look up more CIDs than one statement binds', async () => {
const storage = await open();
const cids = Array.from({ length: 250 }, (_, i) => `cid${1000 + i}`);
for (const cid of cids) {
await storage.putBlock(cid, new Uint8Array([1]));
await storage.putRecord(
`at://did:x/c/${cid}`,
cid,
'c',
cid,
new Uint8Array([1]),
);
}
expect(await storage.recordCidsAmong(cids)).toHaveLength(250);
await storage.deleteBlocks(cids.slice(0, 240));
const left = await storage.listBlocks(null, 500);
expect(left.blocks.map((b) => b.cid)).toEqual(cids.slice(240));
});
it('say which CIDs a record still has', async () => {
const storage = await open();
const value = new Uint8Array([1]);
await storage.putRecord('at://did:x/c/1', 'kept', 'c', '1', value);
await storage.putRecord('at://did:x/c/2', 'kept', 'c', '2', value);
expect(await storage.recordCidsAmong(['kept', 'gone'])).toEqual(['kept']);
});
it('are not collected until a sweep says so', async () => {
const storage = await open();
expect(await storage.getBlocksCollected()).toBe(false);
await storage.setBlocksCollected(true);
expect(await storage.getBlocksCollected()).toBe(true);
await storage.setBlocksCollected(false);
expect(await storage.getBlocksCollected()).toBe(false);
});
});
}