Files

47 lines
1.2 KiB
JavaScript

import { link, mkdir, open, rename, rm } from 'node:fs/promises'
import { randomUUID } from 'node:crypto'
import { dirname } from 'node:path'
async function syncDirectory(path) {
const handle = await open(path, 'r')
try {
await handle.sync()
} finally {
await handle.close()
}
}
async function temporaryFile(path, bytes, mode) {
await mkdir(dirname(path), { recursive: true })
const temporary = `${path}.${randomUUID()}.tmp`
const handle = await open(temporary, 'wx', mode)
try {
await handle.writeFile(bytes)
await handle.sync()
} finally {
await handle.close()
}
return temporary
}
export async function durableReplace(path, bytes, mode = 0o600) {
const temporary = await temporaryFile(path, bytes, mode)
try {
await rename(temporary, path)
await syncDirectory(dirname(path))
} catch (error) {
await rm(temporary, { force: true })
throw error
}
}
export async function durableCreate(path, bytes, mode = 0o600) {
const temporary = await temporaryFile(path, bytes, mode)
try {
await link(temporary, path)
await syncDirectory(dirname(path))
} finally {
await rm(temporary, { force: true })
}
}