From 0a321610aad975d1a555da86d29ac8eb7b3a59e2 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Tue, 16 May 2017 18:35:30 +0200 Subject: [PATCH] use rollup for yjs --- .babelrc | 12 ++ declarations/Structs.js | 72 ----------- declarations/Type.js | 0 declarations/Y.js | 34 ------ gulpfile.helper.js | 214 -------------------------------- gulpfile.js | 104 ---------------- package.json | 57 +++------ rollup.dist.js | 47 +++++++ rollup.test.js | 20 +++ src/Connector.js | 34 +++--- src/Database.js | 84 ++++++------- src/Database.spec.js | 256 +++++++++++++++++++-------------------- src/SpecHelper.js | 42 +++---- src/Struct.js | 62 +++++----- src/Transaction.js | 262 ++++++++++++++++++++-------------------- src/Utils.js | 48 ++++---- src/y.js | 38 +++--- 17 files changed, 509 insertions(+), 877 deletions(-) create mode 100644 .babelrc delete mode 100644 declarations/Structs.js delete mode 100644 declarations/Type.js delete mode 100644 declarations/Y.js delete mode 100644 gulpfile.helper.js delete mode 100644 gulpfile.js create mode 100644 rollup.dist.js create mode 100644 rollup.test.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..afaefc15 --- /dev/null +++ b/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["latest", { + "es2015": { + "modules": false + } + }] + ], + "plugins": [ + "external-helpers" + ] +} diff --git a/declarations/Structs.js b/declarations/Structs.js deleted file mode 100644 index e65c7207..00000000 --- a/declarations/Structs.js +++ /dev/null @@ -1,72 +0,0 @@ -/* @flow */ - -type UserId = string -type Id = [UserId, number|string] - -/* -type Struct = { - id: Id, - left?: Id, - right?: Id, - target?: Id, - struct: 'Insert' | 'Delete' -}*/ - -type Struct = Insertion | Deletion -type Operation = Struct - -type Insertion = { - id: Id, - left: ?Id, - origin: ?Id, - right: ?Id, - parent: Id, - parentSub: ?Id, - opContent: ?Id, - content: ?any, - struct: 'Insert' -} - -type Deletion = { - target: Id, - struct: 'Delete' -} - -type MapStruct = { - id: Id, - type: TypeNames, - map: any -} - -type ListStruct = { - id: Id, - type: TypeNames, - start: Id, - end: Id -} - - -type MessageSyncStep1 = { - type: 'sync step 1', - deleteSet: any, - stateSet: any -} - -type MessageSyncStep2 = { - type: 'sync step 2', - os: Array, - deleteSet: any, - stateSet: any -} - -type MessageUpdate = { - type: 'update', - ops: Array -} - -type MessageSyncDone = { - type: 'sync done' -} - -type Message = MessageSyncStep1 | MessageSyncStep2 | MessageUpdate | MessageSyncDone - diff --git a/declarations/Type.js b/declarations/Type.js deleted file mode 100644 index e69de29b..00000000 diff --git a/declarations/Y.js b/declarations/Y.js deleted file mode 100644 index 9a91a83d..00000000 --- a/declarations/Y.js +++ /dev/null @@ -1,34 +0,0 @@ -/* @flow */ - -type YGlobal = { - utils: Object, - Struct: any, - AbstractDatabase: any, - AbstractConnector: any, - Transaction: any -} - -type YConfig = { - db: Object, - connector: Object, - root: Object -} - -type TypeName = 'array' | 'map' | 'text' - -declare var YConcurrency_TestingMode : boolean - -type Transaction = Generator - -type SyncRole = 'master' | 'slave' - -declare class Store { - find: (id:Id) => Transaction; - put: (n:any) => Transaction; - delete: (id:Id) => Transaction; - findWithLowerBound: (start:Id) => Transaction; - findWithUpperBound: (end:Id) => Transaction; - findNext: (id:Id) => Transaction; - findPrev: (id:Id) => Transaction; - iterate: (t:any,start:?Id,end:?Id,gen:any) => Transaction; -} \ No newline at end of file diff --git a/gulpfile.helper.js b/gulpfile.helper.js deleted file mode 100644 index 54ed9466..00000000 --- a/gulpfile.helper.js +++ /dev/null @@ -1,214 +0,0 @@ - -var $ = require('gulp-load-plugins')() -var minimist = require('minimist') -var browserify = require('browserify') -var source = require('vinyl-source-stream') -var buffer = require('vinyl-buffer') - -module.exports = function (gulp, helperOptions) { - var runSequence = require('run-sequence').use(gulp) - var options = minimist(process.argv.slice(2), { - string: ['modulename', 'export', 'name', 'port', 'testfiles', 'es6'], - default: { - moduleName: helperOptions.moduleName, - targetName: helperOptions.targetName, - export: 'ignore', - port: '8888', - testfiles: '**/*.spec.js', - es6: false, - browserify: helperOptions.browserify != null ? helperOptions.browserify : false, - includeRuntime: helperOptions.includeRuntime || false, - debug: false - } - }) - if (options.es6 !== false) { - options.es6 = true - } - var files = { - dist: helperOptions.entry, - specs: helperOptions.specs, - src: './src/**/*.js' - } - - if (options.includeRuntime) { - files.distEs5 = ['node_modules/regenerator/runtime.js', files.dist] - } else { - files.distEs5 = [files.dist] - } - - var header = require('gulp-header') - var banner = ['/**', - ' * <%= pkg.name %> - <%= pkg.description %>', - ' * @version v<%= pkg.version %>', - ' * @link <%= pkg.homepage %>', - ' * @license <%= pkg.license %>', - ' */', - ''].join('\n') - - gulp.task('dist:es5', function () { - var babelOptions = { - presets: ['es2015'] - } - return (browserify({ - entries: files.distEs5, - debug: true, - standalone: options.moduleName - }).transform('babelify', babelOptions) - .bundle() - .pipe(source(options.targetName)) - .pipe(buffer()) - .pipe($.sourcemaps.init({loadMaps: true})) - .pipe($.if(!options.debug, $.uglify().on('error', function (e) { - console.log('\x07', e.message, JSON.stringify(e)); return this.end() - }))) - .pipe(header(banner, { pkg: require('./package.json') })) - .pipe($.sourcemaps.write('.')) - .pipe(gulp.dest('./dist/'))) - }) - - gulp.task('dist:es6', function () { - return (browserify({ - entries: files.dist, - debug: true, - standalone: options.moduleName - }).bundle() - .pipe(source(options.targetName)) - .pipe(buffer()) - .pipe($.sourcemaps.init({loadMaps: true})) - // .pipe($.uglify()) -- generators not yet supported see #448 - .pipe($.rename({ - extname: '.es6' - })) - .pipe(header(banner, { pkg: require('./package.json') })) - .pipe($.sourcemaps.write('.')) - .pipe(gulp.dest('./dist/'))) - }) - - gulp.task('dist', ['dist:es6', 'dist:es5']) - - gulp.task('watch:dist', function (cb) { - options.debug = true - gulp.src(['./README.md']) - .pipe($.watch('./README.md')) - .pipe(gulp.dest('./dist/')) - runSequence('dist', function () { - gulp.watch(files.src.concat('./README.md'), ['dist']) - cb() - }) - }) - - gulp.task('dev:node', ['test'], function () { - gulp.watch(files.src, ['test']) - }) - - gulp.task('spec-build', function () { - var browserify = require('browserify') - var source = require('vinyl-source-stream') - var buffer = require('vinyl-buffer') - - return browserify({ - entries: files.specs, // .concat(files.distEs5), - debug: true - })// .transform('babelify', { presets: ['es2015'] }) - .bundle() - .pipe(source('specs.js')) - .pipe(buffer()) - // .pipe($.sourcemaps.init({loadMaps: true})) - // .pipe($.sourcemaps.write('.')) - .pipe(gulp.dest('./build/')) - }) - - gulp.task('dev:browser', ['spec-build'], function () { - gulp.watch(files.src, ['spec-build']) - return gulp.src('./build/specs.js') - .pipe($.jasmineBrowser.specRunner()) - .pipe($.jasmineBrowser.server({port: options.port})) - }) - - gulp.task('test', function () { - return gulp.src(files.specs) - .pipe($.jasmine({ - verbose: true, - includeStuckTrace: true - })) - }) - - gulp.task('updateSubmodule', function () { - return gulp.src('./package.json', {read: false}) - .pipe($.shell([ - 'git submodule update --init', - 'cd dist && git pull origin dist' - ])) - }) - - gulp.task('bump', function (cb) { - gulp.src(['./package.json', './bower.json', './dist/bower.json'], {base: '.'}) - .pipe($.prompt.prompt({ - type: 'checkbox', - name: 'bump', - message: 'What type of bump would you like to do?', - choices: ['patch', 'minor', 'major'] - }, function (res) { - if (res.bump.length === 0) { - console.info('You have to select a bump type. Now I\'m going to use "patch" as bump type..') - } - var bumptype = res.bump[0] - if (bumptype === 'major') { - runSequence('bump_major', cb) - } else if (bumptype === 'minor') { - runSequence('bump_minor', cb) - } else { - runSequence('bump_patch', cb) - } - })) - }) - gulp.task('bump_patch', function () { - return gulp.src(['./package.json', './bower.json', './dist/bower.json'], {base: '.'}) - .pipe($.bump({type: 'patch'})) - .pipe(gulp.dest('./')) - }) - gulp.task('bump_minor', function () { - return gulp.src(['./package.json', './bower.json', './dist/bower.json'], {base: '.'}) - .pipe($.bump({type: 'minor'})) - .pipe(gulp.dest('./')) - }) - gulp.task('bump_major', function () { - return gulp.src(['./package.json', './bower.json', './dist/bower.json'], {base: '.'}) - .pipe($.bump({type: 'major'})) - .pipe(gulp.dest('./')) - }) - - gulp.task('publish_commits', function () { - return gulp.src('./package.json') - .pipe($.prompt.confirm({ - message: 'Are you sure you want to publish this release?', - default: false - })) - .pipe($.shell([ - 'cp README.md dist', - 'standard', - 'echo "Deploying version <%= getVersion(file.path) %>"', - 'git pull', - 'cd ./dist/ && git add -A', - 'cd ./dist/ && git commit -am "Deploy <%= getVersion(file.path) %>" -n', - 'cd ./dist/ && git push origin HEAD:dist', - 'cd ./dist/ && git tag -a v<%= getVersion(file.path) %> -m "Release <%= getVersion(file.path) %>"', - 'cd ./dist/ && git push origin --tags', - 'git commit -am "Release <%= getVersion(file.path) %>" -n', - 'git push', - 'npm publish', - 'echo Finished' - ], { - templateData: { - getVersion: function () { - return JSON.parse(String.fromCharCode.apply(null, this.file._contents)).version - } - } - })) - }) - - gulp.task('publish', function (cb) { - /* TODO: include 'test',*/ - runSequence('updateSubmodule', 'bump', 'dist', 'publish_commits', cb) - }) -} diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 8751b7be..00000000 --- a/gulpfile.js +++ /dev/null @@ -1,104 +0,0 @@ -/* eslint-env node */ - -/** Gulp Commands - - gulp command* - [--export ModuleType] - [--name ModuleName] - [--testport TestPort] - [--testfiles TestFiles] - - Module name (ModuleName): - Compile this to "y.js" (default) - - Supported module types (ModuleType): - - amd - - amdStrict - - common - - commonStrict - - ignore (default) - - system - - umd - - umdStrict - - Test port (TestPort): - Serve the specs on port 8888 (default) - - Test files (TestFiles): - Specify which specs to use! - - Commands: - - build:deploy - Build this library for deployment (es6->es5, minified) - - dev:browser - Watch the ./src directory. - Builds the library on changes. - Starts an http-server and serves the test suite on http://127.0.0.1:8888. - - dev:node - Watch the ./src directory. - Builds and specs the library on changes. - Usefull to run with node-inspector. - `node-debug $(which gulp) dev:node - - test: - Test this library -*/ - -var gulp = require('gulp') -var $ = require('gulp-load-plugins')() -var runSequence = require('run-sequence').use(gulp) - -require('./gulpfile.helper.js')(gulp, { - polyfills: [], - entry: './src/y.js', - targetName: 'y.js', - moduleName: 'Y', - includeRuntime: true, - specs: [ - './src/Database.spec.js', - '../y-array/src/Array.spec.js', - '../y-map/src/Map.spec.js' - ] -}) - -gulp.task('dev:examples', ['watch:dist'], function () { - // watch all distfiles and copy them to bower_components - var distfiles = ['./dist/*.{js,es6}', './dist/*.{js,es6}.map', '../y-*/dist/*.{js,es6}', '../y-*/dist/*.{js,es6}.map'] - gulp.src(distfiles) - .pipe($.watch(distfiles)) - .pipe($.rename(function (path) { - var dir = path.dirname.split(/[\\\/]/)[0] - console.log(JSON.stringify(path)) - path.dirname = dir === '.' ? 'yjs' : dir - })) - .pipe(gulp.dest('./dist/Examples/bower_components/')) - - return $.serve('dist/Examples/')() -}) - -gulp.task('default', ['updateSubmodule'], function (cb) { - gulp.src('package.json') - .pipe($.prompt.prompt({ - type: 'checkbox', - name: 'tasks', - message: 'Which tasks would you like to run?', - choices: [ - 'test Test this project', - 'dev:examples Serve the examples directory in ./dist/', - 'dev:browser Watch files & serve the testsuite for the browser', - 'dev:nodejs Watch filse & test this project with nodejs', - 'bump Bump the current state of the project', - 'publish Publish this project. Creates a github tag', - 'dist Build the distribution files' - ] - }, function (res) { - var tasks = res.tasks.map(function (task) { - return task.split(' ')[0] - }) - if (tasks.length > 0) { - console.info('gulp ' + tasks.join(' ')) - runSequence(tasks, cb) - } else { - console.info('Ok, .. goodbye') - } - })) -}) diff --git a/package.json b/package.json index 6ec4d451..e9a981dc 100644 --- a/package.json +++ b/package.json @@ -4,19 +4,15 @@ "description": "A framework for real-time p2p shared editing on any data", "main": "./src/y.js", "scripts": { - "test": "node --harmony ./node_modules/.bin/gulp test", - "lint": "./node_modules/.bin/standard" + "lint": "standard", + "dist": "rollup -c rollup.dist.js" }, "pre-commit": [ "lint", "test" ], "standard": { - "parser": "babel-eslint", "ignore": [ - "build/**", - "dist/**", - "declarations/**", "./y.js", "./y.js.map" ] @@ -42,41 +38,22 @@ }, "homepage": "http://y-js.org", "devDependencies": { - "babel-eslint": "^5.0.0-beta6", - "babel-plugin-transform-runtime": "^6.1.18", - "babel-preset-es2015": "^6.1.18", - "babelify": "^7.2.0", - "browserify": "^12.0.1", - "eslint": "^1.10.2", - "gulp": "^3.9.0", - "gulp-bump": "^1.0.0", - "gulp-concat": "^2.6.0", - "gulp-filter": "^3.0.1", - "gulp-git": "^1.6.0", - "gulp-header": "^1.8.8", - "gulp-if": "^2.0.0", - "gulp-jasmine": "^2.0.1", - "gulp-jasmine-browser": "^0.2.3", - "gulp-load-plugins": "^1.0.0", - "gulp-prompt": "^0.1.2", - "gulp-rename": "^1.2.2", - "gulp-serve": "^1.2.0", - "gulp-shell": "^0.5.1", - "gulp-sourcemaps": "^1.5.2", - "gulp-tag-version": "^1.3.0", - "gulp-uglify": "^2.0.0", - "gulp-util": "^3.0.6", - "gulp-watch": "^4.3.5", - "minimist": "^1.2.0", - "pre-commit": "^1.1.1", - "regenerator": "^0.8.42", - "run-sequence": "^1.1.4", - "seedrandom": "^2.4.2", - "standard": "^5.2.2", - "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^1.1.0" + "babel-cli": "^6.24.1", + "babel-plugin-external-helpers": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.24.1", + "babel-plugin-transform-runtime": "^6.23.0", + "rollup-plugin-babel": "^2.7.1", + "rollup-plugin-commonjs": "^8.0.2", + "rollup-plugin-multi-entry": "^2.0.1", + "rollup-plugin-node-resolve": "^3.0.0", + "rollup-plugin-uglify": "^1.0.2", + "rollup-regenerator-runtime": "^6.23.1", + "rollup-watch": "^3.2.2", + "standard": "^10.0.2" }, "dependencies": { - "debug": "^2.6.3" + "babel-plugin-external-helpers": "^6.22.0", + "babel-preset-latest": "^6.24.1", + "debug": "^2.6.6" } } diff --git a/rollup.dist.js b/rollup.dist.js new file mode 100644 index 00000000..0ec4b137 --- /dev/null +++ b/rollup.dist.js @@ -0,0 +1,47 @@ +import inject from 'rollup-plugin-inject' +import babel from 'rollup-plugin-babel' +import uglify from 'rollup-plugin-uglify' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs' +var pkg = require('./package.json') + +export default { + entry: 'src/y.js', + moduleName: 'yjs', + format: 'umd', + plugins: [ + nodeResolve({ + main: true, + module: true, + browser: true + }), + commonjs(), + babel({ + runtimeHelpers: true + }), + inject({ + regeneratorRuntime: 'regenerator-runtime' + }), + uglify({ + output: { + comments: function (node, comment) { + var text = comment.value + var type = comment.type + if (type === 'comment2') { + // multiline comment + return /@license/i.test(text) + } + } + } + }) + ], + dest: 'y.js', + sourceMap: true, + banner: ` +/** + * ${pkg.name} - ${pkg.description} + * @version v${pkg.version} + * @license ${pkg.license} + */ +` +} diff --git a/rollup.test.js b/rollup.test.js new file mode 100644 index 00000000..8ff10e53 --- /dev/null +++ b/rollup.test.js @@ -0,0 +1,20 @@ +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs' +import multiEntry from 'rollup-plugin-multi-entry' + +export default { + entry: 'tests/*.js', + moduleName: 'y-array-tests', + format: 'umd', + plugins: [ + nodeResolve({ + main: true, + module: true, + browser: true + }), + commonjs(), + multiEntry() + ], + dest: 'y-array.test.js', + sourceMap: true +} diff --git a/src/Connector.js b/src/Connector.js index edf06719..f3fbced6 100644 --- a/src/Connector.js +++ b/src/Connector.js @@ -4,7 +4,7 @@ function canRead (auth) { return auth === 'read' || auth === 'write' } function canWrite (auth) { return auth === 'write' } -module.exports = function (Y/* :any */) { +export default function extendConnector (Y/* :any */) { class AbstractConnector { /* :: y: YConfig; @@ -113,7 +113,7 @@ module.exports = function (Y/* :any */) { this.userEventListeners.push(f) } removeUserEventListener (f) { - this.userEventListeners = this.userEventListeners.filter(g => { f !== g }) + this.userEventListeners = this.userEventListeners.filter(g => f !== g) } userLeft (user) { if (this.connections[user] != null) { @@ -181,9 +181,9 @@ module.exports = function (Y/* :any */) { var conn = this if (syncUser != null) { this.currentSyncTarget = syncUser - this.y.db.requestTransaction(function *() { - var stateSet = yield* this.getStateSet() - var deleteSet = yield* this.getDeleteSet() + this.y.db.requestTransaction(function * () { + var stateSet = yield * this.getStateSet() + var deleteSet = yield * this.getDeleteSet() var answer = { type: 'sync step 1', stateSet: stateSet, @@ -198,11 +198,11 @@ module.exports = function (Y/* :any */) { }) } else { if (!conn.isSynced) { - this.y.db.requestTransaction(function *() { + this.y.db.requestTransaction(function * () { if (!conn.isSynced) { // it is crucial that isSynced is set at the time garbageCollectAfterSync is called conn.isSynced = true - yield* this.garbageCollectAfterSync() + yield * this.garbageCollectAfterSync() // call whensynced listeners for (var f of conn.whenSyncedListeners) { f() @@ -268,7 +268,7 @@ module.exports = function (Y/* :any */) { type: 'sync stop', protocolVersion: this.protocolVersion }) - return Promise.reject('Incompatible protocol version') + return Promise.reject(new Error('Incompatible protocol version')) } if (message.auth != null && this.connections[sender] != null) { // authenticate using auth in message @@ -293,13 +293,13 @@ module.exports = function (Y/* :any */) { let conn = this let m = message - this.y.db.requestTransaction(function *() { - var currentStateSet = yield* this.getStateSet() + this.y.db.requestTransaction(function * () { + var currentStateSet = yield * this.getStateSet() if (canWrite(auth)) { - yield* this.applyDeleteSet(m.deleteSet) + yield * this.applyDeleteSet(m.deleteSet) } - var ds = yield* this.getDeleteSet() + var ds = yield * this.getDeleteSet() var answer = { type: 'sync step 2', stateSet: currentStateSet, @@ -308,9 +308,9 @@ module.exports = function (Y/* :any */) { auth: this.authInfo } if (message.preferUntransformed === true && Object.keys(m.stateSet).length === 0) { - answer.osUntransformed = yield* this.getOperationsUntransformed() + answer.osUntransformed = yield * this.getOperationsUntransformed() } else { - answer.os = yield* this.getOperations(m.stateSet) + answer.os = yield * this.getOperations(m.stateSet) } conn.send(sender, answer) if (this.forwardToSyncingClients) { @@ -338,9 +338,9 @@ module.exports = function (Y/* :any */) { this.syncStep2 = defer.promise let m /* :MessageSyncStep2 */ = message db.requestTransaction(function * () { - yield* this.applyDeleteSet(m.deleteSet) + yield * this.applyDeleteSet(m.deleteSet) if (m.osUntransformed != null) { - yield* this.applyOperationsUntransformed(m.osUntransformed, m.stateSet) + yield * this.applyOperationsUntransformed(m.osUntransformed, m.stateSet) } else { this.store.apply(m.os) } @@ -388,7 +388,7 @@ module.exports = function (Y/* :any */) { } }) } else { - return Promise.reject('Unable to deliver message') + return Promise.reject(new Error('Unable to deliver message')) } } _setSyncedWith (user) { diff --git a/src/Database.js b/src/Database.js index 372cf085..7787a8fe 100644 --- a/src/Database.js +++ b/src/Database.js @@ -1,7 +1,7 @@ /* @flow */ 'use strict' -module.exports = function (Y /* :any */) { +export default function extendDatabase (Y /* :any */) { /* Partial definition of an OperationStore. TODO: name it Database, operation store only holds operations. @@ -42,11 +42,11 @@ module.exports = function (Y /* :any */) { this.dbOpts = opts var os = this this.userId = null - var resolve - this.userIdPromise = new Promise(function (r) { - resolve = r + var resolve_ + this.userIdPromise = new Promise(function (resolve) { + resolve_ = resolve }) - this.userIdPromise.resolve = resolve + this.userIdPromise.resolve = resolve_ // whether to broadcast all applied operations (insert & delete hook) this.forwardAppliedOperations = false // E.g. this.listenersById[id] : Array @@ -71,7 +71,7 @@ module.exports = function (Y /* :any */) { this.waitingTransactions = [] this.transactionInProgress = false this.transactionIsFlushed = false - if (typeof YConcurrency_TestingMode !== 'undefined') { + if (typeof YConcurrencyTestingMode !== 'undefined') { this.executeOrder = [] } this.gc1 = [] // first stage @@ -88,7 +88,7 @@ module.exports = function (Y /* :any */) { if (os.y.connector != null && os.y.connector.isSynced) { for (var i = 0; i < os.gc2.length; i++) { var oid = os.gc2[i] - yield* this.garbageCollectOperation(oid) + yield * this.garbageCollectOperation(oid) } os.gc2 = os.gc1 os.gc1 = [] @@ -177,7 +177,7 @@ module.exports = function (Y /* :any */) { }) } addToDebug () { - if (typeof YConcurrency_TestingMode !== 'undefined') { + if (typeof YConcurrencyTestingMode !== 'undefined') { var command /* :string */ = Array.prototype.map.call(arguments, function (s) { if (typeof s === 'string') { return s @@ -201,10 +201,10 @@ module.exports = function (Y /* :any */) { self.gc1 = [] self.gc2 = [] for (var i = 0; i < ungc.length; i++) { - var op = yield* this.getOperation(ungc[i]) + var op = yield * this.getOperation(ungc[i]) if (op != null) { delete op.gc - yield* this.setOperation(op) + yield * this.setOperation(op) } } resolve() @@ -234,12 +234,12 @@ module.exports = function (Y /* :any */) { if (left != null && left.deleted === true) { gc = true } else if (op.content != null && op.content.length > 1) { - op = yield* this.getInsertionCleanStart([op.id[0], op.id[1] + 1]) + op = yield * this.getInsertionCleanStart([op.id[0], op.id[1] + 1]) gc = true } if (gc) { op.gc = true - yield* this.setOperation(op) + yield * this.setOperation(op) this.store.queueGarbageCollector(op.id) return true } @@ -275,7 +275,7 @@ module.exports = function (Y /* :any */) { var self = this self.requestTransaction(function * () { self.userId = userId - var state = yield* this.getState(userId) + var state = yield * this.getState(userId) self.opClock = state.clock self.userIdPromise.resolve(userId) }) @@ -363,7 +363,7 @@ module.exports = function (Y /* :any */) { for (let key = 0; key < exeNow.length; key++) { let o = exeNow[key].op - yield* store.tryExecute.call(this, o) + yield * store.tryExecute.call(this, o) } for (var sid in ls) { @@ -371,9 +371,9 @@ module.exports = function (Y /* :any */) { var id = JSON.parse(sid) var op if (typeof id[1] === 'string') { - op = yield* this.getOperation(id) + op = yield * this.getOperation(id) } else { - op = yield* this.getInsertion(id) + op = yield * this.getInsertion(id) } if (op == null) { store.listenersById[sid] = l @@ -382,7 +382,7 @@ module.exports = function (Y /* :any */) { let listener = l[i] let o = listener.op if (--listener.missing === 0) { - yield* store.tryExecute.call(this, o) + yield * store.tryExecute.call(this, o) } } } @@ -402,12 +402,12 @@ module.exports = function (Y /* :any */) { * tryExecute (op) { this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(op), ')') if (op.struct === 'Delete') { - yield* Y.Struct.Delete.execute.call(this, op) + yield * Y.Struct.Delete.execute.call(this, op) // this is now called in Transaction.deleteOperation! // yield* this.store.operationAdded(this, op) } else { // check if this op was defined - var defined = yield* this.getInsertion(op.id) + var defined = yield * this.getInsertion(op.id) while (defined != null && defined.content != null) { // check if this op has a longer content in the case it is defined if (defined.id[1] + defined.content.length < op.id[1] + op.content.length) { @@ -416,23 +416,23 @@ module.exports = function (Y /* :any */) { op.id = [op.id[0], op.id[1] + overlapSize] op.left = Y.utils.getLastId(defined) op.origin = op.left - defined = yield* this.getOperation(op.id) // getOperation suffices here + defined = yield * this.getOperation(op.id) // getOperation suffices here } else { break } } if (defined == null) { var opid = op.id - var isGarbageCollected = yield* this.isGarbageCollected(opid) + var isGarbageCollected = yield * this.isGarbageCollected(opid) if (!isGarbageCollected) { // TODO: reduce number of get / put calls for op .. - yield* Y.Struct[op.struct].execute.call(this, op) - yield* this.addOperation(op) - yield* this.store.operationAdded(this, op) + yield * Y.Struct[op.struct].execute.call(this, op) + yield * this.addOperation(op) + yield * this.store.operationAdded(this, op) // operationAdded can change op.. - op = yield* this.getOperation(opid) + op = yield * this.getOperation(opid) // if insertion, try to combine with left - yield* this.tryCombineWithLeft(op) + yield * this.tryCombineWithLeft(op) } } } @@ -453,11 +453,11 @@ module.exports = function (Y /* :any */) { if (op.struct === 'Delete') { var type = this.initializedTypes[JSON.stringify(op.targetParent)] if (type != null) { - yield* type._changed(transaction, op) + yield * type._changed(transaction, op) } } else { // increase SS - yield* transaction.updateState(op.id[0]) + yield * transaction.updateState(op.id[0]) var opLen = op.content != null ? op.content.length : 1 for (let i = 0; i < opLen; i++) { // notify whenOperation listeners (by id) @@ -477,9 +477,9 @@ module.exports = function (Y /* :any */) { // if parent is deleted, mark as gc'd and return if (op.parent != null) { - var parentIsDeleted = yield* transaction.isDeleted(op.parent) + var parentIsDeleted = yield * transaction.isDeleted(op.parent) if (parentIsDeleted) { - yield* transaction.deleteList(op.id) + yield * transaction.deleteList(op.id) return } } @@ -487,7 +487,7 @@ module.exports = function (Y /* :any */) { // notify parent, if it was instanciated as a custom type if (t != null) { let o = Y.utils.copyOperation(op) - yield* t._changed(transaction, o) + yield * t._changed(transaction, o) } if (!op.deleted) { // Delete if DS says this is actually deleted @@ -496,13 +496,13 @@ module.exports = function (Y /* :any */) { // TODO: !! console.log('TODO: change this before commiting') for (let i = 0; i < len; i++) { var id = [startId[0], startId[1] + i] - var opIsDeleted = yield* transaction.isDeleted(id) + var opIsDeleted = yield * transaction.isDeleted(id) if (opIsDeleted) { var delop = { struct: 'Delete', target: id } - yield* this.tryExecute.call(transaction, delop) + yield * this.tryExecute.call(transaction, delop) } } } @@ -511,12 +511,12 @@ module.exports = function (Y /* :any */) { whenTransactionsFinished () { if (this.transactionInProgress) { if (this.transactionsFinished == null) { - var resolve - var promise = new Promise(function (r) { - resolve = r + var resolve_ + var promise = new Promise(function (resolve) { + resolve_ = resolve }) this.transactionsFinished = { - resolve: resolve, + resolve: resolve_, promise: promise } } @@ -540,7 +540,7 @@ module.exports = function (Y /* :any */) { } else { this.transactionIsFlushed = true return function * () { - yield* this.flush() + yield * this.flush() } } } else { @@ -571,9 +571,9 @@ module.exports = function (Y /* :any */) { var sid = JSON.stringify(id) var t = this.store.initializedTypes[sid] if (t == null) { - var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id) + var op/* :MapStruct | ListStruct */ = yield * this.getOperation(id) if (op != null) { - t = yield* Y[op.type].typeDefinition.initType.call(this, this.store, op, args) + t = yield * Y[op.type].typeDefinition.initType.call(this, this.store, op, args) this.store.initializedTypes[sid] = t } } @@ -590,9 +590,9 @@ module.exports = function (Y /* :any */) { this.requestTransaction(function * () { if (op.id[0] === '_') { - yield* this.setOperation(op) + yield * this.setOperation(op) } else { - yield* this.applyCreatedOperations([op]) + yield * this.applyCreatedOperations([op]) } }) var t = Y[op.type].typeDefinition.createType(this, op, typedefinition[1]) diff --git a/src/Database.spec.js b/src/Database.spec.js index 4aa3a825..353b2880 100644 --- a/src/Database.spec.js +++ b/src/Database.spec.js @@ -17,141 +17,141 @@ for (let database of databases) { }) afterEach(function (done) { store.requestTransaction(function * () { - yield* this.store.destroy() + yield * this.store.destroy() done() }) }) it('Deleted operation is deleted', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['u1', 10], 1) - expect(yield* this.isDeleted(['u1', 10])).toBeTruthy() - expect(yield* this.getDeleteSet()).toEqual({'u1': [[10, 1, false]]}) + yield * this.markDeleted(['u1', 10], 1) + expect(yield * this.isDeleted(['u1', 10])).toBeTruthy() + expect(yield * this.getDeleteSet()).toEqual({'u1': [[10, 1, false]]}) done() }) })) it('Deleted operation extends other deleted operation', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['u1', 10], 1) - yield* this.markDeleted(['u1', 11], 1) - expect(yield* this.isDeleted(['u1', 10])).toBeTruthy() - expect(yield* this.isDeleted(['u1', 11])).toBeTruthy() - expect(yield* this.getDeleteSet()).toEqual({'u1': [[10, 2, false]]}) + yield * this.markDeleted(['u1', 10], 1) + yield * this.markDeleted(['u1', 11], 1) + expect(yield * this.isDeleted(['u1', 10])).toBeTruthy() + expect(yield * this.isDeleted(['u1', 11])).toBeTruthy() + expect(yield * this.getDeleteSet()).toEqual({'u1': [[10, 2, false]]}) done() }) })) it('Deleted operation extends other deleted operation', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['0', 3], 1) - yield* this.markDeleted(['0', 4], 1) - yield* this.markDeleted(['0', 2], 1) - expect(yield* this.getDeleteSet()).toEqual({'0': [[2, 3, false]]}) + yield * this.markDeleted(['0', 3], 1) + yield * this.markDeleted(['0', 4], 1) + yield * this.markDeleted(['0', 2], 1) + expect(yield * this.getDeleteSet()).toEqual({'0': [[2, 3, false]]}) done() }) })) it('Debug #1', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['166', 0], 1) - yield* this.markDeleted(['166', 2], 1) - yield* this.markDeleted(['166', 0], 1) - yield* this.markDeleted(['166', 2], 1) - yield* this.markGarbageCollected(['166', 2], 1) - yield* this.markDeleted(['166', 1], 1) - yield* this.markDeleted(['166', 3], 1) - yield* this.markGarbageCollected(['166', 3], 1) - yield* this.markDeleted(['166', 0], 1) - expect(yield* this.getDeleteSet()).toEqual({'166': [[0, 2, false], [2, 2, true]]}) + yield * this.markDeleted(['166', 0], 1) + yield * this.markDeleted(['166', 2], 1) + yield * this.markDeleted(['166', 0], 1) + yield * this.markDeleted(['166', 2], 1) + yield * this.markGarbageCollected(['166', 2], 1) + yield * this.markDeleted(['166', 1], 1) + yield * this.markDeleted(['166', 3], 1) + yield * this.markGarbageCollected(['166', 3], 1) + yield * this.markDeleted(['166', 0], 1) + expect(yield * this.getDeleteSet()).toEqual({'166': [[0, 2, false], [2, 2, true]]}) done() }) })) it('Debug #2', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['293', 0], 1) - yield* this.markDeleted(['291', 2], 1) - yield* this.markDeleted(['291', 2], 1) - yield* this.markGarbageCollected(['293', 0], 1) - yield* this.markDeleted(['293', 1], 1) - yield* this.markGarbageCollected(['291', 2], 1) - expect(yield* this.getDeleteSet()).toEqual({'291': [[2, 1, true]], '293': [[0, 1, true], [1, 1, false]]}) + yield * this.markDeleted(['293', 0], 1) + yield * this.markDeleted(['291', 2], 1) + yield * this.markDeleted(['291', 2], 1) + yield * this.markGarbageCollected(['293', 0], 1) + yield * this.markDeleted(['293', 1], 1) + yield * this.markGarbageCollected(['291', 2], 1) + expect(yield * this.getDeleteSet()).toEqual({'291': [[2, 1, true]], '293': [[0, 1, true], [1, 1, false]]}) done() }) })) it('Debug #3', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['581', 0], 1) - yield* this.markDeleted(['581', 1], 1) - yield* this.markDeleted(['580', 0], 1) - yield* this.markDeleted(['580', 0], 1) - yield* this.markGarbageCollected(['581', 0], 1) - yield* this.markDeleted(['581', 2], 1) - yield* this.markDeleted(['580', 1], 1) - yield* this.markDeleted(['580', 2], 1) - yield* this.markDeleted(['580', 1], 1) - yield* this.markDeleted(['580', 2], 1) - yield* this.markGarbageCollected(['581', 2], 1) - yield* this.markGarbageCollected(['581', 1], 1) - yield* this.markGarbageCollected(['580', 1], 1) - expect(yield* this.getDeleteSet()).toEqual({'580': [[0, 1, false], [1, 1, true], [2, 1, false]], '581': [[0, 3, true]]}) + yield * this.markDeleted(['581', 0], 1) + yield * this.markDeleted(['581', 1], 1) + yield * this.markDeleted(['580', 0], 1) + yield * this.markDeleted(['580', 0], 1) + yield * this.markGarbageCollected(['581', 0], 1) + yield * this.markDeleted(['581', 2], 1) + yield * this.markDeleted(['580', 1], 1) + yield * this.markDeleted(['580', 2], 1) + yield * this.markDeleted(['580', 1], 1) + yield * this.markDeleted(['580', 2], 1) + yield * this.markGarbageCollected(['581', 2], 1) + yield * this.markGarbageCollected(['581', 1], 1) + yield * this.markGarbageCollected(['580', 1], 1) + expect(yield * this.getDeleteSet()).toEqual({'580': [[0, 1, false], [1, 1, true], [2, 1, false]], '581': [[0, 3, true]]}) done() }) })) it('Debug #4', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['544', 0], 1) - yield* this.markDeleted(['543', 2], 1) - yield* this.markDeleted(['544', 0], 1) - yield* this.markDeleted(['543', 2], 1) - yield* this.markGarbageCollected(['544', 0], 1) - yield* this.markDeleted(['545', 1], 1) - yield* this.markDeleted(['543', 4], 1) - yield* this.markDeleted(['543', 3], 1) - yield* this.markDeleted(['544', 1], 1) - yield* this.markDeleted(['544', 2], 1) - yield* this.markDeleted(['544', 1], 1) - yield* this.markDeleted(['544', 2], 1) - yield* this.markGarbageCollected(['543', 2], 1) - yield* this.markGarbageCollected(['543', 4], 1) - yield* this.markGarbageCollected(['544', 2], 1) - yield* this.markGarbageCollected(['543', 3], 1) - expect(yield* this.getDeleteSet()).toEqual({'543': [[2, 3, true]], '544': [[0, 1, true], [1, 1, false], [2, 1, true]], '545': [[1, 1, false]]}) + yield * this.markDeleted(['544', 0], 1) + yield * this.markDeleted(['543', 2], 1) + yield * this.markDeleted(['544', 0], 1) + yield * this.markDeleted(['543', 2], 1) + yield * this.markGarbageCollected(['544', 0], 1) + yield * this.markDeleted(['545', 1], 1) + yield * this.markDeleted(['543', 4], 1) + yield * this.markDeleted(['543', 3], 1) + yield * this.markDeleted(['544', 1], 1) + yield * this.markDeleted(['544', 2], 1) + yield * this.markDeleted(['544', 1], 1) + yield * this.markDeleted(['544', 2], 1) + yield * this.markGarbageCollected(['543', 2], 1) + yield * this.markGarbageCollected(['543', 4], 1) + yield * this.markGarbageCollected(['544', 2], 1) + yield * this.markGarbageCollected(['543', 3], 1) + expect(yield * this.getDeleteSet()).toEqual({'543': [[2, 3, true]], '544': [[0, 1, true], [1, 1, false], [2, 1, true]], '545': [[1, 1, false]]}) done() }) })) it('Debug #5', async(function * (done) { store.requestTransaction(function * () { - yield* this.applyDeleteSet({'16': [[1, 2, false]], '17': [[0, 1, true], [1, 3, false]]}) - expect(yield* this.getDeleteSet()).toEqual({'16': [[1, 2, false]], '17': [[0, 1, true], [1, 3, false]]}) - yield* this.applyDeleteSet({'16': [[1, 2, false]], '17': [[0, 4, true]]}) - expect(yield* this.getDeleteSet()).toEqual({'16': [[1, 2, false]], '17': [[0, 4, true]]}) + yield * this.applyDeleteSet({'16': [[1, 2, false]], '17': [[0, 1, true], [1, 3, false]]}) + expect(yield * this.getDeleteSet()).toEqual({'16': [[1, 2, false]], '17': [[0, 1, true], [1, 3, false]]}) + yield * this.applyDeleteSet({'16': [[1, 2, false]], '17': [[0, 4, true]]}) + expect(yield * this.getDeleteSet()).toEqual({'16': [[1, 2, false]], '17': [[0, 4, true]]}) done() }) })) it('Debug #6', async(function * (done) { store.requestTransaction(function * () { - yield* this.applyDeleteSet({'40': [[0, 3, false]]}) - expect(yield* this.getDeleteSet()).toEqual({'40': [[0, 3, false]]}) - yield* this.applyDeleteSet({'39': [[2, 2, false]], '40': [[0, 1, true], [1, 2, false]], '41': [[2, 1, false]]}) - expect(yield* this.getDeleteSet()).toEqual({'39': [[2, 2, false]], '40': [[0, 1, true], [1, 2, false]], '41': [[2, 1, false]]}) + yield * this.applyDeleteSet({'40': [[0, 3, false]]}) + expect(yield * this.getDeleteSet()).toEqual({'40': [[0, 3, false]]}) + yield * this.applyDeleteSet({'39': [[2, 2, false]], '40': [[0, 1, true], [1, 2, false]], '41': [[2, 1, false]]}) + expect(yield * this.getDeleteSet()).toEqual({'39': [[2, 2, false]], '40': [[0, 1, true], [1, 2, false]], '41': [[2, 1, false]]}) done() }) })) it('Debug #7', async(function * (done) { store.requestTransaction(function * () { - yield* this.markDeleted(['9', 2], 1) - yield* this.markDeleted(['11', 2], 1) - yield* this.markDeleted(['11', 4], 1) - yield* this.markDeleted(['11', 1], 1) - yield* this.markDeleted(['9', 4], 1) - yield* this.markDeleted(['10', 0], 1) - yield* this.markGarbageCollected(['11', 2], 1) - yield* this.markDeleted(['11', 2], 1) - yield* this.markGarbageCollected(['11', 3], 1) - yield* this.markDeleted(['11', 3], 1) - yield* this.markDeleted(['11', 3], 1) - yield* this.markDeleted(['9', 4], 1) - yield* this.markDeleted(['10', 0], 1) - yield* this.markGarbageCollected(['11', 1], 1) - yield* this.markDeleted(['11', 1], 1) - expect(yield* this.getDeleteSet()).toEqual({'9': [[2, 1, false], [4, 1, false]], '10': [[0, 1, false]], '11': [[1, 3, true], [4, 1, false]]}) + yield * this.markDeleted(['9', 2], 1) + yield * this.markDeleted(['11', 2], 1) + yield * this.markDeleted(['11', 4], 1) + yield * this.markDeleted(['11', 1], 1) + yield * this.markDeleted(['9', 4], 1) + yield * this.markDeleted(['10', 0], 1) + yield * this.markGarbageCollected(['11', 2], 1) + yield * this.markDeleted(['11', 2], 1) + yield * this.markGarbageCollected(['11', 3], 1) + yield * this.markDeleted(['11', 3], 1) + yield * this.markDeleted(['11', 3], 1) + yield * this.markDeleted(['9', 4], 1) + yield * this.markDeleted(['10', 0], 1) + yield * this.markGarbageCollected(['11', 1], 1) + yield * this.markDeleted(['11', 1], 1) + expect(yield * this.getDeleteSet()).toEqual({'9': [[2, 1, false], [4, 1, false]], '10': [[0, 1, false]], '11': [[1, 3, true], [4, 1, false]]}) done() }) })) @@ -167,54 +167,54 @@ for (let database of databases) { }) afterEach(function (done) { store.requestTransaction(function * () { - yield* this.store.destroy() + yield * this.store.destroy() done() }) }) it('debug #1', function (done) { store.requestTransaction(function * () { - yield* this.os.put({id: [2]}) - yield* this.os.put({id: [0]}) - yield* this.os.delete([2]) - yield* this.os.put({id: [1]}) - expect(yield* this.os.find([0])).toBeTruthy() - expect(yield* this.os.find([1])).toBeTruthy() - expect(yield* this.os.find([2])).toBeFalsy() + yield * this.os.put({id: [2]}) + yield * this.os.put({id: [0]}) + yield * this.os.delete([2]) + yield * this.os.put({id: [1]}) + expect(yield * this.os.find([0])).toBeTruthy() + expect(yield * this.os.find([1])).toBeTruthy() + expect(yield * this.os.find([2])).toBeFalsy() done() }) }) it('can add&retrieve 5 elements', function (done) { store.requestTransaction(function * () { - yield* this.os.put({val: 'four', id: [4]}) - yield* this.os.put({val: 'one', id: [1]}) - yield* this.os.put({val: 'three', id: [3]}) - yield* this.os.put({val: 'two', id: [2]}) - yield* this.os.put({val: 'five', id: [5]}) - expect((yield* this.os.find([1])).val).toEqual('one') - expect((yield* this.os.find([2])).val).toEqual('two') - expect((yield* this.os.find([3])).val).toEqual('three') - expect((yield* this.os.find([4])).val).toEqual('four') - expect((yield* this.os.find([5])).val).toEqual('five') + yield * this.os.put({val: 'four', id: [4]}) + yield * this.os.put({val: 'one', id: [1]}) + yield * this.os.put({val: 'three', id: [3]}) + yield * this.os.put({val: 'two', id: [2]}) + yield * this.os.put({val: 'five', id: [5]}) + expect((yield * this.os.find([1])).val).toEqual('one') + expect((yield * this.os.find([2])).val).toEqual('two') + expect((yield * this.os.find([3])).val).toEqual('three') + expect((yield * this.os.find([4])).val).toEqual('four') + expect((yield * this.os.find([5])).val).toEqual('five') done() }) }) it('5 elements do not exist anymore after deleting them', function (done) { store.requestTransaction(function * () { - yield* this.os.put({val: 'four', id: [4]}) - yield* this.os.put({val: 'one', id: [1]}) - yield* this.os.put({val: 'three', id: [3]}) - yield* this.os.put({val: 'two', id: [2]}) - yield* this.os.put({val: 'five', id: [5]}) - yield* this.os.delete([4]) - expect(yield* this.os.find([4])).not.toBeTruthy() - yield* this.os.delete([3]) - expect(yield* this.os.find([3])).not.toBeTruthy() - yield* this.os.delete([2]) - expect(yield* this.os.find([2])).not.toBeTruthy() - yield* this.os.delete([1]) - expect(yield* this.os.find([1])).not.toBeTruthy() - yield* this.os.delete([5]) - expect(yield* this.os.find([5])).not.toBeTruthy() + yield * this.os.put({val: 'four', id: [4]}) + yield * this.os.put({val: 'one', id: [1]}) + yield * this.os.put({val: 'three', id: [3]}) + yield * this.os.put({val: 'two', id: [2]}) + yield * this.os.put({val: 'five', id: [5]}) + yield * this.os.delete([4]) + expect(yield * this.os.find([4])).not.toBeTruthy() + yield * this.os.delete([3]) + expect(yield * this.os.find([3])).not.toBeTruthy() + yield * this.os.delete([2]) + expect(yield * this.os.find([2])).not.toBeTruthy() + yield * this.os.delete([1]) + expect(yield * this.os.find([1])).not.toBeTruthy() + yield * this.os.delete([5]) + expect(yield * this.os.find([5])).not.toBeTruthy() done() }) }) @@ -232,9 +232,9 @@ for (let database of databases) { var r = Math.random() if (r < 0.8) { var obj = [Math.floor(Math.random() * numberOfOSTests * 10000)] - if (!(yield* this.os.find(obj))) { + if (!(yield * this.os.find(obj))) { elements.push(obj) - yield* this.os.put({id: obj}) + yield * this.os.put({id: obj}) } } else if (elements.length > 0) { var elemid = Math.floor(Math.random() * elements.length) @@ -242,7 +242,7 @@ for (let database of databases) { elements = elements.filter(function (e) { return !Y.utils.compareIds(e, elem) }) - yield* this.os.delete(elem) + yield * this.os.delete(elem) } } done() @@ -250,14 +250,14 @@ for (let database of databases) { }) afterAll(function (done) { store.requestTransaction(function * () { - yield* this.store.destroy() + yield * this.store.destroy() done() }) }) it('can find every object', function (done) { store.requestTransaction(function * () { for (var id of elements) { - expect((yield* this.os.find(id)).id).toEqual(id) + expect((yield * this.os.find(id)).id).toEqual(id) } done() }) @@ -266,7 +266,7 @@ for (let database of databases) { it('can find every object with lower bound search', function (done) { store.requestTransaction(function * () { for (var id of elements) { - var e = yield* this.os.findWithLowerBound(id) + var e = yield * this.os.findWithLowerBound(id) expect(e.id).toEqual(id) } done() @@ -281,7 +281,7 @@ for (let database of databases) { var actualResults = 0 store.requestTransaction(function * () { - yield* this.os.iterate(this, lowerBound, null, function * (val) { + yield * this.os.iterate(this, lowerBound, null, function * (val) { expect(val).toBeDefined() actualResults++ }) @@ -297,7 +297,7 @@ for (let database of databases) { }).length var actualResults = 0 store.requestTransaction(function * () { - yield* this.os.iterate(this, lowerBound, null, function * (val) { + yield * this.os.iterate(this, lowerBound, null, function * (val) { expect(val).toBeDefined() actualResults++ }) @@ -314,7 +314,7 @@ for (let database of databases) { var actualResults = 0 store.requestTransaction(function * () { - yield* this.os.iterate(this, null, upperBound, function * (val) { + yield * this.os.iterate(this, null, upperBound, function * (val) { expect(val).toBeDefined() actualResults++ }) @@ -340,7 +340,7 @@ for (let database of databases) { }).length var actualResults = 0 store.requestTransaction(function * () { - yield* this.os.iterate(this, lowerBound, upperBound, function * (val) { + yield * this.os.iterate(this, lowerBound, upperBound, function * (val) { expect(val).toBeDefined() actualResults++ }) diff --git a/src/SpecHelper.js b/src/SpecHelper.js index 90c81be2..ff31eb9c 100644 --- a/src/SpecHelper.js +++ b/src/SpecHelper.js @@ -46,7 +46,7 @@ g.setRandomSeed = function setRandomSeed (seed) { g.generateRandomSeed() -g.YConcurrency_TestingMode = true +g.YConcurrencyTestingMode = true jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000 @@ -168,7 +168,7 @@ function fixAwaitingInType (type) { type.os.requestTransaction(function * () { if (type.eventHandler.awaiting > 0 && type.eventHandler._debuggingAwaiting === true) { type.eventHandler._debuggingAwaiting = false - yield* type.eventHandler.awaitOps(this, function * () { /* mock function */ }) + yield * type.eventHandler.awaitOps(this, function * () { /* mock function */ }) } wait(50).then(type.os.whenTransactionsFinished()).then(wait(50)).then(resolve) }) @@ -178,13 +178,13 @@ function fixAwaitingInType (type) { g.fixAwaitingInType = fixAwaitingInType g.applyRandomTransactionsNoGCNoDisconnect = async(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) { - yield* applyTransactions(1, numberOfTransactions, objects, users, transactions, true) + yield * applyTransactions(1, numberOfTransactions, objects, users, transactions, true) yield Y.utils.globalRoom.flushAll() yield Promise.all(objects.map(fixAwaitingInType)) }) g.applyRandomTransactionsAllRejoinNoGC = async(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) { - yield* applyTransactions(1, numberOfTransactions, objects, users, transactions) + yield * applyTransactions(1, numberOfTransactions, objects, users, transactions) yield Promise.all(objects.map(fixAwaitingInType)) yield Y.utils.globalRoom.flushAll() yield Promise.all(objects.map(fixAwaitingInType)) @@ -200,7 +200,7 @@ g.applyRandomTransactionsAllRejoinNoGC = async(function * applyRandomTransaction }) g.applyRandomTransactionsWithGC = async(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) { - yield* applyTransactions(1, numberOfTransactions, objects, users.slice(1), transactions) + yield * applyTransactions(1, numberOfTransactions, objects, users.slice(1), transactions) yield Y.utils.globalRoom.flushAll() yield Promise.all(objects.map(fixAwaitingInType)) for (var u in users) { @@ -242,18 +242,18 @@ g.compareAllUsers = async(function * compareAllUsers (users) { // t1 and t2 basically do the same. They define t[1,2], ds[1,2], and allDels[1,2] function * t1 () { - s1 = yield* this.getStateSet() - ds1 = yield* this.getDeleteSet() + s1 = yield * this.getStateSet() + ds1 = yield * this.getDeleteSet() allDels1 = [] - yield* this.ds.iterate(this, null, null, function * (d) { + yield * this.ds.iterate(this, null, null, function * (d) { allDels1.push(d) }) } function * t2 () { - s2 = yield* this.getStateSet() - ds2 = yield* this.getDeleteSet() + s2 = yield * this.getStateSet() + ds2 = yield * this.getDeleteSet() allDels2 = [] - yield* this.ds.iterate(this, null, null, function * (d) { + yield * this.ds.iterate(this, null, null, function * (d) { allDels2.push(d) }) } @@ -269,25 +269,25 @@ g.compareAllUsers = async(function * compareAllUsers (users) { for (var uid = 0; uid < users.length; uid++) { var u = users[uid] u.db.requestTransaction(function * () { - var sv = yield* this.getStateVector() + var sv = yield * this.getStateVector() for (var s of sv) { - yield* this.updateState(s.user) + yield * this.updateState(s.user) } // compare deleted ops against deleteStore - yield* this.os.iterate(this, null, null, function * (o) { + yield * this.os.iterate(this, null, null, function * (o) { if (o.deleted === true) { - expect(yield* this.isDeleted(o.id)).toBeTruthy() + expect(yield * this.isDeleted(o.id)).toBeTruthy() } }) // compare deleteStore against deleted ops var ds = [] - yield* this.ds.iterate(this, null, null, function * (d) { + yield * this.ds.iterate(this, null, null, function * (d) { ds.push(d) }) for (var j in ds) { var d = ds[j] for (var i = 0; i < d.len; i++) { - var o = yield* this.getInsertion([d.id[0], d.id[1] + i]) + var o = yield * this.getInsertion([d.id[0], d.id[1] + i]) // gc'd or deleted if (d.gc) { expect(o).toBeFalsy() @@ -300,8 +300,8 @@ g.compareAllUsers = async(function * compareAllUsers (users) { // compare allDels tree if (s1 == null) { u.db.requestTransaction(function * () { - yield* t1.call(this) - yield* this.os.iterate(this, null, null, function * (o) { + yield * t1.call(this) + yield * this.os.iterate(this, null, null, function * (o) { o = Y.utils.copyObject(o) delete o.origin delete o.originOf @@ -310,9 +310,9 @@ g.compareAllUsers = async(function * compareAllUsers (users) { }) } else { u.db.requestTransaction(function * () { - yield* t2.call(this) + yield * t2.call(this) var db2 = [] - yield* this.os.iterate(this, null, null, function * (o) { + yield * this.os.iterate(this, null, null, function * (o) { o = Y.utils.copyObject(o) delete o.origin delete o.originOf diff --git a/src/Struct.js b/src/Struct.js index 0574d351..1b6581d7 100644 --- a/src/Struct.js +++ b/src/Struct.js @@ -19,7 +19,7 @@ * requiredOps - Operations that are required to execute this operation. */ -module.exports = function (Y/* :any */) { +export default function extendStruct (Y) { var Struct = { /* This is the only operation that is actually not a structure, because it is not stored in the OS. This is why it _does not_ have an id @@ -40,7 +40,7 @@ module.exports = function (Y/* :any */) { return [] // [op.target] }, execute: function * (op) { - return yield* this.deleteOperation(op.target, op.length || 1) + return yield * this.deleteOperation(op.target, op.length || 1) } }, Insert: { @@ -101,13 +101,13 @@ module.exports = function (Y/* :any */) { return 0 } else { var d = 0 - var o = yield* this.getInsertion(op.left) + var o = yield * this.getInsertion(op.left) while (!Y.utils.matchesId(o, op.origin)) { d++ if (o.left == null) { break } else { - o = yield* this.getInsertion(o.left) + o = yield * this.getInsertion(o.left) } } return d @@ -138,17 +138,17 @@ module.exports = function (Y/* :any */) { if (op.origin != null) { // TODO: !== instead of != // we save in origin that op originates in it // we need that later when we eventually garbage collect origin (see transaction) - var origin = yield* this.getInsertionCleanEnd(op.origin) + var origin = yield * this.getInsertionCleanEnd(op.origin) if (origin.originOf == null) { origin.originOf = [] } origin.originOf.push(op.id) - yield* this.setOperation(origin) + yield * this.setOperation(origin) if (origin.right != null) { tryToRemergeLater.push(origin.right) } } - var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0) + var distanceToOrigin = i = yield * Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0) // now we begin to insert op in the list of insertions.. var o @@ -157,29 +157,29 @@ module.exports = function (Y/* :any */) { // find o. o is the first conflicting operation if (op.left != null) { - o = yield* this.getInsertionCleanEnd(op.left) + o = yield * this.getInsertionCleanEnd(op.left) if (!Y.utils.compareIds(op.left, op.origin) && o.right != null) { // only if not added previously tryToRemergeLater.push(o.right) } - o = (o.right == null) ? null : yield* this.getOperation(o.right) + o = (o.right == null) ? null : yield * this.getOperation(o.right) } else { // left == null - parent = yield* this.getOperation(op.parent) + parent = yield * this.getOperation(op.parent) let startId = op.parentSub ? parent.map[op.parentSub] : parent.start - start = startId == null ? null : yield* this.getOperation(startId) + start = startId == null ? null : yield * this.getOperation(startId) o = start } // make sure to split op.right if necessary (also add to tryCombineWithLeft) if (op.right != null) { tryToRemergeLater.push(op.right) - yield* this.getInsertionCleanStart(op.right) + yield * this.getInsertionCleanStart(op.right) } // handle conflicts while (true) { if (o != null && !Y.utils.compareIds(o.id, op.right)) { - var oOriginDistance = yield* Struct.Insert.getDistanceToOrigin.call(this, o) + var oOriginDistance = yield * Struct.Insert.getDistanceToOrigin.call(this, o) if (oOriginDistance === i) { // case 1 if (o.id[0] < op.id[0]) { @@ -197,7 +197,7 @@ module.exports = function (Y/* :any */) { } i++ if (o.right != null) { - o = yield* this.getInsertion(o.right) + o = yield * this.getInsertion(o.right) } else { o = null } @@ -210,17 +210,17 @@ module.exports = function (Y/* :any */) { var left = null var right = null if (parent == null) { - parent = yield* this.getOperation(op.parent) + parent = yield * this.getOperation(op.parent) } // reconnect left and set right of op if (op.left != null) { - left = yield* this.getInsertion(op.left) + left = yield * this.getInsertion(op.left) // link left op.right = left.right left.right = op.id - yield* this.setOperation(left) + yield * this.setOperation(left) } else { // set op.right from parent, if necessary op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start @@ -228,33 +228,33 @@ module.exports = function (Y/* :any */) { // reconnect right if (op.right != null) { // TODO: wanna connect right too? - right = yield* this.getOperation(op.right) + right = yield * this.getOperation(op.right) right.left = Y.utils.getLastId(op) // if right exists, and it is supposed to be gc'd. Remove it from the gc if (right.gc != null) { if (right.content != null && right.content.length > 1) { - right = yield* this.getInsertionCleanEnd(right.id) + right = yield * this.getInsertionCleanEnd(right.id) } this.store.removeFromGarbageCollector(right) } - yield* this.setOperation(right) + yield * this.setOperation(right) } // update parents .map/start/end properties if (op.parentSub != null) { if (left == null) { parent.map[op.parentSub] = op.id - yield* this.setOperation(parent) + yield * this.setOperation(parent) } // is a child of a map struct. // Then also make sure that only the most left element is not deleted // We do not call the type in this case (this is what the third parameter is for) if (op.right != null) { - yield* this.deleteOperation(op.right, 1, true) + yield * this.deleteOperation(op.right, 1, true) } if (op.left != null) { - yield* this.deleteOperation(op.id, 1, true) + yield * this.deleteOperation(op.id, 1, true) } } else { if (right == null || left == null) { @@ -264,14 +264,14 @@ module.exports = function (Y/* :any */) { if (left == null) { parent.start = op.id } - yield* this.setOperation(parent) + yield * this.setOperation(parent) } } // try to merge original op.left and op.origin for (i = 0; i < tryToRemergeLater.length; i++) { - var m = yield* this.getOperation(tryToRemergeLater[i]) - yield* this.tryCombineWithLeft(m) + var m = yield * this.getOperation(tryToRemergeLater[i]) + yield * this.tryCombineWithLeft(m) } } }, @@ -329,7 +329,7 @@ module.exports = function (Y/* :any */) { return null } var res = null - var o = yield* this.getOperation(op.start) + var o = yield * this.getOperation(op.start) while (true) { if (!o.deleted) { @@ -337,7 +337,7 @@ module.exports = function (Y/* :any */) { pos-- } if (pos >= 0 && o.right != null) { - o = yield* this.getOperation(o.right) + o = yield * this.getOperation(o.right) } else { break } @@ -348,7 +348,7 @@ module.exports = function (Y/* :any */) { o = o.start var res = [] while (o != null) { // TODO: change to != (at least some convention) - var operation = yield* this.getOperation(o) + var operation = yield * this.getOperation(o) if (!operation.deleted) { res.push(f(operation)) } @@ -398,13 +398,13 @@ module.exports = function (Y/* :any */) { get: function * (op, name) { var oid = op.map[name] if (oid != null) { - var res = yield* this.getOperation(oid) + var res = yield * this.getOperation(oid) if (res == null || res.deleted) { return void 0 } else if (res.opContent == null) { return res.content[0] } else { - return yield* this.getType(res.opContent) + return yield * this.getType(res.opContent) } } } diff --git a/src/Transaction.js b/src/Transaction.js index d21adba9..aad43054 100644 --- a/src/Transaction.js +++ b/src/Transaction.js @@ -74,7 +74,7 @@ - this is called only by `getOperations(startSS)`. It makes an operation applyable on a given SS. */ -module.exports = function (Y/* :any */) { +export default function extendTransaction (Y) { class TransactionInterface { /* :: store: Y.AbstractDatabase; @@ -91,7 +91,7 @@ module.exports = function (Y/* :any */) { var send = [] for (var i = 0; i < ops.length; i++) { var op = ops[i] - yield* this.store.tryExecute.call(this, op) + yield * this.store.tryExecute.call(this, op) if (op.id == null || typeof op.id[1] !== 'string') { send.push(Y.Struct[op.struct].encode(op)) } @@ -104,15 +104,15 @@ module.exports = function (Y/* :any */) { * deleteList (start) { while (start != null) { - start = yield* this.getOperation(start) + start = yield * this.getOperation(start) if (!start.gc) { start.gc = true start.deleted = true - yield* this.setOperation(start) + yield * this.setOperation(start) var delLength = start.content != null ? start.content.length : 1 - yield* this.markDeleted(start.id, delLength) + yield * this.markDeleted(start.id, delLength) if (start.opContent != null) { - yield* this.deleteOperation(start.opContent) + yield * this.deleteOperation(start.opContent) } this.store.queueGarbageCollector(start.id) } @@ -127,10 +127,10 @@ module.exports = function (Y/* :any */) { if (length == null) { length = 1 } - yield* this.markDeleted(targetId, length) + yield * this.markDeleted(targetId, length) while (length > 0) { var callType = false - var target = yield* this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1]) + var target = yield * this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1]) var targetLength = target != null && target.content != null ? target.content.length : 1 if (target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1]) { // does not exist or is not in the range of the deletion @@ -141,12 +141,12 @@ module.exports = function (Y/* :any */) { if (!target.deleted) { if (target.id[1] < targetId[1]) { // starts to the left of the deletion range - target = yield* this.getInsertionCleanStart(targetId) + target = yield * this.getInsertionCleanStart(targetId) targetLength = target.content.length // must have content property! } if (target.id[1] + targetLength > targetId[1] + length) { // ends to the right of the deletion range - target = yield* this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1]) + target = yield * this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1]) targetLength = target.content.length } } @@ -161,35 +161,35 @@ module.exports = function (Y/* :any */) { // delete containing lists if (target.start != null) { // TODO: don't do it like this .. -.- - yield* this.deleteList(target.start) + yield * this.deleteList(target.start) // yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced } if (target.map != null) { for (var name in target.map) { - yield* this.deleteList(target.map[name]) + yield * this.deleteList(target.map[name]) } // TODO: here to.. (see above) // yield* this.deleteList(target.id) -- see above } if (target.opContent != null) { - yield* this.deleteOperation(target.opContent) + yield * this.deleteOperation(target.opContent) // target.opContent = null } if (target.requires != null) { for (var i = 0; i < target.requires.length; i++) { - yield* this.deleteOperation(target.requires[i]) + yield * this.deleteOperation(target.requires[i]) } } } var left if (target.left != null) { - left = yield* this.getInsertion(target.left) + left = yield * this.getInsertion(target.left) } else { left = null } // set here because it was deleted and/or gc'd - yield* this.setOperation(target) + yield * this.setOperation(target) /* Check if it is possible to add right to the gc. @@ -198,12 +198,12 @@ module.exports = function (Y/* :any */) { */ var right if (target.right != null) { - right = yield* this.getOperation(target.right) + right = yield * this.getOperation(target.right) } else { right = null } if (callType && !preventCallType) { - yield* this.store.operationAdded(this, { + yield * this.store.operationAdded(this, { struct: 'Delete', target: target.id, length: targetLength, @@ -211,9 +211,9 @@ module.exports = function (Y/* :any */) { }) } // need to gc in the end! - yield* this.store.addToGarbageCollector.call(this, target, left) + yield * this.store.addToGarbageCollector.call(this, target, left) if (right != null) { - yield* this.store.addToGarbageCollector.call(this, right, target) + yield * this.store.addToGarbageCollector.call(this, right, target) } } } @@ -224,22 +224,22 @@ module.exports = function (Y/* :any */) { * markGarbageCollected (id, len) { // this.mem.push(["gc", id]); this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')') - var n = yield* this.markDeleted(id, len) + var n = yield * this.markDeleted(id, len) if (n.id[1] < id[1] && !n.gc) { // un-extend left var newlen = n.len - (id[1] - n.id[1]) n.len -= newlen - yield* this.ds.put(n) + yield * this.ds.put(n) n = {id: id, len: newlen, gc: false} - yield* this.ds.put(n) + yield * this.ds.put(n) } // get prev&next before adding a new operation - var prev = yield* this.ds.findPrev(id) - var next = yield* this.ds.findNext(id) + var prev = yield * this.ds.findPrev(id) + var next = yield * this.ds.findNext(id) if (id[1] + len < n.id[1] + n.len && !n.gc) { // un-extend right - yield* this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false}) + yield * this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false}) n.len = len } // set gc'd @@ -251,7 +251,7 @@ module.exports = function (Y/* :any */) { Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id) ) { prev.len += n.len - yield* this.ds.delete(n.id) + yield * this.ds.delete(n.id) n = prev // ds.put n here? } @@ -262,10 +262,10 @@ module.exports = function (Y/* :any */) { Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id) ) { n.len += next.len - yield* this.ds.delete(next.id) + yield * this.ds.delete(next.id) } - yield* this.ds.put(n) - yield* this.updateState(n.id[0]) + yield * this.ds.put(n) + yield * this.updateState(n.id[0]) } /* Mark an operation as deleted. @@ -277,7 +277,7 @@ module.exports = function (Y/* :any */) { length = 1 } // this.mem.push(["del", id]); - var n = yield* this.ds.findWithUpperBound(id) + var n = yield * this.ds.findWithUpperBound(id) if (n != null && n.id[0] === id[0]) { if (n.id[1] <= id[1] && id[1] <= n.id[1] + n.len) { // id is in n's range @@ -291,7 +291,7 @@ module.exports = function (Y/* :any */) { if (diff < length) { // a partial deletion n = {id: [id[0], id[1] + diff], len: length - diff, gc: false} - yield* this.ds.put(n) + yield * this.ds.put(n) } else { // already gc'd throw new Error('Cannot happen! (it dit though.. :()') @@ -305,15 +305,15 @@ module.exports = function (Y/* :any */) { } else { // cannot extend left (there is no left!) n = {id: id, len: length, gc: false} - yield* this.ds.put(n) // TODO: you double-put !! + yield * this.ds.put(n) // TODO: you double-put !! } } else { // cannot extend left n = {id: id, len: length, gc: false} - yield* this.ds.put(n) + yield * this.ds.put(n) } // can extend right? - var next = yield* this.ds.findNext(n.id) + var next = yield * this.ds.findNext(n.id) if ( next != null && n.id[0] === next.id[0] && @@ -329,8 +329,8 @@ module.exports = function (Y/* :any */) { // delete the missing range after next diff = diff - next.len // missing range after next if (diff > 0) { - yield* this.ds.put(n) // unneccessary? TODO! - yield* this.markDeleted([next.id[0], next.id[1] + next.len], diff) + yield * this.ds.put(n) // unneccessary? TODO! + yield * this.markDeleted([next.id[0], next.id[1] + next.len], diff) } } break @@ -339,8 +339,8 @@ module.exports = function (Y/* :any */) { if (diff > next.len) { // n is even longer than next // get next.next, and try to extend it - var _next = yield* this.ds.findNext(next.id) - yield* this.ds.delete(next.id) + var _next = yield * this.ds.findNext(next.id) + yield * this.ds.delete(next.id) if (_next == null || n.id[0] !== _next.id[0]) { break } else { @@ -351,13 +351,13 @@ module.exports = function (Y/* :any */) { } else { // n just partially overlaps with next. extend n, delete next, and break this loop n.len += next.len - diff - yield* this.ds.delete(next.id) + yield * this.ds.delete(next.id) break } } } } - yield* this.ds.put(n) + yield * this.ds.put(n) return n } /* @@ -372,28 +372,28 @@ module.exports = function (Y/* :any */) { if (!this.store.gc) { return } - yield* this.os.iterate(this, null, null, function * (op) { + yield * this.os.iterate(this, null, null, function * (op) { if (op.gc) { delete op.gc - yield* this.setOperation(op) + yield * this.setOperation(op) } if (op.parent != null) { - var parentDeleted = yield* this.isDeleted(op.parent) + var parentDeleted = yield * this.isDeleted(op.parent) if (parentDeleted) { op.gc = true if (!op.deleted) { - yield* this.markDeleted(op.id, op.content != null ? op.content.length : 1) + yield * this.markDeleted(op.id, op.content != null ? op.content.length : 1) op.deleted = true if (op.opContent != null) { - yield* this.deleteOperation(op.opContent) + yield * this.deleteOperation(op.opContent) } if (op.requires != null) { for (var i = 0; i < op.requires.length; i++) { - yield* this.deleteOperation(op.requires[i]) + yield * this.deleteOperation(op.requires[i]) } } } - yield* this.setOperation(op) + yield * this.setOperation(op) this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!) return } @@ -401,9 +401,9 @@ module.exports = function (Y/* :any */) { if (op.deleted) { var left = null if (op.left != null) { - left = yield* this.getInsertion(op.left) + left = yield * this.getInsertion(op.left) } - yield* this.store.addToGarbageCollector.call(this, op, left) + yield * this.store.addToGarbageCollector.call(this, op, left) } }) } @@ -418,8 +418,8 @@ module.exports = function (Y/* :any */) { */ * garbageCollectOperation (id) { this.store.addToDebug('yield* this.garbageCollectOperation(', id, ')') - var o = yield* this.getOperation(id) - yield* this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd + var o = yield * this.getOperation(id) + yield * this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd // if op exists, then clean that mess up.. if (o != null) { var deps = [] @@ -430,32 +430,32 @@ module.exports = function (Y/* :any */) { deps = deps.concat(o.requires) } for (var i = 0; i < deps.length; i++) { - var dep = yield* this.getOperation(deps[i]) + var dep = yield * this.getOperation(deps[i]) if (dep != null) { if (!dep.deleted) { - yield* this.deleteOperation(dep.id) - dep = yield* this.getOperation(dep.id) + yield * this.deleteOperation(dep.id) + dep = yield * this.getOperation(dep.id) } dep.gc = true - yield* this.setOperation(dep) + yield * this.setOperation(dep) this.store.queueGarbageCollector(dep.id) } else { - yield* this.markGarbageCollected(deps[i], 1) + yield * this.markGarbageCollected(deps[i], 1) } } // remove gc'd op from the left op, if it exists if (o.left != null) { - var left = yield* this.getInsertion(o.left) + var left = yield * this.getInsertion(o.left) left.right = o.right - yield* this.setOperation(left) + yield * this.setOperation(left) } // remove gc'd op from the right op, if it exists // also reset origins of right ops if (o.right != null) { - var right = yield* this.getOperation(o.right) + var right = yield * this.getOperation(o.right) right.left = o.left - yield* this.setOperation(right) + yield * this.setOperation(right) if (o.originOf != null && o.originOf.length > 0) { // find new origin of right ops @@ -463,7 +463,7 @@ module.exports = function (Y/* :any */) { var neworigin = o.left var neworigin_ = null while (neworigin != null) { - neworigin_ = yield* this.getInsertion(neworigin) + neworigin_ = yield * this.getInsertion(neworigin) if (neworigin_.deleted) { break } @@ -506,10 +506,10 @@ module.exports = function (Y/* :any */) { // ** Now the new implementation starts ** // reset neworigin of all originOf[*] for (var _i in o.originOf) { - var originsIn = yield* this.getOperation(o.originOf[_i]) + var originsIn = yield * this.getOperation(o.originOf[_i]) if (originsIn != null) { originsIn.origin = neworigin - yield* this.setOperation(originsIn) + yield * this.setOperation(originsIn) } } if (neworigin != null) { @@ -518,7 +518,7 @@ module.exports = function (Y/* :any */) { } else { neworigin_.originOf = o.originOf.concat(neworigin_.originOf) } - yield* this.setOperation(neworigin_) + yield * this.setOperation(neworigin_) } // we don't need to set right here, because // right should be in o.originOf => it is set it the previous for loop @@ -527,15 +527,15 @@ module.exports = function (Y/* :any */) { // o may originate in another operation. // Since o is deleted, we have to reset o.origin's `originOf` property if (o.origin != null) { - var origin = yield* this.getInsertion(o.origin) + var origin = yield * this.getInsertion(o.origin) origin.originOf = origin.originOf.filter(function (_id) { return !Y.utils.compareIds(id, _id) }) - yield* this.setOperation(origin) + yield * this.setOperation(origin) } var parent if (o.parent != null) { - parent = yield* this.getOperation(o.parent) + parent = yield * this.getOperation(o.parent) } // remove gc'd op from parent, if it exists if (parent != null) { @@ -562,32 +562,32 @@ module.exports = function (Y/* :any */) { } } if (setParent) { - yield* this.setOperation(parent) + yield * this.setOperation(parent) } } // finally remove it from the os - yield* this.removeOperation(o.id) + yield * this.removeOperation(o.id) } } * checkDeleteStoreForState (state) { - var n = yield* this.ds.findWithUpperBound([state.user, state.clock]) + var n = yield * this.ds.findWithUpperBound([state.user, state.clock]) if (n != null && n.id[0] === state.user && n.gc) { state.clock = Math.max(state.clock, n.id[1] + n.len) } } * updateState (user) { - var state = yield* this.getState(user) - yield* this.checkDeleteStoreForState(state) - var o = yield* this.getInsertion([user, state.clock]) + var state = yield * this.getState(user) + yield * this.checkDeleteStoreForState(state) + var o = yield * this.getInsertion([user, state.clock]) var oLength = (o != null && o.content != null) ? o.content.length : 1 while (o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock) { // either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS state.clock += oLength - yield* this.checkDeleteStoreForState(state) - o = yield* this.os.findNext(o.id) + yield * this.checkDeleteStoreForState(state) + o = yield * this.os.findNext(o.id) oLength = (o != null && o.content != null) ? o.content.length : 1 } - yield* this.setState(state) + yield * this.setState(state) } /* apply a delete set in order to get @@ -600,7 +600,7 @@ module.exports = function (Y/* :any */) { var dv = ds[user] var pos = 0 var d = dv[pos] - yield* this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) { + yield * this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) { // cases: // 1. d deletes something to the right of n // => go to next n (break) @@ -649,14 +649,14 @@ module.exports = function (Y/* :any */) { for (var i = 0; i < deletions.length; i++) { var del = deletions[i] // always try to delete.. - yield* this.deleteOperation([del[0], del[1]], del[2]) + yield * this.deleteOperation([del[0], del[1]], del[2]) if (del[3]) { // gc.. - yield* this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd + yield * this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd // remove operation.. var counter = del[1] + del[2] while (counter >= del[1]) { - var o = yield* this.os.findWithUpperBound([del[0], counter - 1]) + var o = yield * this.os.findWithUpperBound([del[0], counter - 1]) if (o == null) { break } @@ -667,14 +667,14 @@ module.exports = function (Y/* :any */) { } if (o.id[1] + oLen > del[1] + del[2]) { // overlaps right - o = yield* this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1]) + o = yield * this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1]) } if (o.id[1] < del[1]) { // overlaps left - o = yield* this.getInsertionCleanStart([del[0], del[1]]) + o = yield * this.getInsertionCleanStart([del[0], del[1]]) } counter = o.id[1] - yield* this.garbageCollectOperation(o.id) + yield * this.garbageCollectOperation(o.id) } } if (this.store.forwardAppliedOperations) { @@ -685,7 +685,7 @@ module.exports = function (Y/* :any */) { } } * isGarbageCollected (id) { - var n = yield* this.ds.findWithUpperBound(id) + var n = yield * this.ds.findWithUpperBound(id) return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc } /* @@ -693,7 +693,7 @@ module.exports = function (Y/* :any */) { */ * getDeleteSet () { var ds = {} - yield* this.ds.iterate(this, null, null, function * (n) { + yield * this.ds.iterate(this, null, null, function * (n) { var user = n.id[0] var counter = n.id[1] var len = n.len @@ -708,15 +708,15 @@ module.exports = function (Y/* :any */) { return ds } * isDeleted (id) { - var n = yield* this.ds.findWithUpperBound(id) + var n = yield * this.ds.findWithUpperBound(id) return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len } * setOperation (op) { - yield* this.os.put(op) + yield * this.os.put(op) return op } * addOperation (op) { - yield* this.os.put(op) + yield * this.os.put(op) if (this.store.y.connector.isSynced && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') { // is connected, and this is not going to be send in addOperation this.store.y.connector.broadcastOps([op]) @@ -731,7 +731,7 @@ module.exports = function (Y/* :any */) { op.left[0] === op.id[0] && Y.utils.compareIds(op.left, op.origin) ) { - var left = yield* this.getInsertion(op.left) + var left = yield * this.getInsertion(op.left) if (left.content != null && left.id[1] + left.content.length === op.id[1] && left.originOf.length === 1 && @@ -746,13 +746,13 @@ module.exports = function (Y/* :any */) { } left.content = left.content.concat(op.content) left.right = op.right - yield* this.os.delete(op.id) - yield* this.setOperation(left) + yield * this.os.delete(op.id) + yield * this.setOperation(left) } } } * getInsertion (id) { - var ins = yield* this.os.findWithUpperBound(id) + var ins = yield * this.os.findWithUpperBound(id) if (ins == null) { return null } else { @@ -765,13 +765,13 @@ module.exports = function (Y/* :any */) { } } * getInsertionCleanStartEnd (id) { - yield* this.getInsertionCleanStart(id) - return yield* this.getInsertionCleanEnd(id) + yield * this.getInsertionCleanStart(id) + return yield * this.getInsertionCleanEnd(id) } // Return an insertion such that id is the first element of content // This function manipulates an operation, if necessary * getInsertionCleanStart (id) { - var ins = yield* this.getInsertion(id) + var ins = yield * this.getInsertion(id) if (ins != null) { if (ins.id[1] === id[1]) { return ins @@ -785,8 +785,8 @@ module.exports = function (Y/* :any */) { left.right = ins.id ins.left = leftLid // debugger // check - yield* this.setOperation(left) - yield* this.setOperation(ins) + yield * this.setOperation(left) + yield * this.setOperation(ins) if (left.gc) { this.store.queueGarbageCollector(ins.id) } @@ -799,7 +799,7 @@ module.exports = function (Y/* :any */) { // Return an insertion such that id is the last element of content // This function manipulates an operation, if necessary * getInsertionCleanEnd (id) { - var ins = yield* this.getInsertion(id) + var ins = yield * this.getInsertion(id) if (ins != null) { if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) { return ins @@ -813,8 +813,8 @@ module.exports = function (Y/* :any */) { ins.right = right.id right.left = insLid // debugger // check - yield* this.setOperation(right) - yield* this.setOperation(ins) + yield * this.setOperation(right) + yield * this.setOperation(ins) if (ins.gc) { this.store.queueGarbageCollector(right.id) } @@ -825,7 +825,7 @@ module.exports = function (Y/* :any */) { } } * getOperation (id/* :any */)/* :Transaction */ { - var o = yield* this.os.find(id) + var o = yield * this.os.find(id) if (id[0] !== '_' || o != null) { return o } else { // type is string @@ -835,7 +835,7 @@ module.exports = function (Y/* :any */) { var struct = comp[0] var op = Y.Struct[struct].create(id) op.type = comp[1] - yield* this.setOperation(op) + yield * this.setOperation(op) return op } else { // won't be called. but just in case.. @@ -846,17 +846,17 @@ module.exports = function (Y/* :any */) { } } * removeOperation (id) { - yield* this.os.delete(id) + yield * this.os.delete(id) } * setState (state) { var val = { id: [state.user], clock: state.clock } - yield* this.ss.put(val) + yield * this.ss.put(val) } * getState (user) { - var n = yield* this.ss.find([user]) + var n = yield * this.ss.find([user]) var clock = n == null ? null : n.clock if (clock == null) { clock = 0 @@ -868,7 +868,7 @@ module.exports = function (Y/* :any */) { } * getStateVector () { var stateVector = [] - yield* this.ss.iterate(this, null, null, function * (n) { + yield * this.ss.iterate(this, null, null, function * (n) { stateVector.push({ user: n.id[0], clock: n.clock @@ -878,7 +878,7 @@ module.exports = function (Y/* :any */) { } * getStateSet () { var ss = {} - yield* this.ss.iterate(this, null, null, function * (n) { + yield * this.ss.iterate(this, null, null, function * (n) { ss[n.id[0]] = n.clock }) return ss @@ -936,7 +936,7 @@ module.exports = function (Y/* :any */) { } var send = [] - var endSV = yield* this.getStateVector() + var endSV = yield * this.getStateVector() for (var endState of endSV) { var user = endState.user if (user === '_') { @@ -946,14 +946,14 @@ module.exports = function (Y/* :any */) { if (startPos > 0) { // There is a change that [user, startPos] is in a composed Insertion (with a smaller counter) // find out if that is the case - var firstMissing = yield* this.getInsertion([user, startPos]) + var firstMissing = yield * this.getInsertion([user, startPos]) if (firstMissing != null) { // update startPos startPos = firstMissing.id[1] startSS[user] = startPos } } - yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) { + yield * this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) { op = Y.Struct[op.struct].encode(op) if (op.struct !== 'Insert') { send.push(op) @@ -966,7 +966,7 @@ module.exports = function (Y/* :any */) { // 2. or to the first operation that has an origin that is not to the // right of op. // For this we maintain a list of ops which origins are not found yet. - var missing_origins = [op] + var missingOrigins = [op] var newright = op.right while (true) { if (o.left == null) { @@ -974,15 +974,15 @@ module.exports = function (Y/* :any */) { send.push(op) if (!Y.utils.compareIds(o.id, op.id)) { o = Y.Struct[op.struct].encode(o) - o.right = missing_origins[missing_origins.length - 1].id + o.right = missingOrigins[missingOrigins.length - 1].id send.push(o) } break } - o = yield* this.getInsertion(o.left) - // we set another o, check if we can reduce $missing_origins - while (missing_origins.length > 0 && Y.utils.matchesId(o, missing_origins[missing_origins.length - 1].origin)) { - missing_origins.pop() + o = yield * this.getInsertion(o.left) + // we set another o, check if we can reduce $missingOrigins + while (missingOrigins.length > 0 && Y.utils.matchesId(o, missingOrigins[missingOrigins.length - 1].origin)) { + missingOrigins.pop() } if (o.id[1] < (startSS[o.id[0]] || 0)) { // case 2. o is known @@ -995,17 +995,17 @@ module.exports = function (Y/* :any */) { send.push(op) op = Y.Struct[op.struct].encode(o) op.right = newright - if (missing_origins.length > 0) { + if (missingOrigins.length > 0) { console.log('This should not happen .. :( please report this') } - missing_origins = [op] + missingOrigins = [op] } else { // case 4. send o, continue to find op.origin var s = Y.Struct[op.struct].encode(o) - s.right = missing_origins[missing_origins.length - 1].id + s.right = missingOrigins[missingOrigins.length - 1].id s.left = s.origin send.push(s) - missing_origins.push(o) + missingOrigins.push(o) } } } @@ -1020,7 +1020,7 @@ module.exports = function (Y/* :any */) { */ * getOperationsUntransformed () { var ops = [] - yield* this.os.iterate(this, null, null, function * (op) { + yield * this.os.iterate(this, null, null, function * (op) { if (op.id[0] !== '_') { ops.push(op) } @@ -1039,25 +1039,25 @@ module.exports = function (Y/* :any */) { // update parents .map/start/end properties if (op.parentSub != null && op.left == null) { // op is child of Map - let parent = yield* this.getOperation(op.parent) + let parent = yield * this.getOperation(op.parent) parent.map[op.parentSub] = op.id - yield* this.setOperation(parent) + yield * this.setOperation(parent) } else if (op.right == null || op.left == null) { - let parent = yield* this.getOperation(op.parent) + let parent = yield * this.getOperation(op.parent) if (op.right == null) { parent.end = Y.utils.getLastId(op) } if (op.left == null) { parent.start = op.id } - yield* this.setOperation(parent) + yield * this.setOperation(parent) } } } - yield* this.os.put(op) + yield * this.os.put(op) } for (var user in stateSet) { - yield* this.ss.put({ + yield * this.ss.put({ id: [user], clock: stateSet[user] }) @@ -1089,9 +1089,9 @@ module.exports = function (Y/* :any */) { } */ * flush () { - yield* this.os.flush() - yield* this.ss.flush() - yield* this.ds.flush() + yield * this.os.flush() + yield * this.ss.flush() + yield * this.ds.flush() } } Y.Transaction = TransactionInterface diff --git a/src/Utils.js b/src/Utils.js index 18467db8..9e8a2aff 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,6 +1,3 @@ -/* @flow */ -'use strict' - /* EventHandler is an helper class for constructing custom types. @@ -23,7 +20,8 @@ database request to finish). EventHandler helps you to make your type synchronous. */ -module.exports = function (Y /* : any*/) { + +export default function Utils (Y) { Y.utils = {} Y.utils.bubbleEvent = function (type, event) { @@ -299,7 +297,7 @@ module.exports = function (Y /* : any*/) { } var before = this.waiting.length // somehow create new operations - yield* f.apply(transaction, args) + yield * f.apply(transaction, args) // remove all appended ops / awaited ops this.waiting.splice(before) if (this.awaiting > 0) this.awaiting-- @@ -309,7 +307,7 @@ module.exports = function (Y /* : any*/) { for (let i = 0; i < this.waiting.length; i++) { var o = this.waiting[i] if (o.struct === 'Insert') { - var _o = yield* transaction.getInsertion(o.id) + var _o = yield * transaction.getInsertion(o.id) if (_o.parentSub != null && _o.left != null) { // if o is an insertion of a map struc (parentSub is defined), then it shouldn't be necessary to compute left this.waiting.splice(i, 1) @@ -321,10 +319,10 @@ module.exports = function (Y /* : any*/) { o.left = null } else { // find next undeleted op - var left = yield* transaction.getInsertion(_o.left) + var left = yield * transaction.getInsertion(_o.left) while (left.deleted != null) { if (left.left != null) { - left = yield* transaction.getInsertion(left.left) + left = yield * transaction.getInsertion(left.left) } else { left = null break @@ -662,7 +660,7 @@ module.exports = function (Y /* : any*/) { if (i < 0 && noSuperCall === undefined) { // did not reach break in last loop // read id and put it to the end of readBuffer - o = yield* super.find(id) + o = yield * super.find(id) } if (o != null) { for (i = 0; i < this.readBuffer.length - 1; i++) { @@ -692,7 +690,7 @@ module.exports = function (Y /* : any*/) { // write writeBuffer[0] var write = this.writeBuffer[0] if (write.id[0] !== null) { - yield* super.put(write) + yield * super.put(write) } // put o to the end of writeBuffer for (i = 0; i < this.writeBuffer.length - 1; i++) { @@ -722,44 +720,44 @@ module.exports = function (Y /* : any*/) { } } } - yield* this.flush() - yield* super.delete(id) + yield * this.flush() + yield * super.delete(id) } * findWithLowerBound (id) { - var o = yield* this.find(id, true) + var o = yield * this.find(id, true) if (o != null) { return o } else { - yield* this.flush() - return yield* super.findWithLowerBound.apply(this, arguments) + yield * this.flush() + return yield * super.findWithLowerBound.apply(this, arguments) } } * findWithUpperBound (id) { - var o = yield* this.find(id, true) + var o = yield * this.find(id, true) if (o != null) { return o } else { - yield* this.flush() - return yield* super.findWithUpperBound.apply(this, arguments) + yield * this.flush() + return yield * super.findWithUpperBound.apply(this, arguments) } } * findNext () { - yield* this.flush() - return yield* super.findNext.apply(this, arguments) + yield * this.flush() + return yield * super.findNext.apply(this, arguments) } * findPrev () { - yield* this.flush() - return yield* super.findPrev.apply(this, arguments) + yield * this.flush() + return yield * super.findPrev.apply(this, arguments) } * iterate () { - yield* this.flush() - yield* super.iterate.apply(this, arguments) + yield * this.flush() + yield * super.iterate.apply(this, arguments) } * flush () { for (var i = 0; i < this.writeBuffer.length; i++) { var write = this.writeBuffer[i] if (write.id[0] !== null) { - yield* super.put(write) + yield * super.put(write) this.writeBuffer[i] = { id: [null, null] } diff --git a/src/y.js b/src/y.js index 7b828d97..b96acc09 100644 --- a/src/y.js +++ b/src/y.js @@ -1,18 +1,20 @@ -/* @flow */ -'use strict' +import debug from 'debug' +import extendConnector from './Connector.js' +import extendDatabase from './Database.js' +import extendTransaction from './Transaction.js' +import extendStruct from './Struct.js' +import extendUtils from './Utils.js' -require('./Connector.js')(Y) -require('./Database.js')(Y) -require('./Transaction.js')(Y) -require('./Struct.js')(Y) -require('./Utils.js')(Y) -require('./Connectors/Test.js')(Y) +extendConnector(Y) +extendDatabase(Y) +extendTransaction(Y) +extendStruct(Y) +extendUtils(Y) -Y.debug = require('debug') +Y.debug = debug var requiringModules = {} -module.exports = Y Y.requiringModules = requiringModules Y.extend = function (name, value) { @@ -110,7 +112,7 @@ type YOptions = { } */ -function Y (opts/* :YOptions */) /* :Promise */ { +export default function Y (opts/* :YOptions */) /* :Promise */ { if (opts.hasOwnProperty('sourceDir')) { Y.sourceDir = opts.sourceDir } @@ -120,11 +122,11 @@ function Y (opts/* :YOptions */) /* :Promise */ { modules.push(opts.share[name]) } return new Promise(function (resolve, reject) { - if (opts == null) reject('An options object is expected! ') - else if (opts.connector == null) reject('You must specify a connector! (missing connector property)') - else if (opts.connector.name == null) reject('You must specify connector name! (missing connector.name property)') - else if (opts.db == null) reject('You must specify a database! (missing db property)') - else if (opts.connector.name == null) reject('You must specify db name! (missing db.name property)') + if (opts == null) reject(new Error('An options object is expected!')) + else if (opts.connector == null) reject(new Error('You must specify a connector! (missing connector property)')) + else if (opts.connector.name == null) reject(new Error('You must specify connector name! (missing connector.name property)')) + else if (opts.db == null) reject(new Error('You must specify a database! (missing db property)')) + else if (opts.connector.name == null) reject(new Error('You must specify db name! (missing db.name property)')) else { opts = Y.utils.copyObject(opts) opts.connector = Y.utils.copyObject(opts.connector) @@ -182,7 +184,7 @@ class YConfig { args = typedef.parseArguments(args[0])[1] } } - share[propertyname] = yield* this.store.initType.call(this, id, args) + share[propertyname] = yield * this.store.initType.call(this, id, args) } this.store.whenTransactionsFinished() .then(callback) @@ -229,7 +231,7 @@ class YConfig { this.db.destroyTypes() // make sure to wait for all transactions before destroying the db this.db.requestTransaction(function * () { - yield* self.db.destroy() + yield * self.db.destroy() }) return this.db.whenTransactionsFinished() })