@smithers-orchestrator/components 0.24.0 → 0.25.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,57 @@
1
+ import type { SidecarDelta } from "./SidecarDelta.ts";
2
+
3
+ type RowLike = {
4
+ nodeId?: string;
5
+ node_id?: string;
6
+ scorerId?: string;
7
+ scorer_id?: string;
8
+ score?: number;
9
+ scoredAtMs?: number;
10
+ scored_at_ms?: number;
11
+ } & Record<string, unknown>;
12
+
13
+ type ComputeSidecarDeltaOptions = {
14
+ primaryNodeId: string;
15
+ sidecarNodeId: string;
16
+ scorerId?: string;
17
+ };
18
+
19
+ function getNodeId(row: RowLike): string | undefined {
20
+ return typeof row.nodeId === "string" ? row.nodeId : typeof row.node_id === "string" ? row.node_id : undefined;
21
+ }
22
+
23
+ function getScorerId(row: RowLike): string | undefined {
24
+ return typeof row.scorerId === "string"
25
+ ? row.scorerId
26
+ : typeof row.scorer_id === "string"
27
+ ? row.scorer_id
28
+ : undefined;
29
+ }
30
+
31
+ function getScoredAtMs(row: RowLike): number {
32
+ const value = row.scoredAtMs ?? row.scored_at_ms;
33
+ return typeof value === "number" ? value : 0;
34
+ }
35
+
36
+ function getScore(row: RowLike | undefined): number | null {
37
+ return typeof row?.score === "number" ? row.score : null;
38
+ }
39
+
40
+ function latestMatching(rows: RowLike[], nodeId: string, scorerId?: string): RowLike | undefined {
41
+ return rows
42
+ .filter((row) => getNodeId(row) === nodeId && (!scorerId || getScorerId(row) === scorerId))
43
+ .sort((a, b) => getScoredAtMs(b) - getScoredAtMs(a))[0];
44
+ }
45
+
46
+ export function computeSidecarDelta(rows: RowLike[], opts: ComputeSidecarDeltaOptions): SidecarDelta {
47
+ const primaryScore = getScore(latestMatching(rows, opts.primaryNodeId, opts.scorerId));
48
+ const sidecarScore = getScore(latestMatching(rows, opts.sidecarNodeId, opts.scorerId));
49
+ const delta =
50
+ primaryScore == null || sidecarScore == null ? null : Number((primaryScore - sidecarScore).toFixed(12));
51
+ return {
52
+ primaryScore,
53
+ sidecarScore,
54
+ delta,
55
+ cheaperWins: primaryScore != null && sidecarScore != null && sidecarScore >= primaryScore,
56
+ };
57
+ }
@@ -59,6 +59,8 @@
59
59
  /** @typedef {import("./ScanFixVerifyProps.ts").ScanFixVerifyProps} ScanFixVerifyProps */
60
60
  /** @typedef {import("@smithers-orchestrator/graph/types").ScorersMap} ScorersMap */
61
61
  /** @typedef {import("./SequenceProps.ts").SequenceProps} SequenceProps */
62
+ /** @typedef {import("./SidecarDelta.ts").SidecarDelta} SidecarDelta */
63
+ /** @typedef {import("./SidecarProps.ts").SidecarProps} SidecarProps */
62
64
  /**
63
65
  * @template Schema
64
66
  * @typedef {import("./SignalProps.ts").SignalProps<Schema>} SignalProps
@@ -108,6 +110,8 @@ export { ScanFixVerify } from "./ScanFixVerify.js";
108
110
  export { Poller } from "./Poller.js";
109
111
  export { Supervisor } from "./Supervisor.js";
110
112
  export { Runbook } from "./Runbook.js";
113
+ export { Sidecar } from "./Sidecar.js";
114
+ export { computeSidecarDelta } from "./computeSidecarDelta.ts";
111
115
  // --- Engine-Backed Primitives ---
112
116
  export { Subflow } from "./Subflow.js";
113
117
  export { Sandbox } from "./Sandbox.js";
@@ -115,7 +119,7 @@ export { WaitForEvent } from "./WaitForEvent.js";
115
119
  export { Signal } from "./Signal.js";
116
120
  export { Timer } from "./Timer.js";
117
121
  export { HumanTask } from "./HumanTask.js";
118
- export { Saga } from "./Saga.js";
122
+ export { Saga, SagaStep } from "./Saga.js";
119
123
  export { TryCatchFinally } from "./TryCatchFinally.js";
120
124
  // --- Core Enhancements ---
121
125
  export { Aspects } from "./Aspects.js";