@astroscope/boot 0.2.3 → 0.3.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/chunk-I62ZQYTP.js +36 -0
- package/dist/chunk-LUFQ5I47.js +23 -0
- package/dist/events.cjs +62 -0
- package/dist/events.d.cts +18 -0
- package/dist/events.d.ts +18 -0
- package/dist/events.js +10 -0
- package/dist/index.cjs +134 -104
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +107 -104
- package/dist/lifecycle.cjs +64 -0
- package/dist/lifecycle.d.cts +10 -0
- package/dist/lifecycle.d.ts +10 -0
- package/dist/lifecycle.js +9 -0
- package/dist/setup.cjs +89 -0
- package/dist/setup.d.cts +9 -0
- package/dist/setup.d.ts +9 -0
- package/dist/setup.js +35 -0
- package/package.json +12 -3
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/events.ts
|
|
2
|
+
var STORE_KEY = /* @__PURE__ */ Symbol.for("@astroscope/boot/events");
|
|
3
|
+
function getStore() {
|
|
4
|
+
const existing = globalThis[STORE_KEY];
|
|
5
|
+
if (existing) return existing;
|
|
6
|
+
const store = { listeners: /* @__PURE__ */ new Map() };
|
|
7
|
+
globalThis[STORE_KEY] = store;
|
|
8
|
+
return store;
|
|
9
|
+
}
|
|
10
|
+
function on(event, handler) {
|
|
11
|
+
const store = getStore();
|
|
12
|
+
let handlers = store.listeners.get(event);
|
|
13
|
+
if (!handlers) {
|
|
14
|
+
handlers = /* @__PURE__ */ new Set();
|
|
15
|
+
store.listeners.set(event, handlers);
|
|
16
|
+
}
|
|
17
|
+
handlers.add(handler);
|
|
18
|
+
}
|
|
19
|
+
function off(event, handler) {
|
|
20
|
+
const store = getStore();
|
|
21
|
+
store.listeners.get(event)?.delete(handler);
|
|
22
|
+
}
|
|
23
|
+
async function emit(event, context) {
|
|
24
|
+
const store = getStore();
|
|
25
|
+
const handlers = store.listeners.get(event);
|
|
26
|
+
if (!handlers) return;
|
|
27
|
+
for (const handler of handlers) {
|
|
28
|
+
await handler(context);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
on,
|
|
34
|
+
off,
|
|
35
|
+
emit
|
|
36
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
emit
|
|
3
|
+
} from "./chunk-I62ZQYTP.js";
|
|
4
|
+
|
|
5
|
+
// src/lifecycle.ts
|
|
6
|
+
async function runStartup(boot, context) {
|
|
7
|
+
await emit("beforeOnStartup", context);
|
|
8
|
+
await boot.onStartup?.(context);
|
|
9
|
+
await emit("afterOnStartup", context);
|
|
10
|
+
}
|
|
11
|
+
async function runShutdown(boot, context) {
|
|
12
|
+
try {
|
|
13
|
+
await emit("beforeOnShutdown", context);
|
|
14
|
+
await boot.onShutdown?.(context);
|
|
15
|
+
} finally {
|
|
16
|
+
await emit("afterOnShutdown", context);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
runStartup,
|
|
22
|
+
runShutdown
|
|
23
|
+
};
|
package/dist/events.cjs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/events.ts
|
|
21
|
+
var events_exports = {};
|
|
22
|
+
__export(events_exports, {
|
|
23
|
+
emit: () => emit,
|
|
24
|
+
off: () => off,
|
|
25
|
+
on: () => on
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(events_exports);
|
|
28
|
+
var STORE_KEY = /* @__PURE__ */ Symbol.for("@astroscope/boot/events");
|
|
29
|
+
function getStore() {
|
|
30
|
+
const existing = globalThis[STORE_KEY];
|
|
31
|
+
if (existing) return existing;
|
|
32
|
+
const store = { listeners: /* @__PURE__ */ new Map() };
|
|
33
|
+
globalThis[STORE_KEY] = store;
|
|
34
|
+
return store;
|
|
35
|
+
}
|
|
36
|
+
function on(event, handler) {
|
|
37
|
+
const store = getStore();
|
|
38
|
+
let handlers = store.listeners.get(event);
|
|
39
|
+
if (!handlers) {
|
|
40
|
+
handlers = /* @__PURE__ */ new Set();
|
|
41
|
+
store.listeners.set(event, handlers);
|
|
42
|
+
}
|
|
43
|
+
handlers.add(handler);
|
|
44
|
+
}
|
|
45
|
+
function off(event, handler) {
|
|
46
|
+
const store = getStore();
|
|
47
|
+
store.listeners.get(event)?.delete(handler);
|
|
48
|
+
}
|
|
49
|
+
async function emit(event, context) {
|
|
50
|
+
const store = getStore();
|
|
51
|
+
const handlers = store.listeners.get(event);
|
|
52
|
+
if (!handlers) return;
|
|
53
|
+
for (const handler of handlers) {
|
|
54
|
+
await handler(context);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
58
|
+
0 && (module.exports = {
|
|
59
|
+
emit,
|
|
60
|
+
off,
|
|
61
|
+
on
|
|
62
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { B as BootContext } from './types-CxpusND2.cjs';
|
|
2
|
+
|
|
3
|
+
type BootEventName = 'beforeOnStartup' | 'afterOnStartup' | 'beforeOnShutdown' | 'afterOnShutdown';
|
|
4
|
+
type BootEventHandler = (context: BootContext) => Promise<void> | void;
|
|
5
|
+
/**
|
|
6
|
+
* Register a handler for a boot lifecycle event.
|
|
7
|
+
*/
|
|
8
|
+
declare function on(event: BootEventName, handler: BootEventHandler): void;
|
|
9
|
+
/**
|
|
10
|
+
* Remove a previously registered handler.
|
|
11
|
+
*/
|
|
12
|
+
declare function off(event: BootEventName, handler: BootEventHandler): void;
|
|
13
|
+
/**
|
|
14
|
+
* Emit a boot lifecycle event, running all registered handlers sequentially.
|
|
15
|
+
*/
|
|
16
|
+
declare function emit(event: BootEventName, context: BootContext): Promise<void>;
|
|
17
|
+
|
|
18
|
+
export { type BootEventHandler, type BootEventName, emit, off, on };
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { B as BootContext } from './types-CxpusND2.js';
|
|
2
|
+
|
|
3
|
+
type BootEventName = 'beforeOnStartup' | 'afterOnStartup' | 'beforeOnShutdown' | 'afterOnShutdown';
|
|
4
|
+
type BootEventHandler = (context: BootContext) => Promise<void> | void;
|
|
5
|
+
/**
|
|
6
|
+
* Register a handler for a boot lifecycle event.
|
|
7
|
+
*/
|
|
8
|
+
declare function on(event: BootEventName, handler: BootEventHandler): void;
|
|
9
|
+
/**
|
|
10
|
+
* Remove a previously registered handler.
|
|
11
|
+
*/
|
|
12
|
+
declare function off(event: BootEventName, handler: BootEventHandler): void;
|
|
13
|
+
/**
|
|
14
|
+
* Emit a boot lifecycle event, running all registered handlers sequentially.
|
|
15
|
+
*/
|
|
16
|
+
declare function emit(event: BootEventName, context: BootContext): Promise<void>;
|
|
17
|
+
|
|
18
|
+
export { type BootEventHandler, type BootEventName, emit, off, on };
|
package/dist/events.js
ADDED
package/dist/index.cjs
CHANGED
|
@@ -36,10 +36,12 @@ __export(index_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
38
|
// src/integration.ts
|
|
39
|
-
var
|
|
40
|
-
var import_node_path = __toESM(require("path"), 1);
|
|
39
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
41
40
|
var import_magic_string = __toESM(require("magic-string"), 1);
|
|
42
41
|
|
|
42
|
+
// src/hmr.ts
|
|
43
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
44
|
+
|
|
43
45
|
// src/ignored.ts
|
|
44
46
|
var ignoredSuffixes = [
|
|
45
47
|
// type definitions
|
|
@@ -83,13 +85,123 @@ var ignoredSuffixes = [
|
|
|
83
85
|
".less"
|
|
84
86
|
];
|
|
85
87
|
|
|
88
|
+
// src/events.ts
|
|
89
|
+
var STORE_KEY = /* @__PURE__ */ Symbol.for("@astroscope/boot/events");
|
|
90
|
+
function getStore() {
|
|
91
|
+
const existing = globalThis[STORE_KEY];
|
|
92
|
+
if (existing) return existing;
|
|
93
|
+
const store = { listeners: /* @__PURE__ */ new Map() };
|
|
94
|
+
globalThis[STORE_KEY] = store;
|
|
95
|
+
return store;
|
|
96
|
+
}
|
|
97
|
+
async function emit(event, context) {
|
|
98
|
+
const store = getStore();
|
|
99
|
+
const handlers = store.listeners.get(event);
|
|
100
|
+
if (!handlers) return;
|
|
101
|
+
for (const handler of handlers) {
|
|
102
|
+
await handler(context);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/lifecycle.ts
|
|
107
|
+
async function runStartup(boot2, context) {
|
|
108
|
+
await emit("beforeOnStartup", context);
|
|
109
|
+
await boot2.onStartup?.(context);
|
|
110
|
+
await emit("afterOnStartup", context);
|
|
111
|
+
}
|
|
112
|
+
async function runShutdown(boot2, context) {
|
|
113
|
+
try {
|
|
114
|
+
await emit("beforeOnShutdown", context);
|
|
115
|
+
await boot2.onShutdown?.(context);
|
|
116
|
+
} finally {
|
|
117
|
+
await emit("afterOnShutdown", context);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/hmr.ts
|
|
122
|
+
function setupBootHmr(server, entry, logger, getBootContext) {
|
|
123
|
+
const bootModuleId = `/${entry}`;
|
|
124
|
+
const bootFilePath = import_node_path.default.resolve(server.config.root, entry);
|
|
125
|
+
const getBootDependencies = () => {
|
|
126
|
+
const deps = /* @__PURE__ */ new Set();
|
|
127
|
+
const bootModules = server.moduleGraph.getModulesByFile(bootFilePath);
|
|
128
|
+
const bootModule = bootModules ? [...bootModules][0] : void 0;
|
|
129
|
+
if (!bootModule) return deps;
|
|
130
|
+
const collectDeps = (mod, visited = /* @__PURE__ */ new Set()) => {
|
|
131
|
+
if (!mod?.file || visited.has(mod.file)) return;
|
|
132
|
+
visited.add(mod.file);
|
|
133
|
+
deps.add(mod.file);
|
|
134
|
+
for (const imported of mod.importedModules) {
|
|
135
|
+
collectDeps(imported, visited);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
collectDeps(bootModule);
|
|
139
|
+
return deps;
|
|
140
|
+
};
|
|
141
|
+
const shouldIgnore = (filePath) => {
|
|
142
|
+
const p = filePath.toLowerCase();
|
|
143
|
+
return ignoredSuffixes.some((suffix) => p.endsWith(suffix));
|
|
144
|
+
};
|
|
145
|
+
server.watcher.on("change", async (changedPath) => {
|
|
146
|
+
if (shouldIgnore(changedPath)) return;
|
|
147
|
+
const bootDeps = getBootDependencies();
|
|
148
|
+
if (bootDeps.has(changedPath)) {
|
|
149
|
+
logger.info(`boot dependency changed: ${changedPath}, rerunning hooks...`);
|
|
150
|
+
const bootContext = getBootContext();
|
|
151
|
+
try {
|
|
152
|
+
const oldModule = await server.ssrLoadModule(bootModuleId);
|
|
153
|
+
await runShutdown(oldModule, bootContext);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
logger.error(`Error during boot HMR shutdown: ${error}`);
|
|
156
|
+
}
|
|
157
|
+
server.moduleGraph.invalidateAll();
|
|
158
|
+
try {
|
|
159
|
+
const newModule = await server.ssrLoadModule(bootModuleId);
|
|
160
|
+
await runStartup(newModule, bootContext);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.error(`Error during boot HMR startup: ${error}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/warmup-manifest.ts
|
|
169
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
170
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
171
|
+
var WARMUP_MANIFEST_FILE = "warmup-manifest.json";
|
|
172
|
+
function collectWarmupModules(bundle) {
|
|
173
|
+
const pageModules = [];
|
|
174
|
+
let middlewarePath = null;
|
|
175
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
176
|
+
if (chunk.type !== "chunk") continue;
|
|
177
|
+
if (fileName.startsWith("pages/") && fileName.endsWith(".mjs")) {
|
|
178
|
+
pageModules.push(fileName);
|
|
179
|
+
}
|
|
180
|
+
if (fileName.includes("_astro-internal_middleware") || fileName.includes("_noop-middleware")) {
|
|
181
|
+
middlewarePath = fileName;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return { pageModules, middlewarePath };
|
|
185
|
+
}
|
|
186
|
+
function writeWarmupManifest(outDir, { pageModules, middlewarePath }, logger) {
|
|
187
|
+
const modules = [];
|
|
188
|
+
if (middlewarePath) {
|
|
189
|
+
modules.push(`./${middlewarePath}`);
|
|
190
|
+
}
|
|
191
|
+
for (const page of pageModules) {
|
|
192
|
+
modules.push(`./${page}`);
|
|
193
|
+
}
|
|
194
|
+
const manifestPath = import_node_path2.default.join(outDir, "chunks", WARMUP_MANIFEST_FILE);
|
|
195
|
+
import_node_fs.default.writeFileSync(manifestPath, JSON.stringify({ modules }));
|
|
196
|
+
logger.info(`generated warmup for ${pageModules.length} pages`);
|
|
197
|
+
}
|
|
198
|
+
|
|
86
199
|
// src/integration.ts
|
|
87
200
|
function resolveEntry(entry) {
|
|
88
201
|
if (entry) return entry;
|
|
89
|
-
if (
|
|
202
|
+
if (import_node_fs2.default.existsSync("src/boot/index.ts")) return "src/boot/index.ts";
|
|
90
203
|
return "src/boot.ts";
|
|
91
204
|
}
|
|
92
|
-
var WARMUP_MANIFEST_FILE = "warmup-manifest.json";
|
|
93
205
|
function getServerDefaults(config) {
|
|
94
206
|
return {
|
|
95
207
|
host: typeof config?.server?.host === "string" ? config.server.host : config?.server?.host === true ? "0.0.0.0" : "localhost",
|
|
@@ -103,8 +215,7 @@ function boot(options = {}) {
|
|
|
103
215
|
let isSSR = false;
|
|
104
216
|
let bootChunkRef = null;
|
|
105
217
|
let astroConfig = null;
|
|
106
|
-
let
|
|
107
|
-
let middlewarePath = null;
|
|
218
|
+
let warmupModules = null;
|
|
108
219
|
return {
|
|
109
220
|
name: "@astroscope/boot",
|
|
110
221
|
hooks: {
|
|
@@ -117,7 +228,7 @@ function boot(options = {}) {
|
|
|
117
228
|
{
|
|
118
229
|
name: "@astroscope/boot",
|
|
119
230
|
enforce: "pre",
|
|
120
|
-
configureServer(server) {
|
|
231
|
+
async configureServer(server) {
|
|
121
232
|
if (isBuild) return;
|
|
122
233
|
const getBootContext = () => {
|
|
123
234
|
const addr = server.httpServer?.address();
|
|
@@ -125,72 +236,27 @@ function boot(options = {}) {
|
|
|
125
236
|
const host2 = addr.address === "::" || addr.address === "0.0.0.0" ? "localhost" : addr.address;
|
|
126
237
|
return { dev: true, host: host2, port: addr.port };
|
|
127
238
|
}
|
|
128
|
-
const
|
|
129
|
-
const host = process.env["HOST"] ?? defaults.host;
|
|
130
|
-
const port = process.env["PORT"] ? Number(process.env["PORT"]) : defaults.port;
|
|
239
|
+
const { host, port } = getServerDefaults(astroConfig);
|
|
131
240
|
return { dev: true, host, port };
|
|
132
241
|
};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
});
|
|
242
|
+
try {
|
|
243
|
+
const bootContext = getBootContext();
|
|
244
|
+
const module2 = await server.ssrLoadModule(`/${entry}`);
|
|
245
|
+
await runStartup(module2, bootContext);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
logger.error(`Error running startup script: ${error}`);
|
|
248
|
+
}
|
|
142
249
|
server.httpServer?.once("close", async () => {
|
|
143
250
|
try {
|
|
144
251
|
const bootContext = getBootContext();
|
|
145
252
|
const module2 = await server.ssrLoadModule(`/${entry}`);
|
|
146
|
-
await module2
|
|
253
|
+
await runShutdown(module2, bootContext);
|
|
147
254
|
} catch (error) {
|
|
148
255
|
logger.error(`Error running shutdown script: ${error}`);
|
|
149
256
|
}
|
|
150
257
|
});
|
|
151
258
|
if (hmr) {
|
|
152
|
-
|
|
153
|
-
const bootFilePath = import_node_path.default.resolve(server.config.root, entry);
|
|
154
|
-
const getBootDependencies = () => {
|
|
155
|
-
const deps = /* @__PURE__ */ new Set();
|
|
156
|
-
const bootModules = server.moduleGraph.getModulesByFile(bootFilePath);
|
|
157
|
-
const bootModule = bootModules ? [...bootModules][0] : void 0;
|
|
158
|
-
if (!bootModule) return deps;
|
|
159
|
-
const collectDeps = (mod, visited = /* @__PURE__ */ new Set()) => {
|
|
160
|
-
if (!mod?.file || visited.has(mod.file)) return;
|
|
161
|
-
visited.add(mod.file);
|
|
162
|
-
deps.add(mod.file);
|
|
163
|
-
for (const imported of mod.importedModules) {
|
|
164
|
-
collectDeps(imported, visited);
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
collectDeps(bootModule);
|
|
168
|
-
return deps;
|
|
169
|
-
};
|
|
170
|
-
const rerunBoot = async (changedFile) => {
|
|
171
|
-
logger.info(`boot dependency changed: ${changedFile}, rerunning hooks...`);
|
|
172
|
-
try {
|
|
173
|
-
const bootContext = getBootContext();
|
|
174
|
-
const oldModule = await server.ssrLoadModule(bootModuleId);
|
|
175
|
-
await oldModule.onShutdown?.(bootContext);
|
|
176
|
-
server.moduleGraph.invalidateAll();
|
|
177
|
-
const newModule = await server.ssrLoadModule(bootModuleId);
|
|
178
|
-
await newModule.onStartup?.(bootContext);
|
|
179
|
-
} catch (error) {
|
|
180
|
-
logger.error(`Error during boot HMR: ${error}`);
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
const shouldIgnore = (filePath) => {
|
|
184
|
-
const p = filePath.toLowerCase();
|
|
185
|
-
return ignoredSuffixes.some((suffix) => p.endsWith(suffix));
|
|
186
|
-
};
|
|
187
|
-
server.watcher.on("change", async (changedPath) => {
|
|
188
|
-
if (shouldIgnore(changedPath)) return;
|
|
189
|
-
const bootDeps = getBootDependencies();
|
|
190
|
-
if (bootDeps.has(changedPath)) {
|
|
191
|
-
await rerunBoot(changedPath);
|
|
192
|
-
}
|
|
193
|
-
});
|
|
259
|
+
setupBootHmr(server, entry, logger, getBootContext);
|
|
194
260
|
}
|
|
195
261
|
},
|
|
196
262
|
configResolved(config2) {
|
|
@@ -215,39 +281,12 @@ function boot(options = {}) {
|
|
|
215
281
|
logger.warn("entry.mjs not found - boot injection skipped");
|
|
216
282
|
return;
|
|
217
283
|
}
|
|
218
|
-
|
|
219
|
-
middlewarePath = null;
|
|
220
|
-
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
221
|
-
if (chunk.type !== "chunk") continue;
|
|
222
|
-
if (fileName.startsWith("pages/") && fileName.endsWith(".mjs")) {
|
|
223
|
-
pageModules.push(fileName);
|
|
224
|
-
}
|
|
225
|
-
if (fileName.includes("_astro-internal_middleware") || fileName.includes("_noop-middleware")) {
|
|
226
|
-
middlewarePath = fileName;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
284
|
+
warmupModules = collectWarmupModules(bundle);
|
|
229
285
|
const { host, port } = getServerDefaults(astroConfig);
|
|
230
286
|
const bootImport = `globalThis.__astroscope_server_url = import.meta.url;
|
|
231
|
-
import * as
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
await __boot.onStartup?.(__bootContext);
|
|
235
|
-
} catch (err) {
|
|
236
|
-
console.error('[boot] startup failed:', err);
|
|
237
|
-
try { await __boot.onShutdown?.(__bootContext); } catch {}
|
|
238
|
-
process.exit(1);
|
|
239
|
-
}
|
|
240
|
-
if (__boot.onShutdown) {
|
|
241
|
-
process.on('SIGTERM', async () => {
|
|
242
|
-
try {
|
|
243
|
-
await __boot.onShutdown(__bootContext);
|
|
244
|
-
process.exit(0);
|
|
245
|
-
} catch (err) {
|
|
246
|
-
console.error('[boot] shutdown failed:', err);
|
|
247
|
-
process.exit(1);
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
}
|
|
287
|
+
import * as __astroscope_boot from './${bootChunkName}';
|
|
288
|
+
import { setup as __astroscope_bootSetup } from '@astroscope/boot/setup';
|
|
289
|
+
await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })});
|
|
251
290
|
`;
|
|
252
291
|
const s = new import_magic_string.default(entryChunk.code);
|
|
253
292
|
s.prepend(bootImport);
|
|
@@ -258,19 +297,10 @@ if (__boot.onShutdown) {
|
|
|
258
297
|
logger.info(`injected ${bootChunkName} into entry.mjs`);
|
|
259
298
|
},
|
|
260
299
|
writeBundle(outputOptions) {
|
|
261
|
-
if (!isSSR) return;
|
|
300
|
+
if (!isSSR || !warmupModules) return;
|
|
262
301
|
const outDir = outputOptions.dir;
|
|
263
302
|
if (!outDir) return;
|
|
264
|
-
|
|
265
|
-
if (middlewarePath) {
|
|
266
|
-
modules.push(`./${middlewarePath}`);
|
|
267
|
-
}
|
|
268
|
-
for (const page of pageModules) {
|
|
269
|
-
modules.push(`./${page}`);
|
|
270
|
-
}
|
|
271
|
-
const manifestPath = import_node_path.default.join(outDir, "chunks", WARMUP_MANIFEST_FILE);
|
|
272
|
-
import_node_fs.default.writeFileSync(manifestPath, JSON.stringify({ modules }));
|
|
273
|
-
logger.info(`generated warmup for ${pageModules.length} pages`);
|
|
303
|
+
writeWarmupManifest(outDir, warmupModules, logger);
|
|
274
304
|
}
|
|
275
305
|
}
|
|
276
306
|
]
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runShutdown,
|
|
3
|
+
runStartup
|
|
4
|
+
} from "./chunk-LUFQ5I47.js";
|
|
5
|
+
import "./chunk-I62ZQYTP.js";
|
|
6
|
+
|
|
1
7
|
// src/integration.ts
|
|
2
|
-
import
|
|
3
|
-
import path from "path";
|
|
8
|
+
import fs2 from "fs";
|
|
4
9
|
import MagicString from "magic-string";
|
|
5
10
|
|
|
11
|
+
// src/hmr.ts
|
|
12
|
+
import path from "path";
|
|
13
|
+
|
|
6
14
|
// src/ignored.ts
|
|
7
15
|
var ignoredSuffixes = [
|
|
8
16
|
// type definitions
|
|
@@ -46,13 +54,90 @@ var ignoredSuffixes = [
|
|
|
46
54
|
".less"
|
|
47
55
|
];
|
|
48
56
|
|
|
57
|
+
// src/hmr.ts
|
|
58
|
+
function setupBootHmr(server, entry, logger, getBootContext) {
|
|
59
|
+
const bootModuleId = `/${entry}`;
|
|
60
|
+
const bootFilePath = path.resolve(server.config.root, entry);
|
|
61
|
+
const getBootDependencies = () => {
|
|
62
|
+
const deps = /* @__PURE__ */ new Set();
|
|
63
|
+
const bootModules = server.moduleGraph.getModulesByFile(bootFilePath);
|
|
64
|
+
const bootModule = bootModules ? [...bootModules][0] : void 0;
|
|
65
|
+
if (!bootModule) return deps;
|
|
66
|
+
const collectDeps = (mod, visited = /* @__PURE__ */ new Set()) => {
|
|
67
|
+
if (!mod?.file || visited.has(mod.file)) return;
|
|
68
|
+
visited.add(mod.file);
|
|
69
|
+
deps.add(mod.file);
|
|
70
|
+
for (const imported of mod.importedModules) {
|
|
71
|
+
collectDeps(imported, visited);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
collectDeps(bootModule);
|
|
75
|
+
return deps;
|
|
76
|
+
};
|
|
77
|
+
const shouldIgnore = (filePath) => {
|
|
78
|
+
const p = filePath.toLowerCase();
|
|
79
|
+
return ignoredSuffixes.some((suffix) => p.endsWith(suffix));
|
|
80
|
+
};
|
|
81
|
+
server.watcher.on("change", async (changedPath) => {
|
|
82
|
+
if (shouldIgnore(changedPath)) return;
|
|
83
|
+
const bootDeps = getBootDependencies();
|
|
84
|
+
if (bootDeps.has(changedPath)) {
|
|
85
|
+
logger.info(`boot dependency changed: ${changedPath}, rerunning hooks...`);
|
|
86
|
+
const bootContext = getBootContext();
|
|
87
|
+
try {
|
|
88
|
+
const oldModule = await server.ssrLoadModule(bootModuleId);
|
|
89
|
+
await runShutdown(oldModule, bootContext);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
logger.error(`Error during boot HMR shutdown: ${error}`);
|
|
92
|
+
}
|
|
93
|
+
server.moduleGraph.invalidateAll();
|
|
94
|
+
try {
|
|
95
|
+
const newModule = await server.ssrLoadModule(bootModuleId);
|
|
96
|
+
await runStartup(newModule, bootContext);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
logger.error(`Error during boot HMR startup: ${error}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/warmup-manifest.ts
|
|
105
|
+
import fs from "fs";
|
|
106
|
+
import path2 from "path";
|
|
107
|
+
var WARMUP_MANIFEST_FILE = "warmup-manifest.json";
|
|
108
|
+
function collectWarmupModules(bundle) {
|
|
109
|
+
const pageModules = [];
|
|
110
|
+
let middlewarePath = null;
|
|
111
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
112
|
+
if (chunk.type !== "chunk") continue;
|
|
113
|
+
if (fileName.startsWith("pages/") && fileName.endsWith(".mjs")) {
|
|
114
|
+
pageModules.push(fileName);
|
|
115
|
+
}
|
|
116
|
+
if (fileName.includes("_astro-internal_middleware") || fileName.includes("_noop-middleware")) {
|
|
117
|
+
middlewarePath = fileName;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { pageModules, middlewarePath };
|
|
121
|
+
}
|
|
122
|
+
function writeWarmupManifest(outDir, { pageModules, middlewarePath }, logger) {
|
|
123
|
+
const modules = [];
|
|
124
|
+
if (middlewarePath) {
|
|
125
|
+
modules.push(`./${middlewarePath}`);
|
|
126
|
+
}
|
|
127
|
+
for (const page of pageModules) {
|
|
128
|
+
modules.push(`./${page}`);
|
|
129
|
+
}
|
|
130
|
+
const manifestPath = path2.join(outDir, "chunks", WARMUP_MANIFEST_FILE);
|
|
131
|
+
fs.writeFileSync(manifestPath, JSON.stringify({ modules }));
|
|
132
|
+
logger.info(`generated warmup for ${pageModules.length} pages`);
|
|
133
|
+
}
|
|
134
|
+
|
|
49
135
|
// src/integration.ts
|
|
50
136
|
function resolveEntry(entry) {
|
|
51
137
|
if (entry) return entry;
|
|
52
|
-
if (
|
|
138
|
+
if (fs2.existsSync("src/boot/index.ts")) return "src/boot/index.ts";
|
|
53
139
|
return "src/boot.ts";
|
|
54
140
|
}
|
|
55
|
-
var WARMUP_MANIFEST_FILE = "warmup-manifest.json";
|
|
56
141
|
function getServerDefaults(config) {
|
|
57
142
|
return {
|
|
58
143
|
host: typeof config?.server?.host === "string" ? config.server.host : config?.server?.host === true ? "0.0.0.0" : "localhost",
|
|
@@ -66,8 +151,7 @@ function boot(options = {}) {
|
|
|
66
151
|
let isSSR = false;
|
|
67
152
|
let bootChunkRef = null;
|
|
68
153
|
let astroConfig = null;
|
|
69
|
-
let
|
|
70
|
-
let middlewarePath = null;
|
|
154
|
+
let warmupModules = null;
|
|
71
155
|
return {
|
|
72
156
|
name: "@astroscope/boot",
|
|
73
157
|
hooks: {
|
|
@@ -80,7 +164,7 @@ function boot(options = {}) {
|
|
|
80
164
|
{
|
|
81
165
|
name: "@astroscope/boot",
|
|
82
166
|
enforce: "pre",
|
|
83
|
-
configureServer(server) {
|
|
167
|
+
async configureServer(server) {
|
|
84
168
|
if (isBuild) return;
|
|
85
169
|
const getBootContext = () => {
|
|
86
170
|
const addr = server.httpServer?.address();
|
|
@@ -88,72 +172,27 @@ function boot(options = {}) {
|
|
|
88
172
|
const host2 = addr.address === "::" || addr.address === "0.0.0.0" ? "localhost" : addr.address;
|
|
89
173
|
return { dev: true, host: host2, port: addr.port };
|
|
90
174
|
}
|
|
91
|
-
const
|
|
92
|
-
const host = process.env["HOST"] ?? defaults.host;
|
|
93
|
-
const port = process.env["PORT"] ? Number(process.env["PORT"]) : defaults.port;
|
|
175
|
+
const { host, port } = getServerDefaults(astroConfig);
|
|
94
176
|
return { dev: true, host, port };
|
|
95
177
|
};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
});
|
|
178
|
+
try {
|
|
179
|
+
const bootContext = getBootContext();
|
|
180
|
+
const module = await server.ssrLoadModule(`/${entry}`);
|
|
181
|
+
await runStartup(module, bootContext);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
logger.error(`Error running startup script: ${error}`);
|
|
184
|
+
}
|
|
105
185
|
server.httpServer?.once("close", async () => {
|
|
106
186
|
try {
|
|
107
187
|
const bootContext = getBootContext();
|
|
108
188
|
const module = await server.ssrLoadModule(`/${entry}`);
|
|
109
|
-
await module
|
|
189
|
+
await runShutdown(module, bootContext);
|
|
110
190
|
} catch (error) {
|
|
111
191
|
logger.error(`Error running shutdown script: ${error}`);
|
|
112
192
|
}
|
|
113
193
|
});
|
|
114
194
|
if (hmr) {
|
|
115
|
-
|
|
116
|
-
const bootFilePath = path.resolve(server.config.root, entry);
|
|
117
|
-
const getBootDependencies = () => {
|
|
118
|
-
const deps = /* @__PURE__ */ new Set();
|
|
119
|
-
const bootModules = server.moduleGraph.getModulesByFile(bootFilePath);
|
|
120
|
-
const bootModule = bootModules ? [...bootModules][0] : void 0;
|
|
121
|
-
if (!bootModule) return deps;
|
|
122
|
-
const collectDeps = (mod, visited = /* @__PURE__ */ new Set()) => {
|
|
123
|
-
if (!mod?.file || visited.has(mod.file)) return;
|
|
124
|
-
visited.add(mod.file);
|
|
125
|
-
deps.add(mod.file);
|
|
126
|
-
for (const imported of mod.importedModules) {
|
|
127
|
-
collectDeps(imported, visited);
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
collectDeps(bootModule);
|
|
131
|
-
return deps;
|
|
132
|
-
};
|
|
133
|
-
const rerunBoot = async (changedFile) => {
|
|
134
|
-
logger.info(`boot dependency changed: ${changedFile}, rerunning hooks...`);
|
|
135
|
-
try {
|
|
136
|
-
const bootContext = getBootContext();
|
|
137
|
-
const oldModule = await server.ssrLoadModule(bootModuleId);
|
|
138
|
-
await oldModule.onShutdown?.(bootContext);
|
|
139
|
-
server.moduleGraph.invalidateAll();
|
|
140
|
-
const newModule = await server.ssrLoadModule(bootModuleId);
|
|
141
|
-
await newModule.onStartup?.(bootContext);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
logger.error(`Error during boot HMR: ${error}`);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
const shouldIgnore = (filePath) => {
|
|
147
|
-
const p = filePath.toLowerCase();
|
|
148
|
-
return ignoredSuffixes.some((suffix) => p.endsWith(suffix));
|
|
149
|
-
};
|
|
150
|
-
server.watcher.on("change", async (changedPath) => {
|
|
151
|
-
if (shouldIgnore(changedPath)) return;
|
|
152
|
-
const bootDeps = getBootDependencies();
|
|
153
|
-
if (bootDeps.has(changedPath)) {
|
|
154
|
-
await rerunBoot(changedPath);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
195
|
+
setupBootHmr(server, entry, logger, getBootContext);
|
|
157
196
|
}
|
|
158
197
|
},
|
|
159
198
|
configResolved(config2) {
|
|
@@ -178,39 +217,12 @@ function boot(options = {}) {
|
|
|
178
217
|
logger.warn("entry.mjs not found - boot injection skipped");
|
|
179
218
|
return;
|
|
180
219
|
}
|
|
181
|
-
|
|
182
|
-
middlewarePath = null;
|
|
183
|
-
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
184
|
-
if (chunk.type !== "chunk") continue;
|
|
185
|
-
if (fileName.startsWith("pages/") && fileName.endsWith(".mjs")) {
|
|
186
|
-
pageModules.push(fileName);
|
|
187
|
-
}
|
|
188
|
-
if (fileName.includes("_astro-internal_middleware") || fileName.includes("_noop-middleware")) {
|
|
189
|
-
middlewarePath = fileName;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
220
|
+
warmupModules = collectWarmupModules(bundle);
|
|
192
221
|
const { host, port } = getServerDefaults(astroConfig);
|
|
193
222
|
const bootImport = `globalThis.__astroscope_server_url = import.meta.url;
|
|
194
|
-
import * as
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
await __boot.onStartup?.(__bootContext);
|
|
198
|
-
} catch (err) {
|
|
199
|
-
console.error('[boot] startup failed:', err);
|
|
200
|
-
try { await __boot.onShutdown?.(__bootContext); } catch {}
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
if (__boot.onShutdown) {
|
|
204
|
-
process.on('SIGTERM', async () => {
|
|
205
|
-
try {
|
|
206
|
-
await __boot.onShutdown(__bootContext);
|
|
207
|
-
process.exit(0);
|
|
208
|
-
} catch (err) {
|
|
209
|
-
console.error('[boot] shutdown failed:', err);
|
|
210
|
-
process.exit(1);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
}
|
|
223
|
+
import * as __astroscope_boot from './${bootChunkName}';
|
|
224
|
+
import { setup as __astroscope_bootSetup } from '@astroscope/boot/setup';
|
|
225
|
+
await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })});
|
|
214
226
|
`;
|
|
215
227
|
const s = new MagicString(entryChunk.code);
|
|
216
228
|
s.prepend(bootImport);
|
|
@@ -221,19 +233,10 @@ if (__boot.onShutdown) {
|
|
|
221
233
|
logger.info(`injected ${bootChunkName} into entry.mjs`);
|
|
222
234
|
},
|
|
223
235
|
writeBundle(outputOptions) {
|
|
224
|
-
if (!isSSR) return;
|
|
236
|
+
if (!isSSR || !warmupModules) return;
|
|
225
237
|
const outDir = outputOptions.dir;
|
|
226
238
|
if (!outDir) return;
|
|
227
|
-
|
|
228
|
-
if (middlewarePath) {
|
|
229
|
-
modules.push(`./${middlewarePath}`);
|
|
230
|
-
}
|
|
231
|
-
for (const page of pageModules) {
|
|
232
|
-
modules.push(`./${page}`);
|
|
233
|
-
}
|
|
234
|
-
const manifestPath = path.join(outDir, "chunks", WARMUP_MANIFEST_FILE);
|
|
235
|
-
fs.writeFileSync(manifestPath, JSON.stringify({ modules }));
|
|
236
|
-
logger.info(`generated warmup for ${pageModules.length} pages`);
|
|
239
|
+
writeWarmupManifest(outDir, warmupModules, logger);
|
|
237
240
|
}
|
|
238
241
|
}
|
|
239
242
|
]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lifecycle.ts
|
|
21
|
+
var lifecycle_exports = {};
|
|
22
|
+
__export(lifecycle_exports, {
|
|
23
|
+
runShutdown: () => runShutdown,
|
|
24
|
+
runStartup: () => runStartup
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(lifecycle_exports);
|
|
27
|
+
|
|
28
|
+
// src/events.ts
|
|
29
|
+
var STORE_KEY = /* @__PURE__ */ Symbol.for("@astroscope/boot/events");
|
|
30
|
+
function getStore() {
|
|
31
|
+
const existing = globalThis[STORE_KEY];
|
|
32
|
+
if (existing) return existing;
|
|
33
|
+
const store = { listeners: /* @__PURE__ */ new Map() };
|
|
34
|
+
globalThis[STORE_KEY] = store;
|
|
35
|
+
return store;
|
|
36
|
+
}
|
|
37
|
+
async function emit(event, context) {
|
|
38
|
+
const store = getStore();
|
|
39
|
+
const handlers = store.listeners.get(event);
|
|
40
|
+
if (!handlers) return;
|
|
41
|
+
for (const handler of handlers) {
|
|
42
|
+
await handler(context);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/lifecycle.ts
|
|
47
|
+
async function runStartup(boot, context) {
|
|
48
|
+
await emit("beforeOnStartup", context);
|
|
49
|
+
await boot.onStartup?.(context);
|
|
50
|
+
await emit("afterOnStartup", context);
|
|
51
|
+
}
|
|
52
|
+
async function runShutdown(boot, context) {
|
|
53
|
+
try {
|
|
54
|
+
await emit("beforeOnShutdown", context);
|
|
55
|
+
await boot.onShutdown?.(context);
|
|
56
|
+
} finally {
|
|
57
|
+
await emit("afterOnShutdown", context);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
61
|
+
0 && (module.exports = {
|
|
62
|
+
runShutdown,
|
|
63
|
+
runStartup
|
|
64
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { B as BootContext } from './types-CxpusND2.cjs';
|
|
2
|
+
|
|
3
|
+
interface BootModule {
|
|
4
|
+
onStartup?: ((context: BootContext) => Promise<void> | void) | undefined;
|
|
5
|
+
onShutdown?: ((context: BootContext) => Promise<void> | void) | undefined;
|
|
6
|
+
}
|
|
7
|
+
declare function runStartup(boot: BootModule, context: BootContext): Promise<void>;
|
|
8
|
+
declare function runShutdown(boot: BootModule, context: BootContext): Promise<void>;
|
|
9
|
+
|
|
10
|
+
export { type BootModule, runShutdown, runStartup };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { B as BootContext } from './types-CxpusND2.js';
|
|
2
|
+
|
|
3
|
+
interface BootModule {
|
|
4
|
+
onStartup?: ((context: BootContext) => Promise<void> | void) | undefined;
|
|
5
|
+
onShutdown?: ((context: BootContext) => Promise<void> | void) | undefined;
|
|
6
|
+
}
|
|
7
|
+
declare function runStartup(boot: BootModule, context: BootContext): Promise<void>;
|
|
8
|
+
declare function runShutdown(boot: BootModule, context: BootContext): Promise<void>;
|
|
9
|
+
|
|
10
|
+
export { type BootModule, runShutdown, runStartup };
|
package/dist/setup.cjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/setup.ts
|
|
21
|
+
var setup_exports = {};
|
|
22
|
+
__export(setup_exports, {
|
|
23
|
+
setup: () => setup
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(setup_exports);
|
|
26
|
+
|
|
27
|
+
// src/events.ts
|
|
28
|
+
var STORE_KEY = /* @__PURE__ */ Symbol.for("@astroscope/boot/events");
|
|
29
|
+
function getStore() {
|
|
30
|
+
const existing = globalThis[STORE_KEY];
|
|
31
|
+
if (existing) return existing;
|
|
32
|
+
const store = { listeners: /* @__PURE__ */ new Map() };
|
|
33
|
+
globalThis[STORE_KEY] = store;
|
|
34
|
+
return store;
|
|
35
|
+
}
|
|
36
|
+
async function emit(event, context) {
|
|
37
|
+
const store = getStore();
|
|
38
|
+
const handlers = store.listeners.get(event);
|
|
39
|
+
if (!handlers) return;
|
|
40
|
+
for (const handler of handlers) {
|
|
41
|
+
await handler(context);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/lifecycle.ts
|
|
46
|
+
async function runStartup(boot, context) {
|
|
47
|
+
await emit("beforeOnStartup", context);
|
|
48
|
+
await boot.onStartup?.(context);
|
|
49
|
+
await emit("afterOnStartup", context);
|
|
50
|
+
}
|
|
51
|
+
async function runShutdown(boot, context) {
|
|
52
|
+
try {
|
|
53
|
+
await emit("beforeOnShutdown", context);
|
|
54
|
+
await boot.onShutdown?.(context);
|
|
55
|
+
} finally {
|
|
56
|
+
await emit("afterOnShutdown", context);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/setup.ts
|
|
61
|
+
async function setup(boot, config) {
|
|
62
|
+
const context = {
|
|
63
|
+
dev: false,
|
|
64
|
+
host: process.env["HOST"] ?? config.host,
|
|
65
|
+
port: process.env["PORT"] ? Number(process.env["PORT"]) : config.port
|
|
66
|
+
};
|
|
67
|
+
try {
|
|
68
|
+
await runStartup(boot, context);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error("[boot] startup failed:", err);
|
|
71
|
+
try {
|
|
72
|
+
await runShutdown(boot, context);
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
process.on("SIGTERM", async () => {
|
|
78
|
+
try {
|
|
79
|
+
await runShutdown(boot, context);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
console.error("[boot] shutdown failed:", err);
|
|
82
|
+
}
|
|
83
|
+
process.exit(0);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
87
|
+
0 && (module.exports = {
|
|
88
|
+
setup
|
|
89
|
+
});
|
package/dist/setup.d.cts
ADDED
package/dist/setup.d.ts
ADDED
package/dist/setup.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runShutdown,
|
|
3
|
+
runStartup
|
|
4
|
+
} from "./chunk-LUFQ5I47.js";
|
|
5
|
+
import "./chunk-I62ZQYTP.js";
|
|
6
|
+
|
|
7
|
+
// src/setup.ts
|
|
8
|
+
async function setup(boot, config) {
|
|
9
|
+
const context = {
|
|
10
|
+
dev: false,
|
|
11
|
+
host: process.env["HOST"] ?? config.host,
|
|
12
|
+
port: process.env["PORT"] ? Number(process.env["PORT"]) : config.port
|
|
13
|
+
};
|
|
14
|
+
try {
|
|
15
|
+
await runStartup(boot, context);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
console.error("[boot] startup failed:", err);
|
|
18
|
+
try {
|
|
19
|
+
await runShutdown(boot, context);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
process.on("SIGTERM", async () => {
|
|
25
|
+
try {
|
|
26
|
+
await runShutdown(boot, context);
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.error("[boot] shutdown failed:", err);
|
|
29
|
+
}
|
|
30
|
+
process.exit(0);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
setup
|
|
35
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astroscope/boot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Startup and graceful shutdown hooks for Astro SSR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -14,6 +14,14 @@
|
|
|
14
14
|
"./warmup": {
|
|
15
15
|
"types": "./dist/warmup.d.ts",
|
|
16
16
|
"import": "./dist/warmup.js"
|
|
17
|
+
},
|
|
18
|
+
"./events": {
|
|
19
|
+
"types": "./dist/events.d.ts",
|
|
20
|
+
"import": "./dist/events.js"
|
|
21
|
+
},
|
|
22
|
+
"./setup": {
|
|
23
|
+
"types": "./dist/setup.d.ts",
|
|
24
|
+
"import": "./dist/setup.js"
|
|
17
25
|
}
|
|
18
26
|
},
|
|
19
27
|
"files": [
|
|
@@ -41,7 +49,7 @@
|
|
|
41
49
|
},
|
|
42
50
|
"homepage": "https://github.com/smnbbrv/astroscope/tree/main/packages/boot#readme",
|
|
43
51
|
"scripts": {
|
|
44
|
-
"build": "tsup src/index.ts src/warmup.ts --format esm,cjs --dts",
|
|
52
|
+
"build": "tsup src/index.ts src/warmup.ts src/events.ts src/lifecycle.ts src/setup.ts --format esm,cjs --dts",
|
|
45
53
|
"typecheck": "tsc --noEmit",
|
|
46
54
|
"lint": "eslint 'src/**/*.{ts,tsx}'",
|
|
47
55
|
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix"
|
|
@@ -49,7 +57,8 @@
|
|
|
49
57
|
"devDependencies": {
|
|
50
58
|
"astro": "^5.17.1",
|
|
51
59
|
"tsup": "^8.5.1",
|
|
52
|
-
"typescript": "^5.9.3"
|
|
60
|
+
"typescript": "^5.9.3",
|
|
61
|
+
"vite": "^6.4.1"
|
|
53
62
|
},
|
|
54
63
|
"peerDependencies": {
|
|
55
64
|
"astro": "^5.0.0"
|