mirror of
https://github.com/cudr/slate-collaborative.git
synced 2024-10-27 20:34:06 +00:00
Do not do shortcut merge batch operations, do it one by one for toSlateOps.
This commit is contained in:
parent
f65ab040ee
commit
4576605958
@ -19,10 +19,12 @@ const byAction = {
|
|||||||
const rootKey = '00000000-0000-0000-0000-000000000000'
|
const rootKey = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
const toSlateOp = (ops: Automerge.Diff[], doc: SyncDoc) => {
|
const toSlateOp = (ops: Automerge.Diff[], doc: SyncDoc) => {
|
||||||
|
const tempDoc = toJS(doc)
|
||||||
|
|
||||||
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]
|
||||||
|
|
||||||
const result = action ? action(op, acc, doc) : acc
|
const result = action ? action(op, acc, doc, tempDoc) : acc
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -34,9 +36,7 @@ const toSlateOp = (ops: Automerge.Diff[], doc: SyncDoc) => {
|
|||||||
[]
|
[]
|
||||||
])
|
])
|
||||||
|
|
||||||
const tempDoc = toJS(doc)
|
return defer.flatMap(op => op).filter(op => op)
|
||||||
|
|
||||||
return defer.flatMap(op => op(tempTree, tempDoc)).filter(op => op)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { toSlateOp }
|
export { toSlateOp }
|
||||||
|
@ -1,25 +1,35 @@
|
|||||||
import * as Automerge from 'automerge'
|
import * as Automerge from 'automerge'
|
||||||
|
import { Element, Node } from 'slate'
|
||||||
|
|
||||||
import { toSlatePath, toJS } from '../utils'
|
import { toSlatePath, toJS } from '../utils'
|
||||||
|
|
||||||
import { SyncDoc } from '../model'
|
import { SyncDoc } from '../model'
|
||||||
|
|
||||||
const insertTextOp = ({ index, path, value }: Automerge.Diff) => () => ({
|
const insertTextOp = ({ index, path, value }: Automerge.Diff) => (
|
||||||
|
map: any,
|
||||||
|
doc: Element
|
||||||
|
) => {
|
||||||
|
const slatePath = toSlatePath(path)
|
||||||
|
const node = Node.get(doc, slatePath)!
|
||||||
|
const text = node.text! as string
|
||||||
|
node.text = [text.slice(0, index), value, text.slice(index)].join('')
|
||||||
|
return {
|
||||||
type: 'insert_text',
|
type: 'insert_text',
|
||||||
path: toSlatePath(path),
|
path: slatePath,
|
||||||
offset: index,
|
offset: index,
|
||||||
text: value,
|
text: value,
|
||||||
marks: []
|
marks: []
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const insertNodeOp = (
|
const insertNodeOp = (
|
||||||
{ value, obj, index, path }: Automerge.Diff,
|
{ value, obj, index, path }: Automerge.Diff,
|
||||||
doc: any
|
doc: any
|
||||||
) => (map: any) => {
|
) => (map: any, tmpDoc: Element) => {
|
||||||
const ops: any = []
|
const ops: any = []
|
||||||
|
|
||||||
const iterate = ({ children, ...json }: any, path: any) => {
|
const iterate = ({ children, ...json }: any, path: any) => {
|
||||||
const node = children ? { ...json, children: [] } : json
|
const node = toJS(children ? { ...json, children: [] } : json)
|
||||||
|
|
||||||
ops.push({
|
ops.push({
|
||||||
type: 'insert_node',
|
type: 'insert_node',
|
||||||
@ -27,6 +37,11 @@ const insertNodeOp = (
|
|||||||
node
|
node
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// update the temp doc so later remove_node won't error.
|
||||||
|
const parent = Node.parent(tmpDoc, path)
|
||||||
|
const index = path[path.length - 1]
|
||||||
|
parent.children.splice(index, 0, toJS(node))
|
||||||
|
|
||||||
children &&
|
children &&
|
||||||
children.forEach((n: any, i: any) => {
|
children.forEach((n: any, i: any) => {
|
||||||
const node = map[n] || Automerge.getObjectById(doc, n)
|
const node = map[n] || Automerge.getObjectById(doc, n)
|
||||||
@ -48,7 +63,12 @@ const insertByType = {
|
|||||||
list: insertNodeOp
|
list: insertNodeOp
|
||||||
}
|
}
|
||||||
|
|
||||||
const opInsert = (op: Automerge.Diff, [map, ops]: any, doc: SyncDoc) => {
|
const opInsert = (
|
||||||
|
op: Automerge.Diff,
|
||||||
|
[map, ops]: any,
|
||||||
|
doc: SyncDoc,
|
||||||
|
tmpDoc: Element
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const { link, obj, path, index, type, value } = op
|
const { link, obj, path, index, type, value } = op
|
||||||
|
|
||||||
@ -61,10 +81,11 @@ const opInsert = (op: Automerge.Diff, [map, ops]: any, doc: SyncDoc) => {
|
|||||||
.concat(value)
|
.concat(value)
|
||||||
.concat(map[obj].slice(index))
|
.concat(map[obj].slice(index))
|
||||||
: value
|
: value
|
||||||
} else {
|
}
|
||||||
|
if (path) {
|
||||||
const insert = insertByType[type]
|
const insert = insertByType[type]
|
||||||
|
|
||||||
const operation = insert && insert(op, doc)
|
const operation = insert && insert(op, doc)(map, tmpDoc)
|
||||||
|
|
||||||
ops.push(operation)
|
ops.push(operation)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,9 @@ const removeTextOp = (op: Automerge.Diff) => (map: any, doc: Element) => {
|
|||||||
const text = node?.text?.[index] || '*'
|
const text = node?.text?.[index] || '*'
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
node.text = node?.text ? (node.text.slice(0, index) + node.text.slice(index + 1)) : ''
|
node.text = node?.text
|
||||||
|
? node.text.slice(0, index) + node.text.slice(index + 1)
|
||||||
|
: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -38,17 +40,15 @@ const removeTextOp = (op: Automerge.Diff) => (map: any, doc: Element) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeNodeOp = (op: Automerge.Diff) => (
|
const removeNodeOp = (op: Automerge.Diff) => (map: any, doc: Element) => {
|
||||||
map: any,
|
|
||||||
doc: Element
|
|
||||||
) => {
|
|
||||||
try {
|
try {
|
||||||
const { index, obj, path } = op
|
const { index, obj, path } = op
|
||||||
|
|
||||||
const slatePath = toSlatePath(path)
|
const slatePath = toSlatePath(path)
|
||||||
|
|
||||||
const parent = getTarget(doc, slatePath)
|
const parent = getTarget(doc, slatePath)
|
||||||
const target = parent?.children?.[index as number] || parent?.[index as number] || { children: [] }
|
const target = parent?.children?.[index as number] ||
|
||||||
|
parent?.[index as number] || { children: [] }
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
throw new TypeError('Target is not found!')
|
throw new TypeError('Target is not found!')
|
||||||
@ -62,6 +62,12 @@ const removeNodeOp = (op: Automerge.Diff) => (
|
|||||||
throw new TypeError('Index is not a number')
|
throw new TypeError('Index is not a number')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent?.children?.[index as number]) {
|
||||||
|
parent.children.splice(index, 1)
|
||||||
|
} else if (parent?.[index as number]) {
|
||||||
|
parent.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'remove_node',
|
type: 'remove_node',
|
||||||
path: slatePath.length ? slatePath.concat(index) : [index],
|
path: slatePath.length ? slatePath.concat(index) : [index],
|
||||||
@ -72,7 +78,12 @@ const removeNodeOp = (op: Automerge.Diff) => (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const opRemove = (op: Automerge.Diff, [map, ops]: any) => {
|
const opRemove = (
|
||||||
|
op: Automerge.Diff,
|
||||||
|
[map, ops]: any,
|
||||||
|
doc: any,
|
||||||
|
tmpDoc: Element
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const { index, path, obj, type } = op
|
const { index, path, obj, type } = op
|
||||||
|
|
||||||
@ -95,7 +106,7 @@ const opRemove = (op: Automerge.Diff, [map, ops]: any) => {
|
|||||||
|
|
||||||
const fn = key === 'text' ? removeTextOp : removeNodeOp
|
const fn = key === 'text' ? removeTextOp : removeNodeOp
|
||||||
|
|
||||||
return [map, [...ops, fn(op)]]
|
return [map, [...ops, fn(op)(map, tmpDoc)]]
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e, op, toJS(map))
|
console.error(e, op, toJS(map))
|
||||||
|
|
||||||
|
@ -1,29 +1,33 @@
|
|||||||
import * as Automerge from 'automerge'
|
import * as Automerge from 'automerge'
|
||||||
|
import { Element, Node } from 'slate'
|
||||||
|
|
||||||
import { toSlatePath, toJS } from '../utils'
|
import { toSlatePath, toJS } from '../utils'
|
||||||
|
|
||||||
const setDataOp = (
|
const setDataOp = (
|
||||||
{ key = '', obj, path, value }: Automerge.Diff,
|
{ key = '', obj, path, value }: Automerge.Diff,
|
||||||
doc: any
|
doc: any
|
||||||
) => (map: any) => {
|
) => (map: any, tmpDoc: Element) => {
|
||||||
|
const slatePath = toSlatePath(path)
|
||||||
|
const node = Node.get(tmpDoc, slatePath)
|
||||||
|
node[key] = toJS(map?.[value] || value)
|
||||||
return {
|
return {
|
||||||
type: 'set_node',
|
type: 'set_node',
|
||||||
path: toSlatePath(path),
|
path: slatePath,
|
||||||
properties: {
|
properties: {
|
||||||
[key]: toJS(Automerge.getObjectById(doc, obj)?.[key])
|
[key]: toJS(Automerge.getObjectById(doc, obj)?.[key])
|
||||||
},
|
},
|
||||||
newProperties: {
|
newProperties: {
|
||||||
[key]: map?.[value] || value
|
[key]: toJS(node[key])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const opSet = (op: Automerge.Diff, [map, ops]: any, doc: any) => {
|
const opSet = (op: Automerge.Diff, [map, ops]: any, doc: any, tmpDoc: any) => {
|
||||||
const { link, value, path, obj, key } = op
|
const { link, value, path, obj, key } = op
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (path && path.length && path[0] !== 'cursors') {
|
if (path && path.length && path[0] !== 'cursors') {
|
||||||
ops.push(setDataOp(op, doc))
|
ops.push(setDataOp(op, doc)(map, tmpDoc))
|
||||||
} else if (map[obj]) {
|
} else if (map[obj]) {
|
||||||
map[obj][key as any] = link ? map[value] : value
|
map[obj][key as any] = link ? map[value] : value
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user