11import { inspect , InspectOptions } from 'util'
2- import { SubstituteNodeBase } from './SubstituteNodeBase'
2+
3+ import { FilterFunction } from './Types'
34import { RecordsSet } from './RecordsSet'
45
5- export class Recorder {
6- private _records : RecordsSet < SubstituteNodeBase >
7- private _indexedRecords : Map < PropertyKey , RecordsSet < SubstituteNodeBase > >
6+ export class Recorder < TRecord > {
7+ private _identity : PropertyKey
8+ private _records : RecordsSet < TRecord >
9+ private _indexedRecords : Map < PropertyKey , RecordsSet < TRecord > >
810
9- constructor ( ) {
11+ private constructor ( identity : PropertyKey ) {
12+ this . _identity = identity
1013 this . _records = new RecordsSet ( )
1114 this . _indexedRecords = new Map ( )
1215 }
1316
14- public get records ( ) : RecordsSet < SubstituteNodeBase > {
17+ public static withIdentityProperty < TRecord > ( identity : keyof TRecord ) : Recorder < TRecord > {
18+ return new this ( identity )
19+ }
20+
21+ public get records ( ) : RecordsSet < TRecord > {
1522 return this . _records
1623 }
1724
18- public get indexedRecords ( ) : Map < PropertyKey , RecordsSet < SubstituteNodeBase > > {
25+ public get indexedRecords ( ) : Map < PropertyKey , RecordsSet < TRecord > > {
1926 return this . _indexedRecords
2027 }
2128
22- public addIndexedRecord ( node : SubstituteNodeBase ) : void {
23- this . addRecord ( node )
24- const existingNodes = this . indexedRecords . get ( node . key )
25- if ( typeof existingNodes === 'undefined' ) this . indexedRecords . set ( node . key , new RecordsSet ( [ node ] ) )
26- else existingNodes . add ( node )
29+ public addIndexedRecord ( record : TRecord ) : void {
30+ const id = this . getIdentity ( record )
31+ this . addRecord ( record )
32+ const existingNodes = this . indexedRecords . get ( id )
33+ if ( typeof existingNodes === 'undefined' ) this . indexedRecords . set ( id , new RecordsSet ( [ record ] ) )
34+ else existingNodes . add ( record )
2735 }
2836
29- public addRecord ( node : SubstituteNodeBase ) : void {
30- this . _records . add ( node )
37+ public addRecord ( record : TRecord ) : void {
38+ this . _records . add ( record )
3139 }
3240
33- public getSiblingsOf ( node : SubstituteNodeBase ) : RecordsSet < SubstituteNodeBase > {
34- const siblingNodes = this . indexedRecords . get ( node . key ) ?? new RecordsSet ( )
35- return siblingNodes . filter ( siblingNode => siblingNode !== node )
41+ public getSiblingsOf ( record : TRecord ) : RecordsSet < TRecord > {
42+ const siblings = this . indexedRecords . get ( this . getIdentity ( record ) ) ?? new RecordsSet ( )
43+ return siblings . filter ( sibling => sibling !== record )
3644 }
3745
38- public clearRecords ( filterFunction : ( node : SubstituteNodeBase ) => boolean ) {
46+ public clearRecords ( filterFunction : FilterFunction < TRecord > ) {
3947 const recordsToRemove = this . records . filter ( filterFunction )
4048 for ( const record of recordsToRemove ) {
41- const indexedRecord = this . indexedRecords . get ( record . key )
49+ const id = this . getIdentity ( record )
50+ const indexedRecord = this . indexedRecords . get ( id )
4251 indexedRecord . delete ( record )
43- if ( indexedRecord . size === 0 ) this . indexedRecords . delete ( record . key )
52+ if ( indexedRecord . size === 0 ) this . indexedRecords . delete ( id )
4453 this . records . delete ( record )
4554 }
4655 }
@@ -51,4 +60,8 @@ export class Recorder {
5160 ( [ key , value ] ) => `\n ${ key . toString ( ) } : {\n${ [ ...value . map ( v => ` ${ inspect ( v , options ) } ` ) ] . join ( ',\n' ) } \n }`
5261 ) . join ( )
5362 }
54- }
63+
64+ private getIdentity ( record : TRecord ) : PropertyKey {
65+ return record [ this . _identity as keyof TRecord ] as PropertyKey
66+ }
67+ }
0 commit comments