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;
|
||||
}
|
||||
*getType (id) {
|
||||
var op = yield* this.getOperation(id);
|
||||
return new Y[op.type].Create(op);
|
||||
var sid = JSON.stringify(id);
|
||||
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.
|
||||
*addOperation (op) {
|
||||
@ -34,9 +48,6 @@ type Id = [string, number];
|
||||
class AbstractOperationStore { //eslint-disable-line no-unused-vars
|
||||
constructor (y) {
|
||||
this.y = y;
|
||||
this.parentListeners = {};
|
||||
this.parentListenersRequestPending = false;
|
||||
this.parentListenersActivated = {};
|
||||
// E.g. this.listenersById[id] : Array<Listener>
|
||||
this.listenersById = {};
|
||||
// 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
|
||||
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) {
|
||||
this.userId = userId;
|
||||
@ -142,32 +156,11 @@ class AbstractOperationStore { //eslint-disable-line no-unused-vars
|
||||
}
|
||||
}
|
||||
}
|
||||
// notify parent listeners, if possible
|
||||
var listeners = this.parentListeners[op.parent];
|
||||
if ( this.parentListenersRequestPending
|
||||
|| ( listeners == null )
|
||||
|| ( listeners.length === 0 )) {
|
||||
return;
|
||||
// notify parent, if it has been initialized as a custom type
|
||||
var t = this.initializedTypes[JSON.stringify(op.parent)];
|
||||
if (t != null) {
|
||||
t._changed(op);
|
||||
}
|
||||
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) {
|
||||
var ls = this.parentListeners[id];
|
||||
|
@ -35,12 +35,10 @@ Y.Memory = (function(){ //eslint-disable-line no-unused-vars
|
||||
return op;
|
||||
}
|
||||
*getOperation (id) {
|
||||
var op = this.os.find(id);
|
||||
if (op == null) {
|
||||
throw new Error("Op does not exist..");
|
||||
} else {
|
||||
return op;
|
||||
if (id == null) {
|
||||
throw new Error("You must define id!");
|
||||
}
|
||||
return this.os.find(id);
|
||||
}
|
||||
*removeOperation (id) {
|
||||
this.os.delete(id);
|
||||
@ -123,13 +121,13 @@ Y.Memory = (function(){ //eslint-disable-line no-unused-vars
|
||||
}
|
||||
requestTransaction (makeGen : Function) {
|
||||
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();
|
||||
while(!res.done){
|
||||
if (res.value === "transaction") {
|
||||
res = gen.next(t);
|
||||
} 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) {
|
||||
var res = yield* this.getOperation(op.map[name]);
|
||||
return (res == null || res.deleted) ? void 0 : (res.opContent == null
|
||||
? res.content : yield* this.getType(res.opContent));
|
||||
var oid = op.map[name];
|
||||
if (oid != null) {
|
||||
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) {
|
||||
var right = op.map[name] || null;
|
||||
@ -429,19 +432,13 @@ var Struct = {
|
||||
parent: op.id,
|
||||
parentSub: name
|
||||
};
|
||||
var oid;
|
||||
if ( value != null && value._model != null
|
||||
&& (oid = value._model.id) != null && oid.length === 2) {
|
||||
insert.opContent = oid;
|
||||
&& value._model.length === 2) {
|
||||
insert.opContent = value._model;
|
||||
} else {
|
||||
insert.content = value;
|
||||
}
|
||||
yield* Struct.Insert.create.call(this, insert);
|
||||
if (right != null) {
|
||||
yield* Struct.Delete.create.call(this, {
|
||||
target: right
|
||||
});
|
||||
}
|
||||
},
|
||||
delete: function* (op, name) {
|
||||
var v = op.map[name] || null;
|
||||
|
@ -8,11 +8,12 @@
|
||||
}
|
||||
*val (pos) {
|
||||
var t = yield "transaction";
|
||||
var model = yield* t.getOperation(this._model);
|
||||
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;
|
||||
} 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) {
|
||||
@ -23,21 +24,25 @@
|
||||
throw new Error("contents must be an Array of objects!");
|
||||
}
|
||||
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) {
|
||||
if (typeof pos !== "number") {
|
||||
throw new Error("pos must be a number!");
|
||||
}
|
||||
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(){
|
||||
var t = yield "transaction";
|
||||
var model = yield* Y.Struct.List.create.call(t, {type: "List"});
|
||||
return new List(model);
|
||||
return t.createType(model);
|
||||
};
|
||||
Y.List.Create = List;
|
||||
})();
|
||||
|
@ -29,13 +29,15 @@
|
||||
var model = yield* t.getOperation(this._model);
|
||||
yield* Y.Struct.Map.delete.call(t, model, key);
|
||||
}
|
||||
_changed () {
|
||||
}
|
||||
}
|
||||
|
||||
Y.Map = function* YMap(){
|
||||
var t = yield "transaction";
|
||||
if (this instanceof Y.AbstractOperationStore) {
|
||||
var model = yield* Y.Struct.map.create.call(t, {type: "Map"});
|
||||
return new Map(model);
|
||||
return t.createType(model);
|
||||
} else {
|
||||
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.db.requestTransaction(function*(){
|
||||
// create initial Map type
|
||||
yield* this.addOperation({
|
||||
var model = {
|
||||
id: ["_", 0],
|
||||
struct: "Map",
|
||||
type: "Map",
|
||||
map: {}
|
||||
});
|
||||
};
|
||||
yield* this.addOperation(model);
|
||||
this.createType(model);
|
||||
});
|
||||
}
|
||||
transact (generator) {
|
||||
|
@ -21,7 +21,6 @@ function getRandomNumber(n) {
|
||||
return Math.floor(Math.random() * n);
|
||||
}
|
||||
|
||||
|
||||
var numberOfYMapTests = 30;
|
||||
|
||||
function applyRandomTransactions (users, transactions, numberOfTransactions) {
|
||||
@ -94,12 +93,30 @@ describe("Yjs", 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 root1;
|
||||
y.transact(function*(root){
|
||||
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(){
|
||||
var y = this.users[0];
|
||||
y.transact(function*(root){
|
||||
|
Loading…
x
Reference in New Issue
Block a user