diff --git a/package-lock.json b/package-lock.json index 21962489..e216c9ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1032,6 +1032,12 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true }, + "ez-async": { + "version": "1.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/ez-async/-/ez-async-1.0.0-alpha.1.tgz", + "integrity": "sha1-ysNCuPqJAm7+c6Jg/p9rgE9J5H8=", + "dev": true + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -2930,6 +2936,12 @@ } } }, + "tag-dist-files": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/tag-dist-files/-/tag-dist-files-0.1.6.tgz", + "integrity": "sha1-h64FrBQw1H2m76Hrx7Bw+QxnTVQ=", + "dev": true + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", diff --git a/package.json b/package.json index 2dbea11e..98c29d86 100644 --- a/package.json +++ b/package.json @@ -6,16 +6,17 @@ "scripts": { "lint": "standard", "dist": "rollup -c rollup.dist.js", - "serve": "concurrently 'serve ..' 'rollup -wc rollup.dist.js -o examples/bower_components/yjs/y.js'" + "serve": "concurrently 'serve ..' 'rollup -wc rollup.dist.js -o examples/bower_components/yjs/y.js'", + "postversion": "npm run lint && npm run dist", + "postpublish": "tag-dist-files --overwrite-existing-tag" }, - "pre-commit": [ - "lint", - "test" + "files": [ + "y.*" ], "standard": { "ignore": [ - "./y.js", - "./y.js.map" + "/y.js", + "/y.js.map" ] }, "repository": { @@ -40,10 +41,10 @@ "homepage": "http://y-js.org", "devDependencies": { "babel-cli": "^6.24.1", - "babel-preset-latest": "^6.24.1", "babel-plugin-external-helpers": "^6.22.0", "babel-plugin-transform-regenerator": "^6.24.1", "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-latest": "^6.24.1", "chance": "^1.0.9", "concurrently": "^3.4.0", "rollup-plugin-babel": "^2.7.1", @@ -54,7 +55,8 @@ "rollup-plugin-uglify": "^1.0.2", "rollup-regenerator-runtime": "^6.23.1", "rollup-watch": "^3.2.2", - "standard": "^10.0.2" + "standard": "^10.0.2", + "tag-dist-files": "^0.1.6" }, "dependencies": { "debug": "^2.6.8" diff --git a/src/Database.js b/src/Database.js index f529c2ab..956a831d 100644 --- a/src/Database.js +++ b/src/Database.js @@ -401,11 +401,11 @@ export default function extendDatabase (Y /* :any */) { whenOperationsExist: any; */ * tryExecute (op) { - this.store.addToDebug('yield* this.store.tryExecute.call(this, ', JSON.stringify(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) // this is now called in Transaction.deleteOperation! - // yield* this.store.operationAdded(this, op) + // yield * this.store.operationAdded(this, op) } else { // check if this op was defined var defined = yield * this.getInsertion(op.id) diff --git a/src/Transaction.js b/src/Transaction.js index 4dd4f1fd..33037084 100644 --- a/src/Transaction.js +++ b/src/Transaction.js @@ -162,14 +162,14 @@ export default function extendTransaction (Y) { if (target.start != null) { // TODO: don't do it like this .. -.- yield * this.deleteList(target.start) - // yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced + // 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]) } // TODO: here to.. (see above) - // yield* this.deleteList(target.id) -- see above + // yield * this.deleteList(target.id) -- see above } if (target.opContent != null) { yield * this.deleteOperation(target.opContent) @@ -223,7 +223,7 @@ export default function extendTransaction (Y) { */ * markGarbageCollected (id, len) { // this.mem.push(["gc", id]); - this.store.addToDebug('yield* this.markGarbageCollected(', id, ', ', len, ')') + this.store.addToDebug('yield * this.markGarbageCollected(', id, ', ', len, ')') var n = yield * this.markDeleted(id, len) if (n.id[1] < id[1] && !n.gc) { // un-extend left @@ -294,8 +294,9 @@ export default function extendTransaction (Y) { yield * this.ds.put(n) } else { // already gc'd - throw new Error('Cannot happen! (it dit though.. :()') - // return n + throw new Error( + 'DS reached an inconsistent state. Please report this issue!' + ) } } } else { @@ -418,7 +419,7 @@ export default function extendTransaction (Y) { * reset origins of all right ops */ * garbageCollectOperation (id) { - this.store.addToDebug('yield* this.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 // if op exists, then clean that mess up.. @@ -475,7 +476,7 @@ export default function extendTransaction (Y) { right.origin = neworigin // search until you find origin pointer to the left of o if (right.right != null) { - var i = yield* this.getOperation(right.right) + var i = yield * this.getOperation(right.right) var ids = [o.id, o.right] while (ids.some(function (id) { return Y.utils.compareIds(id, i.origin) @@ -483,14 +484,14 @@ export default function extendTransaction (Y) { if (Y.utils.compareIds(i.origin, o.id)) { // reset origin of i i.origin = neworigin - yield* this.setOperation(i) + yield * this.setOperation(i) } // get next i if (i.right == null) { break } else { ids.push(i.id) - i = yield* this.getOperation(i.right) + i = yield * this.getOperation(i.right) } } } @@ -1086,7 +1087,7 @@ export default function extendTransaction (Y) { // or the o that has no origin to the right of op // (this is why we use the ids array) while (o.right != null) { - var right = yield* this.getOperation(o.right) + var right = yield * this.getOperation(o.right) if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) { return Y.utils.compareIds(id, right.origin) })) { diff --git a/src/Utils.js b/src/Utils.js index a62caa3c..a8c1b369 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -42,6 +42,32 @@ export default function Utils (Y) { } } + class NamedEventHandler { + constructor () { + this._eventListener = {} + } + on (name, f) { + if (this._eventListener[name] == null) { + this._eventListener[name] = [] + } + this._eventListener[name].push(f) + } + off (name, f) { + if (name == null || f == null) { + throw new Error('You must specify event name and function!') + } + let listener = this._eventListener[name] || [] + this._eventListener[name] = listener.filter(e => e !== f) + } + emit (name, value) { + (this._eventListener[name] || []).forEach(l => l(value)) + } + destroy () { + this._eventListener = null + } + } + Y.utils.NamedEventHandler = NamedEventHandler + class EventListenerHandler { constructor () { this.eventListeners = [] diff --git a/src/y.js b/src/y.js index 4e2b3346..77ce392a 100644 --- a/src/y.js +++ b/src/y.js @@ -144,7 +144,7 @@ export default function Y (opts/* :YOptions */) /* :Promise */ { }) } -class YConfig { +class YConfig extends Y.utils.NamedEventHandler { /* :: db: Y.AbstractDatabase; connector: Y.AbstractConnector; @@ -152,6 +152,7 @@ class YConfig { options: Object; */ constructor (opts, callback) { + super() this.options = opts this.db = new Y[opts.db.name](this, opts.db) this.connector = new Y[opts.connector.name](this, opts.connector) @@ -215,6 +216,9 @@ class YConfig { } else { return Promise.resolve() } + }).then(() => { + // remove existing event listener + super.destroy() }) } close () {