key-file-storage
Version:
Simple key-value storage directly on file system, maps each key to a separate file.
163 lines (141 loc) • 4.82 kB
text/typescript
import keyFileBasic from './key-file-basic';
export interface KeyFileStorage {
[key: string]: any;
[index: number]: any;
<T, U = T>(key: string | number, value: T, callback?: (error: any) => U): Promise<U>;
<T = any, U = T>(key: string | number, callback?: (error: any, value?: T) => U): Promise<U>;
new <U = boolean>(key: string | number, callback?: (error: any) => U): Promise<U>;
new <U = boolean>(callback?: (error: any) => U): Promise<U>;
<U = boolean>(callback?: (error: any) => U): Promise<U>;
}
export default function createStore(storagePath: string, cache: { [x: string]: any }): KeyFileStorage {
var kfb = keyFileBasic(storagePath, cache);
// The produced promise and callback function related to the latest async 'in' operator
var hasAsyncHandler: any = null,
hasAsyncPromise: Promise<unknown> | null = null;
/* async has */
var hasAsyncWrap = {
has: function (target: any, property: string) {
var promise = kfb.hasAsync(property);
if (hasAsyncHandler) {
callbackizePromise(promise, hasAsyncHandler);
hasAsyncHandler = null;
} else {
hasAsyncPromise = promise;
}
return false; // No synchronous answer.
},
};
var store = new Proxy(
function () {
var a1 = arguments[0],
a2 = arguments[1],
a3 = arguments[2];
switch (arguments.length) {
case 0:
if (hasAsyncPromise) {
a3 = hasAsyncPromise;
hasAsyncPromise = null;
return a3;
} else {
return new Proxy({}, hasAsyncWrap);
}
// break;
case 1:
if (typeof a1 === 'function') {
if (hasAsyncPromise) {
a3 = hasAsyncPromise;
hasAsyncPromise = null;
return callbackizePromise(a3, a1);
} else {
hasAsyncHandler = a1;
return new Proxy({}, hasAsyncWrap);
}
} else if (String(a1).slice(-1) === '/') {
/* async query pr */
return kfb.queryAsync(String(a1));
} else {
/* async get pr */
return kfb.getAsync(String(a1));
}
// break;
case 2:
if (typeof a2 === 'function') {
if (String(a1).slice(-1) === '/') {
/* async query cb */
return callbackizePromise(kfb.queryAsync(String(a1)), a2);
} else {
/* async get cb */
return callbackizePromise(kfb.getAsync(String(a1)), a2);
}
} else {
/* async set pr */
return kfb.setAsync(String(a1), a2);
}
// break;
case 3:
if (typeof a3 === 'function') {
/* async set cb */
return callbackizePromise(kfb.setAsync(String(a1), a2), a3);
}
// break;
}
throw new Error('Invalid input argument(s).');
},
{
/* sync set */
set: function (target, property, value, receiver) {
kfb.setSync(String(property), value);
return true;
},
get: function (target, property, receiver) {
if (String(property).slice(-1) === '/') {
/* sync query */
return kfb.querySync(String(property));
} else {
/* sync get */
return kfb.getSync(String(property));
}
},
/* sync delete */
deleteProperty: function (target, property) {
return kfb.deleteSync(String(property));
},
/* sync has */
has: function (target, property) {
return kfb.hasSync(String(property));
},
/* async delete */
construct: function (target, argumentsList, newTarget) {
var a1 = argumentsList[0],
a2 = argumentsList[1];
switch (argumentsList.length) {
case 0:
return kfb.clearAsync();
// break;
case 1:
if (typeof a1 === 'function') {
return callbackizePromise(kfb.clearAsync(), a1);
} else {
return kfb.deleteAsync(String(a1));
}
// break;
case 2:
return callbackizePromise(kfb.deleteAsync(String(a1)), a2);
// break;
}
throw new Error('Invalid input argument(s).');
},
},
);
return store as any;
function callbackizePromise(promise: Promise<unknown>, callback: any) {
if (typeof callback === 'function') {
return promise.then(function (data) {
return callback(undefined, data);
}, callback);
} else {
return promise;
}
}
}