@teamscala/service-boot 0.23.295 → 0.23.296

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/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "name": "@teamscala/service-boot",
8
8
  "type": "module",
9
- "version": "0.23.295",
9
+ "version": "0.23.296",
10
10
  "sideEffects": false,
11
11
  "files": [
12
12
  "src"
@@ -14,6 +14,8 @@ import { join } from "node:path";
14
14
  import type { Hono } from "hono";
15
15
  import { etag } from "hono/etag";
16
16
  import { buildErrorReport } from "@teamscala/os/errors/error-report";
17
+ import { collectHeapReport } from "@teamscala/os/observability/heap-report";
18
+ import { isLoopbackHost } from "@teamscala/os/observability/loopback-host";
17
19
  import { handleAssetProxy } from "./asset-proxy";
18
20
  import { resolveBrandFaviconPath, warmBrandFaviconCache } from "./resolve-brand-favicon";
19
21
 
@@ -37,41 +39,20 @@ export async function registerStaticAssets(
37
39
  }),
38
40
  );
39
41
 
40
- // Localhost-gated heap-attribution probe — restores the object-composition
41
- // data the removed /_healthz surface exposed: the heapSize-vs-RSS split
42
- // (JS heap vs native — OTel/Prisma-engine/buffers/compiled code) plus the
43
- // top object types by count. Read-only, no secrets; gated to a localhost
44
- // Host so it never answers over the public domain. Registered here (before
45
- // auth + page routes) so it is reachable on every service kind, like
46
- // /health (`verify-via-127.0.0.1`, sibling of `runtime-metrics-via-railway-cli`).
42
+ // Localhost-gated heap-attribution probe — the heapSize-vs-RSS split (JS heap
43
+ // vs native: OTel/Prisma-engine/buffers/compiled code) plus the top object
44
+ // types by count. Read-only, no secrets; gated to a localhost Host so it never
45
+ // answers over the public domain. Registered here (before auth + page routes)
46
+ // so it is reachable on every service kind, like /health
47
+ // (`verify-via-127.0.0.1`, sibling of `runtime-metrics-via-railway-cli`).
48
+ //
49
+ // The payload shape lives in @teamscala/os so standalone `Bun.serve` daemons
50
+ // (scala-guard) answer this probe identically — `scala-tools heap <slug>` must
51
+ // not mean different things depending on which process replied.
47
52
  app.get("/_heap", async (c) => {
48
- const host = c.req.header("host") ?? "";
49
- const isLocal =
50
- host.startsWith("127.0.0.1") || host.startsWith("localhost") || host.startsWith("[::1]");
51
- if (!isLocal) return c.json({ error: "localhost only" }, 403);
53
+ if (!isLoopbackHost(c.req.header("host"))) return c.json({ error: "localhost only" }, 403);
52
54
  try {
53
- const { heapStats } = await import("bun:jsc");
54
- const s = heapStats() as unknown as {
55
- heapSize: number;
56
- heapCapacity: number;
57
- objectCount: number;
58
- objectTypeCounts?: Record<string, number>;
59
- };
60
- const rss = process.memoryUsage.rss();
61
- const topObjectTypes = Object.fromEntries(
62
- Object.entries(s.objectTypeCounts ?? {})
63
- .sort((a, b) => b[1] - a[1])
64
- .slice(0, 40),
65
- );
66
- return c.json({
67
- service: serviceSlug,
68
- rss,
69
- heapSize: s.heapSize,
70
- heapCapacity: s.heapCapacity,
71
- objectCount: s.objectCount,
72
- nativeApprox: Math.max(0, rss - s.heapSize),
73
- topObjectTypes,
74
- });
55
+ return c.json(await collectHeapReport(serviceSlug));
75
56
  } catch (err) {
76
57
  const report = buildErrorReport(err, { service: serviceSlug, url: c.req.url });
77
58
  return new Response(JSON.stringify(report.http.body), {