mirror of
https://github.com/cudr/slate-collaborative.git
synced 2024-10-27 20:34:06 +00:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f65ab040ee | ||
|
3b60f2c6c8 | ||
|
a67986995d | ||
|
1a536f2fa4 | ||
|
322b083f68 | ||
|
ef35812723 | ||
|
d141da4430 | ||
|
24dca9a49c | ||
|
e415684d64 | ||
|
2bd7544977 | ||
|
67218fc8ee | ||
|
e3068d0b48 | ||
|
1106bc1724 | ||
|
829dc2a71b | ||
|
d1d3939c6a | ||
|
ba61211cf6 | ||
|
230117694e | ||
|
b68f5afcf9 | ||
|
cc4449e6dd | ||
|
71ab42d5be | ||
|
05e46faf4f | ||
|
ab3c36ab7d | ||
|
5e0ee3e8d9 | ||
|
a9b20ae99d | ||
|
45b8a16ef5 | ||
|
55b1b2ca5a | ||
|
b49cf33464 |
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Device (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version of slate [e.g. 0.58.0]
|
||||
- Version of slate-collaborative
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
42
CHANGELOG.md
42
CHANGELOG.md
@ -2,9 +2,47 @@
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v0.6.5](https://github.com/cudr/slate-collaborative/compare/v0.6.6...v0.6.5)
|
||||
#### [v0.7.2](https://github.com/cudr/slate-collaborative/compare/v0.7.1...v0.7.2)
|
||||
|
||||
> 21 June 2020
|
||||
> 18 January 2021
|
||||
|
||||
- fix dependency update [`#50`](https://github.com/cudr/slate-collaborative/pull/50)
|
||||
- Fix split_node missing properties bug. [`#45`](https://github.com/cudr/slate-collaborative/pull/45)
|
||||
- Always call external onChange. [`#43`](https://github.com/cudr/slate-collaborative/pull/43)
|
||||
- Fix setNodes undefined value since automerge does not handle undefined value correctly. [`#49`](https://github.com/cudr/slate-collaborative/pull/49)
|
||||
- Fix destory [`#48`](https://github.com/cudr/slate-collaborative/pull/48)
|
||||
- Fix cursor delete [`#44`](https://github.com/cudr/slate-collaborative/pull/44)
|
||||
- build(deps): bump react from 16.14.0 to 17.0.1 [`#40`](https://github.com/cudr/slate-collaborative/pull/40)
|
||||
- build(deps-dev): bump husky from 3.1.0 to 4.3.6 [`#46`](https://github.com/cudr/slate-collaborative/pull/46)
|
||||
- build(deps): bump @types/node from 12.7.5 to 14.14.6 [`#42`](https://github.com/cudr/slate-collaborative/pull/42)
|
||||
- build(deps-dev): bump ts-jest from 25.5.1 to 26.4.4 [`#41`](https://github.com/cudr/slate-collaborative/pull/41)
|
||||
- build(deps): bump react-dom from 16.14.0 to 17.0.1 [`#39`](https://github.com/cudr/slate-collaborative/pull/39)
|
||||
- build(deps-dev): bump @commitlint/cli from 9.1.2 to 11.0.0 [`#38`](https://github.com/cudr/slate-collaborative/pull/38)
|
||||
- build(deps): bump slate-react from 0.58.3 to 0.59.0 [`#37`](https://github.com/cudr/slate-collaborative/pull/37)
|
||||
- build(deps): bump slate from 0.58.3 to 0.59.0 [`#36`](https://github.com/cudr/slate-collaborative/pull/36)
|
||||
- build(deps): bump faker from 4.1.0 to 5.1.0 [`#35`](https://github.com/cudr/slate-collaborative/pull/35)
|
||||
- build(deps): bump nodemon from 1.19.4 to 2.0.6 [`#34`](https://github.com/cudr/slate-collaborative/pull/34)
|
||||
- Update issue templates [`cc4449e`](https://github.com/cudr/slate-collaborative/commit/cc4449e6dd35fbf36675a5ac5a7bac61222dad06)
|
||||
- feat: nodemon run example [`71ab42d`](https://github.com/cudr/slate-collaborative/commit/71ab42d5bec04b89819f51a85659a93587f1af67)
|
||||
|
||||
#### [v0.7.1](https://github.com/cudr/slate-collaborative/compare/v0.7.0...v0.7.1)
|
||||
|
||||
> 28 October 2020
|
||||
|
||||
- defensive code for when the document sometimes isn't there on server restarts. [`#26`](https://github.com/cudr/slate-collaborative/pull/26)
|
||||
- fix: socket io namespace message broadcast [`ab3c36a`](https://github.com/cudr/slate-collaborative/commit/ab3c36ab7dd7f24059c5d0864735c5892df98028)
|
||||
|
||||
#### [v0.7.0](https://github.com/cudr/slate-collaborative/compare/v0.6.7...v0.7.0)
|
||||
|
||||
> 2 July 2020
|
||||
|
||||
- Preserve external history option [`#22`](https://github.com/cudr/slate-collaborative/pull/22)
|
||||
- Generate auto-changelog [`#21`](https://github.com/cudr/slate-collaborative/pull/21)
|
||||
- feat: take changelog version from bridge package [`45b8a16`](https://github.com/cudr/slate-collaborative/commit/45b8a16ef57e582a617c7f6284de697a90e16030)
|
||||
|
||||
#### [v0.6.7](https://github.com/cudr/slate-collaborative/compare/v0.6.6...v0.6.7)
|
||||
|
||||
> 22 June 2020
|
||||
|
||||
- feat: add license [`f5bd03c`](https://github.com/cudr/slate-collaborative/commit/f5bd03cf27a1c620c69e6823b433963aea84610e)
|
||||
- feat: modify changelog template [`c40cdda`](https://github.com/cudr/slate-collaborative/commit/c40cdda45d478b733f195058ef7b239bbb476aeb)
|
||||
|
@ -31,6 +31,7 @@ Check [detailed example](https://github.com/cudr/slate-collaborative/blob/master
|
||||
onConnect?: () => void // connect callback
|
||||
onDisconnect?: () => void // disconnect callback
|
||||
onError?: (reason: string) => void // error callback
|
||||
preserveExternalHistory?: boolean // preserve slate-history operations form other clients
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"lerna": "2.7.1",
|
||||
"version": "0.6.7",
|
||||
"version": "0.7.2",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true
|
||||
}
|
||||
|
12
package.json
12
package.json
@ -1,11 +1,12 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "0.7.1",
|
||||
"description": "Slate collaborative plugin & microservice",
|
||||
"scripts": {
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"version": "auto-changelog -p --template changelog-template.hbs && git add CHANGELOG.md",
|
||||
"changelog": "auto-changelog -p ./packages/bridge/package.json --template changelog-template.hbs && git add CHANGELOG.md",
|
||||
"clean": "rimraf ./packages/**/lib/ && rimraf ./packages/**/tsconfig.tsbuildinfo && lerna clean --yes",
|
||||
"release": "yarn prebuild && yarn build && lerna version && lerna publish from-package",
|
||||
"release": "yarn prebuild && yarn build && lerna version && lerna publish from-package && yarn changelog",
|
||||
"deploy:site": "git subtree push --prefix packages/example heroku master",
|
||||
"dev": "lerna run --stream build:js && concurrently \"yarn watch\" \"lerna run dev --stream\"",
|
||||
"build": "lerna run build:module --stream",
|
||||
@ -37,15 +38,14 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^9.0.1",
|
||||
"@commitlint/cli": "^11.0.0",
|
||||
"@commitlint/config-conventional": "^9.0.1",
|
||||
"auto-changelog": "^2.1.0",
|
||||
"concurrently": "^4.1.2",
|
||||
"husky": "^3.0.5",
|
||||
"husky": "^4.3.6",
|
||||
"lerna": "^3.20.2",
|
||||
"lint-staged": "^9.2.5",
|
||||
"prettier": "^1.18.2",
|
||||
"rimraf": "^3.0.2"
|
||||
},
|
||||
"version": "0.6.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@slate-collaborative/backend",
|
||||
"version": "0.6.7",
|
||||
"version": "0.7.2",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
@ -26,12 +26,12 @@
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@slate-collaborative/bridge": "^0.6.7",
|
||||
"@slate-collaborative/bridge": "^0.7.2",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/socket.io": "^2.1.4",
|
||||
"automerge": "0.14.0",
|
||||
"lodash": "^4.17.15",
|
||||
"slate": "0.58.3",
|
||||
"slate": "0.59.0",
|
||||
"socket.io": "^2.3.0",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
|
@ -31,13 +31,14 @@ export default class SocketIOCollaboration {
|
||||
private io: SocketIO.Server
|
||||
private options: SocketIOCollaborationOptions
|
||||
private backend: AutomergeBackend
|
||||
private autoSaveDoc: (docId: string) => void
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
constructor(options: SocketIOCollaborationOptions) {
|
||||
this.io = io(options.entry, options.connectOpts)
|
||||
this.io = io(options.entry as Server, options.connectOpts)
|
||||
|
||||
this.backend = new AutomergeBackend()
|
||||
|
||||
@ -45,6 +46,15 @@ export default class SocketIOCollaboration {
|
||||
|
||||
this.configure()
|
||||
|
||||
/**
|
||||
* Save document with throttle
|
||||
*/
|
||||
this.autoSaveDoc = throttle(
|
||||
async (docId: string) =>
|
||||
this.backend.getDocument(docId) && this.saveDocument(docId),
|
||||
this.options?.saveFrequency || 2000
|
||||
)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
@ -108,14 +118,15 @@ export default class SocketIOCollaboration {
|
||||
const { name } = socket.nsp
|
||||
|
||||
this.backend.createConnection(id, ({ type, payload }: CollabAction) => {
|
||||
if (payload.docId === name) {
|
||||
socket.emit('msg', { type, payload: { id: conn.id, ...payload } })
|
||||
}
|
||||
})
|
||||
|
||||
socket.on('msg', this.onMessage(id, name))
|
||||
|
||||
socket.on('disconnect', this.onDisconnect(id, socket))
|
||||
|
||||
socket.join(id, () => {
|
||||
const doc = this.backend.getDocument(name)
|
||||
|
||||
socket.emit('msg', {
|
||||
@ -124,7 +135,6 @@ export default class SocketIOCollaboration {
|
||||
})
|
||||
|
||||
this.backend.openConnection(id)
|
||||
})
|
||||
|
||||
this.garbageCursors(name)
|
||||
}
|
||||
@ -148,16 +158,6 @@ export default class SocketIOCollaboration {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save document with throttle
|
||||
*/
|
||||
|
||||
private autoSaveDoc = throttle(
|
||||
async (docId: string) =>
|
||||
this.backend.getDocument(docId) && this.saveDocument(docId),
|
||||
this.options?.saveFrequency || 2000
|
||||
)
|
||||
|
||||
/**
|
||||
* Save document
|
||||
*/
|
||||
@ -183,6 +183,8 @@ export default class SocketIOCollaboration {
|
||||
*/
|
||||
|
||||
private onDisconnect = (id: string, socket: SocketIO.Socket) => async () => {
|
||||
socket.leave(socket.nsp.name)
|
||||
|
||||
this.backend.closeConnection(id)
|
||||
|
||||
await this.saveDocument(socket.nsp.name)
|
||||
@ -219,7 +221,7 @@ export default class SocketIOCollaboration {
|
||||
garbageCursors = (nsp: string) => {
|
||||
const doc = this.backend.getDocument(nsp)
|
||||
|
||||
if (!doc.cursors) return
|
||||
if (!doc || !doc.cursors) return
|
||||
|
||||
const namespace = this.io.of(nsp)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@slate-collaborative/bridge",
|
||||
"version": "0.6.7",
|
||||
"version": "0.7.2",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
@ -26,7 +26,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"automerge": "0.14.0",
|
||||
"slate": "0.58.3",
|
||||
"slate": "0.59.0",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -39,7 +39,7 @@
|
||||
"@babel/preset-typescript": "^7.6.0",
|
||||
"@types/jest": "^24.9.0",
|
||||
"jest": "^24.9.0",
|
||||
"ts-jest": "^25.4.0"
|
||||
"ts-jest": "^26.4.4"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
|
@ -9,7 +9,12 @@ const setNode = (doc: SyncValue, op: SetNodeOperation): SyncValue => {
|
||||
const { newProperties } = op
|
||||
|
||||
for (let key in newProperties) {
|
||||
node[key] = newProperties[key]
|
||||
const value = newProperties[key]
|
||||
if (value !== undefined) {
|
||||
node[key] = value
|
||||
} else {
|
||||
delete node[key]
|
||||
}
|
||||
}
|
||||
|
||||
return doc
|
||||
|
@ -8,7 +8,10 @@ const splitNode = (doc: SyncValue, op: SplitNodeOperation): SyncValue => {
|
||||
const [parent, index]: [any, number] = getParent(doc, op.path)
|
||||
|
||||
const target = getChildren(parent)[index]
|
||||
const inject = cloneNode(target)
|
||||
const inject = {
|
||||
...cloneNode(target),
|
||||
...op.properties
|
||||
}
|
||||
|
||||
if (target.text) {
|
||||
target.text.length > op.position &&
|
||||
|
@ -9,7 +9,9 @@ export const insertText = (
|
||||
): SyncValue => {
|
||||
const node = getTarget(doc, op.path)
|
||||
|
||||
node.text.insertAt(op.offset, ...op.text.split(''))
|
||||
const offset = Math.min(node.text.length, op.offset)
|
||||
|
||||
node.text.insertAt(offset, ...op.text.split(''))
|
||||
|
||||
return doc
|
||||
}
|
||||
@ -20,7 +22,9 @@ export const removeText = (
|
||||
): SyncValue => {
|
||||
const node = getTarget(doc, op.path)
|
||||
|
||||
node.text.deleteAt(op.offset, op.text.length)
|
||||
const offset = Math.min(node.text.length, op.offset)
|
||||
|
||||
node.text.deleteAt(offset, op.text.length)
|
||||
|
||||
return doc
|
||||
}
|
||||
|
@ -54,15 +54,13 @@ describe('convert operations to slatejs model', () => {
|
||||
{
|
||||
type: 'remove_node',
|
||||
path: [1],
|
||||
node: {
|
||||
text: '*'
|
||||
}
|
||||
node: createNode('paragraph', 'hello twice!')
|
||||
},
|
||||
{
|
||||
type: 'remove_node',
|
||||
path: [0, 0],
|
||||
node: {
|
||||
text: '*'
|
||||
children: []
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as Automerge from 'automerge'
|
||||
|
||||
const createByType = (type: any) =>
|
||||
const createByType = (type: Automerge.CollectionType) =>
|
||||
type === 'map' ? {} : type === 'list' ? [] : ''
|
||||
|
||||
const opCreate = ({ obj, type }: Automerge.Diff, [map, ops]: any) => {
|
||||
|
@ -5,6 +5,8 @@ import opRemove from './remove'
|
||||
import opSet from './set'
|
||||
import opCreate from './create'
|
||||
|
||||
import { toJS } from '../utils'
|
||||
|
||||
import { SyncDoc } from '../model'
|
||||
|
||||
const byAction = {
|
||||
@ -32,7 +34,9 @@ const toSlateOp = (ops: Automerge.Diff[], doc: SyncDoc) => {
|
||||
[]
|
||||
])
|
||||
|
||||
return defer.flatMap(op => op(tempTree, doc)).filter(op => op)
|
||||
const tempDoc = toJS(doc)
|
||||
|
||||
return defer.flatMap(op => op(tempTree, tempDoc)).filter(op => op)
|
||||
}
|
||||
|
||||
export { toSlateOp }
|
||||
|
@ -1,33 +1,74 @@
|
||||
import * as Automerge from 'automerge'
|
||||
import { Element } from 'slate'
|
||||
|
||||
import { toSlatePath, toJS } from '../utils'
|
||||
import { getTarget } from '../path'
|
||||
|
||||
const removeTextOp = ({ index, path }: Automerge.Diff) => () => ({
|
||||
const removeTextOp = (op: Automerge.Diff) => (map: any, doc: Element) => {
|
||||
try {
|
||||
const { index, path, obj } = op
|
||||
|
||||
const slatePath = toSlatePath(path).slice(0, path?.length)
|
||||
|
||||
let node = map[obj]
|
||||
|
||||
try {
|
||||
node = getTarget(doc, slatePath)
|
||||
} catch (e) {
|
||||
console.error(e, slatePath, op, map, toJS(doc))
|
||||
}
|
||||
|
||||
if (typeof index !== 'number') return
|
||||
|
||||
const text = node?.text?.[index] || '*'
|
||||
|
||||
if (node) {
|
||||
node.text = node?.text ? (node.text.slice(0, index) + node.text.slice(index + 1)) : ''
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'remove_text',
|
||||
path: toSlatePath(path).slice(0, path?.length),
|
||||
path: slatePath,
|
||||
offset: index,
|
||||
text: '*',
|
||||
text,
|
||||
marks: []
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e, op, map, toJS(doc))
|
||||
}
|
||||
}
|
||||
|
||||
const removeNodeOp = ({ index, obj, path }: Automerge.Diff) => (
|
||||
const removeNodeOp = (op: Automerge.Diff) => (
|
||||
map: any,
|
||||
doc: any
|
||||
doc: Element
|
||||
) => {
|
||||
const slatePath = toSlatePath(path)
|
||||
if (!map.hasOwnProperty(obj)) {
|
||||
const target = getTarget(doc, [...slatePath, index] as any)
|
||||
try {
|
||||
const { index, obj, path } = op
|
||||
|
||||
const slatePath = toSlatePath(path)
|
||||
|
||||
const parent = getTarget(doc, slatePath)
|
||||
const target = parent?.children?.[index as number] || parent?.[index as number] || { children: [] }
|
||||
|
||||
if (!target) {
|
||||
throw new TypeError('Target is not found!')
|
||||
}
|
||||
|
||||
if (!map.hasOwnProperty(obj)) {
|
||||
map[obj] = target
|
||||
}
|
||||
|
||||
if (!Number.isInteger(index)) {
|
||||
throw new TypeError('Index is not a number')
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'remove_node',
|
||||
path: slatePath.length ? slatePath.concat(index) : [index],
|
||||
node: {
|
||||
text: '*'
|
||||
node: target
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e, op, map, toJS(doc))
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +79,8 @@ const opRemove = (op: Automerge.Diff, [map, ops]: any) => {
|
||||
if (
|
||||
map.hasOwnProperty(obj) &&
|
||||
typeof map[obj] !== 'string' &&
|
||||
type !== 'text'
|
||||
type !== 'text' &&
|
||||
map?.obj?.length
|
||||
) {
|
||||
map[obj].splice(index, 1)
|
||||
|
||||
@ -49,7 +91,7 @@ const opRemove = (op: Automerge.Diff, [map, ops]: any) => {
|
||||
|
||||
const key = path[path.length - 1]
|
||||
|
||||
if (key === 'cursors') return [map, ops]
|
||||
if (key === 'cursors' || op.key === 'cursors') return [map, ops]
|
||||
|
||||
const fn = key === 'text' ? removeTextOp : removeNodeOp
|
||||
|
||||
|
@ -10,10 +10,10 @@ const setDataOp = (
|
||||
type: 'set_node',
|
||||
path: toSlatePath(path),
|
||||
properties: {
|
||||
[key]: Automerge.getObjectById(doc, obj)?.[key]
|
||||
[key]: toJS(Automerge.getObjectById(doc, obj)?.[key])
|
||||
},
|
||||
newProperties: {
|
||||
[key]: value
|
||||
[key]: map?.[value] || value
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,7 @@ const opSet = (op: Automerge.Diff, [map, ops]: any, doc: any) => {
|
||||
const { link, value, path, obj, key } = op
|
||||
|
||||
try {
|
||||
if (path && path[0] !== 'cursors') {
|
||||
if (path && path.length && path[0] !== 'cursors') {
|
||||
ops.push(setDataOp(op, doc))
|
||||
} else if (map[obj]) {
|
||||
map[obj][key as any] = link ? map[value] : value
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Node, Path } from 'slate'
|
||||
import { Element, Node, Path } from 'slate'
|
||||
|
||||
import { SyncValue } from '../model'
|
||||
|
||||
export const isTree = (node: Node): boolean => Boolean(node?.children)
|
||||
|
||||
export const getTarget = (doc: SyncValue, path: Path) => {
|
||||
export const getTarget = (doc: SyncValue | Element, path: Path) => {
|
||||
const iterate = (current: any, idx: number) => {
|
||||
if (!(isTree(current) || current[idx])) {
|
||||
throw new TypeError(
|
||||
@ -30,7 +30,7 @@ export const getParentPath = (
|
||||
}
|
||||
|
||||
export const getParent = (
|
||||
doc: SyncValue,
|
||||
doc: SyncValue | Element,
|
||||
path: Path,
|
||||
level = 1
|
||||
): [any, number] => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@slate-collaborative/client",
|
||||
"version": "0.6.7",
|
||||
"version": "0.7.2",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
@ -26,9 +26,10 @@
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@slate-collaborative/bridge": "^0.6.7",
|
||||
"@slate-collaborative/bridge": "^0.7.2",
|
||||
"automerge": "0.14.0",
|
||||
"slate": "0.58.3",
|
||||
"slate": "0.59.0",
|
||||
"slate-history": "0.58.3",
|
||||
"socket.io-client": "^2.3.0",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Automerge from 'automerge'
|
||||
|
||||
import { Editor, Operation } from 'slate'
|
||||
import { HistoryEditor } from 'slate-history'
|
||||
|
||||
import {
|
||||
toJS,
|
||||
@ -111,7 +112,8 @@ export const AutomergeEditor = {
|
||||
applyOperation: (
|
||||
e: AutomergeEditor,
|
||||
docId: string,
|
||||
data: Automerge.Message
|
||||
data: Automerge.Message,
|
||||
preserveExternalHistory?: boolean
|
||||
) => {
|
||||
try {
|
||||
const current: any = e.docSet.getDoc(docId)
|
||||
@ -126,12 +128,18 @@ export const AutomergeEditor = {
|
||||
e.isRemote = true
|
||||
|
||||
Editor.withoutNormalizing(e, () => {
|
||||
if (HistoryEditor.isHistoryEditor(e) && !preserveExternalHistory) {
|
||||
HistoryEditor.withoutSaving(e, () => {
|
||||
slateOps.forEach((o: Operation) => {
|
||||
e.apply(o)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
slateOps.forEach((o: Operation) => e.apply(o))
|
||||
}
|
||||
|
||||
e.onCursor && e.onCursor(updated.cursors)
|
||||
})
|
||||
|
||||
Promise.resolve().then(_ => (e.isRemote = false))
|
||||
}
|
||||
@ -143,8 +151,12 @@ export const AutomergeEditor = {
|
||||
garbageCursor: (e: AutomergeEditor, docId: string) => {
|
||||
const doc = e.docSet.getDoc(docId)
|
||||
|
||||
if (!doc) {
|
||||
return
|
||||
}
|
||||
|
||||
const changed = Automerge.change<SyncDoc>(doc, (d: any) => {
|
||||
delete d.cusors
|
||||
delete d.cursors
|
||||
})
|
||||
|
||||
e.onCursor && e.onCursor(null)
|
||||
|
@ -9,6 +9,7 @@ import { CursorData, CollabAction } from '@slate-collaborative/bridge'
|
||||
export interface AutomergeOptions {
|
||||
docId: string
|
||||
cursorData?: CursorData
|
||||
preserveExternalHistory?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,7 +24,7 @@ const withAutomerge = <T extends Editor>(
|
||||
|
||||
const { onChange } = e
|
||||
|
||||
const { docId, cursorData } = options || {}
|
||||
const { docId, cursorData, preserveExternalHistory } = options || {}
|
||||
|
||||
e.docSet = new Automerge.DocSet()
|
||||
|
||||
@ -76,8 +77,6 @@ const withAutomerge = <T extends Editor>(
|
||||
}
|
||||
|
||||
onChange()
|
||||
|
||||
// console.log('e', e.children)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +96,7 @@ const withAutomerge = <T extends Editor>(
|
||||
e.receiveOperation = data => {
|
||||
if (docId !== data.docId) return
|
||||
|
||||
AutomergeEditor.applyOperation(e, docId, data)
|
||||
AutomergeEditor.applyOperation(e, docId, data, preserveExternalHistory)
|
||||
}
|
||||
|
||||
return e
|
||||
|
@ -122,6 +122,8 @@ const withSocketIO = <T extends AutomergeEditor>(
|
||||
*/
|
||||
|
||||
e.destroy = () => {
|
||||
e.socket.removeListener('disconnect')
|
||||
|
||||
e.socket.close()
|
||||
|
||||
e.closeConnection()
|
||||
|
@ -1,36 +1,28 @@
|
||||
{
|
||||
"name": "@slate-collaborative/example",
|
||||
"version": "0.6.7",
|
||||
"version": "0.7.2",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/core": "^10.0.17",
|
||||
"@emotion/styled": "^10.0.17",
|
||||
"@slate-collaborative/backend": "^0.6.7",
|
||||
"@slate-collaborative/client": "^0.6.7",
|
||||
"@types/faker": "^4.1.5",
|
||||
"@types/is-url": "^1.2.28",
|
||||
"@types/jest": "24.0.18",
|
||||
"@types/node": "12.7.5",
|
||||
"@types/randomcolor": "^0.5.4",
|
||||
"@types/react-dom": "^16.9.6",
|
||||
"@slate-collaborative/backend": "^0.7.2",
|
||||
"@slate-collaborative/client": "^0.7.2",
|
||||
"concurrently": "^4.1.2",
|
||||
"cross-env": "^6.0.3",
|
||||
"express": "^4.17.1",
|
||||
"faker": "^4.1.0",
|
||||
"is-url": "^1.2.4",
|
||||
"lodash": "^4.17.15",
|
||||
"nodemon": "^1.19.2",
|
||||
"nodemon": "^2.0.6",
|
||||
"randomcolor": "^0.5.4",
|
||||
"react": "^16.9.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-scripts": "3.1.2",
|
||||
"slate": "0.58.3",
|
||||
"slate": "0.59.0",
|
||||
"slate-history": "0.58.3",
|
||||
"slate-react": "0.58.3",
|
||||
"typescript": "^3.8.3"
|
||||
"slate-react": "0.59.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"start": "nodemon server.js",
|
||||
"start:cra": "react-scripts start",
|
||||
"prebuild": "cp -f ./tsconfig.production.json ./tsconfig.json",
|
||||
"build": "cross-env NODE_ENV=production && react-scripts build",
|
||||
@ -54,5 +46,15 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": "12.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/faker": "^4.1.5",
|
||||
"@types/is-url": "^1.2.28",
|
||||
"@types/jest": "24.0.18",
|
||||
"@types/node": "14.14.6",
|
||||
"@types/randomcolor": "^0.5.4",
|
||||
"@types/react-dom": "^16.9.6",
|
||||
"faker": "^5.1.0",
|
||||
"typescript": "^3.8.3"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user