This package has been deprecated

Author message:

this package has been deprecated

@shiftcode/shift.storage

0.1.3 • Public • Published

shift.storage is a object oriented way to store data locally on your device, being that a web or hibrid mobile application and, optionally, syncing in background any changed data with your server. It wraps and uses localForage lib and some of it's extensions, as well as it includes the localForage's cordova SQLite driver and makes it the primary option of use, when cordova sqlite plugin is available.

Install

npm i @shiftcode/shift.storage

Concept

shift.storage treats every data as objects, so you won't be creating tables or schemas, neither performing any sort of querying that doesn't take place in memory.

When saving objects to the database all object's data will replace any existent one for that same object. Objects equality come from having the same id and that's also why the storage needs to know the name of the key that contains the id.

Quick Example

import Storage from 'shift.storage';

const userStorage = Storage('user');

const userA = { name: 'Peter Parker', secretIdentity: 'Spider Man' };
const userB = { name: 'Scott Lang', secretIdentity: 'Ant Man' };

// insert them to the storage
// both will have their id's auto generated as they were not informed
userStorage.put(userA);
userStorage.put(userB);

// retrieve all users
userStorage.list()
    .then(users => {
        console.log(users);
        // logs out
        // [
        //  { _id: '__5968ef6ef06c4254d6238ab5', name: 'Peter Parker', secretIdentity: 'Spider-Man' },
        //  { _id: '__5968ef77b729de73d8e94437', name: 'Scott Lang', secretIdentity: 'Ant-Man' }
        // ]
        return userStorage.delete('__5968ef77b729de73d8e94437');
    })
    .then(() => {
        // retrieve them all again to check for deletion
        return userStorage.list();
    })
    .then(users => {
        // ant-man was deleted
        console.log(users);
        // logs out
        // [
        //  { _id: '__5968ef6ef06c4254d6238ab5', name: 'Peter Parker', secretIdentity: 'Spider Man' }
        // ]
        return userStorage.get('__5968ef6ef06c4254d6238ab5');
    })
    .then(user => {
        // peter parker may also be retrieved by it's id
        // and updated by simply putting him again to the storage
        user.team = 'Team Iron Man';
        return userStorage.put(user);
    })
    .then(() => {
        // retrieve them all again to check the update
        return userStorage.list();
    })
    .then(users => {
        // spider-man was updated
        console.log(users);
        // logs out
        // [
        //  { _id: '__5968ef6ef06c4254d6238ab5', name: 'Peter Parker', secretIdentity: 'Spider Man', team: 'Team Iron Man' }
        // ]
    });

Server Synchronization

The whole point about this lib being made was about facilitating server side synchronization when working with REST API.

There are two forms of active synchronization: onPut and onDelete. And one form of passive synchronization: fetch.

The first two are method implementations that are triggered respectively whenever a put or delete call happens. The third one is also a method implementation but it's triggered in a time interval, every 5 minutes by default.

Server side synchronization relies strongly on operation's timestamp for consistency and should have it's API also working with those concepts in order to things work. Check the Storage API description for more information. There's also a full sync example at the end of this doc.

Storage API

-> initialization

Arguments

  • name: String
  • settings: Object (optional)

Return

  • storage referencing a database for the given name

Usage

import Storage from 'shift.storage';

// default settings
const userStorage = Storage('user');

// custom settings (assigning defaults)
const companyStorage = Storage('company', {
    id: '_id', // key name that represents the id
    fetchInterval: 300000, // ms -> 5 min
    fetchReturn: { // syncWithServer().fetch return object description
        updated: 'updated',
        removed: 'removed'
    }
});

-> get(id)

Arguments

  • id: String|Number

Return

  • promise => object for given id

Usage

Pass in the id and receive the object for that id.

userStorage.get(1).then(user => {
    // user object {}
});

-> list(query)

Arguments

  • query: Array|Function|Object (optional)

Return

  • promise => array of object for given query

Usage

Call it with no arguments for retrieving all objects.

userStorage.list().then(users => {
    // all users retrieved [{}, {}, {}, {}, {}]
});

Passing an Array of ids will retrieve only the objects for those ids.

userStorage.list([1, 2, 3]).then(users => {
    // only users with ids 1, 2 and 3 retrieved [{}, {}, {}]
});

Passing an Object will filter the response by the values present in each key.

userStorage.list({ team: 'Team Iron Man' }).then(users => {
    // only users from Iron Man's team retrieved [{}, {}, {}]
});

Pass in a function to implement a custom filter.

userStorage.list(user => user.movies >= 2).then(users => {
    // only users with two or more movies retrieved [{}, {}, {}]
});

-> put(data)

Arguments

  • id: Object|Array

Return

  • promise => saved object or array with saved objects

Usage

Pass in a single object and receive it after creation/update. If the object already exists in the database it will be entirely replaced.

* Triggers onPut if implemented.

// auto generated id
let user = { name: 'Peter Parker', secretIdentity: 'Spider Man' };
userStorage.put(user).then(savedUser => {
    // user object with a generated id {}
    console.log(savedUser._id); // => __5968ef6ef06c4254d6238ab5
});

// pre generated id
let user = { _id: 1, name: 'Peter Parker', secretIdentity: 'Spider Man' };
userStorage.put(user).then(savedUser => {
    // user object {}
    console.log(savedUser._id); // => 1
});

To update an object just put it again.

* Triggers onPut if implemented.

userStorage.get(1).then(user => {
    // retrieves peter parker and update his team
    user.team = 'Team Iron Man';
    return userStorage.put(user);
}).then(savedUser => {
    // updated peter parker
    console.log(savedUser); // => { _id: 1, name: 'Peter Parker', secretIdentity: 'Spider Man', team: 'Team Iron Man' }
});

It's also possible to put a list of objects at once. However in this case the onPut is not triggered for any of them.

* Doesn't trigger onPut even if implemented.

const userA = { name: 'Peter Parker', secretIdentity: 'Spider Man' };
const userB = { name: 'Scott Lang', secretIdentity: 'Ant Man' };

userStorage.put([userA, userB]).then(users => {
    console.log(users);
    // logs out
    // [
    //  { _id: '__5968ef6ef06c4254d6238ab5', name: 'Peter Parker', secretIdentity: 'Spider-Man' },
    //  { _id: '__5968ef77b729de73d8e94437', name: 'Scott Lang', secretIdentity: 'Ant-Man' }
    // ]
});

Sync with server

If onPut synchronization method is implemented it will be triggered every time a put is called. The onPut implemented function receives the stored user object as parameter and must return a promise that resolves with user's latest data on server side.

Even if an ID was auto generated for putting the object without an id in the storage, the stored object passed in as parameter to the onPut implemented function won't contain an id if it didn't by the time it was put in the storage. Meaning "create" functions won't have an id when onPut is called and "update" functions will.

Check out the syncWithServer().onPut(putFunction) for it's docs.

-> delete(idOrIds)

Arguments

  • idOrIds: String|Number|Array

Return

  • promise => resolves if object(s) were successful deleted

Usage

Remove the object from database by id.

* Triggers onDelete if implemented.

userStorage.delete(user._id).then(() => {
    // user was deleted
}).catch(() => {
    // operation failed
});

Remove multiple objects from database by their id.

* Doesn't trigger onDelete even if implemented.

userStorage.delete([userA._id, userB._id]).then(() => {
    // users were deleted
}).catch(() => {
    // operation failed
});

Sync with server

If onDelete synchronization method is implemented it will be triggered every time a delete is called. The onDelete implemented function receives the deleted id as parameter and must return a promise that simply resolves by the time it was confirmedly deleted.

Check out the syncWithServer().onDelete(deleteFunction) for it's docs.

-> count()

Return

  • promise => resolves with the number of current stored objects

Usage

Assuming there are 5 stored entities, a call to count should return the number 5.

userStorage.count().then(size => {
    // size === 5
});

-> clear()

Return

  • promise => resolves when database has been completed cleared

Usage

Calling the clear method will empty the database and any synchronization tasks that are still pending as well as stoping the fetch interval from being called.

userStorage.clear().then(size => {
    // userStorage is now empty
});

-> isSyncing(id)

Arguments

  • id: String|Number

Return

  • boolean

Usage

Check if an object has any pending synchronization task with the server. May be used to show that the object is not fully synced yet.

userStorage.isSyncing(user._id); // => returns either true or false

-> isFetching()

Return

  • boolean

Usage

Check if the storage is processing a fetch call to the server.

userStorage.isFetching(); // => returns either true or false

-> isFetchingForTheFirstTime()

Return

  • boolean

Usage

Check if the storage is processing a fetch call to the server for the first time. Even between app/browser closes and reopens storage data is persistent so this will return true only on the first time ever. When the app/browser is reopened if fetch was already called before it will still return false even if it's the first call for that session. Note that the clear method does reset this fetching control for the first time.

userStorage.isFetching(); // => returns either true or false

-> syncWithServer().fetch(fetchFunction)

-> syncWithServer().onPut(putFunction)

-> syncWithServer().onDelete(deleteFunction)

-> reloadFetch()

-> cancelFetch()

Readme

Keywords

none

Package Sidebar

Install

npm i @shiftcode/shift.storage

Weekly Downloads

2

Version

0.1.3

License

MIT

Last publish

Collaborators

  • marioch
  • cainaf
  • gutoverz