update
This commit is contained in:
parent
b471c91d1d
commit
434432a742
@ -1,38 +0,0 @@
|
||||
/* global Y */
|
||||
|
||||
// create a shared object. This function call will return a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory',
|
||||
namespace: 'offlineEditingDemo'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'offlineEditingDemo',
|
||||
debug: true
|
||||
},
|
||||
types: ['Array', 'Text'],
|
||||
sourceDir: '/bower_components'
|
||||
}).then(function (yconfig) {
|
||||
// yconfig holds all the information about the shared object
|
||||
window.yconfig = yconfig
|
||||
|
||||
// now we bind the textarea and the contenteditable h1 element
|
||||
// to a shared element
|
||||
var textarea = document.getElementById('textfield')
|
||||
yconfig.root.observePath(['text'], function (text) {
|
||||
// every time the 'text' property of the yconfig.root changes,
|
||||
// this function is called. Then we bind it to the html elements
|
||||
if (text != null) {
|
||||
// when the text property is deleted, text may be undefined!
|
||||
// This is why we have to check if text exists..
|
||||
text.bind(textarea)
|
||||
}
|
||||
})
|
||||
// create a shared Text
|
||||
var textpromise = yconfig.root.get('text')
|
||||
if (textpromise == null) {
|
||||
// Set the text type if it does not yet exist
|
||||
yconfig.root.set('text', Y.Text)
|
||||
}
|
||||
})
|
18
Examples/Puzzle/index.html
Normal file
18
Examples/Puzzle/index.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.cell {
|
||||
fill: black;
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg id="puzzle-example" width="100%" viewBox="0 0 1 1"></svg>
|
||||
|
||||
<script src="../bower_components/yjs/y.es6"></script>
|
||||
<script src="../bower_components/d3/d3.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
63
Examples/Puzzle/index.js
Normal file
63
Examples/Puzzle/index.js
Normal file
@ -0,0 +1,63 @@
|
||||
/* @flow */
|
||||
/* global Y, d3 */
|
||||
|
||||
// initialize a shared object. This function call returns a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'Puzzle-example'
|
||||
},
|
||||
sourceDir: '/bower_components',
|
||||
share: {
|
||||
piece1: 'Map',
|
||||
piece2: 'Map',
|
||||
piece3: 'Map'
|
||||
}
|
||||
}).then(function (y) {
|
||||
window.y = y
|
||||
|
||||
var dragX, dragY // x,y coordinates of drag event
|
||||
var drag = d3.behavior.drag()
|
||||
.on("drag", function(){
|
||||
dragX = d3.event.x-0.05
|
||||
dragY = d3.event.y-0.05
|
||||
d3.select(this)
|
||||
//.transition()
|
||||
.attr("transform", "translate(" + dragX + "," + dragY+ ")")
|
||||
})
|
||||
.on('dragend', function (piece) {
|
||||
// change the shared model of the puzzle
|
||||
piece.set('x', dragX)
|
||||
piece.set('y', dragY)
|
||||
})
|
||||
|
||||
var data = [y.share.piece1, y.share.piece2, y.share.piece3]
|
||||
var nodes = d3.select(document.querySelector("#puzzle-example")).append('g').selectAll("rect").data(data)
|
||||
nodes
|
||||
.enter()
|
||||
.append('rect')
|
||||
.attr('width', 0.1)
|
||||
.attr('height', 0.1)
|
||||
.attr("class", "cell")
|
||||
.attr("transform", function (piece, i) {
|
||||
var x = piece.get('x') || i/3
|
||||
var y = piece.get('y') || i/3
|
||||
return "translate(" + x + "," + y + ")"
|
||||
}).call(drag)
|
||||
|
||||
function repaint () {
|
||||
nodes
|
||||
.transition()
|
||||
.attr("transform", function (piece, i) {
|
||||
var x = piece.get('x') || i/3
|
||||
var y = piece.get('y') || i/3
|
||||
return "translate(" + x + "," + y + ")"
|
||||
})
|
||||
}
|
||||
data.forEach(function(piece){
|
||||
piece.observe(repaint)
|
||||
})
|
||||
})
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<button id="button">Disconnect</button>
|
||||
<h1 id="contenteditable" contentEditable></h1>
|
||||
<textarea style="width:80%;" rows=40 id="textfield"></textarea>
|
||||
|
||||
<script src="../bower_components/yjs/y.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,49 +0,0 @@
|
||||
/* global Y */
|
||||
|
||||
// create a shared object. This function call will return a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'textEditingDem0',
|
||||
debug: true
|
||||
},
|
||||
types: ['Array', 'Text'],
|
||||
sourceDir: '/bower_components/'
|
||||
}).then(function (yconfig) {
|
||||
// yconfig holds all the information about the shared object
|
||||
window.yconfig = yconfig
|
||||
// yconfig.root holds the shared element
|
||||
window.y = yconfig.root
|
||||
|
||||
// now we bind the textarea and the contenteditable h1 element
|
||||
// to a shared element
|
||||
var textarea = document.getElementById('textfield')
|
||||
var contenteditable = document.getElementById('contenteditable')
|
||||
yconfig.root.observePath(['text'], function (text) {
|
||||
// every time the 'text' property of the yconfig.root changes,
|
||||
// this function is called. Then we bind it to the html elements
|
||||
if (text != null) {
|
||||
// when the text property is deleted, text may be undefined!
|
||||
// This is why we have to check if text exists..
|
||||
text.bind(textarea)
|
||||
text.bind(contenteditable)
|
||||
}
|
||||
})
|
||||
// create a shared Text
|
||||
yconfig.root.set('text', Y.Text)
|
||||
|
||||
// We also provide a button for disconnecting/reconnecting the shared element
|
||||
var button = document.querySelector('#button')
|
||||
button.onclick = function () {
|
||||
if (button.innerText === 'Disconnect') {
|
||||
yconfig.disconnect()
|
||||
button.innerText = 'Reconnect'
|
||||
} else {
|
||||
yconfig.reconnect()
|
||||
button.innerText = 'Disconnect'
|
||||
}
|
||||
}
|
||||
})
|
@ -3,7 +3,7 @@
|
||||
<body>
|
||||
<textarea style="width:80%;" rows=40 id="textfield"></textarea>
|
||||
|
||||
<script src="../bower_components/yjs/y.js"></script>
|
||||
<script src="../bower_components/yjs/y.es6"></script>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
22
Examples/Textarea/index.js
Normal file
22
Examples/Textarea/index.js
Normal file
@ -0,0 +1,22 @@
|
||||
/* global Y */
|
||||
|
||||
// initialize a shared object. This function call returns a promise!
|
||||
Y({
|
||||
db: {
|
||||
name: 'memory'
|
||||
},
|
||||
connector: {
|
||||
name: 'websockets-client',
|
||||
room: 'Textarea-example'
|
||||
},
|
||||
sourceDir: '/bower_components',
|
||||
share: {
|
||||
textarea: 'Text' // y.share.textarea is of type Y.Text
|
||||
}
|
||||
}).then(function (y) {
|
||||
window.y = y
|
||||
|
||||
// bind the textarea to a shared text element
|
||||
y.share.textarea.bind(document.getElementById('textfield'))
|
||||
// thats it..
|
||||
})
|
848
y.es6
848
y.es6
@ -1,770 +1,4 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
// shim for using process in browser
|
||||
|
||||
var process = module.exports = {};
|
||||
var queue = [];
|
||||
var draining = false;
|
||||
var currentQueue;
|
||||
var queueIndex = -1;
|
||||
|
||||
function cleanUpNextTick() {
|
||||
draining = false;
|
||||
if (currentQueue.length) {
|
||||
queue = currentQueue.concat(queue);
|
||||
} else {
|
||||
queueIndex = -1;
|
||||
}
|
||||
if (queue.length) {
|
||||
drainQueue();
|
||||
}
|
||||
}
|
||||
|
||||
function drainQueue() {
|
||||
if (draining) {
|
||||
return;
|
||||
}
|
||||
var timeout = setTimeout(cleanUpNextTick);
|
||||
draining = true;
|
||||
|
||||
var len = queue.length;
|
||||
while(len) {
|
||||
currentQueue = queue;
|
||||
queue = [];
|
||||
while (++queueIndex < len) {
|
||||
if (currentQueue) {
|
||||
currentQueue[queueIndex].run();
|
||||
}
|
||||
}
|
||||
queueIndex = -1;
|
||||
len = queue.length;
|
||||
}
|
||||
currentQueue = null;
|
||||
draining = false;
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
process.nextTick = function (fun) {
|
||||
var args = new Array(arguments.length - 1);
|
||||
if (arguments.length > 1) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
}
|
||||
queue.push(new Item(fun, args));
|
||||
if (queue.length === 1 && !draining) {
|
||||
setTimeout(drainQueue, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// v8 likes predictible objects
|
||||
function Item(fun, array) {
|
||||
this.fun = fun;
|
||||
this.array = array;
|
||||
}
|
||||
Item.prototype.run = function () {
|
||||
this.fun.apply(null, this.array);
|
||||
};
|
||||
process.title = 'browser';
|
||||
process.browser = true;
|
||||
process.env = {};
|
||||
process.argv = [];
|
||||
process.version = ''; // empty string to avoid regexp issues
|
||||
process.versions = {};
|
||||
|
||||
function noop() {}
|
||||
|
||||
process.on = noop;
|
||||
process.addListener = noop;
|
||||
process.once = noop;
|
||||
process.off = noop;
|
||||
process.removeListener = noop;
|
||||
process.removeAllListeners = noop;
|
||||
process.emit = noop;
|
||||
|
||||
process.binding = function (name) {
|
||||
throw new Error('process.binding is not supported');
|
||||
};
|
||||
|
||||
process.cwd = function () { return '/' };
|
||||
process.chdir = function (dir) {
|
||||
throw new Error('process.chdir is not supported');
|
||||
};
|
||||
process.umask = function() { return 0; };
|
||||
|
||||
},{}],2:[function(require,module,exports){
|
||||
(function (process,global){
|
||||
/**
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* https://raw.github.com/facebook/regenerator/master/LICENSE file. An
|
||||
* additional grant of patent rights can be found in the PATENTS file in
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
!(function(global) {
|
||||
"use strict";
|
||||
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var undefined; // More compressible than void 0.
|
||||
var $Symbol = typeof Symbol === "function" ? Symbol : {};
|
||||
var iteratorSymbol = $Symbol.iterator || "@@iterator";
|
||||
var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
|
||||
|
||||
var inModule = typeof module === "object";
|
||||
var runtime = global.regeneratorRuntime;
|
||||
if (runtime) {
|
||||
if (inModule) {
|
||||
// If regeneratorRuntime is defined globally and we're in a module,
|
||||
// make the exports object identical to regeneratorRuntime.
|
||||
module.exports = runtime;
|
||||
}
|
||||
// Don't bother evaluating the rest of this file if the runtime was
|
||||
// already defined globally.
|
||||
return;
|
||||
}
|
||||
|
||||
// Define the runtime globally (as expected by generated code) as either
|
||||
// module.exports (if we're in a module) or a new, empty object.
|
||||
runtime = global.regeneratorRuntime = inModule ? module.exports : {};
|
||||
|
||||
function wrap(innerFn, outerFn, self, tryLocsList) {
|
||||
// If outerFn provided, then outerFn.prototype instanceof Generator.
|
||||
var generator = Object.create((outerFn || Generator).prototype);
|
||||
var context = new Context(tryLocsList || []);
|
||||
|
||||
// The ._invoke method unifies the implementations of the .next,
|
||||
// .throw, and .return methods.
|
||||
generator._invoke = makeInvokeMethod(innerFn, self, context);
|
||||
|
||||
return generator;
|
||||
}
|
||||
runtime.wrap = wrap;
|
||||
|
||||
// Try/catch helper to minimize deoptimizations. Returns a completion
|
||||
// record like context.tryEntries[i].completion. This interface could
|
||||
// have been (and was previously) designed to take a closure to be
|
||||
// invoked without arguments, but in all the cases we care about we
|
||||
// already have an existing method we want to call, so there's no need
|
||||
// to create a new function object. We can even get away with assuming
|
||||
// the method takes exactly one argument, since that happens to be true
|
||||
// in every case, so we don't have to touch the arguments object. The
|
||||
// only additional allocation required is the completion record, which
|
||||
// has a stable shape and so hopefully should be cheap to allocate.
|
||||
function tryCatch(fn, obj, arg) {
|
||||
try {
|
||||
return { type: "normal", arg: fn.call(obj, arg) };
|
||||
} catch (err) {
|
||||
return { type: "throw", arg: err };
|
||||
}
|
||||
}
|
||||
|
||||
var GenStateSuspendedStart = "suspendedStart";
|
||||
var GenStateSuspendedYield = "suspendedYield";
|
||||
var GenStateExecuting = "executing";
|
||||
var GenStateCompleted = "completed";
|
||||
|
||||
// Returning this object from the innerFn has the same effect as
|
||||
// breaking out of the dispatch switch statement.
|
||||
var ContinueSentinel = {};
|
||||
|
||||
// Dummy constructor functions that we use as the .constructor and
|
||||
// .constructor.prototype properties for functions that return Generator
|
||||
// objects. For full spec compliance, you may wish to configure your
|
||||
// minifier not to mangle the names of these two functions.
|
||||
function Generator() {}
|
||||
function GeneratorFunction() {}
|
||||
function GeneratorFunctionPrototype() {}
|
||||
|
||||
var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype;
|
||||
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
|
||||
GeneratorFunctionPrototype.constructor = GeneratorFunction;
|
||||
GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction";
|
||||
|
||||
// Helper for defining the .next, .throw, and .return methods of the
|
||||
// Iterator interface in terms of a single ._invoke method.
|
||||
function defineIteratorMethods(prototype) {
|
||||
["next", "throw", "return"].forEach(function(method) {
|
||||
prototype[method] = function(arg) {
|
||||
return this._invoke(method, arg);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
runtime.isGeneratorFunction = function(genFun) {
|
||||
var ctor = typeof genFun === "function" && genFun.constructor;
|
||||
return ctor
|
||||
? ctor === GeneratorFunction ||
|
||||
// For the native GeneratorFunction constructor, the best we can
|
||||
// do is to check its .name property.
|
||||
(ctor.displayName || ctor.name) === "GeneratorFunction"
|
||||
: false;
|
||||
};
|
||||
|
||||
runtime.mark = function(genFun) {
|
||||
if (Object.setPrototypeOf) {
|
||||
Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
|
||||
} else {
|
||||
genFun.__proto__ = GeneratorFunctionPrototype;
|
||||
if (!(toStringTagSymbol in genFun)) {
|
||||
genFun[toStringTagSymbol] = "GeneratorFunction";
|
||||
}
|
||||
}
|
||||
genFun.prototype = Object.create(Gp);
|
||||
return genFun;
|
||||
};
|
||||
|
||||
// Within the body of any async function, `await x` is transformed to
|
||||
// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
|
||||
// `value instanceof AwaitArgument` to determine if the yielded value is
|
||||
// meant to be awaited. Some may consider the name of this method too
|
||||
// cutesy, but they are curmudgeons.
|
||||
runtime.awrap = function(arg) {
|
||||
return new AwaitArgument(arg);
|
||||
};
|
||||
|
||||
function AwaitArgument(arg) {
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
function AsyncIterator(generator) {
|
||||
function invoke(method, arg, resolve, reject) {
|
||||
var record = tryCatch(generator[method], generator, arg);
|
||||
if (record.type === "throw") {
|
||||
reject(record.arg);
|
||||
} else {
|
||||
var result = record.arg;
|
||||
var value = result.value;
|
||||
if (value instanceof AwaitArgument) {
|
||||
return Promise.resolve(value.arg).then(function(value) {
|
||||
invoke("next", value, resolve, reject);
|
||||
}, function(err) {
|
||||
invoke("throw", err, resolve, reject);
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(value).then(function(unwrapped) {
|
||||
// When a yielded Promise is resolved, its final value becomes
|
||||
// the .value of the Promise<{value,done}> result for the
|
||||
// current iteration. If the Promise is rejected, however, the
|
||||
// result for this iteration will be rejected with the same
|
||||
// reason. Note that rejections of yielded Promises are not
|
||||
// thrown back into the generator function, as is the case
|
||||
// when an awaited Promise is rejected. This difference in
|
||||
// behavior between yield and await is important, because it
|
||||
// allows the consumer to decide what to do with the yielded
|
||||
// rejection (swallow it and continue, manually .throw it back
|
||||
// into the generator, abandon iteration, whatever). With
|
||||
// await, by contrast, there is no opportunity to examine the
|
||||
// rejection reason outside the generator function, so the
|
||||
// only option is to throw it from the await expression, and
|
||||
// let the generator function handle the exception.
|
||||
result.value = unwrapped;
|
||||
resolve(result);
|
||||
}, reject);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof process === "object" && process.domain) {
|
||||
invoke = process.domain.bind(invoke);
|
||||
}
|
||||
|
||||
var previousPromise;
|
||||
|
||||
function enqueue(method, arg) {
|
||||
function callInvokeWithMethodAndArg() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
invoke(method, arg, resolve, reject);
|
||||
});
|
||||
}
|
||||
|
||||
return previousPromise =
|
||||
// If enqueue has been called before, then we want to wait until
|
||||
// all previous Promises have been resolved before calling invoke,
|
||||
// so that results are always delivered in the correct order. If
|
||||
// enqueue has not been called before, then it is important to
|
||||
// call invoke immediately, without waiting on a callback to fire,
|
||||
// so that the async generator function has the opportunity to do
|
||||
// any necessary setup in a predictable way. This predictability
|
||||
// is why the Promise constructor synchronously invokes its
|
||||
// executor callback, and why async functions synchronously
|
||||
// execute code before the first await. Since we implement simple
|
||||
// async functions in terms of async generators, it is especially
|
||||
// important to get this right, even though it requires care.
|
||||
previousPromise ? previousPromise.then(
|
||||
callInvokeWithMethodAndArg,
|
||||
// Avoid propagating failures to Promises returned by later
|
||||
// invocations of the iterator.
|
||||
callInvokeWithMethodAndArg
|
||||
) : callInvokeWithMethodAndArg();
|
||||
}
|
||||
|
||||
// Define the unified helper method that is used to implement .next,
|
||||
// .throw, and .return (see defineIteratorMethods).
|
||||
this._invoke = enqueue;
|
||||
}
|
||||
|
||||
defineIteratorMethods(AsyncIterator.prototype);
|
||||
|
||||
// Note that simple async functions are implemented on top of
|
||||
// AsyncIterator objects; they just return a Promise for the value of
|
||||
// the final result produced by the iterator.
|
||||
runtime.async = function(innerFn, outerFn, self, tryLocsList) {
|
||||
var iter = new AsyncIterator(
|
||||
wrap(innerFn, outerFn, self, tryLocsList)
|
||||
);
|
||||
|
||||
return runtime.isGeneratorFunction(outerFn)
|
||||
? iter // If outerFn is a generator, return the full iterator.
|
||||
: iter.next().then(function(result) {
|
||||
return result.done ? result.value : iter.next();
|
||||
});
|
||||
};
|
||||
|
||||
function makeInvokeMethod(innerFn, self, context) {
|
||||
var state = GenStateSuspendedStart;
|
||||
|
||||
return function invoke(method, arg) {
|
||||
if (state === GenStateExecuting) {
|
||||
throw new Error("Generator is already running");
|
||||
}
|
||||
|
||||
if (state === GenStateCompleted) {
|
||||
if (method === "throw") {
|
||||
throw arg;
|
||||
}
|
||||
|
||||
// Be forgiving, per 25.3.3.3.3 of the spec:
|
||||
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
|
||||
return doneResult();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
var delegate = context.delegate;
|
||||
if (delegate) {
|
||||
if (method === "return" ||
|
||||
(method === "throw" && delegate.iterator[method] === undefined)) {
|
||||
// A return or throw (when the delegate iterator has no throw
|
||||
// method) always terminates the yield* loop.
|
||||
context.delegate = null;
|
||||
|
||||
// If the delegate iterator has a return method, give it a
|
||||
// chance to clean up.
|
||||
var returnMethod = delegate.iterator["return"];
|
||||
if (returnMethod) {
|
||||
var record = tryCatch(returnMethod, delegate.iterator, arg);
|
||||
if (record.type === "throw") {
|
||||
// If the return method threw an exception, let that
|
||||
// exception prevail over the original return or throw.
|
||||
method = "throw";
|
||||
arg = record.arg;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (method === "return") {
|
||||
// Continue with the outer return, now that the delegate
|
||||
// iterator has been terminated.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var record = tryCatch(
|
||||
delegate.iterator[method],
|
||||
delegate.iterator,
|
||||
arg
|
||||
);
|
||||
|
||||
if (record.type === "throw") {
|
||||
context.delegate = null;
|
||||
|
||||
// Like returning generator.throw(uncaught), but without the
|
||||
// overhead of an extra function call.
|
||||
method = "throw";
|
||||
arg = record.arg;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Delegate generator ran and handled its own exceptions so
|
||||
// regardless of what the method was, we continue as if it is
|
||||
// "next" with an undefined arg.
|
||||
method = "next";
|
||||
arg = undefined;
|
||||
|
||||
var info = record.arg;
|
||||
if (info.done) {
|
||||
context[delegate.resultName] = info.value;
|
||||
context.next = delegate.nextLoc;
|
||||
} else {
|
||||
state = GenStateSuspendedYield;
|
||||
return info;
|
||||
}
|
||||
|
||||
context.delegate = null;
|
||||
}
|
||||
|
||||
if (method === "next") {
|
||||
if (state === GenStateSuspendedYield) {
|
||||
context.sent = arg;
|
||||
} else {
|
||||
context.sent = undefined;
|
||||
}
|
||||
|
||||
} else if (method === "throw") {
|
||||
if (state === GenStateSuspendedStart) {
|
||||
state = GenStateCompleted;
|
||||
throw arg;
|
||||
}
|
||||
|
||||
if (context.dispatchException(arg)) {
|
||||
// If the dispatched exception was caught by a catch block,
|
||||
// then let that catch block handle the exception normally.
|
||||
method = "next";
|
||||
arg = undefined;
|
||||
}
|
||||
|
||||
} else if (method === "return") {
|
||||
context.abrupt("return", arg);
|
||||
}
|
||||
|
||||
state = GenStateExecuting;
|
||||
|
||||
var record = tryCatch(innerFn, self, context);
|
||||
if (record.type === "normal") {
|
||||
// If an exception is thrown from innerFn, we leave state ===
|
||||
// GenStateExecuting and loop back for another invocation.
|
||||
state = context.done
|
||||
? GenStateCompleted
|
||||
: GenStateSuspendedYield;
|
||||
|
||||
var info = {
|
||||
value: record.arg,
|
||||
done: context.done
|
||||
};
|
||||
|
||||
if (record.arg === ContinueSentinel) {
|
||||
if (context.delegate && method === "next") {
|
||||
// Deliberately forget the last sent value so that we don't
|
||||
// accidentally pass it on to the delegate.
|
||||
arg = undefined;
|
||||
}
|
||||
} else {
|
||||
return info;
|
||||
}
|
||||
|
||||
} else if (record.type === "throw") {
|
||||
state = GenStateCompleted;
|
||||
// Dispatch the exception by looping back around to the
|
||||
// context.dispatchException(arg) call above.
|
||||
method = "throw";
|
||||
arg = record.arg;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Define Generator.prototype.{next,throw,return} in terms of the
|
||||
// unified ._invoke helper method.
|
||||
defineIteratorMethods(Gp);
|
||||
|
||||
Gp[iteratorSymbol] = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
Gp[toStringTagSymbol] = "Generator";
|
||||
|
||||
Gp.toString = function() {
|
||||
return "[object Generator]";
|
||||
};
|
||||
|
||||
function pushTryEntry(locs) {
|
||||
var entry = { tryLoc: locs[0] };
|
||||
|
||||
if (1 in locs) {
|
||||
entry.catchLoc = locs[1];
|
||||
}
|
||||
|
||||
if (2 in locs) {
|
||||
entry.finallyLoc = locs[2];
|
||||
entry.afterLoc = locs[3];
|
||||
}
|
||||
|
||||
this.tryEntries.push(entry);
|
||||
}
|
||||
|
||||
function resetTryEntry(entry) {
|
||||
var record = entry.completion || {};
|
||||
record.type = "normal";
|
||||
delete record.arg;
|
||||
entry.completion = record;
|
||||
}
|
||||
|
||||
function Context(tryLocsList) {
|
||||
// The root entry object (effectively a try statement without a catch
|
||||
// or a finally block) gives us a place to store values thrown from
|
||||
// locations where there is no enclosing try statement.
|
||||
this.tryEntries = [{ tryLoc: "root" }];
|
||||
tryLocsList.forEach(pushTryEntry, this);
|
||||
this.reset(true);
|
||||
}
|
||||
|
||||
runtime.keys = function(object) {
|
||||
var keys = [];
|
||||
for (var key in object) {
|
||||
keys.push(key);
|
||||
}
|
||||
keys.reverse();
|
||||
|
||||
// Rather than returning an object with a next method, we keep
|
||||
// things simple and return the next function itself.
|
||||
return function next() {
|
||||
while (keys.length) {
|
||||
var key = keys.pop();
|
||||
if (key in object) {
|
||||
next.value = key;
|
||||
next.done = false;
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
// To avoid creating an additional object, we just hang the .value
|
||||
// and .done properties off the next function object itself. This
|
||||
// also ensures that the minifier will not anonymize the function.
|
||||
next.done = true;
|
||||
return next;
|
||||
};
|
||||
};
|
||||
|
||||
function values(iterable) {
|
||||
if (iterable) {
|
||||
var iteratorMethod = iterable[iteratorSymbol];
|
||||
if (iteratorMethod) {
|
||||
return iteratorMethod.call(iterable);
|
||||
}
|
||||
|
||||
if (typeof iterable.next === "function") {
|
||||
return iterable;
|
||||
}
|
||||
|
||||
if (!isNaN(iterable.length)) {
|
||||
var i = -1, next = function next() {
|
||||
while (++i < iterable.length) {
|
||||
if (hasOwn.call(iterable, i)) {
|
||||
next.value = iterable[i];
|
||||
next.done = false;
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
next.value = undefined;
|
||||
next.done = true;
|
||||
|
||||
return next;
|
||||
};
|
||||
|
||||
return next.next = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Return an iterator with no values.
|
||||
return { next: doneResult };
|
||||
}
|
||||
runtime.values = values;
|
||||
|
||||
function doneResult() {
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
|
||||
Context.prototype = {
|
||||
constructor: Context,
|
||||
|
||||
reset: function(skipTempReset) {
|
||||
this.prev = 0;
|
||||
this.next = 0;
|
||||
this.sent = undefined;
|
||||
this.done = false;
|
||||
this.delegate = null;
|
||||
|
||||
this.tryEntries.forEach(resetTryEntry);
|
||||
|
||||
if (!skipTempReset) {
|
||||
for (var name in this) {
|
||||
// Not sure about the optimal order of these conditions:
|
||||
if (name.charAt(0) === "t" &&
|
||||
hasOwn.call(this, name) &&
|
||||
!isNaN(+name.slice(1))) {
|
||||
this[name] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
this.done = true;
|
||||
|
||||
var rootEntry = this.tryEntries[0];
|
||||
var rootRecord = rootEntry.completion;
|
||||
if (rootRecord.type === "throw") {
|
||||
throw rootRecord.arg;
|
||||
}
|
||||
|
||||
return this.rval;
|
||||
},
|
||||
|
||||
dispatchException: function(exception) {
|
||||
if (this.done) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
var context = this;
|
||||
function handle(loc, caught) {
|
||||
record.type = "throw";
|
||||
record.arg = exception;
|
||||
context.next = loc;
|
||||
return !!caught;
|
||||
}
|
||||
|
||||
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
||||
var entry = this.tryEntries[i];
|
||||
var record = entry.completion;
|
||||
|
||||
if (entry.tryLoc === "root") {
|
||||
// Exception thrown outside of any try block that could handle
|
||||
// it, so set the completion value of the entire function to
|
||||
// throw the exception.
|
||||
return handle("end");
|
||||
}
|
||||
|
||||
if (entry.tryLoc <= this.prev) {
|
||||
var hasCatch = hasOwn.call(entry, "catchLoc");
|
||||
var hasFinally = hasOwn.call(entry, "finallyLoc");
|
||||
|
||||
if (hasCatch && hasFinally) {
|
||||
if (this.prev < entry.catchLoc) {
|
||||
return handle(entry.catchLoc, true);
|
||||
} else if (this.prev < entry.finallyLoc) {
|
||||
return handle(entry.finallyLoc);
|
||||
}
|
||||
|
||||
} else if (hasCatch) {
|
||||
if (this.prev < entry.catchLoc) {
|
||||
return handle(entry.catchLoc, true);
|
||||
}
|
||||
|
||||
} else if (hasFinally) {
|
||||
if (this.prev < entry.finallyLoc) {
|
||||
return handle(entry.finallyLoc);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new Error("try statement without catch or finally");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
abrupt: function(type, arg) {
|
||||
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
||||
var entry = this.tryEntries[i];
|
||||
if (entry.tryLoc <= this.prev &&
|
||||
hasOwn.call(entry, "finallyLoc") &&
|
||||
this.prev < entry.finallyLoc) {
|
||||
var finallyEntry = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (finallyEntry &&
|
||||
(type === "break" ||
|
||||
type === "continue") &&
|
||||
finallyEntry.tryLoc <= arg &&
|
||||
arg <= finallyEntry.finallyLoc) {
|
||||
// Ignore the finally entry if control is not jumping to a
|
||||
// location outside the try/catch block.
|
||||
finallyEntry = null;
|
||||
}
|
||||
|
||||
var record = finallyEntry ? finallyEntry.completion : {};
|
||||
record.type = type;
|
||||
record.arg = arg;
|
||||
|
||||
if (finallyEntry) {
|
||||
this.next = finallyEntry.finallyLoc;
|
||||
} else {
|
||||
this.complete(record);
|
||||
}
|
||||
|
||||
return ContinueSentinel;
|
||||
},
|
||||
|
||||
complete: function(record, afterLoc) {
|
||||
if (record.type === "throw") {
|
||||
throw record.arg;
|
||||
}
|
||||
|
||||
if (record.type === "break" ||
|
||||
record.type === "continue") {
|
||||
this.next = record.arg;
|
||||
} else if (record.type === "return") {
|
||||
this.rval = record.arg;
|
||||
this.next = "end";
|
||||
} else if (record.type === "normal" && afterLoc) {
|
||||
this.next = afterLoc;
|
||||
}
|
||||
},
|
||||
|
||||
finish: function(finallyLoc) {
|
||||
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
||||
var entry = this.tryEntries[i];
|
||||
if (entry.finallyLoc === finallyLoc) {
|
||||
this.complete(entry.completion, entry.afterLoc);
|
||||
resetTryEntry(entry);
|
||||
return ContinueSentinel;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"catch": function(tryLoc) {
|
||||
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
||||
var entry = this.tryEntries[i];
|
||||
if (entry.tryLoc === tryLoc) {
|
||||
var record = entry.completion;
|
||||
if (record.type === "throw") {
|
||||
var thrown = record.arg;
|
||||
resetTryEntry(entry);
|
||||
}
|
||||
return thrown;
|
||||
}
|
||||
}
|
||||
|
||||
// The context.catch method must only be called with a location
|
||||
// argument that corresponds to a known catch block.
|
||||
throw new Error("illegal catch attempt");
|
||||
},
|
||||
|
||||
delegateYield: function(iterable, resultName, nextLoc) {
|
||||
this.delegate = {
|
||||
iterator: values(iterable),
|
||||
resultName: resultName,
|
||||
nextLoc: nextLoc
|
||||
};
|
||||
|
||||
return ContinueSentinel;
|
||||
}
|
||||
};
|
||||
})(
|
||||
// Among the various tricks for obtaining a reference to the global
|
||||
// object, this seems to be the most reliable technique that does not
|
||||
// use indirect eval (which violates Content Security Policy).
|
||||
typeof global === "object" ? global :
|
||||
typeof window === "object" ? window :
|
||||
typeof self === "object" ? self : this
|
||||
);
|
||||
|
||||
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||||
|
||||
},{"_process":1}],3:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -1132,7 +366,7 @@ module.exports = function (Y/* :any */) {
|
||||
Y.AbstractConnector = AbstractConnector
|
||||
}
|
||||
|
||||
},{}],4:[function(require,module,exports){
|
||||
},{}],2:[function(require,module,exports){
|
||||
/* global getRandom, async */
|
||||
'use strict'
|
||||
|
||||
@ -1274,7 +508,7 @@ module.exports = function (Y) {
|
||||
Y.Test = Test
|
||||
}
|
||||
|
||||
},{}],5:[function(require,module,exports){
|
||||
},{}],3:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -1463,10 +697,13 @@ module.exports = function (Y /* :any */) {
|
||||
}
|
||||
}
|
||||
getNextOpId () {
|
||||
if (this.userId == null) {
|
||||
if (this._nextUserId != null) {
|
||||
return this._nextUserId
|
||||
} else if (this.userId == null) {
|
||||
throw new Error('OperationStore not yet initialized!')
|
||||
} else {
|
||||
return [this.userId, this.opClock++]
|
||||
}
|
||||
return [this.userId, this.opClock++]
|
||||
}
|
||||
/*
|
||||
Apply a list of operations.
|
||||
@ -1664,7 +901,7 @@ module.exports = function (Y /* :any */) {
|
||||
}
|
||||
}
|
||||
requestTransaction (makeGen/* :any */, callImmediately) {
|
||||
if (callImmediately) {
|
||||
if (true || callImmediately) { // TODO: decide whether this is ok or not..
|
||||
this.waitingTransactions.push(makeGen)
|
||||
if (!this.transactionInProgress) {
|
||||
this.transactionInProgress = true
|
||||
@ -1685,7 +922,7 @@ module.exports = function (Y /* :any */) {
|
||||
Y.AbstractDatabase = AbstractDatabase
|
||||
}
|
||||
|
||||
},{}],6:[function(require,module,exports){
|
||||
},{}],4:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -2024,7 +1261,7 @@ module.exports = function (Y/* :any */) {
|
||||
Y.Struct = Struct
|
||||
}
|
||||
|
||||
},{}],7:[function(require,module,exports){
|
||||
},{}],5:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -2118,7 +1355,7 @@ module.exports = function (Y/* :any */) {
|
||||
var sid = JSON.stringify(id)
|
||||
var t = this.store.initializedTypes[sid]
|
||||
if (t == null) {
|
||||
var op = yield* this.getOperation(id)
|
||||
var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id)
|
||||
if (op != null) {
|
||||
t = yield* Y[op.type].initType.call(this, this.store, op)
|
||||
this.store.initializedTypes[sid] = t
|
||||
@ -2425,7 +1662,7 @@ module.exports = function (Y/* :any */) {
|
||||
|
||||
if (o.parent != null) {
|
||||
// remove gc'd op from parent, if it exists
|
||||
var parent = yield* this.getOperation(o.parent)
|
||||
var parent /* MapOperation */ = yield* this.getOperation(o.parent)
|
||||
var setParent = false // whether to save parent to the os
|
||||
if (o.parentSub != null) {
|
||||
if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {
|
||||
@ -2585,8 +1822,23 @@ module.exports = function (Y/* :any */) {
|
||||
})
|
||||
}
|
||||
}
|
||||
* getOperation (id) {
|
||||
return yield* this.os.find(id)
|
||||
* getOperation (id/* :any */)/* :Transaction<any> */ {
|
||||
var o = yield* this.os.find(id)
|
||||
if (o != null || id[0] != '_') {
|
||||
return o
|
||||
} 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)
|
||||
} else {
|
||||
// Can only generate one operation at a time
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
* removeOperation (id) {
|
||||
yield* this.os.delete(id)
|
||||
@ -2716,7 +1968,7 @@ module.exports = function (Y/* :any */) {
|
||||
Y.Transaction = TransactionInterface
|
||||
}
|
||||
|
||||
},{}],8:[function(require,module,exports){
|
||||
},{}],6:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -3032,7 +2284,7 @@ module.exports = function (Y /* :any */) {
|
||||
})
|
||||
}
|
||||
|
||||
},{}],9:[function(require,module,exports){
|
||||
},{}],7:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -3259,7 +2511,7 @@ module.exports = function (Y /* : any*/) {
|
||||
Y.utils.compareIds = compareIds
|
||||
}
|
||||
|
||||
},{}],10:[function(require,module,exports){
|
||||
},{}],8:[function(require,module,exports){
|
||||
/* @flow */
|
||||
'use strict'
|
||||
|
||||
@ -3295,7 +2547,8 @@ function requestModules (modules) {
|
||||
// module does not exist
|
||||
if (typeof window !== 'undefined') {
|
||||
var imported = document.createElement('script')
|
||||
imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + '.js'
|
||||
var extention = typeof regeneratorRuntime === "undefined" ? '.es6' : '.js'
|
||||
imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention
|
||||
document.head.appendChild(imported)
|
||||
|
||||
let requireModule = {}
|
||||
@ -3331,26 +2584,28 @@ type DbOptions = MemoryOptions | IndexedDBOptions
|
||||
type WebRTCOptions = {
|
||||
name: 'webrtc',
|
||||
room: string
|
||||
}
|
||||
}
|
||||
type WebsocketsClientOptions = {
|
||||
name: 'websockets-client',
|
||||
room: string
|
||||
}
|
||||
type ConnectionOptions = WebRTCOptions | WebsocketsClientOptions
|
||||
|
||||
type TypesOptions = Array<'array'|'map'|'text'>
|
||||
|
||||
type YOptions = {
|
||||
connector: ConnectionOptions,
|
||||
db: DbOptions,
|
||||
types: TypesOptions,
|
||||
sourceDir: string
|
||||
types: Array<TypeName>,
|
||||
sourceDir: string,
|
||||
share: {[key: string]: TypeName}
|
||||
}
|
||||
*/
|
||||
|
||||
function Y (opts/* :YOptions */) /* :Promise<YConfig> */ {
|
||||
opts.types = opts.types != null ? opts.types : []
|
||||
var modules = [opts.db.name, opts.connector.name].concat(opts.types)
|
||||
for (var name in opts.share) {
|
||||
modules.push(opts.share[name])
|
||||
}
|
||||
Y.sourceDir = opts.sourceDir
|
||||
return Y.requestModules(modules).then(function () {
|
||||
return new Promise(function (resolve) {
|
||||
@ -3367,24 +2622,19 @@ class YConfig {
|
||||
/* ::
|
||||
db: Y.AbstractDatabase;
|
||||
connector: Y.AbstractConnector;
|
||||
share: {[key: string]: any};
|
||||
*/
|
||||
constructor (opts, callback) {
|
||||
this.db = new Y[opts.db.name](this, opts.db)
|
||||
this.connector = new Y[opts.connector.name](this, opts.connector)
|
||||
var share = {}
|
||||
this.share = share
|
||||
this.db.requestTransaction(function * requestTransaction () {
|
||||
// create initial Map type
|
||||
var model = {
|
||||
id: ['_', 0],
|
||||
struct: 'Map',
|
||||
type: 'Map',
|
||||
map: {}
|
||||
// create shared object
|
||||
for (var propertyname in opts.share) {
|
||||
share[propertyname] = yield* this.getType(['_', opts.share[propertyname] + '_' + propertyname])
|
||||
}
|
||||
yield* this.store.tryExecute.call(this, model)
|
||||
var root = yield* this.getType(model.id)
|
||||
this.store.y.root = root
|
||||
setTimeout(function () {
|
||||
callback()
|
||||
}, 0)
|
||||
setTimeout(callback, 0)
|
||||
})
|
||||
}
|
||||
isConnected () {
|
||||
@ -3408,5 +2658,5 @@ if (typeof window !== 'undefined') {
|
||||
window.Y = Y
|
||||
}
|
||||
|
||||
},{"./Connector.js":3,"./Connectors/Test.js":4,"./Database.js":5,"./Struct.js":6,"./Transaction.js":7,"./Types/Map.js":8,"./Utils.js":9}]},{},[2,10])
|
||||
},{"./Connector.js":1,"./Connectors/Test.js":2,"./Database.js":3,"./Struct.js":4,"./Transaction.js":5,"./Types/Map.js":6,"./Utils.js":7}]},{},[8])
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user