// A draft outlives its composer, and a reload: written to storage once typing // pauses, read back by the next page, dropped when emptied. Browser-only state. import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { stripTypeScriptTypes } from 'node:module'; import test from 'node:test'; async function load(path, prelude = '') { const source = stripTypeScriptTypes((await readFile(new URL(path, import.meta.url), 'utf8')).replace(/^import [\s\S]*?;$/gm, '')); return import(`data:text/javascript;base64,${Buffer.from(prelude + source).toString('base64')}`); } const store = new Map(); globalThis.localStorage = { getItem: (key) => store.get(key) ?? null, setItem: (key, value) => store.set(key, String(value)), removeItem: (key) => store.delete(key), }; const { withoutMarkers } = await load('../src/lib/chat/attachments.ts'); globalThis.__drafts = { withoutMarkers }; // Each call is a page load: a module of its own, with the same storage. let pages = 0; const page = () => load('../src/lib/chat/drafts.ts', `const SvelteMap = Map; const { withoutMarkers } = globalThis.__drafts; /* page ${++pages} */\n`); const paused = () => new Promise((resolve) => setTimeout(resolve, 400)); test('a draft is saved once typing pauses and the next page starts with it', async () => { const { draftOf } = await page(); const draft = draftOf('s1'); assert.equal(draft.text, ''); draft.text = 'half a thought'; assert.equal(store.size, 0, 'nothing is written on every keystroke'); await paused(); const next = (await page()).draftOf('s1'); assert.equal(next.text, 'half a thought'); assert.equal((await page()).draftOf('s2').text, '', 'another session has its own'); }); test('a draft keeps its words and loses the markers of images that do not survive a reload', async () => { const { draftOf } = await page(); draftOf('s3').text = 'look at [Image #1] and also [Image #2], then fix it'; await paused(); assert.equal((await page()).draftOf('s3').text, 'look at and also, then fix it'); }); test('an emptied or sent draft leaves nothing behind', async () => { const { draftOf } = await page(); const draft = draftOf('s4'); draft.text = 'to be sent'; await paused(); assert.ok(store.has('albedo.draft.v1:s4')); draft.text = ''; await paused(); assert.equal(store.has('albedo.draft.v1:s4'), false); assert.equal((await page()).draftOf('s4').text, ''); });