Skip to content

Commit

Permalink
feat(loader): support entry.id with separator
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 30, 2024
1 parent 6688d23 commit 16b1a89
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 13 deletions.
14 changes: 11 additions & 3 deletions packages/loader/src/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function sortKeys<T extends {}>(object: T, prepend = ['id', 'name'], append = ['
}

export class Entry {
static key = Symbol.for('cordis.entry')
static readonly key = Symbol.for('cordis.entry')

public fork?: ForkScope
public suspend = false
Expand All @@ -54,9 +54,17 @@ export class Entry {

constructor(public loader: Loader, public parent: EntryGroup) {}

get id() {
let id = this.options.id
if (this.parent.tree.ctx.scope.entry) {
id = this.parent.tree.ctx.scope.entry.id + EntryTree.sep + id
}
return id
}

resolveRealm(label: string | true) {
if (label === true) {
return '#' + this.options.id
return '#' + this.id
} else {
return '@' + label
}
Expand Down Expand Up @@ -87,7 +95,7 @@ export class Entry {
for (const key in { ...oldMap, ...newMap, ...this.loader.delims }) {
if (newMap[key] === oldMap[key]) continue
const delim = this.loader.delims[key] ??= Symbol(`delim:${key}`)
ctx[delim] = Symbol(`${key}#${this.options.id}`)
ctx[delim] = Symbol(`${key}#${this.id}`)
for (const symbol of [oldMap[key], newMap[key]]) {
const value = symbol && ctx[symbol]
if (!(value instanceof Object)) continue
Expand Down
2 changes: 1 addition & 1 deletion packages/loader/src/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class EntryGroup {
// so we need to update the parent reference.
entry.parent = this
await entry.update(options, true)
return id
return entry.id
}

unlink(options: Entry.Options) {
Expand Down
2 changes: 1 addition & 1 deletion packages/loader/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export abstract class Loader extends ImportTree {
}

locate(ctx = this[Context.current]) {
return this._locate(ctx.scope).map(entry => entry.options.id)
return this._locate(ctx.scope).map(entry => entry.id)
}

_locate(scope: EffectScope): Entry[] {
Expand Down
30 changes: 22 additions & 8 deletions packages/loader/src/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Entry } from './entry.ts'
import { EntryGroup } from './group.ts'

export abstract class EntryTree {
static readonly sep = ':'

public url!: string
public root: EntryGroup
public store: Dict<Entry> = Object.create(null)
Expand Down Expand Up @@ -31,10 +33,24 @@ export abstract class EntryTree {
return options.id!
}

resolve(id: string) {
const parts = id.split(EntryTree.sep)
let tree: EntryTree | undefined = this
const final = parts.pop()!
for (const part of parts) {
tree = tree.store[part]?.subtree
if (!tree) throw new Error(`cannot resolve entry ${id}`)
}
const entry = tree.store[final]
if (!entry) throw new Error(`cannot resolve entry ${id}`)
return entry
}

resolveGroup(id: string | null) {
const group = id ? this.store[id]?.subgroup : this.root
if (!group) throw new Error(`entry ${id} not found`)
return group
if (!id) return this.root
const entry = this.resolve(id)
if (!entry.subgroup) throw new Error(`entry ${id} is not a group`)
return entry.subgroup
}

async create(options: Omit<Entry.Options, 'id'>, parent: string | null = null, position = Infinity) {
Expand All @@ -45,24 +61,22 @@ export abstract class EntryTree {
}

remove(id: string) {
const entry = this.store[id]
if (!entry) throw new Error(`entry ${id} not found`)
const entry = this.resolve(id)
entry.parent.remove(id)
entry.parent.tree.write()
}

async update(id: string, options: Omit<Entry.Options, 'id' | 'name'>, parent?: string | null, position?: number) {
const entry = this.store[id]
if (!entry) throw new Error(`entry ${id} not found`)
const entry = this.resolve(id)
const source = entry.parent
source.tree.write()
if (parent !== undefined) {
const target = this.resolveGroup(parent)
source.unlink(entry.options)
target.data.splice(position ?? Infinity, 0, entry.options)
target.tree.write()
entry.parent = target
}
source.tree.write()
return entry.update(options)
}

Expand Down

0 comments on commit 16b1a89

Please sign in to comment.