(id: string, data: Uint8Array)
| 172 | } |
| 173 | |
| 174 | async function saveUpdate(id: string, data: Uint8Array): Promise<void> { |
| 175 | const previous = saveQueues.get(id) ?? Promise.resolve() |
| 176 | const current = previous.then(async () => { |
| 177 | await ensureRoot() |
| 178 | const filePath = docPath(id) |
| 179 | const tempPath = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}` |
| 180 | const doc = new Y.Doc() |
| 181 | try { |
| 182 | const existing = await readUpdate(id) |
| 183 | if (existing) Y.applyUpdate(doc, existing) |
| 184 | Y.applyUpdate(doc, data) |
| 185 | await fs.writeFile(tempPath, Y.encodeStateAsUpdate(doc)) |
| 186 | await fs.rename(tempPath, filePath) |
| 187 | } catch (error) { |
| 188 | await fs.unlink(tempPath).catch(() => undefined) |
| 189 | throw error |
| 190 | } finally { |
| 191 | doc.destroy() |
| 192 | } |
| 193 | }) |
| 194 | saveQueues.set(id, current.catch(() => undefined)) |
| 195 | await current.finally(() => { |
| 196 | if (saveQueues.get(id) === current) saveQueues.delete(id) |
| 197 | }) |
| 198 | } |
| 199 | |
| 200 | async function loadDoc(id: string): Promise<Y.Doc | null> { |
| 201 | const data = await readUpdate(id) |
nothing calls this directly
no test coverage detected