fixing types.
This commit is contained in:
		
							parent
							
								
									f862fae473
								
							
						
					
					
						commit
						9b45a78e58
					
				@ -4,8 +4,22 @@ class AbstractTransaction { //eslint-disable-line no-unused-vars
 | 
				
			|||||||
    this.store = store;
 | 
					    this.store = store;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  *getType (id) {
 | 
					  *getType (id) {
 | 
				
			||||||
    var op = yield* this.getOperation(id);
 | 
					    var sid = JSON.stringify(id);
 | 
				
			||||||
    return new Y[op.type].Create(op);
 | 
					    var t = this.store.initializedTypes[sid];
 | 
				
			||||||
 | 
					    if (t == null) {
 | 
				
			||||||
 | 
					      var op = yield* this.getOperation(id);
 | 
				
			||||||
 | 
					      if (op != null) {
 | 
				
			||||||
 | 
					        t = new Y[op.type].Create(op.id);
 | 
				
			||||||
 | 
					        this.store.initializedTypes[sid] = t;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return t;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  createType (model) {
 | 
				
			||||||
 | 
					    var sid = JSON.stringify(model.id);
 | 
				
			||||||
 | 
					    var t = new Y[model.type].Create(model.id);
 | 
				
			||||||
 | 
					    this.store.initializedTypes[sid] = t;
 | 
				
			||||||
 | 
					    return t;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // returns false if operation is not expected.
 | 
					  // returns false if operation is not expected.
 | 
				
			||||||
  *addOperation (op) {
 | 
					  *addOperation (op) {
 | 
				
			||||||
@ -34,9 +48,6 @@ type Id = [string, number];
 | 
				
			|||||||
class AbstractOperationStore { //eslint-disable-line no-unused-vars
 | 
					class AbstractOperationStore { //eslint-disable-line no-unused-vars
 | 
				
			||||||
  constructor (y) {
 | 
					  constructor (y) {
 | 
				
			||||||
    this.y = y;
 | 
					    this.y = y;
 | 
				
			||||||
    this.parentListeners = {};
 | 
					 | 
				
			||||||
    this.parentListenersRequestPending = false;
 | 
					 | 
				
			||||||
    this.parentListenersActivated = {};
 | 
					 | 
				
			||||||
    // E.g. this.listenersById[id] : Array<Listener>
 | 
					    // E.g. this.listenersById[id] : Array<Listener>
 | 
				
			||||||
    this.listenersById = {};
 | 
					    this.listenersById = {};
 | 
				
			||||||
    // Execute the next time a transaction is requested
 | 
					    // Execute the next time a transaction is requested
 | 
				
			||||||
@ -53,6 +64,9 @@ class AbstractOperationStore { //eslint-disable-line no-unused-vars
 | 
				
			|||||||
      Always remember to first overwrite
 | 
					      Always remember to first overwrite
 | 
				
			||||||
      a property before you iterate over it!
 | 
					      a property before you iterate over it!
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
 | 
					    // TODO: Use ES7 Weak Maps. This way types that are no longer user,
 | 
				
			||||||
 | 
					    // wont be kept in memory.
 | 
				
			||||||
 | 
					    this.initializedTypes = {};
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  setUserId (userId) {
 | 
					  setUserId (userId) {
 | 
				
			||||||
    this.userId = userId;
 | 
					    this.userId = userId;
 | 
				
			||||||
@ -142,32 +156,11 @@ class AbstractOperationStore { //eslint-disable-line no-unused-vars
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // notify parent listeners, if possible
 | 
					    // notify parent, if it has been initialized as a custom type
 | 
				
			||||||
    var listeners = this.parentListeners[op.parent];
 | 
					    var t = this.initializedTypes[JSON.stringify(op.parent)];
 | 
				
			||||||
    if ( this.parentListenersRequestPending
 | 
					    if (t != null) {
 | 
				
			||||||
        || ( listeners == null )
 | 
					      t._changed(op);
 | 
				
			||||||
        || ( listeners.length === 0 )) {
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    var al = this.parentListenersActivated[JSON.stringify(op.parent)];
 | 
					 | 
				
			||||||
    if ( al == null ){
 | 
					 | 
				
			||||||
      al = [];
 | 
					 | 
				
			||||||
      this.parentListenersActivated[JSON.stringify(op.parent)] = al;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    al.push(op);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.parentListenersRequestPending = true;
 | 
					 | 
				
			||||||
    var store = this;
 | 
					 | 
				
			||||||
    this.requestTransaction(function*(){
 | 
					 | 
				
			||||||
      store.parentListenersRequestPending = false;
 | 
					 | 
				
			||||||
      var activatedOperations = store.parentListenersActivated;
 | 
					 | 
				
			||||||
      store.parentListenersActivated = {};
 | 
					 | 
				
			||||||
      for (var parentId in activatedOperations){
 | 
					 | 
				
			||||||
        var parent = yield* this.getOperation(parentId);
 | 
					 | 
				
			||||||
        Struct[parent.struct].notifyObservers(activatedOperations[parentId]);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  removeParentListener (id, f) {
 | 
					  removeParentListener (id, f) {
 | 
				
			||||||
    var ls = this.parentListeners[id];
 | 
					    var ls = this.parentListeners[id];
 | 
				
			||||||
 | 
				
			|||||||
@ -35,12 +35,10 @@ Y.Memory = (function(){ //eslint-disable-line no-unused-vars
 | 
				
			|||||||
      return op;
 | 
					      return op;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *getOperation (id) {
 | 
					    *getOperation (id) {
 | 
				
			||||||
      var op = this.os.find(id);
 | 
					      if (id == null) {
 | 
				
			||||||
      if (op == null) {
 | 
					        throw new Error("You must define id!");
 | 
				
			||||||
        throw new Error("Op does not exist..");
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        return op;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      return this.os.find(id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *removeOperation (id) {
 | 
					    *removeOperation (id) {
 | 
				
			||||||
      this.os.delete(id);
 | 
					      this.os.delete(id);
 | 
				
			||||||
@ -123,13 +121,13 @@ Y.Memory = (function(){ //eslint-disable-line no-unused-vars
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    requestTransaction (makeGen : Function) {
 | 
					    requestTransaction (makeGen : Function) {
 | 
				
			||||||
      var t = new Transaction(this);
 | 
					      var t = new Transaction(this);
 | 
				
			||||||
      var gen = makeGen.call(t, new Y.Map.Create(["_", 0]));
 | 
					      var gen = makeGen.call(t, t.getType(["_", 0]).next().value);
 | 
				
			||||||
      var res = gen.next();
 | 
					      var res = gen.next();
 | 
				
			||||||
      while(!res.done){
 | 
					      while(!res.done){
 | 
				
			||||||
        if (res.value === "transaction") {
 | 
					        if (res.value === "transaction") {
 | 
				
			||||||
          res = gen.next(t);
 | 
					          res = gen.next(t);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          throw new Error("You may not yield this type. (Maybe you meant to use 'yield*'?)");
 | 
					          throw new Error("You must not yield this type. (Maybe you meant to use 'yield*'?)");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -417,9 +417,12 @@ var Struct = {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    get: function* (op, name) {
 | 
					    get: function* (op, name) {
 | 
				
			||||||
      var res = yield* this.getOperation(op.map[name]);
 | 
					      var oid = op.map[name];
 | 
				
			||||||
      return (res == null || res.deleted) ? void 0 : (res.opContent == null
 | 
					      if (oid != null) {
 | 
				
			||||||
                ? res.content : yield* this.getType(res.opContent));
 | 
					        var res = yield* this.getOperation(oid);
 | 
				
			||||||
 | 
					        return (res == null || res.deleted) ? void 0 : (res.opContent == null
 | 
				
			||||||
 | 
					                  ? res.content : yield* this.getType(res.opContent));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    set: function* (op, name, value) {
 | 
					    set: function* (op, name, value) {
 | 
				
			||||||
      var right = op.map[name] || null;
 | 
					      var right = op.map[name] || null;
 | 
				
			||||||
@ -429,19 +432,13 @@ var Struct = {
 | 
				
			|||||||
        parent: op.id,
 | 
					        parent: op.id,
 | 
				
			||||||
        parentSub: name
 | 
					        parentSub: name
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      var oid;
 | 
					 | 
				
			||||||
      if ( value != null && value._model != null
 | 
					      if ( value != null && value._model != null
 | 
				
			||||||
           && (oid = value._model.id) != null && oid.length === 2) {
 | 
					           && value._model.length === 2) {
 | 
				
			||||||
        insert.opContent = oid;
 | 
					        insert.opContent = value._model;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        insert.content = value;
 | 
					        insert.content = value;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      yield* Struct.Insert.create.call(this, insert);
 | 
					      yield* Struct.Insert.create.call(this, insert);
 | 
				
			||||||
      if (right != null) {
 | 
					 | 
				
			||||||
        yield* Struct.Delete.create.call(this, {
 | 
					 | 
				
			||||||
          target: right
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    delete: function* (op, name) {
 | 
					    delete: function* (op, name) {
 | 
				
			||||||
      var v = op.map[name] || null;
 | 
					      var v = op.map[name] || null;
 | 
				
			||||||
 | 
				
			|||||||
@ -8,11 +8,12 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    *val (pos) {
 | 
					    *val (pos) {
 | 
				
			||||||
      var t = yield "transaction";
 | 
					      var t = yield "transaction";
 | 
				
			||||||
 | 
					      var model = yield* t.getOperation(this._model);
 | 
				
			||||||
      if (pos != null) {
 | 
					      if (pos != null) {
 | 
				
			||||||
        var o = yield* Y.Struct.List.ref.call(t, this._model, pos);
 | 
					        var o = yield* Y.Struct.List.ref.call(t, model, pos);
 | 
				
			||||||
        return o ? o.content : null;
 | 
					        return o ? o.content : null;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        return yield* Y.Struct.List.map.call(t, this._model, function(c){return c; });
 | 
					        return yield* Y.Struct.List.map.call(t, model, function(c){return c; });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *insert (pos, contents) {
 | 
					    *insert (pos, contents) {
 | 
				
			||||||
@ -23,21 +24,25 @@
 | 
				
			|||||||
        throw new Error("contents must be an Array of objects!");
 | 
					        throw new Error("contents must be an Array of objects!");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      var t = yield "transaction";
 | 
					      var t = yield "transaction";
 | 
				
			||||||
      yield* Y.Struct.List.insert.call(t, this._model, pos, contents);
 | 
					      var model = yield* t.getOperation(this._model);
 | 
				
			||||||
 | 
					      yield* Y.Struct.List.insert.call(t, model, pos, contents);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *delete (pos) {
 | 
					    *delete (pos) {
 | 
				
			||||||
      if (typeof pos !== "number") {
 | 
					      if (typeof pos !== "number") {
 | 
				
			||||||
        throw new Error("pos must be a number!");
 | 
					        throw new Error("pos must be a number!");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      var t = yield "transaction";
 | 
					      var t = yield "transaction";
 | 
				
			||||||
      yield* Y.Struct.List.delete.call(t, this._model, pos);
 | 
					      var model = yield* t.getOperation(this._model);
 | 
				
			||||||
 | 
					      yield* Y.Struct.List.delete.call(t, model, pos);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _changed () {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Y.List = function* YList(){
 | 
					  Y.List = function* YList(){
 | 
				
			||||||
    var t = yield "transaction";
 | 
					    var t = yield "transaction";
 | 
				
			||||||
    var model = yield* Y.Struct.List.create.call(t, {type: "List"});
 | 
					    var model = yield* Y.Struct.List.create.call(t, {type: "List"});
 | 
				
			||||||
    return new List(model);
 | 
					    return t.createType(model);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  Y.List.Create = List;
 | 
					  Y.List.Create = List;
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
				
			|||||||
@ -29,13 +29,15 @@
 | 
				
			|||||||
      var model = yield* t.getOperation(this._model);
 | 
					      var model = yield* t.getOperation(this._model);
 | 
				
			||||||
      yield* Y.Struct.Map.delete.call(t, model, key);
 | 
					      yield* Y.Struct.Map.delete.call(t, model, key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    _changed () {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Y.Map = function* YMap(){
 | 
					  Y.Map = function* YMap(){
 | 
				
			||||||
    var t = yield "transaction";
 | 
					    var t = yield "transaction";
 | 
				
			||||||
    if (this instanceof Y.AbstractOperationStore) {
 | 
					    if (this instanceof Y.AbstractOperationStore) {
 | 
				
			||||||
      var model = yield* Y.Struct.map.create.call(t, {type: "Map"});
 | 
					      var model = yield* Y.Struct.map.create.call(t, {type: "Map"});
 | 
				
			||||||
      return new Map(model);
 | 
					      return t.createType(model);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      throw new Error("Don't use `new` to create this type!");
 | 
					      throw new Error("Don't use `new` to create this type!");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										7
									
								
								src/y.js
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								src/y.js
									
									
									
									
									
								
							@ -8,11 +8,14 @@ class Y { //eslint-disable-line no-unused-vars
 | 
				
			|||||||
    this.connector = new Y[opts.connector.name](this, opts.connector);
 | 
					    this.connector = new Y[opts.connector.name](this, opts.connector);
 | 
				
			||||||
    this.db.requestTransaction(function*(){
 | 
					    this.db.requestTransaction(function*(){
 | 
				
			||||||
      // create initial Map type
 | 
					      // create initial Map type
 | 
				
			||||||
      yield* this.addOperation({
 | 
					      var model = {
 | 
				
			||||||
        id: ["_", 0],
 | 
					        id: ["_", 0],
 | 
				
			||||||
        struct: "Map",
 | 
					        struct: "Map",
 | 
				
			||||||
 | 
					        type: "Map",
 | 
				
			||||||
        map: {}
 | 
					        map: {}
 | 
				
			||||||
      });
 | 
					      };
 | 
				
			||||||
 | 
					      yield* this.addOperation(model);
 | 
				
			||||||
 | 
					      this.createType(model);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  transact (generator) {
 | 
					  transact (generator) {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,6 @@ function getRandomNumber(n) {
 | 
				
			|||||||
  return Math.floor(Math.random() * n);
 | 
					  return Math.floor(Math.random() * n);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
var numberOfYMapTests = 30;
 | 
					var numberOfYMapTests = 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function applyRandomTransactions (users, transactions, numberOfTransactions) {
 | 
					function applyRandomTransactions (users, transactions, numberOfTransactions) {
 | 
				
			||||||
@ -94,12 +93,30 @@ describe("Yjs", function(){
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe("Basic tests", function(){
 | 
					  describe("Basic tests", function(){
 | 
				
			||||||
    it("There is an initial Map type", function(){
 | 
					    it("There is an initial Map type & it is created only once", function(){
 | 
				
			||||||
      var y = this.users[0];
 | 
					      var y = this.users[0];
 | 
				
			||||||
 | 
					      var root1;
 | 
				
			||||||
      y.transact(function*(root){
 | 
					      y.transact(function*(root){
 | 
				
			||||||
        expect(root).not.toBeUndefined();
 | 
					        expect(root).not.toBeUndefined();
 | 
				
			||||||
 | 
					        root1 = root;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      y.transact(function*(root2){
 | 
				
			||||||
 | 
					        expect(root1).toBe(root2);
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    it("Custom Types are created only once", function(){
 | 
				
			||||||
 | 
					      var y = this.users[0];
 | 
				
			||||||
 | 
					      var l1;
 | 
				
			||||||
 | 
					      y.transact(function*(root){
 | 
				
			||||||
 | 
					        var l = yield* Y.List();
 | 
				
			||||||
 | 
					        yield* root.val("list", l);
 | 
				
			||||||
 | 
					        l1 = l;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      y.transact(function*(root){
 | 
				
			||||||
 | 
					        expect(l1).toBe(yield* root.val("list"));
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it("Basic get&set of Map property (converge via sync)", function(){
 | 
					    it("Basic get&set of Map property (converge via sync)", function(){
 | 
				
			||||||
      var y = this.users[0];
 | 
					      var y = this.users[0];
 | 
				
			||||||
      y.transact(function*(root){
 | 
					      y.transact(function*(root){
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user