@@ -11,13 +11,14 @@ import {compare, ITimestampStruct} from '../../../json-crdt-patch/clock';
1111import { CONST , updateNum } from '../../../json-hash' ;
1212import { MarkerSlice } from '../slice/MarkerSlice' ;
1313import { Range } from '../rga/Range' ;
14- import { UndefEndIter } from '../../../util/iterator' ;
14+ import { UndefEndIter , UndefIterator } from '../../../util/iterator' ;
1515import type { Chunk } from '../../../json-crdt/nodes/rga' ;
1616import type { Peritext } from '../Peritext' ;
1717import type { Stateful } from '../types' ;
1818import type { Printable } from 'tree-dump/lib/types' ;
1919import type { MutableSlice , Slice } from '../slice/types' ;
2020import type { Slices } from '../slice/Slices' ;
21+ import type { OverlayPair , OverlayTuple } from './types' ;
2122
2223/**
2324 * Overlay is a tree structure that represents all the intersections of slices
@@ -29,7 +30,17 @@ import type {Slices} from '../slice/Slices';
2930export class Overlay < T = string > implements Printable , Stateful {
3031 public root : OverlayPoint < T > | undefined = undefined ;
3132
32- constructor ( protected readonly txt : Peritext < T > ) { }
33+ /** A virtual absolute start point, used when the absolute start is missing. */
34+ private readonly START : OverlayPoint < T > ;
35+
36+ /** A virtual absolute end point, used when the absolute end is missing. */
37+ private readonly END : OverlayPoint < T > ;
38+
39+ constructor ( protected readonly txt : Peritext < T > ) {
40+ const id = txt . str . id ;
41+ this . START = this . point ( id , Anchor . After )
42+ this . END = this . point ( id , Anchor . Before ) ;
43+ }
3344
3445 private point ( id : ITimestampStruct , anchor : Anchor ) : OverlayPoint < T > {
3546 return new OverlayPoint ( this . txt . str , id , anchor ) ;
@@ -47,34 +58,6 @@ export class Overlay<T = string> implements Printable, Stateful {
4758 return this . root ? last ( this . root ) : undefined ;
4859 }
4960
50- public iterator ( ) : ( ) => OverlayPoint < T > | undefined {
51- return this . points ( undefined ) ;
52- }
53-
54- public entries ( ) : IterableIterator < OverlayPoint < T > > {
55- return new UndefEndIter ( this . iterator ( ) ) ;
56- }
57-
58- // [Symbol.iterator]() {
59- // return this.entries();
60- // }
61-
62- public markerIterator ( ) : ( ) => MarkerOverlayPoint | undefined {
63- let curr = this . first ( ) ;
64- return ( ) => {
65- while ( curr ) {
66- const ret = curr ;
67- if ( curr ) curr = next ( curr ) ;
68- if ( ret instanceof MarkerOverlayPoint ) return ret ;
69- }
70- return ;
71- } ;
72- }
73-
74- public markers ( ) : IterableIterator < OverlayPoint < T > > {
75- return new UndefEndIter ( this . iterator ( ) ) ;
76- }
77-
7861 /**
7962 * Retrieve overlay point or the previous one, measured in spacial dimension.
8063 */
@@ -183,7 +166,7 @@ export class Overlay<T = string> implements Printable, Stateful {
183166 } ) as Chunk < T > ;
184167 }
185168
186- public points ( after : undefined | OverlayPoint < T > ) : ( ) => OverlayPoint < T > | undefined {
169+ public points0 ( after : undefined | OverlayPoint < T > ) : UndefIterator < OverlayPoint < T > > {
187170 let curr = after ? next ( after ) : this . first ( ) ;
188171 return ( ) => {
189172 const ret = curr ;
@@ -192,82 +175,55 @@ export class Overlay<T = string> implements Printable, Stateful {
192175 } ;
193176 }
194177
195- /**
196- * @todo Unify this with `.entries()`.
197- * @deprecated
198- */
199- public points0 (
200- start : undefined | OverlayPoint < T > ,
201- end : undefined | ( ( next : OverlayPoint < T > ) => boolean ) ,
202- callback : ( point : OverlayPoint < T > ) => void ,
203- ) : void {
204- const i = this . points ( start ) ;
205- let point = i ( ) ;
206- while ( point ) {
207- if ( end && end ( point ) ) return ;
208- callback ( point ) ;
209- point = i ( ) ;
210- }
178+ public points ( after ?: undefined | OverlayPoint < T > ) : IterableIterator < OverlayPoint < T > > {
179+ return new UndefEndIter ( this . points0 ( after ) ) ;
211180 }
212181
213- /** @deprecated */
214- public points1 (
215- start : undefined | OverlayPoint < T > ,
216- end : undefined | ( ( next : OverlayPoint < T > ) => boolean ) ,
217- callback : ( p1 : OverlayPoint < T > , p2 : OverlayPoint < T > ) => void ,
218- ) : void {
219- let p1 : OverlayPoint < T > | undefined ;
220- let p2 : OverlayPoint < T > | undefined ;
221- this . points0 ( start , end , ( point ) => {
222- if ( p1 ) {
223- p2 = point ;
224- callback ( p1 , p2 ) ;
225- p1 = p2 ;
226- } else {
227- p1 = point ;
182+ public markers0 ( ) : UndefIterator < MarkerOverlayPoint < T > > {
183+ let curr = this . first ( ) ;
184+ return ( ) => {
185+ while ( curr ) {
186+ const ret = curr ;
187+ if ( curr ) curr = next ( curr ) ;
188+ if ( ret instanceof MarkerOverlayPoint ) return ret ;
228189 }
229- } ) ;
190+ return ;
191+ } ;
192+ }
193+
194+ public markers ( ) : IterableIterator < MarkerOverlayPoint < T > > {
195+ return new UndefEndIter ( this . markers0 ( ) ) ;
230196 }
231197
232- public pairs0 ( after : undefined | OverlayPoint < T > ) : ( ) => undefined | [ p1 : OverlayPoint < T > | undefined , p2 : OverlayPoint < T > | undefined ] {
198+ public pairs0 ( after : undefined | OverlayPoint < T > ) : UndefIterator < OverlayPair < T > > {
233199 let p1 : OverlayPoint < T > | undefined ;
234200 let p2 : OverlayPoint < T > | undefined ;
235- const iterator = this . points ( after ) ;
201+ const iterator = this . points0 ( after ) ;
236202 return ( ) => {
237203 p1 = p2 ;
238204 p2 = iterator ( ) ;
239205 return ( p1 || p2 ) ? [ p1 , p2 ] : undefined ;
240206 } ;
241207 }
242208
243- public pairs ( after ?: undefined | OverlayPoint < T > ) : IterableIterator < [ p1 : OverlayPoint < T > | undefined , p2 : OverlayPoint < T > | undefined ] > {
209+ public pairs ( after ?: undefined | OverlayPoint < T > ) : IterableIterator < OverlayPair < T > > {
244210 return new UndefEndIter ( this . pairs0 ( after ) ) ;
245211 }
246212
247- public tuples0 ( after : undefined | OverlayPoint < T > ) : ( ) => undefined | [ p1 : OverlayPoint < T > , p2 : OverlayPoint < T > ] {
213+ public tuples0 ( after : undefined | OverlayPoint < T > ) : UndefIterator < OverlayTuple < T > > {
248214 const iterator = this . pairs0 ( after ) ;
249215 return ( ) => {
250216 const pair = iterator ( ) ;
251217 if ( ! pair ) return ;
252- if ( pair [ 0 ] ) pair [ 0 ] = this . point ( this . txt . str . id , Anchor . After ) ;
253- if ( pair [ 1 ] ) pair [ 1 ] = this . point ( this . txt . str . id , Anchor . Before ) ;
218+ if ( pair [ 0 ] === undefined ) pair [ 0 ] = this . START ;
219+ if ( pair [ 1 ] === undefined ) pair [ 1 ] = this . END ;
220+ return pair as OverlayTuple < T > ;
254221 } ;
255222 }
256223
257- // public tuples2(after: undefined | OverlayPoint<T>): () => undefined | [p1: OverlayPoint<T>, p2: OverlayPoint<T>] {
258- // let p1: OverlayPoint<T> | undefined;
259- // let p2: OverlayPoint<T> | undefined;
260- // const iterator = this.points(after);
261- // return () => {
262- // const isFirst = !p1;
263- // if (isFirst) {
264- // p1 = iterator();
265- // }
266- // // p1 = p2;
267- // // p2 = iterator();
268- // // return p2 ? [p1, p2] : undefined;
269- // };
270- // }
224+ public tuples ( after ?: undefined | OverlayPoint < T > ) : IterableIterator < OverlayTuple < T > > {
225+ return new UndefEndIter ( this . tuples0 ( after ) ) ;
226+ }
271227
272228 public findContained ( range : Range < T > ) : Set < Slice < T > > {
273229 const result = new Set < Slice < T > > ( ) ;
@@ -461,7 +417,9 @@ export class Overlay<T = string> implements Printable, Stateful {
461417 let chunk : Chunk < T > | undefined = firstChunk ;
462418 let marker : MarkerOverlayPoint < T > | undefined = undefined ;
463419 let state : number = CONST . START_STATE ;
464- this . points1 ( undefined , undefined , ( p1 , p2 ) => {
420+ const i = this . tuples0 ( undefined ) ;
421+ for ( let pair = i ( ) ; pair ; pair = i ( ) ) {
422+ const [ p1 , p2 ] = pair ;
465423 // TODO: need to incorporate slice attribute hash here?
466424 const id1 = p1 . id ;
467425 state = ( state << 5 ) + state + ( id1 . sid >>> 0 ) + id1 . time ;
@@ -484,7 +442,7 @@ export class Overlay<T = string> implements Printable, Stateful {
484442 state = CONST . START_STATE ;
485443 marker = p2 ;
486444 }
487- } ) ;
445+ }
488446 if ( ( marker as any ) instanceof MarkerOverlayPoint ) {
489447 ( marker as any as MarkerOverlayPoint < T > ) . textHash = state ;
490448 } else {
0 commit comments