spooder 3.0.0 → 3.0.2
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/README.md +39 -10
- package/package.json +8 -2
- package/src/cli.d.ts +1 -0
- package/src/cli.ts +98 -1
- package/bun.lockb +0 -0
- package/docs/project-logo.png +0 -0
package/README.md
CHANGED
|
@@ -11,12 +11,16 @@
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
+
# Installing globally for CLI runner usage.
|
|
14
15
|
bun add spooder --global
|
|
16
|
+
|
|
17
|
+
# Install into local package for API usage.
|
|
18
|
+
bun add spooder
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
## Runner
|
|
18
22
|
|
|
19
|
-
`spooder`
|
|
23
|
+
`spooder` includes a global command-line tool for running servers. It is recommended that you run this in a `screen` session.
|
|
20
24
|
|
|
21
25
|
```bash
|
|
22
26
|
screen -S spooder # Create a new screen session
|
|
@@ -24,40 +28,65 @@ cd /var/www/my_server/
|
|
|
24
28
|
spooder
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
While the intended use of this runner is for web servers, it can be used to run anything. It provides two primary features: automatic updating and restarting.
|
|
32
|
+
|
|
33
|
+
### Entry Point
|
|
34
|
+
|
|
35
|
+
`spooder` will attempt to launch the server from the current working directory using the command `bun run index.ts` as a default.
|
|
36
|
+
|
|
37
|
+
To customize this, provide an alternative command via the `run` configuration.
|
|
28
38
|
|
|
29
39
|
```json
|
|
30
40
|
{
|
|
31
41
|
"spooder": {
|
|
32
|
-
"
|
|
42
|
+
"run": "bun run my_server.ts"
|
|
33
43
|
}
|
|
34
44
|
}
|
|
35
45
|
```
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
While `spooder` uses a `bun run` command by default, it is possible to use any command string.
|
|
48
|
+
|
|
49
|
+
It is possible to chain commands, such as updating your source with `git pull && bun run index.ts`, however it is recommended that `run` is only used to launch the service. Instead, use the `update` property for updating which will fail gracefully and will not block the server from starting.
|
|
50
|
+
|
|
51
|
+
### Auto Restart
|
|
52
|
+
|
|
53
|
+
In the event that the server exits (regardless of exit code), `spooder` will automatically restart it after a short delay.
|
|
54
|
+
|
|
55
|
+
This feature is enabled by default with a delay of `5000` milliseconds. The delay can be changed by providing a value for `autoRestart` in the configuration.
|
|
38
56
|
|
|
39
57
|
```json
|
|
40
58
|
{
|
|
41
59
|
"spooder": {
|
|
42
|
-
"autoRestart":
|
|
43
|
-
"restartDelay": 5000, // Defaults to 5000ms.
|
|
60
|
+
"autoRestart": 5000
|
|
44
61
|
}
|
|
45
62
|
}
|
|
46
63
|
```
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
If set to `0`, the server will be restarted immediately without delay. If set to `-1`, the server will not be restarted at all.
|
|
66
|
+
|
|
67
|
+
### Auto Update
|
|
68
|
+
|
|
69
|
+
When starting your server, `spooder` can automatically update the source code in the working directory. To enable this feature, provide an update command as `update` in the configuration.
|
|
49
70
|
|
|
50
71
|
```json
|
|
51
72
|
{
|
|
52
73
|
"spooder": {
|
|
53
|
-
"
|
|
74
|
+
"update": "git pull && bun install"
|
|
54
75
|
}
|
|
55
76
|
}
|
|
56
77
|
```
|
|
78
|
+
It is worth nothing that if the `update` command fails to execute, the server will still be started. This is preferred over entering a restart loop or failing to start the server at all.
|
|
57
79
|
|
|
58
|
-
|
|
80
|
+
As well as being executed when the server is first started, the `update` command is also run when `spooder` automatically restarts the server after it exits.
|
|
59
81
|
|
|
60
|
-
|
|
82
|
+
You can utilize this to automatically update your server in response to a webhook or other event by simply exiting the process.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
events.on('receive-webhook', () => {
|
|
86
|
+
// <- Gracefully finish processing here.
|
|
87
|
+
process.exit(0);
|
|
88
|
+
});
|
|
89
|
+
```
|
|
61
90
|
|
|
62
91
|
## API
|
|
63
92
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spooder",
|
|
3
3
|
"type": "module",
|
|
4
|
+
"version": "3.0.2",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"bun": "./src/api.ts",
|
|
8
|
+
"import": "./src/api.ts"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
4
11
|
"module": "./src/api.ts",
|
|
5
|
-
"version": "3.0.0",
|
|
6
12
|
"devDependencies": {
|
|
7
13
|
"@types/node": "^20.0.0",
|
|
8
14
|
"bun-types": "^0.5.0"
|
|
9
15
|
},
|
|
10
16
|
"bin": {
|
|
11
|
-
"spooder": "./src/cli.ts"
|
|
17
|
+
"spooder": "bun run ./src/cli.ts"
|
|
12
18
|
}
|
|
13
19
|
}
|
package/src/cli.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/src/cli.ts
CHANGED
|
@@ -1 +1,98 @@
|
|
|
1
|
-
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
type Config = Record<string, unknown>;
|
|
4
|
+
|
|
5
|
+
async function load_config(): Promise<Config> {
|
|
6
|
+
try {
|
|
7
|
+
const config_file = Bun.file(path.join(process.cwd(), 'package.json'));
|
|
8
|
+
const json = await config_file.json();
|
|
9
|
+
|
|
10
|
+
return json?.spooder ?? {};
|
|
11
|
+
} catch (e) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parse_command(command: string): string[] {
|
|
17
|
+
const args = [];
|
|
18
|
+
let current_arg = '';
|
|
19
|
+
let in_quotes = false;
|
|
20
|
+
let in_escape = false;
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < command.length; i++) {
|
|
23
|
+
const char = command[i];
|
|
24
|
+
|
|
25
|
+
if (in_escape) {
|
|
26
|
+
current_arg += char;
|
|
27
|
+
in_escape = false;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (char === '\\') {
|
|
32
|
+
in_escape = true;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (char === '"') {
|
|
37
|
+
in_quotes = !in_quotes;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (char === ' ' && !in_quotes) {
|
|
42
|
+
args.push(current_arg);
|
|
43
|
+
current_arg = '';
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
current_arg += char;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (current_arg.length > 0)
|
|
51
|
+
args.push(current_arg);
|
|
52
|
+
|
|
53
|
+
return args;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function log(message: string, ...args: unknown[]): void {
|
|
57
|
+
console.log('[spooder] ' + message, ...args);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const config = await load_config();
|
|
61
|
+
const config_update_command = config.update as string ?? '';
|
|
62
|
+
const config_run_command = config.run as string ?? 'bun run index.ts';
|
|
63
|
+
const config_auto_restart_ms = config.autoRestart as number ?? 5000;
|
|
64
|
+
|
|
65
|
+
async function start_server() {
|
|
66
|
+
log('start_server');
|
|
67
|
+
|
|
68
|
+
if (config_update_command.length > 0) {
|
|
69
|
+
log('running update command: %s', config_update_command);
|
|
70
|
+
const update = Bun.spawn(parse_command(config_update_command), {
|
|
71
|
+
cwd: process.cwd(),
|
|
72
|
+
stdout: 'inherit',
|
|
73
|
+
stderr: 'inherit'
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await update.exited;
|
|
77
|
+
log('auto update exited with code %d', update.exitCode)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const server_process = Bun.spawn(parse_command(config_run_command), {
|
|
81
|
+
cwd: process.cwd(),
|
|
82
|
+
stdout: 'inherit',
|
|
83
|
+
stderr: 'inherit'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
log('server process started with pid %d', server_process.pid);
|
|
87
|
+
|
|
88
|
+
server_process.exited.then(() => {
|
|
89
|
+
log('server exited with code %d', server_process.exitCode);
|
|
90
|
+
|
|
91
|
+
if (config_auto_restart_ms > -1) {
|
|
92
|
+
log('restarting server in %dms', config_auto_restart_ms);
|
|
93
|
+
setTimeout(start_server, config_auto_restart_ms);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
start_server();
|
package/bun.lockb
DELETED
|
Binary file
|
package/docs/project-logo.png
DELETED
|
Binary file
|