feat: update to slate 0.58 && fix site build

This commit is contained in:
cudr 2020-05-11 09:21:49 +03:00
parent 0fd9390a99
commit 6adf4082dc
30 changed files with 180 additions and 107 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ node_modules/
.DS_Store
lerna-debug.log
/.npmrc
.vscode/
yarn.lock
yarn-error.log
package-lock.json

View File

@ -1,13 +1,14 @@
{
"private": true,
"version": "0.5.0",
"version": "0.6.0",
"description": "Slate collaborative plugin & microservice",
"scripts": {
"bootstrap": "lerna bootstrap",
"clean": "rimraf ./packages/**/lib/ && rimraf ./packages/**/tsconfig.tsbuildinfo && lerna clean --yes",
"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\"",
"build": "lerna run build --stream && lerna run build:example --stream",
"build": "lerna run build:module --stream",
"watch": "lerna run --parallel watch",
"clean:module": "lerna clean --yes",
"prebuild": "yarn clean",

View File

@ -1,6 +1,6 @@
{
"name": "@slate-collaborative/backend",
"version": "0.5.0",
"version": "0.6.0",
"files": [
"lib"
],
@ -17,8 +17,8 @@
"author": "cudr",
"license": "MIT",
"scripts": {
"prepublishOnly": "yarn run build",
"build": "yarn run build:types && yarn run build:js",
"prepublishOnly": "yarn run build:module",
"build:module": "yarn run build:types && yarn run build:js",
"build:types": "tsc --emitDeclarationOnly",
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
"watch": "yarn build:js -w"
@ -26,12 +26,12 @@
"dependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/runtime": "^7.6.3",
"@slate-collaborative/bridge": "^0.5.0",
"@slate-collaborative/bridge": "0.6.0",
"@types/lodash": "^4.14.150",
"@types/socket.io": "^2.1.4",
"automerge": "^0.14.0",
"automerge": "0.14.0",
"lodash": "^4.17.15",
"slate": "^0.57.2",
"slate": "0.58.0",
"socket.io": "^2.3.0",
"typescript": "^3.8.3"
},
@ -46,5 +46,6 @@
},
"directories": {
"lib": "lib"
}
},
"gitHead": "1a29cf0da2dc171c1fadd5c8e6eac2327b5b0241"
}

View File

@ -111,7 +111,7 @@ class AutomergeBackend {
if (!doc.cursors) return
const change = Automerge.change(doc, d => {
const change = Automerge.change(doc, (d: any) => {
delete d.cursors[id]
})

View File

@ -1,6 +1,6 @@
{
"name": "@slate-collaborative/bridge",
"version": "0.5.0",
"version": "0.6.0",
"files": [
"lib"
],
@ -17,16 +17,16 @@
"author": "cudr",
"license": "MIT",
"scripts": {
"prepublishOnly": "yarn run build",
"build": "yarn run build:types && yarn run build:js",
"prepublishOnly": "yarn run build:module",
"build:module": "yarn run build:types && yarn run build:js",
"build:types": "tsc --emitDeclarationOnly",
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
"watch": "yarn build:js -w",
"test": "jest"
},
"dependencies": {
"automerge": "^0.14.0",
"slate": "^0.57.2",
"automerge": "0.14.0",
"slate": "0.58.0",
"typescript": "^3.8.3"
},
"devDependencies": {
@ -63,5 +63,6 @@
"^.+\\.ts?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$"
}
},
"gitHead": "1a29cf0da2dc171c1fadd5c8e6eac2327b5b0241"
}

View File

@ -3,7 +3,7 @@ import { Operation } from 'slate'
import node from './node'
import text from './text'
import { SyncDoc } from '../model'
import { SyncValue } from '../model'
import { toJS } from '../utils'
const setSelection = (doc: any) => doc
@ -14,7 +14,7 @@ const opType = {
set_selection: setSelection
}
const applyOperation = (doc: SyncDoc, op: Operation): SyncDoc => {
const applyOperation = (doc: SyncValue, op: Operation): SyncValue => {
try {
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)
}

View File

@ -1,10 +1,10 @@
import { InsertNodeOperation } from 'slate'
import { SyncDoc } from '../../model'
import { SyncValue } from '../../model'
import { getParent, getChildren } from '../../path'
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)
if (parent.text) {

View File

@ -1,10 +1,10 @@
import { MergeNodeOperation, Node } from 'slate'
import { SyncDoc } from '../../model'
import { SyncValue } from '../../model'
import { getParent, getChildren } from '../../path'
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 prev = parent[index - 1] || parent.children[index - 1]

View File

@ -1,10 +1,10 @@
import { MoveNodeOperation } from 'slate'
import { cloneNode } from '../../utils'
import { SyncDoc } from '../../model'
import { SyncValue } from '../../model'
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 [to, toIndex] = getParent(doc, op.newPath)

View File

@ -1,9 +1,12 @@
import { RemoveNodeOperation } from 'slate'
import { SyncDoc } from '../../model'
import { SyncValue } from '../../model'
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)
if (parent.text) {

View File

@ -1,9 +1,9 @@
import { SetNodeOperation } from 'slate'
import { SyncDoc } from '../../model'
import { SyncValue } from '../../model'
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 { newProperties } = op

View File

@ -1,10 +1,10 @@
import { SplitNodeOperation } from 'slate'
import { SyncDoc } from '../../model'
import { SyncValue } from '../../model'
import { getParent, getChildren } from '../../path'
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 target = getChildren(parent)[index]

View File

@ -1,9 +1,12 @@
import { InsertTextOperation, RemoveTextOperation } from 'slate'
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)
node.text.insertAt(op.offset, ...op.text.split(''))
@ -11,7 +14,10 @@ export const insertText = (doc: SyncDoc, op: InsertTextOperation): SyncDoc => {
return doc
}
export const removeText = (doc: SyncDoc, op: RemoveTextOperation): SyncDoc => {
export const removeText = (
doc: SyncValue,
op: RemoveTextOperation
): SyncValue => {
const node = getTarget(doc, op.path)
node.text.deleteAt(op.offset, op.text.length)

View File

@ -1,11 +1,12 @@
import * as Automerge from 'automerge'
import { Node } from 'slate'
import opInsert from './insert'
import opRemove from './remove'
import opSet from './set'
import opCreate from './create'
import { SyncDoc } from '../model'
const byAction = {
create: opCreate,
remove: opRemove,
@ -15,7 +16,7 @@ const byAction = {
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 action = byAction[op.action]

View File

@ -16,17 +16,17 @@ export const setCursor = (
const newCursor = cursorOps[cursorOps.length - 1]?.newProperties || {}
if (selection) {
doc.cursors[id] = JSON.stringify(
Object.assign(
(doc.cursors[id] && JSON.parse(doc.cursors[id])) || {},
newCursor,
selection,
{
...cursorData,
isForward: Boolean(newCursor.focus)
}
)
const newCursorData = Object.assign(
(doc.cursors[id] && JSON.parse(doc.cursors[id])) || {},
newCursor,
selection,
{
...cursorData,
isForward: Range.isForward(selection)
}
)
doc.cursors[id] = JSON.stringify(newCursorData)
} else {
delete doc.cursors[id]
}

View File

@ -1,7 +1,9 @@
import Automerge from 'automerge'
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'
@ -18,6 +20,6 @@ export interface Cursor extends Range, CursorData {
isForward: boolean
}
export interface Cursors {
export type Cursors = {
[key: string]: Cursor
}

View File

@ -1,10 +1,10 @@
import { Node, Path } from 'slate'
import { SyncDoc } from '../model'
import { SyncValue } from '../model'
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) => {
if (!(isTree(current) || current[idx])) {
throw new TypeError(
@ -30,7 +30,7 @@ export const getParentPath = (
}
export const getParent = (
doc: SyncDoc,
doc: SyncValue,
path: Path,
level = 1
): [any, number] => {
@ -39,4 +39,4 @@ export const getParent = (
return [getTarget(doc, parentPath), idx]
}
export const getChildren = (node: Node) => node.children || node
export const getChildren = (node: any) => node.children || node

View File

@ -1,6 +1,6 @@
{
"name": "@slate-collaborative/client",
"version": "0.5.0",
"version": "0.6.0",
"files": [
"lib"
],
@ -17,8 +17,8 @@
"author": "cudr",
"license": "MIT",
"scripts": {
"prepublishOnly": "npm run build",
"build": "npm run build:types && npm run build:js",
"prepublishOnly": "npm run build:module",
"build:module": "npm run build:types && npm run build:js",
"build:types": "tsc --emitDeclarationOnly",
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
"watch": "yarn build:js -w"
@ -26,9 +26,9 @@
"dependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/preset-react": "^7.0.0",
"@slate-collaborative/bridge": "^0.5.0",
"automerge": "^0.14.0",
"slate": "^0.57.2",
"@slate-collaborative/bridge": "0.6.0",
"automerge": "0.14.0",
"slate": "0.58.0",
"socket.io-client": "^2.3.0",
"typescript": "^3.8.3"
},
@ -44,5 +44,6 @@
},
"directories": {
"lib": "lib"
}
},
"gitHead": "1a29cf0da2dc171c1fadd5c8e6eac2327b5b0241"
}

View File

@ -66,7 +66,7 @@ export const AutomergeEditor = {
let changed
for await (let op of operations) {
changed = Automerge.change(changed || doc, d =>
changed = Automerge.change<SyncDoc>(changed || doc, d =>
applyOperation(d.children, op)
)
}
@ -143,7 +143,7 @@ export const AutomergeEditor = {
garbageCursor: (e: AutomergeEditor, docId: string) => {
const doc = e.docSet.getDoc(docId)
const changed = Automerge.change<SyncDoc>(doc, d => {
const changed = Automerge.change<SyncDoc>(doc, (d: any) => {
delete d.cusors
})

View File

@ -38,17 +38,28 @@ const useCursor = (
if (Range.includes(cursor, path)) {
const { focus, anchor, isForward } = cursor
const isFocusNode = Path.equals(focus.path, path)
const isAnchorNode = Path.equals(anchor.path, path)
ranges.push({
...cursor,
isCaret: isForward
? Path.equals(focus.path, path)
: Path.equals(anchor.path, path),
anchor: Path.isBefore(anchor.path, path)
? { ...anchor, offset: 0 }
: anchor,
focus: Path.isAfter(focus.path, path)
? { ...focus, offset: node.text.length }
: focus
isCaret: isFocusNode,
anchor: {
path,
offset: isAnchorNode
? anchor.offset
: isForward
? 0
: node.text.length
},
focus: {
path,
offset: isFocusNode
? focus.offset
: isForward
? node.text.length
: 0
}
})
}
})

View File

@ -31,6 +31,7 @@ const withAutomerge = <T extends Editor>(
if (e.connection) e.connection.close()
e.connection = AutomergeEditor.createConnection(e, (data: CollabAction) =>
//@ts-ignore
e.send(data)
)

View File

@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@slate-collaborative/bridge": ["../../bridge"],
"@slate-collaborative/client": ["../../client"]
}
}
}

View File

@ -1,12 +1,12 @@
{
"name": "@slate-collaborative/example",
"version": "0.5.0",
"version": "0.6.0",
"private": true,
"dependencies": {
"@emotion/core": "^10.0.17",
"@emotion/styled": "^10.0.17",
"@slate-collaborative/backend": "^0.5.0",
"@slate-collaborative/client": "^0.5.0",
"@slate-collaborative/backend": "^0.6.0",
"@slate-collaborative/client": "^0.6.0",
"@types/faker": "^4.1.5",
"@types/jest": "24.0.18",
"@types/node": "12.7.5",
@ -22,15 +22,16 @@
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "3.1.2",
"slate": "^0.57.2",
"slate-history": "^0.57.2",
"slate-react": "^0.57.2",
"slate": "0.58.0",
"slate-history": "0.58.0",
"slate-react": "0.58.0",
"typescript": "^3.8.3"
},
"scripts": {
"start": "node server.js",
"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\"",
"serve": "nodemon --watch ../backend/lib --inspect server.js"
},
@ -48,5 +49,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"engines": {
"node": "12.x"
}
}

View File

@ -10,7 +10,7 @@ import styled from '@emotion/styled'
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'

View File

@ -9,11 +9,11 @@ import {
useSlate
} from 'slate-react'
import { ClientFrame, IconButton, Icon } from './Elements'
import { ClientFrame, IconButton, Icon } from './Components'
import Caret from './Caret'
const LIST_TYPES = ['numbered-list', 'bulleted-list']
const LIST_TYPES: string[] = ['numbered-list', 'bulleted-list']
export interface EditorFrame {
editor: ReactEditor
@ -75,7 +75,7 @@ const toggleBlock = (editor: any, format: any) => {
const isList = LIST_TYPES.includes(format)
Transforms.unwrapNodes(editor, {
match: n => LIST_TYPES.includes(n.type),
match: n => LIST_TYPES.includes(n.type as any),
split: true
})
@ -151,10 +151,12 @@ const Leaf: React.FC<RenderLeafProps> = ({ attributes, children, leaf }) => {
return (
<span
{...attributes}
style={{
position: 'relative',
backgroundColor: leaf.alphaColor
}}
style={
{
position: 'relative',
backgroundColor: leaf.alphaColor
} as any
}
>
{leaf.isCaret ? <Caret {...(leaf as any)} /> : null}
{children}

View File

@ -3,7 +3,7 @@ import React, { useState, ChangeEvent } from 'react'
import faker from 'faker'
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'

View 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" }
]
}

View File

@ -2,25 +2,30 @@
"include": [
"src/**/*"
],
"extends": "./extend.tsconfig.json",
"extends": "./tsconfig.extend.json",
"compilerOptions": {
"rootDir": "../",
"baseUrl": "./src",
"allowJs": true,
"skipLibCheck": true,
"downlevelIteration": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"resolveJsonModule": true,
"declaration": false,
"declarationMap": false,
"noEmit": true
},
"references": [
{
"path": "../client"
},
{
"path": "../backend"
}
]
"noEmit": true,
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"module": "esnext",
"moduleResolution": "node",
"jsx": "react"
}
}

View 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"]
}