Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0600197977 | ||
|
|
f4327529b9 | ||
|
|
67189f4d44 | ||
|
|
6225fb4dfd | ||
|
|
a7550fe5d3 | ||
|
|
9d9c84f40e | ||
|
|
ae91902de3 | ||
|
|
033d24eee7 | ||
|
|
8abef69aa7 | ||
|
|
7e4dedab38 | ||
|
|
85e488bbe6 | ||
|
|
a6a321da10 | ||
|
|
008764ccdc | ||
|
|
de5f4abe32 | ||
|
|
382d06f6d4 | ||
|
|
66de422749 | ||
|
|
bbf5e39408 |
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
|||||||
[submodule "dist"]
|
|
||||||
path = dist
|
|
||||||
url = https://github.com/y-js/yjs.git
|
|
||||||
branch = dist
|
|
||||||
1
dist
1
dist
Submodule dist deleted from 42aa7ec5c9
@@ -1,5 +1,4 @@
|
|||||||
/* @flow */
|
/* global Y, chat */
|
||||||
/* global Y */
|
|
||||||
|
|
||||||
// initialize a shared object. This function call returns a promise!
|
// initialize a shared object. This function call returns a promise!
|
||||||
Y({
|
Y({
|
||||||
@@ -20,7 +19,7 @@ Y({
|
|||||||
function appendMessage (message, position) {
|
function appendMessage (message, position) {
|
||||||
var p = document.createElement('p')
|
var p = document.createElement('p')
|
||||||
var uname = document.createElement('span')
|
var uname = document.createElement('span')
|
||||||
uname.appendChild(document.createTextNode(message.username + ": "))
|
uname.appendChild(document.createTextNode(message.username + ': '))
|
||||||
p.appendChild(uname)
|
p.appendChild(uname)
|
||||||
p.appendChild(document.createTextNode(message.message))
|
p.appendChild(document.createTextNode(message.message))
|
||||||
document.querySelector('#chat').insertBefore(p, chat.children[position] || null)
|
document.querySelector('#chat').insertBefore(p, chat.children[position] || null)
|
||||||
@@ -28,9 +27,8 @@ Y({
|
|||||||
// This function makes sure that only 7 messages exist in the chat history.
|
// This function makes sure that only 7 messages exist in the chat history.
|
||||||
// The rest is deleted
|
// The rest is deleted
|
||||||
function cleanupChat () {
|
function cleanupChat () {
|
||||||
var len
|
if (y.share.chat.length > 7) {
|
||||||
while ((len = y.share.chat.length) > 7) {
|
y.share.chat.delete(0, y.chat.length - 7)
|
||||||
y.share.chat.delete(0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Insert the initial content
|
// Insert the initial content
|
||||||
@@ -40,11 +38,11 @@ Y({
|
|||||||
// whenever content changes, make sure to reflect the changes in the DOM
|
// whenever content changes, make sure to reflect the changes in the DOM
|
||||||
y.share.chat.observe(function (event) {
|
y.share.chat.observe(function (event) {
|
||||||
if (event.type === 'insert') {
|
if (event.type === 'insert') {
|
||||||
for (var i = 0; i < event.length; i++) {
|
for (let i = 0; i < event.length; i++) {
|
||||||
appendMessage(event.values[i], event.index + i)
|
appendMessage(event.values[i], event.index + i)
|
||||||
}
|
}
|
||||||
} else if (event.type === 'delete') {
|
} else if (event.type === 'delete') {
|
||||||
for (var i = 0; i < event.length; i++) {
|
for (let i = 0; i < event.length; i++) {
|
||||||
chat.children[event.index].remove()
|
chat.children[event.index].remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,8 +52,8 @@ Y({
|
|||||||
document.querySelector('#chatform').onsubmit = function (event) {
|
document.querySelector('#chatform').onsubmit = function (event) {
|
||||||
// the form is submitted
|
// the form is submitted
|
||||||
var message = {
|
var message = {
|
||||||
username: this.querySelector("[name=username]").value,
|
username: this.querySelector('[name=username]').value,
|
||||||
message: this.querySelector("[name=message]").value
|
message: this.querySelector('[name=message]').value
|
||||||
}
|
}
|
||||||
if (message.username.length > 0 && message.message.length > 0) {
|
if (message.username.length > 0 && message.message.length > 0) {
|
||||||
if (y.share.chat.length > 6) {
|
if (y.share.chat.length > 6) {
|
||||||
@@ -66,7 +64,7 @@ Y({
|
|||||||
// This will call the observe function (see line 40)
|
// This will call the observe function (see line 40)
|
||||||
// and reflect the change in the DOM
|
// and reflect the change in the DOM
|
||||||
y.share.chat.push([message])
|
y.share.chat.push([message])
|
||||||
this.querySelector("[name=message]").value = ""
|
this.querySelector('[name=message]').value = ''
|
||||||
}
|
}
|
||||||
// Do not send this form!
|
// Do not send this form!
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|||||||
@@ -23,7 +23,12 @@ Y({
|
|||||||
var drag = d3.behavior.drag()
|
var drag = d3.behavior.drag()
|
||||||
.on('dragstart', function (params) {
|
.on('dragstart', function (params) {
|
||||||
// get the translation of the element
|
// get the translation of the element
|
||||||
var translation = d3.select(this).attr('transform').slice(10,-1).split(',').map(Number)
|
var translation = d3
|
||||||
|
.select(this)
|
||||||
|
.attr('transform')
|
||||||
|
.slice(10, -1)
|
||||||
|
.split(',')
|
||||||
|
.map(Number)
|
||||||
// mouse coordinates
|
// mouse coordinates
|
||||||
var mouse = d3.mouse(this.parentNode)
|
var mouse = d3.mouse(this.parentNode)
|
||||||
origin = {
|
origin = {
|
||||||
@@ -31,11 +36,11 @@ Y({
|
|||||||
y: mouse[1] - translation[1]
|
y: mouse[1] - translation[1]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("drag", function(){
|
.on('drag', function () {
|
||||||
var mouse = d3.mouse(this.parentNode)
|
var mouse = d3.mouse(this.parentNode)
|
||||||
var x = mouse[0] - origin.x // =^= mouse - mouse at dragstart + translation at dragstart
|
var x = mouse[0] - origin.x // =^= mouse - mouse at dragstart + translation at dragstart
|
||||||
var y = mouse[1] - origin.y
|
var y = mouse[1] - origin.y
|
||||||
d3.select(this).attr("transform", "translate(" + x + "," + y + ")")
|
d3.select(this).attr('transform', 'translate(' + x + ',' + y + ')')
|
||||||
})
|
})
|
||||||
.on('dragend', function (piece, i) {
|
.on('dragend', function (piece, i) {
|
||||||
// save the current translation of the puzzle piece
|
// save the current translation of the puzzle piece
|
||||||
@@ -46,13 +51,13 @@ Y({
|
|||||||
})
|
})
|
||||||
|
|
||||||
var data = [y.share.piece1, y.share.piece2, y.share.piece3, y.share.piece4]
|
var data = [y.share.piece1, y.share.piece2, y.share.piece3, y.share.piece4]
|
||||||
var pieces = d3.select(document.querySelector("#puzzle-example")).selectAll("path").data(data)
|
var pieces = d3.select(document.querySelector('#puzzle-example')).selectAll('path').data(data)
|
||||||
|
|
||||||
pieces
|
pieces
|
||||||
.classed('draggable', true)
|
.classed('draggable', true)
|
||||||
.attr("transform", function (piece) {
|
.attr('transform', function (piece) {
|
||||||
var translation = piece.get('translation') || {x: 0, y: 0}
|
var translation = piece.get('translation') || {x: 0, y: 0}
|
||||||
return "translate(" + translation.x + "," + translation.y + ")"
|
return 'translate(' + translation.x + ',' + translation.y + ')'
|
||||||
}).call(drag)
|
}).call(drag)
|
||||||
|
|
||||||
data.forEach(function (piece) {
|
data.forEach(function (piece) {
|
||||||
@@ -60,9 +65,9 @@ Y({
|
|||||||
// whenever a property of a piece changes, update the translation of the pieces
|
// whenever a property of a piece changes, update the translation of the pieces
|
||||||
pieces
|
pieces
|
||||||
.transition()
|
.transition()
|
||||||
.attr("transform", function (piece) {
|
.attr('transform', function (piece) {
|
||||||
var translation = piece.get('translation') || {x: 0, y: 0}
|
var translation = piece.get('translation') || {x: 0, y: 0}
|
||||||
return "translate(" + translation.x + "," + translation.y + ")"
|
return 'translate(' + translation.x + ',' + translation.y + ')'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* global Y */
|
/* global Y, monaco */
|
||||||
|
|
||||||
require.config({ paths: { 'vs': '../node_modules/monaco-editor/min/vs' } })
|
require.config({ paths: { 'vs': '../node_modules/monaco-editor/min/vs' } })
|
||||||
require(['vs/editor/editor.main'], function() {
|
|
||||||
|
|
||||||
|
require(['vs/editor/editor.main'], function () {
|
||||||
// Initialize a shared object. This function call returns a promise!
|
// Initialize a shared object. This function call returns a promise!
|
||||||
Y({
|
Y({
|
||||||
db: {
|
db: {
|
||||||
@@ -28,4 +28,3 @@ require(['vs/editor/editor.main'], function() {
|
|||||||
y.share.monaco.bindMonaco(editor)
|
y.share.monaco.bindMonaco(editor)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
1173
examples/package-lock.json
generated
Normal file
1173
examples/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,5 +6,11 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"monaco-editor": "^0.8.3"
|
"monaco-editor": "^0.8.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"standard": "^10.0.2"
|
||||||
|
},
|
||||||
|
"standard": {
|
||||||
|
"ignore": ["bower_components"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Y({
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
theme: 'snow'
|
theme: 'snow'
|
||||||
});
|
})
|
||||||
// bind quill to richtext type
|
// bind quill to richtext type
|
||||||
y.share.richtext.bind(window.quill)
|
y.share.richtext.bind(window.quill)
|
||||||
})
|
})
|
||||||
@@ -5,9 +5,9 @@ if('serviceWorker' in navigator){
|
|||||||
// Register service worker
|
// Register service worker
|
||||||
// it is important to copy yjs-sw-template to the root directory!
|
// it is important to copy yjs-sw-template to the root directory!
|
||||||
navigator.serviceWorker.register('./yjs-sw-template.js').then(function (reg) {
|
navigator.serviceWorker.register('./yjs-sw-template.js').then(function (reg) {
|
||||||
console.log("Yjs service worker registration succeeded. Scope is " + reg.scope);
|
console.log('Yjs service worker registration succeeded. Scope is ' + reg.scope)
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
console.error("Yjs service worker registration failed with error " + err);
|
console.error('Yjs service worker registration failed with error ' + err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<textarea style="width:80%;" rows=40 id="textfield" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>
|
<textarea style="width:80%;" rows=40 id="textfield" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>
|
||||||
<script src="../bower_components/yjs/y.js"></script>
|
<script src="../../y.js"></script>
|
||||||
|
<script src="../../../y-array/y-array.js"></script>
|
||||||
|
<script src="../../../y-text/dist/y-text.js"></script>
|
||||||
|
<script src="../../../y-memory/y-memory.js"></script>
|
||||||
|
<script src="../../../y-websockets-client/dist/y-websockets-client.js"></script>
|
||||||
<script src="./index.js"></script>
|
<script src="./index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
156
package-lock.json
generated
156
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "yjs",
|
"name": "yjs",
|
||||||
"version": "13.0.0-0",
|
"version": "13.0.0-2",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": {
|
"acorn": {
|
||||||
@@ -149,15 +149,7 @@
|
|||||||
"version": "6.25.0",
|
"version": "6.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz",
|
||||||
"integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=",
|
"integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
|
||||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"babel-generator": {
|
"babel-generator": {
|
||||||
"version": "6.25.0",
|
"version": "6.25.0",
|
||||||
@@ -487,15 +479,7 @@
|
|||||||
"version": "6.25.0",
|
"version": "6.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz",
|
||||||
"integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=",
|
"integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
|
||||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"babel-types": {
|
"babel-types": {
|
||||||
"version": "6.25.0",
|
"version": "6.25.0",
|
||||||
@@ -504,9 +488,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"babylon": {
|
"babylon": {
|
||||||
"version": "6.17.3",
|
"version": "6.17.4",
|
||||||
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.3.tgz",
|
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz",
|
||||||
"integrity": "sha512-mq0x3HCAGGmQyZXviOVe5TRsw37Ijy3D43jCqt/9WVf+onx2dUgW3PosnqCbScAFhRO9DGs8nxoMzU0iiosMqQ==",
|
"integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
@@ -593,9 +577,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chance": {
|
"chance": {
|
||||||
"version": "1.0.9",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/chance/-/chance-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/chance/-/chance-1.0.10.tgz",
|
||||||
"integrity": "sha1-ha5SwUXEM9afbx7/JPBWASt3pg8=",
|
"integrity": "sha1-A1ALBK2U53jdKJGwnsc6ath7GZY=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
@@ -642,9 +626,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"commander": {
|
"commander": {
|
||||||
"version": "2.9.0",
|
"version": "2.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.10.0.tgz",
|
||||||
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
|
"integrity": "sha512-q/r9trjmuikWDRJNTBHAVnWhuU6w+z80KgBq7j9YDclik5E7X4xi0KnlZBNFA1zOQ+SH/vHMWd2mC9QTOz7GpA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
@@ -660,9 +644,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"concurrently": {
|
"concurrently": {
|
||||||
"version": "3.4.0",
|
"version": "3.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.0.tgz",
|
||||||
"integrity": "sha1-YGYrPe/eBzdbrhmqwKt4DsdIunk=",
|
"integrity": "sha1-jPG3cHppFqeKT/W3e7BN7FSzebI=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
@@ -878,12 +862,6 @@
|
|||||||
"integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=",
|
"integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
|
||||||
"version": "2.6.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
|
||||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"user-home": {
|
"user-home": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
|
||||||
@@ -908,48 +886,20 @@
|
|||||||
"version": "0.2.3",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz",
|
||||||
"integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=",
|
"integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
|
||||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"eslint-module-utils": {
|
"eslint-module-utils": {
|
||||||
"version": "2.0.0",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
|
||||||
"integrity": "sha1-pvjCHZATWHWc3DXbrBmCrh7li84=",
|
"integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
|
||||||
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
|
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ms": {
|
|
||||||
"version": "0.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
|
||||||
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"eslint-plugin-import": {
|
"eslint-plugin-import": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz",
|
||||||
"integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=",
|
"integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
|
||||||
"version": "2.6.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
|
|
||||||
"integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"doctrine": {
|
"doctrine": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
|
||||||
@@ -1017,18 +967,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"esrecurse": {
|
"esrecurse": {
|
||||||
"version": "4.1.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
|
||||||
"integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=",
|
"integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"estraverse": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz",
|
|
||||||
"integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=",
|
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"estraverse": {
|
"estraverse": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
@@ -1090,6 +1032,12 @@
|
|||||||
"integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
|
"integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ez-async": {
|
||||||
|
"version": "1.0.0-alpha.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ez-async/-/ez-async-1.0.0-alpha.1.tgz",
|
||||||
|
"integrity": "sha1-ysNCuPqJAm7+c6Jg/p9rgE9J5H8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"fast-levenshtein": {
|
"fast-levenshtein": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||||
@@ -1121,9 +1069,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"find-root": {
|
"find-root": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
|
||||||
"integrity": "sha1-li/yEaqyXGUg/u641ih/j26VgHo=",
|
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"find-up": {
|
"find-up": {
|
||||||
@@ -2169,9 +2117,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"js-tokens": {
|
"js-tokens": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||||
"integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=",
|
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"js-yaml": {
|
"js-yaml": {
|
||||||
@@ -2587,9 +2535,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.2.11",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
|
||||||
"integrity": "sha512-h+8+r3MKEhkiVrwdKL8aWs1oc1VvBu33ueshOvS26RsZQ3Amhx/oO3TKe4lApSV9ueY6as8EAh7mtuFjdlhg9Q==",
|
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"readdirp": {
|
"readdirp": {
|
||||||
@@ -2834,9 +2782,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.0.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||||
"integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=",
|
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
@@ -2921,9 +2869,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||||
"integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=",
|
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
@@ -2962,6 +2910,12 @@
|
|||||||
"integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
|
"integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||||
@@ -2969,13 +2923,25 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz",
|
||||||
"integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=",
|
"integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tag-dist-files": {
|
||||||
|
"version": "0.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/tag-dist-files/-/tag-dist-files-0.1.6.tgz",
|
||||||
|
"integrity": "sha1-h64FrBQw1H2m76Hrx7Bw+QxnTVQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"text-table": {
|
"text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
|||||||
21
package.json
21
package.json
@@ -1,21 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "yjs",
|
"name": "yjs",
|
||||||
"version": "13.0.0-0",
|
"version": "13.0.0-2",
|
||||||
"description": "A framework for real-time p2p shared editing on any data",
|
"description": "A framework for real-time p2p shared editing on any data",
|
||||||
"main": "./src/y.js",
|
"main": "./src/y.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"test": "npm run lint",
|
||||||
"lint": "standard",
|
"lint": "standard",
|
||||||
"dist": "rollup -c rollup.dist.js",
|
"dist": "rollup -c rollup.dist.js",
|
||||||
"serve": "concurrently 'serve examples' 'rollup -wc rollup.dist.js -o examples/bower_components/yjs/y.js'"
|
"serve": "concurrently 'serve ..' 'rollup -wc rollup.dist.js -o examples/bower_components/yjs/y.js'",
|
||||||
|
"postversion": "npm run dist",
|
||||||
|
"postpublish": "tag-dist-files --overwrite-existing-tag"
|
||||||
},
|
},
|
||||||
"pre-commit": [
|
"files": [
|
||||||
"lint",
|
"y.*"
|
||||||
"test"
|
|
||||||
],
|
],
|
||||||
"standard": {
|
"standard": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"./y.js",
|
"/y.js",
|
||||||
"./y.js.map"
|
"/y.js.map"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -40,10 +42,10 @@
|
|||||||
"homepage": "http://y-js.org",
|
"homepage": "http://y-js.org",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-cli": "^6.24.1",
|
"babel-cli": "^6.24.1",
|
||||||
"babel-preset-latest": "^6.24.1",
|
|
||||||
"babel-plugin-external-helpers": "^6.22.0",
|
"babel-plugin-external-helpers": "^6.22.0",
|
||||||
"babel-plugin-transform-regenerator": "^6.24.1",
|
"babel-plugin-transform-regenerator": "^6.24.1",
|
||||||
"babel-plugin-transform-runtime": "^6.23.0",
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
|
"babel-preset-latest": "^6.24.1",
|
||||||
"chance": "^1.0.9",
|
"chance": "^1.0.9",
|
||||||
"concurrently": "^3.4.0",
|
"concurrently": "^3.4.0",
|
||||||
"rollup-plugin-babel": "^2.7.1",
|
"rollup-plugin-babel": "^2.7.1",
|
||||||
@@ -54,7 +56,8 @@
|
|||||||
"rollup-plugin-uglify": "^1.0.2",
|
"rollup-plugin-uglify": "^1.0.2",
|
||||||
"rollup-regenerator-runtime": "^6.23.1",
|
"rollup-regenerator-runtime": "^6.23.1",
|
||||||
"rollup-watch": "^3.2.2",
|
"rollup-watch": "^3.2.2",
|
||||||
"standard": "^10.0.2"
|
"standard": "^10.0.2",
|
||||||
|
"tag-dist-files": "^0.1.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^2.6.8"
|
"debug": "^2.6.8"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default function extendConnector (Y/* :any */) {
|
|||||||
this.protocolVersion = 11
|
this.protocolVersion = 11
|
||||||
this.authInfo = opts.auth || null
|
this.authInfo = opts.auth || null
|
||||||
this.checkAuth = opts.checkAuth || function () { return Promise.resolve('write') } // default is everyone has write access
|
this.checkAuth = opts.checkAuth || function () { return Promise.resolve('write') } // default is everyone has write access
|
||||||
if (opts.generateUserId === true) {
|
if (opts.generateUserId !== false) {
|
||||||
this.setUserId(Y.utils.generateGuid())
|
this.setUserId(Y.utils.generateGuid())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ export default function extendConnector (Y/* :any */) {
|
|||||||
this.currentSyncTarget = syncUser
|
this.currentSyncTarget = syncUser
|
||||||
this.y.db.requestTransaction(function * () {
|
this.y.db.requestTransaction(function * () {
|
||||||
var stateSet = yield * this.getStateSet()
|
var stateSet = yield * this.getStateSet()
|
||||||
var deleteSet = yield * this.getDeleteSet()
|
// var deleteSet = yield * this.getDeleteSet()
|
||||||
var answer = {
|
var answer = {
|
||||||
type: 'sync step 1',
|
type: 'sync step 1',
|
||||||
stateSet: stateSet,
|
stateSet: stateSet,
|
||||||
@@ -346,21 +346,21 @@ export default function extendConnector (Y/* :any */) {
|
|||||||
let m = message
|
let m = message
|
||||||
// apply operations first
|
// apply operations first
|
||||||
db.requestTransaction(function * () {
|
db.requestTransaction(function * () {
|
||||||
yield * this.applyDeleteSet(m.deleteSet)
|
// yield * this.applyDeleteSet(m.deleteSet)
|
||||||
if (m.osUntransformed != null) {
|
if (m.osUntransformed != null) {
|
||||||
yield * this.applyOperationsUntransformed(m.osUntransformed, m.stateSet)
|
yield * this.applyOperationsUntransformed(m.osUntransformed, m.stateSet)
|
||||||
} else {
|
} else {
|
||||||
this.store.apply(m.os)
|
this.store.apply(m.os)
|
||||||
}
|
}
|
||||||
defer.resolve()
|
// defer.resolve()
|
||||||
})
|
})
|
||||||
/*/ then apply ds
|
// then apply ds
|
||||||
db.whenTransactionsFinished().then(() => {
|
db.whenTransactionsFinished().then(() => {
|
||||||
db.requestTransaction(function * () {
|
db.requestTransaction(function * () {
|
||||||
yield * this.applyDeleteSet(m.deleteSet)
|
yield * this.applyDeleteSet(m.deleteSet)
|
||||||
})
|
})
|
||||||
defer.resolve()
|
defer.resolve()
|
||||||
})*/
|
})
|
||||||
return defer.promise
|
return defer.promise
|
||||||
} else if (message.type === 'sync done') {
|
} else if (message.type === 'sync done') {
|
||||||
var self = this
|
var self = this
|
||||||
|
|||||||
@@ -81,10 +81,6 @@ export default function extendDatabase (Y /* :any */) {
|
|||||||
function garbageCollect () {
|
function garbageCollect () {
|
||||||
return os.whenTransactionsFinished().then(function () {
|
return os.whenTransactionsFinished().then(function () {
|
||||||
if (os.gcTimeout > 0 && (os.gc1.length > 0 || os.gc2.length > 0)) {
|
if (os.gcTimeout > 0 && (os.gc1.length > 0 || os.gc2.length > 0)) {
|
||||||
// debug
|
|
||||||
if (os.y.connector.isSynced === false) {
|
|
||||||
debugger
|
|
||||||
}
|
|
||||||
if (!os.y.connector.isSynced) {
|
if (!os.y.connector.isSynced) {
|
||||||
console.warn('gc should be empty when not synced!')
|
console.warn('gc should be empty when not synced!')
|
||||||
}
|
}
|
||||||
@@ -124,7 +120,7 @@ export default function extendDatabase (Y /* :any */) {
|
|||||||
startGarbageCollector () {
|
startGarbageCollector () {
|
||||||
this.gc = this.dbOpts.gc
|
this.gc = this.dbOpts.gc
|
||||||
if (this.gc) {
|
if (this.gc) {
|
||||||
this.gcTimeout = !this.dbOpts.gcTimeout ? 50000 : this.dbOpts.gcTimeout
|
this.gcTimeout = !this.dbOpts.gcTimeout ? 100000 : this.dbOpts.gcTimeout
|
||||||
} else {
|
} else {
|
||||||
this.gcTimeout = -1
|
this.gcTimeout = -1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,8 +294,9 @@ export default function extendTransaction (Y) {
|
|||||||
yield * this.ds.put(n)
|
yield * this.ds.put(n)
|
||||||
} else {
|
} else {
|
||||||
// already gc'd
|
// already gc'd
|
||||||
throw new Error('Cannot happen! (it dit though.. :()')
|
throw new Error(
|
||||||
// return n
|
'DS reached an inconsistent state. Please report this issue!'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -366,6 +367,7 @@ export default function extendTransaction (Y) {
|
|||||||
operations that can be gc'd and add them to the garbage collector.
|
operations that can be gc'd and add them to the garbage collector.
|
||||||
*/
|
*/
|
||||||
* garbageCollectAfterSync () {
|
* garbageCollectAfterSync () {
|
||||||
|
// debugger
|
||||||
if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {
|
if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {
|
||||||
console.warn('gc should be empty after sync')
|
console.warn('gc should be empty after sync')
|
||||||
}
|
}
|
||||||
@@ -459,16 +461,8 @@ export default function extendTransaction (Y) {
|
|||||||
|
|
||||||
if (o.originOf != null && o.originOf.length > 0) {
|
if (o.originOf != null && o.originOf.length > 0) {
|
||||||
// find new origin of right ops
|
// find new origin of right ops
|
||||||
// origin is the first left deleted operation
|
// origin is the first left operation
|
||||||
var neworigin = o.left
|
var neworigin = o.left
|
||||||
var neworigin_ = null
|
|
||||||
while (neworigin != null) {
|
|
||||||
neworigin_ = yield * this.getInsertion(neworigin)
|
|
||||||
if (neworigin_.deleted) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
neworigin = neworigin_.left
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset origin of all right ops (except first right - duh!),
|
// reset origin of all right ops (except first right - duh!),
|
||||||
|
|
||||||
@@ -513,6 +507,7 @@ export default function extendTransaction (Y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (neworigin != null) {
|
if (neworigin != null) {
|
||||||
|
var neworigin_ = yield * this.getInsertion(neworigin)
|
||||||
if (neworigin_.originOf == null) {
|
if (neworigin_.originOf == null) {
|
||||||
neworigin_.originOf = o.originOf
|
neworigin_.originOf = o.originOf
|
||||||
} else {
|
} else {
|
||||||
@@ -838,10 +833,10 @@ export default function extendTransaction (Y) {
|
|||||||
yield * this.setOperation(op)
|
yield * this.setOperation(op)
|
||||||
return op
|
return op
|
||||||
} else {
|
} else {
|
||||||
// won't be called. but just in case..
|
throw new Error(
|
||||||
console.error('Unexpected case. How can this happen?')
|
'Unexpected case. Operation cannot be generated correctly!' +
|
||||||
debugger // eslint-disable-line
|
'Incompatible Yjs version?'
|
||||||
return null
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -937,21 +932,28 @@ export default function extendTransaction (Y) {
|
|||||||
var send = []
|
var send = []
|
||||||
|
|
||||||
var endSV = yield * this.getStateVector()
|
var endSV = yield * this.getStateVector()
|
||||||
for (var endState of endSV) {
|
for (let endState of endSV) {
|
||||||
var user = endState.user
|
let user = endState.user
|
||||||
if (user === '_') {
|
if (user === '_') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var startPos = startSS[user] || 0
|
let startPos = startSS[user] || 0
|
||||||
if (startPos > 0) {
|
if (startPos > 0) {
|
||||||
// There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)
|
// There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)
|
||||||
// find out if that is the case
|
// find out if that is the case
|
||||||
var firstMissing = yield * this.getInsertion([user, startPos])
|
let firstMissing = yield * this.getInsertion([user, startPos])
|
||||||
if (firstMissing != null) {
|
if (firstMissing != null) {
|
||||||
// update startPos
|
// update startPos
|
||||||
startPos = firstMissing.id[1]
|
startPos = firstMissing.id[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
startSS[user] = startPos
|
startSS[user] = startPos
|
||||||
}
|
}
|
||||||
|
for (let endState of endSV) {
|
||||||
|
let user = endState.user
|
||||||
|
let startPos = startSS[user]
|
||||||
|
if (user === '_') {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
yield * this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
|
yield * this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
|
||||||
op = Y.Struct[op.struct].encode(op)
|
op = Y.Struct[op.struct].encode(op)
|
||||||
@@ -959,7 +961,9 @@ export default function extendTransaction (Y) {
|
|||||||
send.push(op)
|
send.push(op)
|
||||||
} else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {
|
} else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {
|
||||||
// case 1. op.right is known
|
// case 1. op.right is known
|
||||||
var o = op
|
// this case is only reached if op.right is known.
|
||||||
|
// => this is not called for op.left, as op.right is unknown
|
||||||
|
let o = op
|
||||||
// Remember: ?
|
// Remember: ?
|
||||||
// -> set op.right
|
// -> set op.right
|
||||||
// 1. to the first operation that is known (according to startSS)
|
// 1. to the first operation that is known (according to startSS)
|
||||||
@@ -972,11 +976,14 @@ export default function extendTransaction (Y) {
|
|||||||
if (o.left == null) {
|
if (o.left == null) {
|
||||||
op.left = null
|
op.left = null
|
||||||
send.push(op)
|
send.push(op)
|
||||||
if (!Y.utils.compareIds(o.id, op.id)) {
|
/* not necessary, as o is already sent..
|
||||||
|
if (!Y.utils.compareIds(o.id, op.id) && o.id[1] >= (startSS[o.id[0]] || 0)) {
|
||||||
|
// o is not op && o is unknown
|
||||||
o = Y.Struct[op.struct].encode(o)
|
o = Y.Struct[op.struct].encode(o)
|
||||||
o.right = missingOrigins[missingOrigins.length - 1].id
|
o.right = missingOrigins[missingOrigins.length - 1].id
|
||||||
send.push(o)
|
send.push(o)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
o = yield * this.getInsertion(o.left)
|
o = yield * this.getInsertion(o.left)
|
||||||
@@ -996,8 +1003,10 @@ export default function extendTransaction (Y) {
|
|||||||
op = Y.Struct[op.struct].encode(o)
|
op = Y.Struct[op.struct].encode(o)
|
||||||
op.right = newright
|
op.right = newright
|
||||||
if (missingOrigins.length > 0) {
|
if (missingOrigins.length > 0) {
|
||||||
debugger
|
throw new Error(
|
||||||
console.log('This should not happen .. :( please report this')
|
'Reached inconsistent OS state.' +
|
||||||
|
'Operations are not correctly connected.'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
missingOrigins = [op]
|
missingOrigins = [op]
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
34
src/Utils.js
34
src/Utils.js
@@ -42,6 +42,32 @@ export default function Utils (Y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NamedEventHandler {
|
||||||
|
constructor () {
|
||||||
|
this._eventListener = {}
|
||||||
|
}
|
||||||
|
on (name, f) {
|
||||||
|
if (this._eventListener[name] == null) {
|
||||||
|
this._eventListener[name] = []
|
||||||
|
}
|
||||||
|
this._eventListener[name].push(f)
|
||||||
|
}
|
||||||
|
off (name, f) {
|
||||||
|
if (name == null || f == null) {
|
||||||
|
throw new Error('You must specify event name and function!')
|
||||||
|
}
|
||||||
|
let listener = this._eventListener[name] || []
|
||||||
|
this._eventListener[name] = listener.filter(e => e !== f)
|
||||||
|
}
|
||||||
|
emit (name, value) {
|
||||||
|
(this._eventListener[name] || []).forEach(l => l(value))
|
||||||
|
}
|
||||||
|
destroy () {
|
||||||
|
this._eventListener = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Y.utils.NamedEventHandler = NamedEventHandler
|
||||||
|
|
||||||
class EventListenerHandler {
|
class EventListenerHandler {
|
||||||
constructor () {
|
constructor () {
|
||||||
this.eventListeners = []
|
this.eventListeners = []
|
||||||
@@ -72,7 +98,12 @@ export default function Utils (Y) {
|
|||||||
}
|
}
|
||||||
this.eventListeners[i](_event)
|
this.eventListeners[i](_event)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Your observer threw an error. This error was caught so that Yjs still can ensure data consistency! In order to debug this error you have to check "Pause On Caught Exceptions"', e)
|
/*
|
||||||
|
Your observer threw an error. This error was caught so that Yjs
|
||||||
|
can ensure data consistency! In order to debug this error you
|
||||||
|
have to check "Pause On Caught Exceptions" in developer tools.
|
||||||
|
*/
|
||||||
|
console.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -610,6 +641,7 @@ export default function Utils (Y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
Y.utils.matchesId = matchesId
|
Y.utils.matchesId = matchesId
|
||||||
|
|
||||||
|
|||||||
6
src/y.js
6
src/y.js
@@ -144,7 +144,7 @@ export default function Y (opts/* :YOptions */) /* :Promise<YConfig> */ {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
class YConfig {
|
class YConfig extends Y.utils.NamedEventHandler {
|
||||||
/* ::
|
/* ::
|
||||||
db: Y.AbstractDatabase;
|
db: Y.AbstractDatabase;
|
||||||
connector: Y.AbstractConnector;
|
connector: Y.AbstractConnector;
|
||||||
@@ -152,6 +152,7 @@ class YConfig {
|
|||||||
options: Object;
|
options: Object;
|
||||||
*/
|
*/
|
||||||
constructor (opts, callback) {
|
constructor (opts, callback) {
|
||||||
|
super()
|
||||||
this.options = opts
|
this.options = opts
|
||||||
this.db = new Y[opts.db.name](this, opts.db)
|
this.db = new Y[opts.db.name](this, opts.db)
|
||||||
this.connector = new Y[opts.connector.name](this, opts.connector)
|
this.connector = new Y[opts.connector.name](this, opts.connector)
|
||||||
@@ -215,6 +216,9 @@ class YConfig {
|
|||||||
} else {
|
} else {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
}).then(() => {
|
||||||
|
// remove existing event listener
|
||||||
|
super.destroy()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
close () {
|
close () {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import _Y from '../../yjs/src/y.js'
|
import _Y from '../../yjs/src/y.js'
|
||||||
|
|
||||||
import yMemory from '../../y-memory/src/Memory.js'
|
import yMemory from '../../y-memory/src/y-memory.js'
|
||||||
import yArray from '../../y-array/src/y-array.js'
|
import yArray from '../../y-array/src/y-array.js'
|
||||||
import yMap from '../../y-map/src/Map.js'
|
import yMap from '../../y-map/src/Map.js'
|
||||||
import yTest from './test-connector.js'
|
import yTest from './test-connector.js'
|
||||||
@@ -30,12 +30,14 @@ export async function compareUsers (t, users) {
|
|||||||
await wait(100)
|
await wait(100)
|
||||||
}
|
}
|
||||||
await flushAll(t, users)
|
await flushAll(t, users)
|
||||||
|
await wait()
|
||||||
await users[0].db.garbageCollect()
|
await flushAll(t, users)
|
||||||
await users[0].db.garbageCollect()
|
|
||||||
|
|
||||||
var userTypeContents = users.map(u => u.share.array._content.map(c => c.val || JSON.stringify(c.type)))
|
var userTypeContents = users.map(u => u.share.array._content.map(c => c.val || JSON.stringify(c.type)))
|
||||||
|
|
||||||
|
await users[0].db.garbageCollect()
|
||||||
|
await users[0].db.garbageCollect()
|
||||||
|
|
||||||
// disconnect all except user 0
|
// disconnect all except user 0
|
||||||
await Promise.all(users.slice(1).map(async u =>
|
await Promise.all(users.slice(1).map(async u =>
|
||||||
u.disconnect()
|
u.disconnect()
|
||||||
@@ -54,18 +56,29 @@ export async function compareUsers (t, users) {
|
|||||||
u.connector.whenSynced(resolve)
|
u.connector.whenSynced(resolve)
|
||||||
})
|
})
|
||||||
))
|
))
|
||||||
|
let filterDeletedOps = users.every(u => u.db.gc === false)
|
||||||
var data = await Promise.all(users.map(async (u) => {
|
var data = await Promise.all(users.map(async (u) => {
|
||||||
var data = {}
|
var data = {}
|
||||||
u.db.requestTransaction(function * () {
|
u.db.requestTransaction(function * () {
|
||||||
var os = yield * this.getOperationsUntransformed()
|
var os = yield * this.getOperationsUntransformed()
|
||||||
data.os = {}
|
data.os = {}
|
||||||
os.untransformed.forEach((op) => {
|
for (let i = 0; i < os.untransformed.length; i++) {
|
||||||
|
let op = os.untransformed[i]
|
||||||
op = Y.Struct[op.struct].encode(op)
|
op = Y.Struct[op.struct].encode(op)
|
||||||
delete op.origin
|
delete op.origin
|
||||||
|
/*
|
||||||
|
If gc = false, it is necessary to filter deleted ops
|
||||||
|
as they might have been split up differently..
|
||||||
|
*/
|
||||||
|
if (filterDeletedOps) {
|
||||||
|
let opIsDeleted = yield * this.isDeleted(op.id)
|
||||||
|
if (!opIsDeleted) {
|
||||||
data.os[JSON.stringify(op.id)] = op
|
data.os[JSON.stringify(op.id)] = op
|
||||||
return op
|
}
|
||||||
})
|
} else {
|
||||||
|
data.os[JSON.stringify(op.id)] = op
|
||||||
|
}
|
||||||
|
}
|
||||||
data.ds = yield * this.getDeleteSet()
|
data.ds = yield * this.getDeleteSet()
|
||||||
data.ss = yield * this.getStateSet()
|
data.ss = yield * this.getStateSet()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,8 +14,11 @@ export class TestRoom {
|
|||||||
connector.setUserId('' + (this.nextUserId++))
|
connector.setUserId('' + (this.nextUserId++))
|
||||||
}
|
}
|
||||||
Object.keys(this.users).forEach(uid => {
|
Object.keys(this.users).forEach(uid => {
|
||||||
|
let user = this.users[uid]
|
||||||
|
if (user.role === 'master' || connector.role === 'master') {
|
||||||
this.users[uid].userJoined(connector.userId, connector.role)
|
this.users[uid].userJoined(connector.userId, connector.role)
|
||||||
connector.userJoined(uid, this.users[uid].role)
|
connector.userJoined(uid, this.users[uid].role)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
this.users[connector.userId] = connector
|
this.users[connector.userId] = connector
|
||||||
}
|
}
|
||||||
@@ -67,6 +70,7 @@ export default function extendTestConnector (Y) {
|
|||||||
if (options.room == null) {
|
if (options.room == null) {
|
||||||
throw new Error('You must define a room name!')
|
throw new Error('You must define a room name!')
|
||||||
}
|
}
|
||||||
|
options.forwardAppliedOperations = options.role === 'master'
|
||||||
super(y, options)
|
super(y, options)
|
||||||
this.options = options
|
this.options = options
|
||||||
this.room = options.room
|
this.room = options.room
|
||||||
@@ -128,7 +132,7 @@ export default function extendTestConnector (Y) {
|
|||||||
var finished = []
|
var finished = []
|
||||||
for (let i = 0; i < flushUsers.length; i++) {
|
for (let i = 0; i < flushUsers.length; i++) {
|
||||||
let userId = flushUsers[i].connector.userId
|
let userId = flushUsers[i].connector.userId
|
||||||
if (userId === this.userId) continue
|
if (userId !== this.userId && this.connections[userId] != null) {
|
||||||
let buffer = this.connections[userId].buffer
|
let buffer = this.connections[userId].buffer
|
||||||
if (buffer != null) {
|
if (buffer != null) {
|
||||||
var messages = buffer.splice(0)
|
var messages = buffer.splice(0)
|
||||||
@@ -138,6 +142,7 @@ export default function extendTestConnector (Y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
await Promise.all(finished)
|
await Promise.all(finished)
|
||||||
await this.y.db.whenTransactionsFinished()
|
await this.y.db.whenTransactionsFinished()
|
||||||
return finished.length > 0 ? 'flushing' : 'done'
|
return finished.length > 0 ? 'flushing' : 'done'
|
||||||
|
|||||||
Reference in New Issue
Block a user