@@ -56,6 +56,10 @@ export namespace Loader {
56
56
}
57
57
58
58
export abstract class Loader < T extends Loader . Options = Loader . Options > extends Service < Entry . Options [ ] > {
59
+ static inject = {
60
+ optional : [ 'loader' ] ,
61
+ }
62
+
59
63
// process
60
64
public baseDir = process . cwd ( )
61
65
public envData = process . env . CORDIS_SHARED
@@ -66,7 +70,7 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
66
70
env : process . env ,
67
71
}
68
72
69
- public root : Entry
73
+ public root : EntryGroup
70
74
public suspend = false
71
75
public writable = false
72
76
public mimeType ! : string
@@ -83,8 +87,7 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
83
87
84
88
constructor ( public app : Context , public options : T ) {
85
89
super ( app , 'loader' , true )
86
- this . root = new Entry ( this )
87
- this . entries [ '' ] = this . root
90
+ this . root = new EntryGroup ( this . app )
88
91
this . realms [ '#' ] = app . root [ Context . isolate ]
89
92
90
93
this . app . on ( 'dispose' , ( ) => {
@@ -105,6 +108,10 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
105
108
} )
106
109
107
110
this . app . on ( 'internal/fork' , ( fork ) => {
111
+ if ( fork . parent [ Entry . key ] ) {
112
+ fork . entry = fork . parent [ Entry . key ]
113
+ delete fork . parent [ Entry . key ]
114
+ }
108
115
// fork.uid: fork is created (we only care about fork dispose event)
109
116
// fork.parent.runtime.plugin !== group: fork is not tracked by loader
110
117
if ( fork . uid || ! fork . entry ) return
@@ -242,7 +249,7 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
242
249
return ! ! this . interpolate ( `\${{ ${ expr } }}` )
243
250
}
244
251
245
- private ensureId ( options : Partial < Entry . Options > ) {
252
+ ensureId ( options : Partial < Entry . Options > ) {
246
253
if ( ! options . id ) {
247
254
do {
248
255
options . id = Math . random ( ) . toString ( 36 ) . slice ( 2 , 8 )
@@ -251,13 +258,6 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
251
258
return options . id !
252
259
}
253
260
254
- async _ensure ( parent : Context , options : Omit < Entry . Options , 'id' > ) {
255
- const id = this . ensureId ( options )
256
- const entry = this . entries [ id ] ??= new Entry ( this )
257
- await entry . update ( parent , options as Entry . Options )
258
- return id
259
- }
260
-
261
261
async update ( id : string , options : Partial < Omit < Entry . Options , 'id' | 'name' > > ) {
262
262
const entry = this . entries [ id ]
263
263
if ( ! entry ) throw new Error ( `entry ${ id } not found` )
@@ -270,23 +270,20 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
270
270
}
271
271
}
272
272
this . writeConfig ( )
273
- return entry . update ( entry . parent , override )
273
+ return entry . update ( override )
274
274
}
275
275
276
- async create ( options : Omit < Entry . Options , 'id' > , target = '' , index = Infinity ) {
277
- const targetEntry = this . entries [ target ]
278
- if ( ! targetEntry ?. fork ) throw new Error ( `entry ${ target } not found` )
279
- targetEntry . options . config . splice ( index , 0 , options )
280
- this . writeConfig ( )
281
- return this . _ensure ( targetEntry . fork . ctx , options )
276
+ resolveGroup ( id : string | null ) {
277
+ const group = id ? this . entries [ id ] ?. children : this . root
278
+ if ( ! group ) throw new Error ( `entry ${ id } not found` )
279
+ return group
282
280
}
283
281
284
- _remove ( id : string ) {
285
- const entry = this . entries [ id ]
286
- if ( ! entry ) return
287
- entry . stop ( )
288
- entry . unlink ( )
289
- delete this . entries [ id ]
282
+ async create ( options : Omit < Entry . Options , 'id' > , parent : string | null = null , position = Infinity ) {
283
+ const group = this . resolveGroup ( parent )
284
+ group . config . splice ( position , 0 , options as Entry . Options )
285
+ this . writeConfig ( )
286
+ return group . _create ( options )
290
287
}
291
288
292
289
remove ( id : string ) {
@@ -298,17 +295,16 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
298
295
this . writeConfig ( )
299
296
}
300
297
301
- transfer ( id : string , target : string , index = Infinity ) {
298
+ transfer ( id : string , parent : string | null , position = Infinity ) {
302
299
const entry = this . entries [ id ]
303
300
if ( ! entry ) throw new Error ( `entry ${ id } not found` )
304
- const sourceEntry = entry . parent . scope . entry !
305
- const targetEntry = this . entries [ target ]
306
- if ( ! targetEntry ?. fork ) throw new Error ( `entry ${ target } not found` )
301
+ const source = entry . parent
302
+ const target = this . resolveGroup ( parent )
307
303
entry . unlink ( )
308
- targetEntry . options . config . splice ( index , 0 , entry . options )
304
+ target . config . splice ( position , 0 , entry . options )
309
305
this . writeConfig ( )
310
- if ( sourceEntry === targetEntry ) return
311
- entry . parent = targetEntry . fork . ctx
306
+ if ( source === target ) return
307
+ entry . parent = target
312
308
if ( ! entry . fork ) return
313
309
const ctx = entry . createContext ( )
314
310
entry . patch ( entry . fork . parent , ctx )
@@ -331,19 +327,9 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
331
327
return this . _locate ( scope . parent . scope )
332
328
}
333
329
334
- createGroup ( ) {
335
- const ctx = this [ Context . current ]
336
- // if (!ctx.scope.entry) throw new Error(`expected entry scope`)
337
- return new EntryGroup ( this , ctx )
338
- }
339
-
340
330
async start ( ) {
341
331
await this . readConfig ( )
342
- this . root . update ( this . app , {
343
- id : '' ,
344
- name : 'cordis/group' ,
345
- config : this . config ,
346
- } )
332
+ this . root . update ( this . config )
347
333
348
334
while ( this . tasks . size ) {
349
335
await Promise . all ( this . tasks )
@@ -387,13 +373,19 @@ export interface GroupOptions {
387
373
export function createGroup ( config ?: Entry . Options [ ] , options : GroupOptions = { } ) {
388
374
options . initial = config
389
375
390
- function group ( ctx : Context , config : Entry . Options [ ] ) {
391
- const group = ctx . get ( 'loader' ) ! . createGroup ( )
376
+ function group ( ctx : Context ) {
377
+ if ( ! ctx . scope . entry ) throw new Error ( `expected entry scope` )
378
+ const group = new EntryGroup ( ctx )
379
+ ctx . scope . entry . children = group
380
+ ctx . on ( 'dispose' , ( ) => {
381
+ group . dispose ( )
382
+ } )
392
383
ctx . accept ( ( config : Entry . Options [ ] ) => {
393
384
group . update ( config )
394
385
} , { passive : true , immediate : true } )
395
386
}
396
387
388
+ defineProperty ( group , 'inject' , [ 'loader' ] )
397
389
defineProperty ( group , 'reusable' , true )
398
390
defineProperty ( group , kGroup , options )
399
391
if ( options . name ) defineProperty ( group , 'name' , options . name )
0 commit comments