UNPKG

ui-framework-jps

Version:

A simple UI framework for state management and UI components

335 lines 14.4 kB
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()); }); }; import debug from 'debug'; import { openDB } from "idb"; import { StateEventType, StateManagerType } from "../interface/StateManager"; import { AbstractAsynchronousStateManager } from "./AbstractAsynchronousStateManager"; const logger = debug('indexeddb-ts'); const loggerInit = debug('indexeddb-ts:init'); export class IndexedDBStateManager extends AbstractAsynchronousStateManager { constructor() { super('indexeddb', 'indexeddb'); this.dbName = 'default'; this.collections = []; this.callbackForAddItem = this.callbackForAddItem.bind(this); this.callbackForRemoveItem = this.callbackForRemoveItem.bind(this); this.callbackForUpdateItem = this.callbackForUpdateItem.bind(this); this.callbackForGetItems = this.callbackForGetItems.bind(this); this.setStateByName = this.setStateByName.bind(this); this.getType = this.getType.bind(this); } static getInstance() { if (!IndexedDBStateManager.instance) { IndexedDBStateManager.instance = new IndexedDBStateManager(); } return IndexedDBStateManager.instance; } initialise(dbName, collections) { return __awaiter(this, void 0, void 0, function* () { logger(`opening database for ${dbName} with collections`); logger(collections); this.dbName = dbName; this.collections = collections; this.collections.forEach((collection) => { this.addStateNameToConfigurations(collection.name); }); const isOpen = yield this.openDatabase(dbName, collections); if (!isOpen) { logger('Configuration change required, delete the database'); } this.initialised = true; }); } _addNewNamedStateToStorage(state) { } _getState(name) { if (this.hasCompletedRun(name)) { logger(`Getting All ${name} - not done - previously retrieved`); } else { if (!this.isRunInProgress(name)) { this.setRunInProgress(name); logger(`getting state ${name}`); this.getWithCollectionKey(name, this.getKeyFieldForKey(name)); } } let state = { name: name, value: [], hasBeenSet: false }; return state; } _ensureStatePresent(name) { } // should be present with initialise _replaceNamedStateInStorage(state) { let fn = () => __awaiter(this, void 0, void 0, function* () { logger(`replacing item in storage ${state.name}`); logger(state.value); yield this.removeAllItemsFromCollectionKey(state.name, this.getKeyFieldForKey(state.name)); yield this.saveWithCollectionKey(state.name, state.value, this.getKeyFieldForKey(state.name)); }); fn(); } _addItemToState(name, stateObj, isPersisted = false) { if (isPersisted) return; this.addNewItemToCollection(name, stateObj, this.getKeyFieldForKey(name)); } _removeItemFromState(name, stateObj, isPersisted) { if (isPersisted) return; this.removeItemFromCollection(name, stateObj, this.getKeyFieldForKey(name)); } _updateItemInState(name, stateObj, isPersisted) { if (isPersisted) return; this.updateItemInCollection(name, stateObj, this.getKeyFieldForKey(name)); } _saveState(name, stateObj) { let fn = () => __awaiter(this, void 0, void 0, function* () { logger(`saving state ${name}`); yield this.removeAllItemsFromCollectionKey(name, this.getKeyFieldForKey(name)); yield this.saveWithCollectionKey(name, stateObj, this.getKeyFieldForKey(name)); }); fn(); } saveWithCollectionKey(key, saveData, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { logger(`Saving array with key ${key}`); logger(saveData); let db = yield openDB(this.dbName); // @ts-ignore let transaction = db.transaction([key], "readwrite"); transaction.oncomplete = function (ev) { logger('Success'); logger(ev); }; transaction.onerror = function (ev) { logger('Error'); logger(ev); }; // @ts-ignore let objectStore = transaction.store; // @ts-ignore yield this.saveItemsToCollection(objectStore, saveData, keyField); }); } /* add a new item to the local storage if not already there */ addNewItemToCollection(key, item, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { if (item !== null) { logger(`Adding with key ${key}`); logger(item); let db = yield openDB(this.dbName); // @ts-ignore let transaction = db.transaction([key], "readwrite").objectStore(key).add(item); transaction.oncomplete = function (ev) { logger('Success'); logger(ev); }; transaction.onerror = function (ev) { logger('Error'); logger(ev); }; this.callbackForAddItem(item, key); } }); } removeItemFromCollection(key, item, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { if (item !== null) { logger(`Removing with key ${key} item ${item[keyField]}`); logger(item); let db = yield openDB(this.dbName); // @ts-ignore let transaction = db.transaction([key], "readwrite").objectStore(key).delete(item[keyField]); transaction.oncomplete = function (ev) { logger('Success'); logger(ev); }; transaction.onerror = function (ev) { logger('Error'); logger(ev); }; yield transaction.done; this.callbackForRemoveItem(item, key); } }); } updateItemInCollection(key, item, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { if (item) { logger(`Updating item in storage ${key} with keyField path of ${keyField}`); logger(item); let db = yield openDB(this.dbName); // @ts-ignore let transaction = db.transaction([key], "readwrite").objectStore(key).put(item); transaction.oncomplete = function (ev) { logger('Success'); logger(ev); }; transaction.onerror = function (ev) { logger('Error'); logger(ev); }; // @ts-ignore yield transaction.done; this.callbackForUpdateItem(item, key); } }); } setStateByName(name, stateObjectForName, informListeners) { this._replaceNamedStateInStorage({ name: name, value: stateObjectForName, hasBeenSet: true }); if (informListeners) this.delegate.informChangeListenersForStateWithName(name, stateObjectForName, StateEventType.StateChanged, null); } getWithCollectionKey(key, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { let savedResults = []; logger(`Loading with key ${key}`); let db = yield openDB(this.dbName); yield this.checkForObjectStore(db, key, keyField); // @ts-ignore let transaction = db.transaction([key]); // @ts-ignore let objectStore = transaction.store; // @ts-ignore let cursor = yield objectStore.openCursor(); while (cursor) { // @ts-ignore savedResults.push(cursor.value); // @ts-ignore cursor = yield cursor.continue(); } logger(savedResults); this.callbackForGetItems(savedResults, key); }); } _findItemsInState(name, filters) { return []; } getType() { return StateManagerType.AsyncLocal; } _findItemInState(name, item) { } getKeyFieldForKey(key) { let result = '_id'; const foundIndex = this.collections.findIndex((collection) => collection.name === key); if (foundIndex >= 0) { result = this.collections[foundIndex].keyField; } return result; } checkForObjectStore(db, key, keyField) { return __awaiter(this, void 0, void 0, function* () { logger(`Checking for collection ${key}`); if (!db.objectStoreNames.contains(key)) { // @ts-ignore logger(`Checking for collection ${key} - NOT found, creating`); yield db.createObjectStore(key, { keyPath: keyField, autoIncrement: false }); } }); } saveItemsToCollection(objectStore, saveData, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { logger(`Saving items to collection`); saveData.forEach((data) => { // @ts-ignore objectStore.add(data); }); }); } removeAllItemsFromCollectionKey(key, keyField = 'id') { return __awaiter(this, void 0, void 0, function* () { logger(`Clearing collection ${key}`); let db = yield openDB(this.dbName); yield this.checkForObjectStore(db, key, keyField); // @ts-ignore let transaction = db.transaction([key], "readwrite"); // @ts-ignore let objectStore = transaction.store; // @ts-ignore yield objectStore.clear(); }); } callbackForRemoveItem(data, associatedStateName) { return __awaiter(this, void 0, void 0, function* () { logger(`callback for remove item for state ${associatedStateName} - not forwarded`); logger(data); }); } callbackForUpdateItem(data, associatedStateName) { return __awaiter(this, void 0, void 0, function* () { logger(`callback for update item for state ${associatedStateName} - not forwarded`); logger(data); }); } callbackForGetItems(data, associatedStateName) { logger(`callback for get items for state ${associatedStateName} - FORWARDING`); logger(data); this.setCompletedRun(associatedStateName, data); this.clearRunInProgress(associatedStateName); this.delegate.informChangeListenersForStateWithName(associatedStateName, data, StateEventType.StateChanged, null); } callbackForAddItem(data, associatedStateName) { return __awaiter(this, void 0, void 0, function* () { logger(`callback for add item for state ${associatedStateName} - FORWARDING`); logger(data); this.delegate.informChangeListenersForStateWithName(associatedStateName, data, StateEventType.ItemAdded, null); }); } openDatabase(dbName, collections) { return __awaiter(this, void 0, void 0, function* () { let result = true; try { let db = yield openDB(this.dbName); let currentVersion = db.version; // do we have any new collections? let collectionsToCreate = []; collections.forEach((collection) => { loggerInit(`checking for collection ${collection.name} with key ${collection.keyField} with database version ${currentVersion}`); if (!db.objectStoreNames.contains(collection.name)) { loggerInit(`collection ${collection.name} not present in database version ${currentVersion}`); collectionsToCreate.push(collection); } }); db.close(); if (collectionsToCreate.length > 0) { currentVersion++; } yield openDB(dbName, currentVersion, { upgrade(db, oldVersion, newVersion, transaction) { collectionsToCreate.forEach((collection) => { loggerInit(`creating collection for ${collection.name} with key ${collection.keyField} in database version ${currentVersion}`); db.createObjectStore(collection.name, { keyPath: collection.keyField, autoIncrement: false }); }); }, blocked() { // … }, blocking() { // … }, terminated() { // … }, }); } catch (error) { result = false; logger(error); loggerInit(`Deleting database ${dbName}`); yield indexedDB.deleteDatabase(dbName); loggerInit(`Re-opening database ${dbName}`); return yield this.openDatabase(dbName, collections); } return result; }); } } //# sourceMappingURL=IndexedDBStateManager.js.map