import {onCleanup} from "solid-js" import {Doc, DocHandle, DocHandleChangePayload} from "@automerge/automerge-repo" import autoproduce from "./autoproduce.js" import {createStore, produce, reconcile, type Store} from "solid-js/store" const cache = new WeakMap< DocHandle, { refs: number store: Store> cleanup(): void } >() /** * make a fine-grained live view of a document from its handle. * @param handle an Automerge * [DocHandle](https://automerge.org/automerge-repo/classes/_automerge_automerge_repo.DocHandle.html) */ export default function makeDocumentProjection(handle: DocHandle) { onCleanup(() => { const item = cache.get(handle)! if (!item) return if (!item.refs--) { item.cleanup() } }) if (cache.has(handle)) { const item = cache.get(handle)! item.refs++ return item.store as Doc } const [doc, set] = createStore>(handle.doc()) cache.set(handle, { refs: 0, store: doc, cleanup() { handle.off("change", patch) handle.off("delete", ondelete) }, }) function patch(payload: DocHandleChangePayload) { set(produce(autoproduce(payload))) } function ondelete() { set(reconcile({} as Doc)) } handle.on("change", patch) handle.on("delete", ondelete) handle.whenReady().then(() => { set(handle.doc()) }) return doc }