@telorun/kernel 0.60.0 → 0.61.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.
- package/dist/controllers/resource-definition/resource-inherited-controller.d.ts.map +1 -1
- package/dist/controllers/resource-definition/resource-inherited-controller.js +57 -10
- package/dist/controllers/resource-definition/resource-inherited-controller.js.map +1 -1
- package/dist/controllers/type/json-schema-controller.d.ts +8 -0
- package/dist/controllers/type/json-schema-controller.d.ts.map +1 -0
- package/dist/controllers/type/json-schema-controller.js +91 -0
- package/dist/controllers/type/json-schema-controller.js.map +1 -0
- package/dist/evaluation-context.d.ts +5 -0
- package/dist/evaluation-context.d.ts.map +1 -1
- package/dist/evaluation-context.js +63 -33
- package/dist/evaluation-context.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init-failure-diagnostics.d.ts +61 -0
- package/dist/init-failure-diagnostics.d.ts.map +1 -0
- package/dist/init-failure-diagnostics.js +141 -0
- package/dist/init-failure-diagnostics.js.map +1 -0
- package/dist/invocation-contract-binding.d.ts +105 -0
- package/dist/invocation-contract-binding.d.ts.map +1 -0
- package/dist/invocation-contract-binding.js +296 -0
- package/dist/invocation-contract-binding.js.map +1 -0
- package/dist/kernel.d.ts +17 -0
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +62 -5
- package/dist/kernel.js.map +1 -1
- package/dist/module-context.d.ts.map +1 -1
- package/dist/module-context.js +21 -0
- package/dist/module-context.js.map +1 -1
- package/dist/resource-context.d.ts +45 -0
- package/dist/resource-context.d.ts.map +1 -1
- package/dist/resource-context.js +79 -0
- package/dist/resource-context.js.map +1 -1
- package/dist/schema-compiled-values.d.ts +9 -1
- package/dist/schema-compiled-values.d.ts.map +1 -1
- package/dist/schema-compiled-values.js +55 -16
- package/dist/schema-compiled-values.js.map +1 -1
- package/dist/schema-validator.d.ts.map +1 -1
- package/dist/schema-validator.js +15 -1
- package/dist/schema-validator.js.map +1 -1
- package/package.json +3 -3
- package/src/controllers/resource-definition/resource-inherited-controller.ts +69 -10
- package/src/controllers/type/json-schema-controller.ts +114 -0
- package/src/evaluation-context.ts +81 -32
- package/src/index.ts +1 -0
- package/src/init-failure-diagnostics.ts +169 -0
- package/src/invocation-contract-binding.ts +392 -0
- package/src/kernel.ts +83 -6
- package/src/module-context.ts +27 -0
- package/src/resource-context.ts +81 -0
- package/src/schema-compiled-values.ts +55 -15
- package/src/schema-validator.ts +15 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-inherited-controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/resource-definition/resource-inherited-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EAEjB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAG3B;;;;gCAIgC;AAChC,MAAM,WAAW,qBAAqB;IACpC,uBAAuB,CACrB,WAAW,EAAE,iBAAiB,EAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACrC;
|
|
1
|
+
{"version":3,"file":"resource-inherited-controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/resource-definition/resource-inherited-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EAEjB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAG3B;;;;gCAIgC;AAChC,MAAM,WAAW,qBAAqB;IACpC,uBAAuB,CACrB,WAAW,EAAE,iBAAiB,EAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACrC;AA6HD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,kBAAkB,EAC9B,eAAe,EAAE,iBAAiB,EAClC,UAAU,EAAE,WAAW,GACtB,kBAAkB,CA2DpB"}
|
|
@@ -36,33 +36,76 @@ function resolveRefSlot(value, ctx) {
|
|
|
36
36
|
: ctx.moduleContext.resourceInstances.get(name)?.instance;
|
|
37
37
|
return instance ?? undefined;
|
|
38
38
|
}
|
|
39
|
-
/** Expand a
|
|
40
|
-
* a pure `self.<path>` access is navigated directly so live
|
|
41
|
-
* through.
|
|
42
|
-
|
|
39
|
+
/** Expand a mapping node against a CEL scope. `self`-only CEL resolves to
|
|
40
|
+
* literals now; a pure `self.<path>` access is navigated directly so live
|
|
41
|
+
* instances pass through (CEL's output type checker rejects them). Shared by
|
|
42
|
+
* `base:` (construction, scope `{ self }`) and the dispatch mappings
|
|
43
|
+
* `inputs:` / `result:` (scope `{ self, inputs }` / `{ self, result }`). */
|
|
44
|
+
function expandMappingNode(value, scope, ctx) {
|
|
43
45
|
if (isCompiledValue(value)) {
|
|
44
46
|
const src = typeof value.source === "string" ? value.source.trim() : "";
|
|
45
47
|
const m = src.match(SELF_PATH);
|
|
46
48
|
if (m) {
|
|
47
|
-
let cur = self;
|
|
49
|
+
let cur = scope.self;
|
|
48
50
|
for (const key of m[1].split(".").slice(1)) {
|
|
49
51
|
cur = cur?.[key];
|
|
50
52
|
}
|
|
51
53
|
return cur;
|
|
52
54
|
}
|
|
53
|
-
return ctx.expandWith(value,
|
|
55
|
+
return ctx.expandWith(value, scope);
|
|
54
56
|
}
|
|
55
57
|
if (Array.isArray(value))
|
|
56
|
-
return value.map((v) =>
|
|
58
|
+
return value.map((v) => expandMappingNode(v, scope, ctx));
|
|
57
59
|
if (value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
|
|
58
60
|
const out = {};
|
|
59
61
|
for (const [k, v] of Object.entries(value)) {
|
|
60
|
-
out[k] =
|
|
62
|
+
out[k] = expandMappingNode(v, scope, ctx);
|
|
61
63
|
}
|
|
62
64
|
return out;
|
|
63
65
|
}
|
|
64
66
|
return value;
|
|
65
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Bind the dispatch mappings of a child that REPLACED its inherited contract.
|
|
70
|
+
*
|
|
71
|
+
* A contract resolves to the nearest declaration along `extends` and never
|
|
72
|
+
* merges, so a child declaring `inputType` presents a signature the inherited
|
|
73
|
+
* controller has never heard of. `inputs:` is the adapter that turns the child's
|
|
74
|
+
* signature into the parent's call, and `result:` turns the parent's result back
|
|
75
|
+
* into the child's declared output — the same top-level-sibling factoring a
|
|
76
|
+
* template definition uses for `invoke:`.
|
|
77
|
+
*
|
|
78
|
+
* Bound onto the parent instance rather than wrapping it, so the child still IS
|
|
79
|
+
* a parent instance: `init`, `snapshot`, `teardown` and status plumbing are
|
|
80
|
+
* untouched, and nothing new appears in a declared ref slot. It composes with
|
|
81
|
+
* the kernel's contract binding by position — the parent's contract was bound
|
|
82
|
+
* when the parent instance was produced, this mapping goes on next, and the
|
|
83
|
+
* child's own contract is bound outermost by the caller. One dispatch therefore
|
|
84
|
+
* checks the child's inputs, maps, checks the parent's inputs, runs, checks the
|
|
85
|
+
* parent's result, maps back, and checks the child's result.
|
|
86
|
+
*/
|
|
87
|
+
function bindDispatchMapping(instance, definition, self, ctx) {
|
|
88
|
+
const body = definition;
|
|
89
|
+
const inputsMapping = body.inputs;
|
|
90
|
+
const resultMapping = body.result;
|
|
91
|
+
if (inputsMapping == null && resultMapping == null)
|
|
92
|
+
return;
|
|
93
|
+
if (typeof instance.invoke !== "function")
|
|
94
|
+
return;
|
|
95
|
+
// Every argument is forwarded — the mapping rewrites `inputs`, while the
|
|
96
|
+
// InvokeContext (cancellation, tracing) in later parameters belongs to the
|
|
97
|
+
// caller and must reach the inherited controller untouched.
|
|
98
|
+
const original = instance.invoke.bind(instance);
|
|
99
|
+
instance.invoke = async (inputs, ...rest) => {
|
|
100
|
+
const mappedInputs = inputsMapping != null
|
|
101
|
+
? expandMappingNode(inputsMapping, { self, inputs }, ctx)
|
|
102
|
+
: inputs;
|
|
103
|
+
const result = await original(mappedInputs, ...rest);
|
|
104
|
+
return resultMapping != null
|
|
105
|
+
? expandMappingNode(resultMapping, { self, result }, ctx)
|
|
106
|
+
: result;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
66
109
|
/**
|
|
67
110
|
* Controller for a definition that inherits its controller by delegation — it
|
|
68
111
|
* `extends` a concrete kind, declares no own `controllers:` / template body, and
|
|
@@ -107,7 +150,7 @@ export function createInheritedController(definition, definingContext, resolveDe
|
|
|
107
150
|
// instances in `self`), minus the reserved keys.
|
|
108
151
|
let parentConfig;
|
|
109
152
|
if (base != null) {
|
|
110
|
-
parentConfig =
|
|
153
|
+
parentConfig = expandMappingNode(base, { self }, definingContext);
|
|
111
154
|
}
|
|
112
155
|
else {
|
|
113
156
|
const { kind: _kind, metadata: _metadata, name: _name, ...config } = self;
|
|
@@ -122,7 +165,11 @@ export function createInheritedController(definition, definingContext, resolveDe
|
|
|
122
165
|
if (typeof host.createInheritedInstance !== "function") {
|
|
123
166
|
throw new Error(`Telo.Definition '${definition.metadata.name}': inherited controller requires a ResourceContext host that implements createInheritedInstance().`);
|
|
124
167
|
}
|
|
125
|
-
|
|
168
|
+
const instance = await host.createInheritedInstance(definingContext, parentResource);
|
|
169
|
+
if (!instance)
|
|
170
|
+
return null;
|
|
171
|
+
bindDispatchMapping(instance, definition, self, definingContext);
|
|
172
|
+
return instance;
|
|
126
173
|
},
|
|
127
174
|
};
|
|
128
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-inherited-controller.js","sourceRoot":"","sources":["../../../src/controllers/resource-definition/resource-inherited-controller.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,UAAU,GAEX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcpD;;2DAE2D;AAC3D,MAAM,SAAS,GAAG,iCAAiC,CAAC;AAKpD,MAAM,WAAW,GAAG,CAAC,CAAU,EAAqB,EAAE,CACpD,CAAC,CAAC,CAAC,IAAI,OAAQ,CAA4B,CAAC,QAAQ,KAAK,UAAU,CAAC;AAEtE;;;;;0EAK0E;AAC1E,SAAS,cAAc,CAAC,KAAc,EAAE,GAAoB;IAC1D,IAAI,WAAW,CAAC,KAAK,CAAC;QAAE,OAAO,KAAoC,CAAC;IACpE,IAAI,IAAwB,CAAC;IAC7B,IAAI,KAAyB,CAAC;IAC9B,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAqC,CAAC;QACzE,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAChB,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACpB,CAAC;SAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,KAA4C,CAAC;QACzD,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAChB,KAAK,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,QAAQ,GACZ,KAAK,IAAI,KAAK,KAAK,MAAM;QACvB,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC;QACxD,CAAC,CAAE,GAAG,CAAC,aAAa,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,QAAyC,CAAC;IAChG,OAAO,QAAQ,IAAI,SAAS,CAAC;AAC/B,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"resource-inherited-controller.js","sourceRoot":"","sources":["../../../src/controllers/resource-definition/resource-inherited-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResourceContext, ResourceInstance, ResourceManifest } from "@telorun/sdk";
|
|
2
|
+
/** A type resource is pure declaration: it registers a schema and holds the
|
|
3
|
+
* resolved shape, implementing none of the lifecycle verbs. `ResourceInstance`
|
|
4
|
+
* is entirely optional members, so a class with none of them satisfies it only
|
|
5
|
+
* by assertion — the same shape the module-loaded controller had, where the
|
|
6
|
+
* dynamic-import boundary erased the type instead of asserting it. */
|
|
7
|
+
export declare function create(resource: ResourceManifest, ctx: ResourceContext): Promise<ResourceInstance | null>;
|
|
8
|
+
//# sourceMappingURL=json-schema-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/type/json-schema-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AAoDtB;;;;uEAIuE;AACvE,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA+ClC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { evaluate } from "@marcbachmann/cel-js";
|
|
2
|
+
import { canonicalTypeSchemaId, mergeTypeSchemas, RuntimeError } from "@telorun/sdk";
|
|
3
|
+
/**
|
|
4
|
+
* `Telo.JsonSchema` — a named data shape.
|
|
5
|
+
*
|
|
6
|
+
* It lives in the kernel rather than in an installable module for the same
|
|
7
|
+
* reason the mandatory log sinks do: declaring a shape is not optional. Every
|
|
8
|
+
* kind that carries an invocation contract needs one, so requiring an import to
|
|
9
|
+
* write `inputType:` would tax the exact thing contracts want authors to do —
|
|
10
|
+
* and a library declaring its own contract would have to import a module purely
|
|
11
|
+
* to describe itself.
|
|
12
|
+
*
|
|
13
|
+
* `type.JsonSchema` is retained as a deprecated alias with the same behaviour, so
|
|
14
|
+
* published manifests keep resolving.
|
|
15
|
+
*/
|
|
16
|
+
class JsonSchemaType {
|
|
17
|
+
constructor(qualifiedName, rules,
|
|
18
|
+
/** The fully-resolved (post-`extends`), self-contained JSON Schema. Read by
|
|
19
|
+
* consumers that need the effective shape — e.g. a templated resource
|
|
20
|
+
* threading `${{ self.model.schema }}` into a request validation schema. */
|
|
21
|
+
schema) {
|
|
22
|
+
this.qualifiedName = qualifiedName;
|
|
23
|
+
this.rules = rules;
|
|
24
|
+
this.schema = schema;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate data against this type's CEL rules — the invariant layer on top of
|
|
28
|
+
* the schema itself, which AJV enforces through the schema registry.
|
|
29
|
+
*/
|
|
30
|
+
validateRules(data) {
|
|
31
|
+
for (const rule of this.rules) {
|
|
32
|
+
let result;
|
|
33
|
+
try {
|
|
34
|
+
result = evaluate(rule.condition, { this: data });
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw new RuntimeError("ERR_TYPE_VALIDATION_FAILED", `Type "${this.qualifiedName}" rule evaluation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
38
|
+
}
|
|
39
|
+
if (result !== true) {
|
|
40
|
+
throw new RuntimeError(rule.code, rule.message ??
|
|
41
|
+
`Type "${this.qualifiedName}" validation failed: rule "${rule.code}" not satisfied`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** A type resource is pure declaration: it registers a schema and holds the
|
|
47
|
+
* resolved shape, implementing none of the lifecycle verbs. `ResourceInstance`
|
|
48
|
+
* is entirely optional members, so a class with none of them satisfies it only
|
|
49
|
+
* by assertion — the same shape the module-loaded controller had, where the
|
|
50
|
+
* dynamic-import boundary erased the type instead of asserting it. */
|
|
51
|
+
export async function create(resource, ctx) {
|
|
52
|
+
const qualifiedName = `${resource.metadata.module}.${resource.metadata.name}`;
|
|
53
|
+
const ownSchema = resource.schema;
|
|
54
|
+
let schema = ownSchema;
|
|
55
|
+
const extendsField = resource.extends;
|
|
56
|
+
if (extendsField) {
|
|
57
|
+
const parents = Array.isArray(extendsField) ? extendsField : [extendsField];
|
|
58
|
+
const parentSchemas = [];
|
|
59
|
+
for (const parent of parents) {
|
|
60
|
+
const parentSchema = ctx.lookupSchema(parent);
|
|
61
|
+
// Defer if any parent schema isn't registered yet (multi-pass resolution).
|
|
62
|
+
if (!parentSchema)
|
|
63
|
+
return null;
|
|
64
|
+
parentSchemas.push(parentSchema);
|
|
65
|
+
}
|
|
66
|
+
// Each parent's registered schema is itself already resolved, so merging
|
|
67
|
+
// them makes inheritance transitive through grandparents with no `$ref`s
|
|
68
|
+
// left in the result.
|
|
69
|
+
schema = mergeTypeSchemas([...parentSchemas, ownSchema]);
|
|
70
|
+
}
|
|
71
|
+
const rules = (Array.isArray(resource.rules) ? resource.rules : []);
|
|
72
|
+
ctx.registerSchema(qualifiedName, schema);
|
|
73
|
+
ctx.registerTypeRules(qualifiedName, rules);
|
|
74
|
+
// Also register under the short name so types can be referenced without a
|
|
75
|
+
// module prefix.
|
|
76
|
+
const shortName = resource.metadata.name;
|
|
77
|
+
if (shortName !== qualifiedName) {
|
|
78
|
+
ctx.registerSchema(shortName, schema);
|
|
79
|
+
ctx.registerTypeRules(shortName, rules);
|
|
80
|
+
}
|
|
81
|
+
// Canonical module-scoped id — the target of `$ref: "telo://Self/<name>"` (and
|
|
82
|
+
// `telo://<Alias>/<name>` across imports) once the loader resolves the
|
|
83
|
+
// authority to this module. Authority-free, so a validator can actually
|
|
84
|
+
// resolve the reference; see `canonicalTypeSchemaId`.
|
|
85
|
+
const moduleName = resource.metadata.module;
|
|
86
|
+
if (moduleName) {
|
|
87
|
+
ctx.registerSchema(canonicalTypeSchemaId(moduleName, shortName), schema);
|
|
88
|
+
}
|
|
89
|
+
return new JsonSchemaType(qualifiedName, rules, schema);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=json-schema-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-controller.js","sourceRoot":"","sources":["../../../src/controllers/type/json-schema-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -59,6 +59,11 @@ export declare class EvaluationContext implements IEvaluationContext {
|
|
|
59
59
|
}>;
|
|
60
60
|
/** Resources queued for initialization on this context node. */
|
|
61
61
|
private pendingResources;
|
|
62
|
+
/** Per-resource dependency names, captured at create() time — BEFORE Phase-5
|
|
63
|
+
* injection swaps refs for live instances, so the walk sees plain objects and
|
|
64
|
+
* cannot wander into a controller's (possibly cyclic) object graph. Read only
|
|
65
|
+
* when init fails, to attribute each failure to its cause. */
|
|
66
|
+
private readonly resourceDependencies;
|
|
62
67
|
/**
|
|
63
68
|
* Optional hook called between create() and init() for each resource.
|
|
64
69
|
* Set by the kernel to inject live instances into reference fields.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluation-context.d.ts","sourceRoot":"","sources":["../src/evaluation-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,WAAW,EAEX,KAAK,iBAAiB,IAAI,kBAAkB,EAC5C,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAGlB,KAAK,WAAW,EAChB,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"evaluation-context.d.ts","sourceRoot":"","sources":["../src/evaluation-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { formatSpanCounter } from "./logging/span-id.js";
|
|
|
3
3
|
import { getRefIdentity, isCompiledValue, isInvokeError, isCancellationError, resourceKey, UNCANCELLABLE_CONTEXT, } from "@telorun/sdk";
|
|
4
4
|
import { RuntimeError } from "@telorun/sdk";
|
|
5
5
|
import { evalPathCovers } from "@telorun/analyzer";
|
|
6
|
+
import { classifyInitFailures, renderInitFailureText, summarizeInitFailures, } from "./init-failure-diagnostics.js";
|
|
6
7
|
import { acceptReportedStatus, buildPublishedProps, diagnoseObservedStateAccess, } from "./observed-state.js";
|
|
7
8
|
export { resourceKey };
|
|
8
9
|
/** A pure resolved reference is a `{ kind, name, alias? }` object and nothing
|
|
@@ -65,6 +66,15 @@ function collectResourceRefs(resource) {
|
|
|
65
66
|
}
|
|
66
67
|
return [...found.values()];
|
|
67
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Project resource refs onto the names they depend on IN THIS CONTEXT. A local
|
|
71
|
+
* ref is its own name; a cross-module `Alias.name` ref depends on the local
|
|
72
|
+
* `Telo.Import` resource named by the alias, since that is the resource whose
|
|
73
|
+
* failure would strand it. Used to attribute an init failure to its cause.
|
|
74
|
+
*/
|
|
75
|
+
function localDependencyNames(refs) {
|
|
76
|
+
return refs.map((r) => (r.alias && r.alias !== "Self" ? r.alias : r.name));
|
|
77
|
+
}
|
|
68
78
|
/**
|
|
69
79
|
* Build a resource's resolved properties for the debug stream — its config "after
|
|
70
80
|
* templating", with `${{ }}` / `!cel` reduced to concrete values. The manifest is
|
|
@@ -308,6 +318,11 @@ export class EvaluationContext {
|
|
|
308
318
|
this.createdInstances = new Map();
|
|
309
319
|
/** Resources queued for initialization on this context node. */
|
|
310
320
|
this.pendingResources = [];
|
|
321
|
+
/** Per-resource dependency names, captured at create() time — BEFORE Phase-5
|
|
322
|
+
* injection swaps refs for live instances, so the walk sees plain objects and
|
|
323
|
+
* cannot wander into a controller's (possibly cyclic) object graph. Read only
|
|
324
|
+
* when init fails, to attribute each failure to its cause. */
|
|
325
|
+
this.resourceDependencies = new Map();
|
|
311
326
|
/** Cache of compiled walker closures keyed on the manifest subtree they walk.
|
|
312
327
|
* WeakMap so entries are GC'd if the manifest is reloaded. */
|
|
313
328
|
this.walkerCache = new WeakMap();
|
|
@@ -515,6 +530,8 @@ export class EvaluationContext {
|
|
|
515
530
|
errors.delete(name);
|
|
516
531
|
progress = true;
|
|
517
532
|
const createdRes = created.resource;
|
|
533
|
+
const refs = collectResourceRefs(createdRes);
|
|
534
|
+
this.resourceDependencies.set(name, localDependencyNames(refs));
|
|
518
535
|
const payload = {
|
|
519
536
|
resource: {
|
|
520
537
|
kind: createdRes.kind,
|
|
@@ -523,7 +540,7 @@ export class EvaluationContext {
|
|
|
523
540
|
id: this.resourceId(createdRes.kind, createdRes.metadata.name),
|
|
524
541
|
},
|
|
525
542
|
...(this.owner ? { owner: this.owner } : {}),
|
|
526
|
-
dependencies: this.qualifyDeps(
|
|
543
|
+
dependencies: this.qualifyDeps(refs),
|
|
527
544
|
};
|
|
528
545
|
// `properties` (the resolved config) is a second full config walk plus
|
|
529
546
|
// a secret scrub. Build it lazily: the EventBus short-circuits when
|
|
@@ -553,7 +570,7 @@ export class EvaluationContext {
|
|
|
553
570
|
if (this.preInitHook) {
|
|
554
571
|
this.preInitHook(resource, (n, alias) => alias && alias !== "Self"
|
|
555
572
|
? this.resolveImportedInstance(alias, n)
|
|
556
|
-
: this.resourceInstances.get(n)?.instance, (n) => this.hasManifest(n) && !this.resourceInstances.has(n));
|
|
573
|
+
: this.resourceInstances.get(n)?.instance, (n) => this.hasManifest(n) && !this.resourceInstances.has(n), this);
|
|
557
574
|
}
|
|
558
575
|
if (instance.init)
|
|
559
576
|
await instance.init(ctx);
|
|
@@ -566,6 +583,9 @@ export class EvaluationContext {
|
|
|
566
583
|
await this.publishSnapshot(name);
|
|
567
584
|
this.resourceInstances.set(name, { resource, instance });
|
|
568
585
|
this.createdInstances.delete(name);
|
|
586
|
+
// Read only on failure, and this one succeeded — drop it rather than
|
|
587
|
+
// holding a dep-name array per resource for the context's lifetime.
|
|
588
|
+
this.resourceDependencies.delete(name);
|
|
569
589
|
errors.delete(name);
|
|
570
590
|
progress = true;
|
|
571
591
|
await this.emit(`${resource.kind}.${resource.metadata.name}.Initialized`, {
|
|
@@ -588,36 +608,27 @@ export class EvaluationContext {
|
|
|
588
608
|
break;
|
|
589
609
|
} while (pass <= MAX_PASSES);
|
|
590
610
|
if (this.pendingResources.length > 0 || this.createdInstances.size > 0) {
|
|
591
|
-
const
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
code: info.code,
|
|
610
|
-
};
|
|
611
|
-
}),
|
|
611
|
+
const toFailure = (name, kind, deps) => {
|
|
612
|
+
const info = errors.get(name) ?? { message: "Unknown error" };
|
|
613
|
+
return {
|
|
614
|
+
resource: name,
|
|
615
|
+
kind,
|
|
616
|
+
message: info.message,
|
|
617
|
+
details: info.details,
|
|
618
|
+
code: info.code,
|
|
619
|
+
children: info.children,
|
|
620
|
+
deps,
|
|
621
|
+
};
|
|
622
|
+
};
|
|
623
|
+
const failures = [
|
|
624
|
+
// A resource that never got created was never injected either, so its
|
|
625
|
+
// manifest still carries plain `{kind, name}` refs — walk it here rather
|
|
626
|
+
// than relying on the create-time capture it never reached.
|
|
627
|
+
...this.pendingResources.map((r) => toFailure(r.metadata.name, r.kind, localDependencyNames(collectResourceRefs(r)))),
|
|
628
|
+
...[...this.createdInstances].map(([name, { resource }]) => toFailure(name, resource.kind, this.resourceDependencies.get(name) ?? [])),
|
|
612
629
|
];
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
const head = ` ${d.kind ? `${d.kind} ` : ""}${d.resource}: ${d.message}${d.code ? ` [${d.code}]` : ""}`;
|
|
616
|
-
const extra = d.details ? "\n" + d.details.split("\n").map((l) => ` ${l}`).join("\n") : "";
|
|
617
|
-
return head + extra;
|
|
618
|
-
})
|
|
619
|
-
.join("\n");
|
|
620
|
-
throw new RuntimeError("ERR_RESOURCE_INITIALIZATION_FAILED", `Unable to process resources:\n${textDetails}`, diagnostics);
|
|
630
|
+
const diagnostics = classifyInitFailures(failures);
|
|
631
|
+
throw new RuntimeError("ERR_RESOURCE_INITIALIZATION_FAILED", `${summarizeInitFailures(diagnostics)}:\n${renderInitFailureText(diagnostics)}`, diagnostics);
|
|
621
632
|
}
|
|
622
633
|
this.state = "Initialized";
|
|
623
634
|
}
|
|
@@ -664,7 +675,7 @@ export class EvaluationContext {
|
|
|
664
675
|
// Propagate injection hook: extend getInstance to also resolve parent singleton instances.
|
|
665
676
|
if (parent.preInitHook) {
|
|
666
677
|
const parentHook = parent.preInitHook;
|
|
667
|
-
child.preInitHook = (resource, childGetInstance, childIsPending) => {
|
|
678
|
+
child.preInitHook = (resource, childGetInstance, childIsPending, owner) => {
|
|
668
679
|
parentHook(resource, (name, alias) => {
|
|
669
680
|
if (alias && alias !== "Self")
|
|
670
681
|
return parent.resolveImportedInstance(alias, name);
|
|
@@ -685,7 +696,10 @@ export class EvaluationContext {
|
|
|
685
696
|
},
|
|
686
697
|
// Only a scope-local dependency can still be pending — an outer resource
|
|
687
698
|
// is live by the time a scope opens — so the child's own predicate suffices.
|
|
688
|
-
childIsPending
|
|
699
|
+
childIsPending,
|
|
700
|
+
// Forwarded, not replaced by `child`: a `with:` nested inside a scoped
|
|
701
|
+
// resource must still resolve kinds against the scope it opened in.
|
|
702
|
+
owner);
|
|
689
703
|
};
|
|
690
704
|
}
|
|
691
705
|
try {
|
|
@@ -1446,6 +1460,22 @@ function formatErrorForDiagnostic(err) {
|
|
|
1446
1460
|
if (!(err instanceof Error)) {
|
|
1447
1461
|
return { message: String(err) };
|
|
1448
1462
|
}
|
|
1463
|
+
// A nested context's aggregate (an import initializing its library's
|
|
1464
|
+
// resources) already carries a classified diagnostic list. Keep it structured
|
|
1465
|
+
// instead of letting the cause-chain walk flatten it into this entry's
|
|
1466
|
+
// message: the child's root causes stay distinguishable from the child's own
|
|
1467
|
+
// cascade, and the error count sees the real leaves rather than one import.
|
|
1468
|
+
// The headline is re-derived from the diagnostics, never recovered by parsing
|
|
1469
|
+
// the message the child already rendered from them.
|
|
1470
|
+
if (err instanceof RuntimeError &&
|
|
1471
|
+
err.code === "ERR_RESOURCE_INITIALIZATION_FAILED" &&
|
|
1472
|
+
err.diagnostics?.length) {
|
|
1473
|
+
return {
|
|
1474
|
+
message: summarizeInitFailures(err.diagnostics),
|
|
1475
|
+
code: err.code,
|
|
1476
|
+
children: err.diagnostics,
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1449
1479
|
const detailLines = [];
|
|
1450
1480
|
const seen = new Set();
|
|
1451
1481
|
let current = err;
|