mirror of
https://github.com/cudr/slate-collaborative.git
synced 2025-06-09 19:04:05 +00:00
fix: remove node and remove text errors
This commit is contained in:
parent
89dafd78b9
commit
eb6f39679b
@ -22,6 +22,10 @@ export const removeText = (
|
||||
): SyncValue => {
|
||||
const node = getTarget(doc, op.path)
|
||||
|
||||
// if we are removing text for a node that no longer exists
|
||||
// treat this as a noop
|
||||
if (!node) return doc
|
||||
|
||||
const offset = Math.min(node.text.length, op.offset)
|
||||
|
||||
node.text.deleteAt(offset, op.text.length)
|
||||
|
@ -10,12 +10,12 @@ const removeTextOp = (op: Automerge.Diff) => (map: any, doc: Element) => {
|
||||
|
||||
const slatePath = toSlatePath(path).slice(0, path?.length)
|
||||
|
||||
let node
|
||||
const node = getTarget(doc, slatePath) || map[obj]
|
||||
|
||||
try {
|
||||
node = getTarget(doc, slatePath) || map[obj]
|
||||
} catch (e) {
|
||||
console.error(e, op, doc)
|
||||
// if we are removing text for a node that has already been removed
|
||||
// treat this as a noop
|
||||
if (!node) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof index !== 'number') return
|
||||
@ -41,6 +41,11 @@ const removeNodeOp = ({ index, obj, path }: Automerge.Diff) => (
|
||||
const slatePath = toSlatePath(path)
|
||||
|
||||
const parent = getTarget(doc, slatePath)
|
||||
|
||||
// if we are removing a node that has already been removed
|
||||
// treat this as a noop
|
||||
if (!parent) return
|
||||
|
||||
const target = parent?.children?.[index as number] || { children: [] }
|
||||
|
||||
if (!map.hasOwnProperty(obj)) {
|
||||
|
@ -6,10 +6,8 @@ export const isTree = (node: Node): boolean => Boolean(node?.children)
|
||||
|
||||
export const getTarget = (doc: SyncValue | Element, path: Path) => {
|
||||
const iterate = (current: any, idx: number) => {
|
||||
if (!(isTree(current) || current[idx])) {
|
||||
throw new TypeError(
|
||||
`path ${path.toString()} does not match tree ${JSON.stringify(current)}`
|
||||
)
|
||||
if (current === null || !(isTree(current) || current[idx])) {
|
||||
return null
|
||||
}
|
||||
|
||||
return current[idx] || current?.children[idx]
|
||||
|
@ -1,7 +1,9 @@
|
||||
import Automerge, { Frontend } from 'automerge'
|
||||
import { createServer } from 'http'
|
||||
import fs from 'fs'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import { createEditor, Node, Transforms } from 'slate'
|
||||
import { toJS } from '@hiveteams/collab-bridge'
|
||||
import { SyncDoc, toJS, toSlateOp } from '@hiveteams/collab-bridge'
|
||||
import AutomergeCollaboration from '@hiveteams/collab-backend/lib/AutomergeCollaboration'
|
||||
import withIOCollaboration from './withIOCollaboration'
|
||||
import { AutomergeOptions, SocketIOPluginOptions } from './interfaces'
|
||||
@ -186,6 +188,23 @@ describe('automerge editor client tests', () => {
|
||||
editor2.destroy()
|
||||
})
|
||||
|
||||
it('deep nested tree error', () => {
|
||||
// Ready from our test json file for the deep tree error
|
||||
// This allows us to easily reproduce real production errors
|
||||
// and create test cases that resolve those errors
|
||||
const rawData = fs.readFileSync(
|
||||
`${__dirname}/test-json/deep-tree.json`,
|
||||
'utf-8'
|
||||
)
|
||||
const parsedData = JSON.parse(rawData)
|
||||
const { current, operations } = parsedData
|
||||
const currentDoc = Automerge.load<SyncDoc>(current)
|
||||
|
||||
// ensure no errors throw when removing a deep tree node
|
||||
// that has already been removed
|
||||
toSlateOp(operations, currentDoc)
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
collabBackend.destroy()
|
||||
server.close()
|
||||
|
403
packages/client/src/test-json/deep-tree.json
Normal file
403
packages/client/src/test-json/deep-tree.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user