import { _ as __awaiter, a as __generator } from './_tslib-ca2dd4fc.js';
import { handler } from './handler.esm.js';
import localForage from 'localforage';
import { mergeDeepWithKey, mergeDeepWith, concat, mergeWithKey, mergeWith, mergeDeepRight, mergeRight } from 'ramda';
// todo: rename keys to rows / row, values to keys
/**
* @description -> externally, we are using the same API as localForage,
* with the exception of the dropInstance interface, which, while
* still available, has been split out into three distinct calls.
* Also, are using `.then` instead of the callback approach, and
* always catch an error.
*
* Of note are the extensions to the generic interface:
* - mergeItem (with a number of merge strategies available)
* - getKeyValue
* - deleteItemKey
* - hasKey
* - hasKeyValue
*
* Note:
* Even if undefined is saved, null will be returned by getItem().
* This is due to a limitation in localStorage, and for compatibility
* reasons localForage cannot store the value undefined.
*
* Usage Options:
* 1. Exactly the same interface as localForage
* 2. With a currying function applied to the result
* 3. Modify the value returned (with or without curry)
* 4. Define error suppression
*
* @category forage
* @namespace forage
*/
var forage = {
/**
* @description get the object of a specific row if it exists.
* @
* @param {string} key
* @param {string} logger
* @param {number} returner
* @param {boolean} before
* @param {string} store
* @returns {Promise<object|string|*>}
* @function getItem
* @memberof forage
*/
getItem: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, logger = _b.logger, returner = _b.returner, before = _b.before, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _b.sent();
if (!before) return [3 /*break*/, 3];
return [4 /*yield*/, handler.maybeCurry(curry || null)(key)];
case 2:
_a = _b.sent();
return [3 /*break*/, 4];
case 3:
_a = key;
_b.label = 4;
case 4:
key = _a;
return [2 /*return*/, handler.returner(storage.getItem(key).then(function (v) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, !before ? handler.maybeCurry(curry || null)(v) : v];
});
}); }).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
}))(returner)];
}
});
});
};
},
/**
* @description get the value of a specific key in a row if it exists.
*
* @param {string} key
* @param {string} value
* @param {function} curry
* @param {string} logger
* @param {number|string} returner
* @returns {Promise<object|string|*>}
* @function getKeyValue
* @memberof forage
*/
getKeyValue: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, value = _b.value, logger = _b.logger, returner = _b.returner, before = _b.before, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _b.sent();
if (!before) return [3 /*break*/, 3];
return [4 /*yield*/, handler.maybeCurry(curry || null)(value)];
case 2:
_a = _b.sent();
return [3 /*break*/, 4];
case 3:
_a = value;
_b.label = 4;
case 4:
value = _a;
return [2 /*return*/, handler.returner(storage.getItem(key).then(function (v) {
// console.log(v)
return !before ? handler.maybeCurry(curry || null)(v[value]) : v[value];
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
}))(returner)];
}
});
});
};
},
/**
* @description set an row if it exists, completely overwrite it if
* it does not exist.
*
* @param {string} key
* @param {string} value
* @param {...Function|string|number} restArgs
* @param {function} restArgs.curry
* @param {string} restArgs.logger
* @param {number} restArgs.returner
* @returns {Promise<object|string|*>}
* @function setItem
* @memberof forage
*/
setItem: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, value = _b.value, logger = _b.logger, returner = _b.returner, before = _b.before, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
storage = _defineStore({ store: store });
if (!before) return [3 /*break*/, 2];
return [4 /*yield*/, handler.maybeCurry(curry || null)(value)];
case 1:
_a = _b.sent();
return [3 /*break*/, 3];
case 2:
_a = value;
_b.label = 3;
case 3:
value = _a;
return [2 /*return*/, handler.returner(storage.setItem(key, value).then(function (v) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, !before ? handler.maybeCurry(curry || null)(v) : v];
});
}); }).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
}))(returner)];
}
});
});
};
},
/**
*
* @param {...Function|string|number} restArgs
* @param {number} restArgs.index
* @param {function} restArgs.curry
* @param {string} restArgs.logger
* @param {number} restArgs.returner
* @returns {Promise<string>}
* @function setItem
* @memberof forage
*/
key: function (_a) {
var _b = _a === void 0 ? {} : _a, index = _b.index, logger = _b.logger, returner = _b.returner, before = _b.before, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _b.sent();
if (!before) return [3 /*break*/, 3];
return [4 /*yield*/, handler.maybeCurry(curry || null)(index)];
case 2:
_a = _b.sent();
return [3 /*break*/, 4];
case 3:
_a = index;
_b.label = 4;
case 4:
index = _a;
return [2 /*return*/, handler.returner(storage.key(index).then(function (v) {
return !before ? handler.maybeCurry(curry || null)(v) : v;
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
}))(returner)];
}
});
});
};
},
/**
* @description Merging data shouldn't be hard, so that logic is in here.
* There are so many ways to do it though, that the caller can define
* merge strategy. This is a "prebuilt" Curry.
*
* See https://ramdajs.com/docs/ for the exact features we are using.
*
* The default is to use the `deepWithKey` approach.
*
* @param {string} key
* @param {string|object|array} value
* @param {string} type
* @param {...Function|string|number} restArgs
* @param {function} restArgs.curry
* @param {string} restArgs.logger
* @param {number} restArgs.returner
* @returns {Promise<object|string|*>}
* @function mergeItem
* @memberof forage
*/
mergeItem: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, value = _b.value, type = _b.type, returner = _b.returner, logger = _b.logger, before = _b.before, store = _b.store;
var concatValues = function (k, l, r) { return k === 'values' ? concat(l, r) : r; };
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a, _b, _c;
var _this = this;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
storage = _defineStore({ store: store });
if (!before) return [3 /*break*/, 2];
return [4 /*yield*/, handler.maybeCurry(curry || null)(value)];
case 1:
_a = _d.sent();
return [3 /*break*/, 3];
case 2:
_a = value;
_d.label = 3;
case 3:
value = _a;
_c = (_b = handler).returner;
return [4 /*yield*/, storage.getItem(key).then(function (v) { return __awaiter(_this, void 0, void 0, function () {
var val, _a, _b, _c, _d, err_1, err_2, err_3, err_4, err_5;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
_a = type;
switch (_a) {
case 'custom': return [3 /*break*/, 1];
case 'right': return [3 /*break*/, 5];
case 'deepRight': return [3 /*break*/, 8];
case 'with': return [3 /*break*/, 11];
case 'withKey': return [3 /*break*/, 14];
case 'deepWith': return [3 /*break*/, 15];
case 'deepWithKey': return [3 /*break*/, 16];
}
return [3 /*break*/, 16];
case 1:
_e.trys.push([1, 4, , 5]);
_c = (_b = storage).setItem;
_d = [key];
return [4 /*yield*/, handler.maybeCurry(curry)(v)];
case 2: return [4 /*yield*/, _c.apply(_b, _d.concat([_e.sent()]))];
case 3:
val = _e.sent();
return [2 /*return*/, val];
case 4:
err_1 = _e.sent();
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err_1)(logger)];
case 5:
_e.trys.push([5, 7, , 8]);
return [4 /*yield*/, storage.setItem(key, mergeRight(v, value))];
case 6:
val = _e.sent();
return [2 /*return*/, val];
case 7:
err_2 = _e.sent();
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err_2)(logger)];
case 8:
_e.trys.push([8, 10, , 11]);
return [4 /*yield*/, storage.setItem(key, mergeDeepRight(v, value))];
case 9:
val = _e.sent();
return [2 /*return*/, val];
case 10:
err_3 = _e.sent();
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err_3)(logger)];
case 11:
_e.trys.push([11, 13, , 14]);
return [4 /*yield*/, storage.setItem(key, mergeWith(concat, v, value))];
case 12:
val = _e.sent();
return [2 /*return*/, val];
case 13:
err_4 = _e.sent();
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err_4)(logger)];
case 14:
try {
return [2 /*return*/, storage.setItem(key, mergeWithKey(concatValues, v, value))];
}
catch (err) {
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err)(logger)];
}
_e.label = 15;
case 15:
try {
return [2 /*return*/, storage.setItem(key, mergeDeepWith(concat, v, value))];
}
catch (err) {
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err)(logger)];
}
_e.label = 16;
case 16:
_e.trys.push([16, 18, , 19]);
return [4 /*yield*/, storage.setItem(key, mergeDeepWithKey(concatValues, v, value))];
case 17:
val = _e.sent();
return [2 /*return*/, val];
case 18:
err_5 = _e.sent();
/* istanbul ignore next */
return [2 /*return*/, handler.logger(err_5)(logger)];
case 19: return [2 /*return*/];
}
});
}); }).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
case 4: return [2 /*return*/, _c.apply(_b, [_d.sent()])(returner)];
}
});
});
};
},
removeItem: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, logger = _b.logger, returner = _b.returner, before = _b.before, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var _a, storage, _b, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
if (!before) return [3 /*break*/, 2];
return [4 /*yield*/, handler.maybeCurry(curry || null)(key)];
case 1:
_a = _d.sent();
return [3 /*break*/, 3];
case 2:
_a = key;
_d.label = 3;
case 3:
key = _a;
return [4 /*yield*/, _defineStore({ store: store })];
case 4:
storage = _d.sent();
_c = (_b = handler).returner;
return [4 /*yield*/, storage.removeItem(key).then(function () {
return true; // !before ? handler.maybeCurry(curry || null)(true) : true
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
case 5: return [2 /*return*/, _c.apply(_b, [_d.sent()])(returner)];
}
});
});
};
},
deleteItemKey: function (key, value) {
var restArgs = [];
for (var _i = 2; _i < arguments.length; _i++) {
restArgs[_i - 2] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var args;
return __generator(this, function (_a) {
args = _mapArgs(restArgs);
return [2 /*return*/, localForage.getItem(key).then(function (val) {
if (typeof value === 'string') {
delete val[value];
}
else if (typeof value === typeof []) {
value.forEach(function (v) { return delete val[v]; });
}
return localForage.setItem(key, val).then(function (val) {
return val;
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err, args[0].logger);
});
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err, args[0].logger);
})];
});
});
},
clear: function (_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.logger, logger = _c === void 0 ? 'none' : _c, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _a.sent();
return [2 /*return*/, storage.clear().then(function () {
return handler.maybeCurry(curry || null)(true);
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
}
});
});
};
},
length: function (_a) {
var _b = _a === void 0 ? {} : _a, logger = _b.logger, returner = _b.returner, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _c.sent();
_b = (_a = handler).returner;
return [4 /*yield*/, storage.length().then(function (v) {
return handler.maybeCurry(curry || null)(v);
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
case 2: return [2 /*return*/, _b.apply(_a, [_c.sent()])(returner)];
}
});
});
};
},
/**
* EXPERIMENTAL!!!
* @param {number} index
* @returns {Promise<string>}
*/
/*
keyCurry: async (curry, index) => { // must be a key
const future = async function res (curry) {
return handler.maybeCurry2(curry)(2) // broken state
}
return future()
},
*/
keys: function (_a) {
var _b = _a === void 0 ? {} : _a, logger = _b.logger, returner = _b.returner, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _c.sent();
_b = (_a = handler).returner;
return [4 /*yield*/, storage.keys().then(function (v) {
return handler.maybeCurry(curry || null)(v);
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
case 2: return [2 /*return*/, _b.apply(_a, [_c.sent()])(returner)];
}
});
});
};
},
hasKey: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, logger = _b.logger, returner = _b.returner, store = _b.store;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var storage, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, _defineStore({ store: store })];
case 1:
storage = _c.sent();
_b = (_a = handler).returner;
return [4 /*yield*/, storage.keys().then(function (k) {
return handler.maybeCurry(curry || null)(k.includes(key));
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
case 2: return [2 /*return*/, _b.apply(_a, [_c.sent()])(returner)];
}
});
});
};
},
// This version has destructuring and currying
// call it like:
// forage.hasKey({ key: 'user4', closure: closureFn })
/*
hasKey_WORKS ({ key, curry, logger, returner }) { // must be a key
return localForage.keys().then(k => {
return handler.maybeCurry(curry)(k.includes(key))
}).catch(err => {
return handler.logger(err)(logger)
})
},
*/
hasKeyValue: function (_a) {
var _b = _a === void 0 ? {} : _a, key = _b.key, value = _b.value, logger = _b.logger, returner = _b.returner;
return function (curry) {
return __awaiter(this, void 0, void 0, function () {
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_b = (_a = handler).returner;
return [4 /*yield*/, localForage.getItem(key).then(function (val) {
return handler.maybeCurry(curry)(!!val[value]);
}).catch(function (err) {
/* istanbul ignore next */
return handler.logger(err)(logger);
})];
case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])(returner)];
}
});
});
};
},
iterate: function (iteratorCallback, callback) {
localForage.iterate(iteratorCallback, callback);
},
// UTILS
/**
*
* @param {object} options
*/
config: function (options) {
return localForage.config(options);
},
/**
* not async, not thenable
* don't use this. prefer to use config
* @returns {string}
*/
driver: function () {
return localForage.driver();
},
ready: function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, localForage.ready()
.then(function () { return true; })
.catch(function (err) {
/* istanbul ignore next */
console.error(err);
/* istanbul ignore next */
return false;
})];
});
});
},
/**
* This will return the entire object.
* If you just want to know if it worked, do this:
* ```
* const driver = !!forage.createInstance({ name: 'Test' })
* ```
* @param {string} name
* @returns {boolean}
*/
createInstance: function (_a) {
var _b = _a === void 0 ? {} : _a, name = _b.name, logger = _b.logger;
// this should also register itself in a list of stores
return localForage.createInstance({
name: name || 'curriedForage'
}
// , (success: any, err: any) => {
// /* istanbul ignore next */
// return err ? handler.logger(err, logger) : success
// }
);
},
// todo: when purging data, this will be important.
dropInstance: function (_a) {
var name = _a.name;
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_b) {
return [2 /*return*/, localForage.dropInstance({ name: name }).then(function () {
return true;
}).catch(function (err) {
/* istanbul ignore next */
console.log(err);
/* istanbul ignore next */
return false;
})];
});
});
},
dropAll: function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, localForage.dropInstance({}).then(function () {
return true;
}).catch(function (err) {
/* istanbul ignore next */
console.log(err);
/* istanbul ignore next */
return false;
})];
});
});
},
dropStore: function (_a) {
var name = _a.name, storeName = _a.storeName;
return localForage.dropInstance({
name: name,
storeName: storeName
});
}
};
/**
* @name _mapArgs
* @description Internal function for mapping the args to be
* passed to the forage functions. We don't care about order,
* we just care about type. And speed.
*
* In fact, we care so much about speed, we will probably
* deprecate this. :D
*
* @category curriedForage
* @param {Array} arr
* @returns {Array}
* @private
*/
var _mapArgs = function (arr) {
if (arr) {
var arrint = arr.map(function (val) {
var type = typeof val;
switch (type) {
case 'function':
return { curry: val }; // function to curry with
case 'string':
return { logger: val }; // name of logger to use
case 'number':
return { returner: val }; // type of return
case 'boolean':
return { before: val }; // curry before forage if true
default:
return { curry: val };
}
});
return arrint;
}
else
return [];
};
var _defineStore = function (_a) {
var store = (_a === void 0 ? {} : _a).store;
if (!store)
return localForage;
return forage.createInstance({
name: store
});
};
// we are exporting the internals for testing purposes
var internals = { _mapArgs: _mapArgs, _defineStore: _defineStore };
var getItem = forage.getItem;
var getKeyValue = forage.getKeyValue;
var setItem = forage.setItem;
var key = forage.key;
var mergeItem = forage.mergeItem;
var removeItem = forage.removeItem;
var deleteItemKey = forage.removeItem;
var clear = forage.clear;
var length = forage.length;
var keys = forage.keys;
var hasKey = forage.hasKey;
var hasKeyValue = forage.hasKeyValue;
var ready = forage.ready;
var defineStore = _defineStore;
export { clear, defineStore, deleteItemKey, forage, getItem, getKeyValue, hasKey, hasKeyValue, internals, key, keys, length, mergeItem, ready, removeItem, setItem };
//# sourceMappingURL=curriedForage.esm.js.map
Source