Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ember-fryctoria

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ember-fryctoria - npm Package Compare versions

Comparing version 0.1.8 to 0.1.9

14

addon/stores/local-store.js

@@ -20,3 +20,4 @@ import DS from 'ember-data';

container: container,
serializer: serializer
serializer: serializer,
clear: clearLFAdapter
});

@@ -43,1 +44,12 @@

});
function clearLFAdapter() {
// clear cache
var cache = this.get('cache');
if(cache) {
cache.clear();
}
// clear data in localforage
return window.localforage.setItem('DS.LFAdapter', []);
}

4

addon/stores/main-store/decorate-adapter.js

@@ -39,5 +39,7 @@ import backup from '../../utils/backup';

var backupMethod = createBackupMethod(localAdapter, methodName);
var isOffline = adapter.container.lookup('syncer:main').isOffline;
adapter[methodName] = function() {
return originMethod.apply(adapter, arguments).catch(backup(backupMethod, arguments));
return originMethod.apply(adapter, arguments)
.catch(backup(isOffline, backupMethod, arguments));
};

@@ -44,0 +46,0 @@

import Ember from 'ember';
import isOffline from './utils/is-offline';
import generateUniqueId from './utils/generate-unique-id';

@@ -47,3 +46,3 @@ import reloadLocalRecords from './utils/reload-local-records';

*
* Initialize jobs, remoteIdRecords. Either from localforage or emmpty array.
* Initialize jobs, remoteIdRecords.
*

@@ -56,4 +55,9 @@ * @method init

syncer.set('db', window.localforage);
var localStore = syncer.get('container').lookup('store:local');
var localAdapter = localStore.get('adapter');
syncer.set('db', window.localforage);
syncer.set('localStore', localStore);
syncer.set('localAdapter', localAdapter);
// NOTE: get remoteIdRecords first then get jobs,

@@ -77,3 +81,3 @@ // since jobs depend on remoteIdRecords

var typeName = snapshot.typeKey;
var serializer = this.lookupStore('main').serializerFor(typeName);
var serializer = this.get('mainStore').serializerFor(typeName);
snapshot.fryctoria = true;

@@ -133,2 +137,28 @@

/**
* Reset syncer and localforage records.
* Remove all jobs and remoteIdRecords.
* Remove all records in localforage.
*
* @method
* @public
*/
reset: function() {
return RSVP.all([
this.deleteAll('job'),
this.deleteAll('remoteIdRecord'),
this.get('localAdapter').clear()
]);
},
/**
* Decide if the error indicates offline
*
* @method
* @public
*/
isOffline: function(error) {
return error && error.status === 0;
},
/**
* This method does not talk to remote store, it only need to get serializer

@@ -141,4 +171,4 @@ * from a store.

syncDownRecord: function(record) {
var localStore = this.lookupStore('local');
var localAdapter = localStore.get('adapter');
var localStore = this.get('localStore');
var localAdapter = this.get('localAdapter');
var snapshot = record._createSnapshot();

@@ -153,13 +183,4 @@

reset: function() {
this.deleteAll('jobs');
this.deleteAll('remoteIdRecord');
},
/**
* Attampt to run all the jobs one by one. It will stop when all jobs are
* processed or one of the three errors:
* 1. offline: resolve
* 2. 'clear': clear all the jobs and resolve
* 3. other error: reject
* Attampt to run all the jobs one by one. Deal with syncing failure.
*

@@ -195,6 +216,6 @@ * @method runAllJobs

.catch(function(error) {
if(isOffline(error && error.status)) {
if(syncer.isOffline(error)) {
Ember.Logger.info('Can not connect to server, stop syncing');
} else if(syncer.handleSyncError){
return syncer.handleSyncError(error);
} else if(syncer.handleSyncUpError){
return syncer.handleSyncUpError(error);
} else {

@@ -209,3 +230,3 @@ return RSVP.reject(error);

var store = syncer.lookupStore('main');
var store = syncer.get('mainStore');

@@ -287,4 +308,4 @@ var typeName = job.typeName;

// delete existing record with localId
var localStore = syncer.lookupStore('local');
var localAdapter = localStore.get('adapter');
var localStore = syncer.get('localStore');
var localAdapter = syncer.get('localAdapter');

@@ -303,5 +324,6 @@ return localAdapter.deleteRecord(

lookupStore: function(storeName) {
return this.get('container').lookup('store:' + storeName);
},
// lazy evaluate main store, since main store is initialized after syncer
mainStore: Ember.computed(function() {
return this.get('container').lookup('store:main');
}),

@@ -369,7 +391,7 @@ getRemoteId: function(typeName, id) {

function getNamespace(typeName) {
if(typeName === 'job') {
return 'EmberFryctoriaJobs';
} else if(typeName === 'remoteIdRecord') {
return 'EmberFryctoriaRemoteIdRecords';
}
var LocalForageKeyHash = {
'job': 'EmberFryctoriaJobs',
'remoteIdRecord': 'EmberFryctoriaRemoteIdRecords',
};
return LocalForageKeyHash[typeName];
}

@@ -423,5 +445,5 @@

function getOrCreateRecord(syncer, type, id) {
var store = syncer.lookupStore('main');
var mainStore = syncer.get('mainStore');
return store.getById(type.typeKey, id) ||
return mainStore.getById(type.typeKey, id) ||
createRecordInLocalStore(syncer, type, id);

@@ -435,3 +457,3 @@ }

id: id,
store: syncer.lookupStore('local'),
store: syncer.get('localStore'),
container: syncer.get('container'),

@@ -438,0 +460,0 @@ });

import Ember from 'ember';
import isOffline from './is-offline';
export default function backup(backupFn, args) {
export default function backup(isOffline, backupFn, args) {
return function(error) {
var isOnline = !isOffline(error && error.status);
if(isOnline) {
if(isOffline(error)) {
return backupFn.apply(null, args);
} else {
return Ember.RSVP.reject(error);
}
return backupFn.apply(null, args);
};
}

@@ -7,9 +7,16 @@ import Ember from 'ember';

/*
* Handle errors when tyring to syncUp
* Remove all jobs once there is an error and restart your app
* Handle errors when tyring to syncUp.
*
* Default: undefined
*
* The following example remove all jobs and records in localforage
* and restart your app.
*/
// syncer.reopen({
// handleSyncError: function(error) {
// this.reset(); // delete all jobs.
// application.reset(); // reset application. A reload is recommended.
// handleSyncUpError: function(error) {
// // delete all jobs and all records in localforage.
// this.reset().then(function() {
// // reload page.
// window.location.reload();
// });
// }

@@ -19,4 +26,10 @@ // });

/*
* Decide what is offline
* The following is the default behavior
* Decide what is offline.
*
* Default:
* ```
* isOffline: function(error) {
* return error && error.status === 0;
* }
* ```
*/

@@ -23,0 +36,0 @@ // syncer.reopen({

{
"name": "ember-fryctoria",
"version": "0.1.8",
"version": "0.1.9",
"description": "Make ember data work offline with automatic sync.",

@@ -5,0 +5,0 @@ "directories": {

@@ -24,3 +24,3 @@ # Warning

When offline, it will use the local backup via localforage-adapter to retrive records (e.g. store.find). A queue of jobs is created when the user create, update or delete while offline. When online we flush this queue to keep the server in sync.
When offline, it will use the local backup(localforage) to retrive records. A queue of jobs is created when the user create, update or delete while offline. When online we flush this queue to keep the server in sync.

@@ -35,5 +35,13 @@ **Features NOT supported(yet):**

# How to sync?
An object called *syncer* is responsible for syncing. It is registered into
container and you can get it via *container.lookup('main:syncer')*.
An object called *syncer* is responsible for syncing.
- It is registered into *container*, therefore you can get syncer like this
```javascript
container.lookup('main:syncer')
```
- It is also injected into main *store*, therefore you can get syncer like this
```javascript
store.get('syncer')
```
It has a *jobs* property whichs is a queue of operations including create, update and delete. These are your offline operations.

@@ -43,32 +51,32 @@

- syncUp: push local changes to remote server
- syncDown: save changes from remote server to localforage
In most cases, you do not need to manully sync since ember-fryctoria automatially syncUp before every request to server and automatially syncDown after every request to server.
However, when you sideload or embed records, you probably want to manully save sideloaded or embeded records to localforage. Also you may want to syncUp periodially. In these cases, you can manully syncDown or syncUp.
*syncer* is injected into store. So you can do this to flush the queue of jobs:
- syncUp: push local changes to remote server, flush the queue of jobs.
- syncDown: save data in main *store* into localforage.
```javascript
store.syncer.syncUp();
syncer.syncDown('user'); // remove all records in localforage and save all current user records into localforage
syncer.syncDown(user); // create or update user record into localforage
syncer.syncDown([user1, user2]); // create or update user records into localforage
```
You can also capture records into localforage from ember-data store by doing this:
### Automatic sync
In most cases, you do not need to manully sync since ember-fryctoria automatially
*syncUp* before every request to server and automatially
*syncDown* after every request to server.
```javascript
store.syncer.syncDown('user'); // remove all records in localforage and save all current user records in localforage
store.syncer.syncDown(user); // create or update user record into localforage
store.syncer.syncDown([user1, user2]); // create or update user records into localforage
store.find('user') // syncDown('user') is called.
store.fetchAll('user') // syncDown('user') is called.
store.find('user', 1) // syncDown(user) is called.
store.fetchById('user', 1) // syncDown(user) is called.
user.reload() // syncDown(user) is called.
```
### Manual sync
When you sideload or embed records, you probably want to manully save sideloaded or embeded records to localforage. Also you may want to syncUp periodially. In these cases, you can manully syncDown or syncUp.
# How to handle errors during syncUp?
By default, when we get an error during syncUp, syncer will stop syncing. In the
next syncUp, syncer will try to start from the failed job. You can change this
behavior by adding a initializer ```ember g reopen-syncer-initializer```
and add a handleSyncError method in syncer.
next syncUp, syncer will retry starting from the failed job.
For example, you can remove all jobs when you get an error during syncUp. And
then restart your app by ```App.destroy()```,
since the outdated records in ember data store may create
errors when the user try to operate these records.
WARNING: This strategy will remove all the operations by user when he/her
was offline.
You can customize this by overwriting *handleSyncUpError* method in syncer in
reopen-syncer-initializer.

@@ -78,7 +86,9 @@ IMO, there is really not a single robust way to handle syncing faliure for

to only enable user to read while offline. Or you should implement a robust way
to handle syncing errors for a specific app.
to handle syncing errors for your app.
# How to decide what is offline?(Need implementation)
By default, whenever we have ```error.status === 0```, we define it as offline.
You can overwrite this behavior by overwriting *isOffline* method in the syncer.
Again, you can do this in reopen-syncer initializer ```ember g reopen-syncer-initializer```.
# How to decide what is offline?
By default, offline is defined by ```jqXHR && jqXHR.status === 0```.
[jqXHR](http://api.jquery.com/jQuery.ajax/#jqXHR)
You can overwrite this by overwriting *isOffline* method in syncer in
reopen-syncer-initializer.

@@ -1,50 +0,16 @@

1. implement isOffline in readme
1. test reopen-syncer initializer in syncer
1. Decorate local adapter instead of do things before store and syncer
# TODO:
1. Test on brain check
1. Test on bn pro
1. Release 1.0.0-alpha.1
1. Decorate adapter and serializer to use the correct one?
1. May be there is no a good way we can solve this problem
1. Do something to flushPendingSave and etc?
1. remove fryctoria.isOffline?
benefit: Stateless, do not worry or think about state
tradeoff: I have to maintain a lot of code from ember data
1. isOffline is changed when:
1. Model: we want to save to local adapter but in main store(offline)
2. Syncer: we want to save to main adapter(online)
3. MainStore: we want to talk to main(online) or talk to local(offline)
1. Refactor: move part logic from decorate-adapter to localAdpater?
1. add 'debug' segment in readme
1. TODO: when we ARE syncing, another call to syncing should return the same
promise! Then user can safely sync before any request.
1. move syncUp to adapter decorator?
1. add meta data to records and check in fetchAll before reloadAll(performance latter)
1. localforage use serializerFor to get serializer, do not use record.serialize
1. syncdown(model and store main) is not efficient now, remove duplicate save
1. remove local store, use and register localAdapter and serializer?
1. remove local store?
1. Wrap things in Ember.run to make test eaiser.
1. TODO: support findQuery
# NOTE:
serializer.adapter is not supported, in most case it should be fine.
# TODO:
1. <del>create an application store</del>
1. <del>overwrite methods in DS.Store</del>
1. <del>fetchAll</del>
1. <del>fetchById</del>
1. <del>didSaveRecord</del>
1. <del>createRecord(This does not talk to adapter, we do not care)</del>
1. <del>deleteRecord(This is just an alias to Model#deleteRecord, we do not care)</del>
1. <del>overwrite methods in DS.Model (If connection error, push to local and queue).
Note: only handle error, since success is handled by didSaveRecord.</del>
1. <del>createRecord</del>
1. <del>updateRecord</del>
1. <del>deleteRecord</del>
1. <del>add a blueprint for applicaiton store</del>
1. <del>save offline jobs to a queue</del>
1. <del>Write a service and a queue to run the jobs</del>
1. <del>Change name: Ember Fryctoria</del>
1. <del>Think of a mechanisem to do syncing</del>
1. <del>Perf, cached jobs in syncer</del>
1. <del>Namespace all custome stuff or put them into functions</del>
1. TODO: think about how to deal with slow internet.

@@ -57,23 +23,11 @@ (Ping?, disadvantage: overhead, not a good predicator of the internet?,

1. TODO: Add a blueprint(initializer) to handle syncer error
1. TODO: create a customized adapter and serializer and make sure the addon still works
1. TODO: when we ARE syncing, another call to syncing should return the same
promise! Then user can safely sync before any request.
1. TODO: patch localforage to save serializer into container in a initializer
1. TODO: add local-forage as a dependency?
1. fork ember-localforage-adapter, remove warning
1. Use configuration to turn on and off logging info
1. Support different serializers
1. Support findQuery
1. Add a throttle option to control syncing
1. A logo
1. move all non-extending functions out of store.js to avoid name collision
1. make local forage a dependency
1. Sideload (manul save to local)
1. Do syncing periodically or check if online
1. Refresh local data after create or update
1. ? sideload save to localforage(how to decide if reloadAll or insertAll)
# Resources:
1. [How ember data store is initialized] (https://github.com/emberjs/data/blob/b8aff0910775f864d6f918ecda1333491a3c001f/packages/ember-data/lib/initializers/store.js)
2. [Ember Data Store] (https://github.com/emberjs/data/blob/1.0.0-beta.15/packages/ember-data/lib/system/store.js#L107)
# NOTE:
1. serializer.adapter is not supported, in most case it should be fine.
1. adapter.findHasMany and adapter.findBelongsTo are not supported because they
are not supported by localforage adapter

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc