All files / lib/common ide.state.ts

0% Statements 0/38
100% Branches 0/0
0% Functions 0/10
0% Lines 0/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                                                                                                                                                                                                 
import {BehaviorSubject} from 'rxjs'
import { UpdateOrigin, SourceCode, SourceContent, SourcePath } from './models'
import { logFactory } from './log-factory.conf'
import {debounceTime, filter} from 'rxjs/operators'
 
const log = logFactory().getChildLogger('ide.state.ts')
 
export class IdeState {
    public readonly fsMap$ = new BehaviorSubject<Map<string, string>>(undefined)
 
    public readonly updates$: {
        [k: string]: BehaviorSubject<{
            path: SourcePath
            content: SourceContent
            updateOrigin: UpdateOrigin
        }>
    }
 
    constructor(params: {
        files: SourceCode[]
        defaultFileSystem: Promise<Map<string, string>>
    }) {
        Object.assign(this, params)
 
        this.fsMap$
            .pipe(
                filter((fsMap) => fsMap != undefined),
                debounceTime(500)
            )
            .subscribe(() => log.info('IdeState => fsMap updated'))
 
        log.info('IdeState.constructor()')
        params.defaultFileSystem.then((defaultFsMap) => {
            const fsMap = new Map(defaultFsMap)
            params.files.forEach((file) => {
                fsMap.set(file.path, file.content)
            })
            log.info('IdeState => virtual files system initialized')
            this.fsMap$.next(fsMap)
        })
        this.updates$ = params.files.reduce((acc, e) => {
            return {
                ...acc,
                [e.path]: new BehaviorSubject({
                    path: e.path,
                    content: e.content,
                    updateOrigin: { uid: 'IdeState' },
                }),
            }
        }, {})
    }
 
    update({
        path,
        content,
        updateOrigin,
    }: {
        path: SourcePath
        content: SourceContent
        updateOrigin: UpdateOrigin
    }) {
 
        const fsMap = this.fsMap$.value
        fsMap.set(path, content)
        this.fsMap$.next(fsMap)
        this.updates$[path].next({
            path,
            content,
            updateOrigin: updateOrigin,
        })
    }
 
    addFile(source: SourceCode){
        const fsMap = this.fsMap$.value
        fsMap.set(source.path, source.content)
        this.fsMap$.next(fsMap)
        this.updates$[source.path] = new BehaviorSubject({...source, updateOrigin:{ uid: 'IdeState' }})
    }
 
    removeFile(path: string){
        const fsMap = this.fsMap$.value
        fsMap.delete(path)
        this.fsMap$.next(fsMap)
        delete this.updates$[path]
    }
 
    moveFile(oldPath: string, newPath: string){
        const fsMap = this.fsMap$.value
        const content =  fsMap.get(oldPath)
        fsMap.set(newPath, content)
        fsMap.delete(oldPath)
        this.fsMap$.next(fsMap)
        delete this.updates$[oldPath]
        this.updates$[newPath] = new BehaviorSubject({path: newPath, content, updateOrigin:{ uid: 'IdeState' }})
    }
}