Spaces:
Running
Running
| 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(); | |
| } | |