diff --git a/src/Struct.js b/src/Struct.js index 48671fa6aa3a78fd1f2f5dcdaaf770e87a8d0543..0ea0dd132a593c530ad6074b2f4120e0ebca1ac2 100644 --- a/src/Struct.js +++ b/src/Struct.js @@ -237,6 +237,14 @@ module.exports = function (Y/* :any */) { id: this.os.getNextOpId() } */ + create: function (id) { + return { + start: null, + end: null, + struct: 'List', + id: id + } + }, encode: function (op) { return { struct: 'List', @@ -303,6 +311,13 @@ module.exports = function (Y/* :any */) { id: this.os.getNextOpId() } */ + create: function (id) { + return { + id: id, + map: {}, + struct: 'Map' + } + }, encode: function (op) { return { struct: 'Map', diff --git a/src/Transaction.js b/src/Transaction.js index 57e14fed39c545d79f3fb1f7165321c2953b2ee6..68533c1e0a5caa10416ed1fe966e0683e5ea47a7 100644 --- a/src/Transaction.js +++ b/src/Transaction.js @@ -99,6 +99,14 @@ module.exports = function (Y/* :any */) { } return t } + * createType (typedefinition) { + var structname = typedefinition.struct + var id = this.store.getNextOpId() + var op = Y.Struct[structname].create(id) + op.type = typedefinition.name + yield* this.applyCreatedOperations([op]) + return yield* this.getType(id) + } /* Apply operations that this user created (no remote ones!) * does not check for Struct.*.requiredOps() @@ -109,9 +117,11 @@ module.exports = function (Y/* :any */) { for (var i = 0; i < ops.length; i++) { var op = ops[i] yield* this.store.tryExecute.call(this, op) - send.push(Y.Struct[op.struct].encode(op)) + if (op.id == null || op.id[0] !== '_') { + send.push(Y.Struct[op.struct].encode(op)) + } } - if (!this.store.y.connector.isDisconnected()) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops) + if (!this.store.y.connector.isDisconnected() && send.length > 0) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops) // is connected, and this is not going to be send in addOperation this.store.y.connector.broadcast({ type: 'update', @@ -565,11 +575,12 @@ module.exports = function (Y/* :any */) { } else { // need to generate this operation if (this.store._nextUserId == null) { - var typename = id[1].split('_')[0] - this.store._nextUserId = id - yield* Y[typename].createType.call(this) - delete this.store._nextUserId - return yield* this.os.find(id) + var struct = id[1].split('_')[0] + // this.store._nextUserId = id + var op = Y.Struct[struct].create(id) + yield* this.setOperation(op) + // delete this.store._nextUserId + return op } else { // Can only generate one operation at a time return null diff --git a/src/Utils.js b/src/Utils.js index e02b403d7271b514b1b9d1c601a5edd58fd24bb1..8cea17d7f016bd0c4488d55301fa3e0df33d39e7 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -160,8 +160,8 @@ module.exports = function (Y /* : any*/) { A wrapper for the definition of a custom type. Every custom type must have three properties: - * createType - - Defines the model of a newly created custom type and returns the type + * struct + - Structname of this type * initType - Given a model, creates a custom type * class @@ -169,20 +169,23 @@ module.exports = function (Y /* : any*/) { */ class CustomType { // eslint-disable-line /* :: - createType: any; + struct: any; initType: any; class: Function; + name: String; */ constructor (def) { - if (def.createType == null || + if (def.struct == null || def.initType == null || - def.class == null + def.class == null || + def.name == null ) { throw new Error('Custom type was not initialized correctly!') } - this.createType = def.createType + this.struct = def.struct this.initType = def.initType this.class = def.class + this.name = def.name } } Y.utils.CustomType = CustomType diff --git a/src/y.js b/src/y.js index 17b5595bb009e846d881400de0e615420fb0ecc3..90c6ed18a6dc5a5be2efe33dec2ff0aa0b36b13d 100644 --- a/src/y.js +++ b/src/y.js @@ -115,7 +115,15 @@ class YConfig { this.db.requestTransaction(function * requestTransaction () { // create shared object for (var propertyname in opts.share) { - share[propertyname] = yield* this.getType(['_', opts.share[propertyname] + '_' + propertyname]) + var typename = opts.share[propertyname] + var id = ['_', Y[typename].struct + '_' + propertyname] + var op = yield* this.getOperation(id) + if (op.type !== typename) { + // not already in the db + op.type = typename + yield* this.setOperation(op) + } + share[propertyname] = yield* this.getType(id) } setTimeout(callback, 0) })