@neat.is/core 0.2.10 → 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-QYUB3FQL.js → chunk-4ASCXBZF.js} +12 -124
- package/dist/chunk-4ASCXBZF.js.map +1 -0
- package/dist/{chunk-5BQWBQJR.js → chunk-66Z5IEFY.js} +126 -7
- package/dist/chunk-66Z5IEFY.js.map +1 -0
- package/dist/{chunk-JMLZOKCS.js → chunk-FIXKIYNF.js} +818 -18
- package/dist/chunk-FIXKIYNF.js.map +1 -0
- package/dist/chunk-G3PDTGOW.js +125 -0
- package/dist/chunk-G3PDTGOW.js.map +1 -0
- package/dist/cli.cjs +60 -25
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +17 -15
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +186 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -12
- package/dist/index.d.ts +11 -12
- package/dist/index.js +10 -11
- package/dist/neatd.cjs +1886 -34
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +5 -3
- package/dist/neatd.js.map +1 -1
- package/dist/{otel-grpc-USFL3OI3.js → otel-grpc-J4O2SIBZ.js} +3 -3
- package/dist/server.cjs +49 -17
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +6 -7
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-5BQWBQJR.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-JMLZOKCS.js.map +0 -1
- package/dist/chunk-QYUB3FQL.js.map +0 -1
- package/dist/chunk-W7ZYJZC7.js +0 -807
- package/dist/chunk-W7ZYJZC7.js.map +0 -1
- package/dist/otel-grpc-USFL3OI3.js.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → otel-grpc-J4O2SIBZ.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1653,6 +1653,29 @@ async function appendErrorEvent(ctx, ev) {
|
|
|
1653
1653
|
await import_node_fs3.promises.mkdir(import_node_path3.default.dirname(ctx.errorsPath), { recursive: true });
|
|
1654
1654
|
await import_node_fs3.promises.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
1655
1655
|
}
|
|
1656
|
+
function buildErrorEventForReceiver(span) {
|
|
1657
|
+
if (span.statusCode !== 2) return null;
|
|
1658
|
+
const ts = span.startTimeIso ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1659
|
+
return {
|
|
1660
|
+
id: `${span.traceId}:${span.spanId}`,
|
|
1661
|
+
timestamp: ts,
|
|
1662
|
+
service: span.service,
|
|
1663
|
+
traceId: span.traceId,
|
|
1664
|
+
spanId: span.spanId,
|
|
1665
|
+
errorMessage: span.exception?.message ?? span.errorMessage ?? span.name ?? "unknown error",
|
|
1666
|
+
...span.exception?.type ? { exceptionType: span.exception.type } : {},
|
|
1667
|
+
...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
|
|
1668
|
+
affectedNode: (0, import_types3.serviceId)(span.service)
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
function makeErrorSpanWriter(errorsPath) {
|
|
1672
|
+
return async (span) => {
|
|
1673
|
+
const ev = buildErrorEventForReceiver(span);
|
|
1674
|
+
if (!ev) return;
|
|
1675
|
+
await import_node_fs3.promises.mkdir(import_node_path3.default.dirname(errorsPath), { recursive: true });
|
|
1676
|
+
await import_node_fs3.promises.appendFile(errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1656
1679
|
async function handleSpan(ctx, span) {
|
|
1657
1680
|
const ts = span.startTimeIso ?? nowIso(ctx);
|
|
1658
1681
|
const nowMs = ctx.now ? ctx.now() : Date.now();
|
|
@@ -4516,9 +4539,15 @@ function registerRoutes(scope, ctx) {
|
|
|
4516
4539
|
scope.get("/health", async (req, reply) => {
|
|
4517
4540
|
const proj = resolveProject(registry, req, reply);
|
|
4518
4541
|
if (!proj) return;
|
|
4542
|
+
const uptimeMs = Date.now() - startedAt;
|
|
4519
4543
|
return {
|
|
4520
|
-
|
|
4544
|
+
ok: true,
|
|
4521
4545
|
project: proj.name,
|
|
4546
|
+
uptimeMs,
|
|
4547
|
+
// Legacy fields kept additively. The web shell's StatusBar reads
|
|
4548
|
+
// nodeCount / edgeCount; ADR-061's HealthResponseSchema validates
|
|
4549
|
+
// the canonical triple and lets the extras pass through.
|
|
4550
|
+
uptime: Math.floor(uptimeMs / 1e3),
|
|
4522
4551
|
nodeCount: proj.graph.order,
|
|
4523
4552
|
edgeCount: proj.graph.size,
|
|
4524
4553
|
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -4538,7 +4567,7 @@ function registerRoutes(scope, ctx) {
|
|
|
4538
4567
|
if (!proj.graph.hasNode(id)) {
|
|
4539
4568
|
return reply.code(404).send({ error: "node not found", id });
|
|
4540
4569
|
}
|
|
4541
|
-
return proj.graph.getNodeAttributes(id);
|
|
4570
|
+
return { node: proj.graph.getNodeAttributes(id) };
|
|
4542
4571
|
}
|
|
4543
4572
|
);
|
|
4544
4573
|
scope.get(
|
|
@@ -4555,12 +4584,12 @@ function registerRoutes(scope, ctx) {
|
|
|
4555
4584
|
return { inbound, outbound };
|
|
4556
4585
|
}
|
|
4557
4586
|
);
|
|
4558
|
-
scope.get("/graph/
|
|
4587
|
+
scope.get("/graph/dependencies/:nodeId", async (req, reply) => {
|
|
4559
4588
|
const proj = resolveProject(registry, req, reply);
|
|
4560
4589
|
if (!proj) return;
|
|
4561
|
-
const {
|
|
4562
|
-
if (!proj.graph.hasNode(
|
|
4563
|
-
return reply.code(404).send({ error: "node not found", id });
|
|
4590
|
+
const { nodeId } = req.params;
|
|
4591
|
+
if (!proj.graph.hasNode(nodeId)) {
|
|
4592
|
+
return reply.code(404).send({ error: "node not found", id: nodeId });
|
|
4564
4593
|
}
|
|
4565
4594
|
const depth = req.query.depth ? Number(req.query.depth) : TRANSITIVE_DEPENDENCIES_DEFAULT_DEPTH;
|
|
4566
4595
|
if (!Number.isFinite(depth) || depth < 1 || depth > TRANSITIVE_DEPENDENCIES_MAX_DEPTH) {
|
|
@@ -4568,7 +4597,7 @@ function registerRoutes(scope, ctx) {
|
|
|
4568
4597
|
error: `depth must be an integer in [1, ${TRANSITIVE_DEPENDENCIES_MAX_DEPTH}]`
|
|
4569
4598
|
});
|
|
4570
4599
|
}
|
|
4571
|
-
return getTransitiveDependencies(proj.graph,
|
|
4600
|
+
return getTransitiveDependencies(proj.graph, nodeId, depth);
|
|
4572
4601
|
});
|
|
4573
4602
|
scope.get("/graph/divergences", async (req, reply) => {
|
|
4574
4603
|
const proj = resolveProject(registry, req, reply);
|
|
@@ -4609,19 +4638,26 @@ function registerRoutes(scope, ctx) {
|
|
|
4609
4638
|
const proj = resolveProject(registry, req, reply);
|
|
4610
4639
|
if (!proj) return;
|
|
4611
4640
|
const epath = errorsPathFor(proj);
|
|
4612
|
-
if (!epath) return [];
|
|
4613
|
-
|
|
4641
|
+
if (!epath) return { count: 0, total: 0, events: [] };
|
|
4642
|
+
const events = await readErrorEvents(epath);
|
|
4643
|
+
const total = events.length;
|
|
4644
|
+
const limit = req.query.limit ? Number(req.query.limit) : 50;
|
|
4645
|
+
const safeLimit = Number.isFinite(limit) && limit > 0 ? Math.min(limit, 200) : 50;
|
|
4646
|
+
const sliced = events.slice(0, safeLimit);
|
|
4647
|
+
return { count: sliced.length, total, events: sliced };
|
|
4614
4648
|
});
|
|
4615
|
-
scope.get("/
|
|
4649
|
+
scope.get("/stale-events", async (req, reply) => {
|
|
4616
4650
|
const proj = resolveProject(registry, req, reply);
|
|
4617
4651
|
if (!proj) return;
|
|
4618
4652
|
const spath = staleEventsPathFor(proj);
|
|
4619
|
-
if (!spath) return [];
|
|
4653
|
+
if (!spath) return { count: 0, total: 0, events: [] };
|
|
4620
4654
|
const events = await readStaleEvents(spath);
|
|
4621
4655
|
const filtered = req.query.edgeType ? events.filter((e) => e.edgeType === req.query.edgeType) : events;
|
|
4622
4656
|
const ordered = [...filtered].reverse();
|
|
4657
|
+
const total = ordered.length;
|
|
4623
4658
|
const limit = req.query.limit ? Number(req.query.limit) : 50;
|
|
4624
|
-
|
|
4659
|
+
const sliced = ordered.slice(0, Number.isFinite(limit) && limit > 0 ? limit : 50);
|
|
4660
|
+
return { count: sliced.length, total, events: sliced };
|
|
4625
4661
|
});
|
|
4626
4662
|
scope.get(
|
|
4627
4663
|
"/incidents/:nodeId",
|
|
@@ -4633,14 +4669,15 @@ function registerRoutes(scope, ctx) {
|
|
|
4633
4669
|
return reply.code(404).send({ error: "node not found", id: nodeId });
|
|
4634
4670
|
}
|
|
4635
4671
|
const epath = errorsPathFor(proj);
|
|
4636
|
-
if (!epath) return [];
|
|
4672
|
+
if (!epath) return { count: 0, total: 0, events: [] };
|
|
4637
4673
|
const events = await readErrorEvents(epath);
|
|
4638
|
-
|
|
4674
|
+
const filtered = events.filter(
|
|
4639
4675
|
(e) => e.affectedNode === nodeId || e.service === nodeId.replace(/^service:/, "")
|
|
4640
4676
|
);
|
|
4677
|
+
return { count: filtered.length, total: filtered.length, events: filtered };
|
|
4641
4678
|
}
|
|
4642
4679
|
);
|
|
4643
|
-
scope.get("/
|
|
4680
|
+
scope.get("/graph/root-cause/:nodeId", async (req, reply) => {
|
|
4644
4681
|
const proj = resolveProject(registry, req, reply);
|
|
4645
4682
|
if (!proj) return;
|
|
4646
4683
|
const { nodeId } = req.params;
|
|
@@ -4660,7 +4697,7 @@ function registerRoutes(scope, ctx) {
|
|
|
4660
4697
|
if (!result) return reply.code(404).send({ error: "no root cause found", id: nodeId });
|
|
4661
4698
|
return result;
|
|
4662
4699
|
});
|
|
4663
|
-
scope.get("/
|
|
4700
|
+
scope.get("/graph/blast-radius/:nodeId", async (req, reply) => {
|
|
4664
4701
|
const proj = resolveProject(registry, req, reply);
|
|
4665
4702
|
if (!proj) return;
|
|
4666
4703
|
const { nodeId } = req.params;
|
|
@@ -4770,7 +4807,7 @@ function registerRoutes(scope, ctx) {
|
|
|
4770
4807
|
if (req.query.policyId) {
|
|
4771
4808
|
violations = violations.filter((v) => v.policyId === req.query.policyId);
|
|
4772
4809
|
}
|
|
4773
|
-
return violations;
|
|
4810
|
+
return { violations };
|
|
4774
4811
|
});
|
|
4775
4812
|
scope.post("/policies/check", async (req, reply) => {
|
|
4776
4813
|
const proj = resolveProject(registry, req, reply);
|
|
@@ -4849,6 +4886,20 @@ async function buildApi(opts) {
|
|
|
4849
4886
|
});
|
|
4850
4887
|
}
|
|
4851
4888
|
});
|
|
4889
|
+
app.get("/projects/:project", async (req, reply) => {
|
|
4890
|
+
try {
|
|
4891
|
+
const entry = await getProject(req.params.project);
|
|
4892
|
+
if (!entry) {
|
|
4893
|
+
return reply.code(404).send({ error: "project not found", project: req.params.project });
|
|
4894
|
+
}
|
|
4895
|
+
return { project: entry };
|
|
4896
|
+
} catch (err) {
|
|
4897
|
+
return reply.code(500).send({
|
|
4898
|
+
error: "failed to read project registry",
|
|
4899
|
+
details: err.message
|
|
4900
|
+
});
|
|
4901
|
+
}
|
|
4902
|
+
});
|
|
4852
4903
|
registerRoutes(app, routeCtx);
|
|
4853
4904
|
await app.register(
|
|
4854
4905
|
async (scope) => {
|
|
@@ -4867,6 +4918,7 @@ init_otel_grpc();
|
|
|
4867
4918
|
init_cjs_shims();
|
|
4868
4919
|
var import_node_fs19 = require("fs");
|
|
4869
4920
|
var import_node_path33 = __toESM(require("path"), 1);
|
|
4921
|
+
init_otel();
|
|
4870
4922
|
function neatHomeFor(opts) {
|
|
4871
4923
|
if (opts.neatHome && opts.neatHome.length > 0) return import_node_path33.default.resolve(opts.neatHome);
|
|
4872
4924
|
const env = process.env.NEAT_HOME;
|
|
@@ -4885,6 +4937,7 @@ function routeSpanToProject(serviceName, projects) {
|
|
|
4885
4937
|
return DEFAULT_PROJECT;
|
|
4886
4938
|
}
|
|
4887
4939
|
async function bootstrapProject(entry) {
|
|
4940
|
+
const paths = pathsForProject(entry.name, import_node_path33.default.join(entry.path, "neat-out"));
|
|
4888
4941
|
try {
|
|
4889
4942
|
const stat = await import_node_fs19.promises.stat(entry.path);
|
|
4890
4943
|
if (!stat.isDirectory()) {
|
|
@@ -4899,6 +4952,7 @@ async function bootstrapProject(entry) {
|
|
|
4899
4952
|
// output; nothing routes to it because it's not 'active'.
|
|
4900
4953
|
graph: getGraph(`__broken__:${entry.name}`),
|
|
4901
4954
|
outPath: "",
|
|
4955
|
+
paths,
|
|
4902
4956
|
stopPersist: () => {
|
|
4903
4957
|
},
|
|
4904
4958
|
status: "broken",
|
|
@@ -4907,10 +4961,7 @@ async function bootstrapProject(entry) {
|
|
|
4907
4961
|
}
|
|
4908
4962
|
resetGraph(entry.name);
|
|
4909
4963
|
const graph = getGraph(entry.name);
|
|
4910
|
-
const outPath =
|
|
4911
|
-
entry.name,
|
|
4912
|
-
import_node_path33.default.join(entry.path, "neat-out")
|
|
4913
|
-
).snapshotPath;
|
|
4964
|
+
const outPath = paths.snapshotPath;
|
|
4914
4965
|
await loadGraphFromDisk(graph, outPath);
|
|
4915
4966
|
await extractFromDirectory(graph, entry.path);
|
|
4916
4967
|
const stopPersist = startPersistLoop(graph, outPath);
|
|
@@ -4920,10 +4971,35 @@ async function bootstrapProject(entry) {
|
|
|
4920
4971
|
entry,
|
|
4921
4972
|
graph,
|
|
4922
4973
|
outPath,
|
|
4974
|
+
paths,
|
|
4923
4975
|
stopPersist,
|
|
4924
4976
|
status: "active"
|
|
4925
4977
|
};
|
|
4926
4978
|
}
|
|
4979
|
+
function resolveRestPort(opts) {
|
|
4980
|
+
if (typeof opts.restPort === "number") return opts.restPort;
|
|
4981
|
+
const env = process.env.PORT;
|
|
4982
|
+
if (env && env.length > 0) {
|
|
4983
|
+
const n = Number.parseInt(env, 10);
|
|
4984
|
+
if (Number.isFinite(n)) return n;
|
|
4985
|
+
}
|
|
4986
|
+
return 8080;
|
|
4987
|
+
}
|
|
4988
|
+
function resolveOtlpPort(opts) {
|
|
4989
|
+
if (typeof opts.otlpPort === "number") return opts.otlpPort;
|
|
4990
|
+
const env = process.env.OTEL_PORT;
|
|
4991
|
+
if (env && env.length > 0) {
|
|
4992
|
+
const n = Number.parseInt(env, 10);
|
|
4993
|
+
if (Number.isFinite(n)) return n;
|
|
4994
|
+
}
|
|
4995
|
+
return 4318;
|
|
4996
|
+
}
|
|
4997
|
+
function resolveHost(opts) {
|
|
4998
|
+
if (opts.host && opts.host.length > 0) return opts.host;
|
|
4999
|
+
const env = process.env.HOST;
|
|
5000
|
+
if (env && env.length > 0) return env;
|
|
5001
|
+
return "0.0.0.0";
|
|
5002
|
+
}
|
|
4927
5003
|
async function startDaemon(opts = {}) {
|
|
4928
5004
|
const home = neatHomeFor(opts);
|
|
4929
5005
|
const regPath = registryPath();
|
|
@@ -4938,6 +5014,15 @@ async function startDaemon(opts = {}) {
|
|
|
4938
5014
|
await writeAtomically(pidPath, `${process.pid}
|
|
4939
5015
|
`);
|
|
4940
5016
|
const slots = /* @__PURE__ */ new Map();
|
|
5017
|
+
const registry = new Projects();
|
|
5018
|
+
function upsertRegistryFromSlot(slot) {
|
|
5019
|
+
if (slot.status !== "active") return;
|
|
5020
|
+
registry.set(slot.entry.name, {
|
|
5021
|
+
scanPath: slot.entry.path,
|
|
5022
|
+
paths: slot.paths,
|
|
5023
|
+
graph: slot.graph
|
|
5024
|
+
});
|
|
5025
|
+
}
|
|
4941
5026
|
async function loadAll() {
|
|
4942
5027
|
const projects = await listProjects();
|
|
4943
5028
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -4947,6 +5032,7 @@ async function startDaemon(opts = {}) {
|
|
|
4947
5032
|
try {
|
|
4948
5033
|
const slot = await bootstrapProject(entry);
|
|
4949
5034
|
slots.set(entry.name, slot);
|
|
5035
|
+
upsertRegistryFromSlot(slot);
|
|
4950
5036
|
if (slot.status === "broken") {
|
|
4951
5037
|
console.warn(`neatd: project "${entry.name}" broken \u2014 ${slot.errorReason}`);
|
|
4952
5038
|
} else {
|
|
@@ -4971,6 +5057,80 @@ async function startDaemon(opts = {}) {
|
|
|
4971
5057
|
}
|
|
4972
5058
|
}
|
|
4973
5059
|
await loadAll();
|
|
5060
|
+
const bind = opts.bindListeners !== false;
|
|
5061
|
+
let restApp = null;
|
|
5062
|
+
let otlpApp = null;
|
|
5063
|
+
let restAddress = "";
|
|
5064
|
+
let otlpAddress = "";
|
|
5065
|
+
if (bind) {
|
|
5066
|
+
const host = resolveHost(opts);
|
|
5067
|
+
const restPort = resolveRestPort(opts);
|
|
5068
|
+
const otlpPort = resolveOtlpPort(opts);
|
|
5069
|
+
try {
|
|
5070
|
+
restApp = await buildApi({ projects: registry });
|
|
5071
|
+
restAddress = await restApp.listen({ port: restPort, host });
|
|
5072
|
+
console.log(`neatd: REST listening on ${restAddress}`);
|
|
5073
|
+
} catch (err) {
|
|
5074
|
+
for (const slot of slots.values()) {
|
|
5075
|
+
try {
|
|
5076
|
+
slot.stopPersist();
|
|
5077
|
+
} catch {
|
|
5078
|
+
}
|
|
5079
|
+
}
|
|
5080
|
+
if (restApp) await restApp.close().catch(() => {
|
|
5081
|
+
});
|
|
5082
|
+
await import_node_fs19.promises.unlink(pidPath).catch(() => {
|
|
5083
|
+
});
|
|
5084
|
+
throw new Error(
|
|
5085
|
+
`neatd: failed to bind REST on port ${restPort} \u2014 ${err.message}`
|
|
5086
|
+
);
|
|
5087
|
+
}
|
|
5088
|
+
try {
|
|
5089
|
+
otlpApp = await buildOtelReceiver({
|
|
5090
|
+
onSpan: async (span) => {
|
|
5091
|
+
const liveEntries = await listProjects().catch(() => []);
|
|
5092
|
+
const target = routeSpanToProject(span.service, liveEntries);
|
|
5093
|
+
const slot = slots.get(target) ?? slots.get(DEFAULT_PROJECT);
|
|
5094
|
+
if (!slot || slot.status !== "active") return;
|
|
5095
|
+
await handleSpan(
|
|
5096
|
+
{
|
|
5097
|
+
graph: slot.graph,
|
|
5098
|
+
errorsPath: slot.paths.errorsPath,
|
|
5099
|
+
project: slot.entry.name,
|
|
5100
|
+
// Receiver already wrote the error event synchronously below.
|
|
5101
|
+
writeErrorEventInline: false
|
|
5102
|
+
},
|
|
5103
|
+
span
|
|
5104
|
+
);
|
|
5105
|
+
},
|
|
5106
|
+
onErrorSpanSync: async (span) => {
|
|
5107
|
+
const liveEntries = await listProjects().catch(() => []);
|
|
5108
|
+
const target = routeSpanToProject(span.service, liveEntries);
|
|
5109
|
+
const slot = slots.get(target) ?? slots.get(DEFAULT_PROJECT);
|
|
5110
|
+
if (!slot || slot.status !== "active") return;
|
|
5111
|
+
await makeErrorSpanWriter(slot.paths.errorsPath)(span);
|
|
5112
|
+
}
|
|
5113
|
+
});
|
|
5114
|
+
otlpAddress = await otlpApp.listen({ port: otlpPort, host });
|
|
5115
|
+
console.log(`neatd: OTLP listening on ${otlpAddress}/v1/traces`);
|
|
5116
|
+
} catch (err) {
|
|
5117
|
+
for (const slot of slots.values()) {
|
|
5118
|
+
try {
|
|
5119
|
+
slot.stopPersist();
|
|
5120
|
+
} catch {
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5123
|
+
if (restApp) await restApp.close().catch(() => {
|
|
5124
|
+
});
|
|
5125
|
+
if (otlpApp) await otlpApp.close().catch(() => {
|
|
5126
|
+
});
|
|
5127
|
+
await import_node_fs19.promises.unlink(pidPath).catch(() => {
|
|
5128
|
+
});
|
|
5129
|
+
throw new Error(
|
|
5130
|
+
`neatd: failed to bind OTLP on port ${otlpPort} \u2014 ${err.message}`
|
|
5131
|
+
);
|
|
5132
|
+
}
|
|
5133
|
+
}
|
|
4974
5134
|
let reloading = null;
|
|
4975
5135
|
const reload = async () => {
|
|
4976
5136
|
if (reloading) return reloading;
|
|
@@ -4994,6 +5154,10 @@ async function startDaemon(opts = {}) {
|
|
|
4994
5154
|
if (stopped) return;
|
|
4995
5155
|
stopped = true;
|
|
4996
5156
|
process.off("SIGHUP", sighupHandler);
|
|
5157
|
+
if (otlpApp) await otlpApp.close().catch(() => {
|
|
5158
|
+
});
|
|
5159
|
+
if (restApp) await restApp.close().catch(() => {
|
|
5160
|
+
});
|
|
4997
5161
|
for (const slot of slots.values()) {
|
|
4998
5162
|
try {
|
|
4999
5163
|
slot.stopPersist();
|
|
@@ -5003,7 +5167,7 @@ async function startDaemon(opts = {}) {
|
|
|
5003
5167
|
await import_node_fs19.promises.unlink(pidPath).catch(() => {
|
|
5004
5168
|
});
|
|
5005
5169
|
};
|
|
5006
|
-
return { slots, reload, stop, pidPath };
|
|
5170
|
+
return { slots, reload, stop, pidPath, restAddress, otlpAddress };
|
|
5007
5171
|
}
|
|
5008
5172
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5009
5173
|
0 && (module.exports = {
|