Last active
March 31, 2016 16:26
-
-
Save blairio/dc116c70911553a9e6aaa13a3aee24b5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
import {manager, ReactCBLite} from 'react-native-couchbase-lite'; | |
import EventEmitter from 'EventEmitter'; | |
export const CHANGE_EVENT_TYPE = 'change'; | |
const ERROR_EVENT_TYPE = 'error'; | |
const DB_NAME = 'db'; //'user_123'; | |
const DB_LOCAL_USER_NAME = 'admin'; | |
const DB_LOCAL_PASSWORD = 'password'; | |
const REMOTE_PROTOCOL = 'https://' | |
const REMOTE_USER = "admin"; | |
const REMOTE_PASSWORD = "password"; | |
const REMOTE_SERVER = "your.server.or.gateway.com:"; | |
const DB_NAME = ""; | |
const Storage = { | |
init: function () { | |
ReactCBLite.init(5984, DB_LOCAL_USER_NAME, DB_LOCAL_PASSWORD, e => {}); | |
const REMOTE_DB = `${REMOTE_PROTOCOL}${REMOTE_USER}:${REMOTE_PASSWORD}@${REMOTE_SERVER}:${REMOTE_PORT}/${DB_NAME}/`; | |
this.database = new manager(`http://${DB_LOCAL_USER_NAME}:${DB_LOCAL_PASSWORD}@localhost:5984/`, DB_NAME); | |
return this.database.createDatabase().then(res => { | |
console.log('createDB', res); | |
}).then(() => { | |
return this.database.replicate(REMOTE_DB, DB_NAME, true); | |
}).then((res) => { | |
console.log('replicate', REMOTE_DB, res); | |
}).catch(error => { | |
console.log('ERROR', error); | |
}) | |
}, | |
getAll: function () { | |
return this.database.getAllDocuments(); | |
}, | |
get: function(key) { | |
return this.database.getDocument(key); | |
}, | |
/** | |
* @returns {Promise} a promise with the event listener that the caller can then subscribe to. | |
* @throws if the change feed cannot be initialized (eg. last_seq cannot be retrieved from the database) | |
* For proper use with React Native see https://colinramsay.co.uk/2015/07/04/react-native-eventemitters.html | |
* Emits two possible events: | |
* * 'change' with JSON parsed result from change feed as argument | |
* * 'error' with last error or bad response Errors will be logged automatically to console | |
* After an error there is delay before listening again with exponential backoff. | |
*/ | |
getChangesEventEmitter: function() { | |
if (!this.changesEventEmitter) { | |
this.changesEventEmitter = new EventEmitter(); | |
this.changesRetryCount = 0; | |
return this.database.latestRevision().then(lastRevision => { | |
this.lastSequence = lastRevision; | |
console.log('INITIAL lastSequence', this.lastSequence); | |
this.listenForChange(); | |
return this.changesEventEmitter; | |
}) | |
} else { | |
return new Promise((resolve, reject) => { | |
resolve(this.changesEventEmitter); | |
}); | |
} | |
}, | |
/** | |
* Override the default change feed options with new options | |
* See See Query parameters in http://developer.couchbase.com/documentation/mobile/1.2/develop/references/couchbase-lite/rest-api/database/get-changes/index.html | |
* @returns void | |
*/ | |
setChangesFeedOptions: function(options) { | |
this.changeFeedOptions = options; | |
}, | |
getChangesFeedOptions: function() { | |
return Object.assign({feed: 'longpoll'}, this.changeFeedOptions || {}, {since: this.lastSequence}); | |
}, | |
listenForChange: function() { | |
const params = this.getChangesFeedOptions(); | |
console.log('Listening for changes with', params); | |
return this.database.getChanges(params).then(res => { | |
if (typeof(res.last_seq) === 'number') { | |
this.lastSequence = res.last_seq; | |
console.log('UPDATE lastSequence', this.lastSequence) | |
this.changesRetryCount = 0; | |
this.changesEventEmitter.emit(CHANGE_EVENT_TYPE, res); | |
} else { | |
throw new Error(res); | |
} | |
return this.listenForChange(); | |
}).catch((error) => { | |
this.changesRetryCount += 1; | |
console.log('ERROR Listening for changes, RetryCount=', this.changesRetryCount, 'Error=', error); | |
this.changesEventEmitter.emit(ERROR_EVENT_TYPE, error); | |
return new Promise((resolve, reject) => { | |
setTimeout(resolve, (Math.exp(this.changesRetryCount)) + 15 + (Math.random() * 30 * (this.changesRetryCount + 1))); | |
}).then(() => { return this.listenForChange() }); | |
}) | |
} | |
}; | |
export default Storage; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment