added new generator approach
This commit is contained in:
		
							parent
							
								
									b6c278f8e4
								
							
						
					
					
						commit
						8d1bccbea0
					
				@ -48,10 +48,14 @@ var jasmineBrowser = require("gulp-jasmine-browser");
 | 
				
			|||||||
var concat = require("gulp-concat");
 | 
					var concat = require("gulp-concat");
 | 
				
			||||||
var watch = require("gulp-watch");
 | 
					var watch = require("gulp-watch");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var polyfills = [
 | 
				
			||||||
 | 
					  "./node_modules/regenerator/runtime.js"
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var files = {
 | 
					var files = {
 | 
				
			||||||
  y: ["src/**/*.js", "!src/**/*.spec.js"],
 | 
					  y: polyfills.concat(["src/**/*.js", "!src/**/*.spec.js"]),
 | 
				
			||||||
  lint: ["src/**/*.js", "gulpfile.js"],
 | 
					  lint: ["src/**/*.js", "gulpfile.js"],
 | 
				
			||||||
  test: ["src/**/*.js"],
 | 
					  test: polyfills.concat(["./node_modules/regenerator/runtime.js", "src/**/*.js"]),
 | 
				
			||||||
  build_test: ["build_test/y.js"]
 | 
					  build_test: ["build_test/y.js"]
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,10 @@
 | 
				
			|||||||
    "gulp-sourcemaps": "^1.5.2",
 | 
					    "gulp-sourcemaps": "^1.5.2",
 | 
				
			||||||
    "gulp-uglify": "^1.2.0",
 | 
					    "gulp-uglify": "^1.2.0",
 | 
				
			||||||
    "gulp-watch": "^4.2.4",
 | 
					    "gulp-watch": "^4.2.4",
 | 
				
			||||||
 | 
					    "gulp-webpack": "^1.5.0",
 | 
				
			||||||
    "minimist": "^1.1.1",
 | 
					    "minimist": "^1.1.1",
 | 
				
			||||||
    "pre-commit": "^1.0.10"
 | 
					    "pre-commit": "^1.0.10",
 | 
				
			||||||
 | 
					    "promise-polyfill": "^2.0.2",
 | 
				
			||||||
 | 
					    "regenerator": "^0.8.30"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DB = (function(){
 | 
					var IndexedDB = (function(){ //eslint-disable-line no-unused-vars
 | 
				
			||||||
  class DBTransaction {
 | 
					  class Transaction {
 | 
				
			||||||
    constructor (transaction) {
 | 
					    constructor (transaction) {
 | 
				
			||||||
      this.transaction = transaction;
 | 
					      this.transaction = transaction;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    setOperation (op) {
 | 
					    setOperation (op) {
 | 
				
			||||||
      return new Promise((resolve, reject)=> {
 | 
					      return new Promise((resolve, reject)=> {
 | 
				
			||||||
        var req = this.transaction.objectStore("OperationBuffer").put(op);
 | 
					        var req = this.transaction.objectStore("OperationBuffer").put(op);
 | 
				
			||||||
        req.onsuccess = function (event) {
 | 
					        req.onsuccess = function () {
 | 
				
			||||||
          resolve(op);
 | 
					          resolve(op);
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        req.onerror = function (event) {
 | 
					        req.onerror = function () {
 | 
				
			||||||
          reject("Could not set Operation!");
 | 
					          reject("Could not set Operation!");
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
@ -18,198 +18,59 @@ DB = (function(){
 | 
				
			|||||||
    getOperation (uid) {
 | 
					    getOperation (uid) {
 | 
				
			||||||
      return new Promise((resolve, reject)=>{
 | 
					      return new Promise((resolve, reject)=>{
 | 
				
			||||||
        var req = this.transaction.objectStore("OperationBuffer").get(uid);
 | 
					        var req = this.transaction.objectStore("OperationBuffer").get(uid);
 | 
				
			||||||
        req.onsuccess = function (event) {
 | 
					        req.onsuccess = function () {
 | 
				
			||||||
          resolve(req.result);
 | 
					          resolve(req.result);
 | 
				
			||||||
        }
 | 
					        };
 | 
				
			||||||
        req.onerror = function (event) {
 | 
					        req.onerror = function () {
 | 
				
			||||||
          reject("Could not get Operation");
 | 
					          reject("Could not get Operation");
 | 
				
			||||||
        }
 | 
					        };
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    getOperations (state_map) {
 | 
					 | 
				
			||||||
      var flow = Promise.resolve();
 | 
					 | 
				
			||||||
      var ops = [];
 | 
					 | 
				
			||||||
      var ob = that.transaction.objectStore("OperationBuffer");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      this.getStateVector().then((end_state_vector)=>{
 | 
					 | 
				
			||||||
         // convert to the db-structure
 | 
					 | 
				
			||||||
        end_state_vector.forEach((end_state)=>{
 | 
					 | 
				
			||||||
          var start_state = {
 | 
					 | 
				
			||||||
            user: end_state.name,
 | 
					 | 
				
			||||||
            state: state_map[end_state] || 0
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  class DB {
 | 
				
			||||||
          flow = flow.then ()->
 | 
					    constructor (namespace : string) {
 | 
				
			||||||
            from = [start_state.user, start_state.number]
 | 
					      this.namespace = namespace;
 | 
				
			||||||
            to = [end_state.user, end_state.number]
 | 
					      this.ready = new Promise(function(yay, nay){
 | 
				
			||||||
            range = IDBKeyRange.bound from, to
 | 
					        var req = indexedDB.open(namespace); //eslint-disable-line no-undef
 | 
				
			||||||
            defer = Promise.defer()
 | 
					        req.onerror = function(){
 | 
				
			||||||
 | 
					          nay("Couldn't open the IndexedDB database!");
 | 
				
			||||||
            hb.openCursor(range).onsuccess = ()->
 | 
					        };
 | 
				
			||||||
              cursor = event.target.result
 | 
					        req.onsuccess = function(event){
 | 
				
			||||||
              if cursor?
 | 
					          yay(event.target.result);
 | 
				
			||||||
                ops.push cursor.value # add Operation
 | 
					        };
 | 
				
			||||||
                cursor.continue()
 | 
					        req.onupgradeneeded = function(event){
 | 
				
			||||||
              else
 | 
					          var db = event.target.result;
 | 
				
			||||||
                # got all ops from this user
 | 
					          db.createObjectStore("OperationBuffer", {keyPath: "uid"});
 | 
				
			||||||
                defer.resolve ops
 | 
					          db.createObjectStore("StateVector", {keyPath: "user"});
 | 
				
			||||||
            defer.promise
 | 
					        };
 | 
				
			||||||
        })
 | 
					      }).catch(function(message){
 | 
				
			||||||
      })
 | 
					          throw new Error(message);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    requestTransaction (generator : Function) {
 | 
				
			||||||
 | 
					      this.ready.then(function(){
 | 
				
			||||||
 | 
					        var gen = generator(3);//new Transaction(db.transaction(["OperationBuffer", "StateVector"], "readwrite"))
 | 
				
			||||||
 | 
					        gen.next();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    "DB": DB,
 | 
				
			||||||
 | 
					    "Transaction": Transaction
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
})()
 | 
					function requestTransaction(makeGen : Function){ //eslint-disable-line no-unused-vars
 | 
				
			||||||
 | 
					  var gen = makeGen([1, 2, 3]);
 | 
				
			||||||
class DBTransaction
 | 
					  function handle(result : Object){
 | 
				
			||||||
 | 
					    if (result.done) {
 | 
				
			||||||
  getOperations: (state_map)->
 | 
					      return result.value;
 | 
				
			||||||
    flow = Promise.resolve()
 | 
					    }
 | 
				
			||||||
    ops = []
 | 
					    return result.value.then(function(res){
 | 
				
			||||||
    that = this
 | 
					      return handle(gen.next(res));
 | 
				
			||||||
    hb = that.t.objectStore("OperationBuffer")
 | 
					    }, function(err){
 | 
				
			||||||
 | 
					      return handle(gen.throw(err));
 | 
				
			||||||
    that.getStateVector().then (end_state_vector)->
 | 
					    });
 | 
				
			||||||
      for end_state of end_state_vector
 | 
					  }
 | 
				
			||||||
        # convert to the db-structure
 | 
					  return handle(gen.next());
 | 
				
			||||||
        do (end_state = end_state)->
 | 
					}
 | 
				
			||||||
          start_state =
 | 
					 | 
				
			||||||
            user: end_state.name
 | 
					 | 
				
			||||||
            state: state_map[end_state] ? 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          flow = flow.then ()->
 | 
					 | 
				
			||||||
            from = [start_state.user, start_state.number]
 | 
					 | 
				
			||||||
            to = [end_state.user, end_state.number]
 | 
					 | 
				
			||||||
            range = IDBKeyRange.bound from, to
 | 
					 | 
				
			||||||
            defer = Promise.defer()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            hb.openCursor(range).onsuccess = ()->
 | 
					 | 
				
			||||||
              cursor = event.target.result
 | 
					 | 
				
			||||||
              if cursor?
 | 
					 | 
				
			||||||
                ops.push cursor.value # add Operation
 | 
					 | 
				
			||||||
                cursor.continue()
 | 
					 | 
				
			||||||
              else
 | 
					 | 
				
			||||||
                # got all ops from this user
 | 
					 | 
				
			||||||
                defer.resolve ops
 | 
					 | 
				
			||||||
            defer.promise
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  setState: (state)->
 | 
					 | 
				
			||||||
    that = this
 | 
					 | 
				
			||||||
    new Promise (resolve, reject)->
 | 
					 | 
				
			||||||
      req = that.t.objectStore("StateVector").put state
 | 
					 | 
				
			||||||
      req.onsuccess = (event)->
 | 
					 | 
				
			||||||
        resolve state
 | 
					 | 
				
			||||||
      req.onerror = (event)->
 | 
					 | 
				
			||||||
        reject "Could not set state vector!"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getState: (user)->
 | 
					 | 
				
			||||||
    defer = Promise.defer()
 | 
					 | 
				
			||||||
    req = @t.objectStore("StateVector").get user
 | 
					 | 
				
			||||||
    req.onsuccess = (event)->
 | 
					 | 
				
			||||||
      defer.resolve req.result
 | 
					 | 
				
			||||||
    req.onerror = (event)->
 | 
					 | 
				
			||||||
      defer.reject "Could not get state vector!"
 | 
					 | 
				
			||||||
    defer.promise
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getStateVector: ()->
 | 
					 | 
				
			||||||
    defer = Promise.defer()
 | 
					 | 
				
			||||||
    state_vector = []
 | 
					 | 
				
			||||||
    @t.objectStore("StateVector").openCursor().onsuccess = ()->
 | 
					 | 
				
			||||||
      cursor = event.target.result
 | 
					 | 
				
			||||||
      if cursor?
 | 
					 | 
				
			||||||
        state = cursor.value
 | 
					 | 
				
			||||||
        state_vector.push state
 | 
					 | 
				
			||||||
        cursor.continue()
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        # got all ops from this user
 | 
					 | 
				
			||||||
        defer.resolve state_vector
 | 
					 | 
				
			||||||
    defer.promise
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Transaction
 | 
					 | 
				
			||||||
  constructor: (@t)->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  updateOperation: (op)->
 | 
					 | 
				
			||||||
    @t.setOperation op
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  addOperation: (op)->
 | 
					 | 
				
			||||||
    that = this
 | 
					 | 
				
			||||||
    @t.getState op.uid[0]
 | 
					 | 
				
			||||||
      .then (state)->
 | 
					 | 
				
			||||||
        # only add operation if this is an expected operation
 | 
					 | 
				
			||||||
        if not state?
 | 
					 | 
				
			||||||
          state =
 | 
					 | 
				
			||||||
            user: op.uid[0]
 | 
					 | 
				
			||||||
            number: 0
 | 
					 | 
				
			||||||
        if op.uid[1] is state.number
 | 
					 | 
				
			||||||
          state.number++
 | 
					 | 
				
			||||||
          that.t.setState state
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          return Promise.reject("Unexpected Operation")
 | 
					 | 
				
			||||||
      .then that.t.setOperation op
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getOperation: (uid)->
 | 
					 | 
				
			||||||
    @t.getOperation uid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getState: (user)->
 | 
					 | 
				
			||||||
    @t.getState user
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getOperations: (state_vector)->
 | 
					 | 
				
			||||||
    @t.getOperations state_vector
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class window.DB
 | 
					 | 
				
			||||||
  constructor: ()->
 | 
					 | 
				
			||||||
    @ready = (new Promise (resolve, reject)->
 | 
					 | 
				
			||||||
      req = indexedDB.open "Testy", 7
 | 
					 | 
				
			||||||
      req.onerror = ()->
 | 
					 | 
				
			||||||
        reject "Couldn't open the IndexedDB database!"
 | 
					 | 
				
			||||||
      req.onsuccess = (event)->
 | 
					 | 
				
			||||||
        resolve event.target.result
 | 
					 | 
				
			||||||
      req.onupgradeneeded = (event)->
 | 
					 | 
				
			||||||
        db = event.target.result
 | 
					 | 
				
			||||||
        objectStore = db.createObjectStore "OperationBuffer", {keyPath: "uid"}
 | 
					 | 
				
			||||||
        objectStore = db.createObjectStore "StateVector", {keyPath: "user"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ).catch (message)->
 | 
					 | 
				
			||||||
      throw new Error message
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  requestTransaction: ()->
 | 
					 | 
				
			||||||
    @ready.then (db)->
 | 
					 | 
				
			||||||
      new Promise (resolve, reject)->
 | 
					 | 
				
			||||||
        resolve new Transaction( new DBTransaction(db.transaction(["OperationBuffer", "StateVector"], "readwrite")) )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  removeDatabase: ()->
 | 
					 | 
				
			||||||
    req = indexedDB.deleteDatabase "Testy"
 | 
					 | 
				
			||||||
    req.onsuccess = ()->
 | 
					 | 
				
			||||||
      console.log("Deleted database successfully");
 | 
					 | 
				
			||||||
    req.onblocked = ()->
 | 
					 | 
				
			||||||
      console.log("Database is currently being blocked")
 | 
					 | 
				
			||||||
      console.dir arguments
 | 
					 | 
				
			||||||
    req.onerror = ()->
 | 
					 | 
				
			||||||
      console.log("Couldn't delete database")
 | 
					 | 
				
			||||||
      console.dir arguments
 | 
					 | 
				
			||||||
    null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
window.db = new DB()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
window.addDummyDataSet = ()->
 | 
					 | 
				
			||||||
  db.requestTransaction().then (t)->
 | 
					 | 
				
			||||||
    t.getState("dmonad").then (state)->
 | 
					 | 
				
			||||||
      state ?= {number: 0}
 | 
					 | 
				
			||||||
      t.addOperation({uid: ["dmonad", state.number]})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
window.getOp = (num = 3)->
 | 
					 | 
				
			||||||
  db.requestTransaction().then (t)->
 | 
					 | 
				
			||||||
    t.getOperation(["dmonad", num])
 | 
					 | 
				
			||||||
      .then (op)->
 | 
					 | 
				
			||||||
        console.log("yay:")
 | 
					 | 
				
			||||||
        console.log(op)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
window.getOps = (state_map = {dmonad: 5})->
 | 
					 | 
				
			||||||
  db.requestTransaction().then (t)->
 | 
					 | 
				
			||||||
    t.getOperations(state_map)
 | 
					 | 
				
			||||||
      .then (op)->
 | 
					 | 
				
			||||||
        console.log("yay:")
 | 
					 | 
				
			||||||
        console.log(op)
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1,24 @@
 | 
				
			|||||||
 | 
					/* @flow */
 | 
				
			||||||
 | 
					/*eslint-env browser,jasmine,console */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var number = 0;
 | 
				
			||||||
 | 
					function llater(time){
 | 
				
			||||||
 | 
					  return new Promise(function(yay){
 | 
				
			||||||
 | 
					    setTimeout(function(){
 | 
				
			||||||
 | 
					      yay(number++);
 | 
				
			||||||
 | 
					    }, time); //eslint-disable-line no-undef
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe("IndexedDB", function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it("can create transactions", function(done) {
 | 
				
			||||||
 | 
					    requestTransaction(function*(numbers){
 | 
				
			||||||
 | 
					      expect(numbers).toEqual([1, 2, 3]);
 | 
				
			||||||
 | 
					      expect(yield llater(10)).toEqual(0);
 | 
				
			||||||
 | 
					      expect(yield llater(50)).toEqual(1);
 | 
				
			||||||
 | 
					      done();
 | 
				
			||||||
 | 
					      return 10;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user