Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960import type { Files } from "../files.ts";import { Doc } from "./doc.ts";
/** One `Files` instance's open docs: a path's `Doc`, and whether a write to it came from `files` itself. */interface Entry { readonly doc: Doc; applyingExternal: boolean;}
export interface FileDocs { /** The shared `Doc` for `path`, created and seeded from `files.read(path)` on first use. */ open(path: string): Doc;}
const registry = new WeakMap<Files, Map<string, Entry>>();
/** * The Loro docs behind a `Files` instance (D16), one per path, shared by every panel open on that * path. Memoized per `Files` in a `WeakMap` so unrelated `Files` instances (tests, other projects) * never share state. * * Keeps each doc and `files` in sync without an echo loop: a local edit (the doc changing while * `applyingExternal` is false) writes `files`; an external `files.write` replaces the doc's text * with no base, so Loro diffs it and cursors survive. `applyingExternal` suppresses the write that * would otherwise bounce straight back to `files`. */export function fileDocs(files: Files): FileDocs { let docs = registry.get(files); if (!docs) { docs = new Map(); registry.set(files, docs); files.watch((path) => { const entry = docs!.get(path); if (!entry) return; const text = files.read(path); if (text === undefined || text === entry.doc.text) return; entry.applyingExternal = true; entry.doc.write(text); entry.applyingExternal = false; }); }
return { open(path) { let entry = docs!.get(path); if (!entry) { const doc = Doc.create(files.read(path) ?? ""); entry = { doc, applyingExternal: false }; docs!.set(path, entry); doc.onChange(() => { if (entry!.applyingExternal) return; const text = entry!.doc.text; if (files.read(path) !== text) files.write(path, text); }); } return entry.doc; }, };}