UNPKG

rt-storage

Version:

A real time storage library based on localforage and rxjs.

457 lines (426 loc) 17.7 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("localforage"), require("rxjs")); else if(typeof define === 'function' && define.amd) define(["localforage", "rxjs"], factory); else if(typeof exports === 'object') exports["RTStorage"] = factory(require("localforage"), require("rxjs")); else root["RTStorage"] = factory(root["localforage"], root["rxjs"]); })(window, function(__WEBPACK_EXTERNAL_MODULE__4__, __WEBPACK_EXTERNAL_MODULE__5__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; }; Object.defineProperty(exports, "__esModule", { value: true }); var uuidv4 = __webpack_require__(1); var localForage = __webpack_require__(4); var rxjs_1 = __webpack_require__(5); var RTStorage = /** @class */ (function () { function RTStorage(_a) { var _this = this; var name = _a.name, option = __rest(_a, ["name"]); this._name = name; this._id = uuidv4(); localForage.config(__assign({ name: this._name }, option)); this._storage = localForage.createInstance({ name: this._name, }); this._localStorage = localStorage; this._storageChangedEventKey = this._name + "_storage_changed"; this._observable = new rxjs_1.Subject(); this._tabSyncHandler = function (event) { return __awaiter(_this, void 0, void 0, function () { var _a, setter, key, value, e_1; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!(event.key !== null && typeof event.key !== 'undefined' && event.key === this._storageChangedEventKey)) return [3 /*break*/, 4]; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); _a = JSON.parse(event.newValue), setter = _a.setter, key = _a.key; if (!setter || setter === this.id) { return [2 /*return*/]; } return [4 /*yield*/, this.getItem(key)]; case 2: value = _b.sent(); this._observable.next({ key: key, value: value }); return [3 /*break*/, 4]; case 3: e_1 = _b.sent(); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; window.addEventListener('storage', this._tabSyncHandler); } RTStorage.prototype.setItem = function (key, value) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.waitForReady()]; case 1: _a.sent(); return [4 /*yield*/, this._storage.setItem(key, { value: value, setter: this.id })]; case 2: _a.sent(); this._observable.next({ key: key, value: value }); this._updateStorageChangeKey(key); return [2 /*return*/]; } }); }); }; RTStorage.prototype.getItem = function (key) { return __awaiter(this, void 0, void 0, function () { var originalData, value; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.waitForReady()]; case 1: _a.sent(); return [4 /*yield*/, this._storage.getItem(key)]; case 2: originalData = _a.sent(); try { value = originalData.value; return [2 /*return*/, value]; } catch (error) { return [2 /*return*/, undefined]; } return [2 /*return*/]; } }); }); }; RTStorage.prototype.removeItem = function (key) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.waitForReady()]; case 1: _a.sent(); return [4 /*yield*/, this._storage.removeItem(key)]; case 2: _a.sent(); this._observable.next({ key: key, value: undefined }); this._updateStorageChangeKey(key); return [2 /*return*/]; } }); }); }; RTStorage.prototype.keys = function () { return __awaiter(this, void 0, void 0, function () { var keys; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.waitForReady()]; case 1: _a.sent(); return [4 /*yield*/, this._storage.keys()]; case 2: keys = _a.sent(); return [2 /*return*/, keys]; } }); }); }; RTStorage.prototype._updateStorageChangeKey = function (key) { this._localStorage.setItem(this._storageChangedEventKey, JSON.stringify({ timestamp: Date.now(), key: key, setter: this.id, })); }; Object.defineProperty(RTStorage.prototype, "id", { get: function () { return this._id; }, enumerable: true, configurable: true }); RTStorage.prototype.waitForReady = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (this._ready) { return [2 /*return*/]; } if (!(typeof this._storage.ready === 'function')) return [3 /*break*/, 2]; return [4 /*yield*/, this._storage.ready()]; case 1: _a.sent(); _a.label = 2; case 2: this._ready = true; return [2 /*return*/]; } }); }); }; Object.defineProperty(RTStorage.prototype, "$", { get: function () { return this._observable; }, enumerable: true, configurable: true }); RTStorage.prototype.subscribe = function (keyOrFunc, func) { if (typeof keyOrFunc === 'function') { return this._observable.subscribe(keyOrFunc); } return this._observable.subscribe(function (e) { if (e.key === keyOrFunc) { func(e.value); } }); }; RTStorage.prototype.destory = function () { if (this._tabSyncHandler) { window.removeEventListener('storage', this._tabSyncHandler); } }; return RTStorage; }()); exports.default = RTStorage; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { var rng = __webpack_require__(2); var bytesToUuid = __webpack_require__(3); function v4(options, buf, offset) { var i = buf && offset || 0; if (typeof(options) == 'string') { buf = options === 'binary' ? new Array(16) : null; options = null; } options = options || {}; var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` rnds[6] = (rnds[6] & 0x0f) | 0x40; rnds[8] = (rnds[8] & 0x3f) | 0x80; // Copy bytes to buffer, if provided if (buf) { for (var ii = 0; ii < 16; ++ii) { buf[i + ii] = rnds[ii]; } } return buf || bytesToUuid(rnds); } module.exports = v4; /***/ }), /* 2 */ /***/ (function(module, exports) { // Unique ID creation requires a high quality random # generator. In the // browser this is a little complicated due to unknown quality of Math.random() // and inconsistent support for the `crypto` API. We do the best we can via // feature-detection // getRandomValues needs to be invoked in a context where "this" is a Crypto // implementation. Also, find the complete implementation of crypto on IE11. var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); if (getRandomValues) { // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef module.exports = function whatwgRNG() { getRandomValues(rnds8); return rnds8; }; } else { // Math.random()-based (RNG) // // If all else fails, use Math.random(). It's fast, but is of unspecified // quality. var rnds = new Array(16); module.exports = function mathRNG() { for (var i = 0, r; i < 16; i++) { if ((i & 0x03) === 0) r = Math.random() * 0x100000000; rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; } return rnds; }; } /***/ }), /* 3 */ /***/ (function(module, exports) { /** * Convert array of 16 byte values to UUID string format of the form: * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ var byteToHex = []; for (var i = 0; i < 256; ++i) { byteToHex[i] = (i + 0x100).toString(16).substr(1); } function bytesToUuid(buf, offset) { var i = offset || 0; var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 return ([bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]]).join(''); } module.exports = bytesToUuid; /***/ }), /* 4 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE__4__; /***/ }), /* 5 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE__5__; /***/ }) /******/ ])["default"]; });