Skip to content

Commit

Permalink
refa: fix regression in last refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 14, 2024
1 parent db83b69 commit 50d097b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 44 deletions.
38 changes: 15 additions & 23 deletions packages/loader/src/config/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,33 @@ import { pathToFileURL } from 'node:url'
import { remove } from 'cosmokit'
import * as yaml from 'js-yaml'
import { EntryOptions } from './entry.ts'
import { Loader } from '../loader.ts'
import { ImportTree } from './import.ts'
import { JsExpr } from './utils.ts'

export const schema = yaml.JSON_SCHEMA.extend(JsExpr)

export class LoaderFile {
public suspend = false
public readonly: boolean
public refs: FileRef[] = []
public trees: ImportTree[] = []
public writeTask?: NodeJS.Timeout

constructor(public loader: Loader, public name: string, public type?: string) {
constructor(public name: string, public type?: string) {
this.readonly = !type
}

ref(tree: ImportTree) {
this.trees.push(tree)
tree.url = pathToFileURL(this.name).href
tree.ctx.loader.files[tree.url] ??= this
}

unref(tree: ImportTree) {
remove(this.trees, tree)
if (this.trees.length) return
delete tree.ctx.loader.files[tree.url]
}

async checkAccess() {
if (!this.type) return
try {
Expand Down Expand Up @@ -59,10 +71,6 @@ export class LoaderFile {
this._write(config)
}, 0)
}

ref() {
return new FileRef(this)
}
}

export namespace LoaderFile {
Expand All @@ -81,19 +89,3 @@ export namespace LoaderFile {
}
}
}

export class FileRef<F extends LoaderFile = LoaderFile> {
public url: string

constructor(public file: F) {
this.file.refs.push(this)
this.url = pathToFileURL(file.name).href
file.loader.files[this.url] ??= this.file
}

stop() {
remove(this.file.refs, this)
if (this.file.refs.length) return
delete this.file.loader.files[this.url]
}
}
27 changes: 15 additions & 12 deletions packages/loader/src/config/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { dirname, extname, resolve } from 'node:path'
import { readdir, stat } from 'node:fs/promises'
import { fileURLToPath } from 'node:url'
import { EntryTree } from './tree.ts'
import { FileRef, LoaderFile } from './file.ts'
import { LoaderFile } from './file.ts'
import Loader from '../loader.ts'

export class ImportTree<C extends Context = Context> extends EntryTree<C> {
static reusable = true

public ref!: FileRef
public file!: LoaderFile

constructor(public ctx: C) {
super(ctx)
Expand All @@ -19,21 +19,21 @@ export class ImportTree<C extends Context = Context> extends EntryTree<C> {

async start() {
await this.refresh()
await this.ref.file.checkAccess()
await this.file.checkAccess()
}

async refresh() {
this.root.update(await this.ref.file.read())
this.root.update(await this.file.read())
}

stop() {
this.ref?.stop()
this.file?.unref(this)
return this.root.stop()
}

write() {
this.context.emit('loader/config-update')
return this.ref.file.write(this.root.data)
return this.file.write(this.root.data)
}

async init(baseDir: string, options: Loader.Config) {
Expand All @@ -47,7 +47,8 @@ export class ImportTree<C extends Context = Context> extends EntryTree<C> {
if (!LoaderFile.supported.has(ext)) {
throw new Error(`extension "${ext}" not supported`)
}
this.ref = new LoaderFile(this.ctx.loader, filename, type).ref()
this.file = new LoaderFile(filename, type)
this.file.ref(this)
} else {
baseDir = filename
await this._init(baseDir, options)
Expand All @@ -56,7 +57,6 @@ export class ImportTree<C extends Context = Context> extends EntryTree<C> {
await this._init(baseDir, options)
}
this.ctx.provide('baseDir', baseDir, true)
this.url = this.ref.url
}

private async _init(baseDir: string, options: Loader.Config) {
Expand All @@ -70,14 +70,16 @@ export class ImportTree<C extends Context = Context> extends EntryTree<C> {
}
const type = LoaderFile.writable[extension]
const filename = resolve(baseDir, name + extension)
this.ref = new LoaderFile(this.ctx.loader, filename, type).ref()
this.file = new LoaderFile(filename, type)
this.file.ref(this)
return
}
if (initial) {
const type = LoaderFile.writable['.yml']
const filename = resolve(baseDir, name + '.yml')
this.ref = new LoaderFile(this.ctx.loader, filename, type).ref()
return this.ref.file.write(initial as any)
this.file = new LoaderFile(filename, type)
this.file.ref(this)
return this.file.write(initial as any)
}
throw new Error('config file not found')
}
Expand All @@ -101,7 +103,8 @@ export class Import extends ImportTree {
if (!LoaderFile.supported.has(ext)) {
throw new Error(`extension "${ext}" not supported`)
}
this.ref = new LoaderFile(this.ctx.loader, filename, LoaderFile.writable[ext]).ref()
this.file = new LoaderFile(filename, LoaderFile.writable[ext])
this.file.ref(this)
await super.start()
}
}
12 changes: 6 additions & 6 deletions packages/loader/tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('loader: basic support', () => {
before(() => loader.start())

it('loader initiate', async () => {
loader.ref.file.write([{
loader.file.write([{
id: '1',
name: 'foo',
}, {
Expand Down Expand Up @@ -45,7 +45,7 @@ describe('loader: basic support', () => {
it('loader update', async () => {
foo.mock.resetCalls()
bar.mock.resetCalls()
loader.ref.file.write([{
loader.file.write([{
id: '1',
name: 'foo',
}, {
Expand All @@ -65,7 +65,7 @@ describe('loader: basic support', () => {
it('plugin self-update 1', async () => {
root.registry.get(foo)!.update({ a: 3 })
await new Promise((resolve) => setTimeout(resolve, 0))
expect(loader.ref.file.data).to.deep.equal([{
expect(loader.file.data).to.deep.equal([{
id: '1',
name: 'foo',
config: { a: 3 },
Expand All @@ -78,7 +78,7 @@ describe('loader: basic support', () => {
it('plugin self-update 2', async () => {
root.registry.get(foo)!.children[0].update({ a: 5 })
await new Promise((resolve) => setTimeout(resolve, 0))
expect(loader.ref.file.data).to.deep.equal([{
expect(loader.file.data).to.deep.equal([{
id: '1',
name: 'foo',
config: { a: 5 },
Expand All @@ -91,7 +91,7 @@ describe('loader: basic support', () => {
it('plugin self-dispose 1', async () => {
root.registry.get(foo)!.dispose()
await new Promise((resolve) => setTimeout(resolve, 0))
expect(loader.ref.file.data).to.deep.equal([{
expect(loader.file.data).to.deep.equal([{
id: '1',
name: 'foo',
disabled: true,
Expand All @@ -105,7 +105,7 @@ describe('loader: basic support', () => {
it('plugin self-dispose 2', async () => {
root.registry.get(qux)!.children[0].dispose()
await new Promise((resolve) => setTimeout(resolve, 0))
expect(loader.ref.file.data).to.deep.equal([{
expect(loader.file.data).to.deep.equal([{
id: '1',
name: 'foo',
disabled: true,
Expand Down
7 changes: 4 additions & 3 deletions packages/loader/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dict } from 'cosmokit'
import { Context, ForkScope, Plugin } from '@cordisjs/core'
import { EntryOptions, FileRef, Group, Loader, LoaderFile } from '../src'
import { EntryOptions, Group, Loader, LoaderFile } from '../src'
import { Mock, mock } from 'node:test'
import { expect } from 'chai'

Expand All @@ -26,13 +26,14 @@ class MockLoaderFile extends LoaderFile {
}

export default class MockLoader extends Loader {
declare ref: FileRef<MockLoaderFile>
declare file: MockLoaderFile

public modules: Dict<Plugin.Object> = Object.create(null)

constructor(ctx: Context) {
super(ctx, { name: 'cordis' })
this.ref = new MockLoaderFile(this, 'config-1.yml').ref()
this.file = new MockLoaderFile('config-1.yml')
this.file.ref(this)
this.mock('cordis/group', Group)
}

Expand Down

0 comments on commit 50d097b

Please sign in to comment.