@astroscope/boot 0.3.3 → 0.4.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/dist/index.cjs CHANGED
@@ -39,6 +39,7 @@ module.exports = __toCommonJS(index_exports);
39
39
  // src/integration.ts
40
40
  var import_node_fs2 = __toESM(require("fs"), 1);
41
41
  var import_magic_string = __toESM(require("magic-string"), 1);
42
+ var import_vite2 = require("vite");
42
43
 
43
44
  // src/hmr.ts
44
45
  var import_node_path = __toESM(require("path"), 1);
@@ -127,6 +128,16 @@ function serializeError(error) {
127
128
  return JSON.stringify(error);
128
129
  }
129
130
 
131
+ // src/vite-env.ts
132
+ var import_vite = require("vite");
133
+ async function ssrImport(server, moduleId) {
134
+ const ssr = server.environments["ssr"];
135
+ if (!(0, import_vite.isRunnableDevEnvironment)(ssr)) {
136
+ throw new Error("SSR environment is not runnable");
137
+ }
138
+ return ssr.runner.import(moduleId);
139
+ }
140
+
130
141
  // src/hmr.ts
131
142
  function setupBootHmr(server, entry, logger, getBootContext2) {
132
143
  const bootModuleId = `/${entry}`;
@@ -158,14 +169,14 @@ function setupBootHmr(server, entry, logger, getBootContext2) {
158
169
  logger.info(`boot dependency changed: ${changedPath}, rerunning hooks...`);
159
170
  const bootContext = getBootContext2();
160
171
  try {
161
- const oldModule = await server.ssrLoadModule(bootModuleId);
172
+ const oldModule = await ssrImport(server, bootModuleId);
162
173
  await runShutdown(oldModule, bootContext);
163
174
  } catch (error) {
164
175
  logger.error(`Error during boot HMR shutdown: ${serializeError(error)}`);
165
176
  }
166
177
  server.moduleGraph.invalidateAll();
167
178
  try {
168
- const newModule = await server.ssrLoadModule(bootModuleId);
179
+ const newModule = await ssrImport(server, bootModuleId);
169
180
  await runStartup(newModule, bootContext);
170
181
  } catch (error) {
171
182
  logger.error(`Error during boot HMR startup: ${serializeError(error)}`);
@@ -235,19 +246,15 @@ function getBootContext(server, config) {
235
246
  const { host, port } = getServerDefaults(config);
236
247
  return { dev: true, host, port };
237
248
  }
249
+ var getState = (0, import_vite2.perEnvironmentState)(() => ({ bootChunkRef: null, warmupModules: null }));
238
250
  function boot(options = {}) {
239
251
  const entry = resolveEntry(options.entry);
240
252
  const hmr = options.hmr ?? false;
241
- let isBuild = false;
242
- let isSSR = false;
243
- let bootChunkRef = null;
244
253
  let astroConfig = null;
245
- let warmupModules = null;
246
254
  return {
247
255
  name: "@astroscope/boot",
248
256
  hooks: {
249
257
  "astro:config:setup": ({ command, updateConfig, logger, config }) => {
250
- isBuild = command === "build";
251
258
  astroConfig = config;
252
259
  updateConfig({
253
260
  vite: {
@@ -255,19 +262,18 @@ function boot(options = {}) {
255
262
  // build plugin: handles entry.mjs injection, warmup manifest
256
263
  {
257
264
  name: "@astroscope/boot",
258
- configResolved(config2) {
259
- isSSR = !!config2.build?.ssr;
260
- },
261
265
  buildStart() {
262
- if (!isSSR) return;
266
+ if (this.environment.name !== "ssr") return;
267
+ const state = getState(this);
263
268
  try {
264
- bootChunkRef = this.emitFile({ type: "chunk", id: entry, name: "boot" });
269
+ state.bootChunkRef = this.emitFile({ type: "chunk", id: entry, name: "boot" });
265
270
  } catch {
266
271
  }
267
272
  },
268
273
  generateBundle(_, bundle) {
269
- if (!isSSR || !bootChunkRef) return;
270
- const bootChunkName = this.getFileName(bootChunkRef);
274
+ const state = getState(this);
275
+ if (!state.bootChunkRef) return;
276
+ const bootChunkName = this.getFileName(state.bootChunkRef);
271
277
  if (!bootChunkName) {
272
278
  logger.warn("boot chunk not found");
273
279
  return;
@@ -277,7 +283,7 @@ function boot(options = {}) {
277
283
  logger.warn("entry.mjs not found - boot injection skipped");
278
284
  return;
279
285
  }
280
- warmupModules = collectWarmupModules(bundle);
286
+ state.warmupModules = collectWarmupModules(bundle);
281
287
  const { host, port } = getServerDefaults(astroConfig);
282
288
  const prependCode = getPrependCode();
283
289
  const prefix = prependCode.length ? `${prependCode.join("\n")}
@@ -296,10 +302,11 @@ await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })
296
302
  logger.info(`injected ${bootChunkName} into entry.mjs`);
297
303
  },
298
304
  writeBundle(outputOptions) {
299
- if (!isSSR || !warmupModules) return;
305
+ const state = getState(this);
306
+ if (!state.warmupModules) return;
300
307
  const outDir = outputOptions.dir;
301
308
  if (!outDir) return;
302
- writeWarmupManifest(outDir, warmupModules, logger);
309
+ writeWarmupManifest(outDir, state.warmupModules, logger);
303
310
  }
304
311
  },
305
312
  // startup plugin: runs after all other configureServer hooks
@@ -307,10 +314,10 @@ await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })
307
314
  name: "@astroscope/boot/startup",
308
315
  enforce: "post",
309
316
  async configureServer(server) {
310
- if (isBuild) return;
317
+ if (command !== "dev") return;
311
318
  try {
312
319
  const bootContext = getBootContext(server, astroConfig);
313
- const module2 = await server.ssrLoadModule(`/${entry}`);
320
+ const module2 = await ssrImport(server, `/${entry}`);
314
321
  await runStartup(module2, bootContext);
315
322
  } catch (error) {
316
323
  logger.error(`Error running startup script: ${serializeError(error)}`);
@@ -318,7 +325,7 @@ await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })
318
325
  server.httpServer?.once("close", async () => {
319
326
  try {
320
327
  const bootContext = getBootContext(server, astroConfig);
321
- const module2 = await server.ssrLoadModule(`/${entry}`);
328
+ const module2 = await ssrImport(server, `/${entry}`);
322
329
  await runShutdown(module2, bootContext);
323
330
  } catch (error) {
324
331
  logger.error(`Error running shutdown script: ${serializeError(error)}`);
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import "./chunk-I62ZQYTP.js";
11
11
  // src/integration.ts
12
12
  import fs2 from "fs";
13
13
  import MagicString from "magic-string";
14
+ import { perEnvironmentState } from "vite";
14
15
 
15
16
  // src/hmr.ts
16
17
  import path from "path";
@@ -66,6 +67,16 @@ function serializeError(error) {
66
67
  return JSON.stringify(error);
67
68
  }
68
69
 
70
+ // src/vite-env.ts
71
+ import { isRunnableDevEnvironment } from "vite";
72
+ async function ssrImport(server, moduleId) {
73
+ const ssr = server.environments["ssr"];
74
+ if (!isRunnableDevEnvironment(ssr)) {
75
+ throw new Error("SSR environment is not runnable");
76
+ }
77
+ return ssr.runner.import(moduleId);
78
+ }
79
+
69
80
  // src/hmr.ts
70
81
  function setupBootHmr(server, entry, logger, getBootContext2) {
71
82
  const bootModuleId = `/${entry}`;
@@ -97,14 +108,14 @@ function setupBootHmr(server, entry, logger, getBootContext2) {
97
108
  logger.info(`boot dependency changed: ${changedPath}, rerunning hooks...`);
98
109
  const bootContext = getBootContext2();
99
110
  try {
100
- const oldModule = await server.ssrLoadModule(bootModuleId);
111
+ const oldModule = await ssrImport(server, bootModuleId);
101
112
  await runShutdown(oldModule, bootContext);
102
113
  } catch (error) {
103
114
  logger.error(`Error during boot HMR shutdown: ${serializeError(error)}`);
104
115
  }
105
116
  server.moduleGraph.invalidateAll();
106
117
  try {
107
- const newModule = await server.ssrLoadModule(bootModuleId);
118
+ const newModule = await ssrImport(server, bootModuleId);
108
119
  await runStartup(newModule, bootContext);
109
120
  } catch (error) {
110
121
  logger.error(`Error during boot HMR startup: ${serializeError(error)}`);
@@ -165,19 +176,15 @@ function getBootContext(server, config) {
165
176
  const { host, port } = getServerDefaults(config);
166
177
  return { dev: true, host, port };
167
178
  }
179
+ var getState = perEnvironmentState(() => ({ bootChunkRef: null, warmupModules: null }));
168
180
  function boot(options = {}) {
169
181
  const entry = resolveEntry(options.entry);
170
182
  const hmr = options.hmr ?? false;
171
- let isBuild = false;
172
- let isSSR = false;
173
- let bootChunkRef = null;
174
183
  let astroConfig = null;
175
- let warmupModules = null;
176
184
  return {
177
185
  name: "@astroscope/boot",
178
186
  hooks: {
179
187
  "astro:config:setup": ({ command, updateConfig, logger, config }) => {
180
- isBuild = command === "build";
181
188
  astroConfig = config;
182
189
  updateConfig({
183
190
  vite: {
@@ -185,19 +192,18 @@ function boot(options = {}) {
185
192
  // build plugin: handles entry.mjs injection, warmup manifest
186
193
  {
187
194
  name: "@astroscope/boot",
188
- configResolved(config2) {
189
- isSSR = !!config2.build?.ssr;
190
- },
191
195
  buildStart() {
192
- if (!isSSR) return;
196
+ if (this.environment.name !== "ssr") return;
197
+ const state = getState(this);
193
198
  try {
194
- bootChunkRef = this.emitFile({ type: "chunk", id: entry, name: "boot" });
199
+ state.bootChunkRef = this.emitFile({ type: "chunk", id: entry, name: "boot" });
195
200
  } catch {
196
201
  }
197
202
  },
198
203
  generateBundle(_, bundle) {
199
- if (!isSSR || !bootChunkRef) return;
200
- const bootChunkName = this.getFileName(bootChunkRef);
204
+ const state = getState(this);
205
+ if (!state.bootChunkRef) return;
206
+ const bootChunkName = this.getFileName(state.bootChunkRef);
201
207
  if (!bootChunkName) {
202
208
  logger.warn("boot chunk not found");
203
209
  return;
@@ -207,7 +213,7 @@ function boot(options = {}) {
207
213
  logger.warn("entry.mjs not found - boot injection skipped");
208
214
  return;
209
215
  }
210
- warmupModules = collectWarmupModules(bundle);
216
+ state.warmupModules = collectWarmupModules(bundle);
211
217
  const { host, port } = getServerDefaults(astroConfig);
212
218
  const prependCode = getPrependCode();
213
219
  const prefix = prependCode.length ? `${prependCode.join("\n")}
@@ -226,10 +232,11 @@ await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })
226
232
  logger.info(`injected ${bootChunkName} into entry.mjs`);
227
233
  },
228
234
  writeBundle(outputOptions) {
229
- if (!isSSR || !warmupModules) return;
235
+ const state = getState(this);
236
+ if (!state.warmupModules) return;
230
237
  const outDir = outputOptions.dir;
231
238
  if (!outDir) return;
232
- writeWarmupManifest(outDir, warmupModules, logger);
239
+ writeWarmupManifest(outDir, state.warmupModules, logger);
233
240
  }
234
241
  },
235
242
  // startup plugin: runs after all other configureServer hooks
@@ -237,10 +244,10 @@ await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })
237
244
  name: "@astroscope/boot/startup",
238
245
  enforce: "post",
239
246
  async configureServer(server) {
240
- if (isBuild) return;
247
+ if (command !== "dev") return;
241
248
  try {
242
249
  const bootContext = getBootContext(server, astroConfig);
243
- const module = await server.ssrLoadModule(`/${entry}`);
250
+ const module = await ssrImport(server, `/${entry}`);
244
251
  await runStartup(module, bootContext);
245
252
  } catch (error) {
246
253
  logger.error(`Error running startup script: ${serializeError(error)}`);
@@ -248,7 +255,7 @@ await __astroscope_bootSetup(__astroscope_boot, ${JSON.stringify({ host, port })
248
255
  server.httpServer?.once("close", async () => {
249
256
  try {
250
257
  const bootContext = getBootContext(server, astroConfig);
251
- const module = await server.ssrLoadModule(`/${entry}`);
258
+ const module = await ssrImport(server, `/${entry}`);
252
259
  await runShutdown(module, bootContext);
253
260
  } catch (error) {
254
261
  logger.error(`Error running shutdown script: ${serializeError(error)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astroscope/boot",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "Startup and graceful shutdown hooks for Astro SSR",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,17 +55,17 @@
55
55
  "scripts": {
56
56
  "build": "tsup src/index.ts src/warmup.ts src/events.ts src/lifecycle.ts src/setup.ts src/prepend.ts --format esm,cjs --dts",
57
57
  "typecheck": "tsc --noEmit",
58
- "lint": "eslint 'src/**/*.{ts,tsx}'",
59
- "lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix"
58
+ "lint": "eslint src",
59
+ "lint:fix": "eslint src --fix"
60
60
  },
61
61
  "devDependencies": {
62
- "astro": "^5.17.1",
62
+ "astro": "^6.0.2",
63
63
  "tsup": "^8.5.1",
64
- "typescript": "^5.9.3",
65
- "vite": "^6.4.1"
64
+ "typescript": "^5.9.3"
66
65
  },
67
66
  "peerDependencies": {
68
- "astro": "^5.0.0"
67
+ "astro": "^6.0.0",
68
+ "vite": "^7.0.0"
69
69
  },
70
70
  "dependencies": {
71
71
  "magic-string": "^0.30.21"