flash-store
Version:
FlashStore is a Key-Value persistent storage with easy to use ES6 Map-like API(both Async and Sync support), powered by LevelDB and TypeScript.
146 lines • 5.34 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
import cuid from 'cuid';
import { StateSwitch, } from 'state-switch';
import { log, } from './config';
import { FlashStore, } from './flash-store';
export class FlashStoreSync {
constructor(workdir) {
this.workdir = workdir;
log.verbose('CacheStore', 'constructor(%s)', workdir);
workdir = workdir || '.flash-store-sync';
this.asyncBusyDict = {};
this.asyncBusyState = new StateSwitch('Busy:' + workdir.split('/').pop(), // get the latest folder name
log);
this.cacheMap = new Map();
this.flashStore = new FlashStore(workdir);
this.asyncBusyAdd(this.loadStoreToCache());
}
loadStoreToCache() {
var e_1, _a;
return __awaiter(this, void 0, void 0, function* () {
this.cacheMap.clear();
try {
for (var _b = __asyncValues(this.flashStore), _c; _c = yield _b.next(), !_c.done;) {
const [key, val] = _c.value;
this.cacheMap.set(key, val);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
});
}
asyncBusyAdd(task) {
this.asyncBusyState.on(true);
const id = cuid();
this.asyncBusyDict[id] = task.finally(() => {
delete this.asyncBusyDict[id];
if (Object.keys(this.asyncBusyDict).length <= 0) {
this.asyncBusyState.off(true);
}
});
}
version() {
return this.flashStore.version();
}
/**
*
* Async methods:
*
*/
close() {
return __awaiter(this, void 0, void 0, function* () {
yield this.ready();
yield this.flashStore.close();
});
}
destroy() {
return __awaiter(this, void 0, void 0, function* () {
this.clear();
// add destroy task at the end of the event loop
this.asyncBusyState.ready('off')
.then(() => this.flashStore.destroy()).catch(console.error);
});
}
ready() {
return __awaiter(this, void 0, void 0, function* () {
yield this.asyncBusyState.ready('off');
});
}
/*******************************************************
*
*
* The following methods is all for ES6 Map Interface
*
*
*******************************************************/
get size() {
return this.cacheMap.size;
}
get [Symbol.toStringTag]() {
return 'FlashStoreSync';
}
[Symbol.iterator]() {
return this.cacheMap[Symbol.iterator]();
}
entries() {
return this.cacheMap.entries();
}
keys() {
return this.cacheMap.keys();
}
values() {
return this.cacheMap.values();
}
clear() {
this.asyncBusyAdd(this.flashStore.clear());
return this.cacheMap.clear();
}
delete(key) {
this.asyncBusyAdd(this.flashStore.delete(key));
return this.cacheMap.delete(key);
}
/**
* Do not mutate the key/value in the forEach loop!
*/
forEach(callbackfn, thisArg) {
/**
* 1. no need to call flashStore
* 2. callbackfn should not mutate the data, or the data will be lost sync between cache & store
*/
return this.cacheMap.forEach(callbackfn, thisArg);
}
get(key) {
return this.cacheMap.get(key);
}
has(key) {
return this.cacheMap.has(key);
}
set(key, value) {
this.asyncBusyAdd(this.flashStore.set(key, value));
this.cacheMap.set(key, value);
return this;
}
}
FlashStoreSync.VERSION = FlashStore.VERSION;
export default FlashStoreSync;
//# sourceMappingURL=flash-store-sync.js.map