@abstract-filesystem/filesystem
Version:
A abstract filesystem
131 lines (100 loc) • 3.22 kB
text/typescript
import { Driver, Disk, DriverConstructor } from '@abstract-filesystem/types'
import MemoryDriver from './memory-driver'
export class FilesystemManagement {
protected _drivers = new Map<string, DriverConstructor>()
protected _disks = new Map<string, { driverName: string; instance: Disk }>()
protected _defaultDisk: string | null = null
registerDriver(name: string, driver: DriverConstructor<Driver>): this {
this._drivers.set(name, driver)
return this
}
driver<D extends Driver>(name: string): DriverConstructor<D> {
const driver = this._drivers.get(name)
if (!driver) {
throw new Error(`Driver not registered: ${name}`)
}
return driver as DriverConstructor<D>
}
drivers(): string[] {
return Array.from(this._drivers.keys())
}
hasDriver(name: string): boolean {
return this._drivers.has(name)
}
hasDisk(name: string): boolean {
return this._disks.has(name)
}
disks(): string[] {
return [...this._disks.keys()]
}
/**
* Make disk by driver
*/
async makeDisk<Drv extends Driver>(driver: DriverConstructor<Drv>, options?: Drv['options']) {
const driverName = driver.name
const disk = new driver()
if (options) {
disk.config(options)
}
try {
await disk.setup()
} catch (e) {
console.error(`Setup driver failed, dist: ${name}, dirver: ${driverName}`)
throw e
}
return disk
}
/**
* Create disk by driver class
*/
async registerDisk<Drv extends Driver>(diskName: string, driver: DriverConstructor<Drv>, options?: Drv['options']) {
if (this.hasDisk(diskName)) {
throw new Error(`Disk already registered: ${diskName}`)
}
const driverName = driver.name
const disk = await this.makeDisk(driver, options)
this._disks.set(diskName, {
instance: disk,
driverName,
})
// Set first create disk is default disk
if (!this._defaultDisk) this._defaultDisk = diskName
return disk
}
/**
* Create disk by driver name
*/
async createDisk<Drv extends Driver>(name: string, driverName: string, options?: Drv['options']): Promise<Disk<Drv>> {
if (!this.hasDriver(driverName)) {
throw new Error(`Driver not registered: ${driverName}`)
}
const driverClass = this.driver<Drv>(driverName)
const disk = await this.registerDisk(name, driverClass, options)
return disk
}
disk<Drv extends Driver, D extends Disk<Drv> = Disk<Drv>>(name: string): D {
const detail = this._disks.get(name)
if (!detail) {
throw new Error(`Disk not exists: ${name}`)
}
return detail.instance as D
}
defaultDiskName(): string | null {
return this._defaultDisk
}
defaultDisk<Drv extends Driver>(): Disk<Drv> {
if (!this._defaultDisk) throw new Error('No disks defined')
return this.disk<Drv>(this._defaultDisk)
}
setDefaultDisk(disk: string): this {
if (!this.hasDisk(disk)) {
throw new Error('Set default disk failed, required disk is not exists: ' + disk)
}
this._defaultDisk = disk
return this
}
}
const fsm = new FilesystemManagement()
export default fsm
export { MemoryDriver }
export type { Driver, Disk, DriverConstructor }