Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556import { Repo as ClassicRepo } from '@automerge/automerge-repo'import { afterEach, describe, expect, it, vi } from 'vitest'import { Repo as NativeRepo } from '../../atproto/automerge-repo-compat'import type { Repository } from '../../storage/document-runtime-contract'import type { PushworkDirectoryDocument } from '../../types/pushwork'import { DocumentManager } from '../../services/document-manager'
const cleanups: Array<() => Promise<void>> = []afterEach(async () => { for (const cleanup of cleanups.splice(0)) await cleanup() })
async function setup(edition: 'classic' | 'native') { const repo = edition === 'classic' ? new ClassicRepo({}) : new NativeRepo({ progressive: true }) const manager = new DocumentManager(repo as Repository) const parentUrl = manager.createFolder() const parent = await repo.find<PushworkDirectoryDocument>(parentUrl) cleanups.push(async () => { manager.dispose(); await (repo instanceof ClassicRepo ? repo.shutdown() : repo.close()) }) return { repo, manager, parentUrl, parent }}
describe('entry mutations with committed observer errors', () => { it.each(['classic', 'native'] as const)('%s retains published children and hands off the parent before mutation', async edition => { const { manager, parent, parentUrl } = await setup(edition) const observerError = new Error('observer exploded') const flush = vi.spyOn(manager as unknown as { flushTextWrite: (url: string) => Promise<void> }, 'flushTextWrite') .mockResolvedValue(undefined) const change = parent.change.bind(parent) vi.spyOn(parent, 'change').mockImplementation(((callback: Parameters<typeof parent.change>[0]) => { change(callback) throw observerError }) as typeof parent.change) await expect(manager.createFileInFolder(parentUrl, 'published.md')).rejects.toBe(observerError) expect(parent.doc().docs).toHaveLength(1) expect(flush).toHaveBeenCalledWith(parentUrl) })
it.each(['classic', 'native'] as const)('%s validates before linking and preserves orphan cleanup', async edition => { const { manager, parent, parentUrl } = await setup(edition) await expect(manager.addFileToFolder(parentUrl, 'automerge:missing' as never, 'missing.md', undefined, () => { throw new Error('prelink guard') })).rejects.toThrow('prelink guard') expect(parent.doc().docs).toEqual([]) })
it('deletes linked md/png leaves and still permits direct orphan cleanup', async () => { const { manager, parent, parentUrl } = await setup('classic') for (const type of ['md', 'png']) { const child = manager.createFile(`${type}.${type}`) parent.change(doc => { doc.docs.push({ name: `${type}.${type}`, type, url: child }) }) await manager.deleteFile(child, parentUrl) expect(parent.doc().docs.some(entry => entry.url === child)).toBe(false) } const orphan = manager.createFile('orphan.md') await expect(manager.deleteFile(orphan, parentUrl)).resolves.toBeUndefined() })})