1- import type { Model } from '../model' ;
1+ import { ArrayType } from '../types/rga-array/ArrayType' ;
2+ import { deepEqual } from '../../json-equal/deepEqual' ;
23import { Draft } from '../../json-crdt-patch/Draft' ;
3- import { Op , OpAdd , OpCopy , OpMove , OpRemove , OpReplace , OpTest } from '../../json-patch/op ' ;
4+ import { isChild , Path } from '../../json-pointer ' ;
45import { ObjectType } from '../types/lww-object/ObjectType' ;
5- import { ArrayType } from '../types/rga-array/ArrayType' ;
66import { UNDEFINED_ID } from '../../json-crdt-patch/constants' ;
7- import { isChild , Path } from '../../json-pointer' ;
8- import { deepEqual } from '../../json-equal/deepEqual' ;
7+ import { toPath } from '../../json-pointer/util' ;
8+ import type { Model } from '../model' ;
9+ import type { Operation , OperationAdd , OperationRemove , OperationReplace , OperationMove , OperationCopy , OperationTest , OperationStrIns , OperationStrDel } from '../../json-patch' ;
910
10- export class JsonPatchDraft extends Draft {
11- constructor ( public readonly model : Model ) {
12- super ( ) ;
13- }
11+ export class JsonPatchDraft {
12+ public readonly draft = new Draft ( ) ;
13+
14+ constructor ( public readonly model : Model ) { }
1415
15- public applyOps ( ops : Op [ ] ) {
16+ public applyOps ( ops : Operation [ ] ) : void {
1617 for ( const op of ops ) this . applyOp ( op ) ;
1718 }
1819
19- public applyOp ( op : Op ) : void {
20- if ( op instanceof OpAdd ) this . applyOpAdd ( op ) ;
21- else if ( op instanceof OpRemove ) this . applyOpRemove ( op ) ;
22- else if ( op instanceof OpReplace ) this . applyOpReplace ( op ) ;
23- else if ( op instanceof OpMove ) this . applyOpMove ( op ) ;
24- else if ( op instanceof OpCopy ) this . applyOpCopy ( op ) ;
25- else if ( op instanceof OpTest ) this . applyOpTest ( op ) ;
20+ public applyOp ( op : Operation ) : void {
21+ switch ( op . op ) {
22+ case 'add' : this . applyOpAdd ( op ) ; break ;
23+ case 'remove' : this . applyRemove ( op ) ; break ;
24+ case 'replace' : this . applyReplace ( op ) ; break ;
25+ case 'move' : this . applyMove ( op ) ; break ;
26+ case 'copy' : this . applyCopy ( op ) ; break ;
27+ case 'test' : this . applyTest ( op ) ; break ;
28+ case 'str_ins' : this . applyStrIns ( op ) ; break ;
29+ case 'str_del' : this . applyStrDel ( op ) ; break ;
30+ default : throw new Error ( 'UNKNOWN_OP' ) ;
31+ }
2632 }
2733
28- public applyOpAdd ( op : OpAdd ) : void {
29- const { builder} = this ;
30- const steps = op . path ;
34+ public applyOpAdd ( op : OperationAdd ) : void {
35+ const { builder} = this . draft ;
36+ const steps = toPath ( op . path ) ;
3137 if ( ! steps . length ) this . setRoot ( op . value ) ;
3238 else {
3339 const objSteps = steps . slice ( 0 , steps . length - 1 ) ;
@@ -54,9 +60,9 @@ export class JsonPatchDraft extends Draft {
5460 }
5561 }
5662
57- public applyOpRemove ( op : OpRemove ) : void {
58- const { builder} = this ;
59- const steps = op . path ;
63+ public applyRemove ( op : OperationRemove ) : void {
64+ const { builder} = this . draft ;
65+ const steps = toPath ( op . path ) ;
6066 if ( ! steps . length ) this . setRoot ( null ) ;
6167 else {
6268 const objSteps = steps . slice ( 0 , steps . length - 1 ) ;
@@ -76,30 +82,52 @@ export class JsonPatchDraft extends Draft {
7682 }
7783 }
7884
79- public applyOpReplace ( op : OpReplace ) : void {
85+ public applyReplace ( op : OperationReplace ) : void {
8086 const { path, value} = op ;
81- this . applyOpRemove ( new OpRemove ( path , undefined ) ) ;
82- this . applyOpAdd ( new OpAdd ( path , value ) ) ;
87+ this . applyRemove ( { op : 'remove' , path } ) ;
88+ this . applyOpAdd ( { op : 'add' , path, value} ) ;
8389 }
8490
85- public applyOpMove ( op : OpMove ) : void {
86- const { path, from} = op ;
91+ public applyMove ( op : OperationMove ) : void {
92+ const path = toPath ( op . path ) ;
93+ const from = toPath ( op . from ) ;
8794 if ( isChild ( from , path ) ) throw new Error ( 'INVALID_CHILD' ) ;
8895 const json = this . json ( from ) ;
89- this . applyOpRemove ( new OpRemove ( from , undefined ) ) ;
90- this . applyOpAdd ( new OpAdd ( path , json ) ) ;
96+ this . applyRemove ( { op : 'remove' , path : from } ) ;
97+ this . applyOpAdd ( { op : 'add' , path, value : json } ) ;
9198 }
9299
93- public applyOpCopy ( op : OpCopy ) : void {
94- const { path, from} = op ;
100+ public applyCopy ( op : OperationCopy ) : void {
101+ const path = toPath ( op . path ) ;
102+ const from = toPath ( op . from ) ;
95103 const json = this . json ( from ) ;
96- this . applyOpAdd ( new OpAdd ( path , json ) ) ;
104+ this . applyOpAdd ( { op : 'add' , path, value : json } ) ;
97105 }
98106
99- public applyOpTest ( op : OpTest ) : void {
100- const { path, value } = op ;
107+ public applyTest ( op : OperationTest ) : void {
108+ const path = toPath ( op . path ) ;
101109 const json = this . json ( path ) ;
102- if ( ! deepEqual ( json , value ) ) throw new Error ( 'TEST' ) ;
110+ if ( ! deepEqual ( json , op . value ) ) throw new Error ( 'TEST' ) ;
111+ }
112+
113+ public applyStrIns ( op : OperationStrIns ) : void {
114+ const path = toPath ( op . path ) ;
115+ const { node} = this . model . api . str ( path ) ;
116+ const { builder} = this . draft ;
117+ const length = node . length ( ) ;
118+ const after = op . pos ? node . findId ( length < op . pos ? length - 1 : op . pos - 1 ) : node . id ;
119+ builder . insStr ( node . id , after , op . str ) ;
120+ }
121+
122+ public applyStrDel ( op : OperationStrDel ) : void {
123+ const path = toPath ( op . path ) ;
124+ const { node} = this . model . api . str ( path ) ;
125+ const { builder} = this . draft ;
126+ const length = node . length ( ) ;
127+ if ( length <= op . pos ) return ;
128+ const after = node . findId ( op . pos ) ;
129+ const deletionLength = Math . min ( op . len ?? op . str ! . length , length - op . pos ) ;
130+ builder . del ( node . id , after , deletionLength ) ;
103131 }
104132
105133 private get ( steps : Path ) : unknown {
@@ -127,7 +155,7 @@ export class JsonPatchDraft extends Draft {
127155 }
128156
129157 private setRoot ( json : unknown ) {
130- const { builder} = this ;
158+ const { builder} = this . draft ;
131159 builder . root ( builder . json ( json ) ) ;
132160 }
133161}
0 commit comments