spooder 2.0.8 → 3.0.0
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 +48 -18
- package/bun.lockb +0 -0
- package/package.json +4 -8
- package/src/api.d.ts +1 -0
- package/src/api.ts +3 -0
- package/src/cli.d.ts +0 -0
- package/src/cli.ts +1 -0
- package/src/heartbeat.d.ts +0 -1
- package/src/heartbeat.ts +0 -6
- package/src/instance.d.ts +0 -2
- package/src/instance.ts +0 -23
- package/src/update.d.ts +0 -2
- package/src/update.ts +0 -93
package/README.md
CHANGED
|
@@ -8,33 +8,63 @@
|
|
|
8
8
|
|
|
9
9
|
> **Warning** - This project is developed for [Bun](https://bun.sh/), which at the time of writing is still experimental. It is not recommended to use this project in production environments unless you understand the risks.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Installation
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```bash
|
|
14
|
+
bun add spooder --global
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Runner
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
`spooder` also includes a global command-line tool for running the server. It is recommended that you run this in a `screen` session.
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
```bash
|
|
22
|
+
screen -S spooder # Create a new screen session
|
|
23
|
+
cd /var/www/my_server/
|
|
24
|
+
spooder
|
|
25
|
+
```
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
`spooder` will load the `module` defined in your `package.json` in a new process using `bun run <module>`. This can be overridden using the `entry` property of the `spooder section` in your `package.json`.
|
|
20
28
|
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"spooder": {
|
|
32
|
+
"entry": "index.ts"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
27
35
|
```
|
|
28
36
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
In the event that the server exits (regardless of exit code), `spooder` will automatically restart it after a short delay. This delay is configurable in the `spooder` section of your `package.json`.
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"spooder": {
|
|
42
|
+
"autoRestart": true, // Defaults to true.
|
|
43
|
+
"restartDelay": 5000, // Defaults to 5000ms.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
32
46
|
```
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
When starting your server, `spooder` can automatically update the source code by running `git pull` in the working directory. This feature is disabled by default and can be enabled in the `spooder` section of your `package.json`.
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"spooder": {
|
|
53
|
+
"autoUpdate": true // Defaults to false.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
When `autoUpdate` is enabled, your server process can initiate a self-update by terminating with the exit code `205`. This will cause `spooder` to run `git pull` and restart the server, which can be useful for responding to webhooks.
|
|
59
|
+
|
|
60
|
+
If `autoUpdate` is disabled, all exit codes will be considered a crash and the server will be restarted if `autoRestart` is enabled.
|
|
61
|
+
|
|
62
|
+
## API
|
|
63
|
+
|
|
64
|
+
`spooder` exposes a simple API which can be imported into your project for bootstrapping a server in Bun. The API is designed to be minimal to leave control in the hands of the developer and not add overhead for features you may not need.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import serve from 'spooder'; // WIP
|
|
38
68
|
```
|
|
39
69
|
|
|
40
70
|
## License
|
package/bun.lockb
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spooder",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"spooder": "./src/instance.ts",
|
|
7
|
-
"spooder-update": "./src/update.ts",
|
|
8
|
-
"spooder-heartbeat": "./src/heartbeat.ts"
|
|
9
|
-
},
|
|
4
|
+
"module": "./src/api.ts",
|
|
5
|
+
"version": "3.0.0",
|
|
10
6
|
"devDependencies": {
|
|
11
7
|
"@types/node": "^20.0.0",
|
|
12
8
|
"bun-types": "^0.5.0"
|
|
13
9
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
10
|
+
"bin": {
|
|
11
|
+
"spooder": "./src/cli.ts"
|
|
16
12
|
}
|
|
17
13
|
}
|
package/src/api.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function test_api(): void;
|
package/src/api.ts
ADDED
package/src/cli.d.ts
ADDED
|
File without changes
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('Welcome to the Spooder CLI!');
|
package/src/heartbeat.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
package/src/heartbeat.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
// TODO: Iterate over all directories in /var/www and identify which ones are spooder domains.
|
|
4
|
-
// TODO: For each spooder domain, check if the process is running.
|
|
5
|
-
// TODO: Run `spooder` inside any domain directory that is not running.
|
|
6
|
-
// TODO: Report crashed domains somewhere/somehow?
|
package/src/instance.d.ts
DELETED
package/src/instance.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
|
|
5
|
-
async function write_pid_file() {
|
|
6
|
-
const pid_file = join(process.cwd(), '.spooder_pid');
|
|
7
|
-
await Bun.write(pid_file, process.pid.toString());
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
async function main() {
|
|
11
|
-
await write_pid_file();
|
|
12
|
-
|
|
13
|
-
const index_file = join(process.cwd(), 'index.ts');
|
|
14
|
-
// TODO: Add error handling if index_file does not exist?
|
|
15
|
-
|
|
16
|
-
const module = await import(index_file);
|
|
17
|
-
console.log(module);
|
|
18
|
-
// TODO: Add a route for GitHub webhooks.
|
|
19
|
-
// TODO: Add authentication for the webhook to prevent abuse.
|
|
20
|
-
// TODO: Run `spooder-update` when the webhook is triggered, then self-terminate.
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
main();
|
package/src/update.d.ts
DELETED
package/src/update.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
|
|
6
|
-
const ConfigSchema = z.object({
|
|
7
|
-
domain: z.object({
|
|
8
|
-
name: z.string(),
|
|
9
|
-
port: z.number()
|
|
10
|
-
}),
|
|
11
|
-
|
|
12
|
-
git: z.object({
|
|
13
|
-
url: z.string(),
|
|
14
|
-
branch: z.string().default('main')
|
|
15
|
-
}).optional()
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
async function get_last_pid() : Promise<number> {
|
|
19
|
-
const pid_file = Bun.file(join(process.cwd(), '.spooder_pid'));
|
|
20
|
-
if (pid_file.size > 0) {
|
|
21
|
-
const pid = parseInt(await pid_file.text());
|
|
22
|
-
if (!isNaN(pid))
|
|
23
|
-
return pid;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return -1;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function pid_is_running(pid: number) : Promise<boolean> {
|
|
30
|
-
const process = Bun.spawnSync(['ps', '-p', pid.toString()]);
|
|
31
|
-
if (!process.success)
|
|
32
|
-
return false;
|
|
33
|
-
|
|
34
|
-
const stdout = process.stdout?.toString();
|
|
35
|
-
|
|
36
|
-
// Ensure stdout contains more than one line.
|
|
37
|
-
if (!stdout || stdout.split('\n').length <= 1)
|
|
38
|
-
return false;
|
|
39
|
-
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function wait_for_pid_to_exit(pid: number) : Promise<void> {
|
|
44
|
-
console.log(`Waiting for process ${pid} to exit...`);
|
|
45
|
-
while (await pid_is_running(pid))
|
|
46
|
-
await Bun.sleep(1000);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function is_git_repository(directory: string): boolean {
|
|
50
|
-
// The command `git rev-parse --is-inside-work-tree` returns `true` to stdout
|
|
51
|
-
// if the current working directory is inside a git repository.
|
|
52
|
-
const process = Bun.spawnSync(['git', 'rev-parse', '--is-inside-work-tree'], { cwd: directory });
|
|
53
|
-
return process.stdout?.toString().trim() === 'true';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function pull_git_repository(directory: string, url: string, branch: string) {
|
|
57
|
-
console.log(`Pulling git repository ${branch} @ ${url} into ${directory}...`);
|
|
58
|
-
const process = Bun.spawnSync(['git', 'pull', url, branch], { cwd: directory });
|
|
59
|
-
if (!process.success)
|
|
60
|
-
throw new Error('Failed to pull git repository.');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function init_git_repository(directory: string) {
|
|
64
|
-
console.log(`Initializing git repository in ${directory}...`);
|
|
65
|
-
const process = Bun.spawnSync(['git', 'init'], { cwd: directory });
|
|
66
|
-
if (!process.success)
|
|
67
|
-
throw new Error('Failed to initialize git repository.');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function load_configuration() {
|
|
71
|
-
const config_file = join(process.cwd(), 'spooder.toml');
|
|
72
|
-
return ConfigSchema.parse(await import(config_file));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function main() {
|
|
76
|
-
const config = await load_configuration();
|
|
77
|
-
|
|
78
|
-
// Wait for the previous process, if it exists, to exit.
|
|
79
|
-
await wait_for_pid_to_exit(await get_last_pid());
|
|
80
|
-
|
|
81
|
-
const cwd = process.cwd();
|
|
82
|
-
if (config.git) {
|
|
83
|
-
if (!is_git_repository(cwd))
|
|
84
|
-
init_git_repository(cwd);
|
|
85
|
-
|
|
86
|
-
pull_git_repository(cwd, config.git.url, config.git.branch);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const server = Bun.spawn(['spooder'], { cwd });
|
|
90
|
-
server.unref();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
main();
|