@blokjs/runner 0.2.1 → 0.2.2
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/Blok.js +11 -11
- package/dist/Blok.js.map +1 -1
- package/dist/Configuration.d.ts +21 -2
- package/dist/Configuration.js +188 -26
- package/dist/Configuration.js.map +1 -1
- package/dist/ConfigurationResolver.d.ts +9 -0
- package/dist/ConfigurationResolver.js +17 -1
- package/dist/ConfigurationResolver.js.map +1 -1
- package/dist/RunnerSteps.js +52 -9
- package/dist/RunnerSteps.js.map +1 -1
- package/dist/RuntimeAdapterNode.d.ts +32 -2
- package/dist/RuntimeAdapterNode.js +122 -27
- package/dist/RuntimeAdapterNode.js.map +1 -1
- package/dist/TriggerBase.js +35 -2
- package/dist/TriggerBase.js.map +1 -1
- package/dist/adapters/BunRuntimeAdapter.d.ts +1 -0
- package/dist/adapters/BunRuntimeAdapter.js +1 -0
- package/dist/adapters/BunRuntimeAdapter.js.map +1 -1
- package/dist/adapters/DockerRuntimeAdapter.d.ts +2 -1
- package/dist/adapters/DockerRuntimeAdapter.js +10 -1
- package/dist/adapters/DockerRuntimeAdapter.js.map +1 -1
- package/dist/adapters/HttpRuntimeAdapter.d.ts +26 -5
- package/dist/adapters/HttpRuntimeAdapter.js +97 -16
- package/dist/adapters/HttpRuntimeAdapter.js.map +1 -1
- package/dist/adapters/NodeJsRuntimeAdapter.d.ts +1 -0
- package/dist/adapters/NodeJsRuntimeAdapter.js +1 -0
- package/dist/adapters/NodeJsRuntimeAdapter.js.map +1 -1
- package/dist/adapters/RuntimeAdapter.d.ts +17 -0
- package/dist/adapters/WasmRuntimeAdapter.d.ts +1 -0
- package/dist/adapters/WasmRuntimeAdapter.js +1 -0
- package/dist/adapters/WasmRuntimeAdapter.js.map +1 -1
- package/dist/adapters/grpc/GrpcChannelOptions.d.ts +31 -0
- package/dist/adapters/grpc/GrpcChannelOptions.js +68 -0
- package/dist/adapters/grpc/GrpcChannelOptions.js.map +1 -0
- package/dist/adapters/grpc/GrpcClientPool.d.ts +43 -0
- package/dist/adapters/grpc/GrpcClientPool.js +89 -0
- package/dist/adapters/grpc/GrpcClientPool.js.map +1 -0
- package/dist/adapters/grpc/GrpcCodec.d.ts +226 -0
- package/dist/adapters/grpc/GrpcCodec.js +275 -0
- package/dist/adapters/grpc/GrpcCodec.js.map +1 -0
- package/dist/adapters/grpc/GrpcErrors.d.ts +59 -0
- package/dist/adapters/grpc/GrpcErrors.js +190 -0
- package/dist/adapters/grpc/GrpcErrors.js.map +1 -0
- package/dist/adapters/grpc/GrpcHealthChecker.d.ts +69 -0
- package/dist/adapters/grpc/GrpcHealthChecker.js +96 -0
- package/dist/adapters/grpc/GrpcHealthChecker.js.map +1 -0
- package/dist/adapters/grpc/GrpcRuntimeAdapter.d.ts +98 -0
- package/dist/adapters/grpc/GrpcRuntimeAdapter.js +478 -0
- package/dist/adapters/grpc/GrpcRuntimeAdapter.js.map +1 -0
- package/dist/adapters/grpc/index.d.ts +13 -0
- package/dist/adapters/grpc/index.js +14 -0
- package/dist/adapters/grpc/index.js.map +1 -0
- package/dist/adapters/grpc/proto/blok/runtime/v1/runtime.proto +302 -0
- package/dist/adapters/grpc/types.d.ts +97 -0
- package/dist/adapters/grpc/types.js +41 -0
- package/dist/adapters/grpc/types.js.map +1 -0
- package/dist/adapters/transport.d.ts +108 -0
- package/dist/adapters/transport.js +196 -0
- package/dist/adapters/transport.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/testing/WorkflowTestRunner.js +12 -0
- package/dist/testing/WorkflowTestRunner.js.map +1 -1
- package/dist/tracing/RunTracker.d.ts +23 -2
- package/dist/tracing/RunTracker.js +120 -10
- package/dist/tracing/RunTracker.js.map +1 -1
- package/dist/tracing/SqliteRunStore.js +19 -3
- package/dist/tracing/SqliteRunStore.js.map +1 -1
- package/dist/tracing/TraceRouter.js +245 -4
- package/dist/tracing/TraceRouter.js.map +1 -1
- package/dist/tracing/types.d.ts +82 -10
- package/dist/types/GlobalOptions.d.ts +9 -2
- package/dist/workflow/PersistenceHelper.d.ts +46 -0
- package/dist/workflow/PersistenceHelper.js +57 -0
- package/dist/workflow/PersistenceHelper.js.map +1 -0
- package/dist/workflow/WorkflowNormalizer.d.ts +91 -0
- package/dist/workflow/WorkflowNormalizer.js +304 -0
- package/dist/workflow/WorkflowNormalizer.js.map +1 -0
- package/package.json +8 -5
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { Context } from "@blokjs/shared";
|
|
2
|
+
import { type ServiceClientConstructor } from "@grpc/grpc-js";
|
|
3
|
+
import type RunnerNode from "../../RunnerNode";
|
|
4
|
+
/**
|
|
5
|
+
* The {@link NodeRuntime} service client constructor — used by
|
|
6
|
+
* {@link GrpcClientPool} to instantiate clients.
|
|
7
|
+
*/
|
|
8
|
+
export declare const NodeRuntimeService: ServiceClientConstructor;
|
|
9
|
+
export interface ExecuteRequestProto {
|
|
10
|
+
node: NodeRefProto;
|
|
11
|
+
inputs: Buffer;
|
|
12
|
+
step: StepInfoProto;
|
|
13
|
+
trigger: TriggerInfoProto;
|
|
14
|
+
state: RuntimeStateProto;
|
|
15
|
+
workflow: WorkflowInfoProto;
|
|
16
|
+
options: ExecuteOptionsProto;
|
|
17
|
+
}
|
|
18
|
+
export interface NodeRefProto {
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
version: string;
|
|
22
|
+
}
|
|
23
|
+
export interface StepInfoProto {
|
|
24
|
+
name: string;
|
|
25
|
+
index: number;
|
|
26
|
+
total: number;
|
|
27
|
+
depth: number;
|
|
28
|
+
}
|
|
29
|
+
export interface TriggerInfoProto {
|
|
30
|
+
body: Buffer;
|
|
31
|
+
headers: Record<string, string>;
|
|
32
|
+
params: Record<string, string>;
|
|
33
|
+
query: Record<string, string>;
|
|
34
|
+
cookies: Record<string, string>;
|
|
35
|
+
method: string;
|
|
36
|
+
url: string;
|
|
37
|
+
baseUrl: string;
|
|
38
|
+
triggerKind: string;
|
|
39
|
+
}
|
|
40
|
+
export interface RuntimeStateProto {
|
|
41
|
+
previousOutput: Buffer;
|
|
42
|
+
vars: Buffer;
|
|
43
|
+
env: Record<string, string>;
|
|
44
|
+
}
|
|
45
|
+
export interface WorkflowInfoProto {
|
|
46
|
+
runId: string;
|
|
47
|
+
name: string;
|
|
48
|
+
path: string;
|
|
49
|
+
version: string;
|
|
50
|
+
startedAt: {
|
|
51
|
+
seconds: string;
|
|
52
|
+
nanos: number;
|
|
53
|
+
} | null;
|
|
54
|
+
}
|
|
55
|
+
export interface ExecuteOptionsProto {
|
|
56
|
+
deadlineMs: string;
|
|
57
|
+
streamLogs: boolean;
|
|
58
|
+
captureMetrics: boolean;
|
|
59
|
+
hints: Record<string, string>;
|
|
60
|
+
}
|
|
61
|
+
export interface ExecuteResponseProto {
|
|
62
|
+
success: boolean;
|
|
63
|
+
data: Buffer;
|
|
64
|
+
contentType: string;
|
|
65
|
+
error: NodeErrorProto | null;
|
|
66
|
+
varsDelta: Buffer;
|
|
67
|
+
logs: LogLineProto[];
|
|
68
|
+
metrics: MetricsProto | null;
|
|
69
|
+
}
|
|
70
|
+
export interface NodeErrorProto {
|
|
71
|
+
code: string;
|
|
72
|
+
category: string;
|
|
73
|
+
severity: string;
|
|
74
|
+
node: string;
|
|
75
|
+
sdk: string;
|
|
76
|
+
sdkVersion: string;
|
|
77
|
+
runtimeKind: string;
|
|
78
|
+
at: {
|
|
79
|
+
seconds: string;
|
|
80
|
+
nanos: number;
|
|
81
|
+
} | null;
|
|
82
|
+
message: string;
|
|
83
|
+
description: string;
|
|
84
|
+
remediation: string;
|
|
85
|
+
docUrl: string;
|
|
86
|
+
causes: NodeErrorProto[];
|
|
87
|
+
stack: string;
|
|
88
|
+
contextSnapshotJson: Buffer;
|
|
89
|
+
httpStatus: number;
|
|
90
|
+
retryable: boolean;
|
|
91
|
+
retryAfterMs: string;
|
|
92
|
+
detailsJson: Buffer;
|
|
93
|
+
}
|
|
94
|
+
export interface LogLineProto {
|
|
95
|
+
timestamp: {
|
|
96
|
+
seconds: string;
|
|
97
|
+
nanos: number;
|
|
98
|
+
} | null;
|
|
99
|
+
level: string;
|
|
100
|
+
message: string;
|
|
101
|
+
attributes: Record<string, string>;
|
|
102
|
+
}
|
|
103
|
+
export interface MetricsProto {
|
|
104
|
+
durationMs: number;
|
|
105
|
+
cpuMs: number;
|
|
106
|
+
memoryBytes: string;
|
|
107
|
+
requestBytes: string;
|
|
108
|
+
responseBytes: string;
|
|
109
|
+
}
|
|
110
|
+
export interface DecodedExecuteResponse {
|
|
111
|
+
readonly success: boolean;
|
|
112
|
+
readonly data: unknown;
|
|
113
|
+
readonly contentType: string;
|
|
114
|
+
readonly varsDelta: Record<string, unknown>;
|
|
115
|
+
readonly logs: ReadonlyArray<DecodedLogLine>;
|
|
116
|
+
readonly error: DecodedNodeError | null;
|
|
117
|
+
readonly metrics: DecodedMetrics;
|
|
118
|
+
}
|
|
119
|
+
export interface DecodedLogLine {
|
|
120
|
+
readonly timestamp: number;
|
|
121
|
+
readonly level: string;
|
|
122
|
+
readonly message: string;
|
|
123
|
+
readonly attributes: Record<string, string>;
|
|
124
|
+
}
|
|
125
|
+
export interface DecodedNodeError {
|
|
126
|
+
readonly code: string;
|
|
127
|
+
readonly category: string;
|
|
128
|
+
readonly severity: string;
|
|
129
|
+
readonly node: string;
|
|
130
|
+
readonly sdk: string;
|
|
131
|
+
readonly sdkVersion: string;
|
|
132
|
+
readonly runtimeKind: string;
|
|
133
|
+
readonly at: number;
|
|
134
|
+
readonly message: string;
|
|
135
|
+
readonly description: string;
|
|
136
|
+
readonly remediation: string;
|
|
137
|
+
readonly docUrl: string;
|
|
138
|
+
readonly causes: ReadonlyArray<DecodedNodeError>;
|
|
139
|
+
readonly stack: string;
|
|
140
|
+
readonly contextSnapshot: unknown;
|
|
141
|
+
readonly httpStatus: number;
|
|
142
|
+
readonly retryable: boolean;
|
|
143
|
+
readonly retryAfterMs: number;
|
|
144
|
+
readonly details: unknown;
|
|
145
|
+
}
|
|
146
|
+
export interface DecodedMetrics {
|
|
147
|
+
readonly durationMs: number;
|
|
148
|
+
readonly cpuMs: number;
|
|
149
|
+
readonly memoryBytes: number;
|
|
150
|
+
readonly requestBytes: number;
|
|
151
|
+
readonly responseBytes: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Encode a workflow {@link Context} and a {@link RunnerNode} into a
|
|
155
|
+
* {@link ExecuteRequestProto} ready for the gRPC wire.
|
|
156
|
+
*
|
|
157
|
+
* Pure function — no I/O. The opaque JSON-shaped fields (`inputs`,
|
|
158
|
+
* `previous_output`, `vars`, body) are serialized to UTF-8 bytes here so the
|
|
159
|
+
* SDK side can JSON-decode lazily.
|
|
160
|
+
*
|
|
161
|
+
* Critically, `inputs` is the resolved node config (from the Blueprint
|
|
162
|
+
* Mapper) sent UNWRAPPED — no `{inputs:{...}}` envelope. This closes the
|
|
163
|
+
* `BLOK_FRAMEWORK_FIXES.md` #3 unwrap-hack family of bugs at the wire format
|
|
164
|
+
* layer.
|
|
165
|
+
*/
|
|
166
|
+
export declare function encodeExecuteRequest(node: RunnerNode, ctx: Context, stepIndex: number, stepTotal: number, stepDepth: number, deadlineMs: number): ExecuteRequestProto;
|
|
167
|
+
/**
|
|
168
|
+
* Proto envelope for a streamed event. proto-loader with `oneofs: true`
|
|
169
|
+
* exposes the active oneof case via the `event` property AND mirrors the
|
|
170
|
+
* matching field at the top level. We discriminate on `event`.
|
|
171
|
+
*/
|
|
172
|
+
export interface ExecuteEventProto {
|
|
173
|
+
event: "started" | "log" | "progress" | "partial" | "final" | undefined;
|
|
174
|
+
started?: {
|
|
175
|
+
at: {
|
|
176
|
+
seconds: string;
|
|
177
|
+
nanos: number;
|
|
178
|
+
} | null;
|
|
179
|
+
};
|
|
180
|
+
log?: LogLineProto;
|
|
181
|
+
progress?: {
|
|
182
|
+
percent: number;
|
|
183
|
+
phase: string;
|
|
184
|
+
};
|
|
185
|
+
partial?: {
|
|
186
|
+
snapshotJson: Buffer;
|
|
187
|
+
};
|
|
188
|
+
final?: ExecuteResponseProto;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Adapter-facing discriminated union — keeps callers free of proto-loader
|
|
192
|
+
* shape concerns and lets TypeScript narrow on the `type` field.
|
|
193
|
+
*/
|
|
194
|
+
export type DecodedExecuteEvent = {
|
|
195
|
+
readonly type: "started";
|
|
196
|
+
readonly at: number;
|
|
197
|
+
} | {
|
|
198
|
+
readonly type: "log";
|
|
199
|
+
readonly log: DecodedLogLine;
|
|
200
|
+
} | {
|
|
201
|
+
readonly type: "progress";
|
|
202
|
+
readonly percent: number;
|
|
203
|
+
readonly phase: string;
|
|
204
|
+
} | {
|
|
205
|
+
readonly type: "partial";
|
|
206
|
+
readonly snapshot: unknown;
|
|
207
|
+
} | {
|
|
208
|
+
readonly type: "final";
|
|
209
|
+
readonly response: DecodedExecuteResponse;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Decode a single streamed `ExecuteEvent` proto into the discriminated union
|
|
213
|
+
* the adapter exposes. Returns `null` when the proto envelope is empty (no
|
|
214
|
+
* oneof field set) — the caller skips such frames.
|
|
215
|
+
*/
|
|
216
|
+
export declare function decodeExecuteEvent(event: ExecuteEventProto): DecodedExecuteEvent | null;
|
|
217
|
+
/**
|
|
218
|
+
* Decode a {@link ExecuteResponseProto} from the wire into the shape the
|
|
219
|
+
* adapter consumes. Defensive against missing fields (proto-loader fills in
|
|
220
|
+
* defaults, but we guard against malformed responses too).
|
|
221
|
+
*/
|
|
222
|
+
export declare function decodeExecuteResponse(response: ExecuteResponseProto): DecodedExecuteResponse;
|
|
223
|
+
/** Encode a value as UTF-8 JSON bytes. `null`/`undefined` → empty buffer. */
|
|
224
|
+
export declare function jsonToBuffer(value: unknown): Buffer;
|
|
225
|
+
/** Decode a buffer as UTF-8 JSON. Empty/missing buffer → `null`. */
|
|
226
|
+
export declare function bufferToJson(buf: Buffer | undefined): unknown;
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { loadPackageDefinition } from "@grpc/grpc-js";
|
|
4
|
+
import { loadSync } from "@grpc/proto-loader";
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Proto loading — single point of I/O in this module
|
|
7
|
+
// =============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the path to `runtime.proto`. Prefers the dist-bundled copy at
|
|
10
|
+
* runtime; falls back to the src copy when running from source.
|
|
11
|
+
*/
|
|
12
|
+
function resolveProtoPath() {
|
|
13
|
+
// `import.meta.url` works under both Node ESM and Bun. The dist copy
|
|
14
|
+
// sits next to the compiled JS; src copy sits next to TS source.
|
|
15
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
return path.resolve(here, "proto/blok/runtime/v1/runtime.proto");
|
|
17
|
+
}
|
|
18
|
+
/** Options for `@grpc/proto-loader` — chosen for fidelity with our schema. */
|
|
19
|
+
const PROTO_LOADER_OPTIONS = {
|
|
20
|
+
keepCase: false, // snake_case in proto -> camelCase in JS for ergonomic field access
|
|
21
|
+
longs: String,
|
|
22
|
+
enums: String,
|
|
23
|
+
defaults: true,
|
|
24
|
+
oneofs: true,
|
|
25
|
+
includeDirs: [],
|
|
26
|
+
};
|
|
27
|
+
/** Loaded once at module init; reused for every encode/decode. */
|
|
28
|
+
const PROTO_PATH = resolveProtoPath();
|
|
29
|
+
const PACKAGE_DEFINITION = loadSync(PROTO_PATH, PROTO_LOADER_OPTIONS);
|
|
30
|
+
const PROTO_DESCRIPTOR = loadPackageDefinition(PACKAGE_DEFINITION);
|
|
31
|
+
/** Path to the `NodeRuntime` service constructor inside the loaded proto. */
|
|
32
|
+
const NODE_RUNTIME_NAMESPACE = PROTO_DESCRIPTOR.blok.runtime.v1;
|
|
33
|
+
/**
|
|
34
|
+
* The {@link NodeRuntime} service client constructor — used by
|
|
35
|
+
* {@link GrpcClientPool} to instantiate clients.
|
|
36
|
+
*/
|
|
37
|
+
export const NodeRuntimeService = NODE_RUNTIME_NAMESPACE.NodeRuntime;
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Encoder — Context + RunnerNode → proto ExecuteRequest
|
|
40
|
+
// =============================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Encode a workflow {@link Context} and a {@link RunnerNode} into a
|
|
43
|
+
* {@link ExecuteRequestProto} ready for the gRPC wire.
|
|
44
|
+
*
|
|
45
|
+
* Pure function — no I/O. The opaque JSON-shaped fields (`inputs`,
|
|
46
|
+
* `previous_output`, `vars`, body) are serialized to UTF-8 bytes here so the
|
|
47
|
+
* SDK side can JSON-decode lazily.
|
|
48
|
+
*
|
|
49
|
+
* Critically, `inputs` is the resolved node config (from the Blueprint
|
|
50
|
+
* Mapper) sent UNWRAPPED — no `{inputs:{...}}` envelope. This closes the
|
|
51
|
+
* `BLOK_FRAMEWORK_FIXES.md` #3 unwrap-hack family of bugs at the wire format
|
|
52
|
+
* layer.
|
|
53
|
+
*/
|
|
54
|
+
export function encodeExecuteRequest(node, ctx, stepIndex, stepTotal, stepDepth, deadlineMs) {
|
|
55
|
+
const resolvedInputs = extractResolvedInputs(ctx, node.name);
|
|
56
|
+
const previousOutput = ctx.response?.data ?? null;
|
|
57
|
+
const vars = ctx.vars ?? {};
|
|
58
|
+
const env = stringEnv(ctx.env);
|
|
59
|
+
const request = ctx.request ?? {};
|
|
60
|
+
const requestBody = request.body;
|
|
61
|
+
return {
|
|
62
|
+
node: {
|
|
63
|
+
name: node.node,
|
|
64
|
+
type: node.type ?? "",
|
|
65
|
+
version: "",
|
|
66
|
+
},
|
|
67
|
+
inputs: jsonToBuffer(resolvedInputs),
|
|
68
|
+
step: {
|
|
69
|
+
name: node.name,
|
|
70
|
+
index: stepIndex,
|
|
71
|
+
total: stepTotal,
|
|
72
|
+
depth: stepDepth,
|
|
73
|
+
},
|
|
74
|
+
trigger: {
|
|
75
|
+
body: bodyToBuffer(requestBody),
|
|
76
|
+
headers: stringMap(request.headers),
|
|
77
|
+
params: stringMap(request.params),
|
|
78
|
+
query: stringMap(request.query),
|
|
79
|
+
cookies: stringMap(request.cookies),
|
|
80
|
+
method: stringField(request.method),
|
|
81
|
+
url: stringField(request.url),
|
|
82
|
+
baseUrl: stringField(request.baseUrl),
|
|
83
|
+
triggerKind: "",
|
|
84
|
+
},
|
|
85
|
+
state: {
|
|
86
|
+
previousOutput: jsonToBuffer(previousOutput),
|
|
87
|
+
vars: jsonToBuffer(vars),
|
|
88
|
+
env,
|
|
89
|
+
},
|
|
90
|
+
workflow: {
|
|
91
|
+
runId: ctx.id,
|
|
92
|
+
name: ctx.workflow_name ?? "",
|
|
93
|
+
path: ctx.workflow_path ?? "",
|
|
94
|
+
version: "",
|
|
95
|
+
startedAt: null,
|
|
96
|
+
},
|
|
97
|
+
options: {
|
|
98
|
+
deadlineMs: String(deadlineMs),
|
|
99
|
+
streamLogs: false,
|
|
100
|
+
captureMetrics: true,
|
|
101
|
+
hints: {},
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Decode a single streamed `ExecuteEvent` proto into the discriminated union
|
|
107
|
+
* the adapter exposes. Returns `null` when the proto envelope is empty (no
|
|
108
|
+
* oneof field set) — the caller skips such frames.
|
|
109
|
+
*/
|
|
110
|
+
export function decodeExecuteEvent(event) {
|
|
111
|
+
switch (event.event) {
|
|
112
|
+
case "started":
|
|
113
|
+
return { type: "started", at: timestampToMs(event.started?.at ?? null) };
|
|
114
|
+
case "log":
|
|
115
|
+
return event.log ? { type: "log", log: decodeLogLine(event.log) } : null;
|
|
116
|
+
case "progress":
|
|
117
|
+
return {
|
|
118
|
+
type: "progress",
|
|
119
|
+
percent: event.progress?.percent ?? 0,
|
|
120
|
+
phase: event.progress?.phase ?? "",
|
|
121
|
+
};
|
|
122
|
+
case "partial":
|
|
123
|
+
return { type: "partial", snapshot: bufferToJson(event.partial?.snapshotJson) };
|
|
124
|
+
case "final":
|
|
125
|
+
return event.final ? { type: "final", response: decodeExecuteResponse(event.final) } : null;
|
|
126
|
+
default:
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// =============================================================================
|
|
131
|
+
// Decoder — proto ExecuteResponse → DecodedExecuteResponse
|
|
132
|
+
// =============================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Decode a {@link ExecuteResponseProto} from the wire into the shape the
|
|
135
|
+
* adapter consumes. Defensive against missing fields (proto-loader fills in
|
|
136
|
+
* defaults, but we guard against malformed responses too).
|
|
137
|
+
*/
|
|
138
|
+
export function decodeExecuteResponse(response) {
|
|
139
|
+
return {
|
|
140
|
+
success: response.success ?? false,
|
|
141
|
+
data: bufferToJson(response.data),
|
|
142
|
+
contentType: response.contentType || "application/json",
|
|
143
|
+
varsDelta: bufferToJson(response.varsDelta) ?? {},
|
|
144
|
+
logs: (response.logs ?? []).map(decodeLogLine),
|
|
145
|
+
error: response.error ? decodeNodeError(response.error) : null,
|
|
146
|
+
metrics: decodeMetrics(response.metrics),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function decodeLogLine(line) {
|
|
150
|
+
return {
|
|
151
|
+
timestamp: timestampToMs(line.timestamp),
|
|
152
|
+
level: line.level,
|
|
153
|
+
message: line.message,
|
|
154
|
+
attributes: line.attributes ?? {},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function decodeNodeError(err) {
|
|
158
|
+
return {
|
|
159
|
+
code: err.code,
|
|
160
|
+
category: err.category,
|
|
161
|
+
severity: err.severity,
|
|
162
|
+
node: err.node,
|
|
163
|
+
sdk: err.sdk,
|
|
164
|
+
sdkVersion: err.sdkVersion,
|
|
165
|
+
runtimeKind: err.runtimeKind,
|
|
166
|
+
at: timestampToMs(err.at),
|
|
167
|
+
message: err.message,
|
|
168
|
+
description: err.description,
|
|
169
|
+
remediation: err.remediation,
|
|
170
|
+
docUrl: err.docUrl,
|
|
171
|
+
causes: (err.causes ?? []).map(decodeNodeError),
|
|
172
|
+
stack: err.stack,
|
|
173
|
+
contextSnapshot: bufferToJson(err.contextSnapshotJson),
|
|
174
|
+
httpStatus: err.httpStatus,
|
|
175
|
+
retryable: err.retryable,
|
|
176
|
+
retryAfterMs: Number(err.retryAfterMs ?? 0),
|
|
177
|
+
details: bufferToJson(err.detailsJson),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function decodeMetrics(metrics) {
|
|
181
|
+
return {
|
|
182
|
+
durationMs: metrics?.durationMs ?? 0,
|
|
183
|
+
cpuMs: metrics?.cpuMs ?? 0,
|
|
184
|
+
memoryBytes: Number(metrics?.memoryBytes ?? 0),
|
|
185
|
+
requestBytes: Number(metrics?.requestBytes ?? 0),
|
|
186
|
+
responseBytes: Number(metrics?.responseBytes ?? 0),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// =============================================================================
|
|
190
|
+
// Internal serialization helpers
|
|
191
|
+
// =============================================================================
|
|
192
|
+
/**
|
|
193
|
+
* Pull resolved node inputs from `ctx.config[nodeName].inputs` (the shape
|
|
194
|
+
* established by the Blueprint Mapper) and return them as a plain object.
|
|
195
|
+
*
|
|
196
|
+
* Falls back to `ctx.response.data` when no resolved inputs exist (matches
|
|
197
|
+
* the legacy zero-config-chaining behavior of `HttpRuntimeAdapter`).
|
|
198
|
+
*/
|
|
199
|
+
function extractResolvedInputs(ctx, nodeName) {
|
|
200
|
+
const nodeConfig = ctx.config
|
|
201
|
+
? ctx.config[nodeName]
|
|
202
|
+
: undefined;
|
|
203
|
+
const resolved = nodeConfig?.inputs;
|
|
204
|
+
if (resolved !== undefined)
|
|
205
|
+
return resolved;
|
|
206
|
+
return ctx.response?.data ?? {};
|
|
207
|
+
}
|
|
208
|
+
/** Encode a value as UTF-8 JSON bytes. `null`/`undefined` → empty buffer. */
|
|
209
|
+
export function jsonToBuffer(value) {
|
|
210
|
+
if (value === null || value === undefined)
|
|
211
|
+
return Buffer.alloc(0);
|
|
212
|
+
return Buffer.from(JSON.stringify(value), "utf-8");
|
|
213
|
+
}
|
|
214
|
+
/** Decode a buffer as UTF-8 JSON. Empty/missing buffer → `null`. */
|
|
215
|
+
export function bufferToJson(buf) {
|
|
216
|
+
if (!buf || buf.length === 0)
|
|
217
|
+
return null;
|
|
218
|
+
try {
|
|
219
|
+
return JSON.parse(buf.toString("utf-8"));
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Malformed JSON — return raw string so callers can salvage what they can.
|
|
223
|
+
return buf.toString("utf-8");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Encode a request body. Strings stay UTF-8; objects become JSON; Buffers
|
|
228
|
+
* pass through. Anything else stringifies via JSON.
|
|
229
|
+
*/
|
|
230
|
+
function bodyToBuffer(body) {
|
|
231
|
+
if (body === null || body === undefined)
|
|
232
|
+
return Buffer.alloc(0);
|
|
233
|
+
if (Buffer.isBuffer(body))
|
|
234
|
+
return body;
|
|
235
|
+
if (typeof body === "string")
|
|
236
|
+
return Buffer.from(body, "utf-8");
|
|
237
|
+
return Buffer.from(JSON.stringify(body), "utf-8");
|
|
238
|
+
}
|
|
239
|
+
/** Coerce an unknown record-like value into `Record<string, string>`. */
|
|
240
|
+
function stringMap(value) {
|
|
241
|
+
if (!value || typeof value !== "object")
|
|
242
|
+
return {};
|
|
243
|
+
const out = {};
|
|
244
|
+
for (const [key, val] of Object.entries(value)) {
|
|
245
|
+
if (typeof val === "string")
|
|
246
|
+
out[key] = val;
|
|
247
|
+
else if (val !== null && val !== undefined)
|
|
248
|
+
out[key] = String(val);
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
/** Coerce an unknown value into a string field; default empty. */
|
|
253
|
+
function stringField(value) {
|
|
254
|
+
return typeof value === "string" ? value : "";
|
|
255
|
+
}
|
|
256
|
+
/** Filter env to string-valued entries (process.env can carry undefined). */
|
|
257
|
+
function stringEnv(env) {
|
|
258
|
+
if (!env)
|
|
259
|
+
return {};
|
|
260
|
+
const out = {};
|
|
261
|
+
for (const [key, val] of Object.entries(env)) {
|
|
262
|
+
if (typeof val === "string")
|
|
263
|
+
out[key] = val;
|
|
264
|
+
}
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
/** Convert a proto Timestamp to ms-since-epoch. */
|
|
268
|
+
function timestampToMs(ts) {
|
|
269
|
+
if (!ts)
|
|
270
|
+
return 0;
|
|
271
|
+
const seconds = Number(ts.seconds ?? 0);
|
|
272
|
+
const nanos = ts.nanos ?? 0;
|
|
273
|
+
return seconds * 1000 + Math.floor(nanos / 1_000_000);
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=GrpcCodec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrpcCodec.js","sourceRoot":"","sources":["../../../src/adapters/grpc/GrpcCodec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAkD,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAgB,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG5D,gFAAgF;AAChF,qDAAqD;AACrD,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,gBAAgB;IACxB,qEAAqE;IACrE,iEAAiE;IACjE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,qCAAqC,CAAC,CAAC;AAClE,CAAC;AAED,8EAA8E;AAC9E,MAAM,oBAAoB,GAAY;IACrC,QAAQ,EAAE,KAAK,EAAE,oEAAoE;IACrF,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,IAAI;IACZ,WAAW,EAAE,EAAE;CACf,CAAC;AAEF,kEAAkE;AAClE,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;AACtC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;AACtE,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,kBAAkB,CAA0B,CAAC;AAE5F,6EAA6E;AAC7E,MAAM,sBAAsB,GAAK,gBAAgB,CAAC,IAAmB,CAAC,OAAsB,CAAC,EAAgB,CAAC;AAE9G;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,WAAkD,CAAC;AAoK5G,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CACnC,IAAgB,EAChB,GAAY,EACZ,SAAiB,EACjB,SAAiB,EACjB,SAAiB,EACjB,UAAkB;IAElB,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC;IAClD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAA0C,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAK,EAAyB,CAAC;IAC1D,MAAM,WAAW,GAAI,OAA8B,CAAC,IAAI,CAAC;IAEzD,OAAO;QACN,IAAI,EAAE;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE,EAAE;SACX;QACD,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC;QACpC,IAAI,EAAE;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,SAAS;SAChB;QACD,OAAO,EAAE;YACR,IAAI,EAAE,YAAY,CAAC,WAAW,CAAC;YAC/B,OAAO,EAAE,SAAS,CAAE,OAAiC,CAAC,OAAO,CAAC;YAC9D,MAAM,EAAE,SAAS,CAAE,OAAgC,CAAC,MAAM,CAAC;YAC3D,KAAK,EAAE,SAAS,CAAE,OAA+B,CAAC,KAAK,CAAC;YACxD,OAAO,EAAE,SAAS,CAAE,OAAiC,CAAC,OAAO,CAAC;YAC9D,MAAM,EAAE,WAAW,CAAE,OAAgC,CAAC,MAAM,CAAC;YAC7D,GAAG,EAAE,WAAW,CAAE,OAA6B,CAAC,GAAG,CAAC;YACpD,OAAO,EAAE,WAAW,CAAE,OAAiC,CAAC,OAAO,CAAC;YAChE,WAAW,EAAE,EAAE;SACf;QACD,KAAK,EAAE;YACN,cAAc,EAAE,YAAY,CAAC,cAAc,CAAC;YAC5C,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC;YACxB,GAAG;SACH;QACD,QAAQ,EAAE;YACT,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,IAAI,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;YAC7B,IAAI,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;YAC7B,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,IAAI;SACf;QACD,OAAO,EAAE;YACR,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;YAC9B,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,IAAI;YACpB,KAAK,EAAE,EAAE;SACT;KACD,CAAC;AACH,CAAC;AA+BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IAC1D,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,SAAS;YACb,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QAC1E,KAAK,KAAK;YACT,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1E,KAAK,UAAU;YACd,OAAO;gBACN,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC;gBACrC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;aAClC,CAAC;QACH,KAAK,SAAS;YACb,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;QACjF,KAAK,OAAO;YACX,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7F;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC;AAED,gFAAgF;AAChF,2DAA2D;AAC3D,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAA8B;IACnE,OAAO;QACN,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,KAAK;QAClC,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;QACjC,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,kBAAkB;QACvD,SAAS,EAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAoC,IAAI,EAAE;QACrF,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;QAC9C,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;QAC9D,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC;KACxC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,IAAkB;IACxC,OAAO;QACN,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC;QACxC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;KACjC,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,GAAmB;IAC3C,OAAO;QACN,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,EAAE,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC;QAC/C,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,eAAe,EAAE,YAAY,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACtD,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC;QAC3C,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC;KACtC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAA4B;IAClD,OAAO;QACN,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,CAAC;QACpC,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,IAAI,CAAC,CAAC;QAC9C,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,CAAC;QAChD,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,aAAa,IAAI,CAAC,CAAC;KAClD,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAS,qBAAqB,CAAC,GAAY,EAAE,QAAgB;IAC5D,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM;QAC5B,CAAC,CAAG,GAAG,CAAC,MAAkC,CAAC,QAAQ,CAAyC;QAC5F,CAAC,CAAC,SAAS,CAAC;IACb,MAAM,QAAQ,GAAG,UAAU,EAAE,MAAM,CAAC;IACpC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,GAAuB;IACnD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,2EAA2E;QAC3E,OAAO,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,IAAa;IAClC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS,CAAC,KAAc;IAChC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACnD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC3E,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;aACvC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,kEAAkE;AAClE,SAAS,WAAW,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,SAAS,SAAS,CAAC,GAAwC;IAC1D,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC7C,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,mDAAmD;AACnD,SAAS,aAAa,CAAC,EAAyD;IAC/E,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAClB,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;IAC5B,OAAO,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { BlokError, ErrorCategory } from "@blokjs/shared";
|
|
2
|
+
import { status as GrpcStatus, type ServiceError } from "@grpc/grpc-js";
|
|
3
|
+
/**
|
|
4
|
+
* Mapping table from `@grpc/grpc-js` `status` codes to canonical
|
|
5
|
+
* `(ErrorCategory, defaultHttpStatus)` pairs.
|
|
6
|
+
*
|
|
7
|
+
* Single source of truth for gRPC-side error classification. Adapters never
|
|
8
|
+
* branch on status codes inline; they call {@link toBlokError} which uses
|
|
9
|
+
* this table.
|
|
10
|
+
*
|
|
11
|
+
* The table is exhaustive — every gRPC status defined in
|
|
12
|
+
* `@grpc/grpc-js#status` has an entry. CI verifies coverage in the unit test.
|
|
13
|
+
*/
|
|
14
|
+
export declare const GRPC_STATUS_MAP: Readonly<Record<GrpcStatus, {
|
|
15
|
+
category: ErrorCategory;
|
|
16
|
+
httpStatus: number;
|
|
17
|
+
codePrefix: string;
|
|
18
|
+
}>>;
|
|
19
|
+
/**
|
|
20
|
+
* Context passed alongside a gRPC error so the resulting {@link BlokError}
|
|
21
|
+
* carries origin information (which SDK, which kind, which step) without
|
|
22
|
+
* the adapter having to know the proto layout.
|
|
23
|
+
*/
|
|
24
|
+
export interface GrpcErrorContext {
|
|
25
|
+
readonly node: string;
|
|
26
|
+
readonly sdk: string;
|
|
27
|
+
readonly sdkVersion: string;
|
|
28
|
+
readonly runtimeKind: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Convert a gRPC `ServiceError` (or any thrown value from a gRPC call) into a
|
|
32
|
+
* canonical {@link BlokError}. Lossless when the SDK populates structured
|
|
33
|
+
* details: gRPC `status.details` carrying a serialized {@link NodeErrorPayload}
|
|
34
|
+
* is decoded and merged into the resulting error.
|
|
35
|
+
*
|
|
36
|
+
* Behavior:
|
|
37
|
+
* - `ServiceError` with a known `code`: looked up in {@link GRPC_STATUS_MAP}.
|
|
38
|
+
* If `metadata` carries `blok-error-bin` (a serialized NodeErrorPayload),
|
|
39
|
+
* the payload is reconstructed via {@link BlokError.fromJSON} and the
|
|
40
|
+
* gRPC status only refines the http_status / category fallback.
|
|
41
|
+
* - Plain `Error`: wrapped via {@link BlokError.fromUnknown}.
|
|
42
|
+
* - Anything else: stringified and wrapped as `INTERNAL`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function toBlokError(err: unknown, ctx: GrpcErrorContext): BlokError;
|
|
45
|
+
/**
|
|
46
|
+
* Type guard for {@link ServiceError}. Duck-typed because `instanceof` checks
|
|
47
|
+
* across `@grpc/grpc-js` module boundaries are unreliable when the dep is
|
|
48
|
+
* deduped at multiple versions.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isServiceError(err: unknown): err is ServiceError;
|
|
51
|
+
/**
|
|
52
|
+
* Translate a `BlokError` produced by the runner side back into a gRPC status
|
|
53
|
+
* code, for cases where the runner needs to report failure to a downstream
|
|
54
|
+
* caller using gRPC. Inverse of {@link GRPC_STATUS_MAP}.
|
|
55
|
+
*
|
|
56
|
+
* Currently used only by tests; will be used by Phase 5 streaming when the
|
|
57
|
+
* runner re-emits node errors as `ExecuteStream` `final` frames.
|
|
58
|
+
*/
|
|
59
|
+
export declare function categoryToGrpcStatus(category: ErrorCategory): GrpcStatus;
|