Compare commits

..

3 Commits

Author SHA1 Message Date
Kevin Jahns
8739fd3a9c Deploy 12.3.3 2017-08-04 20:36:37 +02:00
Kevin Jahns
b3b12958fa Deploy 12.3.2 2017-07-19 18:50:48 +02:00
Kevin Jahns
42aa7ec5c9 Deploy 12.3.1 2017-06-17 14:32:22 +02:00
6 changed files with 109 additions and 79 deletions

View File

@@ -22,6 +22,7 @@ is a list of the modules we know of:
|[webrtc](https://github.com/y-js/y-webrtc) | Propagate updates Browser2Browser via WebRTC|
|[websockets](https://github.com/y-js/y-websockets-client) | Set up [a central server](https://github.com/y-js/y-websockets-client), and connect to it via websockets |
|[xmpp](https://github.com/y-js/y-xmpp) | Propagate updates in a XMPP multi-user-chat room ([XEP-0045](http://xmpp.org/extensions/xep-0045.html))|
|[ipfs](https://github.com/ipfs-labs/y-ipfs-connector) | Connector for the [Interplanetary File System](https://ipfs.io/)!|
|[test](https://github.com/y-js/y-test) | A Connector for testing purposes. It is designed to simulate delays that happen in worst case scenarios|
##### Database adapters
@@ -54,23 +55,23 @@ Install Yjs, and its modules with [bower](http://bower.io/), or
[npm](https://www.npmjs.org/package/yjs).
### Bower
```
```sh
bower install --save yjs y-array % add all y-* modules you want to use
```
You only need to include the `y.js` file. Yjs is able to automatically require
missing modules.
```
```html
<script src="./bower_components/yjs/y.js"></script>
```
### Npm
```
```sh
npm install --save yjs % add all y-* modules you want to use
```
If you don't include via script tag, you have to explicitly include all modules!
(Same goes for other module systems)
```
```js
var Y = require('yjs')
require('y-array')(Y) // add the y-array type to Yjs
require('y-websockets-client')(Y)
@@ -83,7 +84,7 @@ require('y-text')(Y)
```
### ES6 Syntax
```
```js
import Y from 'yjs'
import yArray from 'y-array'
import yWebsocketsClient from 'y-webrtc'
@@ -97,7 +98,7 @@ Y.extend(yArray, yWebsocketsClient, yMemory, yArray, yMap, yText /*, .. */)
# Text editing example
Install dependencies
```
```sh
bower i yjs y-memory y-webrtc y-array y-text
```
@@ -165,6 +166,25 @@ soon, if possible.
endpoint of the used connector.
* All of our connectors also have a default connection endpoint that you can
use for development.
* We provide basic authentification for all connectors. The value of
`options.connector.auth` (this can be a passphase) is sent to all connected
Yjs instances. `options.connector.checkAuth` may grant read or write access
depending on the `auth` information.
Example: A client specifies `options.connector.auth = 'superSecretPassword`.
A server specifies
```js
options.connector.checkAuth = function (auth, yjsInstance, sender) {
return new Promise(function (resolve, reject){
if (auth === 'superSecretPassword') {
resolve('write') // grant read-write access
} else if (auth === 'different password') {
resolve('read') // grant read-only access
} else {
reject('wrong password!') // reject connection
}
})
}
```
* Set `options.connector.generateUserId = true` in order to genenerate a
userid, instead of receiving one from the server. This way the `Y(..)` is
immediately going to be resolved, without waiting for any confirmation from
@@ -180,7 +200,7 @@ soon, if possible.
* Defaults to `/bower_components`
* Not required when running on `nodejs` / `iojs`
* When using nodejs you need to manually extend Yjs:
```
```js
var Y = require('yjs')
// you have to require a db, connector, and *all* types you use!
require('y-memory')(Y)

View File

@@ -1,6 +1,6 @@
{
"name": "yjs",
"version": "12.3.0",
"version": "12.3.3",
"homepage": "y-js.org",
"authors": [
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"

140
y.es6
View File

@@ -1,6 +1,6 @@
/**
* yjs - A framework for real-time p2p shared editing on any data
* @version v12.2.1
* @version v12.3.2
* @link http://y-js.org
* @license MIT
*/
@@ -48,20 +48,20 @@ function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window && typeof window.process !== 'undefined' && window.process.type === 'renderer') {
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
return true;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document && 'WebkitAppearance' in document.documentElement.style) ||
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window && window.console && (console.firebug || (console.exception && console.table))) ||
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
@@ -403,11 +403,11 @@ function coerce(val) {
* Helpers.
*/
var s = 1000
var m = s * 60
var h = m * 60
var d = h * 24
var y = d * 365.25
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var y = d * 365.25;
/**
* Parse or format the given `val`.
@@ -423,18 +423,19 @@ var y = d * 365.25
* @api public
*/
module.exports = function (val, options) {
options = options || {}
var type = typeof val
module.exports = function(val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val)
return parse(val);
} else if (type === 'number' && isNaN(val) === false) {
return options.long ?
fmtLong(val) :
fmtShort(val)
return options.long ? fmtLong(val) : fmtShort(val);
}
throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
@@ -445,53 +446,55 @@ module.exports = function (val, options) {
*/
function parse(str) {
str = String(str)
if (str.length > 10000) {
return
str = String(str);
if (str.length > 100) {
return;
}
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return
return;
}
var n = parseFloat(match[1])
var type = (match[2] || 'ms').toLowerCase()
var n = parseFloat(match[1]);
var type = (match[2] || 'ms').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y
return n * y;
case 'days':
case 'day':
case 'd':
return n * d
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n
return n;
default:
return undefined
return undefined;
}
}
@@ -505,18 +508,18 @@ function parse(str) {
function fmtShort(ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd'
return Math.round(ms / d) + 'd';
}
if (ms >= h) {
return Math.round(ms / h) + 'h'
return Math.round(ms / h) + 'h';
}
if (ms >= m) {
return Math.round(ms / m) + 'm'
return Math.round(ms / m) + 'm';
}
if (ms >= s) {
return Math.round(ms / s) + 's'
return Math.round(ms / s) + 's';
}
return ms + 'ms'
return ms + 'ms';
}
/**
@@ -532,7 +535,7 @@ function fmtLong(ms) {
plural(ms, h, 'hour') ||
plural(ms, m, 'minute') ||
plural(ms, s, 'second') ||
ms + ' ms'
ms + ' ms';
}
/**
@@ -541,12 +544,12 @@ function fmtLong(ms) {
function plural(ms, n, name) {
if (ms < n) {
return
return;
}
if (ms < n * 1.5) {
return Math.floor(ms / n) + ' ' + name
return Math.floor(ms / n) + ' ' + name;
}
return Math.ceil(ms / n) + ' ' + name + 's'
return Math.ceil(ms / n) + ' ' + name + 's';
}
},{}],4:[function(require,module,exports){
@@ -736,9 +739,6 @@ process.chdir = function (dir) {
process.umask = function() { return 0; };
},{}],5:[function(require,module,exports){
/* @flow */
'use strict'
function canRead (auth) { return auth === 'read' || auth === 'write' }
function canWrite (auth) { return auth === 'write' }
@@ -777,7 +777,6 @@ module.exports = function (Y/* :any */) {
// this client receives operations from only one other client.
// In particular, this does not work with y-webrtc.
// It will work with y-websockets-client
this.preferUntransformed = opts.preferUntransformed || false
if (opts.role == null || opts.role === 'master') {
this.role = 'master'
} else if (opts.role === 'slave') {
@@ -817,7 +816,7 @@ module.exports = function (Y/* :any */) {
}
reconnect () {
this.log('reconnecting..')
this.y.db.startGarbageCollector()
return this.y.db.startGarbageCollector()
}
disconnect () {
this.log('discronnecting..')
@@ -826,7 +825,8 @@ module.exports = function (Y/* :any */) {
this.currentSyncTarget = null
this.syncingClients = []
this.whenSyncedListeners = []
return this.y.db.stopGarbageCollector()
this.y.db.stopGarbageCollector()
return this.y.db.whenTransactionsFinished()
}
repair () {
this.log('Repairing the state of Yjs. This can happen if messages get lost, and Yjs detects that something is wrong. If this happens often, please report an issue here: https://github.com/y-js/yjs/issues')
@@ -928,9 +928,6 @@ module.exports = function (Y/* :any */) {
protocolVersion: conn.protocolVersion,
auth: conn.authInfo
}
if (conn.preferUntransformed && Object.keys(stateSet).length === 0) {
answer.preferUntransformed = true
}
conn.send(syncUser, answer)
})
} else {
@@ -1009,7 +1006,7 @@ module.exports = function (Y/* :any */) {
}
if (message.auth != null && this.connections[sender] != null) {
// authenticate using auth in message
var auth = this.checkAuth(message.auth, this.y)
var auth = this.checkAuth(message.auth, this.y, sender)
this.connections[sender].auth = auth
auth.then(auth => {
for (var f of this.userEventListeners) {
@@ -1022,7 +1019,7 @@ module.exports = function (Y/* :any */) {
})
} else if (this.connections[sender] != null && this.connections[sender].auth == null) {
// authenticate without otherwise
this.connections[sender].auth = this.checkAuth(null, this.y)
this.connections[sender].auth = this.checkAuth(null, this.y, sender)
}
if (this.connections[sender] != null && this.connections[sender].auth != null) {
return this.connections[sender].auth.then((auth) => {
@@ -1044,11 +1041,7 @@ module.exports = function (Y/* :any */) {
protocolVersion: this.protocolVersion,
auth: this.authInfo
}
if (message.preferUntransformed === true && Object.keys(m.stateSet).length === 0) {
answer.osUntransformed = yield* this.getOperationsUntransformed()
} else {
answer.os = yield* this.getOperations(m.stateSet)
}
answer.os = yield* this.getOperations(m.stateSet)
conn.send(sender, answer)
if (this.forwardToSyncingClients) {
conn.syncingClients.push(sender)
@@ -2533,7 +2526,7 @@ module.exports = function (Y/* :any */) {
send.push(Y.Struct[op.struct].encode(op))
}
}
if (this.store.y.connector.isSynced && send.length > 0) { // TODO: && !this.store.forwardAppliedOperations (but then i don't send delete ops)
if (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.broadcastOps(send)
}
@@ -3154,7 +3147,7 @@ module.exports = function (Y/* :any */) {
}
* addOperation (op) {
yield* this.os.put(op)
if (this.store.y.connector.isSynced && this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {
if (this.store.forwardAppliedOperations && typeof op.id[1] !== 'string') {
// is connected, and this is not going to be send in addOperation
this.store.y.connector.broadcastOps([op])
}
@@ -3568,9 +3561,13 @@ module.exports = function (Y /* : any*/) {
event.path = []
while (type != null && type._deepEventHandler != null) {
type._deepEventHandler.callEventListeners(event)
if (type._parent != null && type._parentSub != null) {
event.path = [type._parentSub].concat(event.path)
type = type.os.getType(type._parent)
var parent = null
if (type._parent != null) {
parent = type.os.getType(type._parent)
}
if (parent != null && parent._getPathToChild != null) {
event.path = [parent._getPathToChild(type._model)].concat(event.path)
type = parent
} else {
type = null
}
@@ -4015,7 +4012,20 @@ module.exports = function (Y /* : any*/) {
Default class of custom types!
*/
class CustomType {
getPath () {
var parent = null
if (this._parent != null) {
parent = this.os.getType(this._parent)
}
if (parent != null && parent._getPathToChild != null) {
var firstKey = parent._getPathToChild(this._model)
var parentKeys = parent.getPath()
parentKeys.push(firstKey)
return parentKeys
} else {
return []
}
}
}
Y.utils.CustomType = CustomType

File diff suppressed because one or more lines are too long

8
y.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long