mirror of
https://github.com/cudr/slate-collaborative.git
synced 2024-10-27 20:34:06 +00:00
feat: update to slate 0.58 && fix site build
This commit is contained in:
parent
0fd9390a99
commit
6adf4082dc
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@ node_modules/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
lerna-debug.log
|
lerna-debug.log
|
||||||
/.npmrc
|
/.npmrc
|
||||||
|
.vscode/
|
||||||
yarn.lock
|
yarn.lock
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.5.0",
|
"version": "0.6.0",
|
||||||
"description": "Slate collaborative plugin & microservice",
|
"description": "Slate collaborative plugin & microservice",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bootstrap": "lerna bootstrap",
|
"bootstrap": "lerna bootstrap",
|
||||||
"clean": "rimraf ./packages/**/lib/ && rimraf ./packages/**/tsconfig.tsbuildinfo && lerna clean --yes",
|
"clean": "rimraf ./packages/**/lib/ && rimraf ./packages/**/tsconfig.tsbuildinfo && lerna clean --yes",
|
||||||
"release": "yarn prebuild && yarn build && lerna publish from-package",
|
"release": "yarn prebuild && yarn build && lerna publish from-package",
|
||||||
|
"deploy:site": "git subtree push --prefix packages/example heroku master",
|
||||||
"dev": "lerna run --stream build:js && concurrently \"yarn watch\" \"lerna run dev --stream\"",
|
"dev": "lerna run --stream build:js && concurrently \"yarn watch\" \"lerna run dev --stream\"",
|
||||||
"build": "lerna run build --stream && lerna run build:example --stream",
|
"build": "lerna run build:module --stream",
|
||||||
"watch": "lerna run --parallel watch",
|
"watch": "lerna run --parallel watch",
|
||||||
"clean:module": "lerna clean --yes",
|
"clean:module": "lerna clean --yes",
|
||||||
"prebuild": "yarn clean",
|
"prebuild": "yarn clean",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@slate-collaborative/backend",
|
"name": "@slate-collaborative/backend",
|
||||||
"version": "0.5.0",
|
"version": "0.6.0",
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
],
|
],
|
||||||
@ -17,8 +17,8 @@
|
|||||||
"author": "cudr",
|
"author": "cudr",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "yarn run build",
|
"prepublishOnly": "yarn run build:module",
|
||||||
"build": "yarn run build:types && yarn run build:js",
|
"build:module": "yarn run build:types && yarn run build:js",
|
||||||
"build:types": "tsc --emitDeclarationOnly",
|
"build:types": "tsc --emitDeclarationOnly",
|
||||||
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
||||||
"watch": "yarn build:js -w"
|
"watch": "yarn build:js -w"
|
||||||
@ -26,12 +26,12 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
||||||
"@babel/runtime": "^7.6.3",
|
"@babel/runtime": "^7.6.3",
|
||||||
"@slate-collaborative/bridge": "^0.5.0",
|
"@slate-collaborative/bridge": "0.6.0",
|
||||||
"@types/lodash": "^4.14.150",
|
"@types/lodash": "^4.14.150",
|
||||||
"@types/socket.io": "^2.1.4",
|
"@types/socket.io": "^2.1.4",
|
||||||
"automerge": "^0.14.0",
|
"automerge": "0.14.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"slate": "^0.57.2",
|
"slate": "0.58.0",
|
||||||
"socket.io": "^2.3.0",
|
"socket.io": "^2.3.0",
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
@ -46,5 +46,6 @@
|
|||||||
},
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib"
|
"lib": "lib"
|
||||||
}
|
},
|
||||||
|
"gitHead": "1a29cf0da2dc171c1fadd5c8e6eac2327b5b0241"
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ class AutomergeBackend {
|
|||||||
|
|
||||||
if (!doc.cursors) return
|
if (!doc.cursors) return
|
||||||
|
|
||||||
const change = Automerge.change(doc, d => {
|
const change = Automerge.change(doc, (d: any) => {
|
||||||
delete d.cursors[id]
|
delete d.cursors[id]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@slate-collaborative/bridge",
|
"name": "@slate-collaborative/bridge",
|
||||||
"version": "0.5.0",
|
"version": "0.6.0",
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
],
|
],
|
||||||
@ -17,16 +17,16 @@
|
|||||||
"author": "cudr",
|
"author": "cudr",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "yarn run build",
|
"prepublishOnly": "yarn run build:module",
|
||||||
"build": "yarn run build:types && yarn run build:js",
|
"build:module": "yarn run build:types && yarn run build:js",
|
||||||
"build:types": "tsc --emitDeclarationOnly",
|
"build:types": "tsc --emitDeclarationOnly",
|
||||||
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
||||||
"watch": "yarn build:js -w",
|
"watch": "yarn build:js -w",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"automerge": "^0.14.0",
|
"automerge": "0.14.0",
|
||||||
"slate": "^0.57.2",
|
"slate": "0.58.0",
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -63,5 +63,6 @@
|
|||||||
"^.+\\.ts?$": "ts-jest"
|
"^.+\\.ts?$": "ts-jest"
|
||||||
},
|
},
|
||||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$"
|
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$"
|
||||||
}
|
},
|
||||||
|
"gitHead": "1a29cf0da2dc171c1fadd5c8e6eac2327b5b0241"
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { Operation } from 'slate'
|
|||||||
import node from './node'
|
import node from './node'
|
||||||
import text from './text'
|
import text from './text'
|
||||||
|
|
||||||
import { SyncDoc } from '../model'
|
import { SyncValue } from '../model'
|
||||||
import { toJS } from '../utils'
|
import { toJS } from '../utils'
|
||||||
|
|
||||||
const setSelection = (doc: any) => doc
|
const setSelection = (doc: any) => doc
|
||||||
@ -14,7 +14,7 @@ const opType = {
|
|||||||
set_selection: setSelection
|
set_selection: setSelection
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyOperation = (doc: SyncDoc, op: Operation): SyncDoc => {
|
const applyOperation = (doc: SyncValue, op: Operation): SyncValue => {
|
||||||
try {
|
try {
|
||||||
const applyOp = opType[op.type]
|
const applyOp = opType[op.type]
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ const applyOperation = (doc: SyncDoc, op: Operation): SyncDoc => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const applySlateOps = (doc: SyncDoc, operations: Operation[]): SyncDoc => {
|
const applySlateOps = (doc: SyncValue, operations: Operation[]): SyncValue => {
|
||||||
return operations.reduce(applyOperation, doc)
|
return operations.reduce(applyOperation, doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { InsertNodeOperation } from 'slate'
|
import { InsertNodeOperation } from 'slate'
|
||||||
|
|
||||||
import { SyncDoc } from '../../model'
|
import { SyncValue } from '../../model'
|
||||||
import { getParent, getChildren } from '../../path'
|
import { getParent, getChildren } from '../../path'
|
||||||
import { toSync } from '../../utils'
|
import { toSync } from '../../utils'
|
||||||
|
|
||||||
const insertNode = (doc: SyncDoc, op: InsertNodeOperation): SyncDoc => {
|
const insertNode = (doc: SyncValue, op: InsertNodeOperation): SyncValue => {
|
||||||
const [parent, index] = getParent(doc, op.path)
|
const [parent, index] = getParent(doc, op.path)
|
||||||
|
|
||||||
if (parent.text) {
|
if (parent.text) {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { MergeNodeOperation, Node } from 'slate'
|
import { MergeNodeOperation, Node } from 'slate'
|
||||||
|
|
||||||
import { SyncDoc } from '../../model'
|
import { SyncValue } from '../../model'
|
||||||
import { getParent, getChildren } from '../../path'
|
import { getParent, getChildren } from '../../path'
|
||||||
import { toJS, cloneNode } from '../../utils'
|
import { toJS, cloneNode } from '../../utils'
|
||||||
|
|
||||||
const mergeNode = (doc: SyncDoc, op: MergeNodeOperation): SyncDoc => {
|
const mergeNode = (doc: SyncValue, op: MergeNodeOperation): SyncValue => {
|
||||||
const [parent, index]: [any, number] = getParent(doc, op.path)
|
const [parent, index]: [any, number] = getParent(doc, op.path)
|
||||||
|
|
||||||
const prev = parent[index - 1] || parent.children[index - 1]
|
const prev = parent[index - 1] || parent.children[index - 1]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { MoveNodeOperation } from 'slate'
|
import { MoveNodeOperation } from 'slate'
|
||||||
|
|
||||||
import { cloneNode } from '../../utils'
|
import { cloneNode } from '../../utils'
|
||||||
import { SyncDoc } from '../../model'
|
import { SyncValue } from '../../model'
|
||||||
import { getParent, getChildren } from '../../path'
|
import { getParent, getChildren } from '../../path'
|
||||||
|
|
||||||
const moveNode = (doc: SyncDoc, op: MoveNodeOperation): SyncDoc => {
|
const moveNode = (doc: SyncValue, op: MoveNodeOperation): SyncValue => {
|
||||||
const [from, fromIndex] = getParent(doc, op.path)
|
const [from, fromIndex] = getParent(doc, op.path)
|
||||||
const [to, toIndex] = getParent(doc, op.newPath)
|
const [to, toIndex] = getParent(doc, op.newPath)
|
||||||
|
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { RemoveNodeOperation } from 'slate'
|
import { RemoveNodeOperation } from 'slate'
|
||||||
|
|
||||||
import { SyncDoc } from '../../model'
|
import { SyncValue } from '../../model'
|
||||||
import { getParent, getChildren } from '../../path'
|
import { getParent, getChildren } from '../../path'
|
||||||
|
|
||||||
export const removeNode = (doc: SyncDoc, op: RemoveNodeOperation): SyncDoc => {
|
export const removeNode = (
|
||||||
|
doc: SyncValue,
|
||||||
|
op: RemoveNodeOperation
|
||||||
|
): SyncValue => {
|
||||||
const [parent, index] = getParent(doc, op.path)
|
const [parent, index] = getParent(doc, op.path)
|
||||||
|
|
||||||
if (parent.text) {
|
if (parent.text) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { SetNodeOperation } from 'slate'
|
import { SetNodeOperation } from 'slate'
|
||||||
|
|
||||||
import { SyncDoc } from '../../model'
|
import { SyncValue } from '../../model'
|
||||||
import { getTarget } from '../../path'
|
import { getTarget } from '../../path'
|
||||||
|
|
||||||
const setNode = (doc: SyncDoc, op: SetNodeOperation): SyncDoc => {
|
const setNode = (doc: SyncValue, op: SetNodeOperation): SyncValue => {
|
||||||
const node = getTarget(doc, op.path)
|
const node = getTarget(doc, op.path)
|
||||||
|
|
||||||
const { newProperties } = op
|
const { newProperties } = op
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { SplitNodeOperation } from 'slate'
|
import { SplitNodeOperation } from 'slate'
|
||||||
|
|
||||||
import { SyncDoc } from '../../model'
|
import { SyncValue } from '../../model'
|
||||||
import { getParent, getChildren } from '../../path'
|
import { getParent, getChildren } from '../../path'
|
||||||
import { cloneNode } from '../../utils'
|
import { cloneNode } from '../../utils'
|
||||||
|
|
||||||
const splitNode = (doc: SyncDoc, op: SplitNodeOperation): SyncDoc => {
|
const splitNode = (doc: SyncValue, op: SplitNodeOperation): SyncValue => {
|
||||||
const [parent, index]: [any, number] = getParent(doc, op.path)
|
const [parent, index]: [any, number] = getParent(doc, op.path)
|
||||||
|
|
||||||
const target = getChildren(parent)[index]
|
const target = getChildren(parent)[index]
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { InsertTextOperation, RemoveTextOperation } from 'slate'
|
import { InsertTextOperation, RemoveTextOperation } from 'slate'
|
||||||
|
|
||||||
import { getTarget } from '../path'
|
import { getTarget } from '../path'
|
||||||
import { SyncDoc } from '../model'
|
import { SyncValue } from '../model'
|
||||||
|
|
||||||
export const insertText = (doc: SyncDoc, op: InsertTextOperation): SyncDoc => {
|
export const insertText = (
|
||||||
|
doc: SyncValue,
|
||||||
|
op: InsertTextOperation
|
||||||
|
): SyncValue => {
|
||||||
const node = getTarget(doc, op.path)
|
const node = getTarget(doc, op.path)
|
||||||
|
|
||||||
node.text.insertAt(op.offset, ...op.text.split(''))
|
node.text.insertAt(op.offset, ...op.text.split(''))
|
||||||
@ -11,7 +14,10 @@ export const insertText = (doc: SyncDoc, op: InsertTextOperation): SyncDoc => {
|
|||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeText = (doc: SyncDoc, op: RemoveTextOperation): SyncDoc => {
|
export const removeText = (
|
||||||
|
doc: SyncValue,
|
||||||
|
op: RemoveTextOperation
|
||||||
|
): SyncValue => {
|
||||||
const node = getTarget(doc, op.path)
|
const node = getTarget(doc, op.path)
|
||||||
|
|
||||||
node.text.deleteAt(op.offset, op.text.length)
|
node.text.deleteAt(op.offset, op.text.length)
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import * as Automerge from 'automerge'
|
import * as Automerge from 'automerge'
|
||||||
import { Node } from 'slate'
|
|
||||||
|
|
||||||
import opInsert from './insert'
|
import opInsert from './insert'
|
||||||
import opRemove from './remove'
|
import opRemove from './remove'
|
||||||
import opSet from './set'
|
import opSet from './set'
|
||||||
import opCreate from './create'
|
import opCreate from './create'
|
||||||
|
|
||||||
|
import { SyncDoc } from '../model'
|
||||||
|
|
||||||
const byAction = {
|
const byAction = {
|
||||||
create: opCreate,
|
create: opCreate,
|
||||||
remove: opRemove,
|
remove: opRemove,
|
||||||
@ -15,7 +16,7 @@ const byAction = {
|
|||||||
|
|
||||||
const rootKey = '00000000-0000-0000-0000-000000000000'
|
const rootKey = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
const toSlateOp = (ops: Automerge.Diff[], doc: Automerge.Doc<Node>) => {
|
const toSlateOp = (ops: Automerge.Diff[], doc: SyncDoc) => {
|
||||||
const iterate = (acc: [any, any[]], op: Automerge.Diff): any => {
|
const iterate = (acc: [any, any[]], op: Automerge.Diff): any => {
|
||||||
const action = byAction[op.action]
|
const action = byAction[op.action]
|
||||||
|
|
||||||
|
@ -16,17 +16,17 @@ export const setCursor = (
|
|||||||
const newCursor = cursorOps[cursorOps.length - 1]?.newProperties || {}
|
const newCursor = cursorOps[cursorOps.length - 1]?.newProperties || {}
|
||||||
|
|
||||||
if (selection) {
|
if (selection) {
|
||||||
doc.cursors[id] = JSON.stringify(
|
const newCursorData = Object.assign(
|
||||||
Object.assign(
|
(doc.cursors[id] && JSON.parse(doc.cursors[id])) || {},
|
||||||
(doc.cursors[id] && JSON.parse(doc.cursors[id])) || {},
|
newCursor,
|
||||||
newCursor,
|
selection,
|
||||||
selection,
|
{
|
||||||
{
|
...cursorData,
|
||||||
...cursorData,
|
isForward: Range.isForward(selection)
|
||||||
isForward: Boolean(newCursor.focus)
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
doc.cursors[id] = JSON.stringify(newCursorData)
|
||||||
} else {
|
} else {
|
||||||
delete doc.cursors[id]
|
delete doc.cursors[id]
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import Automerge from 'automerge'
|
import Automerge from 'automerge'
|
||||||
import { Node, Range } from 'slate'
|
import { Node, Range } from 'slate'
|
||||||
|
|
||||||
export type SyncDoc = Automerge.Doc<Node & Cursors>
|
export type SyncValue = Automerge.List<Node[]>
|
||||||
|
|
||||||
|
export type SyncDoc = Automerge.Doc<{ children: SyncValue; cursors: Cursors }>
|
||||||
|
|
||||||
export type CollabActionType = 'operation' | 'document'
|
export type CollabActionType = 'operation' | 'document'
|
||||||
|
|
||||||
@ -18,6 +20,6 @@ export interface Cursor extends Range, CursorData {
|
|||||||
isForward: boolean
|
isForward: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Cursors {
|
export type Cursors = {
|
||||||
[key: string]: Cursor
|
[key: string]: Cursor
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Node, Path } from 'slate'
|
import { Node, Path } from 'slate'
|
||||||
|
|
||||||
import { SyncDoc } from '../model'
|
import { SyncValue } from '../model'
|
||||||
|
|
||||||
export const isTree = (node: Node): boolean => Boolean(node?.children)
|
export const isTree = (node: Node): boolean => Boolean(node?.children)
|
||||||
|
|
||||||
export const getTarget = (doc: SyncDoc, path: Path) => {
|
export const getTarget = (doc: SyncValue, path: Path) => {
|
||||||
const iterate = (current: any, idx: number) => {
|
const iterate = (current: any, idx: number) => {
|
||||||
if (!(isTree(current) || current[idx])) {
|
if (!(isTree(current) || current[idx])) {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
@ -30,7 +30,7 @@ export const getParentPath = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getParent = (
|
export const getParent = (
|
||||||
doc: SyncDoc,
|
doc: SyncValue,
|
||||||
path: Path,
|
path: Path,
|
||||||
level = 1
|
level = 1
|
||||||
): [any, number] => {
|
): [any, number] => {
|
||||||
@ -39,4 +39,4 @@ export const getParent = (
|
|||||||
return [getTarget(doc, parentPath), idx]
|
return [getTarget(doc, parentPath), idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getChildren = (node: Node) => node.children || node
|
export const getChildren = (node: any) => node.children || node
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@slate-collaborative/client",
|
"name": "@slate-collaborative/client",
|
||||||
"version": "0.5.0",
|
"version": "0.6.0",
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
],
|
],
|
||||||
@ -17,8 +17,8 @@
|
|||||||
"author": "cudr",
|
"author": "cudr",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "npm run build",
|
"prepublishOnly": "npm run build:module",
|
||||||
"build": "npm run build:types && npm run build:js",
|
"build:module": "npm run build:types && npm run build:js",
|
||||||
"build:types": "tsc --emitDeclarationOnly",
|
"build:types": "tsc --emitDeclarationOnly",
|
||||||
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
||||||
"watch": "yarn build:js -w"
|
"watch": "yarn build:js -w"
|
||||||
@ -26,9 +26,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
"@slate-collaborative/bridge": "^0.5.0",
|
"@slate-collaborative/bridge": "0.6.0",
|
||||||
"automerge": "^0.14.0",
|
"automerge": "0.14.0",
|
||||||
"slate": "^0.57.2",
|
"slate": "0.58.0",
|
||||||
"socket.io-client": "^2.3.0",
|
"socket.io-client": "^2.3.0",
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
@ -44,5 +44,6 @@
|
|||||||
},
|
},
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib"
|
"lib": "lib"
|
||||||
}
|
},
|
||||||
|
"gitHead": "1a29cf0da2dc171c1fadd5c8e6eac2327b5b0241"
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ export const AutomergeEditor = {
|
|||||||
let changed
|
let changed
|
||||||
|
|
||||||
for await (let op of operations) {
|
for await (let op of operations) {
|
||||||
changed = Automerge.change(changed || doc, d =>
|
changed = Automerge.change<SyncDoc>(changed || doc, d =>
|
||||||
applyOperation(d.children, op)
|
applyOperation(d.children, op)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ export const AutomergeEditor = {
|
|||||||
garbageCursor: (e: AutomergeEditor, docId: string) => {
|
garbageCursor: (e: AutomergeEditor, docId: string) => {
|
||||||
const doc = e.docSet.getDoc(docId)
|
const doc = e.docSet.getDoc(docId)
|
||||||
|
|
||||||
const changed = Automerge.change<SyncDoc>(doc, d => {
|
const changed = Automerge.change<SyncDoc>(doc, (d: any) => {
|
||||||
delete d.cusors
|
delete d.cusors
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -38,17 +38,28 @@ const useCursor = (
|
|||||||
if (Range.includes(cursor, path)) {
|
if (Range.includes(cursor, path)) {
|
||||||
const { focus, anchor, isForward } = cursor
|
const { focus, anchor, isForward } = cursor
|
||||||
|
|
||||||
|
const isFocusNode = Path.equals(focus.path, path)
|
||||||
|
const isAnchorNode = Path.equals(anchor.path, path)
|
||||||
|
|
||||||
ranges.push({
|
ranges.push({
|
||||||
...cursor,
|
...cursor,
|
||||||
isCaret: isForward
|
isCaret: isFocusNode,
|
||||||
? Path.equals(focus.path, path)
|
anchor: {
|
||||||
: Path.equals(anchor.path, path),
|
path,
|
||||||
anchor: Path.isBefore(anchor.path, path)
|
offset: isAnchorNode
|
||||||
? { ...anchor, offset: 0 }
|
? anchor.offset
|
||||||
: anchor,
|
: isForward
|
||||||
focus: Path.isAfter(focus.path, path)
|
? 0
|
||||||
? { ...focus, offset: node.text.length }
|
: node.text.length
|
||||||
: focus
|
},
|
||||||
|
focus: {
|
||||||
|
path,
|
||||||
|
offset: isFocusNode
|
||||||
|
? focus.offset
|
||||||
|
: isForward
|
||||||
|
? node.text.length
|
||||||
|
: 0
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -31,6 +31,7 @@ const withAutomerge = <T extends Editor>(
|
|||||||
if (e.connection) e.connection.close()
|
if (e.connection) e.connection.close()
|
||||||
|
|
||||||
e.connection = AutomergeEditor.createConnection(e, (data: CollabAction) =>
|
e.connection = AutomergeEditor.createConnection(e, (data: CollabAction) =>
|
||||||
|
//@ts-ignore
|
||||||
e.send(data)
|
e.send(data)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@slate-collaborative/bridge": ["../../bridge"],
|
|
||||||
"@slate-collaborative/client": ["../../client"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@slate-collaborative/example",
|
"name": "@slate-collaborative/example",
|
||||||
"version": "0.5.0",
|
"version": "0.6.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/core": "^10.0.17",
|
"@emotion/core": "^10.0.17",
|
||||||
"@emotion/styled": "^10.0.17",
|
"@emotion/styled": "^10.0.17",
|
||||||
"@slate-collaborative/backend": "^0.5.0",
|
"@slate-collaborative/backend": "^0.6.0",
|
||||||
"@slate-collaborative/client": "^0.5.0",
|
"@slate-collaborative/client": "^0.6.0",
|
||||||
"@types/faker": "^4.1.5",
|
"@types/faker": "^4.1.5",
|
||||||
"@types/jest": "24.0.18",
|
"@types/jest": "24.0.18",
|
||||||
"@types/node": "12.7.5",
|
"@types/node": "12.7.5",
|
||||||
@ -22,15 +22,16 @@
|
|||||||
"react": "^16.9.0",
|
"react": "^16.9.0",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.9.0",
|
||||||
"react-scripts": "3.1.2",
|
"react-scripts": "3.1.2",
|
||||||
"slate": "^0.57.2",
|
"slate": "0.58.0",
|
||||||
"slate-history": "^0.57.2",
|
"slate-history": "0.58.0",
|
||||||
"slate-react": "^0.57.2",
|
"slate-react": "0.58.0",
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"start:cra": "react-scripts start",
|
"start:cra": "react-scripts start",
|
||||||
"build:example": "cross-env NODE_ENV=production && react-scripts build",
|
"prebuild": "cp -f ./tsconfig.production.json ./tsconfig.json",
|
||||||
|
"build": "cross-env NODE_ENV=production && react-scripts build",
|
||||||
"dev": "concurrently \"yarn start:cra\" \"yarn serve\"",
|
"dev": "concurrently \"yarn start:cra\" \"yarn serve\"",
|
||||||
"serve": "nodemon --watch ../backend/lib --inspect server.js"
|
"serve": "nodemon --watch ../backend/lib --inspect server.js"
|
||||||
},
|
},
|
||||||
@ -48,5 +49,8 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "12.x"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import styled from '@emotion/styled'
|
|||||||
|
|
||||||
import { withIOCollaboration, useCursor } from '@slate-collaborative/client'
|
import { withIOCollaboration, useCursor } from '@slate-collaborative/client'
|
||||||
|
|
||||||
import { Instance, Title, H4, Button } from './Elements'
|
import { Instance, Title, H4, Button } from './Components'
|
||||||
|
|
||||||
import EditorFrame from './EditorFrame'
|
import EditorFrame from './EditorFrame'
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@ import {
|
|||||||
useSlate
|
useSlate
|
||||||
} from 'slate-react'
|
} from 'slate-react'
|
||||||
|
|
||||||
import { ClientFrame, IconButton, Icon } from './Elements'
|
import { ClientFrame, IconButton, Icon } from './Components'
|
||||||
|
|
||||||
import Caret from './Caret'
|
import Caret from './Caret'
|
||||||
|
|
||||||
const LIST_TYPES = ['numbered-list', 'bulleted-list']
|
const LIST_TYPES: string[] = ['numbered-list', 'bulleted-list']
|
||||||
|
|
||||||
export interface EditorFrame {
|
export interface EditorFrame {
|
||||||
editor: ReactEditor
|
editor: ReactEditor
|
||||||
@ -75,7 +75,7 @@ const toggleBlock = (editor: any, format: any) => {
|
|||||||
const isList = LIST_TYPES.includes(format)
|
const isList = LIST_TYPES.includes(format)
|
||||||
|
|
||||||
Transforms.unwrapNodes(editor, {
|
Transforms.unwrapNodes(editor, {
|
||||||
match: n => LIST_TYPES.includes(n.type),
|
match: n => LIST_TYPES.includes(n.type as any),
|
||||||
split: true
|
split: true
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -151,10 +151,12 @@ const Leaf: React.FC<RenderLeafProps> = ({ attributes, children, leaf }) => {
|
|||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
{...attributes}
|
{...attributes}
|
||||||
style={{
|
style={
|
||||||
position: 'relative',
|
{
|
||||||
backgroundColor: leaf.alphaColor
|
position: 'relative',
|
||||||
}}
|
backgroundColor: leaf.alphaColor
|
||||||
|
} as any
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{leaf.isCaret ? <Caret {...(leaf as any)} /> : null}
|
{leaf.isCaret ? <Caret {...(leaf as any)} /> : null}
|
||||||
{children}
|
{children}
|
||||||
|
@ -3,7 +3,7 @@ import React, { useState, ChangeEvent } from 'react'
|
|||||||
import faker from 'faker'
|
import faker from 'faker'
|
||||||
import debounce from 'lodash/debounce'
|
import debounce from 'lodash/debounce'
|
||||||
|
|
||||||
import { RoomWrapper, H4, Title, Button, Grid, Input } from './Elements'
|
import { RoomWrapper, H4, Title, Button, Grid, Input } from './Components'
|
||||||
|
|
||||||
import Client from './Client'
|
import Client from './Client'
|
||||||
|
|
||||||
|
14
packages/example/tsconfig.extend.json
Normal file
14
packages/example/tsconfig.extend.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@slate-collaborative/bridge": ["../../bridge"],
|
||||||
|
"@slate-collaborative/client": ["../../client"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{ "path": "../client" },
|
||||||
|
{ "path": "../backend" }
|
||||||
|
]
|
||||||
|
}
|
@ -2,25 +2,30 @@
|
|||||||
"include": [
|
"include": [
|
||||||
"src/**/*"
|
"src/**/*"
|
||||||
],
|
],
|
||||||
"extends": "./extend.tsconfig.json",
|
"extends": "./tsconfig.extend.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "../",
|
"rootDir": "../",
|
||||||
"baseUrl": "./src",
|
"baseUrl": "./src",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"declarationMap": false,
|
"declarationMap": false,
|
||||||
"noEmit": true
|
"noEmit": true,
|
||||||
},
|
"target": "es5",
|
||||||
"references": [
|
"lib": [
|
||||||
{
|
"dom",
|
||||||
"path": "../client"
|
"dom.iterable",
|
||||||
},
|
"esnext"
|
||||||
{
|
],
|
||||||
"path": "../backend"
|
"esModuleInterop": true,
|
||||||
}
|
"allowSyntheticDefaultImports": true,
|
||||||
]
|
"strict": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"jsx": "react"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
29
packages/example/tsconfig.production.json
Normal file
29
packages/example/tsconfig.production.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"declaration": false,
|
||||||
|
"declarationMap": false,
|
||||||
|
"noEmit": true,
|
||||||
|
"target": "es5",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"jsx": "react"
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules"],
|
||||||
|
"include": ["**/*.ts", "**/*.tsx"]
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user