new build system
This commit is contained in:
parent
4bfe484fc2
commit
82b3e50d49
52
gulpfile.js
52
gulpfile.js
@ -100,24 +100,18 @@ gulp.task('build', function () {
|
|||||||
.pipe(gulp.dest('.'))
|
.pipe(gulp.dest('.'))
|
||||||
})
|
})
|
||||||
|
|
||||||
gulp.task('test', function () {
|
gulp.task('testbuild', function () {
|
||||||
return gulp.src(files.test)
|
gulp.src('src/**/*.js')
|
||||||
.pipe(sourcemaps.init())
|
.pipe(sourcemaps.init())
|
||||||
.pipe(concat('jasmine'))
|
|
||||||
.pipe(babel({
|
.pipe(babel({
|
||||||
loose: 'all',
|
loose: 'all',
|
||||||
optional: ['es7.asyncFunctions'],
|
|
||||||
modules: 'ignore',
|
modules: 'ignore',
|
||||||
|
// optional: ['es7.asyncFunctions'],
|
||||||
|
blacklist: 'regenerator',
|
||||||
experimental: true
|
experimental: true
|
||||||
}))
|
}))
|
||||||
.pipe(uglify())
|
.pipe(sourcemaps.write())
|
||||||
.pipe(sourcemaps.write('.'))
|
|
||||||
.pipe(gulp.dest('build'))
|
.pipe(gulp.dest('build'))
|
||||||
.pipe(ignore.include('*.js'))
|
|
||||||
.pipe(jasmine({
|
|
||||||
verbose: true,
|
|
||||||
includeStuckTrace: true
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
gulp.task('build_jasmine_browser', function () {
|
gulp.task('build_jasmine_browser', function () {
|
||||||
@ -134,16 +128,40 @@ gulp.task('build_jasmine_browser', function () {
|
|||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
.pipe(gulp.dest('build'))
|
.pipe(gulp.dest('build'))
|
||||||
})
|
})
|
||||||
|
var testy = [
|
||||||
gulp.task('develop', ['build_jasmine_browser'], function () {
|
"build/Helper.spec.js",
|
||||||
gulp.watch(files.test, ['build_jasmine_browser'])
|
"build/y.js",
|
||||||
|
"build/Connector.js",
|
||||||
|
"build/OperationStore.js",
|
||||||
|
"build/Struct.js",
|
||||||
|
"build/Utils.js",
|
||||||
|
"build/OperationStores/RedBlackTree.js",
|
||||||
|
"build/OperationStores/Memory.js",
|
||||||
|
"build/OperationStores/IndexedDB.js",
|
||||||
|
"build/Connectors/Test.js",
|
||||||
|
"build/Connectors/WebRTC.js",
|
||||||
|
"build/Types/Array.js",
|
||||||
|
"build/Types/Map.js",
|
||||||
|
"build/Types/TextBind.js",
|
||||||
|
"build/**/*.spec.js"
|
||||||
|
]
|
||||||
|
gulp.task('develop', ['testbuild'], function () {
|
||||||
|
//gulp.watch(files.test, ['build_jasmine_browser'])
|
||||||
// gulp.watch(files.test, ["test"])
|
// gulp.watch(files.test, ["test"])
|
||||||
gulp.watch(files.test, ['build'])
|
gulp.watch('src/**/*.js', ['testbuild'])
|
||||||
|
|
||||||
return gulp.src('build/jasmine_browser.js')
|
return gulp.src(testy)
|
||||||
.pipe(watch('build/jasmine_browser.js'))
|
.pipe(watch('build/**/*.js'))
|
||||||
.pipe(jasmineBrowser.specRunner())
|
.pipe(jasmineBrowser.specRunner())
|
||||||
.pipe(jasmineBrowser.server({port: options.testport}))
|
.pipe(jasmineBrowser.server({port: options.testport}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
gulp.task('test', ['testbuild'], function () {
|
||||||
|
return gulp.src(testy)
|
||||||
|
.pipe(jasmine({
|
||||||
|
verbose: true,
|
||||||
|
includeStuckTrace: true
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
gulp.task('default', ['build', 'test'])
|
gulp.task('default', ['build', 'test'])
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
"gulp": "^3.9.0",
|
"gulp": "^3.9.0",
|
||||||
"gulp-babel": "^5.1.0",
|
"gulp-babel": "^5.1.0",
|
||||||
"gulp-concat": "^2.5.2",
|
"gulp-concat": "^2.5.2",
|
||||||
|
"gulp-ignore": "^1.2.1",
|
||||||
"gulp-jasmine": "^2.0.1",
|
"gulp-jasmine": "^2.0.1",
|
||||||
"gulp-jasmine-browser": "^0.1.3",
|
"gulp-jasmine-browser": "^0.1.3",
|
||||||
"gulp-sourcemaps": "^1.5.2",
|
"gulp-sourcemaps": "^1.5.2",
|
||||||
|
10
q.js
10
q.js
@ -1,4 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
class YY {
|
|
||||||
|
var x = new Promise(function(r){r(true)})
|
||||||
|
|
||||||
|
x.then(function(q){console.log("yay",q)})
|
||||||
|
|
||||||
|
var ff = function * (){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("dtrn")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"spec_dir": "src",
|
"spec_dir": "build",
|
||||||
"spec_files": [
|
"spec_files": [
|
||||||
"**/**.spec.js"
|
"**/**.spec.js"
|
||||||
],
|
],
|
||||||
@ -11,6 +11,12 @@
|
|||||||
"Struct.js",
|
"Struct.js",
|
||||||
"Utils.js",
|
"Utils.js",
|
||||||
"OperationStores/RedBlackTree.js",
|
"OperationStores/RedBlackTree.js",
|
||||||
"OperationStores/Memory.js"
|
"OperationStores/Memory.js",
|
||||||
|
"OperationStores/IndexedDB.js",
|
||||||
|
"Connectors/Test.js",
|
||||||
|
"Connectors/WebRTC.js",
|
||||||
|
"Types/Array.js",
|
||||||
|
"Types/Map.js",
|
||||||
|
"Types/TextBind.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* globals Y */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
class AbstractConnector { // eslint-disable-line no-unused-vars
|
class AbstractConnector { // eslint-disable-line no-unused-vars
|
||||||
@ -297,3 +298,4 @@ class AbstractConnector { // eslint-disable-line no-unused-vars
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Y.AbstractConnector = AbstractConnector
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* global getRandom, AbstractConnector, Y, wait */
|
/* global getRandom, Y, wait */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
var globalRoom = {
|
var globalRoom = {
|
||||||
@ -23,6 +23,8 @@ var globalRoom = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Y.utils.globalRoom = globalRoom
|
||||||
|
|
||||||
function flushOne () {
|
function flushOne () {
|
||||||
var bufs = []
|
var bufs = []
|
||||||
for (var i in globalRoom.buffers) {
|
for (var i in globalRoom.buffers) {
|
||||||
@ -45,7 +47,7 @@ function flushOne () {
|
|||||||
|
|
||||||
var userIdCounter = 0
|
var userIdCounter = 0
|
||||||
|
|
||||||
class Test extends AbstractConnector {
|
class Test extends Y.AbstractConnector {
|
||||||
constructor (y, options) {
|
constructor (y, options) {
|
||||||
if (options === undefined) {
|
if (options === undefined) {
|
||||||
throw new Error('Options must not be undefined!')
|
throw new Error('Options must not be undefined!')
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* global AbstractConnector, Y */
|
/* global Y */
|
||||||
|
'use strict'
|
||||||
|
|
||||||
class WebRTC extends AbstractConnector {
|
class WebRTC extends Y.AbstractConnector {
|
||||||
constructor (y, options) {
|
constructor (y, options) {
|
||||||
if (options === undefined) {
|
if (options === undefined) {
|
||||||
throw new Error('Options must not be undefined!')
|
throw new Error('Options must not be undefined!')
|
||||||
|
@ -5,11 +5,18 @@
|
|||||||
This is just a compilation of functions that help to test this library!
|
This is just a compilation of functions that help to test this library!
|
||||||
***/
|
***/
|
||||||
|
|
||||||
var g = global || window
|
var g
|
||||||
|
if (typeof global !== 'undefined') {
|
||||||
|
g = global
|
||||||
|
} else if (typeof window !== 'undefined') {
|
||||||
|
g = window
|
||||||
|
} else {
|
||||||
|
throw new Error('No global object?')
|
||||||
|
}
|
||||||
g.g = g
|
g.g = g
|
||||||
|
|
||||||
var co = require('co')
|
//var co = require('co')
|
||||||
g.co = co
|
// g.co = co
|
||||||
|
|
||||||
function wait (t) {
|
function wait (t) {
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
@ -46,7 +53,7 @@ function getRandomNumber(n) {//eslint-disable-line
|
|||||||
}
|
}
|
||||||
g.getRandomNumber = getRandomNumber
|
g.getRandomNumber = getRandomNumber
|
||||||
|
|
||||||
g.applyRandomTransactions = co.wrap(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) { //eslint-disable-line
|
g.applyRandomTransactions = async(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) { //eslint-disable-line
|
||||||
function randomTransaction (root) {
|
function randomTransaction (root) {
|
||||||
var f = getRandom(transactions)
|
var f = getRandom(transactions)
|
||||||
f(root)
|
f(root)
|
||||||
@ -74,21 +81,21 @@ g.applyRandomTransactions = co.wrap(function * applyRandomTransactions (users, o
|
|||||||
yield users[0].connector.flushAll()
|
yield users[0].connector.flushAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
g.garbageCollectAllUsers = co.wrap(function * garbageCollectAllUsers (users) {
|
g.garbageCollectAllUsers = async(function * garbageCollectAllUsers (users) {
|
||||||
for (var i in users) {
|
for (var i in users) {
|
||||||
yield users[i].db.garbageCollect()
|
yield users[i].db.garbageCollect()
|
||||||
yield users[i].db.garbageCollect()
|
yield users[i].db.garbageCollect()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
g.compareAllUsers = co.wrap(function * compareAllUsers (users) { //eslint-disable-line
|
g.compareAllUsers = async(function * compareAllUsers (users) { //eslint-disable-line
|
||||||
var s1, s2, ds1, ds2, allDels1, allDels2
|
var s1, s2, ds1, ds2, allDels1, allDels2
|
||||||
var db1 = []
|
var db1 = []
|
||||||
function * t1 () {
|
function * t1 () {
|
||||||
s1 = yield* this.getStateSet()
|
s1 = yield* this.getStateSet()
|
||||||
ds1 = yield* this.getDeleteSet()
|
ds1 = yield* this.getDeleteSet()
|
||||||
allDels1 = []
|
allDels1 = []
|
||||||
yield* this.ds.iterate(null, null, function (d) {
|
this.ds.iterate(null, null, function (d) {
|
||||||
allDels1.push(d)
|
allDels1.push(d)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -96,7 +103,7 @@ g.compareAllUsers = co.wrap(function * compareAllUsers (users) { //eslint-disabl
|
|||||||
s2 = yield* this.getStateSet()
|
s2 = yield* this.getStateSet()
|
||||||
ds2 = yield* this.getDeleteSet()
|
ds2 = yield* this.getDeleteSet()
|
||||||
allDels2 = []
|
allDels2 = []
|
||||||
yield* this.ds.iterate(null, null, function (d) {
|
this.ds.iterate(null, null, function (d) {
|
||||||
allDels2.push(d)
|
allDels2.push(d)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -150,13 +157,13 @@ g.compareAllUsers = co.wrap(function * compareAllUsers (users) { //eslint-disabl
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
g.createUsers = co.wrap(function * createUsers (self, numberOfUsers) { //eslint-disable-line
|
g.createUsers = async(function * createUsers (self, numberOfUsers) { //eslint-disable-line
|
||||||
if (globalRoom.users[0] != null) {//eslint-disable-line
|
if (Y.utils.globalRoom.users[0] != null) {//eslint-disable-line
|
||||||
yield globalRoom.users[0].flushAll()//eslint-disable-line
|
yield Y.utils.globalRoom.users[0].flushAll()//eslint-disable-line
|
||||||
}
|
}
|
||||||
// destroy old users
|
// destroy old users
|
||||||
for (var u in globalRoom.users) {//eslint-disable-line
|
for (var u in Y.utils.globalRoom.users) {//eslint-disable-line
|
||||||
globalRoom.users[u].y.destroy()//eslint-disable-line
|
Y.utils.globalRoom.users[u].y.destroy()//eslint-disable-line
|
||||||
}
|
}
|
||||||
self.users = []
|
self.users = []
|
||||||
|
|
||||||
@ -175,3 +182,35 @@ g.createUsers = co.wrap(function * createUsers (self, numberOfUsers) { //eslint-
|
|||||||
}
|
}
|
||||||
self.users = yield Promise.all(promises)
|
self.users = yield Promise.all(promises)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function async (makeGenerator) {
|
||||||
|
return function (arg) {
|
||||||
|
var generator = makeGenerator.apply(this, arguments)
|
||||||
|
|
||||||
|
function handle (result) {
|
||||||
|
// result => { done: [Boolean], value: [Object] }
|
||||||
|
if (result.done) return Promise.resolve(result.value)
|
||||||
|
|
||||||
|
return Promise.resolve(result.value).then(function (res) {
|
||||||
|
return handle(generator.next(res))
|
||||||
|
}, function (err) {
|
||||||
|
debugger
|
||||||
|
return handle(generator.throw(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return handle(generator.next())
|
||||||
|
} catch (ex) {
|
||||||
|
return Promise.reject(ex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.wrapCo = async
|
||||||
|
|
||||||
|
/*function wrapCo (gen) {
|
||||||
|
return function (done) {
|
||||||
|
return co.wrap(gen)(done)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.wrapCo = wrapCo*/
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
var RBTree = Y.RBTree
|
|
||||||
var Struct = Y.Struct
|
|
||||||
var copyObject = Y.copyObject
|
|
||||||
|
|
||||||
class AbstractTransaction { // eslint-disable-line no-unused-vars
|
class AbstractTransaction { // eslint-disable-line no-unused-vars
|
||||||
constructor (store) {
|
constructor (store) {
|
||||||
this.store = store
|
this.store = store
|
||||||
@ -33,7 +29,7 @@ class AbstractTransaction { // eslint-disable-line no-unused-vars
|
|||||||
for (var i = 0; i < ops.length; i++) {
|
for (var i = 0; i < ops.length; i++) {
|
||||||
var op = ops[i]
|
var op = ops[i]
|
||||||
yield* this.store.tryExecute.call(this, op)
|
yield* this.store.tryExecute.call(this, op)
|
||||||
send.push(copyObject(Struct[op.struct].encode(op)))
|
send.push(Y.utils.copyObject(Y.Struct[op.struct].encode(op)))
|
||||||
}
|
}
|
||||||
if (this.store.y.connector.broadcastedHB) {
|
if (this.store.y.connector.broadcastedHB) {
|
||||||
this.store.y.connector.broadcast({
|
this.store.y.connector.broadcast({
|
||||||
@ -68,7 +64,7 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
|
|||||||
// wont be kept in memory.
|
// wont be kept in memory.
|
||||||
this.initializedTypes = {}
|
this.initializedTypes = {}
|
||||||
this.whenUserIdSetListener = null
|
this.whenUserIdSetListener = null
|
||||||
this.waitingOperations = new RBTree()
|
this.waitingOperations = new Y.utils.RBTree()
|
||||||
|
|
||||||
this.gc1 = [] // first stage
|
this.gc1 = [] // first stage
|
||||||
this.gc2 = [] // second stage -> after that, kill it
|
this.gc2 = [] // second stage -> after that, kill it
|
||||||
@ -136,7 +132,7 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
|
|||||||
for (var key in ops) {
|
for (var key in ops) {
|
||||||
var o = ops[key]
|
var o = ops[key]
|
||||||
if (!o.gc) {
|
if (!o.gc) {
|
||||||
var required = Struct[o.struct].requiredOps(o)
|
var required = Y.Struct[o.struct].requiredOps(o)
|
||||||
this.whenOperationsExist(required, o)
|
this.whenOperationsExist(required, o)
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Must not receive gc'd ops!")
|
throw new Error("Must not receive gc'd ops!")
|
||||||
@ -208,7 +204,7 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
|
|||||||
}
|
}
|
||||||
* tryExecute (op) {
|
* tryExecute (op) {
|
||||||
if (op.struct === 'Delete') {
|
if (op.struct === 'Delete') {
|
||||||
yield* Struct.Delete.execute.call(this, op)
|
yield* Y.Struct.Delete.execute.call(this, op)
|
||||||
} else {
|
} else {
|
||||||
while (op != null) {
|
while (op != null) {
|
||||||
var state = yield* this.getState(op.id[0])
|
var state = yield* this.getState(op.id[0])
|
||||||
@ -216,14 +212,14 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
|
|||||||
state.clock++
|
state.clock++
|
||||||
yield* this.checkDeleteStoreForState(state)
|
yield* this.checkDeleteStoreForState(state)
|
||||||
yield* this.setState(state)
|
yield* this.setState(state)
|
||||||
var isDeleted = yield* this.store.ds.isDeleted(op.id)
|
var isDeleted = this.store.ds.isDeleted(op.id)
|
||||||
|
|
||||||
yield* Struct[op.struct].execute.call(this, op)
|
yield* Y.Struct[op.struct].execute.call(this, op)
|
||||||
yield* this.addOperation(op)
|
yield* this.addOperation(op)
|
||||||
yield* this.store.operationAdded(this, op)
|
yield* this.store.operationAdded(this, op)
|
||||||
|
|
||||||
if (isDeleted) {
|
if (isDeleted) {
|
||||||
yield* Struct['Delete'].execute.call(this, {target: op.id})
|
yield* Y.Struct['Delete'].execute.call(this, {struct: 'Delete', target: op.id})
|
||||||
}
|
}
|
||||||
|
|
||||||
// find next operation to execute
|
// find next operation to execute
|
||||||
@ -259,7 +255,7 @@ class AbstractOperationStore { // eslint-disable-line no-unused-vars
|
|||||||
// notify parent, if it has been initialized as a custom type
|
// notify parent, if it has been initialized as a custom type
|
||||||
var t = this.initializedTypes[JSON.stringify(op.parent)]
|
var t = this.initializedTypes[JSON.stringify(op.parent)]
|
||||||
if (t != null && !op.deleted) {
|
if (t != null && !op.deleted) {
|
||||||
yield* t._changed(transaction, copyObject(op))
|
yield* t._changed(transaction, Y.utils.copyObject(op))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeParentListener (id, f) {
|
removeParentListener (id, f) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
Y.IndexedDB = (function () { // eslint-disable-line
|
Y.IndexedDB = (function () { // eslint-disable-line
|
||||||
class Transaction extends AbstractTransaction { // eslint-disable-line
|
class Transaction extends Y.AbstractTransaction { // eslint-disable-line
|
||||||
constructor (store) {
|
constructor (store) {
|
||||||
super(store)
|
super(store)
|
||||||
this.transaction = store.db.transaction(['OperationStore', 'StateVector'], 'readwrite')
|
this.transaction = store.db.transaction(['OperationStore', 'StateVector'], 'readwrite')
|
||||||
@ -79,7 +81,7 @@ Y.IndexedDB = (function () { // eslint-disable-line
|
|||||||
return ops
|
return ops
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class OperationStore extends AbstractOperationStore { // eslint-disable-line no-undef
|
class OperationStore extends Y.AbstractOperationStore { // eslint-disable-line no-undef
|
||||||
constructor (y, opts) {
|
constructor (y, opts) {
|
||||||
super(y, opts)
|
super(y, opts)
|
||||||
if (opts == null) {
|
if (opts == null) {
|
||||||
@ -162,7 +164,6 @@ Y.IndexedDB = (function () { // eslint-disable-line
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleTransactions(tGen.next())
|
handleTransactions(tGen.next())
|
||||||
|
|
||||||
}
|
}
|
||||||
requestTransaction (makeGen) {
|
requestTransaction (makeGen) {
|
||||||
this.transactionQueue.queue.push(makeGen)
|
this.transactionQueue.queue.push(makeGen)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
/* eslint-env browser,jasmine */
|
/* eslint-env browser,jasmine */
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined' && false) {
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000
|
||||||
describe('IndexedDB', function () {
|
describe('IndexedDB', function () {
|
||||||
var ob
|
var ob
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* global Struct, RBTree, Y, compareIds */
|
/* global Y */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
function copyObject (o) {
|
function copyObject (o) {
|
||||||
@ -8,8 +8,9 @@ function copyObject (o) {
|
|||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
Y.utils.copyObject = copyObject
|
||||||
|
|
||||||
class DeleteStore extends Y.RBTree {
|
class DeleteStore extends Y.utils.RBTree {
|
||||||
constructor () {
|
constructor () {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
@ -36,7 +37,7 @@ class DeleteStore extends Y.RBTree {
|
|||||||
}
|
}
|
||||||
// can extend right?
|
// can extend right?
|
||||||
var next = n.next()
|
var next = n.next()
|
||||||
if (next !== null && compareIds([n.val.id[0], n.val.id[1] + n.val.len], next.val.id)) {
|
if (next !== null && Y.utils.compareIds([n.val.id[0], n.val.id[1] + n.val.len], next.val.id)) {
|
||||||
n.val.len = n.val.len + next.val.len
|
n.val.len = n.val.len + next.val.len
|
||||||
super.delete(next.val.id)
|
super.delete(next.val.id)
|
||||||
}
|
}
|
||||||
@ -117,7 +118,7 @@ class DeleteStore extends Y.RBTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Y.DeleteStore = DeleteStore
|
Y.utils.DeleteStore = DeleteStore
|
||||||
|
|
||||||
Y.Memory = (function () { // eslint-disable-line no-unused-vars
|
Y.Memory = (function () { // eslint-disable-line no-unused-vars
|
||||||
class Transaction extends Y.AbstractTransaction { // eslint-disable-line
|
class Transaction extends Y.AbstractTransaction { // eslint-disable-line
|
||||||
@ -206,7 +207,7 @@ Y.Memory = (function () { // eslint-disable-line no-unused-vars
|
|||||||
|
|
||||||
this.os.iterate([user, startPos], [user, endPos], function (op) {// eslint-disable-line
|
this.os.iterate([user, startPos], [user, endPos], function (op) {// eslint-disable-line
|
||||||
if (!op.gc) {
|
if (!op.gc) {
|
||||||
ops.push(Struct[op.struct].encode(op))
|
ops.push(Y.Struct[op.struct].encode(op))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -251,7 +252,7 @@ Y.Memory = (function () { // eslint-disable-line no-unused-vars
|
|||||||
class OperationStore extends Y.AbstractOperationStore { // eslint-disable-line no-undef
|
class OperationStore extends Y.AbstractOperationStore { // eslint-disable-line no-undef
|
||||||
constructor (y, opts) {
|
constructor (y, opts) {
|
||||||
super(y, opts)
|
super(y, opts)
|
||||||
this.os = new RBTree()
|
this.os = new Y.utils.RBTree()
|
||||||
this.ss = {}
|
this.ss = {}
|
||||||
this.waitingTransactions = []
|
this.waitingTransactions = []
|
||||||
this.transactionInProgress = false
|
this.transactionInProgress = false
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
/* eslint-env browser,jasmine,console */
|
/* eslint-env browser,jasmine,console */
|
||||||
|
|
||||||
var DeleteStore = Y.DeleteStore
|
|
||||||
|
|
||||||
describe('Memory', function () {
|
describe('Memory', function () {
|
||||||
describe('DeleteStore', function () {
|
describe('DeleteStore', function () {
|
||||||
var ds
|
var ds
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
ds = new DeleteStore()
|
ds = new Y.utils.DeleteStore()
|
||||||
})
|
})
|
||||||
it('Deleted operation is deleted', function () {
|
it('Deleted operation is deleted', function () {
|
||||||
ds.delete(['u1', 10])
|
ds.delete(['u1', 10])
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
/* global Y, copyObject */
|
/* global Y */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
var compareIds = Y.compareIds
|
|
||||||
|
|
||||||
function smaller (a, b) {
|
function smaller (a, b) {
|
||||||
return a[0] < b[0] || (a[0] === b[0] && a[1] < b[1])
|
return a[0] < b[0] || (a[0] === b[0] && a[1] < b[1])
|
||||||
}
|
}
|
||||||
|
Y.utils.smaller = smaller
|
||||||
|
|
||||||
class N {
|
class N {
|
||||||
// A created node is always red!
|
// A created node is always red!
|
||||||
@ -190,7 +189,7 @@ class RBTree { // eslint-disable-line no-unused-vars
|
|||||||
}
|
}
|
||||||
iterate (from, to, f) {
|
iterate (from, to, f) {
|
||||||
var o = this.findNodeWithLowerBound(from)
|
var o = this.findNodeWithLowerBound(from)
|
||||||
while (o !== null && (to === null || smaller(o.val.id, to) || compareIds(o.val.id, to))) {
|
while (o !== null && (to === null || smaller(o.val.id, to) || Y.utils.compareIds(o.val.id, to))) {
|
||||||
f(o.val)
|
f(o.val)
|
||||||
o = o.next()
|
o = o.next()
|
||||||
}
|
}
|
||||||
@ -201,7 +200,7 @@ class RBTree { // eslint-disable-line no-unused-vars
|
|||||||
if (to == null) { to = null }
|
if (to == null) { to = null }
|
||||||
var os = []
|
var os = []
|
||||||
this.iterate(from, to, function (o) {
|
this.iterate(from, to, function (o) {
|
||||||
var o_ = copyObject(o)
|
var o_ = Y.utils.copyObject(o)
|
||||||
var id = o_.id
|
var id = o_.id
|
||||||
delete o_.id
|
delete o_.id
|
||||||
o_['id[0]'] = id[0]
|
o_['id[0]'] = id[0]
|
||||||
@ -460,4 +459,4 @@ class RBTree { // eslint-disable-line no-unused-vars
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Y.RBTree = RBTree
|
Y.utils.RBTree = RBTree
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
/* eslint-env browser,jasmine,console */
|
/* eslint-env browser,jasmine,console */
|
||||||
|
|
||||||
var RBTree = Y.RBTree
|
|
||||||
var compareIds = Y.compareIds
|
|
||||||
var smaller = Y.smaller
|
|
||||||
var numberOfRBTreeTests = 1000
|
var numberOfRBTreeTests = 1000
|
||||||
|
|
||||||
function itRedNodesDoNotHaveBlackChildren (tree) {
|
function itRedNodesDoNotHaveBlackChildren (tree) {
|
||||||
@ -54,7 +51,7 @@ function itRootNodeIsBlack (tree) {
|
|||||||
|
|
||||||
describe('RedBlack Tree', function () {
|
describe('RedBlack Tree', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.tree = new RBTree()
|
this.tree = new Y.utils.RBTree()
|
||||||
})
|
})
|
||||||
it('can add&retrieve 5 elements', function () {
|
it('can add&retrieve 5 elements', function () {
|
||||||
this.tree.add({val: 'four', id: [4]})
|
this.tree.add({val: 'four', id: [4]})
|
||||||
@ -97,7 +94,7 @@ describe('RedBlack Tree', function () {
|
|||||||
expect(this.tree.find([2])).toBeUndefined()
|
expect(this.tree.find([2])).toBeUndefined()
|
||||||
})
|
})
|
||||||
describe('debug #2', function () {
|
describe('debug #2', function () {
|
||||||
var tree = new RBTree()
|
var tree = new Y.utils.RBTree()
|
||||||
tree.add({id: [8433]})
|
tree.add({id: [8433]})
|
||||||
tree.add({id: [12844]})
|
tree.add({id: [12844]})
|
||||||
tree.add({id: [1795]})
|
tree.add({id: [1795]})
|
||||||
@ -114,17 +111,19 @@ describe('RedBlack Tree', function () {
|
|||||||
|
|
||||||
describe(`After adding&deleting (0.8/0.2) ${numberOfRBTreeTests} times`, function () {
|
describe(`After adding&deleting (0.8/0.2) ${numberOfRBTreeTests} times`, function () {
|
||||||
var elements = []
|
var elements = []
|
||||||
var tree = new RBTree()
|
var tree = new Y.utils.RBTree()
|
||||||
for (var i = 0; i < numberOfRBTreeTests; i++) {
|
for (var i = 0; i < numberOfRBTreeTests; i++) {
|
||||||
var r = Math.random()
|
var r = Math.random()
|
||||||
if (r < 0.8) {
|
if (r < 0.8) {
|
||||||
var obj = [Math.floor(Math.random() * numberOfRBTreeTests * 10000)]
|
var obj = [Math.floor(Math.random() * numberOfRBTreeTests * 10000)]
|
||||||
|
if (!tree.findNode(obj)) {
|
||||||
elements.push(obj)
|
elements.push(obj)
|
||||||
tree.add({id: obj})
|
tree.add({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)
|
||||||
var elem = elements[elemid]
|
var elem = elements[elemid]
|
||||||
elements = elements.filter(function (e) {return !compareIds(e, elem); }); // eslint-disable-line
|
elements = elements.filter(function (e) {return !Y.utils.compareIds(e, elem); }); // eslint-disable-line
|
||||||
tree.delete(elem)
|
tree.delete(elem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +147,7 @@ describe('RedBlack Tree', function () {
|
|||||||
it('iterating over a tree with lower bound yields the right amount of results', function () {
|
it('iterating over a tree with lower bound yields the right amount of results', function () {
|
||||||
var lowerBound = elements[Math.floor(Math.random() * elements.length)]
|
var lowerBound = elements[Math.floor(Math.random() * elements.length)]
|
||||||
var expectedResults = elements.filter(function (e, pos) {
|
var expectedResults = elements.filter(function (e, pos) {
|
||||||
return (smaller(lowerBound, e) || compareIds(e, lowerBound)) && elements.indexOf(e) === pos
|
return (Y.utils.smaller(lowerBound, e) || Y.utils.compareIds(e, lowerBound)) && elements.indexOf(e) === pos
|
||||||
}).length
|
}).length
|
||||||
|
|
||||||
var actualResults = 0
|
var actualResults = 0
|
||||||
@ -175,7 +174,7 @@ describe('RedBlack Tree', function () {
|
|||||||
it('iterating over a tree with upper bound yields the right amount of results', function () {
|
it('iterating over a tree with upper bound yields the right amount of results', function () {
|
||||||
var upperBound = elements[Math.floor(Math.random() * elements.length)]
|
var upperBound = elements[Math.floor(Math.random() * elements.length)]
|
||||||
var expectedResults = elements.filter(function (e, pos) {
|
var expectedResults = elements.filter(function (e, pos) {
|
||||||
return (smaller(e, upperBound) || compareIds(e, upperBound)) && elements.indexOf(e) === pos
|
return (Y.utils.smaller(e, upperBound) || Y.utils.compareIds(e, upperBound)) && elements.indexOf(e) === pos
|
||||||
}).length
|
}).length
|
||||||
|
|
||||||
var actualResults = 0
|
var actualResults = 0
|
||||||
@ -190,7 +189,7 @@ describe('RedBlack Tree', function () {
|
|||||||
var b1 = elements[Math.floor(Math.random() * elements.length)]
|
var b1 = elements[Math.floor(Math.random() * elements.length)]
|
||||||
var b2 = elements[Math.floor(Math.random() * elements.length)]
|
var b2 = elements[Math.floor(Math.random() * elements.length)]
|
||||||
var upperBound, lowerBound
|
var upperBound, lowerBound
|
||||||
if (smaller(b1, b2)) {
|
if (Y.utils.smaller(b1, b2)) {
|
||||||
lowerBound = b1
|
lowerBound = b1
|
||||||
upperBound = b2
|
upperBound = b2
|
||||||
} else {
|
} else {
|
||||||
@ -198,8 +197,8 @@ describe('RedBlack Tree', function () {
|
|||||||
upperBound = b1
|
upperBound = b1
|
||||||
}
|
}
|
||||||
var expectedResults = elements.filter(function (e, pos) {
|
var expectedResults = elements.filter(function (e, pos) {
|
||||||
return (smaller(lowerBound, e) || compareIds(e, lowerBound)) &&
|
return (Y.utils.smaller(lowerBound, e) || Y.utils.compareIds(e, lowerBound)) &&
|
||||||
(smaller(e, upperBound) || compareIds(e, upperBound)) && elements.indexOf(e) === pos
|
(Y.utils.smaller(e, upperBound) || Y.utils.compareIds(e, upperBound)) && elements.indexOf(e) === pos
|
||||||
}).length
|
}).length
|
||||||
var actualResults = 0
|
var actualResults = 0
|
||||||
tree.iterate(lowerBound, upperBound, function (val) {
|
tree.iterate(lowerBound, upperBound, function (val) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
var copyObject = Y.copyObject
|
|
||||||
|
|
||||||
function compareIds (id1, id2) {
|
function compareIds (id1, id2) {
|
||||||
if (id1 == null || id2 == null) {
|
if (id1 == null || id2 == null) {
|
||||||
if (id1 == null && id2 == null) {
|
if (id1 == null && id2 == null) {
|
||||||
@ -16,7 +14,7 @@ function compareIds (id1, id2) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Y.compareIds = compareIds
|
Y.utils.compareIds = compareIds
|
||||||
|
|
||||||
var Struct = {
|
var Struct = {
|
||||||
/* This Operations does _not_ have an id!
|
/* This Operations does _not_ have an id!
|
||||||
@ -51,7 +49,7 @@ var Struct = {
|
|||||||
yield* this.setOperation(target)
|
yield* this.setOperation(target)
|
||||||
var t = this.store.initializedTypes[JSON.stringify(target.parent)]
|
var t = this.store.initializedTypes[JSON.stringify(target.parent)]
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
yield* t._changed(this, copyObject(op))
|
yield* t._changed(this, Y.utils.copyObject(op))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.ds.delete(op.target)
|
this.ds.delete(op.target)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* global EventHandler, Y, CustomType, Struct */
|
/* global Y */
|
||||||
|
'use strict'
|
||||||
|
|
||||||
;(function () {
|
;(function () {
|
||||||
class YArray {
|
class YArray {
|
||||||
@ -9,7 +10,7 @@
|
|||||||
this.idArray = idArray
|
this.idArray = idArray
|
||||||
// Array of all the values
|
// Array of all the values
|
||||||
this.valArray = valArray
|
this.valArray = valArray
|
||||||
this.eventHandler = new EventHandler(ops => {
|
this.eventHandler = new Y.utils.EventHandler(ops => {
|
||||||
var userEvents = []
|
var userEvents = []
|
||||||
for (var i in ops) {
|
for (var i in ops) {
|
||||||
var op = ops[i]
|
var op = ops[i]
|
||||||
@ -112,7 +113,8 @@
|
|||||||
eventHandler.awaitedLastInserts(ops.length)
|
eventHandler.awaitedLastInserts(ops.length)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
delete (pos, length = 1) {
|
delete (pos, length) {
|
||||||
|
if (length == null) { length = 1 }
|
||||||
if (typeof length !== 'number') {
|
if (typeof length !== 'number') {
|
||||||
throw new Error('pos must be a number!')
|
throw new Error('pos must be a number!')
|
||||||
}
|
}
|
||||||
@ -162,7 +164,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Y.Array = new CustomType({
|
Y.Array = new Y.utils.CustomType({
|
||||||
class: YArray,
|
class: YArray,
|
||||||
createType: function * YArrayCreator () {
|
createType: function * YArrayCreator () {
|
||||||
var model = {
|
var model = {
|
||||||
@ -177,7 +179,7 @@
|
|||||||
},
|
},
|
||||||
initType: function * YArrayInitializer (os, model) {
|
initType: function * YArrayInitializer (os, model) {
|
||||||
var valArray = []
|
var valArray = []
|
||||||
var idArray = yield* Struct.List.map.call(this, model, function (c) {
|
var idArray = yield* Y.Struct.List.map.call(this, model, function (c) {
|
||||||
valArray.push(c.content)
|
valArray.push(c.content)
|
||||||
return JSON.stringify(c.id)
|
return JSON.stringify(c.id)
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* global createUsers, wait, Y, compareAllUsers, getRandomNumber, applyRandomTransactions, co, garbageCollectAllUsers */
|
/* global createUsers, wait, Y, compareAllUsers, getRandomNumber, applyRandomTransactions, wrapCo, garbageCollectAllUsers */
|
||||||
/* eslint-env browser,jasmine */
|
/* eslint-env browser,jasmine */
|
||||||
|
|
||||||
var numberOfYArrayTests = 5
|
var numberOfYArrayTests = 5
|
||||||
@ -7,28 +7,30 @@ describe('Array Type', function () {
|
|||||||
var y1, y2, y3, yconfig1, yconfig2, yconfig3, flushAll
|
var y1, y2, y3, yconfig1, yconfig2, yconfig3, flushAll
|
||||||
|
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000
|
||||||
beforeEach(co.wrap(function * (done) {
|
beforeEach(wrapCo(function * (done) {
|
||||||
yield createUsers(this, 3)
|
yield createUsers(this, 3)
|
||||||
y1 = (yconfig1 = this.users[0]).root
|
y1 = (yconfig1 = this.users[0]).root
|
||||||
y2 = (yconfig2 = this.users[1]).root
|
y2 = (yconfig2 = this.users[1]).root
|
||||||
y3 = (yconfig3 = this.users[2]).root
|
y3 = (yconfig3 = this.users[2]).root
|
||||||
flushAll = this.users[0].connector.flushAll
|
flushAll = this.users[0].connector.flushAll
|
||||||
|
yield wait(100)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
afterEach(co.wrap(function * (done) {
|
afterEach(wrapCo(function * (done) {
|
||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
describe('Basic tests', function () {
|
describe('Basic tests', function () {
|
||||||
it('insert three elements, try re-get property', co.wrap(function * (done) {
|
it('insert three elements, try re-get property', wrapCo(function * (done) {
|
||||||
|
console.log("blahhhhhhhhhhhhhhhhh ")
|
||||||
var array = yield y1.set('Array', Y.Array)
|
var array = yield y1.set('Array', Y.Array)
|
||||||
array.insert(0, [1, 2, 3])
|
array.insert(0, [1, 2, 3])
|
||||||
array = yield y1.get('Array') // re-get property
|
array = yield y1.get('Array') // re-get property
|
||||||
expect(array.toArray()).toEqual([1, 2, 3])
|
expect(array.toArray()).toEqual([1, 2, 3])
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic insert in array (handle three conflicts)', co.wrap(function * (done) {
|
it('Basic insert in array (handle three conflicts)', wrapCo(function * (done) {
|
||||||
yield y1.set('Array', Y.Array)
|
yield y1.set('Array', Y.Array)
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
var l1 = yield y1.get('Array')
|
var l1 = yield y1.get('Array')
|
||||||
@ -42,7 +44,7 @@ describe('Array Type', function () {
|
|||||||
expect(l2.toArray()).toEqual(l3.toArray())
|
expect(l2.toArray()).toEqual(l3.toArray())
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic insert&delete in array (handle three conflicts)', co.wrap(function * (done) {
|
it('Basic insert&delete in array (handle three conflicts)', wrapCo(function * (done) {
|
||||||
var l1, l2, l3
|
var l1, l2, l3
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y', 'z'])
|
l1.insert(0, ['x', 'y', 'z'])
|
||||||
@ -59,7 +61,7 @@ describe('Array Type', function () {
|
|||||||
expect(l2.toArray()).toEqual([0, 2, 'y'])
|
expect(l2.toArray()).toEqual([0, 2, 'y'])
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Handles getOperations ascending ids bug in late sync', co.wrap(function * (done) {
|
it('Handles getOperations ascending ids bug in late sync', wrapCo(function * (done) {
|
||||||
var l1, l2
|
var l1, l2
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y'])
|
l1.insert(0, ['x', 'y'])
|
||||||
@ -78,7 +80,7 @@ describe('Array Type', function () {
|
|||||||
expect(l1.toArray()).toEqual(l2.toArray())
|
expect(l1.toArray()).toEqual(l2.toArray())
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Handles deletions in late sync', co.wrap(function * (done) {
|
it('Handles deletions in late sync', wrapCo(function * (done) {
|
||||||
var l1, l2
|
var l1, l2
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y'])
|
l1.insert(0, ['x', 'y'])
|
||||||
@ -95,7 +97,7 @@ describe('Array Type', function () {
|
|||||||
expect(l1.toArray()).toEqual(l2.toArray())
|
expect(l1.toArray()).toEqual(l2.toArray())
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Handles deletions in late sync (2)', co.wrap(function * (done) {
|
it('Handles deletions in late sync (2)', wrapCo(function * (done) {
|
||||||
var l1, l2
|
var l1, l2
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
@ -109,7 +111,7 @@ describe('Array Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic insert. Then delete the whole array', co.wrap(function * (done) {
|
it('Basic insert. Then delete the whole array', wrapCo(function * (done) {
|
||||||
var l1, l2, l3
|
var l1, l2, l3
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y', 'z'])
|
l1.insert(0, ['x', 'y', 'z'])
|
||||||
@ -123,7 +125,7 @@ describe('Array Type', function () {
|
|||||||
expect(l2.toArray()).toEqual([])
|
expect(l2.toArray()).toEqual([])
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic insert. Then delete the whole array (merge listeners on late sync)', co.wrap(function * (done) {
|
it('Basic insert. Then delete the whole array (merge listeners on late sync)', wrapCo(function * (done) {
|
||||||
var l1, l2, l3
|
var l1, l2, l3
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y', 'z'])
|
l1.insert(0, ['x', 'y', 'z'])
|
||||||
@ -141,7 +143,7 @@ describe('Array Type', function () {
|
|||||||
expect(l2.toArray()).toEqual([])
|
expect(l2.toArray()).toEqual([])
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic insert. Then delete the whole array (merge deleter on late sync)', co.wrap(function * (done) {
|
it('Basic insert. Then delete the whole array (merge deleter on late sync)', wrapCo(function * (done) {
|
||||||
var l1, l2, l3
|
var l1, l2, l3
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y', 'z'])
|
l1.insert(0, ['x', 'y', 'z'])
|
||||||
@ -159,7 +161,7 @@ describe('Array Type', function () {
|
|||||||
expect(l2.toArray()).toEqual([])
|
expect(l2.toArray()).toEqual([])
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('throw insert & delete events', co.wrap(function * (done) {
|
it('throw insert & delete events', wrapCo(function * (done) {
|
||||||
var array = yield this.users[0].root.set('array', Y.Array)
|
var array = yield this.users[0].root.set('array', Y.Array)
|
||||||
var event
|
var event
|
||||||
array.observe(function (e) {
|
array.observe(function (e) {
|
||||||
@ -182,7 +184,7 @@ describe('Array Type', function () {
|
|||||||
yield wait(50)
|
yield wait(50)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('garbage collects', co.wrap(function * (done) {
|
it('garbage collects', wrapCo(function * (done) {
|
||||||
var l1, l2, l3
|
var l1, l2, l3
|
||||||
l1 = yield y1.set('Array', Y.Array)
|
l1 = yield y1.set('Array', Y.Array)
|
||||||
l1.insert(0, ['x', 'y', 'z'])
|
l1.insert(0, ['x', 'y', 'z'])
|
||||||
@ -227,7 +229,7 @@ describe('Array Type', function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
beforeEach(co.wrap(function * (done) {
|
beforeEach(wrapCo(function * (done) {
|
||||||
yield this.users[0].root.set('Array', Y.Array)
|
yield this.users[0].root.set('Array', Y.Array)
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
|
|
||||||
@ -238,11 +240,11 @@ describe('Array Type', function () {
|
|||||||
this.arrays = yield Promise.all(promises)
|
this.arrays = yield Promise.all(promises)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('arrays.length equals users.length', co.wrap(function * (done) { // eslint-disable-line
|
it('arrays.length equals users.length', wrapCo(function * (done) { // eslint-disable-line
|
||||||
expect(this.arrays.length).toEqual(this.users.length)
|
expect(this.arrays.length).toEqual(this.users.length)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it(`succeed after ${numberOfYArrayTests} actions`, co.wrap(function * (done) {
|
it(`succeed after ${numberOfYArrayTests} actions`, wrapCo(function * (done) {
|
||||||
for (var u of this.users) {
|
for (var u of this.users) {
|
||||||
u.connector.debug = true
|
u.connector.debug = true
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
/* global EventHandler, Y, CustomType, copyObject, compareIds */
|
/* global Y */
|
||||||
|
'use strict'
|
||||||
|
|
||||||
;(function () {
|
;(function () {
|
||||||
class YMap {
|
class YMap {
|
||||||
constructor (os, model) {
|
constructor (os, model) {
|
||||||
this._model = model.id
|
this._model = model.id
|
||||||
this.os = os
|
this.os = os
|
||||||
this.map = copyObject(model.map)
|
this.map = Y.utils.copyObject(model.map)
|
||||||
this.contents = {}
|
this.contents = {}
|
||||||
this.opContents = {}
|
this.opContents = {}
|
||||||
this.eventHandler = new EventHandler(ops => {
|
this.eventHandler = new Y.utils.EventHandler(ops => {
|
||||||
var userEvents = []
|
var userEvents = []
|
||||||
for (var i in ops) {
|
for (var i in ops) {
|
||||||
var op = ops[i]
|
var op = ops[i]
|
||||||
@ -61,7 +62,7 @@
|
|||||||
userEvents.push(insertEvent)
|
userEvents.push(insertEvent)
|
||||||
}
|
}
|
||||||
} else if (op.struct === 'Delete') {
|
} else if (op.struct === 'Delete') {
|
||||||
if (compareIds(this.map[key], op.target)) {
|
if (Y.utils.compareIds(this.map[key], op.target)) {
|
||||||
delete this.opContents[key]
|
delete this.opContents[key]
|
||||||
delete this.contents[key]
|
delete this.contents[key]
|
||||||
var deleteEvent = {
|
var deleteEvent = {
|
||||||
@ -85,7 +86,7 @@
|
|||||||
// if property is a type, return a promise
|
// if property is a type, return a promise
|
||||||
if (this.opContents[key] == null) {
|
if (this.opContents[key] == null) {
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return copyObject(this.contents)
|
return Y.utils.copyObject(this.contents)
|
||||||
} else {
|
} else {
|
||||||
return this.contents[key]
|
return this.contents[key]
|
||||||
}
|
}
|
||||||
@ -106,7 +107,7 @@
|
|||||||
struct: 'Delete'
|
struct: 'Delete'
|
||||||
}
|
}
|
||||||
var eventHandler = this.eventHandler
|
var eventHandler = this.eventHandler
|
||||||
var modDel = copyObject(del)
|
var modDel = Y.utils.copyObject(del)
|
||||||
modDel.key = key
|
modDel.key = key
|
||||||
eventHandler.awaitAndPrematurelyCall([modDel])
|
eventHandler.awaitAndPrematurelyCall([modDel])
|
||||||
this.os.requestTransaction(function *() {
|
this.os.requestTransaction(function *() {
|
||||||
@ -130,7 +131,7 @@
|
|||||||
struct: 'Insert'
|
struct: 'Insert'
|
||||||
}
|
}
|
||||||
var def = Promise.defer()
|
var def = Promise.defer()
|
||||||
if (value instanceof CustomType) {
|
if (value instanceof Y.utils.CustomType) {
|
||||||
// construct a new type
|
// construct a new type
|
||||||
this.os.requestTransaction(function *() {
|
this.os.requestTransaction(function *() {
|
||||||
var type = yield* value.createType.call(this)
|
var type = yield* value.createType.call(this)
|
||||||
@ -208,7 +209,7 @@
|
|||||||
this.eventHandler.receivedOp(op)
|
this.eventHandler.receivedOp(op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Y.Map = new CustomType({
|
Y.Map = new Y.utils.CustomType({
|
||||||
class: YMap,
|
class: YMap,
|
||||||
createType: function * YMapCreator () {
|
createType: function * YMapCreator () {
|
||||||
var model = {
|
var model = {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/* global createUsers, Y, compareAllUsers, getRandomNumber, applyRandomTransactions, co */
|
/* global createUsers, Y, compareAllUsers, getRandomNumber, applyRandomTransactions, wrapCo */
|
||||||
/* eslint-env browser,jasmine */
|
/* eslint-env browser,jasmine */
|
||||||
|
|
||||||
var numberOfYMapTests = 100
|
var numberOfYMapTests = 5
|
||||||
|
|
||||||
describe('Map Type', function () {
|
describe('Map Type', function () {
|
||||||
var y1, y2, y3, y4, flushAll
|
var y1, y2, y3, y4, flushAll
|
||||||
|
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000
|
||||||
beforeEach(co.wrap(function * (done) {
|
beforeEach(wrapCo(function * (done) {
|
||||||
yield createUsers(this, 5)
|
yield createUsers(this, 5)
|
||||||
y1 = this.users[0].root
|
y1 = this.users[0].root
|
||||||
y2 = this.users[1].root
|
y2 = this.users[1].root
|
||||||
@ -16,13 +16,13 @@ describe('Map Type', function () {
|
|||||||
flushAll = this.users[0].connector.flushAll
|
flushAll = this.users[0].connector.flushAll
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
afterEach(co.wrap(function * (done) {
|
afterEach(wrapCo(function * (done) {
|
||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}), 5000)
|
}), 5000)
|
||||||
|
|
||||||
describe('Basic tests', function () {
|
describe('Basic tests', function () {
|
||||||
it('Basic get&set of Map property (converge via sync)', co.wrap(function * (done) {
|
it('Basic get&set of Map property (converge via sync)', wrapCo(function * (done) {
|
||||||
y1.set('stuff', 'stuffy')
|
y1.set('stuff', 'stuffy')
|
||||||
expect(y1.get('stuff')).toEqual('stuffy')
|
expect(y1.get('stuff')).toEqual('stuffy')
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
@ -33,7 +33,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Map can set custom types (Map)', co.wrap(function * (done) {
|
it('Map can set custom types (Map)', wrapCo(function * (done) {
|
||||||
var map = yield y1.set('Map', Y.Map)
|
var map = yield y1.set('Map', Y.Map)
|
||||||
map.set('one', 1)
|
map.set('one', 1)
|
||||||
map = yield y1.get('Map')
|
map = yield y1.get('Map')
|
||||||
@ -41,7 +41,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Map can set custom types (Array)', co.wrap(function * (done) {
|
it('Map can set custom types (Array)', wrapCo(function * (done) {
|
||||||
var array = yield y1.set('Array', Y.Array)
|
var array = yield y1.set('Array', Y.Array)
|
||||||
array.insert(0, [1, 2, 3])
|
array.insert(0, [1, 2, 3])
|
||||||
array = yield y1.get('Array')
|
array = yield y1.get('Array')
|
||||||
@ -49,7 +49,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic get&set of Map property (converge via update)', co.wrap(function * (done) {
|
it('Basic get&set of Map property (converge via update)', wrapCo(function * (done) {
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
y1.set('stuff', 'stuffy')
|
y1.set('stuff', 'stuffy')
|
||||||
expect(y1.get('stuff')).toEqual('stuffy')
|
expect(y1.get('stuff')).toEqual('stuffy')
|
||||||
@ -61,7 +61,7 @@ describe('Map Type', function () {
|
|||||||
}
|
}
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic get&set of Map property (handle conflict)', co.wrap(function * (done) {
|
it('Basic get&set of Map property (handle conflict)', wrapCo(function * (done) {
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
y1.set('stuff', 'c0')
|
y1.set('stuff', 'c0')
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic get&set&delete of Map property (handle conflict)', co.wrap(function * (done) {
|
it('Basic get&set&delete of Map property (handle conflict)', wrapCo(function * (done) {
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
y1.set('stuff', 'c0')
|
y1.set('stuff', 'c0')
|
||||||
y1.delete('stuff')
|
y1.delete('stuff')
|
||||||
@ -89,7 +89,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic get&set of Map property (handle three conflicts)', co.wrap(function * (done) {
|
it('Basic get&set of Map property (handle three conflicts)', wrapCo(function * (done) {
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
y1.set('stuff', 'c0')
|
y1.set('stuff', 'c0')
|
||||||
y2.set('stuff', 'c1')
|
y2.set('stuff', 'c1')
|
||||||
@ -104,7 +104,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('Basic get&set&delete of Map property (handle three conflicts)', co.wrap(function * (done) {
|
it('Basic get&set&delete of Map property (handle three conflicts)', wrapCo(function * (done) {
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
y1.set('stuff', 'c0')
|
y1.set('stuff', 'c0')
|
||||||
y2.set('stuff', 'c1')
|
y2.set('stuff', 'c1')
|
||||||
@ -125,7 +125,7 @@ describe('Map Type', function () {
|
|||||||
yield compareAllUsers(this.users)
|
yield compareAllUsers(this.users)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it('throws add & update & delete events (with type and primitive content)', co.wrap(function * (done) {
|
it('throws add & update & delete events (with type and primitive content)', wrapCo(function * (done) {
|
||||||
var event
|
var event
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
y1.observe(function (e) {
|
y1.observe(function (e) {
|
||||||
@ -186,7 +186,7 @@ describe('Map Type', function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
beforeEach(co.wrap(function * (done) {
|
beforeEach(wrapCo(function * (done) {
|
||||||
yield y1.set('Map', Y.Map)
|
yield y1.set('Map', Y.Map)
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ describe('Map Type', function () {
|
|||||||
this.maps = yield Promise.all(promises)
|
this.maps = yield Promise.all(promises)
|
||||||
done()
|
done()
|
||||||
}))
|
}))
|
||||||
it(`succeed after ${numberOfYMapTests} actions`, co.wrap(function * (done) {
|
it(`succeed after ${numberOfYMapTests} actions`, wrapCo(function * (done) {
|
||||||
yield applyRandomTransactions(this.users, this.maps, randomMapTransactions, numberOfYMapTests)
|
yield applyRandomTransactions(this.users, this.maps, randomMapTransactions, numberOfYMapTests)
|
||||||
yield flushAll()
|
yield flushAll()
|
||||||
yield compareMapValues(this.maps)
|
yield compareMapValues(this.maps)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
|
'use strict'
|
||||||
var CustomType = Y.CustomType
|
|
||||||
|
|
||||||
;(function () {
|
;(function () {
|
||||||
class YTextBind extends Y.Array.class {
|
class YTextBind extends Y.Array.class {
|
||||||
@ -12,7 +11,7 @@ var CustomType = Y.CustomType
|
|||||||
return this.valArray.join('')
|
return this.valArray.join('')
|
||||||
}
|
}
|
||||||
insert (pos, content) {
|
insert (pos, content) {
|
||||||
super(pos, content.split(''))
|
super.insert(pos, content.split(''))
|
||||||
}
|
}
|
||||||
bind (textfield, domRoot) {
|
bind (textfield, domRoot) {
|
||||||
domRoot = domRoot || window; // eslint-disable-line
|
domRoot = domRoot || window; // eslint-disable-line
|
||||||
@ -265,7 +264,7 @@ var CustomType = Y.CustomType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Y.TextBind = new CustomType({
|
Y.TextBind = new Y.utils.CustomType({
|
||||||
class: YTextBind,
|
class: YTextBind,
|
||||||
createType: function * YTextBindCreator () {
|
createType: function * YTextBindCreator () {
|
||||||
var model = {
|
var model = {
|
||||||
|
14
src/Utils.js
14
src/Utils.js
@ -1,10 +1,6 @@
|
|||||||
/* global Y */
|
/* global Y */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
var compareIds = Y.compareIds
|
|
||||||
var copyObject = Y.copyObject
|
|
||||||
var GeneratorFunction = (function *() {}).constructor;// eslint-disable-line
|
|
||||||
|
|
||||||
class EventHandler { // eslint-disable-line
|
class EventHandler { // eslint-disable-line
|
||||||
constructor (onevent) {
|
constructor (onevent) {
|
||||||
this.waiting = []
|
this.waiting = []
|
||||||
@ -16,7 +12,7 @@ class EventHandler { // eslint-disable-line
|
|||||||
if (this.awaiting <= 0) {
|
if (this.awaiting <= 0) {
|
||||||
this.onevent([op])
|
this.onevent([op])
|
||||||
} else {
|
} else {
|
||||||
this.waiting.push(copyObject(op))
|
this.waiting.push(Y.utils.copyObject(op))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
awaitAndPrematurelyCall (ops) {
|
awaitAndPrematurelyCall (ops) {
|
||||||
@ -49,12 +45,12 @@ class EventHandler { // eslint-disable-line
|
|||||||
var op = ops[oid]
|
var op = ops[oid]
|
||||||
for (var i = this.waiting.length - 1; i >= 0; i--) {
|
for (var i = this.waiting.length - 1; i >= 0; i--) {
|
||||||
let w = this.waiting[i]
|
let w = this.waiting[i]
|
||||||
if (compareIds(op.left, w.id)) {
|
if (Y.utils.compareIds(op.left, w.id)) {
|
||||||
// include the effect of op in w
|
// include the effect of op in w
|
||||||
w.right = op.id
|
w.right = op.id
|
||||||
// exclude the effect of w in op
|
// exclude the effect of w in op
|
||||||
op.left = w.left
|
op.left = w.left
|
||||||
} else if (compareIds(op.right, w.id)) {
|
} else if (Y.utils.compareIds(op.right, w.id)) {
|
||||||
// similar..
|
// similar..
|
||||||
w.left = op.id
|
w.left = op.id
|
||||||
op.right = w.right
|
op.right = w.right
|
||||||
@ -71,7 +67,7 @@ class EventHandler { // eslint-disable-line
|
|||||||
for (var i in this.waiting) {
|
for (var i in this.waiting) {
|
||||||
let w = this.waiting[i]
|
let w = this.waiting[i]
|
||||||
// We will just care about w.left
|
// We will just care about w.left
|
||||||
if (compareIds(del.target, w.left)) {
|
if (Y.utils.compareIds(del.target, w.left)) {
|
||||||
del.left = newLeft
|
del.left = newLeft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,6 +84,7 @@ class EventHandler { // eslint-disable-line
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Y.utils.EventHandler = EventHandler
|
||||||
|
|
||||||
class CustomType { // eslint-disable-line
|
class CustomType { // eslint-disable-line
|
||||||
constructor (def) {
|
constructor (def) {
|
||||||
@ -102,3 +99,4 @@ class CustomType { // eslint-disable-line
|
|||||||
this.class = def.class
|
this.class = def.class
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Y.utils.CustomType = CustomType
|
||||||
|
8
src/y.js
8
src/y.js
@ -40,7 +40,7 @@ class YConfig { // eslint-disable-line no-unused-vars
|
|||||||
Promise.all([
|
Promise.all([
|
||||||
this.db.garbageCollect(),
|
this.db.garbageCollect(),
|
||||||
this.db.garbageCollect()
|
this.db.garbageCollect()
|
||||||
]).then(function () {
|
]).then(() => {
|
||||||
this.connector.reconnect()
|
this.connector.reconnect()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -55,4 +55,8 @@ class YConfig { // eslint-disable-line no-unused-vars
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g) g.Y = Y //eslint-disable-line
|
if (g) { // eslint-disable-line
|
||||||
|
g.Y = Y //eslint-disable-line
|
||||||
|
debugger //eslint-disable-line
|
||||||
|
}
|
||||||
|
Y.utils = {}
|
||||||
|
21
test.js
21
test.js
@ -2,7 +2,16 @@
|
|||||||
|
|
||||||
function * aaa (){}
|
function * aaa (){}
|
||||||
|
|
||||||
class X {
|
class Y {
|
||||||
|
constructor () {
|
||||||
|
this.y = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class X extends Y {
|
||||||
|
constructor (a) {
|
||||||
|
this.x = 'true'
|
||||||
|
}
|
||||||
stuff () {
|
stuff () {
|
||||||
console.log("yay")
|
console.log("yay")
|
||||||
var r = function * () {
|
var r = function * () {
|
||||||
@ -12,6 +21,14 @@ class X {
|
|||||||
console.dir(r())
|
console.dir(r())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var Q = {}
|
||||||
|
Q["X"] = X
|
||||||
|
|
||||||
(new X).stuff()
|
var P = Q['X']
|
||||||
|
var x = new P( 44 )
|
||||||
|
|
||||||
|
(new Promise(function(resolve){
|
||||||
|
resolve(true)
|
||||||
|
})).then(function(arg){
|
||||||
|
console.log("yay", arg)
|
||||||
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user