@neat.is/core 0.4.10 → 0.4.11
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-J5CEKCTR.js → chunk-OJHI33LD.js} +167 -20
- package/dist/chunk-OJHI33LD.js.map +1 -0
- package/dist/{chunk-RC3CIDZO.js → chunk-W4RNPPB5.js} +4 -2
- package/dist/{chunk-RC3CIDZO.js.map → chunk-W4RNPPB5.js.map} +1 -1
- package/dist/cli.cjs +415 -38
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +254 -24
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +164 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +164 -15
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +87 -10
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +3 -2
- package/dist/chunk-J5CEKCTR.js.map +0 -1
package/dist/neatd.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startDaemon
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W4RNPPB5.js";
|
|
5
5
|
import {
|
|
6
6
|
listProjects,
|
|
7
7
|
registryPath
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-OJHI33LD.js";
|
|
9
9
|
import {
|
|
10
10
|
BindAuthorityError,
|
|
11
11
|
__require
|
package/dist/server.cjs
CHANGED
|
@@ -1819,6 +1819,7 @@ init_cjs_shims();
|
|
|
1819
1819
|
init_cjs_shims();
|
|
1820
1820
|
var import_node_fs3 = require("fs");
|
|
1821
1821
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
1822
|
+
var sourceMapJs = __toESM(require("source-map-js"), 1);
|
|
1822
1823
|
var import_types4 = require("@neat.is/types");
|
|
1823
1824
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
1824
1825
|
var DAY_MS = 24 * HOUR_MS;
|
|
@@ -1864,6 +1865,14 @@ function warnUnidentifiedSpan(project) {
|
|
|
1864
1865
|
`[neatd] span lacked service.name; routed to 'unidentified' in project ${project}; check your OTel SDK config.`
|
|
1865
1866
|
);
|
|
1866
1867
|
}
|
|
1868
|
+
var noSourceMapWarnedServices = /* @__PURE__ */ new Set();
|
|
1869
|
+
function warnNoSourceMaps(serviceName) {
|
|
1870
|
+
if (noSourceMapWarnedServices.has(serviceName)) return;
|
|
1871
|
+
noSourceMapWarnedServices.add(serviceName);
|
|
1872
|
+
console.warn(
|
|
1873
|
+
`[neat] ${serviceName}: no .map files found under dist/; observed file edges will land on dist paths, not src. Set sourceMap: true in tsconfig to enable file-level reconciliation.`
|
|
1874
|
+
);
|
|
1875
|
+
}
|
|
1867
1876
|
function pickAttr(span, ...keys) {
|
|
1868
1877
|
for (const k of keys) {
|
|
1869
1878
|
const v = span.attributes[k];
|
|
@@ -1906,8 +1915,13 @@ function languageForExt(relPath) {
|
|
|
1906
1915
|
return void 0;
|
|
1907
1916
|
}
|
|
1908
1917
|
}
|
|
1909
|
-
function relPathForRuntimeFile(filepath, serviceNode) {
|
|
1918
|
+
function relPathForRuntimeFile(filepath, serviceNode, scanPath) {
|
|
1910
1919
|
let p = toPosix(filepath).replace(/^file:\/\//, "");
|
|
1920
|
+
if (scanPath && scanPath.length > 0) {
|
|
1921
|
+
const absRoot = toPosix(import_node_path3.default.resolve(scanPath, serviceNode?.repoPath ?? ""));
|
|
1922
|
+
const anchor = absRoot.endsWith("/") ? absRoot : `${absRoot}/`;
|
|
1923
|
+
if (p.startsWith(anchor)) return p.slice(anchor.length);
|
|
1924
|
+
}
|
|
1911
1925
|
const root = serviceNode?.repoPath;
|
|
1912
1926
|
if (root && root !== "." && root.length > 0) {
|
|
1913
1927
|
const rootPosix = toPosix(root);
|
|
@@ -1924,16 +1938,65 @@ function relPathForRuntimeFile(filepath, serviceNode) {
|
|
|
1924
1938
|
p = p.replace(/^[A-Za-z]:/, "").replace(/^\/+/, "");
|
|
1925
1939
|
return p.length > 0 ? p : null;
|
|
1926
1940
|
}
|
|
1927
|
-
|
|
1941
|
+
var sourceMapCache = /* @__PURE__ */ new Map();
|
|
1942
|
+
function resolveDistToSrc(absFilepath, line) {
|
|
1943
|
+
if (!absFilepath.endsWith(".js")) return null;
|
|
1944
|
+
let entry = sourceMapCache.get(absFilepath);
|
|
1945
|
+
if (entry === void 0) {
|
|
1946
|
+
entry = null;
|
|
1947
|
+
const mapPath = `${absFilepath}.map`;
|
|
1948
|
+
try {
|
|
1949
|
+
if ((0, import_node_fs3.existsSync)(mapPath)) {
|
|
1950
|
+
const raw = JSON.parse((0, import_node_fs3.readFileSync)(mapPath, "utf8"));
|
|
1951
|
+
const consumer = new sourceMapJs.SourceMapConsumer(raw);
|
|
1952
|
+
entry = { consumer, dir: import_node_path3.default.dirname(mapPath) };
|
|
1953
|
+
}
|
|
1954
|
+
} catch {
|
|
1955
|
+
entry = null;
|
|
1956
|
+
}
|
|
1957
|
+
sourceMapCache.set(absFilepath, entry);
|
|
1958
|
+
}
|
|
1959
|
+
if (!entry) return null;
|
|
1960
|
+
try {
|
|
1961
|
+
const pos = entry.consumer.originalPositionFor({
|
|
1962
|
+
line: line !== void 0 && Number.isFinite(line) ? line : 1,
|
|
1963
|
+
column: 0
|
|
1964
|
+
});
|
|
1965
|
+
if (!pos || !pos.source) return null;
|
|
1966
|
+
const root = entry.consumer.sourceRoot ?? "";
|
|
1967
|
+
const resolved = import_node_path3.default.resolve(entry.dir, root, pos.source);
|
|
1968
|
+
return { filepath: resolved, ...pos.line ? { line: pos.line } : {} };
|
|
1969
|
+
} catch {
|
|
1970
|
+
return null;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
1928
1974
|
const filepath = span.attributes[CODE_FILEPATH_ATTR];
|
|
1929
1975
|
if (typeof filepath !== "string" || filepath.length === 0) return null;
|
|
1930
|
-
const relPath = relPathForRuntimeFile(filepath, serviceNode);
|
|
1931
|
-
if (!relPath) return null;
|
|
1932
1976
|
const linenoRaw = span.attributes[CODE_LINENO_ATTR];
|
|
1933
|
-
|
|
1977
|
+
let line = typeof linenoRaw === "number" && Number.isFinite(linenoRaw) ? linenoRaw : void 0;
|
|
1978
|
+
const abs = toPosix(filepath).replace(/^file:\/\//, "");
|
|
1979
|
+
const resolved = resolveDistToSrc(abs, line);
|
|
1980
|
+
let effectivePath = filepath;
|
|
1981
|
+
let originalRelPath;
|
|
1982
|
+
if (resolved) {
|
|
1983
|
+
originalRelPath = relPathForRuntimeFile(filepath, serviceNode, scanPath) ?? void 0;
|
|
1984
|
+
effectivePath = resolved.filepath;
|
|
1985
|
+
if (resolved.line !== void 0) line = resolved.line;
|
|
1986
|
+
}
|
|
1987
|
+
const relPath = relPathForRuntimeFile(effectivePath, serviceNode, scanPath);
|
|
1988
|
+
if (!relPath) return null;
|
|
1989
|
+
if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && serviceNode?.name) {
|
|
1990
|
+
warnNoSourceMaps(serviceNode.name);
|
|
1991
|
+
}
|
|
1934
1992
|
const fnRaw = span.attributes[CODE_FUNCTION_ATTR];
|
|
1935
1993
|
const fn = typeof fnRaw === "string" && fnRaw.length > 0 ? fnRaw : void 0;
|
|
1936
|
-
return {
|
|
1994
|
+
return {
|
|
1995
|
+
relPath,
|
|
1996
|
+
...line !== void 0 ? { line } : {},
|
|
1997
|
+
...fn ? { fn } : {},
|
|
1998
|
+
...originalRelPath && originalRelPath !== relPath ? { originalRelPath } : {}
|
|
1999
|
+
};
|
|
1937
2000
|
}
|
|
1938
2001
|
function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
1939
2002
|
const fileNodeId = (0, import_types4.fileId)(serviceName, callSite.relPath);
|
|
@@ -1945,6 +2008,7 @@ function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
|
1945
2008
|
service: serviceName,
|
|
1946
2009
|
path: callSite.relPath,
|
|
1947
2010
|
...language ? { language } : {},
|
|
2011
|
+
...callSite.originalRelPath ? { originalPath: callSite.originalRelPath } : {},
|
|
1948
2012
|
discoveredVia: "otel"
|
|
1949
2013
|
};
|
|
1950
2014
|
graph.addNode(fileNodeId, node);
|
|
@@ -1970,6 +2034,12 @@ function makeInferredEdgeId(type, source, target) {
|
|
|
1970
2034
|
}
|
|
1971
2035
|
var INFERRED_CONFIDENCE = 0.6;
|
|
1972
2036
|
var STITCH_MAX_DEPTH = 2;
|
|
2037
|
+
var WIRE_SPAN_KIND_CLIENT = 3;
|
|
2038
|
+
var WIRE_SPAN_KIND_PRODUCER = 4;
|
|
2039
|
+
function spanMintsObservedEdge(kind) {
|
|
2040
|
+
if (kind === void 0 || kind === 0) return true;
|
|
2041
|
+
return kind === WIRE_SPAN_KIND_CLIENT || kind === WIRE_SPAN_KIND_PRODUCER;
|
|
2042
|
+
}
|
|
1973
2043
|
var PARENT_SPAN_CACHE_SIZE = 1e4;
|
|
1974
2044
|
var PARENT_SPAN_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1975
2045
|
var parentSpanCache = /* @__PURE__ */ new Map();
|
|
@@ -2180,12 +2250,13 @@ async function handleSpan(ctx, span) {
|
|
|
2180
2250
|
const isError = span.statusCode === 2;
|
|
2181
2251
|
cacheSpanService(span, nowMs);
|
|
2182
2252
|
const sourceServiceNode = ctx.graph.getNodeAttributes(sourceId);
|
|
2183
|
-
const callSite = callSiteFromSpan(span, sourceServiceNode);
|
|
2253
|
+
const callSite = callSiteFromSpan(span, sourceServiceNode, ctx.scanPath);
|
|
2184
2254
|
const observedSource = () => callSite ? ensureObservedFileNode(ctx.graph, span.service, sourceId, callSite) : sourceId;
|
|
2185
2255
|
let affectedNode = sourceId;
|
|
2256
|
+
const mintsFromCallerSide = spanMintsObservedEdge(span.kind);
|
|
2186
2257
|
if (span.dbSystem) {
|
|
2187
2258
|
const host = pickAddress(span);
|
|
2188
|
-
if (host) {
|
|
2259
|
+
if (mintsFromCallerSide && host) {
|
|
2189
2260
|
ensureDatabaseNode(ctx.graph, host, span.dbSystem);
|
|
2190
2261
|
const targetId = (0, import_types4.databaseId)(host);
|
|
2191
2262
|
const result = upsertObservedEdge(
|
|
@@ -2201,7 +2272,7 @@ async function handleSpan(ctx, span) {
|
|
|
2201
2272
|
} else {
|
|
2202
2273
|
const host = pickAddress(span);
|
|
2203
2274
|
let resolvedViaAddress = false;
|
|
2204
|
-
if (host && host !== span.service) {
|
|
2275
|
+
if (mintsFromCallerSide && host && host !== span.service) {
|
|
2205
2276
|
const targetId = resolveServiceId(ctx.graph, host, env);
|
|
2206
2277
|
if (targetId && targetId !== sourceId) {
|
|
2207
2278
|
upsertObservedEdge(
|
|
@@ -3985,8 +4056,14 @@ function collectStringLiterals(node, out) {
|
|
|
3985
4056
|
if (child) collectStringLiterals(child, out);
|
|
3986
4057
|
}
|
|
3987
4058
|
}
|
|
4059
|
+
var PARSE_CHUNK = 16384;
|
|
4060
|
+
function parseSource(parser, source) {
|
|
4061
|
+
return parser.parse(
|
|
4062
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK)
|
|
4063
|
+
);
|
|
4064
|
+
}
|
|
3988
4065
|
function callsFromSource(source, parser, knownHosts) {
|
|
3989
|
-
const tree = parser
|
|
4066
|
+
const tree = parseSource(parser, source);
|
|
3990
4067
|
const literals = [];
|
|
3991
4068
|
collectStringLiterals(tree.rootNode, literals);
|
|
3992
4069
|
const out = [];
|