import type { SetupOptions } from '@vuedx/preview-provider' ; import { Module } from 'module' ; import * as Path from 'path' ; import * as vm from 'vm' ; import type { App , ComponentPublicInstance } from 'vue' ; import { generatePreviewComponent , getPreviewId } from './transform' ; type PreviewFactory < T = ComponentPublicInstance > = ( overrides : Partial < SetupOptions > ) => T ; type PreviewFactoryModule < T = ComponentPublicInstance > = ( exports : any , require : NodeJS . Require , module : NodeModule , fileName : string , dirName : string ) => PreviewFactory < T > ; const compilations = { } ; function compile ( fileName , previewName ) { const id = getPreviewId ( fileName , previewName , false ) ; if ( compilations [ id ] != null ) return compilations [ id ] ; const code = generatePreviewComponent ( fileName , previewName , false ) ; compilations [ id ] = vm . runInThisContext ( Module . wrap ( code ) , { filename : id , displayErrors : true , microtaskMode : 'afterEvaluate' , } ) ; return compilations [ id ] ; } function compileAsApp ( fileName , previewName ) { const id = `${ fileName }?app&preview=${ encodeURIComponent ( previewName ) . replace ( /%20/g , '+' ) }` ; if ( compilations [ id ] != null ) return compilations [ id ] ; const code = generatePreviewComponent ( fileName , previewName , true ) ; compilations [ id ] = vm . runInThisContext ( Module . wrap ( code ) , { filename : id , displayErrors : true , microtaskMode : 'afterEvaluate' , } ) ; return compilations [ id ] ; } const executions = { } ; interface RunOptions { fileName : string ; previewName : string ; isAppMode : boolean ; } function run < T > ( { fileName , previewName , isAppMode } ) { const id = getPreviewId ( fileName , previewName , isAppMode ) ; if ( executions [ id ] != null ) return executions [ id ] as PreviewFactory < T > ; const fn = isAppMode ? compileAsApp ( fileName , previewName ) : compile ( fileName , previewName ) ; const req = Module . createRequire ( fileName ) ; const m = { id : id , exports : { } , children : [ ] , require : req , filename : id , parent : module , path : Path . dirname ( fileName ) , paths : req . resolve . paths ( Path . dirname ( fileName ) ) ?? [ ] , loaded : false , } ; fn . call ( m , m . exports , req , m , fileName , Path . dirname ( fileName ) ) ; m . loaded = true ; return ( executions [ id ] = m . exports . default ) ; } export function execute ( fileName , previewName ) { return run ( { fileName , previewName , isAppMode : false } ) ; } export function executeAsApp ( fileName , previewName ) { return run ( { fileName , previewName , isAppMode : true } ) ; }