Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798import type { ChangeFn, Doc } from '@automerge/automerge'import bs58check from 'bs58check'
export type AutomergeUrl = string & { __documentUrl: true }export type DocumentId = string & { __documentId: true }export type Heads = string[] & { __automergeUrlHeads: unknown }export type StorageKey = string[]
export interface DocumentLoadOptions { readonly priority?: 'interactive' | 'background' readonly signal?: AbortSignal}
export interface StorageAdapterInterface { load(key: StorageKey): Promise<Uint8Array | undefined> save(key: StorageKey, data: Uint8Array): Promise<void> saveBatch(entries: Array<[StorageKey, Uint8Array]>): Promise<void> remove(key: StorageKey): Promise<void> loadRange(prefix: StorageKey): Promise<Array<{ key: StorageKey; data: Uint8Array }>> removeRange(prefix: StorageKey): Promise<void>}
export interface ChangePayload<T> { readonly handle: DocHandle<T> readonly doc: Doc<T> readonly message?: string readonly patches?: readonly unknown[] readonly patchInfo: { readonly before: Doc<T> readonly after: Doc<T> }}
export interface DocHandle<T> { readonly url: AutomergeUrl readonly documentId: string isReady(): boolean isDeleted(): boolean isUnloaded(): boolean doc(): Doc<T> history(): readonly unknown[] metadata(change?: string): { message?: string | null; time?: number; actor?: string } | undefined change(callback: ChangeFn<T>, options?: { message?: string }): void changeAt(heads: Heads, callback: ChangeFn<T>, options?: { message?: string }): Heads | undefined update(callback: (doc: Doc<T>) => Doc<T>): void merge(other: DocHandle<T>): void on(event: 'change', listener: (payload: ChangePayload<T>) => void): void off(event: 'change', listener: (payload: ChangePayload<T>) => void): void}
export interface Repository { create<T>(initial?: T): DocHandle<T> /** Install/merge shared history at a reserved ID; never replace existing edits. */ import?<T>(binary: Uint8Array, args?: { docId?: DocumentId }): DocHandle<T> openReserved?<T>(url: AutomergeUrl, genesis: Uint8Array): Promise<DocHandle<T>> reservedDocumentUrl?(identity: Uint8Array): AutomergeUrl /** Classic's supported local load seam. Read before importing a reserved ID * so a detached document left by an interrupted initialization is not reset. */ readonly storageSubsystem?: { loadDoc(id: DocumentId): Promise<Doc<unknown> | null | undefined> } readonly handles?: Record<DocumentId, DocHandle<unknown>> find<T>(url: AutomergeUrl): Promise<DocHandle<T>> /** Optional demand/priority capability. Classic keeps its normal find seam. */ load?<T>(url: AutomergeUrl, options?: DocumentLoadOptions): Promise<DocHandle<T>> /** Background consumers may wait for initial workspace readiness. */ readonly backgroundReady?: Promise<void> startBackgroundSync?(): void delete(url: AutomergeUrl): void | Promise<void> flush(documentIds?: DocumentId[]): Promise<void> /** Acknowledge local durability while retaining unpublished intent. May * schedule background publication, but never waits for or acknowledges it. * Edition runtimes may persist their whole partition rather than selected IDs. */ flushLocal?(documentIds?: DocumentId[]): Promise<void>}
export function encodeHeads(heads: readonly string[]): Heads { return heads.map(head => { if (!/^[0-9a-f]{64}$/.test(head)) throw new Error(`Invalid Automerge head: ${head}`) const bytes = new Uint8Array(head.length / 2) for (let index = 0; index < bytes.length; index += 1) { bytes[index] = Number.parseInt(head.slice(index * 2, index * 2 + 2), 16) } return bs58check.encode(bytes) }) as Heads}
export function decodeHeads(heads: Heads): string[] { return heads.map(head => { let bytes: Uint8Array try { bytes = bs58check.decode(head) } catch { throw new Error(`Invalid encoded Automerge head: ${head}`) } if (bytes.length !== 32 || bs58check.encode(bytes) !== head) throw new Error(`Invalid encoded Automerge head: ${head}`) return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('') })}