chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
// The drive browser over the real SQLite actor storage. The package's own
// tests page a fake whose cursor is an index; this storage returns an rkey and
// stops sending one on a short page, so the paging loop is only honest here.
import Database from 'better-sqlite3';
import { describe, expect, it } from 'vitest';
import {
CID,
cborEncodeDagCbor,
cidToString,
createBlobCid,
createCid,
} from '../packages/core/src/repo.js';
import { createDriveBrowser } from '../packages/drive/src/browser.js';
import { createActorStorage } from '../packages/storage-sqlite/src/index.js';
const DID = 'did:plc:drivestorage';
// The folder record every nested file names by key.
const FOLDER_RKEY = '3rfolder0001';
// Above the browser's 100-record page size, so paging runs several times and
// the final short page ends it.
const FILE_COUNT = 250;
async function seeded() {
const actorStorage = createActorStorage(new Database(':memory:'));
await actorStorage.setDid(DID);
const folderValue = cborEncodeDagCbor({
$type: 'dev.pdsjs.drive.folder',
name: 'photos',
createdAt: '2026-08-14T00:00:00.000Z',
});
await actorStorage.putRecord(
`at://${DID}/dev.pdsjs.drive.folder/${FOLDER_RKEY}`,
cidToString(await createCid(folderValue)),
'dev.pdsjs.drive.folder',
FOLDER_RKEY,
folderValue,
);
/** @type {Map<string, Uint8Array>} */
const blobStore = new Map();
for (let index = 0; index < FILE_COUNT; index += 1) {
const data = new TextEncoder().encode(`contents of file ${index}`);
blobStore.set(cidToString(await createBlobCid(data)), data);
const value = cborEncodeDagCbor({
$type: 'dev.pdsjs.drive.file',
name: `file-${String(index).padStart(3, '0')}.txt`,
// Half at the top level, half nested, so both branches page.
...(index % 2 === 0 ? { folder: FOLDER_RKEY } : {}),
parts: [
{
$type: 'blob',
ref: new CID(await createBlobCid(data)),
mimeType: 'application/octet-stream',
size: data.length,
},
],
mimeType: 'text/plain',
createdAt: '2026-08-14T00:00:00.000Z',
});
const rkey = `3rkey${String(index).padStart(4, '0')}`;
await actorStorage.putRecord(
`at://${DID}/dev.pdsjs.drive.file/${rkey}`,
cidToString(await createCid(value)),
'dev.pdsjs.drive.file',
rkey,
value,
);
}
const blobs = /** @type {any} */ ({
get: async (/** @type {string} */ _did, /** @type {string} */ cid) => {
const data = blobStore.get(cid);
return data ? { data, mimeType: 'application/octet-stream' } : null;
},
});
return createDriveBrowser({
actorStorage: /** @type {any} */ (actorStorage),
blobs,
getDid: async () => DID,
});
}
describe('drive browser over sqlite storage', () => {
it('pages every record, not just the first page', async () => {
const browser = await seeded();
const root = await browser.listFolder('');
expect(root?.totalFiles).toBe(FILE_COUNT);
expect(root?.files).toHaveLength(FILE_COUNT / 2);
expect(root?.folders).toEqual([
{
rkey: FOLDER_RKEY,
name: 'photos',
files: FILE_COUNT / 2,
size: expect.any(Number),
createdAt: '2026-08-14T00:00:00.000Z',
},
]);
});
it('lists a nested folder across pages', async () => {
const browser = await seeded();
const nested = await browser.listFolder(FOLDER_RKEY);
expect(nested?.files).toHaveLength(FILE_COUNT / 2);
expect(nested?.folders).toEqual([]);
});
it('reads the bytes of one file back', async () => {
const browser = await seeded();
const file = await browser.readFile('3rkey0000');
expect(new TextDecoder().decode(file?.bytes)).toBe('contents of file 0');
expect(file?.mimeType).toBe('text/plain');
});
});