@@ -3,174 +3,151 @@ import {ClockDecoder} from '../../../../json-crdt-patch/codec/clock/ClockDecoder
33import { ITimestampStruct , Timestamp } from '../../../../json-crdt-patch/clock' ;
44import { Model , UNDEFINED } from '../../../model/Model' ;
55import { JsonCrdtDataType , ORIGIN , SESSION } from '../../../../json-crdt-patch/constants' ;
6+ import type * as t from './types' ;
67
78export class Decoder {
89 protected time ?: number ;
910 protected clockDecoder ?: ClockDecoder ;
1011
11- public decode ( data : unknown [ ] ) : Model {
12- const x = data [ 0 ] ;
13- const isServerTime = typeof x === 'number' ;
12+ public decode ( doc : t . JsonCrdtCompactDocument ) : Model {
13+ const [ time , root ] = doc ;
14+ const isServerTime = typeof time === 'number' ;
1415 if ( isServerTime ) {
15- this . time = x ;
16+ this . time = time ;
1617 } else {
17- this . clockDecoder = ClockDecoder . fromArr ( x as number [ ] ) ;
18+ this . clockDecoder = ClockDecoder . fromArr ( time as number [ ] ) ;
1819 }
19- const doc = isServerTime ? Model . withServerClock ( x as number ) : Model . withLogicalClock ( this . clockDecoder ! . clock ) ;
20- const val = data [ 1 ] ? this . decodeNode ( doc , data [ 1 ] ) : UNDEFINED ;
21- doc . root = new nodes . RootNode ( doc , val . id ) ;
22- return doc ;
20+ const model = isServerTime ? Model . withServerClock ( time as number ) : Model . withLogicalClock ( this . clockDecoder ! . clock ) ;
21+ const val = root ? this . decNode ( model , root ) : UNDEFINED ;
22+ model . root = new nodes . RootNode ( model , val . id ) ;
23+ return model ;
2324 }
2425
25- protected ts ( arr : unknown [ ] , index : number ) : [ ITimestampStruct , number ] {
26- const x = arr [ index ] ;
26+ protected ts ( x : t . JsonCrdtCompactTimestamp ) : ITimestampStruct {
2727 if ( typeof x === 'number' ) {
28- if ( x < 0 ) {
29- const sessionIndex = - x ;
30- const timeDiff = arr [ index + 1 ] as number ;
31- return [ this . clockDecoder ! . decodeId ( sessionIndex , timeDiff ) , index + 2 ] ;
32- } else {
33- return [ new Timestamp ( SESSION . SERVER , this . time ! - x ) , index + 1 ] ;
34- }
28+ return new Timestamp ( SESSION . SERVER , this . time ! - x ) ;
3529 } else {
36- const time = ( x as [ number ] ) [ 0 ] ;
37- switch ( time ) {
38- case ORIGIN . time :
39- return [ ORIGIN , index + 1 ] ;
40- default :
41- return [ new Timestamp ( SESSION . SYSTEM , time ) , index + 1 ] ;
30+ const [ sid , time ] = x as [ number , number ] ;
31+ if ( sid < 0 ) {
32+ return this . clockDecoder ! . decodeId ( - sid , time ) ;
33+ } else {
34+ return new Timestamp ( sid , time ) ;
4235 }
4336 }
4437 }
4538
46- protected decodeNode ( doc : Model , data : unknown ) : nodes . JsonNode {
47- if ( data instanceof Array ) {
48- switch ( data [ 0 ] ) {
49- case JsonCrdtDataType . con :
50- return this . decCon ( doc , data ) ;
51- case JsonCrdtDataType . con + 10 :
52- return this . decConId ( doc , data ) ;
53- case JsonCrdtDataType . val :
54- return this . decVal ( doc , data ) ;
55- case JsonCrdtDataType . obj :
56- return this . decObj ( doc , data ) ;
57- case JsonCrdtDataType . vec :
58- return this . decVec ( doc , data ) ;
59- case JsonCrdtDataType . str :
60- return this . decStr ( doc , data ) ;
61- case JsonCrdtDataType . bin :
62- return this . decBin ( doc , data ) ;
63- case JsonCrdtDataType . arr :
64- return this . decArr ( doc , data ) ;
65- }
39+ protected decNode ( model : Model , node : t . JsonCrdtCompactNode ) : nodes . JsonNode {
40+ switch ( node [ 0 ] ) {
41+ case JsonCrdtDataType . con : return this . decCon ( model , node ) ;
42+ case JsonCrdtDataType . val : return this . decVal ( model , node ) ;
43+ case JsonCrdtDataType . obj : return this . decObj ( model , node ) ;
44+ case JsonCrdtDataType . vec : return this . decVec ( model , node ) ;
45+ case JsonCrdtDataType . str : return this . decStr ( model , node ) ;
46+ case JsonCrdtDataType . bin : return this . decBin ( model , node ) ;
47+ case JsonCrdtDataType . arr : return this . decArr ( model , node ) ;
6648 }
6749 throw new Error ( 'UNKNOWN_NODE' ) ;
6850 }
6951
70- protected decObj ( doc : Model , data : unknown [ ] ) : nodes . ObjNode {
71- const [ id , index ] = this . ts ( data , 1 ) ;
72- const obj = new nodes . ObjNode ( doc , id ) ;
73- const length = data . length ;
74- for ( let i = index ; i < length ; ) {
75- const key = data [ i ] as string ;
76- const val = this . decodeNode ( doc , data [ ++ i ] ) ;
77- obj . put ( key , val . id ) ;
78- i ++ ;
52+ protected decCon ( doc : Model , node : t . JsonCrdtCompactCon ) : nodes . ConNode {
53+ const id = this . ts ( node [ 1 ] ) ;
54+ let data : unknown | undefined | Timestamp = node [ 2 ] ;
55+ if ( node . length > 3 ) {
56+ const specialData = node [ 3 ] as unknown ;
57+ if ( ! specialData ) data = undefined ;
58+ else data = this . ts ( specialData as t . JsonCrdtCompactTimestamp ) ;
7959 }
60+ const obj = new nodes . ConNode ( id , data ) ;
61+ doc . index . set ( id , obj ) ;
62+ return obj ;
63+ }
64+
65+ protected decVal ( doc : Model , node : t . JsonCrdtCompactVal ) : nodes . ValNode {
66+ const id = this . ts ( node [ 1 ] ) ;
67+ const child = this . decNode ( doc , node [ 2 ] ) ;
68+ const obj = new nodes . ValNode ( doc , id , child . id ) ;
8069 doc . index . set ( id , obj ) ;
8170 return obj ;
8271 }
8372
84- protected decVec ( doc : Model , data : unknown [ ] ) : nodes . VecNode {
85- const [ id , index ] = this . ts ( data , 1 ) ;
86- const obj = new nodes . VecNode ( doc , id ) ;
87- const length = data . length ;
73+ protected decObj ( model : Model , node : t . JsonCrdtCompactObj ) : nodes . ObjNode {
74+ const id = this . ts ( node [ 1 ] ) ;
75+ const obj = new nodes . ObjNode ( model , id ) ;
76+ const map = node [ 2 ] as t . JsonCrdtCompactObj [ 2 ] ;
77+ for ( const key in map ) {
78+ const val = this . decNode ( model , map [ key ] ) ;
79+ obj . put ( key , val . id ) ;
80+ }
81+ model . index . set ( id , obj ) ;
82+ return obj ;
83+ }
84+
85+ protected decVec ( model : Model , node : t . JsonCrdtCompactVec ) : nodes . VecNode {
86+ const id = this . ts ( node [ 1 ] ) ;
87+ const obj = new nodes . VecNode ( model , id ) ;
88+ const map = node [ 2 ] as t . JsonCrdtCompactVec [ 2 ] ;
8889 const elements = obj . elements ;
89- for ( let i = index ; i < length ; ) {
90- const component = data [ i ++ ] ;
91- if ( ! component ) elements . push ( undefined ) ;
90+ const length = map . length ;
91+ for ( let i = 0 ; i < length ; i ++ ) {
92+ const item = map [ i ] ;
93+ if ( ! item ) elements . push ( undefined ) ;
9294 else {
93- const node = this . decodeNode ( doc , component ) ;
94- elements . push ( node . id ) ;
95+ const child = this . decNode ( model , item ) ;
96+ elements . push ( child . id ) ;
9597 }
9698 }
97- doc . index . set ( id , obj ) ;
99+ model . index . set ( id , obj ) ;
98100 return obj ;
99101 }
100102
101- protected decArr ( doc : Model , data : unknown [ ] ) : nodes . ArrNode {
102- const size = data [ 1 ] as number ;
103- const [ id , index ] = this . ts ( data , 2 ) ;
104- const obj = new nodes . ArrNode ( doc , id ) ;
105- const self = this ;
106- let i = index ;
103+ protected decStr ( doc : Model , node : t . JsonCrdtCompactStr ) : nodes . StrNode {
104+ const id = this . ts ( node [ 1 ] ) ;
105+ const obj = new nodes . StrNode ( id ) ;
106+ const chunks = node [ 2 ] as t . JsonCrdtCompactStr [ 2 ] ;
107+ const size = chunks . length ;
108+ let i = 0 ;
107109 obj . ingest ( size , ( ) => {
108- const [ chunkId , idx ] = self . ts ( data , i ) ;
109- const content = data [ idx ] ;
110- i = idx + 1 ;
111- if ( typeof content === 'number' ) return new nodes . ArrChunk ( chunkId , content , undefined ) ;
112- const ids = ( content as unknown [ ] ) . map ( ( c ) => this . decodeNode ( doc , c ) . id ) ;
113- return new nodes . ArrChunk ( chunkId , ( content as string ) . length , ids ) ;
114- } ) ;
115- doc . index . set ( id , obj ) ;
116- return obj ;
117- }
118-
119- protected decStr ( doc : Model , data : unknown [ ] ) : nodes . StrNode {
120- const size = data [ 1 ] as number ;
121- const [ id , index ] = this . ts ( data , 2 ) ;
122- const node = new nodes . StrNode ( id ) ;
123- const self = this ;
124- let i = index ;
125- node . ingest ( size , ( ) => {
126- const [ chunkId , idx ] = self . ts ( data , i ) ;
127- const content = data [ idx ] ;
128- i = idx + 1 ;
110+ const chunk = chunks [ i ] ;
111+ const chunkId = this . ts ( chunk [ 0 ] ) ;
112+ const content = chunk [ 1 ] ;
129113 if ( typeof content === 'number' ) return new nodes . StrChunk ( chunkId , content , '' ) ;
130114 return new nodes . StrChunk ( chunkId , ( content as string ) . length , content as string ) ;
131115 } ) ;
132- doc . index . set ( id , node ) ;
133- return node ;
134- }
135-
136- protected decBin ( doc : Model , data : unknown [ ] ) : nodes . BinNode {
137- const size = data [ 1 ] as number ;
138- const [ id , index ] = this . ts ( data , 2 ) ;
139- const node = new nodes . BinNode ( id ) ;
140- const self = this ;
141- let i = index ;
142- node . ingest ( size , ( ) => {
143- const [ chunkId , idx ] = self . ts ( data , i ) ;
144- const content = data [ idx ] ;
145- i = idx + 1 ;
146- if ( typeof content === 'number' ) return new nodes . BinChunk ( chunkId , content , undefined ) ;
147- const buf = content as Uint8Array ;
148- return new nodes . BinChunk ( chunkId , buf . length , buf ) ;
149- } ) ;
150- doc . index . set ( id , node ) ;
151- return node ;
152- }
153-
154- protected decVal ( doc : Model , data : unknown [ ] ) : nodes . ValNode {
155- const [ id , index ] = this . ts ( data , 1 ) ;
156- const child = this . decodeNode ( doc , data [ index ] ) ;
157- const obj = new nodes . ValNode ( doc , id , child . id ) ;
158116 doc . index . set ( id , obj ) ;
159117 return obj ;
160118 }
161119
162- protected decCon ( doc : Model , data : unknown [ ] ) : nodes . ConNode {
163- const [ id , index ] = this . ts ( data , 1 ) ;
164- const value = data [ index ] ;
165- const obj = new nodes . ConNode ( id , value ) ;
120+ protected decBin ( doc : Model , node : t . JsonCrdtCompactBin ) : nodes . BinNode {
121+ const id = this . ts ( node [ 1 ] ) ;
122+ const obj = new nodes . BinNode ( id ) ;
123+ const chunks = node [ 2 ] as t . JsonCrdtCompactBin [ 2 ] ;
124+ const size = chunks . length ;
125+ let i = 0 ;
126+ obj . ingest ( size , ( ) => {
127+ const chunk = chunks [ i ] ;
128+ const chunkId = this . ts ( chunk [ 0 ] ) ;
129+ const content = chunk [ 1 ] ;
130+ if ( typeof content === 'number' ) return new nodes . BinChunk ( chunkId , content , undefined ) ;
131+ return new nodes . BinChunk ( chunkId , content . length , content ) ;
132+ } ) ;
166133 doc . index . set ( id , obj ) ;
167134 return obj ;
168135 }
169136
170- protected decConId ( doc : Model , data : unknown [ ] ) : nodes . ConNode {
171- const [ id , index ] = this . ts ( data , 1 ) ;
172- const val = this . ts ( data , index ) [ 0 ] ;
173- const obj = new nodes . ConNode ( id , val ) ;
137+ protected decArr ( doc : Model , node : t . JsonCrdtCompactArr ) : nodes . ArrNode {
138+ const id = this . ts ( node [ 1 ] ) ;
139+ const obj = new nodes . ArrNode ( doc , id ) ;
140+ const chunks = node [ 2 ] as t . JsonCrdtCompactArr [ 2 ] ;
141+ const size = chunks . length ;
142+ let i = 0 ;
143+ obj . ingest ( size , ( ) => {
144+ const chunk = chunks [ i ] ;
145+ const chunkId = this . ts ( chunk [ 0 ] ) ;
146+ const content = chunk [ 1 ] ;
147+ if ( typeof content === 'number' ) return new nodes . ArrChunk ( chunkId , content , undefined ) ;
148+ const ids = ( content as t . JsonCrdtCompactNode [ ] ) . map ( ( c ) => this . decNode ( doc , c ) . id ) ;
149+ return new nodes . ArrChunk ( chunkId , content . length , ids ) ;
150+ } ) ;
174151 doc . index . set ( id , obj ) ;
175152 return obj ;
176153 }
0 commit comments