@luckystack/server 0.7.0 → 0.7.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/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.1] - 2026-07-18
11
+
12
+ ### Fixed
13
+
14
+ - **A failed dev-tooling init no longer fails silently.** When `initializeAll()`
15
+ throws at boot, `createLuckyStackServer` cleared `devApis`/`devSyncs` but kept
16
+ serving — with only a `warn` — so every `/api` and `/sync` route died with no
17
+ explanation (it once read as a per-route type-validation bug across restarts).
18
+ The init failure is now logged at `error` level with the full cause + recovery
19
+ step (hot reload is off, restart after fixing), and recorded so the API/sync
20
+ HTTP routes answer with a `503` naming the real cause instead of a misleading
21
+ `404` on an empty registry. New internal `devToolsStatus` module.
22
+ - **Dev port auto-increment now explains the zombie-process consequence.** When a
23
+ restart hops off a busy port, the warning spells out that a previous/zombie dev
24
+ server is still holding the old port and that any client pinned there (an old
25
+ browser tab, the Vite proxy's cached target) keeps talking to the OLD process,
26
+ not the restart.
27
+
10
28
  ## [0.7.0] - 2026-07-16
11
29
 
12
30
  ### Fixed
package/dist/index.js CHANGED
@@ -963,6 +963,13 @@ var resolveRequesterIp = (req) => {
963
963
  return rawRemoteAddress || trustProxy && (req.headers["x-forwarded-for"] || req.headers["x-real-ip"]) ? resolveClientIp3({ rawAddress: rawRemoteAddress, headers: req.headers, trustProxy, trustedProxyHopCount }) : void 0;
964
964
  };
965
965
 
966
+ // src/devToolsStatus.ts
967
+ var devToolsInitError = null;
968
+ var markDevToolsInitFailed = (error) => {
969
+ devToolsInitError = error;
970
+ };
971
+ var getDevToolsInitError = () => devToolsInitError;
972
+
966
973
  // src/httpRoutes/apiRoute.ts
967
974
  var handleApiRoute = async ({
968
975
  req,
@@ -1006,6 +1013,20 @@ var handleApiRoute = async ({
1006
1013
  res.end(JSON.stringify(response));
1007
1014
  return true;
1008
1015
  }
1016
+ const devToolsError = getDevToolsInitError();
1017
+ if (devToolsError) {
1018
+ const response = {
1019
+ status: "error",
1020
+ httpStatus: 503,
1021
+ message: "api.devToolsUnavailable",
1022
+ errorCode: "api.devToolsUnavailable",
1023
+ detail: `Dev tooling failed to initialize, so NO API routes are loaded. Fix the cause and RESTART the dev server (hot reload is off). Cause: ${devToolsError.message}`
1024
+ };
1025
+ res.setHeader("Content-Type", "application/json");
1026
+ res.writeHead(503);
1027
+ res.end(JSON.stringify(response));
1028
+ return true;
1029
+ }
1009
1030
  const apiData = typeof params === "object" ? { ...params } : {};
1010
1031
  delete apiData.stream;
1011
1032
  const requesterIp = resolveRequesterIp(req);
@@ -1140,6 +1161,19 @@ var handleSyncRoute = async ({
1140
1161
  res.end(JSON.stringify(response));
1141
1162
  return true;
1142
1163
  }
1164
+ const devToolsError = getDevToolsInitError();
1165
+ if (devToolsError) {
1166
+ const response = {
1167
+ status: "error",
1168
+ message: "sync.devToolsUnavailable",
1169
+ errorCode: "sync.devToolsUnavailable",
1170
+ detail: `Dev tooling failed to initialize, so NO sync routes are loaded. Fix the cause and RESTART the dev server (hot reload is off). Cause: ${devToolsError.message}`
1171
+ };
1172
+ res.setHeader("Content-Type", "application/json");
1173
+ res.writeHead(503);
1174
+ res.end(JSON.stringify(response));
1175
+ return true;
1176
+ }
1143
1177
  const syncParams = normalizeHttpSyncParams(params);
1144
1178
  const requesterIp = resolveRequesterIp(req);
1145
1179
  const result = await sync.handleHttpSyncRequest({
@@ -2296,7 +2330,11 @@ var initDevTools = async () => {
2296
2330
  devkit.setupWatchers();
2297
2331
  });
2298
2332
  if (devkitError) {
2299
- getLogger13().warn("dev tooling failed to initialize \u2014 continuing without hot reload.", { error: devkitError.message });
2333
+ markDevToolsInitFailed(devkitError);
2334
+ getLogger13().error(
2335
+ `dev tooling FAILED to initialize \u2014 the server is running but EVERY /api and /sync route will fail until this is fixed. Hot reload is OFF (the file watchers never started), so fix the cause below and RESTART the server. Cause: ${devkitError.message}`,
2336
+ devkitError
2337
+ );
2300
2338
  }
2301
2339
  };
2302
2340
  var listenLuckyStackServer = (httpServer, ip, port, callback) => new Promise((resolve, reject) => {
@@ -2314,7 +2352,7 @@ var listenLuckyStackServer = (httpServer, ip, port, callback) => new Promise((re
2314
2352
  }
2315
2353
  if (autoIncrement) {
2316
2354
  getLogger13().warn(
2317
- `Port ${String(attemptPort)} is in use \u2014 trying ${String(attemptPort + 1)} (auto-increment; set SERVER_PORT_AUTO_INCREMENT=0 to disable)`
2355
+ `Port ${String(attemptPort)} is in use \u2014 trying ${String(attemptPort + 1)} (auto-increment; set SERVER_PORT_AUTO_INCREMENT=0 to disable). A previous/zombie dev server is still holding :${String(attemptPort)}: anything pinned to that port (an old browser tab, the Vite proxy's cached target, a manual client) will keep talking to the OLD process, NOT this restart. If this restart was meant to replace it, stop the process on :${String(attemptPort)} first.`
2318
2356
  );
2319
2357
  tryListen(attemptPort + 1);
2320
2358
  return;