@telorun/analyzer 0.53.0 → 0.54.0

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.
Files changed (76) hide show
  1. package/dist/analysis-registry.d.ts +8 -0
  2. package/dist/analysis-registry.d.ts.map +1 -1
  3. package/dist/analysis-registry.js +21 -3
  4. package/dist/analyzer.d.ts +3 -2
  5. package/dist/analyzer.d.ts.map +1 -1
  6. package/dist/analyzer.js +188 -26
  7. package/dist/builtins.d.ts.map +1 -1
  8. package/dist/builtins.js +32 -12
  9. package/dist/call-graph.d.ts +189 -0
  10. package/dist/call-graph.d.ts.map +1 -0
  11. package/dist/call-graph.js +617 -0
  12. package/dist/dependency-graph.d.ts +17 -7
  13. package/dist/dependency-graph.d.ts.map +1 -1
  14. package/dist/dependency-graph.js +36 -65
  15. package/dist/flatten-for-analyzer.d.ts +8 -0
  16. package/dist/flatten-for-analyzer.d.ts.map +1 -1
  17. package/dist/flatten-for-analyzer.js +32 -0
  18. package/dist/index.d.ts +14 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +7 -1
  21. package/dist/manifest-navigation.d.ts +32 -0
  22. package/dist/manifest-navigation.d.ts.map +1 -0
  23. package/dist/manifest-navigation.js +91 -0
  24. package/dist/manifest-visitor.js +1 -1
  25. package/dist/ref-slot.d.ts +125 -0
  26. package/dist/ref-slot.d.ts.map +1 -0
  27. package/dist/ref-slot.js +226 -0
  28. package/dist/reference-field-map.d.ts +15 -1
  29. package/dist/reference-field-map.d.ts.map +1 -1
  30. package/dist/reference-field-map.js +29 -35
  31. package/dist/resolve-schema-ref-kinds.d.ts +4 -0
  32. package/dist/resolve-schema-ref-kinds.d.ts.map +1 -1
  33. package/dist/resolve-schema-ref-kinds.js +31 -8
  34. package/dist/resolve-zone-requirements.d.ts +110 -0
  35. package/dist/resolve-zone-requirements.d.ts.map +1 -0
  36. package/dist/resolve-zone-requirements.js +541 -0
  37. package/dist/types.d.ts +8 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/validate-observed-state.d.ts +14 -13
  40. package/dist/validate-observed-state.d.ts.map +1 -1
  41. package/dist/validate-observed-state.js +21 -88
  42. package/dist/validate-ref-slots.d.ts +48 -0
  43. package/dist/validate-ref-slots.d.ts.map +1 -0
  44. package/dist/validate-ref-slots.js +219 -0
  45. package/dist/validate-references.d.ts.map +1 -1
  46. package/dist/validate-references.js +8 -1
  47. package/dist/validate-zone-slots.d.ts +39 -0
  48. package/dist/validate-zone-slots.d.ts.map +1 -0
  49. package/dist/validate-zone-slots.js +114 -0
  50. package/dist/zone-module-documents.d.ts +27 -0
  51. package/dist/zone-module-documents.d.ts.map +1 -0
  52. package/dist/zone-module-documents.js +1 -0
  53. package/dist/zone-slot.d.ts +61 -0
  54. package/dist/zone-slot.d.ts.map +1 -0
  55. package/dist/zone-slot.js +91 -0
  56. package/package.json +3 -3
  57. package/src/analysis-registry.ts +20 -2
  58. package/src/analyzer.ts +206 -24
  59. package/src/builtins.ts +32 -12
  60. package/src/call-graph.ts +827 -0
  61. package/src/dependency-graph.ts +34 -68
  62. package/src/flatten-for-analyzer.ts +32 -0
  63. package/src/index.ts +47 -0
  64. package/src/manifest-navigation.ts +91 -0
  65. package/src/manifest-visitor.ts +1 -1
  66. package/src/ref-slot.ts +273 -0
  67. package/src/reference-field-map.ts +39 -36
  68. package/src/resolve-schema-ref-kinds.ts +34 -7
  69. package/src/resolve-zone-requirements.ts +781 -0
  70. package/src/types.ts +8 -0
  71. package/src/validate-observed-state.ts +26 -92
  72. package/src/validate-ref-slots.ts +293 -0
  73. package/src/validate-references.ts +8 -1
  74. package/src/validate-zone-slots.ts +175 -0
  75. package/src/zone-module-documents.ts +27 -0
  76. package/src/zone-slot.ts +116 -0
@@ -0,0 +1,189 @@
1
+ /**
2
+ * The typed reference graph — one model of "what calls what", replacing the
3
+ * private walkers each analysis used to build for itself.
4
+ *
5
+ * **Two node kinds.** Resource nodes carry their declaration-site identity. Step
6
+ * nodes carry name, lexical order, enclosing array and nesting parent, and
7
+ * *optionally* an outgoing edge. Steps are nodes rather than edge decorations
8
+ * because a pure `value:` step produces `steps.<name>.result` while referencing
9
+ * nothing — it has no edge to hang on — and because step identity, ordering and
10
+ * nesting are exactly what `steps.<name>.result` typing, per-step throws
11
+ * coverage and the editor's step rendering consume.
12
+ *
13
+ * **Lexical order and containment, not execution order.** Order is the written
14
+ * order of the array; which branch actually runs is decided by runtime
15
+ * predicates and is not statically derivable. That is sufficient by
16
+ * construction: result typing needs step names, throws coverage needs
17
+ * `try` / `catch` containment rather than which arm fires, and the editor
18
+ * renders rows as written.
19
+ *
20
+ * **Edges are `(from, slot, to, use)` and the graph is a MULTIGRAPH.** The slot
21
+ * path is part of an edge's identity, so a kind declaring several ref slots
22
+ * emits one edge per slot, each with its own `use` — `Cache.View` holds its
23
+ * `store:` as a `dependency` while its `invoke:` is a `call` — and two slots may
24
+ * name the same target without collapsing. Array slots emit one edge per
25
+ * element. This is a requirement, not a detail: the old `dependency-graph.ts`
26
+ * kept a set-valued adjacency map, which erases parallel edges and would
27
+ * silently merge a dependency with a call. The init-order consumer projects the
28
+ * multigraph down to unique pairs itself, since that is the only consumer for
29
+ * which the distinction genuinely does not matter.
30
+ *
31
+ * **Three discovery mechanics, one graph.** Field-map sites (Phase-5 injection
32
+ * sites — `edge.injected`), schema-driven step slots behind the local `$ref`s
33
+ * the field map deliberately does not descend, and a value-tree scan for `!ref`
34
+ * anywhere else — so a ref in a structure no annotation anticipated is still an
35
+ * edge (with no declared `use`, read conservatively). Inline declarations
36
+ * inside `x-telo-scope` arrays become nodes of their own and their slots are
37
+ * walked, so a `with:`-scoped resource's references are part of the one model.
38
+ *
39
+ * Browser-safe: no Node built-ins.
40
+ */
41
+ import type { ResourceManifest } from "@telorun/sdk";
42
+ import type { AliasResolver } from "./alias-resolver.js";
43
+ import type { DefinitionRegistry } from "./definition-registry.js";
44
+ import { type RefUse, type RefUseCases } from "./ref-slot.js";
45
+ export interface ResourceGraphNode {
46
+ type: "resource";
47
+ id: string;
48
+ kind: string;
49
+ name: string;
50
+ manifest: ResourceManifest;
51
+ /** Declared inside another resource's `x-telo-scope` array: created when the
52
+ * scope opens rather than at boot, so it takes no part in init ordering. Its
53
+ * declaration-site identity is the scope site, never the module. */
54
+ scoped?: boolean;
55
+ /** Node id of the resource whose scope declares this one (set iff `scoped`). */
56
+ scopeOwner?: string;
57
+ /** The scope field's JSON Pointer on the owner (set iff `scoped`). */
58
+ scopeSite?: string;
59
+ }
60
+ export interface StepGraphNode {
61
+ type: "step";
62
+ id: string;
63
+ /** The step's declared `name:`, when it has one. */
64
+ name?: string;
65
+ /** Node id of the resource whose body declares this step. */
66
+ owner: string;
67
+ /** Concrete path within the owner (`steps[0].do[1]`). */
68
+ path: string;
69
+ /** Concrete path of the enclosing step array (`steps`, `steps[0].do`). */
70
+ array: string;
71
+ /** Enclosing step node, when this step nests inside another's branch. */
72
+ parent?: string;
73
+ /** Lexical index within its own array. */
74
+ index: number;
75
+ /** The step value as written. */
76
+ step: Record<string, unknown>;
77
+ }
78
+ export type CallGraphNode = ResourceGraphNode | StepGraphNode;
79
+ export interface CallGraphEdge {
80
+ /** Node id of the resource or step that declares the slot. */
81
+ from: string;
82
+ /** The referenced resource's NAME, always present — including when no node
83
+ * carries it. A `!ref` to a name that does not exist is a real edge some
84
+ * other validator reports; dropping it would make the graph disagree with
85
+ * the manifest about what was written. */
86
+ toName: string;
87
+ /** Node id of the target, when the name resolves to one. A name declared in
88
+ * the source's own scope resolves to the SCOPED node (scope-local first, the
89
+ * order `ScopeContext` and `!ref` already agree on), never to a same-named
90
+ * module-level resource. */
91
+ to?: string;
92
+ /** Field-map path of the slot — part of the edge's identity. */
93
+ slot: string;
94
+ /** Concrete path of this site (`routes[2].handler`). */
95
+ path: string;
96
+ /**
97
+ * What the declaring resource does with the target at this site. Resolved
98
+ * against a case map's selector when the graph could read it; otherwise every
99
+ * use the slot could take (see {@link CallGraphEdge.unresolved}).
100
+ */
101
+ use: RefUse[];
102
+ /** Set when a case map's selector could not be resolved statically, so `use`
103
+ * is the union of the map's cases rather than the one that holds. */
104
+ unresolved?: RefUseCases;
105
+ /** Why the selector did not resolve: written in CEL (`dynamic` — a
106
+ * diagnostic, see `validate-ref-slots.ts`), absent with no schema default
107
+ * (`absent`), or a literal matching no case (`unmatched`). */
108
+ unresolvedReason?: "dynamic" | "absent" | "unmatched";
109
+ /** JSON Pointer to the field carrying this call's arguments, when declared. */
110
+ inputs?: string;
111
+ /** This site is a Phase-5 injection site — the reference field map reaches
112
+ * it, so the kernel puts the live instance into the field before `init()`.
113
+ * THE init-order criterion: injection is what forces construct-before-use,
114
+ * regardless of whether the slot is declared at resource level or inside an
115
+ * inline step array (`Telo.Application.targets`). Step slots behind a local
116
+ * `$ref` and value-tree-discovered refs are not injection sites — those
117
+ * resolve at dispatch. */
118
+ injected?: boolean;
119
+ /** Found by the value-tree scan rather than a declared slot — no schema, no
120
+ * declared `use` (read conservatively as control-transferring). */
121
+ nested?: boolean;
122
+ /** The target is declared INSIDE the source's own `x-telo-scope`, so it is
123
+ * created on demand when the scope opens rather than at boot. Recorded rather
124
+ * than dropped: it is a real edge, and only the init-order consumer wants it
125
+ * gone. */
126
+ scoped?: boolean;
127
+ }
128
+ export interface CallGraph {
129
+ nodes: ReadonlyMap<string, CallGraphNode>;
130
+ edges: readonly CallGraphEdge[];
131
+ /** Edges leaving a node, in declaration order. */
132
+ edgesFrom(id: string): CallGraphEdge[];
133
+ /** Edges arriving at a resource node. */
134
+ edgesTo(id: string): CallGraphEdge[];
135
+ resource(kind: string, name: string): ResourceGraphNode | undefined;
136
+ resourceByName(name: string): ResourceGraphNode | undefined;
137
+ /** Step nodes declared by a resource, in lexical order. */
138
+ steps(resourceId: string): StepGraphNode[];
139
+ /** Every edge whose `use` includes at least one control transfer, plus every
140
+ * edge whose slot declares no `use` at all — see {@link CallGraph.controlEdges}. */
141
+ controlEdges(): CallGraphEdge[];
142
+ }
143
+ export declare const resourceId: (kind: string, name: string) => string;
144
+ export interface BuildCallGraphOptions {
145
+ aliases?: AliasResolver;
146
+ aliasesByModule?: Map<string, AliasResolver>;
147
+ }
148
+ /**
149
+ * Build the call graph for one manifest set.
150
+ *
151
+ * Reference discovery is three-fold. Field-map sites come from `visitManifest`
152
+ * — the same walk the reference validators use — and are stamped `injected`,
153
+ * because those and only those are Phase-5 injection sites. Step slots are read
154
+ * from the step item schema, because they sit behind local `$ref`s the field
155
+ * map deliberately does not descend. Everything else is caught by the value-
156
+ * tree scan (`discoverNestedRefs`): a `!ref` is an explicit marker, so a ref in
157
+ * a structure no annotation anticipated is still an edge — with no declared
158
+ * `use`, read conservatively — instead of a blind spot. Inline declarations in
159
+ * `x-telo-scope` arrays become scoped nodes with edges of their own.
160
+ */
161
+ export declare function buildCallGraph(resources: ResourceManifest[], registry: DefinitionRegistry, options?: BuildCallGraphOptions): CallGraph;
162
+ export interface ProjectToPairsOptions {
163
+ /** Keep only edges whose use satisfies this. Omit to keep every edge. */
164
+ keepUse?: (use: RefUse[]) => boolean;
165
+ /** Also include edges that are NOT injection sites (step slots behind a
166
+ * `$ref`, value-tree-discovered refs). Default false — see below. */
167
+ includeNonInjected?: boolean;
168
+ }
169
+ /**
170
+ * Unique `(from, to)` pairs, dropping slot identity and `use`. The projection
171
+ * the init-order consumer needs — the only consumer for which the distinction
172
+ * between two parallel edges genuinely does not matter.
173
+ *
174
+ * **Only injection sites order boot, and that is a property of the SITE, never
175
+ * of the node kind.** A site the reference field map reaches is a Phase-5
176
+ * injection site: the kernel puts the live instance into the field before
177
+ * `init()`, so the target must be constructed first — and that is as true for
178
+ * `Telo.Application`'s inline `targets[].invoke` (a step-declared slot the
179
+ * field map reaches) as for a resource-level `connection:`. A step slot behind
180
+ * a local `$ref` and a value-tree-discovered ref resolve at dispatch instead,
181
+ * so their targets need only exist by the time the step runs. An earlier
182
+ * revision keyed this on node kind and silently dropped boot targets' inline
183
+ * invoke edges from init order — the regression this comment exists to prevent.
184
+ *
185
+ * Scoped nodes take no part at all: a `with:`-scoped resource is created when
186
+ * the scope opens, and an edge into a scope is the owner's runtime business.
187
+ */
188
+ export declare function projectToPairs(graph: CallGraph, options?: ProjectToPairsOptions): Map<string, Set<string>>;
189
+ //# sourceMappingURL=call-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"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"}