| import {remove} from './helpers' |
| import * as localStorageMemory from './memory' |
| export default Store |
| |
| var uniqueID = 1; |
| |
| /** |
| * Creates a new client side storage object and will create an empty |
| * collection if no collection already exists. |
| * |
| * @param {string} name The name of our DB we want to use |
| * @param {function} callback Our fake DB uses callbacks because in |
| * real life you probably would be making AJAX calls |
| */ |
| function Store(name, callback) { |
| callback = callback || function() { |
| } |
| |
| this._dbName = name |
| |
| if (!localStorageMemory[name]) { |
| var data = { |
| todos: [] |
| } |
| |
| localStorageMemory[name] = JSON.stringify(data) |
| } |
| |
| callback.call(this, JSON.parse(localStorageMemory[name])) |
| this.subscribers = [] |
| } |
| |
| Store.prototype.subscribe = function(subscriber) { |
| this.subscribers.push(subscriber) |
| return () => remove(this.subscribers, subscriber) |
| } |
| |
| Store.prototype._notify = function() { |
| this.subscribers.forEach(s => s()) |
| } |
| |
| /** |
| * Finds items based on a query given as a JS object |
| * |
| * @param {object} query The query to match against (i.e. {foo: 'bar'}) |
| * @param {function} callback The callback to fire when the query has |
| * completed running |
| * |
| * @example |
| * db.find({foo: 'bar', hello: 'world'}, function (data) { |
| * // data will return any items that have foo: bar and |
| * // hello: world in their properties |
| * }); |
| */ |
| Store.prototype.find = function(query, callback) { |
| if (!callback) { |
| return |
| } |
| |
| var todos = JSON.parse(localStorageMemory[this._dbName]).todos |
| |
| callback.call(this, todos.filter(function(todo) { |
| for (var q in query) { |
| if (query[q] !== todo[q]) { |
| return false |
| } |
| } |
| return true |
| })) |
| } |
| |
| /** |
| * Will retrieve all data from the collection |
| * |
| * @param {function} callback The callback to fire upon retrieving data |
| */ |
| Store.prototype.findAll = function(callback) { |
| callback = callback || function() { |
| } |
| callback.call(this, JSON.parse(localStorageMemory[this._dbName]).todos) |
| } |
| |
| /** |
| * Will save the given data to the DB. If no item exists it will create a new |
| * item, otherwise it'll simply update an existing item's properties |
| * |
| * @param {object} updateData The data to save back into the DB |
| * @param {function} callback The callback to fire after saving |
| * @param {number} id An optional param to enter an ID of an item to update |
| */ |
| Store.prototype.save = function(updateData, callback, id) { |
| var data = JSON.parse(localStorageMemory[this._dbName]) |
| var todos = data.todos |
| |
| callback = callback || function() { |
| } |
| |
| // If an ID was actually given, find the item and update each property |
| if (id) { |
| for (var i = 0; i < todos.length; i++) { |
| if (todos[i].id === id) { |
| for (var key in updateData) { // eslint-disable-line guard-for-in |
| todos[i][key] = updateData[key] |
| } |
| break |
| } |
| } |
| |
| localStorageMemory[this._dbName] = JSON.stringify(data) |
| callback.call(this, JSON.parse(localStorageMemory[this._dbName]).todos) |
| } else { |
| // Generate an ID |
| updateData.id = uniqueID++; |
| |
| todos.push(updateData) |
| localStorageMemory[this._dbName] = JSON.stringify(data) |
| callback.call(this, [updateData]) |
| } |
| this._notify() |
| } |
| |
| /** |
| * Will remove an item from the Store based on its ID |
| * |
| * @param {number} id The ID of the item you want to remove |
| * @param {function} callback The callback to fire after saving |
| */ |
| Store.prototype.remove = function(id, callback) { |
| var data = JSON.parse(localStorageMemory[this._dbName]) |
| var todos = data.todos |
| |
| for (var i = 0; i < todos.length; i++) { |
| if (todos[i].id === id) { |
| todos.splice(i, 1) |
| break |
| } |
| } |
| |
| localStorageMemory[this._dbName] = JSON.stringify(data) |
| callback.call(this, JSON.parse(localStorageMemory[this._dbName]).todos) |
| this._notify() |
| } |
| |
| /** |
| * Will drop all storage and start fresh |
| * |
| * @param {function} callback The callback to fire after dropping the data |
| */ |
| Store.prototype.drop = function(callback) { |
| localStorageMemory[this._dbName] = JSON.stringify({todos: []}) |
| callback.call(this, JSON.parse(localStorageMemory[this._dbName]).todos) |
| this._notify() |
| } |