@telorun/kernel 0.56.0 → 0.58.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/module/import-controller.d.ts.map +1 -1
- package/dist/controllers/module/import-controller.js +7 -3
- package/dist/controllers/module/import-controller.js.map +1 -1
- package/dist/controllers/resource-definition/resource-definition-controller.d.ts +1 -0
- package/dist/controllers/resource-definition/resource-definition-controller.d.ts.map +1 -1
- package/dist/controllers/resource-definition/resource-definition-controller.js +10 -1
- package/dist/controllers/resource-definition/resource-definition-controller.js.map +1 -1
- package/dist/evaluation-context.d.ts +57 -2
- package/dist/evaluation-context.d.ts.map +1 -1
- package/dist/evaluation-context.js +209 -8
- package/dist/evaluation-context.js.map +1 -1
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +6 -3
- package/dist/kernel.js.map +1 -1
- package/dist/manifest-schemas.d.ts +8 -0
- package/dist/manifest-schemas.d.ts.map +1 -1
- package/dist/manifest-schemas.js +6 -0
- package/dist/manifest-schemas.js.map +1 -1
- package/dist/module-context.d.ts +8 -0
- package/dist/module-context.d.ts.map +1 -1
- package/dist/module-context.js +20 -5
- package/dist/module-context.js.map +1 -1
- package/dist/observed-state.d.ts +94 -0
- package/dist/observed-state.d.ts.map +1 -0
- package/dist/observed-state.js +148 -0
- package/dist/observed-state.js.map +1 -0
- package/dist/resource-context.d.ts +50 -1
- package/dist/resource-context.d.ts.map +1 -1
- package/dist/resource-context.js +56 -12
- package/dist/resource-context.js.map +1 -1
- package/dist/transports/oci/oci-ref.d.ts +1 -1
- package/dist/transports/oci/oci-ref.d.ts.map +1 -1
- package/dist/transports/oci/oci-ref.js +1 -1
- package/dist/transports/oci/oci-ref.js.map +1 -1
- package/dist/transports/oci/oci-transport.d.ts.map +1 -1
- package/dist/transports/oci/oci-transport.js +7 -10
- package/dist/transports/oci/oci-transport.js.map +1 -1
- package/dist/transports/registry-transport.d.ts.map +1 -1
- package/dist/transports/registry-transport.js +3 -8
- package/dist/transports/registry-transport.js.map +1 -1
- package/package.json +3 -3
- package/src/controllers/module/import-controller.ts +12 -3
- package/src/controllers/resource-definition/resource-definition-controller.ts +14 -0
- package/src/evaluation-context.ts +253 -8
- package/src/kernel.ts +5 -0
- package/src/manifest-schemas.ts +6 -0
- package/src/module-context.ts +19 -5
- package/src/observed-state.ts +210 -0
- package/src/resource-context.ts +55 -11
- package/src/transports/oci/oci-ref.ts +8 -1
- package/src/transports/oci/oci-transport.ts +12 -9
- package/src/transports/registry-transport.ts +4 -6
package/src/resource-context.ts
CHANGED
|
@@ -104,6 +104,23 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
104
104
|
stderr?: NodeJS.WritableStream,
|
|
105
105
|
args?: ParsedArgs,
|
|
106
106
|
ownerPrefix = "",
|
|
107
|
+
/**
|
|
108
|
+
* The context that OWNS this instance — the module context for a top-level
|
|
109
|
+
* resource, the per-run scope child for a `with:`-scoped one.
|
|
110
|
+
*
|
|
111
|
+
* Everything resource-scoped goes through here: registering a manifest,
|
|
112
|
+
* resolving a sibling by name, expanding CEL, spawning a child context,
|
|
113
|
+
* dispatching, publishing. `moduleContext` is reserved for what genuinely
|
|
114
|
+
* belongs to the MODULE rather than to this resource's context — imports
|
|
115
|
+
* (`registerImport` / `resolveImported*`), the controller policy, and the
|
|
116
|
+
* logging scope, all of which a scope child inherits rather than owns.
|
|
117
|
+
*
|
|
118
|
+
* Getting this wrong is not cosmetic: a scoped resource that registers an
|
|
119
|
+
* inline definition into the module lands it in a pending queue the module's
|
|
120
|
+
* init loop has already drained, so the resource is never created and the
|
|
121
|
+
* dispatch fails.
|
|
122
|
+
*/
|
|
123
|
+
private readonly owningContext: IEvaluationContext = moduleContext,
|
|
107
124
|
) {
|
|
108
125
|
// `ctx.env` is the sanctioned host-env channel for controllers — always the
|
|
109
126
|
// real environment (kernel passes its snapshot), never the locked Proxy.
|
|
@@ -115,6 +132,22 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
115
132
|
this.ownerPrefix = ownerPrefix;
|
|
116
133
|
}
|
|
117
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Where a NAME resolves from: the owning context first, then the enclosing
|
|
137
|
+
* module. Same order as `ScopeContext.getInstance` and the CEL `resources`
|
|
138
|
+
* layering — scope-local wins, outer is the fallback — so a `with:`-scoped
|
|
139
|
+
* resource can still dispatch a module-level one by name (an `Http.Server`
|
|
140
|
+
* whose `notFoundHandler` targets a module-level invocable).
|
|
141
|
+
*
|
|
142
|
+
* Registration deliberately does NOT use this: a new manifest belongs to the
|
|
143
|
+
* context that owns the resource creating it, never to the module.
|
|
144
|
+
*/
|
|
145
|
+
private contextForName(name: string): IEvaluationContext {
|
|
146
|
+
return this.owningContext.resourceInstances.has(name)
|
|
147
|
+
? this.owningContext
|
|
148
|
+
: this.moduleContext;
|
|
149
|
+
}
|
|
150
|
+
|
|
118
151
|
createSchemaValidator(schema: any) {
|
|
119
152
|
if (!schema) {
|
|
120
153
|
return new NoopValidator();
|
|
@@ -228,7 +261,7 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
228
261
|
// failure to the EventBus rather than letting it go unhandled. We track the
|
|
229
262
|
// error-handled chain (not the raw promise) so teardown drains a task whose
|
|
230
263
|
// settlement is already observed here.
|
|
231
|
-
const tracked = this.
|
|
264
|
+
const tracked = this.owningContext
|
|
232
265
|
.runDetached(fn) // bare scope-detach primitive
|
|
233
266
|
.catch(async (err: unknown) => {
|
|
234
267
|
const detail =
|
|
@@ -266,11 +299,11 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
266
299
|
}
|
|
267
300
|
|
|
268
301
|
openSpan(base: InvokeContext | undefined, opts: OpenSpanOptions): Promise<OpenSpan> {
|
|
269
|
-
return this.
|
|
302
|
+
return this.owningContext.openSpan(base, opts);
|
|
270
303
|
}
|
|
271
304
|
|
|
272
305
|
invoke<TInputs>(kind: string, name: string, inputs: TInputs): Promise<any> {
|
|
273
|
-
return this.
|
|
306
|
+
return this.contextForName(name).invoke(kind, name, inputs);
|
|
274
307
|
}
|
|
275
308
|
|
|
276
309
|
invokeResolved<TInputs>(
|
|
@@ -280,7 +313,7 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
280
313
|
inputs: TInputs,
|
|
281
314
|
ctx?: InvokeContext,
|
|
282
315
|
): Promise<any> {
|
|
283
|
-
return this.
|
|
316
|
+
return this.owningContext.invokeResolved(kind, name, instance, inputs, ctx);
|
|
284
317
|
}
|
|
285
318
|
|
|
286
319
|
resolveImportedInstance(alias: string, name: string): ResourceInstance | undefined {
|
|
@@ -297,11 +330,22 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
297
330
|
}
|
|
298
331
|
|
|
299
332
|
async run(name: string) {
|
|
300
|
-
await this.
|
|
333
|
+
await this.contextForName(name).run(name);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Report what this resource has observed. Configured state stays on
|
|
337
|
+
* `snapshot()`, which the kernel pulls; only what the resource LEARNS is
|
|
338
|
+
* pushed, because nothing but the controller knows when it learned it. */
|
|
339
|
+
async setStatus(status: Record<string, unknown>): Promise<void> {
|
|
340
|
+
// `metadata` is the resource's `metadata` block, not the resource — every
|
|
341
|
+
// other member here reads `this.metadata.name`.
|
|
342
|
+
const name = this.metadata?.name as string | undefined;
|
|
343
|
+
if (!name) return;
|
|
344
|
+
await this.owningContext.setResourceStatus(name, status);
|
|
301
345
|
}
|
|
302
346
|
|
|
303
347
|
registerManifest(resource: any): void {
|
|
304
|
-
this.
|
|
348
|
+
this.owningContext.registerManifest(resource);
|
|
305
349
|
}
|
|
306
350
|
|
|
307
351
|
loadModule(url: string, options?: LoadOptions): Promise<ResourceManifest[]> {
|
|
@@ -392,7 +436,7 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
392
436
|
// initialized yet when this resolves, and scope-local resources never enter
|
|
393
437
|
// `resourceInstances`).
|
|
394
438
|
const kind =
|
|
395
|
-
(this.
|
|
439
|
+
(this.contextForName(refName).resourceInstances.get(refName)?.resource.kind as string | undefined) ??
|
|
396
440
|
this.kernel.resourceKindByName(refName) ??
|
|
397
441
|
"";
|
|
398
442
|
return { kind, name: refName };
|
|
@@ -451,7 +495,7 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
451
495
|
}
|
|
452
496
|
|
|
453
497
|
getResourcesByName(_kind: string, name: string): RuntimeResource | null {
|
|
454
|
-
const entry = this.
|
|
498
|
+
const entry = this.contextForName(name).resourceInstances.get(name);
|
|
455
499
|
return (entry?.resource ?? null) as RuntimeResource | null;
|
|
456
500
|
}
|
|
457
501
|
|
|
@@ -526,7 +570,7 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
526
570
|
}
|
|
527
571
|
|
|
528
572
|
expandValue(value: any, context: Record<string, any>) {
|
|
529
|
-
return this.
|
|
573
|
+
return this.owningContext.expandWith(value, context);
|
|
530
574
|
}
|
|
531
575
|
|
|
532
576
|
async emitEvent(event: string, payload?: any) {
|
|
@@ -549,11 +593,11 @@ export class ResourceContextImpl implements ResourceContext {
|
|
|
549
593
|
// spawnChildContext(). Rooted on this resource's module context (the
|
|
550
594
|
// consumer scope); a templated definition that needs library-scoped
|
|
551
595
|
// resolution calls the defining library's context directly instead.
|
|
552
|
-
return this.
|
|
596
|
+
return this.owningContext.spawnChildContext();
|
|
553
597
|
}
|
|
554
598
|
|
|
555
599
|
transientChild(context: Record<string, any>): IEvaluationContext {
|
|
556
|
-
return this.
|
|
600
|
+
return this.owningContext.transientChild(context);
|
|
557
601
|
}
|
|
558
602
|
|
|
559
603
|
/**
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
// The OCI ref grammar is pure string parsing shared with the browser-safe
|
|
2
2
|
// manifest-cache key helper, so it lives in `@telorun/analyzer`; this shim
|
|
3
3
|
// keeps the kernel-internal import sites stable.
|
|
4
|
-
export {
|
|
4
|
+
export {
|
|
5
|
+
OCI_SCHEME,
|
|
6
|
+
isOciRef,
|
|
7
|
+
parseOciRef,
|
|
8
|
+
parseVersionedRef,
|
|
9
|
+
withRefVersion,
|
|
10
|
+
type ParsedOciRef,
|
|
11
|
+
} from "@telorun/analyzer";
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
DEFAULT_MANIFEST_FILENAME,
|
|
3
3
|
IntegrityError,
|
|
4
4
|
sha256Base64Url,
|
|
5
|
-
splitIntegrity,
|
|
6
5
|
verifyIntegrity,
|
|
7
6
|
type ManifestCacheCoords,
|
|
8
7
|
type ManifestSource,
|
|
@@ -24,7 +23,13 @@ import {
|
|
|
24
23
|
TELO_LAYER_MEDIA_TYPE,
|
|
25
24
|
type OciManifest,
|
|
26
25
|
} from "./oci-client.js";
|
|
27
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
OCI_SCHEME,
|
|
28
|
+
isOciRef,
|
|
29
|
+
parseOciRef,
|
|
30
|
+
parseVersionedRef,
|
|
31
|
+
withRefVersion,
|
|
32
|
+
} from "./oci-ref.js";
|
|
28
33
|
|
|
29
34
|
/** Pull the module blob, returning its extracted entries and the `telo.yaml`
|
|
30
35
|
* bytes, verified against the ref's inline hash and its own `filesIntegrity`. */
|
|
@@ -139,16 +144,14 @@ export class OciTransport implements Transport {
|
|
|
139
144
|
refVersion(ref: string): string | null {
|
|
140
145
|
// The reference (tag or `sha256:` digest) is what `@` separates. An implicit
|
|
141
146
|
// `latest` (no `@`) is not an upgradeable pin, so return null there; a digest
|
|
142
|
-
// reference flows through raw and the caller's SemVer check skips it.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return at > 0 ? base.slice(at + 1) : null;
|
|
147
|
+
// reference flows through raw and the caller's SemVer check skips it. The
|
|
148
|
+
// split itself is the shared grammar — the editor reads the same pin from a
|
|
149
|
+
// browser, where no transport exists.
|
|
150
|
+
return isOciRef(ref) ? (parseVersionedRef(ref)?.version ?? null) : null;
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
withVersion(ref: string, version: string): string {
|
|
150
|
-
|
|
151
|
-
return `${OCI_SCHEME}${host}/${repo}@${version}`;
|
|
154
|
+
return withRefVersion(ref, version);
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
async digest(ref: string): Promise<string | null> {
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
RegistrySource,
|
|
6
6
|
isRegistryRef,
|
|
7
7
|
parseModuleRef,
|
|
8
|
+
parseVersionedRef,
|
|
8
9
|
sha256Base64Url,
|
|
10
|
+
withRefVersion,
|
|
9
11
|
splitIntegrity,
|
|
10
12
|
type ManifestCacheCoords,
|
|
11
13
|
type ManifestSource,
|
|
@@ -211,15 +213,11 @@ export class RegistryTransport implements Transport {
|
|
|
211
213
|
refVersion(ref: string): string | null {
|
|
212
214
|
// Only bare `namespace/name@version` refs carry an upgradeable version — a
|
|
213
215
|
// direct `https://` URL has no version segment to bump.
|
|
214
|
-
|
|
215
|
-
const { base } = splitIntegrity(ref);
|
|
216
|
-
const at = base.lastIndexOf("@");
|
|
217
|
-
return at > 0 ? base.slice(at + 1) : null;
|
|
216
|
+
return isRegistryRef(ref) ? (parseVersionedRef(ref)?.version ?? null) : null;
|
|
218
217
|
}
|
|
219
218
|
|
|
220
219
|
withVersion(ref: string, version: string): string {
|
|
221
|
-
|
|
222
|
-
return `${modulePath}@${version}`;
|
|
220
|
+
return withRefVersion(ref, version);
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
/** Mirrors the sources' fetch-URL derivation: a direct URL points at (or
|