Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

DELTA STREAM

  • Loading branch information...
commit 4a502f8e3aa16374fc3c8ef510f011911cbc9754 1 parent 86ad570
@Raynos authored
View
19 doc.js
@@ -55,15 +55,13 @@ function Doc (id) {
this.setMaxListeners(Infinity)
this.sets.setMaxListeners(Infinity)
Scuttlebutt.call(this, id)
-
}
Doc.prototype.add = function (initial) {
-
if(!initial.id)
throw new Error('id is required')
var r = this._add(initial.id, 'local')
- r._set(initial, 'local')
+ r.set(initial)
return r
}
@@ -74,10 +72,10 @@ Doc.prototype._add = function (id, source) {
if(this.rows[id])
return this.rows[id]
- var r = id instanceof Row ? id : new Row(id)
+ var r = Row.isRow(id) ? id : Row(id)
this.rows[r.id] = r
- function track (changes, source) {
+ function track (changes) {
// var update = [r.id, changes, u.timestamp(), doc.id]
doc.localUpdate(r.id, changes)
}
@@ -97,7 +95,8 @@ Doc.prototype.timeUpdated = function (row, key) {
Doc.prototype.set = function (id, change) {
var r = this._add(id, 'local')
- return r.set(change)
+ r.set(change)
+ return r
}
/*
@@ -150,16 +149,14 @@ Doc.prototype.applyUpdate = function (update, source) {
// hang on, in the mean time, I will probably only be managing n < 10 sets.
// at once,
- u.merge(row.state, changed)
for(var k in changed)
- this.sets.emit(k, row, changed)
+ this.sets.emit(k, row, changed)
+
+ row._set(changed)
if(!emit) return
this.emit('_update', update)
- row.emit('update', update, changed)
- row.emit('changes', changes, changed)
- row.emit('change', changed) //installing this in paralel, so tests still pass.
//will depreciate the old way later.
this.emit('update', update, source) //rename this event to 'data' or 'diff'?
this.emit('row_update', row) //rename this event to 'update'
View
3,342 example/complex/bundle.js
2,394 additions, 948 deletions not shown
View
10 example/complex/chat.js
@@ -1,4 +1,4 @@
-var crdt = require('crdt')
+var crdt = require('../../index')
module.exports =
@@ -14,7 +14,7 @@ function createChat (el, doc) {
messages.on('add', function (obj) {
var div, span, a
- div =
+ div =
$('<div class=line>')
.append(span = $('<span class=message>'))
.append(a = $('<a href=# class=del>x</a>')
@@ -25,10 +25,10 @@ function createChat (el, doc) {
CONTENT.append(div)
- obj.on('update', function () {
+ obj.on('change', function () {
if(obj.get('__delete')) {
div.remove()
- obj.removeAllListeners('update')
+ obj.removeAllListeners('change')
}
span.text(obj.get('text'))
})
@@ -53,7 +53,7 @@ function createChat (el, doc) {
e.set('text', ntext.split(search).join(replace))
}
})
- } else
+ } else
doc.set('_'+Date.now(), {text: this.value, type: 'message'})
this.value = ''
})
View
2  example/complex/client.js
@@ -1,4 +1,4 @@
-var crdt = require('crdt')
+var crdt = require('../../index')
var reconnect = require('reconnect/shoe')
var MuxDemux = require('mux-demux')
var kv = require('kv')('crdt_example')
View
6 example/complex/mouses.js
@@ -4,7 +4,7 @@
so that users don't feel lonely.
*/
-var crdt = require('crdt')
+var crdt = require('../../index')
module.exports =
function (doc) {
@@ -30,13 +30,13 @@ function (doc) {
mice.on('add', function (m) {
console.log('ADD', m)
- var pointer =
+ var pointer =
$('<span class=pointer>' + m.id +'</span>')
.css({position: 'absolute'})
$('body').append(pointer)
- m.on('update', function () {
+ m.on('change', function () {
console.log(m.get('id'), m.get('x'), m.get('y'), m.get('in'))
pointer.css({
left: m.get('x')
View
3  example/complex/package.json
@@ -10,7 +10,8 @@
"domready": "~0.2.11"
},
"devDependencies": {
- "tap": "0.3.0"
+ "tap": "0.3.0",
+ "domready": "~0.2.11"
},
"scripts": {
"test": "tap test"
View
8 example/complex/sets.js
@@ -1,4 +1,4 @@
-var crdt = require('crdt')
+var crdt = require('../../index')
/*
add some sets, that items can be dragged and dropped between,
@@ -15,7 +15,7 @@ function seqWidget( el, seq, template ) {
el = $(el)
var name = el.attr('id')
- function update (r) {
+ function update (r) {
var li = $('#'+r.id)
li = li.length ? li : $(template(r))
@@ -82,7 +82,7 @@ function (div, doc) {
.append(text = $('<span>'+r.get('text')+'</span>'))
.append(check = $('<input type=checkbox>'))
- r.on('update', function () {
+ r.on('change', function () {
text.text(r.get('text'))
check.attr('checked', r.get('checked'))
})
@@ -103,7 +103,7 @@ function (div, doc) {
}
function st (q) {
- return $('<ul class=sortable id='+q.id+'>')
+ return $('<ul class=sortable id='+q.key+'>')
}
function addable (s, q) {
View
172 example/simple/bundle.js
88 additions, 84 deletions not shown
View
8 package.json
@@ -15,14 +15,18 @@
},
"dependencies": {
"between": "0.0.0",
- "scuttlebutt": "~2.2.0"
+ "scuttlebutt": "~2.2.0",
+ "delta-stream": "~1.1.1"
},
"devDependencies": {
"it-is": "~1.0.1",
"event-stream": "~3.0",
"asynct": "~1.1",
"kv": "~0.5",
- "mux-demux": "~3.2"
+ "mux-demux": "~3.2",
+ "assertions": "~2.3.0",
+ "jquery-browserify": "~1.7.2",
+ "express": "~3.0.0rc4"
},
"optionalDependencies": {}
}
View
72 row.js
@@ -2,57 +2,39 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'use strict';
-var inherits = require('util').inherits
-var EventEmitter = require('events').EventEmitter
+var Delta = require("delta-stream")
-module.exports = Row
+Row.isRow = isRow
-inherits(Row, EventEmitter)
+module.exports = Row
function Row (id) {
- this.id = id
- this.state = {id: id}
- this.setMaxListeners(Infinity)
-}
-
-Row.prototype.set = function (changes, v) {
- if(arguments.length == 2) {
- var k = changes
- changes = {}
- changes[k] = v
+ var delta = Delta(id)
+
+ delta._set = delta.set
+
+ delta.validate = function (changes) {
+ try {
+ delta.emit('validate', changes)
+ return true
+ } catch (e) {
+ console.error('validation', e.message)
+ return false
+ }
}
- if(changes.id && changes.id !== this.state.id)
- throw new Error('id cannot be changed')
-
- this._set(changes, 'local')
- return this
-}
-
-Row.prototype.validate = function (changes) {
- try {
- this.emit('validate', changes)
- return true
- } catch (e) {
- console.error('validation', e.message)
- return false
- }
-}
-
-Row.prototype._set = function (changes, source) {
-
- //the change is applied by the Doc!
- this.emit('preupdate', changes, source)
- return this
-}
-
-Row.prototype.get = function (key) {
- if(key)
- return this.state[key]
- return this.state
-}
+ delta.set = function (key, value) {
+ var changes = key
+ if (typeof key === 'string') {
+ changes = {}
+ changes[key] = value
+ }
+ delta.emit('preupdate', changes)
+ }
-Row.prototype.toJSON = function () {
- return this.state
+ return delta
}
+function isRow(r) {
+ return r.set && r.get && r.validate && r._update
+}
View
16 seq.js
@@ -32,14 +32,14 @@ function Seq (doc, key, val) {
if(!changes._sort) return
sort(seq._array)
//check if there is already an item with this sort key.
- var prev =
+ var prev =
find(seq._array, function (other) {
return other != row && other.get('_sort') == row.get('_sort')
})
- //nudge it forward if it has the same key.
+ //nudge it forward if it has the same key.
if(prev)
- seq.insert(row, prev, seq.next(row))
+ seq.insert(row, prev, seq.next(row))
else
seq.emit('move', row)
})
@@ -53,14 +53,14 @@ function Seq (doc, key, val) {
if('string' === typeof obj)
obj = doc.rows[obj]
- var _sort =
- u.between(before, after )
+ var _sort =
+ u.between(before, after )
+ u.randstr(3) //add a random tail so it's hard
//to concurrently add two items with the
//same sort.
var r, changes
- if(obj instanceof Row) {
+ if(Row.isRow(obj)) {
r = obj
changes = {_sort: _sort}
if(r.get(key) != val)
@@ -70,7 +70,7 @@ function Seq (doc, key, val) {
obj._sort = _sort
obj[key] = val
r = doc.set(id(obj), obj)
- }
+ }
sort(this._array)
return r
}
@@ -80,7 +80,7 @@ function toKey (key) {
return (
'string' === typeof key ? key
- : key instanceof Row ? key.get()._sort
+ : Row.isRow(key) ? key.get("_sort")
: key ? key._sort
: null
)
View
40 set.js
@@ -40,49 +40,61 @@ module.exports = Set
//TODO check if any currently existing items should be in the set. currently, one must create the set before recieving anything.
-function Set(doc, key, value) {
+function Set(doc, masterKey, masterValue) {
var array = this._array = []
var rows = this.rows = {}
var set = this
//DO NOT CHANGE once you have created the set.
- this.key = key
- this.value = value
+ this.key = masterKey
+ this.value = masterValue
function add(row) {
+ // It doesnt have the masterKey prop on state at start
+ var hasKey = false
array.push(row)
rows[row.id] = row
set.emit('add', row)
- function remove (_, changed) {
- if(row.state[key] === value)
- return set.emit('changes', row, changed)
+ function remove (key, value) {
+ // once it has it we no longer need to assume it's set
+ if (key === masterKey) {
+ hasKey = true
+ }
+
+ // If it doesn't have the key yet, assume it's correct
+ if(row.get(masterKey) === masterValue || !hasKey) {
+ var changes = {}
+ changes[key] = value
+ return set.emit('changes', row, changes)
+ }
+
delete rows[row.id]
var i = array.indexOf(row)
if(~i) array.splice(i, 1)
else return
set.emit('remove', row)
- row.removeListener('changes', remove)
+ row.removeListener('change', remove)
}
- row.on('changes', remove)
-
+ row.on('change', remove)
}
- doc.sets.on(key, function (row, changed) {
- if(changed[key] !== value) return
+ doc.sets.on(masterKey, function (row, changed) {
+ if(changed[masterKey] !== masterValue) return
add(row)
})
this.rm = this.remove = function (row) {
row = this.get(row)
if(!row) return
- return row.set(key, null)
+ row.set(masterKey, null)
+ return row
}
for(var id in doc.rows) {
var row = doc.get(id)
- if(row.get(key) === value) add(row)
+ if(row.get(masterKey) === masterValue) add(row)
}
this.setMaxListeners(Infinity)
@@ -95,7 +107,7 @@ Set.prototype.asArray = function () {
Set.prototype.toJSON = function () {
return this._array.map(function (e) {
- return e.state
+ return e.toJSON()
}).sort(function (a, b) {
return u.strord(a._sort || a.id, b._sort || b.id)
})
View
7 test/seq.js
@@ -39,9 +39,10 @@ exports['simple'] = function (t) {
a.equal(seq.indexOf(id(A)), 1)
seq.rm({id: 'c'})
+
a.equal(seq.first(), A)
- console.log(seq.toJSON())
+ //console.log(seq.toJSON())
seq.push(C)
a.strictEqual(seq.last().id, C.id)
@@ -137,7 +138,7 @@ function sync(array, seq) {
r[n] = function (i) {
seq[n](/push|unshift/.test(n) ? i : id(i))
array[n](i)
- console.log(i)
+ //console.log(i)
if(i) {
a.equal(array.indexOf(i), seq.indexOf(i.id))
}
@@ -167,7 +168,7 @@ exports.random = function (t) {
while(l --) {
var op = ['push','pop', 'shift', 'unshift'][~~(Math.random()*4)]
var obj = {id: '_'+Math.random(), r: Math.random()}
- console.log(op, obj, ary.length, l)
+ //console.log(op, obj, ary.length, l)
try {
s[op](obj)
} catch (e) {
View
4 test/sets.js
@@ -10,10 +10,10 @@ exports['test'] = function (t) {
function log(set) {
set.on('add', function (row) {
- console.log('add', set.value,'->', row.state)
+ console.log('add', set.value,'->', row.toJSON())
})
set.on('remove', function (row) {
- console.log('rm', set.value,'->', row.state)
+ console.log('rm', set.value,'->', row.toJSON())
})
}
View
2  test/simple.js
@@ -64,7 +64,7 @@ exports.listen = function (t) {
var random = Math.random()
var thing = doc.get('thing')
- thing.on('changes', function (r) {
+ thing.on('change:random', function (r) {
a.equal(thing.get('random'), random)
t.end()
})
Please sign in to comment.
Something went wrong with that request. Please try again.