11import { existsSync , readFileSync } from "node:fs" ;
22import { resolve , dirname } from "node:path" ;
33
4- /**
5- * Candidate filenames for the pre-built runtime IIFE artifact.
6- * The build copies core's IIFE output into cli/dist under both names.
7- */
84const RUNTIME_FILENAMES = [ "hyperframe-runtime.js" , "hyperframe.runtime.iife.js" ] ;
95
10- /**
11- * Walk up from `startDir` looking for the runtime artifact inside
12- * `node_modules/hyperframes/dist/` or `node_modules/@hyperframes/core/dist/`.
13- * Stops at the filesystem root.
14- */
156function findRuntimeInNodeModules ( startDir : string ) : string | null {
167 const subPaths = [
178 "node_modules/hyperframes/dist/hyperframe-runtime.js" ,
@@ -25,26 +16,20 @@ function findRuntimeInNodeModules(startDir: string): string | null {
2516 if ( existsSync ( candidate ) ) return candidate ;
2617 }
2718 const parent = dirname ( dir ) ;
28- if ( parent === dir ) break ; // reached root
19+ if ( parent === dir ) break ;
2920 dir = parent ;
3021 }
3122 return null ;
3223}
3324
34- /**
35- * Try to locate and read the pre-built IIFE runtime artifact on disk.
36- * Returns the JS source string or null if not found.
37- */
3825function readPrebuiltRuntime ( ) : string | null {
39- // 1. Check alongside the bundled CLI (dist/hyperframe-runtime.js etc.)
4026 for ( const name of RUNTIME_FILENAMES ) {
4127 const candidate = resolve ( __dirname , name ) ;
4228 if ( existsSync ( candidate ) ) {
4329 return readFileSync ( candidate , "utf-8" ) ;
4430 }
4531 }
4632
47- // 2. Walk up from __dirname looking inside node_modules
4833 const fromNodeModules = findRuntimeInNodeModules ( __dirname ) ;
4934 if ( fromNodeModules ) {
5035 return readFileSync ( fromNodeModules , "utf-8" ) ;
@@ -53,22 +38,27 @@ function readPrebuiltRuntime(): string | null {
5338 return null ;
5439}
5540
56- export async function loadRuntimeSourceFallback ( ) : Promise < string | null > {
57- // Primary: dynamically import @hyperframes /core and build via esbuild.
58- // In dev this produces a live build from source. In the bundled CLI,
59- // import.meta.url inside the inlined core code resolves to cli.js,
60- // making the entry.ts path invalid — so this fails for global installs.
41+ function canBuildFromSource ( ) : boolean {
6142 try {
62- const mod = await import ( "@hyperframes/core" ) ;
63- if ( typeof mod . loadHyperframeRuntimeSource === "function" ) {
64- return mod . loadHyperframeRuntimeSource ( ) ;
65- }
43+ const entryPath = resolve ( __dirname , ".." , ".." , ".." , "core" , "src" , "runtime" , "entry.ts" ) ;
44+ return existsSync ( entryPath ) ;
6645 } catch {
67- // Expected in bundled context — fall through to pre-built artifact.
46+ return false ;
47+ }
48+ }
49+
50+ export async function loadRuntimeSourceFallback ( ) : Promise < string | null > {
51+ if ( canBuildFromSource ( ) ) {
52+ try {
53+ const mod = await import ( "@hyperframes/core" ) ;
54+ if ( typeof mod . loadHyperframeRuntimeSource === "function" ) {
55+ return mod . loadHyperframeRuntimeSource ( ) ;
56+ }
57+ } catch {
58+ // esbuild failed even though source exists — fall through to artifact
59+ }
6860 }
6961
70- // Fallback: read the pre-built IIFE artifact from disk. This covers the
71- // globally-installed case where esbuild cannot resolve source files.
7262 const prebuilt = readPrebuiltRuntime ( ) ;
7363 if ( prebuilt ) return prebuilt ;
7464
0 commit comments