Skip to content
Browse files

get paths working right

  • Loading branch information...
1 parent 67d7c08 commit 8f1d4492cad618f5fccddb3c492de041eae0cbd8 @dominictarr committed Apr 26, 2012
Showing with 65 additions and 29 deletions.
  1. +64 −28 index.js
  2. +1 −1 test/simple.js
View
92 index.js
@@ -1,17 +1,42 @@
/*
a model object that is compatible with xdiff
+ x.sync(repo | xmodel | obj)
+
+ var _x = x.at(path...) //path to sub doc
+
+ _x.set(key, value)
+ _x.del(key)
+ _x.splice(index, del, insert...)
+
+it should be possible to listen for changes on each sub doc.
+
*/
var x = require('xdiff')
var EventEmitter = require('events').EventEmitter
-function XModel () {
- this.root = {}
+
+function XModel (parent, path) {
+
+ this._parent = parent || this
+ if(this._parent === this) {
+ this.root = {}
+ this._refs = findRefs(this.root)
+ }
+ path = this._path = path || ['root']
+ this._at =
+ this._parent._refs[path[0]]
+ ? getPath(this._parent._refs, path)
+ : getPath(this._parent, path)
}
var proto = XModel.prototype = new EventEmitter()
+proto.toJSON = function () {
+ return this._at
+}
+
function getPath (obj, path) {
if(!Array.isArray(path))
return obj[path]
@@ -36,81 +61,91 @@ proto.sync = function (other, read, write) {
var method = args.shift()
self[method].apply(self, args)
}
- other.on('change', onChange)
+ other.on('update', onChange)
this.unsync = function () {
- other.removeListener('change', onChange)
+ other.removeListener('update', onChange)
this._synced = null
}
} else { //assume Repo
+ var queued = false
function onPreUpdate () {
//commit
try {
other.commit(self.root)
} catch (e) {
//expect no change
+ console.error(e)
+ //RETHROW IF IT"S not the nochanges error
}
}
function onUpdate () {
var _obj = other.checkout()
var delta = x.diff(self.root, _obj)
- console.log(delta)
if(!delta) return
if(delta) self.patch(delta)
- console.log(self)
+ }
+ function onSelfUpdate () {
+ if(queued) return
+ process.nextTick(function () {
+ onPreUpdate()
+ queued = false
+ })
+ queued = true
}
other.on('preupdate', onPreUpdate)
other.on('update', onUpdate)
+ self.on('update', onSelfUpdate)
self.unsync = function () {
other.removeListener('preupdate', onPreUpdate)
other.removeListener('update', onUpdate)
+ self.removeListener('update', onSelfUpdate)
self._synced = null
}
}
}
+proto.getRoot = function () {
+ return this._parent
+}
proto.at = function (path) {
if(arguments.length > 1)
path = [].slice.call(arguments)
else if('string' == typeof path)
path = [path]
- console.log(path, this._refs, this.root)
- if(this._refs[path[0]])
- return getPath(this._refs, path)
- return getPath(this, path)
+
+ return new XModel(this._parent,
+ this._parent._refs[path[0]]
+ ? path
+ : this._path.concat(path)
+ )
}
-proto.set = function (_path, value) {
- var path = _path.slice()
- var key = path.pop()
- var at = this.at(path)
- var obj = at[key] = value
- this._update('set', path, value)
+proto.set = function (key, value) {
+ var obj = this._at[key] = value
+ this._update('set', this._path.concat(key), value)
return this
}
-proto.del = function (_path) {
- var path = _path.slice()
- var key = path.pop()
- var at = this.at(path)
- this._update('del', path)
+proto.del = function (key) {
+ delete this._at[key]
+ this._update('del', _path)
return this
}
-proto.splice = function (path, splices) {
- var at = this.at(path)
- for (var i in splices)
- [].splice.apply(at, splices[i])
- this._update('splice', path, splices)
+proto.splice = function () {
+ var args = [].slice.call(arguments)
+ ;[].splice.apply(this._at, args)
+ this._update('splice', this._path, args)
return this
}
-proto._change = function () {
+proto._update = function () {
var args = [].slice.call(arguments)
this.emit.apply(this, args)
//TODO: would be better to do this lazy, or only update the inserted objects
// will be much more PERFORMANT
this._refs = findRefs(this.root)
- args.unshift('change')
+ args.unshift('update')
this.emit.apply(this, args)
}
@@ -144,6 +179,7 @@ proto.patch = function (patch) {
patch.forEach(function (change) {
self.emit.apply(self, change)
})
+ self.emit('update', patch)
}
module.exports = XModel
View
2 test/simple.js
@@ -41,4 +41,4 @@ a.deepEqual(x.root,
['ONE', 2, 3, abc]
)
console.log(x)
- a.deepEqual(x.at('abc'), abc)
+ a.deepEqual(x.at('abc').toJSON(), abc)

0 comments on commit 8f1d449

Please sign in to comment.
Something went wrong with that request. Please try again.