@neat.is/types 0.4.26-dev.20260702 → 0.4.26

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.js CHANGED
@@ -33,7 +33,46 @@ var NodeType = {
33
33
  // The primary node of the file-first graph (ADR-089). A source file owned
34
34
  // by a service; relationships originate from it. See
35
35
  // docs/contracts/file-awareness.md §1.
36
- FileNode: "FileNode"
36
+ FileNode: "FileNode",
37
+ // A server route at (method, path-template) granularity (ADR-119). Extracted
38
+ // from a mainstream router (Express / Fastify / Next.js) so a client call
39
+ // site can be matched to the exact route it names, rather than only to the
40
+ // owning service. The node an OBSERVED server span lands on too, which is
41
+ // what makes a two-sided divergence possible at route grain. See
42
+ // docs/contracts/static-extraction.md.
43
+ RouteNode: "RouteNode",
44
+ // A named GraphQL operation — one query, mutation, or subscription — at
45
+ // (service, operationType, operationName) granularity (ADR-122). Every
46
+ // GraphQL request rides one HTTP endpoint (POST /graphql), so at HTTP grain
47
+ // the whole API collapses to a single edge; this node recovers the
48
+ // operation-level topology from the execution span's `graphql.operation.*`
49
+ // semconv. Minted observed-first from OTel; a future static GraphQL extractor
50
+ // fuses onto the same id. See docs/contracts/otel-ingest.md.
51
+ GraphQLOperationNode: "GraphQLOperationNode",
52
+ // A single gRPC method — one `rpc` in a `.proto` service — at
53
+ // (rpcService, rpcMethod) granularity (ADR-123). gRPC used to engage only at
54
+ // service grain: every method collapsed onto one service→service edge, so the
55
+ // per-method topology was invisible and one-sided. This node recovers the
56
+ // method-level shape from both sides: the OBSERVED execution span's
57
+ // `rpc.service` / `rpc.method` semconv and the static `.proto` service/method
58
+ // definitions. It keys on the fully-qualified `rpc.service` — the wire
59
+ // contract both sides carry verbatim — so a declared method and an observed
60
+ // one fuse onto the same node into a two-sided divergence. See
61
+ // docs/contracts/otel-ingest.md and docs/contracts/static-extraction.md.
62
+ GrpcMethodNode: "GrpcMethodNode",
63
+ // A live WebSocket channel — the path/channel a client connects to — at
64
+ // (service, channel) granularity (ADR-125). A WebSocket app used to produce no
65
+ // OBSERVED topology at all: only message-handler errors surfaced, as incidents,
66
+ // and the channels themselves stayed invisible. This node recovers the
67
+ // channel-level topology from the HTTP upgrade span that opens the connection —
68
+ // a SERVER `GET` carrying the WebSocket path. It is minted OBSERVED-only: a
69
+ // WebSocket channel is known from observation, never from static extraction, so
70
+ // there is no declared twin to fuse with. The edge onto it reuses the existing
71
+ // `CONNECTS_TO` (`service ──CONNECTS_TO──▶ ws-channel`) as an observed-liveness
72
+ // edge that carries `lastObserved` and decays OBSERVED → STALE on CONNECTS_TO's
73
+ // own staleness threshold when the channel goes quiet. See
74
+ // docs/contracts/otel-ingest.md.
75
+ WebSocketChannelNode: "WebSocketChannelNode"
37
76
  };
38
77
  var NodeTypeSchema = z.enum([
39
78
  NodeType.ServiceNode,
@@ -41,7 +80,11 @@ var NodeTypeSchema = z.enum([
41
80
  NodeType.ConfigNode,
42
81
  NodeType.InfraNode,
43
82
  NodeType.FrontierNode,
44
- NodeType.FileNode
83
+ NodeType.FileNode,
84
+ NodeType.RouteNode,
85
+ NodeType.GraphQLOperationNode,
86
+ NodeType.GrpcMethodNode,
87
+ NodeType.WebSocketChannelNode
45
88
  ]);
46
89
 
47
90
  // src/nodes.ts
@@ -171,13 +214,60 @@ var FileNodeSchema = z2.object({
171
214
  // Absent when the call site was already source-grained.
172
215
  originalPath: z2.string().optional()
173
216
  });
217
+ var RouteNodeSchema = z2.object({
218
+ id: z2.string(),
219
+ type: z2.literal(NodeType.RouteNode),
220
+ name: z2.string(),
221
+ service: z2.string(),
222
+ method: z2.string(),
223
+ pathTemplate: z2.string(),
224
+ path: z2.string(),
225
+ line: z2.number().int().nonnegative().optional(),
226
+ framework: z2.string().optional(),
227
+ discoveredVia: DiscoveredViaSchema.optional()
228
+ });
229
+ var GraphQLOperationNodeSchema = z2.object({
230
+ id: z2.string(),
231
+ type: z2.literal(NodeType.GraphQLOperationNode),
232
+ name: z2.string(),
233
+ service: z2.string(),
234
+ operationType: z2.string(),
235
+ operationName: z2.string(),
236
+ path: z2.string().optional(),
237
+ line: z2.number().int().nonnegative().optional(),
238
+ discoveredVia: DiscoveredViaSchema.optional()
239
+ });
240
+ var GrpcMethodNodeSchema = z2.object({
241
+ id: z2.string(),
242
+ type: z2.literal(NodeType.GrpcMethodNode),
243
+ name: z2.string(),
244
+ rpcService: z2.string(),
245
+ rpcMethod: z2.string(),
246
+ path: z2.string().optional(),
247
+ line: z2.number().int().nonnegative().optional(),
248
+ discoveredVia: DiscoveredViaSchema.optional()
249
+ });
250
+ var WebSocketChannelNodeSchema = z2.object({
251
+ id: z2.string(),
252
+ type: z2.literal(NodeType.WebSocketChannelNode),
253
+ name: z2.string(),
254
+ service: z2.string(),
255
+ channel: z2.string(),
256
+ path: z2.string().optional(),
257
+ line: z2.number().int().nonnegative().optional(),
258
+ discoveredVia: DiscoveredViaSchema.optional()
259
+ });
174
260
  var GraphNodeSchema = z2.discriminatedUnion("type", [
175
261
  ServiceNodeSchema,
176
262
  DatabaseNodeSchema,
177
263
  ConfigNodeSchema,
178
264
  InfraNodeSchema,
179
265
  FrontierNodeSchema,
180
- FileNodeSchema
266
+ FileNodeSchema,
267
+ RouteNodeSchema,
268
+ GraphQLOperationNodeSchema,
269
+ GrpcMethodNodeSchema,
270
+ WebSocketChannelNodeSchema
181
271
  ]);
182
272
 
183
273
  // src/edges.ts
@@ -202,7 +292,13 @@ var EdgeTypeSchema = z3.enum([
202
292
  var EdgeEvidenceSchema = z3.object({
203
293
  file: z3.string(),
204
294
  line: z3.number().int().nonnegative().optional(),
205
- snippet: z3.string().optional()
295
+ snippet: z3.string().optional(),
296
+ // HTTP shape of a recognised client call site (ADR-119). Present on a
297
+ // client↔route CALLS edge so the edge records the method + path-template the
298
+ // client named, alongside the file:line it named them at. Absent on every
299
+ // other edge — a config or infra edge has no HTTP method.
300
+ method: z3.string().optional(),
301
+ pathTemplate: z3.string().optional()
206
302
  });
207
303
  var EdgeSignalSchema = z3.object({
208
304
  spanCount: z3.number().int().nonnegative(),
@@ -343,6 +439,10 @@ var CONFIG_PREFIX = "config:";
343
439
  var INFRA_PREFIX = "infra:";
344
440
  var FRONTIER_PREFIX = "frontier:";
345
441
  var FILE_PREFIX = "file:";
442
+ var ROUTE_PREFIX = "route:";
443
+ var GRAPHQL_OP_PREFIX = "graphql:";
444
+ var GRPC_METHOD_PREFIX = "grpc:";
445
+ var WEBSOCKET_CHANNEL_PREFIX = "ws:";
346
446
  var ENV_UNKNOWN = "unknown";
347
447
  function serviceId(name, env) {
348
448
  if (env === void 0 || env === ENV_UNKNOWN) return `${SERVICE_PREFIX}${name}`;
@@ -362,6 +462,9 @@ function databaseId(host) {
362
462
  function parseDatabaseId(id) {
363
463
  return id.startsWith(DATABASE_PREFIX) ? id.slice(DATABASE_PREFIX.length) : null;
364
464
  }
465
+ function localDatabaseId(service, name) {
466
+ return `${DATABASE_PREFIX}${service}/${name}`;
467
+ }
365
468
  function configId(relPath) {
366
469
  return `${CONFIG_PREFIX}${relPath}`;
367
470
  }
@@ -397,6 +500,68 @@ function parseFileId(id) {
397
500
  if (service.length === 0 || relPath.length === 0) return null;
398
501
  return { service, relPath };
399
502
  }
503
+ function routeId(service, method, pathTemplate) {
504
+ return `${ROUTE_PREFIX}${service}:${method.toUpperCase()} ${pathTemplate}`;
505
+ }
506
+ function parseRouteId(id) {
507
+ if (!id.startsWith(ROUTE_PREFIX)) return null;
508
+ const rest = id.slice(ROUTE_PREFIX.length);
509
+ const colon = rest.indexOf(":");
510
+ if (colon === -1) return null;
511
+ const service = rest.slice(0, colon);
512
+ const tail = rest.slice(colon + 1);
513
+ const space = tail.indexOf(" ");
514
+ if (space === -1) return null;
515
+ const method = tail.slice(0, space);
516
+ const pathTemplate = tail.slice(space + 1);
517
+ if (service.length === 0 || method.length === 0 || pathTemplate.length === 0) return null;
518
+ return { service, method, pathTemplate };
519
+ }
520
+ function graphqlOperationId(service, operationType, operationName) {
521
+ return `${GRAPHQL_OP_PREFIX}${service}:${operationType.toLowerCase()} ${operationName}`;
522
+ }
523
+ function parseGraphqlOperationId(id) {
524
+ if (!id.startsWith(GRAPHQL_OP_PREFIX)) return null;
525
+ const rest = id.slice(GRAPHQL_OP_PREFIX.length);
526
+ const colon = rest.indexOf(":");
527
+ if (colon === -1) return null;
528
+ const service = rest.slice(0, colon);
529
+ const tail = rest.slice(colon + 1);
530
+ const space = tail.indexOf(" ");
531
+ if (space === -1) return null;
532
+ const operationType = tail.slice(0, space);
533
+ const operationName = tail.slice(space + 1);
534
+ if (service.length === 0 || operationType.length === 0 || operationName.length === 0) {
535
+ return null;
536
+ }
537
+ return { service, operationType, operationName };
538
+ }
539
+ function grpcMethodId(rpcService, rpcMethod) {
540
+ return `${GRPC_METHOD_PREFIX}${rpcService}/${rpcMethod}`;
541
+ }
542
+ function parseGrpcMethodId(id) {
543
+ if (!id.startsWith(GRPC_METHOD_PREFIX)) return null;
544
+ const rest = id.slice(GRPC_METHOD_PREFIX.length);
545
+ const slash = rest.indexOf("/");
546
+ if (slash === -1) return null;
547
+ const rpcService = rest.slice(0, slash);
548
+ const rpcMethod = rest.slice(slash + 1);
549
+ if (rpcService.length === 0 || rpcMethod.length === 0) return null;
550
+ return { rpcService, rpcMethod };
551
+ }
552
+ function websocketChannelId(service, channel) {
553
+ return `${WEBSOCKET_CHANNEL_PREFIX}${service}:${channel}`;
554
+ }
555
+ function parseWebsocketChannelId(id) {
556
+ if (!id.startsWith(WEBSOCKET_CHANNEL_PREFIX)) return null;
557
+ const rest = id.slice(WEBSOCKET_CHANNEL_PREFIX.length);
558
+ const colon = rest.indexOf(":");
559
+ if (colon === -1) return null;
560
+ const service = rest.slice(0, colon);
561
+ const channel = rest.slice(colon + 1);
562
+ if (service.length === 0 || channel.length === 0) return null;
563
+ return { service, channel };
564
+ }
400
565
  var EDGE_ARROW = "->";
401
566
  function extractedEdgeId(source, target, type) {
402
567
  return `${type}:${source}${EDGE_ARROW}${target}`;
@@ -864,6 +1029,8 @@ export {
864
1029
  GraphEdgesResponseSchema,
865
1030
  GraphNodeResponseSchema,
866
1031
  GraphNodeSchema,
1032
+ GraphQLOperationNodeSchema,
1033
+ GrpcMethodNodeSchema,
867
1034
  HealthResponseSchema,
868
1035
  HostMismatchDivergenceSchema,
869
1036
  HypotheticalActionSchema,
@@ -892,6 +1059,7 @@ export {
892
1059
  RegistryFileSchema,
893
1060
  RegistryStatusSchema,
894
1061
  RootCauseResultSchema,
1062
+ RouteNodeSchema,
895
1063
  SearchMatchSchema,
896
1064
  SearchResponseSchema,
897
1065
  SerializedGraphSchema,
@@ -904,6 +1072,7 @@ export {
904
1072
  TransitiveDependenciesResultSchema,
905
1073
  TransitiveDependencySchema,
906
1074
  VersionMismatchDivergenceSchema,
1075
+ WebSocketChannelNodeSchema,
907
1076
  confidenceForExtracted,
908
1077
  confidenceForObservedSignal,
909
1078
  configId,
@@ -912,17 +1081,26 @@ export {
912
1081
  extractedPrecisionFloor,
913
1082
  fileId,
914
1083
  frontierId,
1084
+ graphqlOperationId,
1085
+ grpcMethodId,
915
1086
  inferredEdgeId,
916
1087
  infraId,
1088
+ localDatabaseId,
917
1089
  observedEdgeId,
918
1090
  parseConfigId,
919
1091
  parseDatabaseId,
920
1092
  parseEdgeId,
921
1093
  parseFileId,
922
1094
  parseFrontierId,
1095
+ parseGraphqlOperationId,
1096
+ parseGrpcMethodId,
923
1097
  parseInfraId,
1098
+ parseRouteId,
924
1099
  parseServiceId,
1100
+ parseWebsocketChannelId,
925
1101
  passesExtractedFloor,
926
- serviceId
1102
+ routeId,
1103
+ serviceId,
1104
+ websocketChannelId
927
1105
  };
928
1106
  //# sourceMappingURL=index.js.map