UNPKG

@beenotung/tslib

Version:
107 lines (106 loc) 3.74 kB
"use strict"; 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;