fixed bower & added dependencies & cleanup

This commit is contained in:
Kevin Jahns
2016-02-23 15:41:22 +01:00
parent 54529ab1e7
commit 2f7349b712
2934 changed files with 957878 additions and 3 deletions

View File

@@ -0,0 +1,15 @@
{
"name": "y-array",
"homepage": "https://github.com/y-js/y-array",
"version": "0.7.5",
"_release": "0.7.5",
"_resolution": {
"type": "version",
"tag": "v0.7.5",
"commit": "616d21127c3aece7c1c3619b9f7ffe2f20f03f23"
},
"_source": "git://github.com/y-js/y-array.git",
"_target": "~0.7.5",
"_originalSource": "y-array",
"_direct": true
}

View File

@@ -0,0 +1,3 @@
{
"directory": "../"
}

View File

@@ -0,0 +1,6 @@
/node_modules/
bower_components
.directory
.c9
.codio
.settings

View File

@@ -0,0 +1,11 @@
language: node_js
before_install:
- "npm install -g bower coffee-script"
- "bower install"
node_js:
- "0.12"
- "0.11"
- "0.10"
branches:
only:
- master

View File

@@ -0,0 +1,92 @@
# List Type for [Yjs](https://github.com/y-js/yjs)
Manage list-like data with this shareable list type. You can insert and delete arbitrary objects (also custom types for Yjs) in the list type.
## Use it!
Retrieve this with bower or npm.
##### Bower
```
bower install y-list --save
```
and include the js library.
```
<script src="./bower_components/y-list/y-list.js"></script>
```
##### NPM
```
npm install y-list --save
```
and put it on the `Y` object.
```
Y.List = require("y-list");
```
### List Object
##### Reference
* Create
```
var ylist = new Y.List()
```
* .insert(position, content)
* Insert content at a position
* .insertContents(position, contents)
* Insert a set of content at a position. This expects that contents is an array of content.
* .push(content)
* Insert content at the end of the list
* .delete(position, length)
* Delete content. The *length* parameter is optional and defaults to 1
* .val()
* Retrieve all content as an Array Object
* .val(position)
* Retrieve content from a position
* .ref(position)
* Retrieve a reference to the element on a *position*.
* You can call `ref.getNext()` and `ref.getPrev()` to get the next/previous reference
* You can call `ref.getNext(i)` and `ref.getPrev(i)` to get the i-th next/previous reference
* You can call `ref.val()` to get the element, to which the reference points (`y.ref(1).val() === y.val(1)`)
* .observe(f)
* The observer is called whenever something on this list changed. (throws insert, and delete events)
* .unobserve(f)
* Delete an observer
# A note on intention preservation
If two users insert something at the same position concurrently, the content that was inserted by the user with the higher user-id will be to the right of the other content. In the OT world we often speak of *intention preservation*, which is very loosely defined in most cases. This type has the following notion of intention preservation: When a user inserts content *c* after a set of content *C_left*, and before a set of content *C_right*, then *C_left* will be always to the left of c, and *C_right* will be always to the right of *c*. This property will also hold when content is deleted or when a deletion is undone.
# A note on time complexities
* .insert(position, content)
* O(position)
* .insertContents(position, contents)
* O(position + |contents|)
* .push(content)
* O(1)
* .delete(position, length)
* O(position)
* .val()
* O(|ylist|)
* .val(position)
* O(position|)
* Apply a delete operation from another user
* O(1)
* Apply an insert operation from another user
* Yjs does not transform against operations that do not conflict with each other.
* An operation conflicts with another operation if it intends to be inserted at the same position.
* Overall worst case complexety: O(|conflicts|!)
# Issues
* Support moving of objects
* Create a polymer element
## License
Yjs is licensed under the [MIT License](./LICENSE.txt).
<kevin.jahns@rwth-aachen.de>

View File

@@ -0,0 +1,215 @@
(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){
/* global Y */
'use strict'
function extend (Y) {
class YArray {
constructor (os, _model, _content) {
this.os = os
this._model = _model
// Array of all the neccessary content (includes id (string formatted, and element value))
this._content = _content
this.eventHandler = new Y.utils.EventHandler(ops => {
var userEvents = []
for (var i = 0; i < ops.length; i++) {
var op = ops[i]
if (op.struct === 'Insert') {
let pos
// we check op.left only!,
// because op.right might not be defined when this is called
if (op.left === null) {
pos = 0
} else {
let sid = JSON.stringify(op.left)
pos = 1 + this._content.findIndex(function (c) {
return c.id === sid
})
if (pos <= 0) {
throw new Error('Unexpected operation!')
}
}
this._content.splice(pos, 0, {
id: JSON.stringify(op.id),
val: op.content
})
userEvents.push({
type: 'insert',
object: this,
index: pos,
value: op.content,
length: 1
})
} else if (op.struct === 'Delete') {
let sid = JSON.stringify(op.target)
let pos = this._content.findIndex(function (c) {
return c.id === sid
})
if (pos >= 0) {
var val = this._content[pos].val
this._content.splice(pos, 1)
userEvents.push({
type: 'delete',
object: this,
index: pos,
value: val,
length: 1
})
}
} else {
throw new Error('Unexpected struct!')
}
}
this.eventHandler.callEventListeners(userEvents)
})
}
_destroy () {
this.eventHandler.destroy()
this.eventHandler = null
this._content = null
this._model = null
this.os = null
}
get length () {
return this._content.length
}
get (pos) {
if (pos == null || typeof pos !== 'number') {
throw new Error('pos must be a number!')
}
return this._content[pos].val
}
toArray () {
return this._content.map(function (x) {
return x.val
})
}
push (contents) {
this.insert(this._content.length, contents)
}
insert (pos, contents) {
if (typeof pos !== 'number') {
throw new Error('pos must be a number!')
}
if (!(contents instanceof Array)) {
throw new Error('contents must be an Array of objects!')
}
if (contents.length === 0) {
return
}
if (pos > this._content.length || pos < 0) {
throw new Error('This position exceeds the range of the array!')
}
var mostLeft = pos === 0 ? null : JSON.parse(this._content[pos - 1].id)
var ops = []
var prevId = mostLeft
for (var i = 0; i < contents.length; i++) {
var op = {
left: prevId,
origin: prevId,
// right: mostRight,
// NOTE: I intentionally do not define right here, because it could be deleted
// at the time of inserting this operation (when we get the transaction),
// and would therefore not defined in this._conten
parent: this._model,
content: contents[i],
struct: 'Insert',
id: this.os.getNextOpId()
}
ops.push(op)
prevId = op.id
}
var eventHandler = this.eventHandler
eventHandler.awaitAndPrematurelyCall(ops)
this.os.requestTransaction(function *() {
// now we can set the right reference.
var mostRight
if (mostLeft != null) {
mostRight = (yield* this.getOperation(mostLeft)).right
} else {
mostRight = (yield* this.getOperation(ops[0].parent)).start
}
for (var j = 0; j < ops.length; j++) {
ops[j].right = mostRight
}
yield* this.applyCreatedOperations(ops)
eventHandler.awaitedInserts(ops.length)
})
}
delete (pos, length) {
if (length == null) { length = 1 }
if (typeof length !== 'number') {
throw new Error('length must be a number!')
}
if (typeof pos !== 'number') {
throw new Error('pos must be a number!')
}
if (pos + length > this._content.length || pos < 0 || length < 0) {
throw new Error('The deletion range exceeds the range of the array!')
}
if (length === 0) {
return
}
var eventHandler = this.eventHandler
var newLeft = pos > 0 ? JSON.parse(this._content[pos - 1].id) : null
var dels = []
for (var i = 0; i < length; i++) {
dels.push({
target: JSON.parse(this._content[pos + i].id),
struct: 'Delete'
})
}
eventHandler.awaitAndPrematurelyCall(dels)
this.os.requestTransaction(function *() {
yield* this.applyCreatedOperations(dels)
eventHandler.awaitedDeletes(dels.length, newLeft)
})
}
observe (f) {
this.eventHandler.addEventListener(f)
}
unobserve (f) {
this.eventHandler.removeEventListener(f)
}
* _changed (transaction, op) {
if (!op.deleted) {
if (op.struct === 'Insert') {
var l = op.left
var left
while (l != null) {
left = yield* transaction.getOperation(l)
if (!left.deleted) {
break
}
l = left.left
}
op.left = l
}
this.eventHandler.receivedOp(op)
}
}
}
Y.extend('Array', new Y.utils.CustomType({
name: 'Array', // TODO: copy the name when extending the object.. (see one line above)
class: YArray,
struct: 'List',
initType: function * YArrayInitializer (os, model) {
var _content = yield* Y.Struct.List.map.call(this, model, function (c) {
return {
id: JSON.stringify(c.id),
val: c.content
}
})
return new YArray(os, model.id, _content)
}
}))
}
module.exports = extend
if (typeof Y !== 'undefined') {
extend(Y)
}
},{}]},{},[1])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long