@t8/serve 0.1.29 → 0.1.31
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/LICENSE +21 -0
- package/README.md +2 -1
- package/dist/index.js +22 -5
- package/dist/run.cjs +28 -5
- package/dist/run.mjs +29 -6
- package/package.json +3 -3
- package/src/Config.ts +2 -0
- package/src/bundle.ts +20 -4
- package/src/run.ts +7 -0
- package/src/serve.ts +9 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Alexander Tkačenko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Simple static file server + bundler, primarily for demo apps and tests, manual or automated
|
|
4
4
|
|
|
5
|
-
Use cases
|
|
5
|
+
## Use cases
|
|
6
|
+
|
|
6
7
|
- Use the CLI-based server to launch a demo or test app with a single CLI command.
|
|
7
8
|
- Use the code-based setup to launch an own server from multiple tests, each with its own app.
|
|
8
9
|
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,12 @@ import { extname } from "node:path";
|
|
|
6
6
|
// src/bundle.ts
|
|
7
7
|
import { rm } from "node:fs/promises";
|
|
8
8
|
import { join } from "node:path";
|
|
9
|
-
import { build } from "esbuild";
|
|
10
|
-
async function bundle({
|
|
9
|
+
import { build, context } from "esbuild";
|
|
10
|
+
async function bundle({
|
|
11
|
+
path = "",
|
|
12
|
+
bundle: options,
|
|
13
|
+
watch
|
|
14
|
+
} = {}) {
|
|
11
15
|
if (!options) return;
|
|
12
16
|
let normalizedOptions;
|
|
13
17
|
if (typeof options === "boolean") normalizedOptions = {};
|
|
@@ -20,13 +24,21 @@ async function bundle({ path = "", bundle: options } = {}) {
|
|
|
20
24
|
let inputFile = join(path, normalizedOptions.input ?? "index.ts");
|
|
21
25
|
let outputFile = join(path, dir, normalizedOptions.output ?? "index.js");
|
|
22
26
|
await rm(join(path, dir), { recursive: true, force: true });
|
|
23
|
-
|
|
27
|
+
let buildOptions = {
|
|
24
28
|
entryPoints: [inputFile],
|
|
25
29
|
outfile: outputFile,
|
|
26
30
|
bundle: true,
|
|
27
31
|
platform: "browser",
|
|
28
32
|
logLevel: "warning"
|
|
29
|
-
}
|
|
33
|
+
};
|
|
34
|
+
if (watch) {
|
|
35
|
+
let ctx = await context(buildOptions);
|
|
36
|
+
await ctx.watch();
|
|
37
|
+
return async () => {
|
|
38
|
+
await ctx.dispose();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
await build(buildOptions);
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
// src/getFilePath.ts
|
|
@@ -91,7 +103,7 @@ var mimeTypes = {
|
|
|
91
103
|
|
|
92
104
|
// src/serve.ts
|
|
93
105
|
async function serve(config = {}) {
|
|
94
|
-
await bundle(config);
|
|
106
|
+
let stop = await bundle(config);
|
|
95
107
|
return new Promise((resolve) => {
|
|
96
108
|
let server = createServer(async (req, res) => {
|
|
97
109
|
await config.onRequest?.(req, res);
|
|
@@ -107,6 +119,11 @@ async function serve(config = {}) {
|
|
|
107
119
|
res.writeHead(200, { "content-type": mimeType });
|
|
108
120
|
createReadStream(filePath).pipe(res);
|
|
109
121
|
});
|
|
122
|
+
if (stop) {
|
|
123
|
+
server.on("close", async () => {
|
|
124
|
+
await stop();
|
|
125
|
+
});
|
|
126
|
+
}
|
|
110
127
|
let { host, port } = getTarget(config);
|
|
111
128
|
server.listen(port, host, () => {
|
|
112
129
|
if (config.log) console.log(`Server running at http://${host}:${port}`);
|
package/dist/run.cjs
CHANGED
|
@@ -10,7 +10,11 @@ var import_node_path3 = require("node:path");
|
|
|
10
10
|
var import_promises = require("node:fs/promises");
|
|
11
11
|
var import_node_path = require("node:path");
|
|
12
12
|
var import_esbuild = require("esbuild");
|
|
13
|
-
async function bundle({
|
|
13
|
+
async function bundle({
|
|
14
|
+
path = "",
|
|
15
|
+
bundle: options,
|
|
16
|
+
watch
|
|
17
|
+
} = {}) {
|
|
14
18
|
if (!options) return;
|
|
15
19
|
let normalizedOptions;
|
|
16
20
|
if (typeof options === "boolean") normalizedOptions = {};
|
|
@@ -23,13 +27,21 @@ async function bundle({ path = "", bundle: options } = {}) {
|
|
|
23
27
|
let inputFile = (0, import_node_path.join)(path, normalizedOptions.input ?? "index.ts");
|
|
24
28
|
let outputFile = (0, import_node_path.join)(path, dir, normalizedOptions.output ?? "index.js");
|
|
25
29
|
await (0, import_promises.rm)((0, import_node_path.join)(path, dir), { recursive: true, force: true });
|
|
26
|
-
|
|
30
|
+
let buildOptions = {
|
|
27
31
|
entryPoints: [inputFile],
|
|
28
32
|
outfile: outputFile,
|
|
29
33
|
bundle: true,
|
|
30
34
|
platform: "browser",
|
|
31
35
|
logLevel: "warning"
|
|
32
|
-
}
|
|
36
|
+
};
|
|
37
|
+
if (watch) {
|
|
38
|
+
let ctx = await (0, import_esbuild.context)(buildOptions);
|
|
39
|
+
await ctx.watch();
|
|
40
|
+
return async () => {
|
|
41
|
+
await ctx.dispose();
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
await (0, import_esbuild.build)(buildOptions);
|
|
33
45
|
}
|
|
34
46
|
|
|
35
47
|
// src/getFilePath.ts
|
|
@@ -94,7 +106,7 @@ var mimeTypes = {
|
|
|
94
106
|
|
|
95
107
|
// src/serve.ts
|
|
96
108
|
async function serve(config = {}) {
|
|
97
|
-
await bundle(config);
|
|
109
|
+
let stop = await bundle(config);
|
|
98
110
|
return new Promise((resolve) => {
|
|
99
111
|
let server = (0, import_node_http.createServer)(async (req, res) => {
|
|
100
112
|
await config.onRequest?.(req, res);
|
|
@@ -110,6 +122,11 @@ async function serve(config = {}) {
|
|
|
110
122
|
res.writeHead(200, { "content-type": mimeType });
|
|
111
123
|
(0, import_node_fs.createReadStream)(filePath).pipe(res);
|
|
112
124
|
});
|
|
125
|
+
if (stop) {
|
|
126
|
+
server.on("close", async () => {
|
|
127
|
+
await stop();
|
|
128
|
+
});
|
|
129
|
+
}
|
|
113
130
|
let { host, port } = getTarget(config);
|
|
114
131
|
server.listen(port, host, () => {
|
|
115
132
|
if (config.log) console.log(`Server running at http://${host}:${port}`);
|
|
@@ -122,10 +139,15 @@ async function serve(config = {}) {
|
|
|
122
139
|
async function run() {
|
|
123
140
|
let [url, ...args] = process.argv.slice(2);
|
|
124
141
|
let spa = false;
|
|
142
|
+
let watch = false;
|
|
125
143
|
if (args[0] === "*") {
|
|
126
144
|
spa = true;
|
|
127
145
|
args.shift();
|
|
128
146
|
}
|
|
147
|
+
if (args.at(-1) === "--watch") {
|
|
148
|
+
watch = true;
|
|
149
|
+
args.pop();
|
|
150
|
+
}
|
|
129
151
|
let bundleFlagIndex = args.indexOf("-b");
|
|
130
152
|
let path = args[0];
|
|
131
153
|
let dirs;
|
|
@@ -145,7 +167,8 @@ async function run() {
|
|
|
145
167
|
dirs,
|
|
146
168
|
spa,
|
|
147
169
|
bundle: bundle2,
|
|
148
|
-
log: true
|
|
170
|
+
log: true,
|
|
171
|
+
watch
|
|
149
172
|
});
|
|
150
173
|
}
|
|
151
174
|
run();
|
package/dist/run.mjs
CHANGED
|
@@ -8,8 +8,12 @@ import { extname } from "node:path";
|
|
|
8
8
|
// src/bundle.ts
|
|
9
9
|
import { rm } from "node:fs/promises";
|
|
10
10
|
import { join } from "node:path";
|
|
11
|
-
import { build } from "esbuild";
|
|
12
|
-
async function bundle({
|
|
11
|
+
import { build, context } from "esbuild";
|
|
12
|
+
async function bundle({
|
|
13
|
+
path = "",
|
|
14
|
+
bundle: options,
|
|
15
|
+
watch
|
|
16
|
+
} = {}) {
|
|
13
17
|
if (!options) return;
|
|
14
18
|
let normalizedOptions;
|
|
15
19
|
if (typeof options === "boolean") normalizedOptions = {};
|
|
@@ -22,13 +26,21 @@ async function bundle({ path = "", bundle: options } = {}) {
|
|
|
22
26
|
let inputFile = join(path, normalizedOptions.input ?? "index.ts");
|
|
23
27
|
let outputFile = join(path, dir, normalizedOptions.output ?? "index.js");
|
|
24
28
|
await rm(join(path, dir), { recursive: true, force: true });
|
|
25
|
-
|
|
29
|
+
let buildOptions = {
|
|
26
30
|
entryPoints: [inputFile],
|
|
27
31
|
outfile: outputFile,
|
|
28
32
|
bundle: true,
|
|
29
33
|
platform: "browser",
|
|
30
34
|
logLevel: "warning"
|
|
31
|
-
}
|
|
35
|
+
};
|
|
36
|
+
if (watch) {
|
|
37
|
+
let ctx = await context(buildOptions);
|
|
38
|
+
await ctx.watch();
|
|
39
|
+
return async () => {
|
|
40
|
+
await ctx.dispose();
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
await build(buildOptions);
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
// src/getFilePath.ts
|
|
@@ -93,7 +105,7 @@ var mimeTypes = {
|
|
|
93
105
|
|
|
94
106
|
// src/serve.ts
|
|
95
107
|
async function serve(config = {}) {
|
|
96
|
-
await bundle(config);
|
|
108
|
+
let stop = await bundle(config);
|
|
97
109
|
return new Promise((resolve) => {
|
|
98
110
|
let server = createServer(async (req, res) => {
|
|
99
111
|
await config.onRequest?.(req, res);
|
|
@@ -109,6 +121,11 @@ async function serve(config = {}) {
|
|
|
109
121
|
res.writeHead(200, { "content-type": mimeType });
|
|
110
122
|
createReadStream(filePath).pipe(res);
|
|
111
123
|
});
|
|
124
|
+
if (stop) {
|
|
125
|
+
server.on("close", async () => {
|
|
126
|
+
await stop();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
112
129
|
let { host, port } = getTarget(config);
|
|
113
130
|
server.listen(port, host, () => {
|
|
114
131
|
if (config.log) console.log(`Server running at http://${host}:${port}`);
|
|
@@ -121,10 +138,15 @@ async function serve(config = {}) {
|
|
|
121
138
|
async function run() {
|
|
122
139
|
let [url, ...args] = process.argv.slice(2);
|
|
123
140
|
let spa = false;
|
|
141
|
+
let watch = false;
|
|
124
142
|
if (args[0] === "*") {
|
|
125
143
|
spa = true;
|
|
126
144
|
args.shift();
|
|
127
145
|
}
|
|
146
|
+
if (args.at(-1) === "--watch") {
|
|
147
|
+
watch = true;
|
|
148
|
+
args.pop();
|
|
149
|
+
}
|
|
128
150
|
let bundleFlagIndex = args.indexOf("-b");
|
|
129
151
|
let path = args[0];
|
|
130
152
|
let dirs;
|
|
@@ -144,7 +166,8 @@ async function run() {
|
|
|
144
166
|
dirs,
|
|
145
167
|
spa,
|
|
146
168
|
bundle: bundle2,
|
|
147
|
-
log: true
|
|
169
|
+
log: true,
|
|
170
|
+
watch
|
|
148
171
|
});
|
|
149
172
|
}
|
|
150
173
|
run();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t8/serve",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Simple static file server + bundler, primarily for demo apps and tests, manual or automated",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git+https://github.com/t8js/serve.git"
|
|
16
16
|
},
|
|
17
|
-
"license": "
|
|
17
|
+
"license": "MIT",
|
|
18
18
|
"author": "axtk",
|
|
19
19
|
"type": "module",
|
|
20
20
|
"main": "dist/index.js",
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
"typescript": "^5.9.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"esbuild": "^0.25.
|
|
37
|
+
"esbuild": "^0.25.11"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/Config.ts
CHANGED
package/src/bundle.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { rm } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { build } from "esbuild";
|
|
3
|
+
import { type BuildOptions, build, context } from "esbuild";
|
|
4
4
|
import type { BundleConfig } from "./BundleConfig";
|
|
5
5
|
import type { Config } from "./Config";
|
|
6
6
|
|
|
7
|
-
export async function bundle({
|
|
7
|
+
export async function bundle({
|
|
8
|
+
path = "",
|
|
9
|
+
bundle: options,
|
|
10
|
+
watch,
|
|
11
|
+
}: Config = {}) {
|
|
8
12
|
if (!options) return;
|
|
9
13
|
|
|
10
14
|
let normalizedOptions: BundleConfig;
|
|
@@ -22,11 +26,23 @@ export async function bundle({ path = "", bundle: options }: Config = {}) {
|
|
|
22
26
|
|
|
23
27
|
await rm(join(path, dir), { recursive: true, force: true });
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
let buildOptions: BuildOptions = {
|
|
26
30
|
entryPoints: [inputFile],
|
|
27
31
|
outfile: outputFile,
|
|
28
32
|
bundle: true,
|
|
29
33
|
platform: "browser",
|
|
30
34
|
logLevel: "warning",
|
|
31
|
-
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (watch) {
|
|
38
|
+
let ctx = await context(buildOptions);
|
|
39
|
+
|
|
40
|
+
await ctx.watch();
|
|
41
|
+
|
|
42
|
+
return async () => {
|
|
43
|
+
await ctx.dispose();
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
await build(buildOptions);
|
|
32
48
|
}
|
package/src/run.ts
CHANGED
|
@@ -5,12 +5,18 @@ import { serve } from "./serve";
|
|
|
5
5
|
async function run() {
|
|
6
6
|
let [url, ...args] = process.argv.slice(2);
|
|
7
7
|
let spa = false;
|
|
8
|
+
let watch = false;
|
|
8
9
|
|
|
9
10
|
if (args[0] === "*") {
|
|
10
11
|
spa = true;
|
|
11
12
|
args.shift();
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
if (args.at(-1) === "--watch") {
|
|
16
|
+
watch = true;
|
|
17
|
+
args.pop();
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
let bundleFlagIndex = args.indexOf("-b");
|
|
15
21
|
let path = args[0];
|
|
16
22
|
|
|
@@ -34,6 +40,7 @@ async function run() {
|
|
|
34
40
|
spa,
|
|
35
41
|
bundle,
|
|
36
42
|
log: true,
|
|
43
|
+
watch,
|
|
37
44
|
});
|
|
38
45
|
}
|
|
39
46
|
|
package/src/serve.ts
CHANGED
|
@@ -9,10 +9,10 @@ import { mimeTypes } from "./mimeTypes";
|
|
|
9
9
|
|
|
10
10
|
export type Server = ReturnType<typeof createServer>;
|
|
11
11
|
|
|
12
|
-
export async function serve(config: Config = {})
|
|
13
|
-
await bundle(config);
|
|
12
|
+
export async function serve(config: Config = {}) {
|
|
13
|
+
let stop = await bundle(config);
|
|
14
14
|
|
|
15
|
-
return new Promise((resolve) => {
|
|
15
|
+
return new Promise<Server>((resolve) => {
|
|
16
16
|
let server = createServer(async (req, res) => {
|
|
17
17
|
await config.onRequest?.(req, res);
|
|
18
18
|
|
|
@@ -33,6 +33,12 @@ export async function serve(config: Config = {}): Promise<Server> {
|
|
|
33
33
|
createReadStream(filePath).pipe(res);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
+
if (stop) {
|
|
37
|
+
server.on("close", async () => {
|
|
38
|
+
await stop();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
let { host, port } = getTarget(config);
|
|
37
43
|
|
|
38
44
|
server.listen(port, host, () => {
|