import { ComponentInstance , Component , HookTypes , StyleSheet , CSSResult , defineComponent , normalizeOptions , ComponentOptions } from '@kirei/element' ; /**
 * Cache for a component and its instances
 */ const hmrCache = new Map < string , HMRCache > ( ) ; /**
 * HMR cache item
 */ interface HMRCache { /**
     * Element constructor, to modify static options
     */ ctor : typeof Component ; /**
     * Active instances with HMR enabled
     */ instances : Set < ComponentInstance > ; } param ctor param key param fn function injectHook ( ctor , key , fn ) { const { options } = ctor ; if ( ! options . hooks ) { options . hooks = { } ; } if ( ! options . hooks [ key ] ) { options . hooks [ key ] = [ fn ] ; } else { options . hooks [ key ] . push ( fn ) ; } } param oldStyles param newStyles returns function stylesChanged ( oldStyles , newStyles ) { if ( oldStyles . length != newStyles . length ) { return true ; } return ! oldStyles . every ( ( style , idx ) => { const other = newStyles [ idx ] ; if ( ( style instanceof CSSResult ) && ( other instanceof CSSResult ) ) { return style . cssText === other . cssText ; } return style === other ; } ) ; } param filename param opts returns function generateId ( filename , opts ) { return `${ filename }#${ opts . name }` ; } param filename param opts returns export function has ( filename , opts ) { return hmrCache . has ( generateId ( filename , opts ) ) ; } param filename param opts returns export function createOrUpdate ( filename , opts ) { return has ( filename , opts ) ? update ( filename , opts ) : create ( filename , opts ) ; } param filename param opts returns export function create ( filename , opts ) { const id = generateId ( filename , opts ) ; const cache = hmrCache . get ( id ) ; if ( cache ) { return cache . ctor ; } const ctor = defineComponent ( opts ) ; const instances = new Set < ComponentInstance > ( ) ; ctor . options . filename = filename ; hmrCache . set ( id , { ctor , instances } ) ; injectHook ( ctor , HookTypes . BEFORE_MOUNT , function ( ) { instances . add ( this ) ; } ) ; injectHook ( ctor , HookTypes . BEFORE_UNMOUNT , function ( ) { instances . delete ( this ) ; } ) ; return ctor ; } param filename param opts returns export function update ( filename , opts ) { const { ctor , instances } = hmrCache . get ( generateId ( filename , opts ) ) ; const options = normalizeOptions ( opts ) ; const reflowStyles = ctor . options . styles && stylesChanged ( ctor . options . styles , options . styles ) ; Object . assign ( ctor . options , options ) ; for ( const instance of instances ) { instance . options = ctor . options ; instance . setup ( ) ; instance . effect . options . scheduler ( instance . effect ) ; if ( reflowStyles ) { instance . reflowStyles ( ) ; } } console . log ( `[Kirei HMR]: Updated <${ ctor . options . name }>.` ) ; return ctor ; }