@telorun/sdk 0.31.0 → 0.33.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.
@@ -43,6 +43,39 @@ export interface InvokeContext {
43
43
  /** The {@link invocationId} of the invocation that dispatched this one, or
44
44
  * `undefined` at a trace root. Reconstructs the call tree on the consumer. */
45
45
  readonly parentInvocationId?: number;
46
+ /** The trace this invocation belongs to — minted at the root span and inherited
47
+ * by every descendant. Present only while tracing. Groups all spans of one
48
+ * trace the way OpenTelemetry's `trace_id` does (an exporter maps it directly),
49
+ * independent of the parent chain. */
50
+ readonly traceId?: string;
51
+ }
52
+ /** Terminal status of a span — maps to OpenTelemetry span status. */
53
+ export type SpanOutcome = "ok" | "failed" | "rejected" | "cancelled";
54
+ /** Options for {@link ResourceContext.openSpan}. */
55
+ export interface OpenSpanOptions {
56
+ /** The resource the span is attributed to (an inbound transport's listener,
57
+ * e.g. the `Http.Api`). Becomes the span's `ref`. */
58
+ ref: {
59
+ kind: string;
60
+ name: string;
61
+ };
62
+ /** Human label for the span (e.g. `"POST /feedback"`). */
63
+ label?: string;
64
+ /** Structured attributes (e.g. `{ method, path }`). Map to OTel span attributes. */
65
+ attributes?: Record<string, unknown>;
66
+ /** Continue an upstream distributed trace instead of rooting a new one — e.g.
67
+ * seeded from a W3C `traceparent` header. */
68
+ inbound?: {
69
+ traceId: string;
70
+ parentSpanId?: number;
71
+ };
72
+ }
73
+ /** Handle returned by {@link ResourceContext.openSpan}. */
74
+ export interface OpenSpan {
75
+ /** Thread into `invokeResolved` so the handler nests under the span. */
76
+ readonly context: InvokeContext;
77
+ /** Close the span with an outcome (emits the span's `end` event). */
78
+ settle(outcome: SpanOutcome, detail?: Record<string, unknown>): Promise<void>;
46
79
  }
47
80
  export interface CancellationSource {
48
81
  readonly token: CancellationToken;
@@ -1 +1 @@
1
- {"version":3,"file":"cancellation.d.ts","sourceRoot":"","sources":["../src/cancellation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;yDACqD;IACrD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;2CACuC;IACvC,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACxE,kEAAkE;IAClE,gBAAgB,IAAI,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC;;4CAEwC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;mFAC+E;IAC/E,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC;4EACwE;IACxE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,uCAAuC;IACvC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;mEAG+D;IAC/D,OAAO,IAAI,IAAI,CAAC;CACjB;AAiFD,wBAAgB,wBAAwB,IAAI,kBAAkB,CAE7D;AAMD;2EAC2E;AAC3E,eAAO,MAAM,eAAe,EAAE,iBAU7B,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,EAAE,aAAiD,CAAC;AAEtF,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMzD"}
1
+ {"version":3,"file":"cancellation.d.ts","sourceRoot":"","sources":["../src/cancellation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;yDACqD;IACrD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;2CACuC;IACvC,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACxE,kEAAkE;IAClE,gBAAgB,IAAI,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC;;4CAEwC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;mFAC+E;IAC/E,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC;;;2CAGuC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qEAAqE;AACrE,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;AAErE,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B;0DACsD;IACtD,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;kDAC8C;IAC9C,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,2DAA2D;AAC3D,MAAM,WAAW,QAAQ;IACvB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,qEAAqE;IACrE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC;4EACwE;IACxE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,uCAAuC;IACvC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;mEAG+D;IAC/D,OAAO,IAAI,IAAI,CAAC;CACjB;AAiFD,wBAAgB,wBAAwB,IAAI,kBAAkB,CAE7D;AAMD;2EAC2E;AAC3E,eAAO,MAAM,eAAe,EAAE,iBAU7B,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,EAAE,aAAiD,CAAC;AAEtF,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMzD"}
@@ -0,0 +1,17 @@
1
+ import type { ModuleContext } from "./module-context.js";
2
+ import { type ResourceInstance } from "./resource-instance.js";
3
+ /** The context a decorator kind composes to dispatch its wrapped target. */
4
+ export interface DispatchContext {
5
+ invokeResolved<TInputs>(kind: string, name: string, instance: ResourceInstance, inputs: TInputs): Promise<unknown>;
6
+ readonly moduleContext: ModuleContext;
7
+ }
8
+ /**
9
+ * Resolve a decorator's `invoke:` field to a live invocable and return a thunk
10
+ * that dispatches it through the traced chokepoint. The field is either a
11
+ * Phase-5-injected instance or a raw `{ kind, name, alias }` ref resolved
12
+ * against the module context. Resolution is eager (fail-fast on a bad ref);
13
+ * dispatch is deferred, so a caller can run it synchronously (Cache.View) or
14
+ * detached (Run.Detach). `describe` labels the error with the owning resource.
15
+ */
16
+ export declare function resolveInvocableDispatcher(field: unknown, ctx: DispatchContext, describe: () => string): (inputs: Record<string, unknown>) => Promise<unknown>;
17
+ //# sourceMappingURL=dispatch-invoke-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-invoke-ref.d.ts","sourceRoot":"","sources":["../src/dispatch-invoke-ref.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/E,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,MAAM,MAAM,GACrB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAoBvD"}
@@ -0,0 +1,27 @@
1
+ import { getRefIdentity } from "./resource-instance.js";
2
+ /**
3
+ * Resolve a decorator's `invoke:` field to a live invocable and return a thunk
4
+ * that dispatches it through the traced chokepoint. The field is either a
5
+ * Phase-5-injected instance or a raw `{ kind, name, alias }` ref resolved
6
+ * against the module context. Resolution is eager (fail-fast on a bad ref);
7
+ * dispatch is deferred, so a caller can run it synchronously (Cache.View) or
8
+ * detached (Run.Detach). `describe` labels the error with the owning resource.
9
+ */
10
+ export function resolveInvocableDispatcher(field, ctx, describe) {
11
+ if (field && typeof field.invoke === "function") {
12
+ const instance = field;
13
+ const id = getRefIdentity(field);
14
+ return (inputs) => id ? ctx.invokeResolved(id.kind, id.name, instance, inputs) : instance.invoke(inputs);
15
+ }
16
+ const ref = field;
17
+ if (!ref || typeof ref.name !== "string") {
18
+ throw new Error(`${describe()}: 'invoke' must reference an invocable.`);
19
+ }
20
+ const resolved = (ref.alias && ref.alias !== "Self"
21
+ ? ctx.moduleContext.resolveImportedInstance(ref.alias, ref.name)
22
+ : ctx.moduleContext.getInstance(ref.name));
23
+ if (!resolved || typeof resolved.invoke !== "function") {
24
+ throw new Error(`${describe()}: 'invoke' reference '${ref.name}' did not resolve to an invocable.`);
25
+ }
26
+ return (inputs) => ctx.invokeResolved(ref.kind, ref.name, resolved, inputs);
27
+ }
@@ -0,0 +1,8 @@
1
+ /** Parse a duration string to milliseconds, or `null` if it is not a valid
2
+ * duration. Lets the caller own the error message and error type. */
3
+ export declare function tryParseDurationMs(value: string): number | null;
4
+ /** Parse a duration string (`300s`, `5m`, `1h`, `50ms`) to milliseconds. An
5
+ * `undefined` value yields `fallback` (default `0`) for optional fields; an
6
+ * invalid string throws a plain `Error`. */
7
+ export declare function parseDurationMs(value: string | undefined, fallback?: number): number;
8
+ //# sourceMappingURL=duration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAeA;sEACsE;AACtE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED;;6CAE6C;AAC7C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAI,GAAG,MAAM,CAU/E"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Duration parsing — the shared time helper for controllers. Telo writes human
3
+ * durations (`250ms`, `2s`, `1.5m`, `1h`) in manifests for timers, TTLs,
4
+ * windows, connect timeouts, backoff, and so on; this is the single place that
5
+ * turns one into a millisecond count. Consumers own their own error UX:
6
+ * `tryParseDurationMs` returns `null` on a bad string so a caller can throw its
7
+ * own typed error (e.g. an `InvokeError` for invoke-time input); `parseDurationMs`
8
+ * throws a coded `RuntimeError` and treats `undefined` as a default (for optional
9
+ * fields), so a bad duration in a manifest surfaces as a structured config error.
10
+ */
11
+ import { RuntimeError } from "./types.js";
12
+ const DURATION_PATTERN = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h)$/;
13
+ const UNIT_MS = { ms: 1, s: 1_000, m: 60_000, h: 3_600_000 };
14
+ /** Parse a duration string to milliseconds, or `null` if it is not a valid
15
+ * duration. Lets the caller own the error message and error type. */
16
+ export function tryParseDurationMs(value) {
17
+ const match = DURATION_PATTERN.exec(value.trim());
18
+ if (!match)
19
+ return null;
20
+ return Number(match[1]) * UNIT_MS[match[2]];
21
+ }
22
+ /** Parse a duration string (`300s`, `5m`, `1h`, `50ms`) to milliseconds. An
23
+ * `undefined` value yields `fallback` (default `0`) for optional fields; an
24
+ * invalid string throws a plain `Error`. */
25
+ export function parseDurationMs(value, fallback = 0) {
26
+ if (value === undefined)
27
+ return fallback;
28
+ const ms = tryParseDurationMs(value);
29
+ if (ms === null) {
30
+ throw new RuntimeError("ERR_INVALID_VALUE", `Invalid duration ${JSON.stringify(value)}; use a number with a unit, e.g. "250ms", "2s", "1.5m", "1h".`);
31
+ }
32
+ return ms;
33
+ }
@@ -1,4 +1,4 @@
1
- import type { InvokeContext } from "./cancellation.js";
1
+ import type { InvokeContext, OpenSpan, OpenSpanOptions } from "./cancellation.js";
2
2
  import type { ScopeHandle } from "./ref.js";
3
3
  import type { ResourceInstance } from "./resource-instance.js";
4
4
  import type { ResourceManifest } from "./resource-manifest.js";
@@ -13,6 +13,9 @@ export interface Tracer {
13
13
  readonly enabled: boolean;
14
14
  /** Mint the next monotonic invocation id (unique within the kernel run). */
15
15
  next(): number;
16
+ /** Mint a fresh trace id (OTel-compatible 16-byte hex) for a new root trace.
17
+ * Children inherit it via {@link InvokeContext.traceId}. */
18
+ newTraceId(): string;
16
19
  }
17
20
  /** Four-stage resource lifecycle defined in resource-lifecycle.md */
18
21
  export type LifecycleState = "Pending" | "Validated" | "Initialized" | "Draining" | "Teardown";
@@ -43,8 +46,12 @@ export type InstanceFactory = (context: EvaluationContext, resource: ResourceMan
43
46
  * non-`Self` `alias`, resolves a cross-module reference into that
44
47
  * import's published exported instances instead of the local context.
45
48
  * Returns undefined when the named resource is not yet initialized.
49
+ * @param isPending Reports whether a local (no-alias) reference names a resource that is
50
+ * registered in this context but not yet initialized. Injection uses it
51
+ * to defer a resource whose dependency exists but hasn't inited yet —
52
+ * rather than leaving the slot unresolved — so the init loop retries it.
46
53
  */
47
- export type PreInitHook = (resource: ResourceManifest, getInstance: (name: string, alias?: string) => ResourceInstance | undefined) => void;
54
+ export type PreInitHook = (resource: ResourceManifest, getInstance: (name: string, alias?: string) => ResourceInstance | undefined, isPending?: (name: string) => boolean) => void;
48
55
  /** Canonical key for a resource instance: "<module>.<kind>.<name>" */
49
56
  export declare function resourceKey(r: ResourceManifest): string;
50
57
  /**
@@ -86,6 +93,11 @@ export interface EvaluationContext {
86
93
  invoke<TInputs>(kind: string, name: string, inputs: TInputs, ctx?: InvokeContext): Promise<any>;
87
94
  invokeResolved<TInputs>(kind: string, name: string, instance: ResourceInstance, inputs: TInputs, ctx?: InvokeContext): Promise<any>;
88
95
  run(name: string, ctx?: InvokeContext): Promise<void>;
96
+ openSpan(base: InvokeContext | undefined, opts: OpenSpanOptions): Promise<OpenSpan>;
97
+ /** Bare scope-detach primitive: run `fn` outside the caller's cancellation/
98
+ * trace scope. Tracking/draining the task is the owning `ResourceContext`'s
99
+ * concern (see {@link ResourceContext.runDetached}). */
100
+ runDetached<T>(fn: () => Promise<T>): Promise<T>;
89
101
  expand(value: unknown): unknown;
90
102
  expandWith(value: unknown, extraContext: Record<string, unknown>): unknown;
91
103
  expandPaths(value: Record<string, unknown>, paths: string[], excludePaths?: string[]): Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"evaluation-context.d.ts","sourceRoot":"","sources":["../src/evaluation-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluation-context.d.ts","sourceRoot":"","sources":["../src/evaluation-context.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,9 +3,11 @@ export * from "./compiled-value.js";
3
3
  export * from "./capabilities/invokable.js";
4
4
  export * from "./ref.js";
5
5
  export * from "./invoke-step.js";
6
+ export * from "./dispatch-invoke-ref.js";
6
7
  export * from "./capabilities/provider.js";
7
8
  export * from "./capabilities/runnable.js";
8
9
  export * from "./context-provider.js";
10
+ export * from "./duration.js";
9
11
  export * from "./controller-context.js";
10
12
  export * from "./controller-policy.js";
11
13
  export * from "./evaluation-context.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -3,9 +3,11 @@ export * from "./compiled-value.js";
3
3
  export * from "./capabilities/invokable.js";
4
4
  export * from "./ref.js";
5
5
  export * from "./invoke-step.js";
6
+ export * from "./dispatch-invoke-ref.js";
6
7
  export * from "./capabilities/provider.js";
7
8
  export * from "./capabilities/runnable.js";
8
9
  export * from "./context-provider.js";
10
+ export * from "./duration.js";
9
11
  export * from "./controller-context.js";
10
12
  export * from "./controller-policy.js";
11
13
  export * from "./evaluation-context.js";
@@ -1,6 +1,6 @@
1
1
  import type { Invocable } from "./capabilities/invokable.js";
2
2
  import type { KindRef, ScopeContext } from "./ref.js";
3
- import type { ResourceInstance } from "./resource-instance.js";
3
+ import { type ResourceInstance } from "./resource-instance.js";
4
4
  /** Retry policy for a single invoke step, passed through to `ctx.invoke`. */
5
5
  export interface InvokeStepRetry {
6
6
  attempts?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"invoke-step.d.ts","sourceRoot":"","sources":["../src/invoke-step.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;;;qDAIqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;mFAGmF;AACnF,MAAM,MAAM,UAAU,GAClB,MAAM,GACN;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,kBAAkB,CAAC;AAEvB;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1F,cAAc,CAAC,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,GAAG,CAAC,CAAC;IAChB;;qDAEiD;IACjD,uBAAuB,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;CACrF;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC,CAgCf"}
1
+ {"version":3,"file":"invoke-step.d.ts","sourceRoot":"","sources":["../src/invoke-step.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/E,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;;;qDAIqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;mFAGmF;AACnF,MAAM,MAAM,UAAU,GAClB,MAAM,GACN;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,kBAAkB,CAAC;AAEvB;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1F,cAAc,CAAC,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,GAAG,CAAC,CAAC;IAChB;;qDAEiD;IACjD,uBAAuB,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;CACrF;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -1,3 +1,4 @@
1
+ import { getRefIdentity } from "./resource-instance.js";
1
2
  /**
2
3
  * Execute one invoke step: evaluate the `when` guard, expand `inputs`, resolve
3
4
  * and invoke the target, then record `steps[step.name] = { result }`. Knows
@@ -12,7 +13,14 @@ export async function executeInvokeStep(step, ctx, state) {
12
13
  const raw = step.invoke;
13
14
  let result;
14
15
  if (raw && typeof raw.invoke === "function") {
15
- result = await raw.invoke(inputs);
16
+ // A pre-injected live instance (a `!ref` resolved at Phase 5). Route it
17
+ // through the traced chokepoint using the identity the kernel stamped at
18
+ // injection, so the call is instrumented exactly like a by-name dispatch.
19
+ // A truly anonymous instance (no stamp) falls back to a direct call.
20
+ const identity = getRefIdentity(raw);
21
+ result = identity
22
+ ? await ctx.invokeResolved(identity.kind, identity.name, raw, inputs)
23
+ : await raw.invoke(inputs);
16
24
  }
17
25
  else {
18
26
  const ref = raw;
@@ -1,4 +1,4 @@
1
- import type { CancellationSource, InvokeContext } from "./cancellation.js";
1
+ import type { CancellationSource, InvokeContext, OpenSpan, OpenSpanOptions } from "./cancellation.js";
2
2
  import { ControllerContext } from "./controller-context.js";
3
3
  import { ControllerPolicy } from "./controller-policy.js";
4
4
  import { EvaluationContext } from "./evaluation-context.js";
@@ -40,6 +40,20 @@ export interface ResourceContext extends ControllerContext {
40
40
  * lambda budget). Pass `source.context` into `invokeResolved` to scope an
41
41
  * invocation tree to it. */
42
42
  createCancellationSource(): CancellationSource;
43
+ /** Run `fn` detached from the caller's cancellation/trace scope: the ambient
44
+ * request token + span are replaced with the uncancellable root, so request
45
+ * teardown cannot abort the work and it does not nest under the request's
46
+ * trace. Fire-and-forget — the call returns nothing; the task is tracked
47
+ * against this resource and drained (bounded) when the resource tears down,
48
+ * and a failure (no caller to throw to) is routed to the EventBus. */
49
+ runDetached(fn: () => Promise<unknown>): void;
50
+ /** Open a trace span for an inbound boundary (an HTTP request, a queue message).
51
+ * Returns a child {@link InvokeContext} to thread into `invokeResolved` so the
52
+ * handler nests under this span, plus `settle` to close it with an outcome.
53
+ * The span roots a fresh trace unless `inbound` continues an upstream one
54
+ * (e.g. a W3C `traceparent`). A no-op (returns `base` unchanged) when tracing
55
+ * is off. */
56
+ openSpan(base: InvokeContext | undefined, opts: OpenSpanOptions): Promise<OpenSpan>;
43
57
  invoke<TInputs>(kind: string, name: string, inputs: TInputs, options?: any): Promise<any>;
44
58
  invokeResolved<TInputs>(kind: string, name: string, instance: ResourceInstance, inputs: TInputs, ctx?: InvokeContext): Promise<any>;
45
59
  run(kind: string, name: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"resource-context.d.ts","sourceRoot":"","sources":["../src/resource-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resource-context.d.ts","sourceRoot":"","sources":["../src/resource-context.ts"],"names":[],"mappings":"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"}
@@ -7,4 +7,22 @@ export type ResourceInstance<TInput = Record<string, any>, TOutput = any> = Part
7
7
  teardown?(): void | Promise<void>;
8
8
  snapshot?(): Record<string, any> | Promise<Record<string, any>>;
9
9
  };
10
+ /** The kind+name an instance was resolved from. */
11
+ export interface RefIdentity {
12
+ kind: string;
13
+ name: string;
14
+ }
15
+ /**
16
+ * Non-enumerable identity tag the kernel stamps on a live instance when it
17
+ * injects a resolved `!ref` into a slot. A consumer that holds only the bare
18
+ * instance (an `executeInvokeStep` target whose `!ref` was pre-injected) can
19
+ * then recover the kind+name and dispatch through the traced chokepoint
20
+ * (`invokeResolved`) instead of calling `.invoke()` directly and escaping it.
21
+ */
22
+ export declare const REF_IDENTITY: unique symbol;
23
+ /** Stamp the resolved kind+name onto an injected instance. Idempotent — an
24
+ * instance has exactly one identity, so re-injection into other slots is a no-op. */
25
+ export declare function stampRefIdentity(instance: object, kind: string, name: string): void;
26
+ /** Read the identity stamped by {@link stampRefIdentity}, if any. */
27
+ export declare function getRefIdentity(instance: object): RefIdentity | undefined;
10
28
  //# sourceMappingURL=resource-instance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource-instance.d.ts","sourceRoot":"","sources":["../src/resource-instance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG,IAAI,OAAO,CACjF,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3B,GACC,OAAO,CAAC,QAAQ,CAAC,GACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG;IAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;CACjE,CAAC"}
1
+ {"version":3,"file":"resource-instance.d.ts","sourceRoot":"","sources":["../src/resource-instance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG,IAAI,OAAO,CACjF,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3B,GACC,OAAO,CAAC,QAAQ,CAAC,GACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG;IAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;CACjE,CAAC;AAEJ,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,MAAuC,CAAC;AAE1E;sFACsF;AACtF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CASnF;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAExE"}
@@ -1 +1,24 @@
1
- export {};
1
+ /**
2
+ * Non-enumerable identity tag the kernel stamps on a live instance when it
3
+ * injects a resolved `!ref` into a slot. A consumer that holds only the bare
4
+ * instance (an `executeInvokeStep` target whose `!ref` was pre-injected) can
5
+ * then recover the kind+name and dispatch through the traced chokepoint
6
+ * (`invokeResolved`) instead of calling `.invoke()` directly and escaping it.
7
+ */
8
+ export const REF_IDENTITY = Symbol.for("telo.refIdentity");
9
+ /** Stamp the resolved kind+name onto an injected instance. Idempotent — an
10
+ * instance has exactly one identity, so re-injection into other slots is a no-op. */
11
+ export function stampRefIdentity(instance, kind, name) {
12
+ if (!(REF_IDENTITY in instance)) {
13
+ Object.defineProperty(instance, REF_IDENTITY, {
14
+ value: { kind, name },
15
+ enumerable: false,
16
+ configurable: true,
17
+ writable: false,
18
+ });
19
+ }
20
+ }
21
+ /** Read the identity stamped by {@link stampRefIdentity}, if any. */
22
+ export function getRefIdentity(instance) {
23
+ return instance[REF_IDENTITY];
24
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/sdk",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Telo SDK - Public API for Telo module authors.",
5
5
  "keywords": [
6
6
  "telo",
@@ -48,6 +48,36 @@ export interface InvokeContext {
48
48
  /** The {@link invocationId} of the invocation that dispatched this one, or
49
49
  * `undefined` at a trace root. Reconstructs the call tree on the consumer. */
50
50
  readonly parentInvocationId?: number;
51
+ /** The trace this invocation belongs to — minted at the root span and inherited
52
+ * by every descendant. Present only while tracing. Groups all spans of one
53
+ * trace the way OpenTelemetry's `trace_id` does (an exporter maps it directly),
54
+ * independent of the parent chain. */
55
+ readonly traceId?: string;
56
+ }
57
+
58
+ /** Terminal status of a span — maps to OpenTelemetry span status. */
59
+ export type SpanOutcome = "ok" | "failed" | "rejected" | "cancelled";
60
+
61
+ /** Options for {@link ResourceContext.openSpan}. */
62
+ export interface OpenSpanOptions {
63
+ /** The resource the span is attributed to (an inbound transport's listener,
64
+ * e.g. the `Http.Api`). Becomes the span's `ref`. */
65
+ ref: { kind: string; name: string };
66
+ /** Human label for the span (e.g. `"POST /feedback"`). */
67
+ label?: string;
68
+ /** Structured attributes (e.g. `{ method, path }`). Map to OTel span attributes. */
69
+ attributes?: Record<string, unknown>;
70
+ /** Continue an upstream distributed trace instead of rooting a new one — e.g.
71
+ * seeded from a W3C `traceparent` header. */
72
+ inbound?: { traceId: string; parentSpanId?: number };
73
+ }
74
+
75
+ /** Handle returned by {@link ResourceContext.openSpan}. */
76
+ export interface OpenSpan {
77
+ /** Thread into `invokeResolved` so the handler nests under the span. */
78
+ readonly context: InvokeContext;
79
+ /** Close the span with an outcome (emits the span's `end` event). */
80
+ settle(outcome: SpanOutcome, detail?: Record<string, unknown>): Promise<void>;
51
81
  }
52
82
 
53
83
  export interface CancellationSource {
@@ -0,0 +1,48 @@
1
+ import type { Invocable } from "./capabilities/invokable.js";
2
+ import type { ModuleContext } from "./module-context.js";
3
+ import { getRefIdentity, type ResourceInstance } from "./resource-instance.js";
4
+
5
+ /** The context a decorator kind composes to dispatch its wrapped target. */
6
+ export interface DispatchContext {
7
+ invokeResolved<TInputs>(
8
+ kind: string,
9
+ name: string,
10
+ instance: ResourceInstance,
11
+ inputs: TInputs,
12
+ ): Promise<unknown>;
13
+ readonly moduleContext: ModuleContext;
14
+ }
15
+
16
+ /**
17
+ * Resolve a decorator's `invoke:` field to a live invocable and return a thunk
18
+ * that dispatches it through the traced chokepoint. The field is either a
19
+ * Phase-5-injected instance or a raw `{ kind, name, alias }` ref resolved
20
+ * against the module context. Resolution is eager (fail-fast on a bad ref);
21
+ * dispatch is deferred, so a caller can run it synchronously (Cache.View) or
22
+ * detached (Run.Detach). `describe` labels the error with the owning resource.
23
+ */
24
+ export function resolveInvocableDispatcher(
25
+ field: unknown,
26
+ ctx: DispatchContext,
27
+ describe: () => string,
28
+ ): (inputs: Record<string, unknown>) => Promise<unknown> {
29
+ if (field && typeof (field as Invocable).invoke === "function") {
30
+ const instance = field as ResourceInstance & Invocable;
31
+ const id = getRefIdentity(field as object);
32
+ return (inputs) =>
33
+ id ? ctx.invokeResolved(id.kind, id.name, instance, inputs) : instance.invoke(inputs);
34
+ }
35
+ const ref = field as { kind: string; name: string; alias?: string } | undefined;
36
+ if (!ref || typeof ref.name !== "string") {
37
+ throw new Error(`${describe()}: 'invoke' must reference an invocable.`);
38
+ }
39
+ const resolved = (
40
+ ref.alias && ref.alias !== "Self"
41
+ ? ctx.moduleContext.resolveImportedInstance(ref.alias, ref.name)
42
+ : ctx.moduleContext.getInstance(ref.name)
43
+ ) as ResourceInstance | undefined;
44
+ if (!resolved || typeof resolved.invoke !== "function") {
45
+ throw new Error(`${describe()}: 'invoke' reference '${ref.name}' did not resolve to an invocable.`);
46
+ }
47
+ return (inputs) => ctx.invokeResolved(ref.kind, ref.name, resolved, inputs);
48
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Duration parsing — the shared time helper for controllers. Telo writes human
3
+ * durations (`250ms`, `2s`, `1.5m`, `1h`) in manifests for timers, TTLs,
4
+ * windows, connect timeouts, backoff, and so on; this is the single place that
5
+ * turns one into a millisecond count. Consumers own their own error UX:
6
+ * `tryParseDurationMs` returns `null` on a bad string so a caller can throw its
7
+ * own typed error (e.g. an `InvokeError` for invoke-time input); `parseDurationMs`
8
+ * throws a coded `RuntimeError` and treats `undefined` as a default (for optional
9
+ * fields), so a bad duration in a manifest surfaces as a structured config error.
10
+ */
11
+ import { RuntimeError } from "./types.js";
12
+
13
+ const DURATION_PATTERN = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h)$/;
14
+ const UNIT_MS = { ms: 1, s: 1_000, m: 60_000, h: 3_600_000 } as const;
15
+
16
+ /** Parse a duration string to milliseconds, or `null` if it is not a valid
17
+ * duration. Lets the caller own the error message and error type. */
18
+ export function tryParseDurationMs(value: string): number | null {
19
+ const match = DURATION_PATTERN.exec(value.trim());
20
+ if (!match) return null;
21
+ return Number(match[1]) * UNIT_MS[match[2] as keyof typeof UNIT_MS];
22
+ }
23
+
24
+ /** Parse a duration string (`300s`, `5m`, `1h`, `50ms`) to milliseconds. An
25
+ * `undefined` value yields `fallback` (default `0`) for optional fields; an
26
+ * invalid string throws a plain `Error`. */
27
+ export function parseDurationMs(value: string | undefined, fallback = 0): number {
28
+ if (value === undefined) return fallback;
29
+ const ms = tryParseDurationMs(value);
30
+ if (ms === null) {
31
+ throw new RuntimeError(
32
+ "ERR_INVALID_VALUE",
33
+ `Invalid duration ${JSON.stringify(value)}; use a number with a unit, e.g. "250ms", "2s", "1.5m", "1h".`,
34
+ );
35
+ }
36
+ return ms;
37
+ }
@@ -1,4 +1,4 @@
1
- import type { InvokeContext } from "./cancellation.js";
1
+ import type { InvokeContext, OpenSpan, OpenSpanOptions } from "./cancellation.js";
2
2
  import type { ScopeHandle } from "./ref.js";
3
3
  import type { ResourceInstance } from "./resource-instance.js";
4
4
  import type { ResourceManifest } from "./resource-manifest.js";
@@ -19,6 +19,9 @@ export interface Tracer {
19
19
  readonly enabled: boolean;
20
20
  /** Mint the next monotonic invocation id (unique within the kernel run). */
21
21
  next(): number;
22
+ /** Mint a fresh trace id (OTel-compatible 16-byte hex) for a new root trace.
23
+ * Children inherit it via {@link InvokeContext.traceId}. */
24
+ newTraceId(): string;
22
25
  }
23
26
 
24
27
  /** Four-stage resource lifecycle defined in resource-lifecycle.md */
@@ -60,10 +63,15 @@ export type InstanceFactory = (
60
63
  * non-`Self` `alias`, resolves a cross-module reference into that
61
64
  * import's published exported instances instead of the local context.
62
65
  * Returns undefined when the named resource is not yet initialized.
66
+ * @param isPending Reports whether a local (no-alias) reference names a resource that is
67
+ * registered in this context but not yet initialized. Injection uses it
68
+ * to defer a resource whose dependency exists but hasn't inited yet —
69
+ * rather than leaving the slot unresolved — so the init loop retries it.
63
70
  */
64
71
  export type PreInitHook = (
65
72
  resource: ResourceManifest,
66
73
  getInstance: (name: string, alias?: string) => ResourceInstance | undefined,
74
+ isPending?: (name: string) => boolean,
67
75
  ) => void;
68
76
 
69
77
  /** Canonical key for a resource instance: "<module>.<kind>.<name>" */
@@ -124,6 +132,11 @@ export interface EvaluationContext {
124
132
  ctx?: InvokeContext,
125
133
  ): Promise<any>;
126
134
  run(name: string, ctx?: InvokeContext): Promise<void>;
135
+ openSpan(base: InvokeContext | undefined, opts: OpenSpanOptions): Promise<OpenSpan>;
136
+ /** Bare scope-detach primitive: run `fn` outside the caller's cancellation/
137
+ * trace scope. Tracking/draining the task is the owning `ResourceContext`'s
138
+ * concern (see {@link ResourceContext.runDetached}). */
139
+ runDetached<T>(fn: () => Promise<T>): Promise<T>;
127
140
  expand(value: unknown): unknown;
128
141
  expandWith(value: unknown, extraContext: Record<string, unknown>): unknown;
129
142
  expandPaths(
package/src/index.ts CHANGED
@@ -3,9 +3,11 @@ export * from "./compiled-value.js";
3
3
  export * from "./capabilities/invokable.js";
4
4
  export * from "./ref.js";
5
5
  export * from "./invoke-step.js";
6
+ export * from "./dispatch-invoke-ref.js";
6
7
  export * from "./capabilities/provider.js";
7
8
  export * from "./capabilities/runnable.js";
8
9
  export * from "./context-provider.js";
10
+ export * from "./duration.js";
9
11
  export * from "./controller-context.js";
10
12
  export * from "./controller-policy.js";
11
13
  export * from "./evaluation-context.js";
@@ -1,6 +1,6 @@
1
1
  import type { Invocable } from "./capabilities/invokable.js";
2
2
  import type { KindRef, ScopeContext } from "./ref.js";
3
- import type { ResourceInstance } from "./resource-instance.js";
3
+ import { getRefIdentity, type ResourceInstance } from "./resource-instance.js";
4
4
 
5
5
  /** Retry policy for a single invoke step, passed through to `ctx.invoke`. */
6
6
  export interface InvokeStepRetry {
@@ -94,7 +94,14 @@ export async function executeInvokeStep(
94
94
  let result: unknown;
95
95
 
96
96
  if (raw && typeof (raw as Invocable).invoke === "function") {
97
- result = await (raw as Invocable).invoke(inputs);
97
+ // A pre-injected live instance (a `!ref` resolved at Phase 5). Route it
98
+ // through the traced chokepoint using the identity the kernel stamped at
99
+ // injection, so the call is instrumented exactly like a by-name dispatch.
100
+ // A truly anonymous instance (no stamp) falls back to a direct call.
101
+ const identity = getRefIdentity(raw as object);
102
+ result = identity
103
+ ? await ctx.invokeResolved(identity.kind, identity.name, raw as ResourceInstance, inputs)
104
+ : await (raw as Invocable).invoke(inputs);
98
105
  } else {
99
106
  const ref = raw as KindRef<Invocable>;
100
107
  if (ref.alias && ref.alias !== "Self") {
@@ -1,4 +1,4 @@
1
- import type { CancellationSource, InvokeContext } from "./cancellation.js";
1
+ import type { CancellationSource, InvokeContext, OpenSpan, OpenSpanOptions } from "./cancellation.js";
2
2
  import { ControllerContext } from "./controller-context.js";
3
3
  import { ControllerPolicy } from "./controller-policy.js";
4
4
  import { EvaluationContext } from "./evaluation-context.js";
@@ -49,6 +49,20 @@ export interface ResourceContext extends ControllerContext {
49
49
  * lambda budget). Pass `source.context` into `invokeResolved` to scope an
50
50
  * invocation tree to it. */
51
51
  createCancellationSource(): CancellationSource;
52
+ /** Run `fn` detached from the caller's cancellation/trace scope: the ambient
53
+ * request token + span are replaced with the uncancellable root, so request
54
+ * teardown cannot abort the work and it does not nest under the request's
55
+ * trace. Fire-and-forget — the call returns nothing; the task is tracked
56
+ * against this resource and drained (bounded) when the resource tears down,
57
+ * and a failure (no caller to throw to) is routed to the EventBus. */
58
+ runDetached(fn: () => Promise<unknown>): void;
59
+ /** Open a trace span for an inbound boundary (an HTTP request, a queue message).
60
+ * Returns a child {@link InvokeContext} to thread into `invokeResolved` so the
61
+ * handler nests under this span, plus `settle` to close it with an outcome.
62
+ * The span roots a fresh trace unless `inbound` continues an upstream one
63
+ * (e.g. a W3C `traceparent`). A no-op (returns `base` unchanged) when tracing
64
+ * is off. */
65
+ openSpan(base: InvokeContext | undefined, opts: OpenSpanOptions): Promise<OpenSpan>;
52
66
  invoke<TInputs>(kind: string, name: string, inputs: TInputs, options?: any): Promise<any>;
53
67
  invokeResolved<TInputs>(
54
68
  kind: string,
@@ -12,3 +12,36 @@ export type ResourceInstance<TInput = Record<string, any>, TOutput = any> = Part
12
12
  teardown?(): void | Promise<void>;
13
13
  snapshot?(): Record<string, any> | Promise<Record<string, any>>;
14
14
  };
15
+
16
+ /** The kind+name an instance was resolved from. */
17
+ export interface RefIdentity {
18
+ kind: string;
19
+ name: string;
20
+ }
21
+
22
+ /**
23
+ * Non-enumerable identity tag the kernel stamps on a live instance when it
24
+ * injects a resolved `!ref` into a slot. A consumer that holds only the bare
25
+ * instance (an `executeInvokeStep` target whose `!ref` was pre-injected) can
26
+ * then recover the kind+name and dispatch through the traced chokepoint
27
+ * (`invokeResolved`) instead of calling `.invoke()` directly and escaping it.
28
+ */
29
+ export const REF_IDENTITY: unique symbol = Symbol.for("telo.refIdentity");
30
+
31
+ /** Stamp the resolved kind+name onto an injected instance. Idempotent — an
32
+ * instance has exactly one identity, so re-injection into other slots is a no-op. */
33
+ export function stampRefIdentity(instance: object, kind: string, name: string): void {
34
+ if (!(REF_IDENTITY in instance)) {
35
+ Object.defineProperty(instance, REF_IDENTITY, {
36
+ value: { kind, name } satisfies RefIdentity,
37
+ enumerable: false,
38
+ configurable: true,
39
+ writable: false,
40
+ });
41
+ }
42
+ }
43
+
44
+ /** Read the identity stamped by {@link stampRefIdentity}, if any. */
45
+ export function getRefIdentity(instance: object): RefIdentity | undefined {
46
+ return (instance as Record<symbol, RefIdentity | undefined>)[REF_IDENTITY];
47
+ }