@@ -46,7 +46,7 @@ export interface Metadata {
46
46
}
47
47
48
48
export abstract class ModuleBase <
49
- C extends ModuleBase < any > ,
49
+ C extends ModuleBase < C , any > ,
50
50
I extends ModuleInstanceBase < ModuleBase < C , I > > = ModuleInstanceBase < ModuleBase < C , any > > ,
51
51
> {
52
52
public instances = new Map < Version , I > ( ) ;
@@ -63,14 +63,32 @@ export abstract class ModuleBase<
63
63
return this . identifier ;
64
64
}
65
65
66
- public abstract newChild ( identifier : ModuleIdentifier , module : _Module ) : Promise < C > ;
66
+ public abstract newDescendant ( identifier : ModuleIdentifier , module : _Module ) : Promise < C > ;
67
67
68
- public getChild ( identifier : ModuleIdentifier ) : C | undefined {
69
- return this . children [ identifier ] ;
68
+ public getDescendant ( identifier : ModuleIdentifier ) : C | null {
69
+ for ( const child of this . getChildren ( ) ) {
70
+ if ( identifier . startsWith ( child . identifier ) ) {
71
+ if ( identifier . length === child . identifier . length ) {
72
+ return child ;
73
+ }
74
+ return child . getDescendant ( identifier ) ;
75
+ }
76
+ }
77
+ return null ;
78
+ }
79
+
80
+ public getLastParentOf ( identifier : ModuleIdentifier ) : C | null {
81
+ for ( const child of this . getChildren ( ) ) {
82
+ if ( identifier . startsWith ( child . identifier ) ) {
83
+ return child . getLastParentOf ( identifier ) ;
84
+ }
85
+ }
86
+ // @ts -ignore :(
87
+ return this ;
70
88
}
71
89
72
- public async getChildOrNew ( identifier : ModuleIdentifier ) : Promise < C > {
73
- return this . getChild ( identifier ) ?? this . newChild ( identifier , { enabled : "" , v : { } } ) ;
90
+ public async getDescendantOrNew ( identifier : ModuleIdentifier ) : Promise < C > {
91
+ return this . getDescendant ( identifier ) ?? this . newDescendant ( identifier , { enabled : "" , v : { } } ) ;
74
92
}
75
93
76
94
private setChild ( identifier : ModuleIdentifier , child : C ) {
@@ -85,16 +103,14 @@ export abstract class ModuleBase<
85
103
return Object . values ( this . children ) ;
86
104
}
87
105
88
- public getDescendants ( identifier : ModuleIdentifier ) : Array < ModuleBase < any , ModuleInstanceBase < any > > > {
89
- if ( identifier === this . identifier ) {
90
- return [ this ] ;
106
+ public * getDescendantsByDepth ( ) : Generator < ModuleBase < any , ModuleInstanceBase < any > > > {
107
+ for ( const child of this . getChildren ( ) ) {
108
+ yield child ;
109
+ yield * child . getDescendantsByDepth ( ) ;
91
110
}
92
- return this . getChildren ( ) . filter ( ( child ) => child . identifier . startsWith ( identifier ) ) . flatMap ( ( child ) =>
93
- child . getDescendants ( identifier )
94
- ) ;
95
111
}
96
112
97
- public * getAllDescendantsByBreadth ( ) : Generator < ModuleBase < ModuleBase < any > > > {
113
+ public * getDescendantsByBreadth ( ) : Generator < ModuleBase < ModuleBase < any > > > {
98
114
const i : Array < ModuleBase < ModuleBase < any > > > = [ this ] ;
99
115
100
116
while ( i . length ) {
@@ -138,8 +154,8 @@ export class RootModule extends ModuleBase<Module, never> {
138
154
Object . freeze ( this . instances ) ;
139
155
}
140
156
141
- override newChild ( identifier : ModuleIdentifier , module : _Module , local = false ) {
142
- return Module . prototype . newChild . call ( this , identifier , module , local ) ;
157
+ override newDescendant ( identifier : ModuleIdentifier , module : _Module , local = false ) {
158
+ return Module . prototype . newDescendant . call ( this , identifier , module , local ) ;
143
159
}
144
160
}
145
161
@@ -153,11 +169,20 @@ export class Module extends ModuleBase<Module, ModuleInstance> {
153
169
super ( parent , children , identifier ) ;
154
170
}
155
171
156
- override newChild ( identifier : ModuleIdentifier , module : _Module , local = false ) {
157
- if ( this . getChild ( identifier ) ) {
172
+ override newDescendant ( identifier : ModuleIdentifier , module : _Module , local = false ) {
173
+ if ( this . getDescendant ( identifier ) ) {
158
174
throw new Error ( `Module ${ identifier } already exists` ) ;
159
175
}
160
- return new Module ( this , { } , identifier , local ? module . enabled : "" ) . init ( module . v , local ) ;
176
+
177
+ const parent = this . getLastParentOf ( identifier ) as Module ;
178
+ const descendant = new Module ( parent , { } , identifier , local ? module . enabled : "" ) ;
179
+ for ( const child of parent . getChildren ( ) ) {
180
+ if ( child . getIdentifier ( ) . startsWith ( identifier ) && child != descendant ) {
181
+ child . parent = descendant ;
182
+ }
183
+ }
184
+
185
+ return descendant . init ( module . v , local ) ; ;
161
186
}
162
187
163
188
override async newInstance (
@@ -230,7 +255,7 @@ export interface MixinLoader {
230
255
awaitedMixins : Promise < void > [ ] ;
231
256
}
232
257
233
- export abstract class ModuleInstanceBase < M extends ModuleBase < any > = ModuleBase < any > > {
258
+ export abstract class ModuleInstanceBase < M extends ModuleBase < M > = ModuleBase < any > > {
234
259
public getName ( ) {
235
260
return this . metadata ?. name ;
236
261
}
@@ -288,7 +313,10 @@ export class ModuleInstance extends ModuleInstanceBase<Module> implements MixinL
288
313
Object . keys ( provider )
289
314
// TODO: revisit this check
290
315
. filter ( ( i ) => i . startsWith ( this . getModuleIdentifier ( ) ) )
291
- . forEach ( async ( identifier ) => this . module . newChild ( identifier , provider [ identifier ] ) ) ;
316
+ . forEach ( async ( identifier ) => {
317
+ const module = await this . module . getDescendantOrNew ( identifier ) ;
318
+ await module . init ( provider [ identifier ] . v , false ) ;
319
+ } ) ;
292
320
}
293
321
294
322
private _transformer = createTransformer ( this ) ;
@@ -473,7 +501,7 @@ export class ModuleInstance extends ModuleInstanceBase<Module> implements MixinL
473
501
if ( dependency === "spotify" ) {
474
502
return satisfies ( SPOTIFY_VERSION , range ) ;
475
503
}
476
- const module = RootModule . INSTANCE . getChild ( dependency ) ?. getEnabledInstance ( ) ;
504
+ const module = RootModule . INSTANCE . getDescendant ( dependency ) ?. getEnabledInstance ( ) ;
477
505
if ( ! module ?. canLoadRecur ( isPreload , range ) ) {
478
506
return false ;
479
507
}
@@ -502,7 +530,7 @@ export class ModuleInstance extends ModuleInstanceBase<Module> implements MixinL
502
530
503
531
await Promise . all (
504
532
Object . keys ( this . metadata ! . dependencies ) . map ( ( dependency ) => {
505
- const module = RootModule . INSTANCE . getChild ( dependency ) ! . getEnabledInstance ( ) ! ;
533
+ const module = RootModule . INSTANCE . getDescendant ( dependency ) ! . getEnabledInstance ( ) ! ;
506
534
return module . loadMixinsRecur ( ) ;
507
535
} ) ,
508
536
) ;
@@ -521,7 +549,7 @@ export class ModuleInstance extends ModuleInstanceBase<Module> implements MixinL
521
549
522
550
await Promise . all (
523
551
Object . keys ( this . metadata ! . dependencies ) . map ( ( dependency ) => {
524
- const module = RootModule . INSTANCE . getChild ( dependency ) ! . getEnabledInstance ( ) ! ;
552
+ const module = RootModule . INSTANCE . getDescendant ( dependency ) ! . getEnabledInstance ( ) ! ;
525
553
module . dependants . add ( this ) ;
526
554
return module . loadRecur ( ) ;
527
555
} ) ,
@@ -542,7 +570,7 @@ export class ModuleInstance extends ModuleInstanceBase<Module> implements MixinL
542
570
const resolve = this . transition . extend ( ) ;
543
571
544
572
for ( const dependency of Object . keys ( this . metadata ! . dependencies ) ) {
545
- const module = RootModule . INSTANCE . getChild ( dependency ) ! . getEnabledInstance ( ) ! ;
573
+ const module = RootModule . INSTANCE . getDescendant ( dependency ) ! . getEnabledInstance ( ) ! ;
546
574
module . dependants . delete ( this ) ;
547
575
}
548
576
await Promise . all ( Array . from ( this . dependants ) . map ( ( dependant ) => dependant . unloadRecur ( ) ) ) ;
@@ -586,21 +614,10 @@ export class ModuleInstance extends ModuleInstanceBase<Module> implements MixinL
586
614
return null ;
587
615
}
588
616
589
- const module = await RootModule . INSTANCE . getChildOrNew ( this . getModuleIdentifier ( ) ) ;
590
- const instance = new ModuleInstance (
591
- module ,
592
- this . getVersion ( ) ,
593
- this . metadata ,
594
- this . artifacts ,
595
- this . checksum ,
596
- true ,
597
- false ,
598
- ) ;
599
- module . instances . set ( instance . getVersion ( ) , instance ) ;
600
617
this . added = true ;
601
618
resolve ( ) ;
602
619
603
- return instance ;
620
+ return this ;
604
621
}
605
622
606
623
public canInstallRemove ( ) {
@@ -741,7 +758,7 @@ export async function loadLocalModules() {
741
758
742
759
return Promise . all (
743
760
Object . keys ( localModules ) . map ( ( identifier ) =>
744
- RootModule . INSTANCE . newChild ( identifier , localModules [ identifier ] , true )
761
+ RootModule . INSTANCE . newDescendant ( identifier , localModules [ identifier ] , true )
745
762
) ,
746
763
) ;
747
764
}
@@ -754,16 +771,18 @@ export async function loadRemoteModules() {
754
771
755
772
await Promise . all (
756
773
Object . keys ( remoteModules ) . map ( async ( identifier ) => {
757
- const module = await RootModule . INSTANCE . getChildOrNew ( identifier ) ;
774
+ const module = await RootModule . INSTANCE . getDescendantOrNew ( identifier ) ;
758
775
await module . init ( remoteModules [ identifier ] . v , false ) ;
759
776
} ) ,
760
777
) ;
761
778
}
762
779
763
780
const getLoadableChildrenInstances = ( ) =>
764
- RootModule . INSTANCE . getChildren ( ) . map ( ( module ) => module . getEnabledInstance ( ) ) . filter (
765
- ( instance ) => instance ?. canLoad ( ) ,
766
- ) as ModuleInstance [ ] ;
781
+ Array . from ( RootModule . INSTANCE . getDescendantsByBreadth ( ) )
782
+ . map ( ( module ) => ( module as Module ) . getEnabledInstance ( ) )
783
+ . filter (
784
+ ( instance ) => instance ?. canLoad ( ) ,
785
+ ) as ModuleInstance [ ] ;
767
786
768
787
export const enableAllLoadableMixins = ( ) =>
769
788
Promise . all ( getLoadableChildrenInstances ( ) . map ( ( instance ) => instance . _loadMixins ( ) ) ) ;
0 commit comments