import { Op , OpType } from "./live" ; export type ApplyResult = { reverse : Op [ ] ; modified : AbstractCrdt ; } | { modified : false ; } ; export interface Doc { generateId : ( ) => string ; generateOpId : ( ) => string ; addItem : ( id : string , item : AbstractCrdt ) => void ; deleteItem : ( id : string ) => void ; dispatch : ( ops : Op [ ] , reverseOps : Op [ ] , modified : AbstractCrdt [ ] ) => void ; } export abstract class AbstractCrdt { #parent ? : AbstractCrdt ; #doc ? : Doc ; #id ? : string ; #parentKey ? : string ; /**
     * INTERNAL
     */ protected get _doc ( ) { return this . #doc ; } /**
     * INTERNAL
     */ get _id ( ) { return this . #id ; } /**
     * INTERNAL
     */ get _parent ( ) { return this . #parent ; } /**
     * INTERNAL
     */ get _parentKey ( ) { return this . #parentKey ; } /**
     * INTERNAL
     */ _apply ( op ) { switch ( op . type ) { case OpType . DeleteCrdt : { if ( this . _parent != null && this . _parentKey != null ) { const parent = this . _parent ; const reverse = this . _serialize ( this . _parent . _id ! , this . _parentKey ) ; this . _parent . _detachChild ( this ) ; return { modified : parent , reverse } ; } return { modified : false } ; } } return { modified : false } ; } /**
     * INTERNAL
     */ _setParentLink ( parent , key ) { if ( this . #parent != null && this . #parent !== parent ) { throw new Error ( "Cannot attach parent if it already exist" ) ; } this . #parentKey = key ; this . #parent = parent ; } /**
     * INTERNAL
     */ _attach ( id , doc ) { if ( this . #id || this . #doc ) { throw new Error ( "Cannot attach if CRDT is already attached" ) ; } doc . addItem ( id , this ) ; this . #id = id ; this . #doc = doc ; } /**
     * INTERNAL
     */ abstract _attachChild ( id , key , crdt ) ; /**
     * INTERNAL
     */ _detach ( ) { if ( this . #doc && this . #id ) { this . #doc . deleteItem ( this . #id ) ; } this . #parent = undefined ; this . #doc = undefined ; } /**
     * INTERNAL
     */ abstract _detachChild ( crdt ) ; /**
     * INTERNAL
     */ abstract _serialize ( parentId , parentKey ) ; }