import { EventSlot } from '../library-ts/browser/events/EventSlot.js'; export interface DocumentOpenedEvent { path: string; content: string; } export interface DocumentPathEvent { path: string; } export class Editor { static _instance: Editor = null; static get(): Editor { if ( ! this._instance ) { this._instance = new Editor(); } return this._instance; } projectId: string = ''; projectName: string = ''; openDocs: Map = new Map(); activeDoc: string | null = null; readonly onDocumentOpened: EventSlot = new EventSlot(); readonly onDocumentDirty: EventSlot = new EventSlot(); readonly onDocumentSaved: EventSlot = new EventSlot(); readonly onFilesChanged: EventSlot = new EventSlot(); async openDocument( filePath: string ): Promise { if ( ! this.openDocs.has( filePath ) ) { const res = await fetch( `/api/files/${this.projectId}/${filePath}` ); const content = await res.text(); this.openDocs.set( filePath, { content, dirty: false } ); } this.activeDoc = filePath; const entry = this.openDocs.get( filePath )!; this.onDocumentOpened.dispatch( { path: filePath, content: entry.content } ); } markDirty( filePath: string, content: string ): void { const doc = this.openDocs.get( filePath ); if ( ! doc ) { return; } doc.content = content; doc.dirty = true; this.onDocumentDirty.dispatch( { path: filePath } ); } async save( filePath: string ): Promise { const doc = this.openDocs.get( filePath ); if ( ! doc || ! doc.dirty ) { return; } await fetch( `/api/files/${this.projectId}/${filePath}`, { method: 'PUT', headers: { 'Content-Type': 'text/plain' }, body: doc.content } ); doc.dirty = false; this.onDocumentSaved.dispatch( { path: filePath } ); } }