// 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} */ 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'); }); });