import { InjectionKey } from '@vue/runtime-core' ; import { isFunction } from '@vue/shared' ; import { getCurrentInstance } from './component' ; import { warn } from './errorHandling' ; type PluginInstallFunction = ( app : AppContext [ 'app' ] , ... options : any [ ] ) => any ; export type Plugin = PluginInstallFunction & { install ? : PluginInstallFunction ; } | { install : PluginInstallFunction ; } ; declare global { interface Window { __reactivue_context : AppContext ; } } interface AppContext { app : any ; config : { globalProperties : Record < string , any > ; } ; provides : Record < string | symbol , any > ; mixins : any ; components : any ; directives : any ; } function createAppContext ( ) { return { app : null as any , config : { globalProperties : { } , } , provides : { } , mixins : [ ] , components : { } , directives : { } , } ; } export function createApp ( ) { const context = __BROWSER__ && window . __reactivue_context ? window . __reactivue_context : createAppContext ( ) ; if ( __BROWSER__ ) window . __reactivue_context = context ; const installedPlugins = new Set ( ) ; const app = ( context . app = { version : '3.0.0' , get config ( ) { return context . config ; } , set config ( _v ) { if ( __DEV__ ) { warn ( 'app.config cannot be replaced. Modify individual options instead.' ) ; } } , use ( plugin , ... options ) { if ( installedPlugins . has ( plugin ) ) { __DEV__ && warn ( 'Plugin has already been applied to target app.' ) ; } else if ( plugin && isFunction ( plugin . install ) ) { installedPlugins . add ( plugin ) ; plugin . install ( app , ... options ) ; } else if ( isFunction ( plugin ) ) { installedPlugins . add ( plugin ) ; plugin ( app , ... options ) ; } else if ( __DEV__ ) { warn ( 'A plugin must either be a function or an object with an "install" ' + 'function.' ) ; } return app ; } , provide < T > ( key , value ) { if ( __DEV__ && ( key as string | symbol ) in context . provides ) { warn ( `App already provides property with key "${ String ( key ) }". ` + 'It will be overwritten with the new value.' ) ; } context . provides [ key as string ] = value ; } , mixin ( ) { if ( __DEV__ ) warn ( '`app.mixin` method is not supported in reactivue.' ) ; } , component ( ) { if ( __DEV__ ) warn ( '`app.component` method is not supported in reactivue.' ) ; } , directive ( ) { if ( __DEV__ ) warn ( '`app.directive` method is not supported in reactivue.' ) ; } , } ) ; return app ; } export function h ( ) { } export function provide < T > ( key , value ) { const instance = getCurrentInstance ( ) ; if ( instance ) instance . provides [ key as string ] = value ; } export function inject < T > ( key ) ; export function inject < T > ( key , defaultValue , treatDefaultAsFactory ? ) ; export function inject < T > ( key , defaultValue , treatDefaultAsFactory ) ; export function inject ( key , defaultValue ? , treatDefaultAsFactory = false ) { const instance = getCurrentInstance ( ) ; if ( instance ) { if ( instance . provides && ( key as string | symbol ) in instance . provides ) { return instance . provides [ key as string ] ; } else if ( arguments . length > 1 ) { return treatDefaultAsFactory && isFunction ( defaultValue ) ? defaultValue ( ) : defaultValue ; } else if ( __DEV__ ) { warn ( `injection "${ String ( key ) }" not found.` ) ; } } else if ( __DEV__ ) { warn ( 'inject() can only be used inside setup() or functional components.' ) ; } }