Bonsai-Chat-WebGPU / scripts /test-persistence.mjs
WaveCut's picture
Release browser-local Bonsai WebGPU chat
0ed8124 verified
Raw
History Blame Contribute Delete
3.37 kB
import { chromium } from '@playwright/test';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createServer as createViteServer } from 'vite';
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const memoryKey = '__bonsai_persistence_probe__';
const conversationId = '__bonsai_conversation_probe__';
let browser;
let page;
let vite;
try {
vite = await createViteServer({
root,
logLevel: 'error',
server: { host: '127.0.0.1', port: 0 },
plugins: [{
name: 'persistence-probe-page',
configureServer(server) {
server.middlewares.use('/persistence-probe.html', (_request, response) => {
response.setHeader('Content-Type', 'text/html; charset=utf-8');
response.end('<!doctype html><title>Persistence probe</title>');
});
},
}],
});
await vite.listen();
const address = vite.httpServer?.address();
if (!address || typeof address === 'string') throw new Error('Vite persistence probe did not expose a TCP port');
browser = await chromium.launch({ headless: true });
page = await browser.newPage();
await page.goto(`http://127.0.0.1:${address.port}/persistence-probe.html`);
await page.evaluate(async ({ memoryKey, conversationId }) => {
const idb = await import('/src/lib/idb.ts');
await idb.deleteMemory(memoryKey);
await idb.putMemory(memoryKey, 'survives reload');
await idb.saveConversation({
id: conversationId,
title: 'Persistence probe',
modelId: 'bonsai-1.7b',
updatedAt: 0,
messages: [{ role: 'user', content: 'keep locally' }],
});
}, { memoryKey, conversationId });
await page.reload({ waitUntil: 'domcontentloaded' });
const persisted = await page.evaluate(async ({ memoryKey, conversationId }) => {
const idb = await import('/src/lib/idb.ts');
const memory = await idb.getMemory(memoryKey);
const conversation = await idb.loadConversation(conversationId);
return { memory, conversation };
}, { memoryKey, conversationId });
if (persisted.memory?.value !== 'survives reload') {
throw new Error(`Memory did not survive reload: ${JSON.stringify(persisted.memory)}`);
}
if (persisted.conversation?.messages?.[0]?.content !== 'keep locally') {
throw new Error(`Conversation did not survive reload: ${JSON.stringify(persisted.conversation)}`);
}
console.log('IndexedDB persistence passed: memory and conversation survived a page reload');
} finally {
if (page) {
await page.evaluate(async ({ memoryKey, conversationId }) => {
const idb = await import('/src/lib/idb.ts');
await idb.deleteMemory(memoryKey).catch(() => undefined);
const request = indexedDB.open('bonsai-webgpu-chat', 1);
await new Promise((resolve) => {
request.onsuccess = () => {
const database = request.result;
const transaction = database.transaction('conversations', 'readwrite');
transaction.objectStore('conversations').delete(conversationId);
transaction.oncomplete = () => { database.close(); resolve(); };
transaction.onerror = () => { database.close(); resolve(); };
};
request.onerror = () => resolve();
});
}, { memoryKey, conversationId }).catch(() => undefined);
}
await browser?.close();
await vite?.close();
}