Skip to content

Commit

Permalink
Merge pull request #18 from ampatspell/changes-listener
Browse files Browse the repository at this point in the history
Changes listener
  • Loading branch information
ampatspell authored Jun 18, 2017
2 parents 316e9ac + a11c36d commit 4cd4dd6
Show file tree
Hide file tree
Showing 46 changed files with 1,041 additions and 66 deletions.
9 changes: 9 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@

## sofa

### changes

* on changes prop (`feed`, `view`, `...`) change `couch:database-changes` should be restarted
* on login, logout, Changes should be restarted. optionally (or better yet `autorun: 'authenticated', ...`)

### fastboot

* fastboot -- session

### destroy

* check collection.destroy(), db.destroy() logic

### attachments

* allow to override attachment url resolve (per-database)
Expand Down
73 changes: 73 additions & 0 deletions addon/changes/changes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Ember from 'ember';
import { defaultFeedIdentifiers } from 'couch/couch/changes/changes';

const {
Evented,
computed
} = Ember;

const call = name => {
return function() {
let internal = this._internal;
return internal[name].call(internal, ...arguments);
}
}

const internalProperty = key => {
return computed(function() {
return this._internal.state[key];
}).readOnly();
}

const listener = () => {
return computed(function() {
return this._internal.getListener(false);
}).readOnly();
}

const listenerProperty = key => {
let dep = `_listener.${key}`;
return computed(dep, function() {
return this.get(dep);
}).readOnly();
}

const state = () => {
let keys = [ 'isStarted', 'isSuspended', 'isError', 'error' ];
return computed(...keys, function() {
return this.getProperties(keys);
}).readOnly();
}

const Changes = Ember.Object.extend(Evented, {

_internal: null,
_listener: listener(),

feed: defaultFeedIdentifiers,

isStarted: listenerProperty('isStarted'),
isSuspended: listenerProperty('isSuspended'),
isError: internalProperty('isError'),
error: internalProperty('error'),
state: state(),

start: call('start'),
stop: call('stop'),
restart: call('restart'),
suspend: call('suspend'),

willDestroy() {
this._internal.changesWillDestroy();
this._super();
}

});

Changes.reopenClass({

_create: Changes.create

});

export default Changes;
29 changes: 29 additions & 0 deletions addon/changes/couch/changes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Ember from 'ember';
import Changes from '../changes';
import Error from '../../util/error';

const {
get,
guidFor
} = Ember;

const CouchChanges = Changes.extend({

toString() {
return `<couch-changes@${get(this.constructor, 'modelName')}::${guidFor(this)}>`;
}

});

CouchChanges.reopenClass({

create() {
throw new Error({
error: 'internal',
reason: 'use `couch.changes` to create new changes instances'
});
}

});

export default CouchChanges;
44 changes: 44 additions & 0 deletions addon/changes/couch/internal-changes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import InternalChanges from '../internal-changes';

export default class CouchInternalChanges extends InternalChanges {

constructor(couch, changesClass, identifier, opts) {
super(changesClass, opts);
this.couch = couch;
this.identifier = identifier;
}

createChangesModel() {
return this.couch._createChangesForInternalChanges(this);
}

optionsForListener() {
let model = this.getChangesModel();
return model.getProperties([
'feed',
'timeout',
'heartbeat',
'since',
'delay'
]);
}

createListener() {
return this.couch.get('documents').changes(this.optionsForListener());
}

processData(json) {
let { db_name: name, type } = json;

return {
type,
name
};
}

changesWillDestroy() {
super.changesWillDestroy();
this.couch._onInternalChangesDestroyed(this);
}

}
29 changes: 29 additions & 0 deletions addon/changes/database/changes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Ember from 'ember';
import Changes from '../changes';
import Error from '../../util/error';

const {
get,
guidFor
} = Ember;

const DatabaseChanges = Changes.extend({

toString() {
return `<database-changes@${get(this.constructor, 'modelName')}::${guidFor(this)}>`;
}

});

DatabaseChanges.reopenClass({

create() {
throw new Error({
error: 'internal',
reason: 'use `database.changes` to create new changes instances'
});
}

});

export default DatabaseChanges;
53 changes: 53 additions & 0 deletions addon/changes/database/internal-changes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Ember from 'ember';
import InternalChanges from '../internal-changes';

const {
merge
} = Ember;

export default class DatabaseInternalChanges extends InternalChanges {

constructor(database, changesClass, identifier, opts) {
super(changesClass, opts);
this.database = database;
this.identifier = identifier;
}

createChangesModel() {
return this.database._createChangesForInternalChanges(this);
}

optionsForListener() {
let model = this.getChangesModel();
return merge({
include_docs: true
}, model.getProperties([
'feed',
'view',
'filter',
'timeout',
'attachments',
'heartbeat',
'since',
'delay'
]));
}

createListener() {
return this.database.get('documents').changes(this.optionsForListener())
}

processData(json) {
let doc = json.doc;
if(!doc) {
return;
}
return this.database.push(doc, { optional: true, instantiate: false });
}

changesWillDestroy() {
super.changesWillDestroy();
this.database._onInternalChangesDestroyed(this);
}

}
Loading

0 comments on commit 4cd4dd6

Please sign in to comment.