fix: remove node and remove text errors

This commit is contained in:
Eric Maciel 2021-01-12 11:26:12 -05:00
parent 89dafd78b9
commit eb6f39679b
5 changed files with 439 additions and 10 deletions

View File

@ -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)

View File

@ -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)) {

View File

@ -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]

View File

@ -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()

File diff suppressed because one or more lines are too long