import { isString } from '@vue/shared' ; import { getCurrentInstance } from './runtime/instance' ; import type { ComponentInstance } from './types' ; const INDENT_STEP = 2 ; const INDENT = 4 ; class KireiError extends Error { constructor ( message , context ? ) { super ( ) ; this . message = formatMessage ( message , context ) ; this . name = '[Kirei error]' ; } } param instance returns private function * walkInstanceTree ( instance ) { while ( instance ) { yield instance ; instance = instance . parent ; } } param instance param indent param recursiveCount returns private function formatComponentName ( instance , indent , recursiveCount ? ) { const { name , filename } = instance . options ; let res = `${ indent ? ' ' . repeat ( INDENT + INDENT_STEP * indent ) : '--> ' }<${ name }>` ; if ( filename ) { res += ` at ${ filename }` ; } if ( recursiveCount ) { res += `... (${ recursiveCount } recursive calls)` ; } return res ; } param instance returns private function createStackTrace ( instance ) { if ( ! instance . parent ) { return `\n\n(found in <${ instance . options . name }>)` ; } const tree = [ ] ; let recursionCount = 0 ; for ( const node of walkInstanceTree ( instance ) ) { if ( tree . length ) { const prev = tree [ tree . length - 1 ] ; if ( prev . constructor === node . constructor ) { recursionCount ++ ; continue ; } else if ( recursionCount ) { tree [ tree . length - 1 ] = [ prev , recursionCount ] ; recursionCount = 0 ; } } tree . push ( instance ) ; } return `\n\nfound in:\n\n` + tree . map ( ( res , idx ) => { return Array . isArray ( res ) ? formatComponentName ( res [ 0 ] , idx , res [ 1 ] ) : formatComponentName ( res , idx ) ; } ) . join ( '\n' ) ; } param message param level param context private function formatMessage ( message , context ? ) { const instance = getCurrentInstance ( ) ; if ( message instanceof Error ) { message = message . message ; } if ( isString ( context ) ) { if ( message . endsWith ( '.' ) ) { message = message . slice ( 0 , - 1 ) ; } message += ` in #${ context }.` ; } if ( instance ) { message += createStackTrace ( instance ) ; } return message ; } param message param context private export function exception ( message , context ? ) { if ( message instanceof KireiError ) { throw message ; } else if ( message instanceof Error ) { message = message . message ; } throw new KireiError ( message , context ) ; } param message param context private export function error ( message , context ? ) { console . error ( `[Kirei error]: ${ formatMessage ( message , context ) }` ) ; } param message param context private export function warn ( message , context ? ) { console . warn ( `[Kirei warn]: ${ formatMessage ( message , context ) }` ) ; }