@telorun/sdk 0.32.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.
@@ -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
+ }
@@ -46,8 +46,12 @@ export type InstanceFactory = (context: EvaluationContext, resource: ResourceMan
46
46
  * non-`Self` `alias`, resolves a cross-module reference into that
47
47
  * import's published exported instances instead of the local context.
48
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.
49
53
  */
50
- 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;
51
55
  /** Canonical key for a resource instance: "<module>.<kind>.<name>" */
52
56
  export declare function resourceKey(r: ResourceManifest): string;
53
57
  /**
@@ -90,6 +94,10 @@ export interface EvaluationContext {
90
94
  invokeResolved<TInputs>(kind: string, name: string, instance: ResourceInstance, inputs: TInputs, ctx?: InvokeContext): Promise<any>;
91
95
  run(name: string, ctx?: InvokeContext): Promise<void>;
92
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>;
93
101
  expand(value: unknown): unknown;
94
102
  expandWith(value: unknown, extraContext: Record<string, unknown>): unknown;
95
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";
@@ -40,6 +40,13 @@ 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;
43
50
  /** Open a trace span for an inbound boundary (an HTTP request, a queue message).
44
51
  * Returns a child {@link InvokeContext} to thread into `invokeResolved` so the
45
52
  * handler nests under this span, plus `settle` to close it with an outcome.
@@ -1 +1 @@
1
- {"version":3,"file":"resource-context.d.ts","sourceRoot":"","sources":["../src/resource-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACtG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B;gFAC4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;4EAGwE;IACxE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAc,YAAW,aAAa;IACjD,OAAO;IAIP,QAAQ;CAGT;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC,GAAG;IAAE,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhG,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACzC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;iCAE6B;IAC7B,wBAAwB,IAAI,kBAAkB,CAAC;IAC/C;;;;;kBAKc;IACd,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpF,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,EACf,GAAG,CAAC,EAAE,aAAa,GAClB,OAAO,CAAC,GAAG,CAAC,CAAC;IAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAC;IACvE,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,iBAAiB,IAAI,iBAAiB,CAAC;IACvC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,iBAAiB,CAAC;IAChE,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACnD,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;IAC9C,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,CAAC;IAClD,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACzD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC;IACtD,kFAAkF;IAClF,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,aAAa,CAAC;IACtF,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjG,kBAAkB,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI,CAAC;IAC1C,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjF;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACpD;;;;;;;;;;;OAWG;IACH,WAAW,IAAI,MAAM,GAAG,SAAS,CAAC;IAClC;;;;iEAI6D;IAC7D,cAAc,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC;wDACoD;IACpD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC5E;;;sBAGkB;IAClB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACxD,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CACxC"}
1
+ {"version":3,"file":"resource-context.d.ts","sourceRoot":"","sources":["../src/resource-context.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/sdk",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "Telo SDK - Public API for Telo module authors.",
5
5
  "keywords": [
6
6
  "telo",
@@ -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
+ }
@@ -63,10 +63,15 @@ export type InstanceFactory = (
63
63
  * non-`Self` `alias`, resolves a cross-module reference into that
64
64
  * import's published exported instances instead of the local context.
65
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.
66
70
  */
67
71
  export type PreInitHook = (
68
72
  resource: ResourceManifest,
69
73
  getInstance: (name: string, alias?: string) => ResourceInstance | undefined,
74
+ isPending?: (name: string) => boolean,
70
75
  ) => void;
71
76
 
72
77
  /** Canonical key for a resource instance: "<module>.<kind>.<name>" */
@@ -128,6 +133,10 @@ export interface EvaluationContext {
128
133
  ): Promise<any>;
129
134
  run(name: string, ctx?: InvokeContext): Promise<void>;
130
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>;
131
140
  expand(value: unknown): unknown;
132
141
  expandWith(value: unknown, extraContext: Record<string, unknown>): unknown;
133
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";
@@ -49,6 +49,13 @@ 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;
52
59
  /** Open a trace span for an inbound boundary (an HTTP request, a queue message).
53
60
  * Returns a child {@link InvokeContext} to thread into `invokeResolved` so the
54
61
  * handler nests under this span, plus `settle` to close it with an outcome.