@beenotung/tslib
Version:
utils library in Typescript
107 lines (106 loc) • 3.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncStore = exports.asyncStoreSetItemResultsSymbol = exports.dirpathSymbol = exports.counterSymbol = void 0;
const tslib_1 = require("tslib");
const fs = tslib_1.__importStar(require("fs"));
const path = tslib_1.__importStar(require("path"));
const promises_1 = require("fs/promises");
const store_1 = require("./store");
const counter_1 = require("./counter");
exports.counterSymbol = Symbol.for('counter');
exports.dirpathSymbol = Symbol.for('dirpath');
exports.asyncStoreSetItemResultsSymbol = Symbol.for('asyncStoreSetItemResults');
class AsyncStore {
[exports.counterSymbol] = (0, counter_1.new_counter)();
[exports.dirpathSymbol];
[exports.asyncStoreSetItemResultsSymbol] = new Map();
constructor(dirpath) {
if (!fs.existsSync(dirpath)) {
fs.mkdirSync(dirpath);
}
this[exports.dirpathSymbol] = dirpath;
}
async clear() {
const fs = await (0, promises_1.readdir)(this[exports.dirpathSymbol]);
await Promise.all(fs.map(f => (0, promises_1.unlink)(path.join(this[exports.dirpathSymbol], f))));
}
async getItem(key) {
const b = await (0, promises_1.readFile)(this.keyToPath(key));
return b ? b.toString() : null;
}
async getObject(key) {
return JSON.parse((await this.getItem(key)));
}
async key(index) {
return (0, promises_1.readdir)(this[exports.dirpathSymbol]).then(fs => {
if (index < fs.length) {
return this.getItem(encodeURIComponent(fs[index]));
}
else {
return null;
}
});
}
async keys() {
return (0, promises_1.readdir)(this[exports.dirpathSymbol]).then(fs => fs.map(f => decodeURIComponent(f)));
}
async length() {
return (0, promises_1.readdir)(this[exports.dirpathSymbol]).then(fs => fs.length);
}
async removeItem(key) {
return (0, promises_1.unlink)(this.keyToPath(key));
}
setItem(key, value) {
const tasks = this[exports.asyncStoreSetItemResultsSymbol];
if (tasks.has(key)) {
const task = tasks.get(key);
if (task && !task.hasDone) {
task.cancel();
}
}
const filepath = this.keyToPath(key);
const tmpfile = filepath + '.' + Date.now() + '.' + this[exports.counterSymbol].next();
const status = {
hasCancel: false,
hasDone: false,
};
const p = (0, promises_1.writeFile)(tmpfile, value)
.then(() => {
if (status.hasCancel) {
return (0, promises_1.unlink)(tmpfile);
}
else {
return (0, promises_1.rename)(tmpfile, filepath);
}
})
.then(() => {
status.hasDone = true;
})
.catch(e => {
status.hasDone = true;
return Promise.reject(e);
});
const newTask = Object.assign(p, status, {
cancel: () => {
status.hasCancel = true;
},
});
tasks.set(key, newTask);
newTask.then(() => tasks.delete(key));
return newTask;
}
async setObject(key, value) {
if (value === undefined) {
return this.removeItem(key);
}
await this.setItem(key, JSON.stringify(value));
}
keyToPath(key) {
return path.join(this[exports.dirpathSymbol], encodeURIComponent(key));
}
static create(dirpath) {
const store = new AsyncStore(dirpath);
return (0, store_1.proxyStore)(store);
}
}
exports.AsyncStore = AsyncStore;