Skip to content

Commit 92df648

Browse files
committed
feat(loader): extract entry group
1 parent d783997 commit 92df648

File tree

4 files changed

+51
-32
lines changed

4 files changed

+51
-32
lines changed

packages/loader/.npmignore

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/loader/src/entry.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export class Entry {
4646
public isUpdate = false
4747
public parent!: Context
4848
public options!: Entry.Options
49+
public group: Entry.Options[] | null = null
4950

5051
constructor(public loader: Loader) {}
5152

packages/loader/src/group.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Context } from '@cordisjs/core'
2+
import { Entry } from './entry.ts'
3+
import Loader from './shared.ts'
4+
5+
export class EntryGroup {
6+
public config: Entry.Options[] = []
7+
8+
constructor(public loader: Loader, public ctx: Context) {
9+
ctx.on('dispose', () => {
10+
for (const options of this.config) {
11+
this.loader._remove(options.id)
12+
}
13+
})
14+
}
15+
16+
update(config: Entry.Options[]) {
17+
const oldConfig = this.config as Entry.Options[]
18+
this.config = config
19+
const oldMap = Object.fromEntries(oldConfig.map(options => [options.id, options]))
20+
const newMap = Object.fromEntries(config.map(options => [options.id ?? Symbol('anonymous'), options]))
21+
22+
// update inner plugins
23+
for (const id of Reflect.ownKeys({ ...oldMap, ...newMap }) as string[]) {
24+
if (!newMap[id]) {
25+
this.loader._remove(id)
26+
} else {
27+
this.loader._ensure(this.ctx, newMap[id])
28+
}
29+
}
30+
}
31+
}

packages/loader/src/shared.ts

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { interpolate } from './utils.ts'
77
import { Entry } from './entry.ts'
88
import * as yaml from 'js-yaml'
99
import * as path from 'path'
10+
import { EntryGroup } from './group.ts'
1011

1112
declare module '@cordisjs/core' {
1213
interface Events {
@@ -313,17 +314,27 @@ export abstract class Loader<T extends Loader.Options = Loader.Options> extends
313314
entry.patch(entry.fork.parent, ctx)
314315
}
315316

316-
paths(scope: EffectScope): string[] {
317+
locate(ctx = this[Context.current]) {
318+
return this._locate(ctx.scope).map(entry => entry.options.id)
319+
}
320+
321+
_locate(scope: EffectScope): Entry[] {
317322
// root scope
318323
if (scope === scope.parent.scope) return []
319324

320325
// runtime scope
321326
if (scope.runtime === scope) {
322-
return ([] as string[]).concat(...scope.runtime.children.map(child => this.paths(child)))
327+
return ([] as Entry[]).concat(...scope.runtime.children.map(child => this._locate(child)))
323328
}
324329

325-
if (scope.entry) return [scope.entry.options.id]
326-
return this.paths(scope.parent.scope)
330+
if (scope.entry) return [scope.entry]
331+
return this._locate(scope.parent.scope)
332+
}
333+
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)
327338
}
328339

329340
async start() {
@@ -377,32 +388,10 @@ export function createGroup(config?: Entry.Options[], options: GroupOptions = {}
377388
options.initial = config
378389

379390
function group(ctx: Context, config: Entry.Options[]) {
380-
const loader = ctx.get('loader')!
381-
for (const options of config) {
382-
loader._ensure(ctx, options)
383-
}
384-
385-
ctx.accept((neo: Entry.Options[]) => {
386-
// update config reference
387-
const old = ctx.scope.config as Entry.Options[]
388-
const oldMap: any = Object.fromEntries(old.map(entry => [entry.id, entry]))
389-
const neoMap: any = Object.fromEntries(neo.map(entry => [entry.id, entry]))
390-
391-
// update inner plugins
392-
for (const id in { ...oldMap, ...neoMap }) {
393-
if (!neoMap[id]) {
394-
loader._remove(id)
395-
} else {
396-
loader._ensure(ctx, neoMap[id])
397-
}
398-
}
399-
}, { passive: true })
400-
401-
ctx.on('dispose', () => {
402-
for (const entry of ctx.scope.config as Entry.Options[]) {
403-
loader._remove(entry.id)
404-
}
405-
})
391+
const group = ctx.get('loader')!.createGroup()
392+
ctx.accept((config: Entry.Options[]) => {
393+
group.update(config)
394+
}, { passive: true, immediate: true })
406395
}
407396

408397
defineProperty(group, 'reusable', true)

0 commit comments

Comments
 (0)