import { makeObservable , observable } from 'mobx' ; import type { DataContextGetter } from './DataContextGetter' ; import type { IDataContext } from './IDataContext' ; import type { IDataContextProvider } from './IDataContextProvider' ; export class DataContext implements IDataContext { private map : Map < DataContextGetter < any > , any > ; fallback ? : IDataContextProvider ; constructor ( fallback ? ) { this . map = new Map ( ) ; this . fallback = fallback ; makeObservable < this , 'map' > ( this , { map : observable . shallow , fallback : observable . ref , } ) ; } setFallBack ( fallback ? ) { this . fallback = fallback ; } has ( context ) { return this . map . has ( context ) || this . fallback ?. has ( context ) || false ; } find < T > ( context , value ) { let provider = this ; while ( true ) { if ( this . map . get ( context ) === value ) { return true ; } if ( provider . fallback ) { provider = provider . fallback ; } else { return false ; } } } set < T > ( context , value ) { this . map . set ( context , value ) ; return this ; } delete ( context ) { this . map . delete ( context ) ; return this ; } get < T > ( context ) { if ( ! this . map . has ( context ) ) { const defaultValue = context ( ) ; if ( defaultValue !== undefined ) { return defaultValue ; } if ( this . fallback ) { return this . fallback . get ( context ) ; } throw new Error ( 'Context doesn\'t exists' ) ; } return this . map . get ( context ) ; } tryGet < T > ( context ) { if ( ! this . map . has ( context ) ) { if ( this . fallback ) { return this . fallback . tryGet ( context ) ; } } return this . map . get ( context ) ; } }