54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
import type { IDataStore } from "../repo";
|
|
import * as Fs from "fs";
|
|
import * as Path from "path";
|
|
export default class FSDataStore implements IDataStore {
|
|
#path: string;
|
|
#l = false;
|
|
|
|
constructor(path: string) {
|
|
this.#path = path;
|
|
}
|
|
|
|
async get(name: string) {
|
|
return Fs.promises.readFile(Path.join(this.#path, name));
|
|
}
|
|
|
|
async has(name: string) {
|
|
return Fs.promises
|
|
.access(Path.join(this.#path, name))
|
|
.then(() => true)
|
|
.catch(() => false);
|
|
}
|
|
|
|
async set(name: string, data: Uint8Array) {
|
|
const path = Path.join(this.#path, name);
|
|
await Fs.promises.mkdir(Path.dirname(path), { recursive: true });
|
|
await Fs.promises.writeFile(path, data);
|
|
}
|
|
|
|
async _delete(name: string) {
|
|
await Fs.promises.rm(Path.join(this.#path, name));
|
|
}
|
|
|
|
async getLock() {
|
|
//TODO: This is not atomic yet! FIX
|
|
while ((await this.has("lock")) || this.#l) {
|
|
try {
|
|
let con = (await this.get("lock")).toString("utf-8");
|
|
|
|
if (Number(con) < Date.now() - 10000) break;
|
|
await new Promise((y) => setTimeout(y, 10));
|
|
} catch (err) {}
|
|
}
|
|
this.#l = true;
|
|
|
|
await this.set("lock", Buffer.from(`${Date.now()}`));
|
|
|
|
this.#l = false;
|
|
|
|
return async () => {
|
|
await this._delete("lock");
|
|
};
|
|
}
|
|
}
|