@@ -2,10 +2,10 @@ import {compare, type ITimestampStruct, toDisplayString, equal, tick, containsId
22import { Anchor } from '../constants' ;
33import { ChunkSlice } from '../util/ChunkSlice' ;
44import { updateId } from '../../../json-crdt/hash' ;
5+ import type { AbstractRga , Chunk } from '../../../json-crdt/nodes/rga' ;
56import type { Stateful } from '../types' ;
67import type { Peritext } from '../Peritext' ;
78import type { Printable } from '../../../util/print/types' ;
8- import type { StringChunk } from '../util/types' ;
99
1010/**
1111 * A "point" in a rich-text Peritext document. It is a combination of a
@@ -23,9 +23,10 @@ import type {StringChunk} from '../util/types';
2323 * after the last character, and even after any deleted characters at the end
2424 * of the string.
2525 */
26- export class Point implements Pick < Stateful , 'refresh' > , Printable {
26+ export class Point < T = string > implements Pick < Stateful , 'refresh' > , Printable {
2727 constructor (
2828 protected readonly txt : Peritext ,
29+ protected readonly rga : AbstractRga < T > ,
2930 public id : ITimestampStruct ,
3031 public anchor : Anchor ,
3132 ) { }
@@ -36,7 +37,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
3637 *
3738 * @param point Point to copy.
3839 */
39- public set ( point : Point ) : void {
40+ public set ( point : Point < T > ) : void {
4041 this . id = point . id ;
4142 this . anchor = point . anchor ;
4243 }
@@ -46,8 +47,8 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
4647 *
4748 * @returns Returns a new point with the same ID and anchor as this point.
4849 */
49- public clone ( ) : Point {
50- return new Point ( this . txt , this . id , this . anchor ) ;
50+ public clone ( ) : Point < T > {
51+ return new Point ( this . txt , this . rga , this . id , this . anchor ) ;
5152 }
5253
5354 /**
@@ -60,7 +61,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
6061 * than the other point, and 1 if this point is greater than the other
6162 * point.
6263 */
63- public compare ( other : Point ) : - 1 | 0 | 1 {
64+ public compare ( other : Point < T > ) : - 1 | 0 | 1 {
6465 const cmp = compare ( this . id , other . id ) ;
6566 if ( cmp !== 0 ) return cmp ;
6667 return ( this . anchor - other . anchor ) as - 1 | 0 | 1 ;
@@ -76,7 +77,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
7677 * less than the other point, and positive if this point is greater
7778 * than the other point.
7879 */
79- public compareSpatial ( other : Point ) : number {
80+ public compareSpatial ( other : Point < T > ) : number {
8081 const thisId = this . id ;
8182 const otherId = other . id ;
8283 if ( this . isAbs ( ) ) {
@@ -93,22 +94,22 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
9394 let chunk = this . chunk ( ) ;
9495 if ( ! chunk ) return cmp0 ;
9596 if ( containsId ( chunk . id , chunk . span , otherId ) ) return thisId . time - otherId . time ;
96- const str = this . txt . str ;
97- chunk = str . next ( chunk ) ;
97+ const rga = this . rga ;
98+ chunk = rga . next ( chunk ) ;
9899 while ( chunk ) {
99100 if ( containsId ( chunk . id , chunk . span , otherId ) ) return - 1 ;
100- chunk = str . next ( chunk ) ;
101+ chunk = rga . next ( chunk ) ;
101102 }
102103 return 1 ;
103104 }
104105
105- private _chunk : StringChunk | undefined ;
106+ private _chunk : Chunk < T > | undefined ;
106107
107108 /**
108109 * @returns Returns the chunk that contains the character referenced by the
109110 * point, or `undefined` if the chunk is not found.
110111 */
111- public chunk ( ) : StringChunk | undefined {
112+ public chunk ( ) : Chunk < T > | undefined {
112113 let chunk = this . _chunk ;
113114 const id = this . id ;
114115 if ( chunk ) {
@@ -117,7 +118,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
117118 const idTime = id . time ;
118119 if ( id . sid === chunkId . sid && idTime >= chunkIdTime && idTime < chunkIdTime + chunk . span ) return chunk ;
119120 }
120- this . _chunk = chunk = this . txt . str . findById ( this . id ) ;
121+ this . _chunk = chunk = this . rga . findById ( this . id ) ;
121122 return chunk ;
122123 }
123124
@@ -127,7 +128,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
127128 public pos ( ) : number {
128129 const chunk = this . chunk ( ) ;
129130 if ( ! chunk ) return - 1 ;
130- const pos = this . txt . str . pos ( chunk ) ;
131+ const pos = this . rga . pos ( chunk ) ;
131132 if ( chunk . del ) return pos ;
132133 return pos + this . id . time - chunk . id . time ;
133134 }
@@ -147,7 +148,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
147148 */
148149 public viewPos ( ) : number {
149150 const pos = this . pos ( ) ;
150- if ( pos < 0 ) return this . isAbsStart ( ) ? 0 : this . txt . str . length ( ) ;
151+ if ( pos < 0 ) return this . isAbsStart ( ) ? 0 : this . rga . length ( ) ;
151152 return this . anchor === Anchor . Before ? pos : pos + 1 ;
152153 }
153154
@@ -162,17 +163,16 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
162163 public nextId ( move : number = 1 ) : ITimestampStruct | undefined {
163164 if ( this . isAbsEnd ( ) ) return ;
164165 let remaining : number = move ;
165- const { id, txt} = this ;
166- const str = txt . str ;
167- let chunk : StringChunk | undefined ;
166+ const { id, rga} = this ;
167+ let chunk : Chunk < T > | undefined ;
168168 if ( this . isAbsStart ( ) ) {
169- chunk = str . first ( ) ;
170- while ( chunk && chunk . del ) chunk = str . next ( chunk ) ;
169+ chunk = rga . first ( ) ;
170+ while ( chunk && chunk . del ) chunk = rga . next ( chunk ) ;
171171 if ( ! chunk ) return ;
172172 const span = chunk . span ;
173173 if ( remaining <= span ) return tick ( chunk . id , remaining - 1 ) ;
174174 remaining -= span ;
175- chunk = str . next ( chunk ) ;
175+ chunk = rga . next ( chunk ) ;
176176 } else {
177177 chunk = this . chunk ( ) ;
178178 if ( ! chunk ) return undefined ;
@@ -182,19 +182,19 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
182182 if ( offset + remaining < span ) return tick ( id , remaining ) ;
183183 else remaining -= span - offset - 1 ;
184184 }
185- chunk = str . next ( chunk ) ;
185+ chunk = rga . next ( chunk ) ;
186186 }
187- let lastVisibleChunk : StringChunk | undefined ;
187+ let lastVisibleChunk : Chunk < T > | undefined ;
188188 while ( chunk && remaining >= 0 ) {
189189 if ( chunk . del ) {
190- chunk = str . next ( chunk ) ;
190+ chunk = rga . next ( chunk ) ;
191191 continue ;
192192 }
193193 lastVisibleChunk = chunk ;
194194 const span = chunk . span ;
195195 if ( remaining <= span ) return remaining > 1 ? tick ( chunk . id , remaining - 1 ) : chunk . id ;
196196 remaining -= span ;
197- chunk = str . next ( chunk ) ;
197+ chunk = rga . next ( chunk ) ;
198198 }
199199 if ( remaining > 0 ) return ;
200200 return lastVisibleChunk ? tick ( lastVisibleChunk . id , lastVisibleChunk . span - 1 ) : undefined ;
@@ -208,27 +208,26 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
208208 public prevId ( move : number = 1 ) : ITimestampStruct | undefined {
209209 if ( this . isAbsStart ( ) ) return ;
210210 let remaining : number = move ;
211- const { id, txt} = this ;
212- const str = txt . str ;
211+ const { id, rga} = this ;
213212 let chunk = this . chunk ( ) ;
214- if ( ! chunk ) return str . id ;
213+ if ( ! chunk ) return rga . id ;
215214 if ( ! chunk . del ) {
216215 const offset = id . time - chunk . id . time ;
217216 if ( offset >= remaining ) return tick ( id , - remaining ) ;
218217 remaining -= offset ;
219218 }
220- chunk = str . prev ( chunk ) ;
219+ chunk = rga . prev ( chunk ) ;
221220 while ( chunk ) {
222221 if ( chunk . del ) {
223- chunk = str . prev ( chunk ) ;
222+ chunk = rga . prev ( chunk ) ;
224223 continue ;
225224 }
226225 const span = chunk . span ;
227226 if ( remaining <= span ) {
228227 return tick ( chunk . id , span - remaining ) ;
229228 }
230229 remaining -= span ;
231- chunk = str . prev ( chunk ) ;
230+ chunk = rga . prev ( chunk ) ;
232231 }
233232 return ;
234233 }
@@ -239,10 +238,10 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
239238 *
240239 * @returns A character slice to the left of the point.
241240 */
242- public leftChar ( ) : ChunkSlice | undefined {
243- const str = this . txt . str ;
241+ public leftChar ( ) : ChunkSlice < T > | undefined {
242+ const rga = this . rga ;
244243 if ( this . isAbsEnd ( ) ) {
245- const res = str . findChunk ( str . length ( ) - 1 ) ;
244+ const res = rga . findChunk ( rga . length ( ) - 1 ) ;
246245 if ( ! res ) return ;
247246 return new ChunkSlice ( res [ 0 ] , res [ 1 ] , 1 ) ;
248247 }
@@ -261,10 +260,10 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
261260 *
262261 * @returns A character slice to the right of the point.
263262 */
264- public rightChar ( ) : ChunkSlice | undefined {
265- const str = this . txt . str ;
263+ public rightChar ( ) : ChunkSlice < T > | undefined {
264+ const rga = this . rga ;
266265 if ( this . isAbsStart ( ) ) {
267- const res = str . findChunk ( 0 ) ;
266+ const res = rga . findChunk ( 0 ) ;
268267 if ( ! res ) return ;
269268 return new ChunkSlice ( res [ 0 ] , res [ 1 ] , 1 ) ;
270269 }
@@ -285,7 +284,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
285284 * @returns Returns `true` if the point is an absolute point.
286285 */
287286 public isAbs ( ) : boolean {
288- return equal ( this . id , this . txt . str . id ) ;
287+ return equal ( this . id , this . rga . id ) ;
289288 }
290289
291290 /**
@@ -311,7 +310,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
311310 */
312311 public isRelStart ( ) : boolean {
313312 if ( this . anchor !== Anchor . Before ) return false ;
314- const id = this . txt . str . find ( 0 ) ;
313+ const id = this . rga . find ( 0 ) ;
315314 return ! ! id && equal ( this . id , id ) ;
316315 }
317316
@@ -322,26 +321,26 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
322321 */
323322 public isRelEnd ( ) : boolean {
324323 if ( this . anchor !== Anchor . After ) return false ;
325- const str = this . txt . str ;
326- const length = str . length ( ) ;
324+ const rga = this . rga ;
325+ const length = rga . length ( ) ;
327326 if ( length === 0 ) return false ;
328- const id = str . find ( length - 1 ) ;
327+ const id = rga . find ( length - 1 ) ;
329328 return ! ! id && equal ( this . id , id ) ;
330329 }
331330
332331 /**
333332 * Sets the point to the absolute start of the string.
334333 */
335334 public refAbsStart ( ) : void {
336- this . id = this . txt . str . id ;
335+ this . id = this . rga . id ;
337336 this . anchor = Anchor . After ;
338337 }
339338
340339 /**
341340 * Sets the point to the absolute end of the string.
342341 */
343342 public refAbsEnd ( ) : void {
344- this . id = this . txt . str . id ;
343+ this . id = this . rga . id ;
345344 this . anchor = Anchor . Before ;
346345 }
347346
@@ -371,7 +370,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
371370 const chunk = this . chunk ( ) ;
372371 if ( ! chunk ) {
373372 if ( this . isAbsStart ( ) ) {
374- const id = this . txt . str . find ( 0 ) ;
373+ const id = this . rga . find ( 0 ) ;
375374 if ( id ) {
376375 this . id = id ;
377376 this . anchor = Anchor . Before ;
@@ -382,7 +381,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
382381 }
383382 if ( ! chunk . del && this . anchor === Anchor . Before ) return ;
384383 this . anchor = Anchor . Before ;
385- this . id = this . nextId ( ) || this . txt . str . id ;
384+ this . id = this . nextId ( ) || this . rga . id ;
386385 }
387386
388387 /**
@@ -395,10 +394,10 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
395394 const chunk = this . chunk ( ) ;
396395 if ( ! chunk ) {
397396 if ( this . isAbsEnd ( ) ) {
398- const str = this . txt . str ;
399- const length = str . length ( ) ;
397+ const rga = this . rga ;
398+ const length = rga . length ( ) ;
400399 if ( length !== 0 ) {
401- const id = str . find ( length - 1 ) ;
400+ const id = rga . find ( length - 1 ) ;
402401 if ( id ) {
403402 this . id = id ;
404403 this . anchor = Anchor . After ;
@@ -410,7 +409,7 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
410409 }
411410 if ( ! chunk . del && this . anchor === Anchor . After ) return ;
412411 this . anchor = Anchor . After ;
413- this . id = this . prevId ( ) || this . txt . str . id ;
412+ this . id = this . prevId ( ) || this . rga . id ;
414413 }
415414
416415 /**
0 commit comments