UNPKG

@mieweb/wikigdrive

Version:

Google Drive to MarkDown synchronization

141 lines (114 loc) 3.51 kB
import process from 'node:process'; import type {QueueObject} from 'async'; import casual from 'casual'; import winston from 'winston'; import {FileContentService} from './utils/FileContentService.ts'; import {QueueTask} from './containers/google_folder/QueueTask.ts'; import {FileId} from './model/model.ts'; export interface ContainerConfig { name?: string; [key: string]: string; } export interface ContainerConfigArr { [key: string]: string[]; } type EventCallback = (driveId: FileId, payload) => void; export class Container { protected engine: ContainerEngine; protected filesService: FileContentService; constructor(public readonly params: ContainerConfig, public readonly paramsArr: ContainerConfigArr = {}) { if (!this.params.name) { this.params.name = casual.array_of_words(2).join('_'); } } async mount(fileService: FileContentService) { this.filesService = fileService; } async init(engine: ContainerEngine): Promise<void> { this.engine = engine; } async run(command) { switch (command) { case 'scan': break; } } // eslint-disable-next-line @typescript-eslint/no-empty-function async destroy(): Promise<void> { } // eslint-disable-next-line @typescript-eslint/no-empty-function async flushData() { } getQueue(): QueueObject<QueueTask> { return null; } } export class ContainerError extends Error { constructor(msg) { super(msg); } } export class ContainerEngine { constructor(public readonly logger: winston.Logger, public readonly rootFileService: FileContentService) { process.on('SIGINT', async () => { console.log('SIGINT'); await this.flushData(); process.exit(); }); } private readonly containers: { [name: string]: Container } = {}; private listeners: { [eventName: string]: Set<EventCallback>; } = {}; async registerContainer(container: Container): Promise<Container> { if (this.containers[container.params.name]) { throw new ContainerError(`Container already exists: ${container.params.name}`); } try { await container.init(this); this.containers[container.params.name] = container; } catch (err) { this.logger.error(`Error starting container ${container.params.name} ${err.stack ? err.stack : err.message}`, err); } return container; } async unregisterContainer(name: string): Promise<void> { const container = this.containers[name]; if (!container) { throw new ContainerError(`No such container: ${name}`); } await container.destroy(); delete this.containers[container.params.name]; } // eslint-disable-next-line @typescript-eslint/no-empty-function async run() { } getContainer(name: string) { if (!this.containers[name]) { throw new Error(`Unknown container: ${name}`); } return this.containers[name]; } hasContainer(name: string) { return !!this.containers[name]; } async flushData() { for (const container of Object.values(this.containers)) { await container.flushData(); } } emit(driveId: FileId, eventName: string, payload) { if (!this.listeners[eventName]) { return; } for (const listener of this.listeners[eventName]) { listener(driveId, payload); } } subscribe(eventName: string, callback: EventCallback) { if (!this.listeners[eventName]) { this.listeners[eventName] = new Set(); } this.listeners[eventName].add(callback); } }