bun-dev-server 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/file.svg +4 -0
- package/dist/assets/folder.svg +4 -0
- package/dist/assets/index.ejs +18 -0
- package/dist/assets/output.ejs +74 -0
- package/dist/assets/parent.svg +4 -0
- package/dist/assets/serveOutputStyles.css +166 -0
- package/dist/buildManager.d.ts +20 -0
- package/dist/bunClientHmr.d.ts +1 -0
- package/dist/configManager.d.ts +18 -0
- package/dist/fileWatcher.d.ts +12 -0
- package/dist/httpHandler.d.ts +17 -0
- package/dist/index.js +600 -479
- package/dist/staticAssets.d.ts +18 -0
- package/dist/utils/cors.d.ts +10 -0
- package/dist/utils/filesystem.d.ts +17 -0
- package/package.json +5 -2
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
2
|
+
<path d="M7.5 3.75H13.0607C13.3249 3.75 13.5786 3.85536 13.7678 4.04454L18.7057 8.98242C18.8949 9.1716 19.0003 9.42532 19.0003 9.68954V18.75C19.0003 19.5784 18.3287 20.25 17.5003 20.25H7.5C6.67157 20.25 6 19.5784 6 18.75V5.25C6 4.42157 6.67157 3.75 7.5 3.75Z" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
3
|
+
<path d="M13.5 4V8.25C13.5 8.66421 13.8358 9 14.25 9H18.5" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
2
|
+
<path d="M3.75 6.75H9L10.5 9H20.25C20.6642 9 21 9.33579 21 9.75V17.25C21 18.0784 20.3284 18.75 19.5 18.75H4.5C3.67157 18.75 3 18.0784 3 17.25V7.5C3 7.08579 3.33579 6.75 3.75 6.75Z" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
3
|
+
<path d="M3 9H21" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Bun HTML File</title>
|
|
7
|
+
<% for (const cssFile of cssFiles) { %>
|
|
8
|
+
<link rel="stylesheet" href="<%= cssFile %>" />
|
|
9
|
+
<% } %>
|
|
10
|
+
<% for (const hashedJs of hashedImports) { %>
|
|
11
|
+
<script type="module" src="<%= hashedJs %>"></script>
|
|
12
|
+
<% } %>
|
|
13
|
+
</head>
|
|
14
|
+
|
|
15
|
+
<body>
|
|
16
|
+
<div id="app"></div>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Directory Listing</title>
|
|
8
|
+
<link rel="stylesheet" href="/__bun_dev_server__/serveOutputStyles.css" />
|
|
9
|
+
</head>
|
|
10
|
+
|
|
11
|
+
<body>
|
|
12
|
+
<% const firstEntry = dirs[0] ?? files[0]; %>
|
|
13
|
+
<% const resolvedPath = (typeof requestPath === "string" && requestPath.length > 0) ? requestPath : (firstEntry?.requestPath ?? ""); %>
|
|
14
|
+
<% const currentPath = resolvedPath.replace(/\\/g, "/"); %>
|
|
15
|
+
<% const pathSegments = currentPath.split("/").filter(Boolean); %>
|
|
16
|
+
<% const parentPath = pathSegments.slice(0, -1).join("/"); %>
|
|
17
|
+
<% const parentHref = parentPath.length === 0 ? "/" : `/${parentPath}`; %>
|
|
18
|
+
<div class="wrapper">
|
|
19
|
+
<header>
|
|
20
|
+
<h1>Directory Listing</h1>
|
|
21
|
+
<div class="breadcrumbs">
|
|
22
|
+
<% let accrued = ""; %>
|
|
23
|
+
<a class="back-link" href="/" title="Root directory">
|
|
24
|
+
root
|
|
25
|
+
</a>
|
|
26
|
+
<% pathSegments.forEach((segment, idx) => { %>
|
|
27
|
+
<% accrued += (accrued.length ? "/" : "") + segment; %>
|
|
28
|
+
<span>/</span>
|
|
29
|
+
<a href="/<%= accrued %>"><%= segment %></a>
|
|
30
|
+
<% }); %>
|
|
31
|
+
</div>
|
|
32
|
+
</header>
|
|
33
|
+
|
|
34
|
+
<section class="listing">
|
|
35
|
+
<% if (pathSegments.length > 0) { %>
|
|
36
|
+
<a class="item" href="<%= parentHref %>">
|
|
37
|
+
<img class="icon" src="/__bun_dev_server__/parent.svg" alt="" aria-hidden="true" />
|
|
38
|
+
<span class="text">
|
|
39
|
+
<span class="name">..</span>
|
|
40
|
+
<span class="meta">parent directory</span>
|
|
41
|
+
</span>
|
|
42
|
+
</a>
|
|
43
|
+
<% } %>
|
|
44
|
+
|
|
45
|
+
<% if (dirs.length === 0 && files.length === 0) { %>
|
|
46
|
+
<p class="empty">This folder is empty.</p>
|
|
47
|
+
<% } %>
|
|
48
|
+
|
|
49
|
+
<% dirs.forEach((element) => { %>
|
|
50
|
+
<% const dirHref = element.requestPath === "" ? `/${element.name}` : `${element.requestPath}/${element.name}`; %>
|
|
51
|
+
<a class="item" href="<%= dirHref %>">
|
|
52
|
+
<img class="icon" src="/__bun_dev_server__/folder.svg" alt="" aria-hidden="true" />
|
|
53
|
+
<span class="text">
|
|
54
|
+
<span class="name"><%= element.name %></span>
|
|
55
|
+
<span class="meta">directory</span>
|
|
56
|
+
</span>
|
|
57
|
+
</a>
|
|
58
|
+
<% }); %>
|
|
59
|
+
|
|
60
|
+
<% files.forEach((element) => { %>
|
|
61
|
+
<% const fileHref = element.requestPath === "" ? `/${element.name}` : `${element.requestPath}/${element.name}`; %>
|
|
62
|
+
<a class="item" href="<%= fileHref %>">
|
|
63
|
+
<img class="icon" src="/__bun_dev_server__/file.svg" alt="" aria-hidden="true" />
|
|
64
|
+
<span class="text">
|
|
65
|
+
<span class="name"><%= element.name %></span>
|
|
66
|
+
<span class="meta">file</span>
|
|
67
|
+
</span>
|
|
68
|
+
</a>
|
|
69
|
+
<% }); %>
|
|
70
|
+
</section>
|
|
71
|
+
</div>
|
|
72
|
+
</body>
|
|
73
|
+
|
|
74
|
+
</html>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
2
|
+
<path d="M14.25 6.75L8.25 12L14.25 17.25" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
3
|
+
<path d="M10.5 12H20.25" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
* {
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
body {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 2.5rem 1.5rem 3rem;
|
|
12
|
+
font: 15px/1.5 "Segoe UI", Tahoma, sans-serif;
|
|
13
|
+
color: #0f172a;
|
|
14
|
+
background: #f8fafc;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media (prefers-color-scheme: dark) {
|
|
18
|
+
body {
|
|
19
|
+
color: #e2e8f0;
|
|
20
|
+
background: #0f172a;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.wrapper {
|
|
25
|
+
max-width: 960px;
|
|
26
|
+
margin: 0 auto;
|
|
27
|
+
border-radius: 16px;
|
|
28
|
+
padding: 2rem;
|
|
29
|
+
background: rgba(255, 255, 255, 0.85);
|
|
30
|
+
-webkit-backdrop-filter: blur(6px);
|
|
31
|
+
box-shadow: 0 20px 45px rgba(15, 23, 42, 0.12);
|
|
32
|
+
backdrop-filter: blur(6px);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (prefers-color-scheme: dark) {
|
|
36
|
+
.wrapper {
|
|
37
|
+
background: rgba(15, 23, 42, 0.68);
|
|
38
|
+
box-shadow: 0 20px 45px rgba(15, 23, 42, 0.65);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
header {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
gap: 1rem;
|
|
46
|
+
margin-bottom: 1.75rem;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
h1 {
|
|
50
|
+
margin: 0;
|
|
51
|
+
font-size: 1.75rem;
|
|
52
|
+
letter-spacing: -0.02em;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.breadcrumbs {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
flex-wrap: wrap;
|
|
59
|
+
gap: 0.5rem;
|
|
60
|
+
font-size: 0.95rem;
|
|
61
|
+
color: inherit;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.breadcrumbs span {
|
|
65
|
+
opacity: 0.7;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
a {
|
|
69
|
+
color: #2563eb;
|
|
70
|
+
text-decoration: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
a:hover,
|
|
74
|
+
a:focus-visible {
|
|
75
|
+
text-decoration: underline;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.listing {
|
|
79
|
+
display: grid;
|
|
80
|
+
gap: 0.75rem;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.item {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: 0.9rem;
|
|
87
|
+
padding: 0.85rem 1rem;
|
|
88
|
+
border-radius: 12px;
|
|
89
|
+
border: 1px solid rgba(15, 23, 42, 0.08);
|
|
90
|
+
background: rgba(15, 23, 42, 0.02);
|
|
91
|
+
transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.item:hover,
|
|
95
|
+
.item:focus-visible {
|
|
96
|
+
transform: translateY(-2px);
|
|
97
|
+
border-color: rgba(37, 99, 235, 0.4);
|
|
98
|
+
box-shadow: 0 12px 25px rgba(37, 99, 235, 0.15);
|
|
99
|
+
background: rgba(37, 99, 235, 0.08);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.item .icon {
|
|
103
|
+
flex: none;
|
|
104
|
+
width: 28px;
|
|
105
|
+
height: 28px;
|
|
106
|
+
opacity: 0.85;
|
|
107
|
+
object-fit: contain;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.item .text {
|
|
111
|
+
display: flex;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
gap: 0.2rem;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.item .name {
|
|
117
|
+
font-size: 1rem;
|
|
118
|
+
font-weight: 600;
|
|
119
|
+
word-break: break-word;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.item .meta {
|
|
123
|
+
font-size: 0.78rem;
|
|
124
|
+
text-transform: uppercase;
|
|
125
|
+
letter-spacing: 0.08em;
|
|
126
|
+
opacity: 0.6;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.empty {
|
|
130
|
+
margin: 0;
|
|
131
|
+
padding: 1.5rem;
|
|
132
|
+
border-radius: 12px;
|
|
133
|
+
border: 1px dashed rgba(15, 23, 42, 0.2);
|
|
134
|
+
text-align: center;
|
|
135
|
+
opacity: 0.7;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@media (prefers-color-scheme: dark) {
|
|
139
|
+
.item {
|
|
140
|
+
border-color: rgba(226, 232, 240, 0.08);
|
|
141
|
+
background: rgba(148, 163, 184, 0.06);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.item:hover,
|
|
145
|
+
.item:focus-visible {
|
|
146
|
+
border-color: rgba(96, 165, 250, 0.45);
|
|
147
|
+
background: rgba(59, 130, 246, 0.2);
|
|
148
|
+
box-shadow: 0 12px 25px rgba(15, 23, 42, 0.5);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.empty {
|
|
152
|
+
border-color: rgba(226, 232, 240, 0.18);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.back-link {
|
|
157
|
+
display: inline-flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
gap: 0.35rem;
|
|
160
|
+
font-size: 0.95rem;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.back-link svg {
|
|
164
|
+
width: 20px;
|
|
165
|
+
height: 20px;
|
|
166
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type BuildConfig, type Server } from "bun";
|
|
2
|
+
import { type FileChangeInfo } from "fs/promises";
|
|
3
|
+
import pqueue from "p-queue";
|
|
4
|
+
import { type BunDevServerConfig } from "./bunServeConfig";
|
|
5
|
+
/**
|
|
6
|
+
* Create a throttled build queue to prevent excessive rebuilds
|
|
7
|
+
* @param serverConfig - The server configuration
|
|
8
|
+
* @returns A p-queue instance configured for throttled builds
|
|
9
|
+
*/
|
|
10
|
+
export declare function getThrottledBuildQueue(serverConfig: BunDevServerConfig): pqueue;
|
|
11
|
+
/**
|
|
12
|
+
* Build and notify clients about the build result
|
|
13
|
+
* @param importerMeta - The ImportMeta object from the caller
|
|
14
|
+
* @param finalConfig - The final server configuration
|
|
15
|
+
* @param destinationPath - The absolute path to the output directory
|
|
16
|
+
* @param buildCfg - The build configuration
|
|
17
|
+
* @param bunServer - The Bun server instance
|
|
18
|
+
* @param event - The file change event that triggered the build
|
|
19
|
+
*/
|
|
20
|
+
export declare function cleanBuildAndNotify(importerMeta: ImportMeta, finalConfig: BunDevServerConfig, destinationPath: string, buildCfg: BuildConfig, bunServer: Server<any>, event: FileChangeInfo<string>): Promise<void>;
|
package/dist/bunClientHmr.d.ts
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration management and validation
|
|
3
|
+
*/
|
|
4
|
+
import { type BuildConfig } from "bun";
|
|
5
|
+
import { type BunDevServerConfig } from "./bunServeConfig";
|
|
6
|
+
export interface PreparedConfig {
|
|
7
|
+
finalConfig: BunDevServerConfig;
|
|
8
|
+
destinationPath: string;
|
|
9
|
+
srcWatch: string;
|
|
10
|
+
buildCfg: BuildConfig;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Prepare and validate the server configuration
|
|
14
|
+
* @param serverConfig - The user-provided server configuration
|
|
15
|
+
* @param importMeta - The ImportMeta object from the caller
|
|
16
|
+
* @returns The prepared configuration with resolved paths and build config
|
|
17
|
+
*/
|
|
18
|
+
export declare function prepareConfiguration(serverConfig: BunDevServerConfig, importMeta: ImportMeta): Promise<PreparedConfig>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type BuildConfig, type Server } from "bun";
|
|
2
|
+
import { type BunDevServerConfig } from "./bunServeConfig";
|
|
3
|
+
/**
|
|
4
|
+
* Start watching a directory for changes and trigger builds
|
|
5
|
+
* @param srcWatch - The absolute path to watch for changes
|
|
6
|
+
* @param importMeta - The ImportMeta object from the caller
|
|
7
|
+
* @param finalConfig - The final server configuration
|
|
8
|
+
* @param destinationPath - The absolute path to the output directory
|
|
9
|
+
* @param buildCfg - The build configuration
|
|
10
|
+
* @param bunServer - The Bun server instance
|
|
11
|
+
*/
|
|
12
|
+
export declare function startFileWatcher(srcWatch: string, importMeta: ImportMeta, finalConfig: BunDevServerConfig, destinationPath: string, buildCfg: BuildConfig, bunServer: Server<any>): Promise<void>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type BunDevServerConfig } from "./bunServeConfig";
|
|
2
|
+
/**
|
|
3
|
+
* Handle HTTP error responses
|
|
4
|
+
* @param req - The Request object
|
|
5
|
+
* @param err - The error that occurred
|
|
6
|
+
* @returns A Response with status 500
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleErrorResponse(req: Request, err: unknown): Response;
|
|
9
|
+
/**
|
|
10
|
+
* Handle a path request to the server
|
|
11
|
+
* @param requestPath - The request path
|
|
12
|
+
* @param req - The Request object
|
|
13
|
+
* @param finalConfig - The final server configuration
|
|
14
|
+
* @param destinationPath - The absolute path to the output directory
|
|
15
|
+
* @returns A Response object
|
|
16
|
+
*/
|
|
17
|
+
export declare function handlePathRequest(requestPath: string, req: Request, finalConfig: BunDevServerConfig, destinationPath: string): Promise<Response>;
|