refactored database
This commit is contained in:
parent
ee133ef334
commit
181595293f
@ -41,11 +41,11 @@ class AbstractConnector {
|
|||||||
this.broadcastedHB = false
|
this.broadcastedHB = false
|
||||||
this.syncingClients = []
|
this.syncingClients = []
|
||||||
this.whenSyncedListeners = []
|
this.whenSyncedListeners = []
|
||||||
this.y.db.stopGarbageCollector()
|
return this.y.db.stopGarbageCollector()
|
||||||
}
|
}
|
||||||
setUserId (userId) {
|
setUserId (userId) {
|
||||||
this.userId = userId
|
this.userId = userId
|
||||||
this.y.db.setUserId(userId)
|
return this.y.db.setUserId(userId)
|
||||||
}
|
}
|
||||||
onUserEvent (f) {
|
onUserEvent (f) {
|
||||||
this.userEventListeners.push(f)
|
this.userEventListeners.push(f)
|
||||||
@ -132,7 +132,7 @@ class AbstractConnector {
|
|||||||
}
|
}
|
||||||
this.whenSyncedListeners = []
|
this.whenSyncedListeners = []
|
||||||
this.y.db.requestTransaction(function *() {
|
this.y.db.requestTransaction(function *() {
|
||||||
yield* this.store.garbageCollectAfterSync()
|
yield* this.garbageCollectAfterSync()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,9 @@ class Test extends Y.AbstractConnector {
|
|||||||
options.role = 'master'
|
options.role = 'master'
|
||||||
options.forwardToSyncingClients = false
|
options.forwardToSyncingClients = false
|
||||||
super(y, options)
|
super(y, options)
|
||||||
this.setUserId((userIdCounter++) + '')
|
this.setUserId((userIdCounter++) + '').then(() => {
|
||||||
globalRoom.addUser(this)
|
globalRoom.addUser(this)
|
||||||
|
})
|
||||||
this.globalRoom = globalRoom
|
this.globalRoom = globalRoom
|
||||||
this.syncingClientDuration = 0
|
this.syncingClientDuration = 0
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* destroy()
|
* destroy()
|
||||||
- destroy the database
|
- destroy the database
|
||||||
*/
|
*/
|
||||||
class AbstractOperationStore {
|
class AbstractDatabase {
|
||||||
constructor (y, opts) {
|
constructor (y, opts) {
|
||||||
this.y = y
|
this.y = y
|
||||||
// E.g. this.listenersById[id] : Array<Listener>
|
// E.g. this.listenersById[id] : Array<Listener>
|
||||||
@ -80,16 +80,6 @@ class AbstractOperationStore {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
* garbageCollectAfterSync () {
|
|
||||||
this.requestTransaction(function * () {
|
|
||||||
yield* this.os.iterate(this, null, null, function * (op) {
|
|
||||||
if (op.deleted && op.left != null) {
|
|
||||||
var left = yield this.os.find(op.left)
|
|
||||||
this.store.addToGarbageCollector(op, left)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
Try to add to GC.
|
Try to add to GC.
|
||||||
|
|
||||||
@ -130,12 +120,18 @@ class AbstractOperationStore {
|
|||||||
this.gcInterval = null
|
this.gcInterval = null
|
||||||
}
|
}
|
||||||
setUserId (userId) {
|
setUserId (userId) {
|
||||||
this.userId = userId
|
var self = this
|
||||||
this.opClock = 0
|
return new Promise(function (resolve) {
|
||||||
if (this.whenUserIdSetListener != null) {
|
self.requestTransaction(function * () {
|
||||||
this.whenUserIdSetListener()
|
self.userId = userId
|
||||||
this.whenUserIdSetListener = null
|
self.opClock = (yield* this.getState(userId)).clock
|
||||||
|
if (self.whenUserIdSetListener != null) {
|
||||||
|
self.whenUserIdSetListener()
|
||||||
|
self.whenUserIdSetListener = null
|
||||||
}
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
whenUserIdSet (f) {
|
whenUserIdSet (f) {
|
||||||
if (this.userId != null) {
|
if (this.userId != null) {
|
||||||
@ -280,4 +276,4 @@ class AbstractOperationStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Y.AbstractOperationStore = AbstractOperationStore
|
Y.AbstractDatabase = AbstractDatabase
|
||||||
|
@ -156,10 +156,10 @@ for (var database of databases) {
|
|||||||
})
|
})
|
||||||
it('debug #1', function (done) {
|
it('debug #1', function (done) {
|
||||||
store.requestTransaction(function * () {
|
store.requestTransaction(function * () {
|
||||||
yield this.os.set({id: [2]})
|
yield this.os.put({id: [2]})
|
||||||
yield this.os.set({id: [0]})
|
yield this.os.put({id: [0]})
|
||||||
yield this.os.delete([2])
|
yield this.os.delete([2])
|
||||||
yield this.os.set({id: [1]})
|
yield this.os.put({id: [1]})
|
||||||
expect(yield this.os.find([0])).not.toBeNull()
|
expect(yield this.os.find([0])).not.toBeNull()
|
||||||
expect(yield this.os.find([1])).not.toBeNull()
|
expect(yield this.os.find([1])).not.toBeNull()
|
||||||
expect(yield this.os.find([2])).toBeNull()
|
expect(yield this.os.find([2])).toBeNull()
|
||||||
@ -168,11 +168,11 @@ for (var database of databases) {
|
|||||||
})
|
})
|
||||||
it('can add&retrieve 5 elements', function (done) {
|
it('can add&retrieve 5 elements', function (done) {
|
||||||
store.requestTransaction(function * () {
|
store.requestTransaction(function * () {
|
||||||
yield this.os.set({val: 'four', id: [4]})
|
yield this.os.put({val: 'four', id: [4]})
|
||||||
yield this.os.set({val: 'one', id: [1]})
|
yield this.os.put({val: 'one', id: [1]})
|
||||||
yield this.os.set({val: 'three', id: [3]})
|
yield this.os.put({val: 'three', id: [3]})
|
||||||
yield this.os.set({val: 'two', id: [2]})
|
yield this.os.put({val: 'two', id: [2]})
|
||||||
yield this.os.set({val: 'five', id: [5]})
|
yield this.os.put({val: 'five', id: [5]})
|
||||||
expect((yield this.os.find([1])).val).toEqual('one')
|
expect((yield this.os.find([1])).val).toEqual('one')
|
||||||
expect((yield this.os.find([2])).val).toEqual('two')
|
expect((yield this.os.find([2])).val).toEqual('two')
|
||||||
expect((yield this.os.find([3])).val).toEqual('three')
|
expect((yield this.os.find([3])).val).toEqual('three')
|
||||||
@ -183,11 +183,11 @@ for (var database of databases) {
|
|||||||
})
|
})
|
||||||
it('5 elements do not exist anymore after deleting them', function (done) {
|
it('5 elements do not exist anymore after deleting them', function (done) {
|
||||||
store.requestTransaction(function * () {
|
store.requestTransaction(function * () {
|
||||||
yield this.os.set({val: 'four', id: [4]})
|
yield this.os.put({val: 'four', id: [4]})
|
||||||
yield this.os.set({val: 'one', id: [1]})
|
yield this.os.put({val: 'one', id: [1]})
|
||||||
yield this.os.set({val: 'three', id: [3]})
|
yield this.os.put({val: 'three', id: [3]})
|
||||||
yield this.os.set({val: 'two', id: [2]})
|
yield this.os.put({val: 'two', id: [2]})
|
||||||
yield this.os.set({val: 'five', id: [5]})
|
yield this.os.put({val: 'five', id: [5]})
|
||||||
yield this.os.delete([4])
|
yield this.os.delete([4])
|
||||||
expect(yield this.os.find([4])).not.toBeTruthy()
|
expect(yield this.os.find([4])).not.toBeTruthy()
|
||||||
yield this.os.delete([3])
|
yield this.os.delete([3])
|
||||||
@ -216,7 +216,7 @@ for (var database of databases) {
|
|||||||
var obj = [Math.floor(Math.random() * numberOfOSTests * 10000)]
|
var obj = [Math.floor(Math.random() * numberOfOSTests * 10000)]
|
||||||
if (!(yield this.os.findNode(obj))) {
|
if (!(yield this.os.findNode(obj))) {
|
||||||
elements.push(obj)
|
elements.push(obj)
|
||||||
yield this.os.set({id: obj})
|
yield this.os.put({id: obj})
|
||||||
}
|
}
|
||||||
} else if (elements.length > 0) {
|
} else if (elements.length > 0) {
|
||||||
var elemid = Math.floor(Math.random() * elements.length)
|
var elemid = Math.floor(Math.random() * elements.length)
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
Y.IndexedDB = (function () {
|
Y.IndexedDB = (function () {
|
||||||
class Transaction extends Y.AbstractTransaction {
|
class Transaction {
|
||||||
constructor (store) {
|
constructor (store) {
|
||||||
super(store)
|
|
||||||
this.transaction = store.db.transaction(['OperationStore', 'StateVector'], 'readwrite')
|
this.transaction = store.db.transaction(['OperationStore', 'StateVector'], 'readwrite')
|
||||||
this.sv = this.transaction.objectStore('StateVector')
|
this.sv = this.transaction.objectStore('StateVector')
|
||||||
this.os = this.transaction.objectStore('OperationStore')
|
this.os = this.transaction.objectStore('OperationStore')
|
||||||
@ -83,7 +82,7 @@ Y.IndexedDB = (function () {
|
|||||||
return ops
|
return ops
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class OperationStore extends Y.AbstractOperationStore {
|
class OperationStore extends Y.AbstractDatabase {
|
||||||
constructor (y, opts) {
|
constructor (y, opts) {
|
||||||
super(y, opts)
|
super(y, opts)
|
||||||
if (opts == null) {
|
if (opts == null) {
|
||||||
|
@ -8,101 +8,6 @@ if (typeof window !== 'undefined' && false) {
|
|||||||
ob = new Y.IndexedDB(null, {namespace: 'Test', gcTimeout: -1})
|
ob = new Y.IndexedDB(null, {namespace: 'Test', gcTimeout: -1})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can add and get operation', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
var op = yield* this.setOperation({
|
|
||||||
'id': ['1', 0],
|
|
||||||
'stuff': true
|
|
||||||
})
|
|
||||||
expect(yield* this.getOperation(['1', 0]))
|
|
||||||
.toEqual(op)
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can remove operation', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
var op = yield* this.setOperation({
|
|
||||||
'id': ['1', 0],
|
|
||||||
'stuff': true
|
|
||||||
})
|
|
||||||
expect(yield* this.getOperation(['1', 0]))
|
|
||||||
.toEqual(op)
|
|
||||||
yield* this.removeOperation(['1', 0])
|
|
||||||
expect(yield* this.getOperation(['1', 0]))
|
|
||||||
.toBeNull()
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('getOperation(op) returns undefined if op does not exist', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
var op = yield* this.getOperation("plzDon'tBeThere")
|
|
||||||
expect(op).toBeNull()
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('yield throws if request is unknown', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
try {
|
|
||||||
yield* this.setOperation()
|
|
||||||
} catch (e) {
|
|
||||||
expect(true).toEqual(true)
|
|
||||||
done()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
expect('Expected an Error!').toEqual(true)
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('sets and gets stateVector', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
var s1 = {user: '1', clock: 1}
|
|
||||||
var s2 = {user: '2', clock: 3}
|
|
||||||
yield* this.setState(s1)
|
|
||||||
yield* this.setState(s2)
|
|
||||||
var sv = yield* this.getStateVector()
|
|
||||||
expect(sv).toEqual([s1, s2])
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('gets stateSet', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
var s1 = {user: '1', clock: 1}
|
|
||||||
var s2 = {user: '2', clock: 3}
|
|
||||||
yield* this.setState(s1)
|
|
||||||
yield* this.setState(s2)
|
|
||||||
var sv = yield* this.getStateSet()
|
|
||||||
expect(sv).toEqual({
|
|
||||||
'1': 1,
|
|
||||||
'2': 3
|
|
||||||
})
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('getOperations returns operations (no parameters)', function (done) {
|
|
||||||
ob.requestTransaction(function *() {
|
|
||||||
var s1 = {user: '1', clock: 55}
|
|
||||||
yield* this.setState(s1)
|
|
||||||
var op1 = yield* this.setOperation({
|
|
||||||
'id': ['1', 0],
|
|
||||||
'stuff': true
|
|
||||||
})
|
|
||||||
var op2 = yield* this.setOperation({
|
|
||||||
'id': ['1', 3],
|
|
||||||
'stuff': true
|
|
||||||
})
|
|
||||||
var ops = yield* this.getOperations()
|
|
||||||
expect(ops.length).toBeGreaterThan(1)
|
|
||||||
expect(ops[0]).toEqual(op1)
|
|
||||||
expect(ops[1]).toEqual(op2)
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
afterAll(function (done) {
|
afterAll(function (done) {
|
||||||
ob.requestTransaction(function *() {
|
ob.requestTransaction(function *() {
|
||||||
yield* ob.removeDatabase()
|
yield* ob.removeDatabase()
|
||||||
|
@ -1,19 +1,8 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
class DeleteStore extends Y.utils.RBTree {
|
|
||||||
constructor () {
|
|
||||||
super()
|
|
||||||
this.mem = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Y.utils.DeleteStore = DeleteStore
|
|
||||||
|
|
||||||
Y.Memory = (function () {
|
Y.Memory = (function () {
|
||||||
class Transaction extends Y.AbstractTransaction {
|
class Database extends Y.AbstractDatabase {
|
||||||
}
|
|
||||||
class OperationStore extends Y.AbstractOperationStore {
|
|
||||||
constructor (y, opts) {
|
constructor (y, opts) {
|
||||||
super(y, opts)
|
super(y, opts)
|
||||||
this.os = new Y.utils.RBTree()
|
this.os = new Y.utils.RBTree()
|
||||||
@ -42,7 +31,7 @@ Y.Memory = (function () {
|
|||||||
var transact = () => {
|
var transact = () => {
|
||||||
var makeGen = _makeGen
|
var makeGen = _makeGen
|
||||||
while (makeGen != null) {
|
while (makeGen != null) {
|
||||||
var t = new Transaction(this)
|
var t = new Y.Transaction(this)
|
||||||
var gen = makeGen.call(t)
|
var gen = makeGen.call(t)
|
||||||
var res = gen.next()
|
var res = gen.next()
|
||||||
while (!res.done) {
|
while (!res.done) {
|
||||||
@ -64,7 +53,9 @@ Y.Memory = (function () {
|
|||||||
* destroy () {
|
* destroy () {
|
||||||
super.destroy()
|
super.destroy()
|
||||||
delete this.os
|
delete this.os
|
||||||
|
delete this.ss
|
||||||
|
delete this.ds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OperationStore
|
return Database
|
||||||
})()
|
})()
|
||||||
|
@ -388,7 +388,7 @@ class RBTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set (v) {
|
put (v) {
|
||||||
if (v == null || v.id == null || v.id.constructor !== Array) {
|
if (v == null || v.id == null || v.id.constructor !== Array) {
|
||||||
throw new Error('v is expected to have an id property which is an Array!')
|
throw new Error('v is expected to have an id property which is an Array!')
|
||||||
}
|
}
|
||||||
|
@ -59,15 +59,15 @@ describe('RedBlack Tree', function () {
|
|||||||
})
|
})
|
||||||
describe('debug #2', function () {
|
describe('debug #2', function () {
|
||||||
var tree = new Y.utils.RBTree()
|
var tree = new Y.utils.RBTree()
|
||||||
tree.set({id: [8433]})
|
tree.put({id: [8433]})
|
||||||
tree.set({id: [12844]})
|
tree.put({id: [12844]})
|
||||||
tree.set({id: [1795]})
|
tree.put({id: [1795]})
|
||||||
tree.set({id: [30302]})
|
tree.put({id: [30302]})
|
||||||
tree.set({id: [64287]})
|
tree.put({id: [64287]})
|
||||||
tree.delete([8433])
|
tree.delete([8433])
|
||||||
tree.set({id: [28996]})
|
tree.put({id: [28996]})
|
||||||
tree.delete([64287])
|
tree.delete([64287])
|
||||||
tree.set({id: [22721]})
|
tree.put({id: [22721]})
|
||||||
|
|
||||||
itRootNodeIsBlack(tree, [])
|
itRootNodeIsBlack(tree, [])
|
||||||
itBlackHeightOfSubTreesAreEqual(tree, [])
|
itBlackHeightOfSubTreesAreEqual(tree, [])
|
||||||
@ -82,7 +82,7 @@ describe('RedBlack Tree', function () {
|
|||||||
var obj = [Math.floor(Math.random() * numberOfRBTreeTests * 10000)]
|
var obj = [Math.floor(Math.random() * numberOfRBTreeTests * 10000)]
|
||||||
if (!tree.findNode(obj)) {
|
if (!tree.findNode(obj)) {
|
||||||
elements.push(obj)
|
elements.push(obj)
|
||||||
tree.set({id: obj})
|
tree.put({id: obj})
|
||||||
}
|
}
|
||||||
} else if (elements.length > 0) {
|
} else if (elements.length > 0) {
|
||||||
var elemid = Math.floor(Math.random() * elements.length)
|
var elemid = Math.floor(Math.random() * elements.length)
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
- this is called only by `getOperations(startSS)`. It makes an operation
|
- this is called only by `getOperations(startSS)`. It makes an operation
|
||||||
applyable on a given SS.
|
applyable on a given SS.
|
||||||
*/
|
*/
|
||||||
class AbstractTransaction {
|
class Transaction {
|
||||||
constructor (store) {
|
constructor (store) {
|
||||||
this.store = store
|
this.store = store
|
||||||
this.ss = store.ss
|
this.ss = store.ss
|
||||||
@ -206,14 +206,14 @@ class AbstractTransaction {
|
|||||||
// un-extend left
|
// un-extend left
|
||||||
var newlen = n.val.len - (id[1] - n.val.id[1])
|
var newlen = n.val.len - (id[1] - n.val.id[1])
|
||||||
n.val.len -= newlen
|
n.val.len -= newlen
|
||||||
n = yield this.ds.set({id: id, len: newlen, gc: false})
|
n = yield this.ds.put({id: id, len: newlen, gc: false})
|
||||||
}
|
}
|
||||||
// get prev&next before adding a new operation
|
// get prev&next before adding a new operation
|
||||||
var prev = n.prev()
|
var prev = n.prev()
|
||||||
var next = n.next()
|
var next = n.next()
|
||||||
if (id[1] < n.val.id[1] + n.val.len - 1) {
|
if (id[1] < n.val.id[1] + n.val.len - 1) {
|
||||||
// un-extend right
|
// un-extend right
|
||||||
yield this.ds.set({id: [id[0], id[1] + 1], len: n.val.len - 1, gc: false})
|
yield this.ds.put({id: [id[0], id[1] + 1], len: n.val.len - 1, gc: false})
|
||||||
n.val.len = 1
|
n.val.len = 1
|
||||||
}
|
}
|
||||||
// set gc'd
|
// set gc'd
|
||||||
@ -256,11 +256,11 @@ class AbstractTransaction {
|
|||||||
n.val.len++
|
n.val.len++
|
||||||
} else {
|
} else {
|
||||||
// cannot extend left
|
// cannot extend left
|
||||||
n = yield this.ds.set({id: id, len: 1, gc: false})
|
n = yield this.ds.put({id: id, len: 1, gc: false})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// cannot extend left
|
// cannot extend left
|
||||||
n = yield this.ds.set({id: id, len: 1, gc: false})
|
n = yield this.ds.put({id: id, len: 1, gc: false})
|
||||||
}
|
}
|
||||||
// can extend right?
|
// can extend right?
|
||||||
var next = n.next()
|
var next = n.next()
|
||||||
@ -276,6 +276,19 @@ class AbstractTransaction {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Call this method when the client is connected&synced with the
|
||||||
|
other clients (e.g. master). This will query the database for
|
||||||
|
operations that can be gc'd and add them to the garbage collector.
|
||||||
|
*/
|
||||||
|
* garbageCollectAfterSync () {
|
||||||
|
yield* this.os.iterate(this, null, null, function * (op) {
|
||||||
|
if (op.deleted && op.left != null) {
|
||||||
|
var left = yield* this.getOperation(op.left)
|
||||||
|
this.store.addToGarbageCollector(op, left)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Really remove an op and all its effects.
|
Really remove an op and all its effects.
|
||||||
The complicated case here is the Insert operation:
|
The complicated case here is the Insert operation:
|
||||||
@ -482,13 +495,11 @@ class AbstractTransaction {
|
|||||||
return n !== null && n.val.id[0] === id[0] && id[1] < n.val.id[1] + n.val.len
|
return n !== null && n.val.id[0] === id[0] && id[1] < n.val.id[1] + n.val.len
|
||||||
}
|
}
|
||||||
* setOperation (op) {
|
* setOperation (op) {
|
||||||
// TODO: you can remove this step! probs..
|
yield this.os.put(op)
|
||||||
var n = yield this.os.findNode(op.id)
|
|
||||||
n.val = op
|
|
||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
* addOperation (op) {
|
* addOperation (op) {
|
||||||
var n = yield this.os.set(op)
|
var n = yield this.os.put(op)
|
||||||
return function () {
|
return function () {
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
n = n.next()
|
n = n.next()
|
||||||
@ -505,10 +516,16 @@ class AbstractTransaction {
|
|||||||
yield this.os.delete(id)
|
yield this.os.delete(id)
|
||||||
}
|
}
|
||||||
* setState (state) {
|
* setState (state) {
|
||||||
this.ss.set({
|
var val = {
|
||||||
id: [state.user],
|
id: [state.user],
|
||||||
clock: state.clock
|
clock: state.clock
|
||||||
})
|
}
|
||||||
|
// TODO: find a way to skip this step.. (after implementing some dbs..)
|
||||||
|
if (yield this.ss.find([state.user])) {
|
||||||
|
yield this.ss.put(val)
|
||||||
|
} else {
|
||||||
|
yield this.ss.put(val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
* getState (user) {
|
* getState (user) {
|
||||||
var n
|
var n
|
||||||
@ -625,4 +642,4 @@ class AbstractTransaction {
|
|||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Y.AbstractTransaction = AbstractTransaction
|
Y.Transaction = Transaction
|
||||||
|
Loading…
x
Reference in New Issue
Block a user