@@ -4,74 +4,85 @@ import { join } from "node:path";
44import { program } from "commander" ;
55import * as pkg from "../package.json" ;
66
7+ // if(existsSync(join(process.cwd(), "./hyper.config.js"))) {
8+ // console.log("Found hyper.config.js");
9+ // const config = await import(join(process.cwd(), "./hyper.config.js"));
10+ // }
11+
712program
813 . version ( pkg . version )
9- . option ( "--hot" , "Wether to watch for changes in the served folder ." , false )
10- . option ( "-h, --hostname <hostname>" , "Server's hostname. When ' 0.0.0.0' serve both localhost and to local network." , "localhost" )
11- . option ( "-p, --port <port>" , "The port to listen to. Needs sudo to assign ports below 3000." , 8080 )
12- . option ( "-d , --dir <dir >" , "The folder to serve." , "." )
13- // .argument("<dir >", "Folder to serve. Defaults to current folder .", "." )
14+ . option ( "--hot" , "Enable hot-reloading ." , false )
15+ . option ( "-h, --hostname <hostname>" , "Server's hostname. When ` 0.0.0.0` serve both localhost and to local network." , process . env . HOSTNAME || "localhost" )
16+ . option ( "-p, --port <port>" , "Port to listen to. Needs sudo to assign ports below 3000." , process . env . PORT || 3000 )
17+ . option ( "-r , --root <root >" , "Document root folder to serve." , process . env . ROOT || process . cwd ( ) )
18+ //.argument("<root >", "Folder to serve. Defaults to current working directory .", process.cwd() )
1419 . parse ( process . argv ) ;
1520
1621const opts = program . opts ( ) ;
1722// const args = program.args();
1823
19- if ( existsSync ( "./hyper.config.js" ) ) {
20- console . log ( "Found hyper.config.js" ) ;
21- const config = import ( "./hyper.config.js" ) ;
22- }
23-
24- /** Public directory to serve */
25- const PUBLIC_DIR = join ( process . cwd ( ) , opts . dir || "dir" in config && config . dir || process . env . PUBLIC_DIR || "." ) ;
24+ /** Hot-Reload command */
25+ export const HOT_CMD = "/hot" ;
2626
2727/** Hostname */
28- const HOSTNAME = opts . hostname || process . env . HOSTNAME || "localhost" ;
28+ export const HOSTNAME = opts . hostname ;
2929
3030/** Server port */
31- const PORT = opts . port || process . env . PORT || 8080 ;
31+ export const PORT = opts . port ;
3232
33- /** Hot-Reload command */
34- const HOT_CMD = "/hot" ;
33+ /** Public directory to serve */
34+ export const ROOT = opts . root ;
3535
3636/** Watch files for change */
37- const watcher = opts . hot && watch (
38- PUBLIC_DIR ,
37+ export const watcher = opts . hot && watch (
38+ ROOT ,
3939 { recursive : true } ,
4040 ( eventType , filePath ) => {
4141 console . log ( `FSWatcher: '${ eventType } ' on '${ filePath } '` ) ;
4242 server . publish ( HOT_CMD , `File '${ filePath } ' fired '${ eventType } ' event. You have to reload!` ) ;
4343 }
4444) ;
4545
46- /** Serve files */
46+ /** Start Server */
4747export const server = Bun . serve ( {
48- fetch : ( request , server ) => {
49- try {
50- const requestPath = new URL ( request . url ) . pathname ;
51- console . log ( `${ request . method } ${ requestPath } ` ) ;
52- if ( request . url . endsWith ( HOT_CMD ) ) {
53- console . log ( `Server: Got '${ HOT_CMD } ' request, trying to upgrade...` )
54- if ( ! server . upgrade ( request ) ) {
55- console . log ( `Server: Upgrade failed...` ) ;
56- throw new Error ( "Upgrade Failed" ) ;
57- }
58- }
59- let filePath = join ( PUBLIC_DIR , requestPath ) ;
48+ fetch : async ( request , server ) => {
49+ const requestPath = new URL ( request . url ) . pathname ;
50+ console . log ( `${ request . method } ${ requestPath } ` ) ;
51+ if ( opts . hot && request . url . endsWith ( HOT_CMD ) ) {
52+ console . log ( `Server: Got '${ HOT_CMD } ' request, trying to upgrade...` )
53+ }
54+ else {
55+ let filePath = join ( ROOT , requestPath ) ;
6056 if ( request . url . endsWith ( "/" ) ) {
6157 filePath = `${ filePath } index.html` ;
6258 }
63- if ( existsSync ( filePath ) ) {
64- const file = Bun . file ( filePath ) ;
65- return new Response ( file , { headers : { "Content-Type" : file . type } } ) ;
59+ const file = Bun . file ( filePath ) ;
60+ if ( opts . hot && file . type . startsWith ( "text/html" ) ) {
61+ return new Response (
62+ new HTMLRewriter ( ) . on ( "head" , {
63+ element ( head ) {
64+ head . append (
65+ `<script>
66+ const socket = new WebSocket("ws://${ HOSTNAME } :${ PORT } ${ HOT_CMD } ");
67+ socket.addEventListener("message", event => window.location.reload());
68+ </script>` ,
69+ { html : true }
70+ ) ;
71+ }
72+ } ) . transform ( await file . text ( ) ) ,
73+ {
74+ headers : { "Content-Type" : file . type }
75+ }
76+ ) ;
6677 }
78+ return new Response ( file , { headers :{ "Content-Type" : file . type } } ) ;
6779 }
68- catch ( error ) {
69- console . log ( error ) ;
70- if ( "ENOENT" === error . code ) {
71- return new Response ( "Not Found" , { status : 404 } ) ;
72- }
73- return new Response ( "Internal Server Error" , { status : 500 } ) ;
80+ } ,
81+ error : ( error ) => {
82+ if ( "ENOENT" === error . code ) {
83+ return new Response ( "404 - Not Found" , { status : 404 } ) ;
7484 }
85+ return new Response ( "500 - Internal Server Error" , { status : 500 } ) ;
7586 } ,
7687 hostname : HOSTNAME ,
7788 port : PORT ,
0 commit comments