@astroscope/boot 0.1.1 → 0.1.3
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 +3 -1
- package/dist/index.cjs +84 -7
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +84 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @astroscope/boot
|
|
2
2
|
|
|
3
|
+
> **Note:** This package is in active development. APIs may change between versions.
|
|
4
|
+
|
|
3
5
|
Startup and graceful shutdown hooks for Astro SSR. Run initialization code before the server starts and cleanup code when it shuts down.
|
|
4
6
|
|
|
5
7
|
## Examples
|
|
@@ -83,7 +85,7 @@ boot({ entry: "src/startup.ts" });
|
|
|
83
85
|
|
|
84
86
|
### `hmr`
|
|
85
87
|
|
|
86
|
-
Re-run `onStartup` when the boot file changes during development. This is disabled by default to avoid side effects, because `onStartup` may perform operations that should only run once (e.g., database connections).
|
|
88
|
+
Re-run `onStartup` when the boot file changes during development. This is disabled by default to avoid side effects, because `onStartup` may perform operations that should only run once (e.g., database connections). Please ensure your `onShutdown` function destroys any resources created by `onStartup` to prevent leaks / unexpected behavior.
|
|
87
89
|
|
|
88
90
|
- **Type**: `boolean`
|
|
89
91
|
- **Default**: `false`
|
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,51 @@ __export(index_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
37
37
|
var import_node_path = __toESM(require("path"), 1);
|
|
38
|
+
|
|
39
|
+
// src/ignored.ts
|
|
40
|
+
var ignoredSuffixes = [
|
|
41
|
+
// type definitions
|
|
42
|
+
".d.ts",
|
|
43
|
+
".d.mts",
|
|
44
|
+
".d.cts",
|
|
45
|
+
// images
|
|
46
|
+
".png",
|
|
47
|
+
".jpg",
|
|
48
|
+
".jpeg",
|
|
49
|
+
".gif",
|
|
50
|
+
".svg",
|
|
51
|
+
".webp",
|
|
52
|
+
".avif",
|
|
53
|
+
".ico",
|
|
54
|
+
// fonts
|
|
55
|
+
".woff",
|
|
56
|
+
".woff2",
|
|
57
|
+
".ttf",
|
|
58
|
+
".otf",
|
|
59
|
+
".eot",
|
|
60
|
+
// other static assets
|
|
61
|
+
".pdf",
|
|
62
|
+
".mp3",
|
|
63
|
+
".mp4",
|
|
64
|
+
".webm",
|
|
65
|
+
".ogg",
|
|
66
|
+
".wav",
|
|
67
|
+
// data/config that boot typically doesn't import
|
|
68
|
+
".json",
|
|
69
|
+
".yaml",
|
|
70
|
+
".yml",
|
|
71
|
+
".toml",
|
|
72
|
+
".md",
|
|
73
|
+
".mdx",
|
|
74
|
+
".txt",
|
|
75
|
+
// styles (handled by Vite's CSS HMR)
|
|
76
|
+
".css",
|
|
77
|
+
".scss",
|
|
78
|
+
".sass",
|
|
79
|
+
".less"
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
// src/index.ts
|
|
38
83
|
function resolveEntry(entry) {
|
|
39
84
|
if (entry) return entry;
|
|
40
85
|
if (import_node_fs.default.existsSync("src/boot.ts")) return "src/boot.ts";
|
|
@@ -80,17 +125,49 @@ function boot(options = {}) {
|
|
|
80
125
|
}
|
|
81
126
|
});
|
|
82
127
|
if (hmr) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
128
|
+
const bootModuleId = `/${entry}`;
|
|
129
|
+
const bootFilePath = import_node_path.default.resolve(server.config.root, entry);
|
|
130
|
+
const getBootDependencies = () => {
|
|
131
|
+
const deps = /* @__PURE__ */ new Set();
|
|
132
|
+
const bootModules = server.moduleGraph.getModulesByFile(bootFilePath);
|
|
133
|
+
const bootModule = bootModules ? [...bootModules][0] : void 0;
|
|
134
|
+
if (!bootModule) return deps;
|
|
135
|
+
const collectDeps = (mod, visited = /* @__PURE__ */ new Set()) => {
|
|
136
|
+
if (!mod?.file || visited.has(mod.file)) return;
|
|
137
|
+
visited.add(mod.file);
|
|
138
|
+
deps.add(mod.file);
|
|
139
|
+
for (const imported of mod.importedModules) {
|
|
140
|
+
collectDeps(imported, visited);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
collectDeps(bootModule);
|
|
144
|
+
return deps;
|
|
145
|
+
};
|
|
146
|
+
const rerunBoot = async (changedFile) => {
|
|
147
|
+
logger.info(`boot dependency changed: ${changedFile}, rerunning hooks...`);
|
|
86
148
|
try {
|
|
149
|
+
const oldModule = await server.ssrLoadModule(bootModuleId);
|
|
150
|
+
if (oldModule.onShutdown) {
|
|
151
|
+
await oldModule.onShutdown();
|
|
152
|
+
}
|
|
87
153
|
server.moduleGraph.invalidateAll();
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
await
|
|
154
|
+
const newModule = await server.ssrLoadModule(bootModuleId);
|
|
155
|
+
if (newModule.onStartup) {
|
|
156
|
+
await newModule.onStartup();
|
|
91
157
|
}
|
|
92
158
|
} catch (error) {
|
|
93
|
-
logger.error(`Error
|
|
159
|
+
logger.error(`Error during boot HMR: ${error}`);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const shouldIgnore = (filePath) => {
|
|
163
|
+
const path2 = filePath.toLowerCase();
|
|
164
|
+
return ignoredSuffixes.some((suffix) => path2.endsWith(suffix));
|
|
165
|
+
};
|
|
166
|
+
server.watcher.on("change", async (changedPath) => {
|
|
167
|
+
if (shouldIgnore(changedPath)) return;
|
|
168
|
+
const bootDeps = getBootDependencies();
|
|
169
|
+
if (bootDeps.has(changedPath)) {
|
|
170
|
+
await rerunBoot(changedPath);
|
|
94
171
|
}
|
|
95
172
|
});
|
|
96
173
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,12 +5,12 @@ interface BootOptions {
|
|
|
5
5
|
* Path to the boot file relative to the project root.
|
|
6
6
|
* @default "src/boot.ts"
|
|
7
7
|
*/
|
|
8
|
-
entry?: string;
|
|
8
|
+
entry?: string | undefined;
|
|
9
9
|
/**
|
|
10
10
|
* Enable HMR for the boot file. When true, `onStartup` will re-run when the boot file changes.
|
|
11
11
|
* @default false
|
|
12
12
|
*/
|
|
13
|
-
hmr?: boolean;
|
|
13
|
+
hmr?: boolean | undefined;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Astro integration for application lifecycle hooks.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,12 +5,12 @@ interface BootOptions {
|
|
|
5
5
|
* Path to the boot file relative to the project root.
|
|
6
6
|
* @default "src/boot.ts"
|
|
7
7
|
*/
|
|
8
|
-
entry?: string;
|
|
8
|
+
entry?: string | undefined;
|
|
9
9
|
/**
|
|
10
10
|
* Enable HMR for the boot file. When true, `onStartup` will re-run when the boot file changes.
|
|
11
11
|
* @default false
|
|
12
12
|
*/
|
|
13
|
-
hmr?: boolean;
|
|
13
|
+
hmr?: boolean | undefined;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Astro integration for application lifecycle hooks.
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
+
|
|
5
|
+
// src/ignored.ts
|
|
6
|
+
var ignoredSuffixes = [
|
|
7
|
+
// type definitions
|
|
8
|
+
".d.ts",
|
|
9
|
+
".d.mts",
|
|
10
|
+
".d.cts",
|
|
11
|
+
// images
|
|
12
|
+
".png",
|
|
13
|
+
".jpg",
|
|
14
|
+
".jpeg",
|
|
15
|
+
".gif",
|
|
16
|
+
".svg",
|
|
17
|
+
".webp",
|
|
18
|
+
".avif",
|
|
19
|
+
".ico",
|
|
20
|
+
// fonts
|
|
21
|
+
".woff",
|
|
22
|
+
".woff2",
|
|
23
|
+
".ttf",
|
|
24
|
+
".otf",
|
|
25
|
+
".eot",
|
|
26
|
+
// other static assets
|
|
27
|
+
".pdf",
|
|
28
|
+
".mp3",
|
|
29
|
+
".mp4",
|
|
30
|
+
".webm",
|
|
31
|
+
".ogg",
|
|
32
|
+
".wav",
|
|
33
|
+
// data/config that boot typically doesn't import
|
|
34
|
+
".json",
|
|
35
|
+
".yaml",
|
|
36
|
+
".yml",
|
|
37
|
+
".toml",
|
|
38
|
+
".md",
|
|
39
|
+
".mdx",
|
|
40
|
+
".txt",
|
|
41
|
+
// styles (handled by Vite's CSS HMR)
|
|
42
|
+
".css",
|
|
43
|
+
".scss",
|
|
44
|
+
".sass",
|
|
45
|
+
".less"
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// src/index.ts
|
|
4
49
|
function resolveEntry(entry) {
|
|
5
50
|
if (entry) return entry;
|
|
6
51
|
if (fs.existsSync("src/boot.ts")) return "src/boot.ts";
|
|
@@ -46,17 +91,49 @@ function boot(options = {}) {
|
|
|
46
91
|
}
|
|
47
92
|
});
|
|
48
93
|
if (hmr) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
94
|
+
const bootModuleId = `/${entry}`;
|
|
95
|
+
const bootFilePath = path.resolve(server.config.root, entry);
|
|
96
|
+
const getBootDependencies = () => {
|
|
97
|
+
const deps = /* @__PURE__ */ new Set();
|
|
98
|
+
const bootModules = server.moduleGraph.getModulesByFile(bootFilePath);
|
|
99
|
+
const bootModule = bootModules ? [...bootModules][0] : void 0;
|
|
100
|
+
if (!bootModule) return deps;
|
|
101
|
+
const collectDeps = (mod, visited = /* @__PURE__ */ new Set()) => {
|
|
102
|
+
if (!mod?.file || visited.has(mod.file)) return;
|
|
103
|
+
visited.add(mod.file);
|
|
104
|
+
deps.add(mod.file);
|
|
105
|
+
for (const imported of mod.importedModules) {
|
|
106
|
+
collectDeps(imported, visited);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
collectDeps(bootModule);
|
|
110
|
+
return deps;
|
|
111
|
+
};
|
|
112
|
+
const rerunBoot = async (changedFile) => {
|
|
113
|
+
logger.info(`boot dependency changed: ${changedFile}, rerunning hooks...`);
|
|
52
114
|
try {
|
|
115
|
+
const oldModule = await server.ssrLoadModule(bootModuleId);
|
|
116
|
+
if (oldModule.onShutdown) {
|
|
117
|
+
await oldModule.onShutdown();
|
|
118
|
+
}
|
|
53
119
|
server.moduleGraph.invalidateAll();
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
await
|
|
120
|
+
const newModule = await server.ssrLoadModule(bootModuleId);
|
|
121
|
+
if (newModule.onStartup) {
|
|
122
|
+
await newModule.onStartup();
|
|
57
123
|
}
|
|
58
124
|
} catch (error) {
|
|
59
|
-
logger.error(`Error
|
|
125
|
+
logger.error(`Error during boot HMR: ${error}`);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const shouldIgnore = (filePath) => {
|
|
129
|
+
const path2 = filePath.toLowerCase();
|
|
130
|
+
return ignoredSuffixes.some((suffix) => path2.endsWith(suffix));
|
|
131
|
+
};
|
|
132
|
+
server.watcher.on("change", async (changedPath) => {
|
|
133
|
+
if (shouldIgnore(changedPath)) return;
|
|
134
|
+
const bootDeps = getBootDependencies();
|
|
135
|
+
if (bootDeps.has(changedPath)) {
|
|
136
|
+
await rerunBoot(changedPath);
|
|
60
137
|
}
|
|
61
138
|
});
|
|
62
139
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astroscope/boot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Startup and graceful shutdown hooks for Astro SSR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"astro": "^5.
|
|
46
|
+
"astro": "^5.16.9",
|
|
47
47
|
"tsup": "^8.5.1",
|
|
48
48
|
"typescript": "^5.9.3"
|
|
49
49
|
},
|