All files / lib/common ide.state.ts

0% Statements 0/24
0% Branches 0/4
0% Functions 0/8
0% Lines 0/24

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                                                                                                                                                 
import { BehaviorSubject, merge } 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))
            .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' },
                }),
            }
        }, {})
        merge(...Object.values(this.updates$))
            .pipe(debounceTime(250))
            .subscribe(({ path, content }) => {
                const fsMap = this.fsMap$.getValue()
                fsMap && fsMap.set(path, content)
                fsMap && this.fsMap$.next(fsMap)
            })
    }
 
    update({
        path,
        content,
        updateOrigin,
    }: {
        path: SourcePath
        content: SourceContent
        updateOrigin: UpdateOrigin
    }) {
        this.updates$[path].next({
            path,
            content,
            updateOrigin: updateOrigin,
        })
    }
}