import * as Automerge from '@automerge/automerge'; import type { FileDocument } from '../types'; /** * Splice text into an Automerge document at a given path. * Wraps Automerge.splice() for the vault document shape. * * Only works when the target field is an Automerge text object. * For plain strings, use updateTextContent instead. */ export function spliceText( doc: Automerge.Doc, path: readonly string[], index: number, deleteCount: number, insert: string, ): Automerge.Doc { return Automerge.change(doc, (d) => { Automerge.splice(d, path as any, index, deleteCount, insert); }); } /** * Update the `content` field of a FileDocument to match `newContent`. * * For regular strings: assigns directly (plain strings in Automerge are * replaced wholesale; this is the correct path for the PushworkFileDocument * schema which stores content as `string | Uint8Array`). * * For legacy immutable strings (RawString / ImmutableString): assigns directly. * For Automerge text objects: uses Automerge.updateText for efficient * character-level diffing. */ export function updateTextContent( doc: Automerge.Doc, newContent: string, ): Automerge.Doc { const current = readDocContent(doc); if (current === newContent) return doc; return Automerge.change(doc, (d) => { const content = d.content as unknown; if (typeof content === 'string') { // Plain string: direct assignment d.content = newContent as unknown as T['content']; } else if (Automerge.isImmutableString(content)) { // ImmutableString / RawString: direct assignment d.content = newContent as unknown as T['content']; } else { // Assume it's an Automerge text object Automerge.updateText(d, ['content'] as any, newContent); } }); } /** * Read the `content` field from a FileDocument, normalizing RawString to plain string. */ export function readDocContent(doc: Automerge.Doc): string { const content = doc.content as unknown; if (typeof content === 'string') return content; if (content instanceof Uint8Array) return ''; // RawString / ImmutableString fallback if (Automerge.isImmutableString(content)) { return content.val; } return ''; }