Compare commits

...

13 Commits

Author SHA1 Message Date
Kevin Jahns
bbfb1d9bcb Deploy 12.1.6 2017-03-20 19:15:59 +01:00
Kevin Jahns
e1108d4007 Deploy 12.1.5 2017-03-06 13:27:26 +01:00
Kevin Jahns
c00dee819f Deploy 12.1.4 2016-12-19 10:41:55 +01:00
Kevin Jahns
92b9cb8143 Deploy 12.1.3 2016-11-22 13:12:32 +01:00
Kevin Jahns
5dad1ed410 update webworker example 2016-11-21 16:28:20 +01:00
Kevin Jahns
b613630cef improved examples 2016-11-16 18:08:01 +01:00
Kevin Jahns
afa05b62a1 added sw example 2016-11-14 16:29:04 +01:00
Kevin Jahns
957d650f81 Deploy 12.1.2 2016-11-10 17:01:53 +01:00
Kevin Jahns
9769968c1c Deploy 12.1.1 2016-11-09 14:26:32 +01:00
Kevin Jahns
1e30a877e6 merge 2016-11-09 14:17:00 +01:00
Kevin Jahns
7744993dde Deploy 12.1.0 2016-10-29 21:45:33 +02:00
Kevin Jahns
cf3969dff6 fix richtext example 2016-10-13 17:28:22 +02:00
Kevin Jahns
549ab76b42 Deploy 12.0.4 2016-10-12 15:52:00 +02:00
12 changed files with 943 additions and 264 deletions

View File

@@ -2,7 +2,7 @@
<html>
<head>
<style type="text/css" media="screen">
#ace {
#aceContainer {
position: absolute;
top: 0;
right: 0;
@@ -23,10 +23,10 @@
</head>
<body>
<div id="ace"></div>
<div id="aceContainer"></div>
<script src="../bower_components/yjs/y.es6"></script>
<script src="../bower_components/ace-builds/src/ace.js"></script>
<script src="./index.js"></script>
</body>
</html>

View File

@@ -17,7 +17,7 @@ Y({
window.yAce = y
// bind the textarea to a shared text element
var editor = ace.edit('ace')
var editor = ace.edit('aceContainer')
editor.setTheme('ace/theme/chrome')
editor.getSession().setMode('ace/mode/javascript')

View File

@@ -36,17 +36,4 @@ Y({
});
// bind quill to richtext type
y.share.richtext.bind(window.quill)
})
Y({
db: {
name: 'indexeddb'
},
connector: {
name: 'websockets-client',
room: 'test42'
},
share: {
state : 'Map'
}
}).then((y) => { window.y = y })
})

View File

@@ -8,6 +8,7 @@ Y({
connector: {
name: 'websockets-client',
room: 'Textarea-example'
// url: '127.0.0.1:1234'
},
sourceDir: '/bower_components',
share: {

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<!-- quill does not include dist files! We are using the hosted version instead -->
<!--link rel="stylesheet" href="../bower_components/quill/dist/quill.snow.css" /-->
<link href="https://cdn.quilljs.com/1.0.4/quill.snow.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.2.0/styles/monokai-sublime.min.css" rel="stylesheet">
<style>
#quill-container {
border: 1px solid gray;
box-shadow: 0px 0px 10px gray;
}
</style>
</head>
<body>
<div id="quill-container">
<div id="quill">
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.2.0/highlight.min.js" type="text/javascript"></script>
<script src="https://cdn.quilljs.com/1.0.4/quill.js"></script>
<!-- quill does not include dist files! We are using the hosted version instead (see above)
<script src="../bower_components/quill/dist/quill.js"></script>
-->
<script src="../bower_components/yjs/y.es6"></script>
<script src="./index.js"></script>
</body>
</html>

View File

@@ -0,0 +1,39 @@
/* global Y, Quill */
// initialize a shared object. This function call returns a promise!
Y({
db: {
name: 'memory'
},
connector: {
name: 'webworker',
url: '../bower_components/y-webworker/yjs-webworker.js',
room: 'WebWorkerExample2'
},
sourceDir: '/bower_components',
share: {
richtext: 'Richtext' // y.share.richtext is of type Y.Richtext
}
}).then(function (y) {
window.yQuill = y
// create quill element
window.quill = new Quill('#quill', {
modules: {
formula: true,
syntax: true,
toolbar: [
[{ size: ['small', false, 'large', 'huge'] }],
['bold', 'italic', 'underline'],
[{ color: [] }, { background: [] }], // Snow theme fills in values
[{ script: 'sub' }, { script: 'super' }],
['link', 'image'],
['link', 'code-block'],
[{list: 'ordered' }]
]
},
theme: 'snow'
})
// bind quill to richtext type
y.share.richtext.bind(window.quill)
})

109
README.md
View File

@@ -1,13 +1,13 @@
# ![Yjs](http://y-js.org/images/yjs.png)
Yjs is a framework for p2p shared editing on structured data like (rich-)text, json, and XML.
It is similar to [ShareJs] and [OpenCoweb], but easy to use.
Yjs is a framework for offline-first p2p shared editing on structured data like text, richtext, json, or XML.
It is fairly easy to get started, as Yjs hides most of the complexity of concurrent editing.
For additional information, demos, and tutorials visit [y-js.org](http://y-js.org/).
### Extensions
Yjs only knows how to resolve conflicts on shared data. You have to choose a ..
* *Connector* - a communication protocol that propagates changes to the clients
* *Connector* - a communication protocol that propagates changes to the clients
* *Database* - a database to store your changes
* one or more *Types* - that represent the shared data
@@ -41,8 +41,14 @@ Connectors, Databases, and Types are available as modules that extend Yjs. Here
|[text](https://github.com/y-js/y-text) | Collaborate on text. Supports two way binding to the [Ace Editor](https://ace.c9.io), textareas, input elements, and HTML elements (e.g. <*h1*>, or <*p*>) |
|[richtext](https://github.com/y-js/y-richtext) | Collaborate on rich text. Supports two way binding to the [Quill Rich Text Editor](http://quilljs.com/)|
## Use it!
Install Yjs, and its modules with [bower](http://bower.io/), or [npm](https://www.npmjs.org/package/yjs).
##### Other
| Name | Description |
|-----------|-------------------|
|[y-element](http://y-js.org/y-element/) | Yjs Polymer Element |
## Use it!
Install Yjs, and its modules with [bower](http://bower.io/), or [npm](https://www.npmjs.org/package/yjs).
### Bower
```
@@ -91,23 +97,23 @@ bower i yjs y-memory y-webrtc y-array y-text
```
Here is a simple example of a shared textarea
```
```HTML
<!DOCTYPE html>
<html>
<body>
<script src="./bower_components/yjs/y.js"></script>
<!-- Yjs automatically includes all missing dependencies (browser only) -->
<script>
Y({
db: {
name: 'memory' // use memory database adapter.
// name: 'indexeddb'
// name: 'leveldb'
// name: 'indexeddb' // use indexeddb database adapter instead for offline apps
},
connector: {
name: 'webrtc', // use webrtc connector
// name: 'websockets-client'
// name: 'xmpp'
room: 'my-room' // clients connecting to the same room share data
room: 'my-room' // clients connecting to the same room share data
},
sourceDir: '/bower_components', // location of the y-* modules (browser only)
share: {
@@ -116,10 +122,10 @@ Here is a simple example of a shared textarea
}).then(function (y) {
// The Yjs instance `y` is available
// y.share.* contains the shared types
// Bind the textarea to y.share.textarea
// Bind `y.share.textarea` to `<textarea/>`
y.share.textarea.bind(document.querySelector('textarea'))
}
})
</script>
<textarea></textarea>
</body>
@@ -134,6 +140,9 @@ Report _any_ issues to the [Github issue page](https://github.com/y-js/yjs/issue
# API
### Y(options)
* Y.extend(module1, module2, ..)
* Add extensions to Y
* `Y.extend(require('y-webrtc'))` has the same semantics as `require('y-webrtc')(Y)`
* options.db
* Will be forwarded to the database adapter. Specify the database adaper on `options.db.name`.
* Have a look at the used database adapter repository to see all available options.
@@ -141,7 +150,8 @@ Report _any_ issues to the [Github issue page](https://github.com/y-js/yjs/issue
* Will be forwarded to the connector adapter. Specify the connector adaper on `options.connector.name`.
* All our connectors implement a `room` property. Clients that specify the same room share the same data.
* All of our connectors specify an `url` property that defines the connection endpoint of the used connector.
* All of our connectors also have a default connection endpoint that you can use for development.
* All of our connectors also have a default connection endpoint that you can use for development.
* 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 the server. Use with caution.
* Have a look at the used connector repository to see all available options.
* options.sourceDir (browser only)
* Path where all y-* modules are stored
@@ -150,12 +160,12 @@ Report _any_ issues to the [Github issue page](https://github.com/y-js/yjs/issue
* When using nodejs you need to manually extend Yjs:
```
var Y = require('yjs')
// you have to require a db, connector, and *all* types you use!
// you have to require a db, connector, and *all* types you use!
require('y-memory')(Y)
require('y-webrtc')(Y)
require('y-map')(Y)
// ..
```
```
* options.share
* Specify on `options.share[arbitraryName]` types that are shared among all users.
* E.g. Specify `options.share[arbitraryName] = 'Array'` to require y-array and create an y-array type on `y.share[arbitraryName]`.
@@ -195,61 +205,46 @@ The promise returns an instance of Y. We denote it with a lower case `y`.
* Force to disconnect this instance from the other instances
* y.connector.reconnect()
* Try to reconnect to the other instances (needs to be supported by the connector)
* Not supported by y-xmpp
* y.destroy()
* Not supported by y-xmpp
* y.close()
* Destroy this object.
* Destroys all types (they will throw weird errors if you still use them)
* Disconnects from the other instances (via connector)
* Returns a promise
* y.destroy()
* calls y.close()
* Removes all data from the database
* Returns a promise
* y.db.stopGarbageCollector()
* Stop the garbage collector. Call y.db.garbageCollect() to continue garbage collection
* y.db.gc :: Boolean
* Whether gc is turned on
* y.db.gcTimeout :: Number (defaults to 50000 ms)
* Time interval between two garbage collect cycles
* It is required that all instances exchanged all messages after two garbage collect cycles (after 100000 ms per default)
* y.db.userId :: String
* The used user id for this client. **Never overwrite this**
## Changelog
### Logging
Yjs uses [debug](https://github.com/visionmedia/debug) for logging. The flag
`y*` enables logging for all y-* components. You can selectively remove
components you are not interested in: E.g. The flag `y*,-y:connector-message`
will not log the long `y:connector-message` messages.
### 12.0.0
* **Types are synchronous and never return a promise (except explicitly stated)**
* `y.share.map.get('map type') // => returns a y-map instead of a promise`
* The event property `oldValues`, and `values` contain a list of values (without wrapper)
* Support for the [y-leveldb](https://github.com/y-js/y-leveldb) database adapter
* [y-richtext](https://github.com/y-js/y-richtext) supports Quill@1.0.0-rc.2
* Only the types are affected by this release. You have to upgrade y-array@10.0.0, y-map@10.0.0, y-richtext@9.0.0, and y-xml@10.0.0
##### Enable logging in Node.js
```sh
DEBUG=y* node app.js
```
### 11.0.0
* **All types return a single event instead of list of events**
* Insert events contain a list of values
* Improved performance for large insertions & deletions
* Several bugfixes (offline editing related)
* Native support for node 4 (see #49)
### 10.0.0
* Support for more complex types (a type can be a composition of several types)
* Fixes several memory leaks
### 9.0.0
There were several rolling updates from 0.6 to 0.8. We consider Yjs stable since a long time,
and intend to continue stable releases. From this release forward y-* modules will implement peer-dependencies for npm, and dependencies for bower.
Furthermore, incompatible yjs instances throw errors now when syncing - this feature was influenced by #48. The versioning jump was influenced by react (see [here](https://facebook.github.io/react/blog/2016/02/19/new-versioning-scheme.html))
### 0.6.0
This is a complete rewrite of the 0.5 version of Yjs. Since Yjs 0.6.0 it is possible to work asynchronously on a persistent database, which enables offline support.
* Switched to semver versioning
* Requires a promise implementation in environment (es6 promises suffice, included in all the major browsers). Otherwise you have to include a polyfill
* Y.Object has been renamed to Y.Map
* Y.Map exchanges `.val(name [, value])` in favor of `.set(name, value)` and `.get(name)`
* Y.Map `.get(name)` returns a promise, if the value is a custom type
* The Connector definition slightly changed (I'll update the wiki)
* The Type definitions completely changed, so you have to rewrite them (I'll rewrite the article in the wiki)
* Support for several packaging systems
* Flowtype
Remove the colors in order to log to a file:
```sh
DEBUG_COLORS=0 DEBUG=y* node app.js > log
```
##### Enable logging in the browser
```js
localStorage.debug = 'y*'
```
## Contribution
I created this framework during my bachelor thesis at the chair of computer science 5 [(i5)](http://dbis.rwth-aachen.de/cms), RWTH University. Since December 2014 I'm working on Yjs as a part of my student worker job at the i5.
@@ -258,7 +253,3 @@ I created this framework during my bachelor thesis at the chair of computer scie
Yjs is licensed under the [MIT License](./LICENSE).
<yjs@dbis.rwth-aachen.de>
[ShareJs]: https://github.com/share/ShareJS
[OpenCoweb]: https://github.com/opencoweb/coweb/wiki

View File

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

986
y.es6

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

12
y.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long