service-bridge 1.8.5-dev.49 → 2.0.0-alpha
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/LICENSE +21 -0
- package/README.md +386 -1053
- package/dist/http/express/index.d.ts +31 -0
- package/dist/http/express/index.js +2765 -0
- package/dist/http/express/index.js.map +1 -0
- package/dist/http/fastify/index.d.ts +38 -0
- package/dist/http/fastify/index.js +2726 -0
- package/dist/http/fastify/index.js.map +1 -0
- package/dist/http/hono/index.d.ts +39 -0
- package/dist/http/hono/index.js +2706 -0
- package/dist/http/hono/index.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +14907 -2722
- package/dist/index.js.map +1 -0
- package/dist/service-bridge-CPmirNES.d.ts +2261 -0
- package/package.json +107 -123
- package/dist/express.d.ts +0 -51
- package/dist/express.js +0 -129
- package/dist/fastify.d.ts +0 -43
- package/dist/fastify.js +0 -122
- package/dist/trace.d.ts +0 -19
|
@@ -0,0 +1,2261 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js';
|
|
2
|
+
import { Client, CallOptions, ClientReadableStream, Metadata, ChannelCredentials, ClientOptions, ServiceError, ClientUnaryCall, ClientDuplexStream } from '@grpc/grpc-js';
|
|
3
|
+
import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Route — canonical HTTP route entry collected by an integration (Express /
|
|
7
|
+
* Fastify / Hono) and published into the SB registry as METHOD_TYPE_HTTP.
|
|
8
|
+
*
|
|
9
|
+
* @internal — потребляется только интеграциями `servicebridge/{express,
|
|
10
|
+
* fastify,hono}` через `ServiceBridge.routes`. Прикладной код использует
|
|
11
|
+
* subpath-API, см. ../../userDocs/integrations.md.
|
|
12
|
+
*/
|
|
13
|
+
interface Route {
|
|
14
|
+
/** Uppercase HTTP method: "GET", "POST", "PUT", "PATCH", "DELETE", etc. */
|
|
15
|
+
method: string;
|
|
16
|
+
/** Raw framework pattern. SDK не нормализует — косметика на UI Service Map. */
|
|
17
|
+
pattern: string;
|
|
18
|
+
/** Source framework, for diagnostics and (later) Service Map UI badges. */
|
|
19
|
+
source: "express" | "fastify" | "hono";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Хук, передаваемый коллектору при конструировании. Реализуется `ServiceBridge`:
|
|
23
|
+
* `setEndpoint` синхронно обновляет `Registry._httpEndpoint`; `triggerRestart`
|
|
24
|
+
* рестартует Registry-watch стрим, если SDK уже запущен (no-op до `start()`).
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
interface RouteSink {
|
|
29
|
+
setEndpoint(endpoint: string): void;
|
|
30
|
+
triggerRestart(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* RouteCollector аккумулирует роуты по ключу `${method} ${pattern}` (дедуп) и
|
|
34
|
+
* управляет HTTP-endpoint жизненным циклом инстанса.
|
|
35
|
+
*
|
|
36
|
+
* Один публичный метод `publishHttp({host, port})`:
|
|
37
|
+
* 1. Записывает endpoint в Registry (`sink.setEndpoint`).
|
|
38
|
+
* 2. Триггерит `sink.triggerRestart()` — рестарт Registry-watch стрима.
|
|
39
|
+
* Если SDK ещё не стартовал, `triggerRestart` — no-op; endpoint просто
|
|
40
|
+
* оседает и попадёт в первый `RegisterRequest`.
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
declare class RouteCollector {
|
|
45
|
+
private readonly _routes;
|
|
46
|
+
private readonly _sink;
|
|
47
|
+
constructor(sink: RouteSink);
|
|
48
|
+
/** Добавляет роут. Дедуп по `${method} ${pattern}`. */
|
|
49
|
+
add(route: Route): void;
|
|
50
|
+
/** Сколько роутов уже собрано (для диагностики тестов). */
|
|
51
|
+
size(): number;
|
|
52
|
+
/**
|
|
53
|
+
* Записывает endpoint в Registry и триггерит `triggerRestart` callback.
|
|
54
|
+
* Безопасен до `sb.start()` — `triggerRestart` тогда no-op.
|
|
55
|
+
*/
|
|
56
|
+
publishHttp(endpoint: {
|
|
57
|
+
host: string;
|
|
58
|
+
port: number;
|
|
59
|
+
}): void;
|
|
60
|
+
/** Snapshot собранных роутов в порядке добавления (insertion order Map). */
|
|
61
|
+
snapshot(): readonly Route[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare enum MethodType {
|
|
65
|
+
METHOD_TYPE_UNSPECIFIED = 0,
|
|
66
|
+
METHOD_TYPE_RPC = 1,
|
|
67
|
+
METHOD_TYPE_EVENT = 2,
|
|
68
|
+
METHOD_TYPE_WORKFLOW = 3,
|
|
69
|
+
METHOD_TYPE_JOB = 4,
|
|
70
|
+
METHOD_TYPE_HTTP = 5,
|
|
71
|
+
UNRECOGNIZED = -1
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* CaptureMode is one channel's payload capture policy. The runtime is the
|
|
75
|
+
* single authority: it resolves each channel's mode from runtime settings and
|
|
76
|
+
* pushes the whole CaptureModes set to every SDK over RegisterAndWatch. SDKs
|
|
77
|
+
* apply the mode for an op's channel as its effective capture mode; a per-handler
|
|
78
|
+
* override may only narrow it (privacy ordering NONE < ERRORS < ALL), never
|
|
79
|
+
* widen it.
|
|
80
|
+
*/
|
|
81
|
+
declare enum CaptureMode$1 {
|
|
82
|
+
CAPTURE_MODE_UNSPECIFIED = 0,
|
|
83
|
+
CAPTURE_MODE_ALL = 1,
|
|
84
|
+
CAPTURE_MODE_ERRORS = 2,
|
|
85
|
+
CAPTURE_MODE_NONE = 3,
|
|
86
|
+
UNRECOGNIZED = -1
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* CaptureModes carries the per-channel payload capture policy pushed to SDKs.
|
|
90
|
+
* One CaptureMode per op channel; the runtime resolves each from its matching
|
|
91
|
+
* <channel>.payload_capture setting. The SDK picks the mode for an op's channel.
|
|
92
|
+
* Jobs carry no input/output payload (JobExecution has no args, the handler
|
|
93
|
+
* returns void), so the job channel has no capture mode — field 5 is reserved.
|
|
94
|
+
*/
|
|
95
|
+
interface CaptureModes {
|
|
96
|
+
rpc: CaptureMode$1;
|
|
97
|
+
http: CaptureMode$1;
|
|
98
|
+
event: CaptureMode$1;
|
|
99
|
+
workflow: CaptureMode$1;
|
|
100
|
+
}
|
|
101
|
+
declare const CaptureModes: MessageFns$5<CaptureModes>;
|
|
102
|
+
interface IncomingMethod {
|
|
103
|
+
type: MethodType;
|
|
104
|
+
name: string;
|
|
105
|
+
inputSchemaJson: Buffer;
|
|
106
|
+
outputSchemaJson: Buffer;
|
|
107
|
+
streaming: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* SDK-supplied contract hash (hex SHA-256). Runtime stores opaque,
|
|
110
|
+
* does not recompute. Empty for non-RPC method types (event/workflow/job/http).
|
|
111
|
+
*/
|
|
112
|
+
contractHash: string;
|
|
113
|
+
}
|
|
114
|
+
declare const IncomingMethod: MessageFns$5<IncomingMethod>;
|
|
115
|
+
interface PublishedEvent {
|
|
116
|
+
name: string;
|
|
117
|
+
schemaJson: Buffer;
|
|
118
|
+
/**
|
|
119
|
+
* SDK-supplied contract hash (hex SHA-256) of the Protobuf descriptor for
|
|
120
|
+
* this event's payload schema. Empty when the publisher declared the event
|
|
121
|
+
* without a schema. Runtime stores opaque, does not recompute (ADR-0005).
|
|
122
|
+
*/
|
|
123
|
+
contractHash: string;
|
|
124
|
+
}
|
|
125
|
+
declare const PublishedEvent: MessageFns$5<PublishedEvent>;
|
|
126
|
+
interface OutgoingDep {
|
|
127
|
+
serviceName: string;
|
|
128
|
+
methodName: string;
|
|
129
|
+
type: MethodType;
|
|
130
|
+
}
|
|
131
|
+
declare const OutgoingDep: MessageFns$5<OutgoingDep>;
|
|
132
|
+
interface EventSubscription {
|
|
133
|
+
pattern: string;
|
|
134
|
+
durable: boolean;
|
|
135
|
+
}
|
|
136
|
+
declare const EventSubscription: MessageFns$5<EventSubscription>;
|
|
137
|
+
interface RegisterRequest {
|
|
138
|
+
incoming: IncomingMethod[];
|
|
139
|
+
published: PublishedEvent[];
|
|
140
|
+
outgoing: OutgoingDep[];
|
|
141
|
+
callEndpoint: string;
|
|
142
|
+
eventSubscriptions: EventSubscription[];
|
|
143
|
+
/**
|
|
144
|
+
* Public HTTP host:port of this SDK instance (ADR 0001 — HTTP lives in user
|
|
145
|
+
* app). Used only by Service Map / Discovery; runtime does not proxy HTTP.
|
|
146
|
+
* Empty when SDK has no HTTP integration registered.
|
|
147
|
+
*/
|
|
148
|
+
httpEndpoint: string;
|
|
149
|
+
}
|
|
150
|
+
declare const RegisterRequest: MessageFns$5<RegisterRequest>;
|
|
151
|
+
interface MethodDescriptor {
|
|
152
|
+
serviceName: string;
|
|
153
|
+
serviceId: string;
|
|
154
|
+
instanceId: string;
|
|
155
|
+
type: MethodType;
|
|
156
|
+
name: string;
|
|
157
|
+
contractHash: string;
|
|
158
|
+
published: boolean;
|
|
159
|
+
inputSchema: Buffer;
|
|
160
|
+
outputSchema: Buffer;
|
|
161
|
+
streaming: boolean;
|
|
162
|
+
}
|
|
163
|
+
declare const MethodDescriptor: MessageFns$5<MethodDescriptor>;
|
|
164
|
+
interface ServiceInstanceInfo {
|
|
165
|
+
instanceId: string;
|
|
166
|
+
serviceId: string;
|
|
167
|
+
serviceName: string;
|
|
168
|
+
callEndpoint: string;
|
|
169
|
+
status: string;
|
|
170
|
+
/**
|
|
171
|
+
* Public HTTP host:port of this instance (ADR 0001). Empty when instance has
|
|
172
|
+
* no HTTP integration or after disconnect.
|
|
173
|
+
*/
|
|
174
|
+
httpEndpoint: string;
|
|
175
|
+
/**
|
|
176
|
+
* Start of the current unhealthy window for this instance (ADR-0008 §6).
|
|
177
|
+
* Unix-ms timestamp; 0 when the instance is healthy. SDK-side LB treats it as a hint.
|
|
178
|
+
*/
|
|
179
|
+
isUnhealthySinceUnixMs: number;
|
|
180
|
+
}
|
|
181
|
+
declare const ServiceInstanceInfo: MessageFns$5<ServiceInstanceInfo>;
|
|
182
|
+
interface RegistrySnapshot {
|
|
183
|
+
methods: MethodDescriptor[];
|
|
184
|
+
instances: ServiceInstanceInfo[];
|
|
185
|
+
/**
|
|
186
|
+
* ── Service-map enrichment (ADR-0014) ────────────────────────────────────
|
|
187
|
+
* Per-service event subscriptions visible to the caller. Combined with
|
|
188
|
+
* event publishers from `methods` (METHOD_TYPE_EVENT + published=true) this
|
|
189
|
+
* lets UI / SDK draw the full pub/sub graph including wildcards.
|
|
190
|
+
*/
|
|
191
|
+
eventSubscriptions: EventSubscriptionDescriptor[];
|
|
192
|
+
/**
|
|
193
|
+
* Per-service outgoing call declarations from sb.service(...). One row per
|
|
194
|
+
* (caller_service, target_service, target_method, target_type) tuple.
|
|
195
|
+
*/
|
|
196
|
+
outgoingCalls: OutgoingCallDescriptor[];
|
|
197
|
+
/**
|
|
198
|
+
* Policy evaluation for the caller of this RegisterAndWatch stream — the
|
|
199
|
+
* caller's effective capabilities + rules + per-declaration warnings.
|
|
200
|
+
*/
|
|
201
|
+
policy?: PolicyEvaluation | undefined;
|
|
202
|
+
/**
|
|
203
|
+
* Per-channel payload capture modes. Always stamped on the snapshot so the
|
|
204
|
+
* SDK has an effective mode per channel from the first frame (before any
|
|
205
|
+
* update).
|
|
206
|
+
*/
|
|
207
|
+
captureModes?: CaptureModes | undefined;
|
|
208
|
+
}
|
|
209
|
+
declare const RegistrySnapshot: MessageFns$5<RegistrySnapshot>;
|
|
210
|
+
interface RegistryUpdate {
|
|
211
|
+
added: MethodDescriptor[];
|
|
212
|
+
removed: MethodDescriptor[];
|
|
213
|
+
addedInstances: ServiceInstanceInfo[];
|
|
214
|
+
removedInstances: ServiceInstanceInfo[];
|
|
215
|
+
/** Same enrichment as RegistrySnapshot.* but incremental. */
|
|
216
|
+
addedEventSubscriptions: EventSubscriptionDescriptor[];
|
|
217
|
+
removedEventSubscriptions: EventSubscriptionDescriptor[];
|
|
218
|
+
addedOutgoingCalls: OutgoingCallDescriptor[];
|
|
219
|
+
removedOutgoingCalls: OutgoingCallDescriptor[];
|
|
220
|
+
/**
|
|
221
|
+
* When policy changes (NOTIFY policy_changed touches caller), runtime
|
|
222
|
+
* re-emits the full PolicyEvaluation. Not incremental on purpose: policy
|
|
223
|
+
* edits are rare and the evaluation is small.
|
|
224
|
+
*/
|
|
225
|
+
policy?: PolicyEvaluation | undefined;
|
|
226
|
+
/**
|
|
227
|
+
* Derived from per-field diff after a policy push. peer_id is in
|
|
228
|
+
* added_peers when it first appears in the caller's scope; in removed_peers
|
|
229
|
+
* when the last method/instance/subscription from that peer disappears from
|
|
230
|
+
* scope. SDK uses these to update serviceMap and close stale direct-conns.
|
|
231
|
+
*/
|
|
232
|
+
addedPeers: string[];
|
|
233
|
+
removedPeers: string[];
|
|
234
|
+
/**
|
|
235
|
+
* Re-emitted full per-channel capture modes when any channel's mode changes.
|
|
236
|
+
* Like policy, not incremental: the whole set is sent on change.
|
|
237
|
+
*/
|
|
238
|
+
captureModes?: CaptureModes | undefined;
|
|
239
|
+
}
|
|
240
|
+
declare const RegistryUpdate: MessageFns$5<RegistryUpdate>;
|
|
241
|
+
interface RegistryEvent {
|
|
242
|
+
snapshot?: RegistrySnapshot | undefined;
|
|
243
|
+
update?: RegistryUpdate | undefined;
|
|
244
|
+
}
|
|
245
|
+
declare const RegistryEvent: MessageFns$5<RegistryEvent>;
|
|
246
|
+
interface EventSubscriptionDescriptor {
|
|
247
|
+
serviceId: string;
|
|
248
|
+
serviceName: string;
|
|
249
|
+
/** AMQP pattern, supports * and # */
|
|
250
|
+
pattern: string;
|
|
251
|
+
durable: boolean;
|
|
252
|
+
}
|
|
253
|
+
declare const EventSubscriptionDescriptor: MessageFns$5<EventSubscriptionDescriptor>;
|
|
254
|
+
interface OutgoingCallDescriptor {
|
|
255
|
+
callerServiceId: string;
|
|
256
|
+
callerServiceName: string;
|
|
257
|
+
targetServiceId: string;
|
|
258
|
+
targetServiceName: string;
|
|
259
|
+
targetMethod: string;
|
|
260
|
+
/** RPC, WORKFLOW, HTTP */
|
|
261
|
+
targetType: MethodType;
|
|
262
|
+
}
|
|
263
|
+
declare const OutgoingCallDescriptor: MessageFns$5<OutgoingCallDescriptor>;
|
|
264
|
+
interface PolicyEvaluation {
|
|
265
|
+
/**
|
|
266
|
+
* Capability flags currently enabled for the caller — names of the four
|
|
267
|
+
* booleans on services that are TRUE: "rpc.handle", "event.handle",
|
|
268
|
+
* "workflow.handle", "job.handle".
|
|
269
|
+
*/
|
|
270
|
+
capabilities: string[];
|
|
271
|
+
/** The caller's effective egress rules. */
|
|
272
|
+
egress: PolicyRule[];
|
|
273
|
+
/** The caller's effective acceptance rules. */
|
|
274
|
+
acceptance: PolicyRule[];
|
|
275
|
+
/** Per-declaration violations from the most recent registration. */
|
|
276
|
+
warnings: PolicyViolation[];
|
|
277
|
+
}
|
|
278
|
+
declare const PolicyEvaluation: MessageFns$5<PolicyEvaluation>;
|
|
279
|
+
interface PolicyRule {
|
|
280
|
+
/**
|
|
281
|
+
* 'rpc.call' | 'workflow.run' | 'event.publish' for egress;
|
|
282
|
+
* 'rpc.handle' | 'workflow.handle' | 'event.handle' for acceptance.
|
|
283
|
+
*/
|
|
284
|
+
action: string;
|
|
285
|
+
/**
|
|
286
|
+
* For rpc.* /workflow.*: peer service UUID (target for egress, caller for
|
|
287
|
+
* acceptance). Empty string for event.* (no per-service routing).
|
|
288
|
+
*/
|
|
289
|
+
peerServiceId: string;
|
|
290
|
+
/** Human-readable peer service name (for UI / sb-policy show). */
|
|
291
|
+
peerServiceName: string;
|
|
292
|
+
/**
|
|
293
|
+
* Method name pattern (literal or '*') for rpc.* /workflow.*; AMQP pattern
|
|
294
|
+
* for event.*.
|
|
295
|
+
*/
|
|
296
|
+
targetName: string;
|
|
297
|
+
}
|
|
298
|
+
declare const PolicyRule: MessageFns$5<PolicyRule>;
|
|
299
|
+
interface PolicyViolation {
|
|
300
|
+
/**
|
|
301
|
+
* Declaration type, e.g. 'rpc.call', 'event.handle', 'event.publish',
|
|
302
|
+
* 'rpc.handle' (capability), etc.
|
|
303
|
+
*/
|
|
304
|
+
declaration: string;
|
|
305
|
+
/** Concrete value, e.g. 'payments/charge', 'orders.*'. */
|
|
306
|
+
value: string;
|
|
307
|
+
/** 'capability' | 'self_egress' | 'self_acceptance' | 'peer_acceptance'. */
|
|
308
|
+
denySide: string;
|
|
309
|
+
/** Human-readable explanation. */
|
|
310
|
+
reason: string;
|
|
311
|
+
}
|
|
312
|
+
declare const PolicyViolation: MessageFns$5<PolicyViolation>;
|
|
313
|
+
type RegistryService = typeof RegistryService;
|
|
314
|
+
declare const RegistryService: {
|
|
315
|
+
readonly registerAndWatch: {
|
|
316
|
+
readonly path: "/servicebridge.v1.Registry/RegisterAndWatch";
|
|
317
|
+
readonly requestStream: false;
|
|
318
|
+
readonly responseStream: true;
|
|
319
|
+
readonly requestSerialize: (value: RegisterRequest) => Buffer;
|
|
320
|
+
readonly requestDeserialize: (value: Buffer) => RegisterRequest;
|
|
321
|
+
readonly responseSerialize: (value: RegistryEvent) => Buffer;
|
|
322
|
+
readonly responseDeserialize: (value: Buffer) => RegistryEvent;
|
|
323
|
+
};
|
|
324
|
+
};
|
|
325
|
+
interface RegistryClient extends Client {
|
|
326
|
+
registerAndWatch(request: RegisterRequest, options?: Partial<CallOptions>): ClientReadableStream<RegistryEvent>;
|
|
327
|
+
registerAndWatch(request: RegisterRequest, metadata?: Metadata, options?: Partial<CallOptions>): ClientReadableStream<RegistryEvent>;
|
|
328
|
+
}
|
|
329
|
+
declare const RegistryClient: {
|
|
330
|
+
new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): RegistryClient;
|
|
331
|
+
service: typeof RegistryService;
|
|
332
|
+
serviceName: string;
|
|
333
|
+
};
|
|
334
|
+
type Builtin$5 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
335
|
+
type DeepPartial$5<T> = T extends Builtin$5 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$5<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$5<U>> : T extends {} ? {
|
|
336
|
+
[K in keyof T]?: DeepPartial$5<T[K]>;
|
|
337
|
+
} : Partial<T>;
|
|
338
|
+
type KeysOfUnion$5<T> = T extends T ? keyof T : never;
|
|
339
|
+
type Exact$5<P, I extends P> = P extends Builtin$5 ? P : P & {
|
|
340
|
+
[K in keyof P]: Exact$5<P[K], I[K]>;
|
|
341
|
+
} & {
|
|
342
|
+
[K in Exclude<keyof I, KeysOfUnion$5<P>>]: never;
|
|
343
|
+
};
|
|
344
|
+
interface MessageFns$5<T> {
|
|
345
|
+
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
346
|
+
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
347
|
+
create<I extends Exact$5<DeepPartial$5<T>, I>>(base?: I): T;
|
|
348
|
+
fromPartial<I extends Exact$5<DeepPartial$5<T>, I>>(object: I): T;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
type CaptureMode = "all" | "errors" | "none";
|
|
352
|
+
|
|
353
|
+
interface DispatchPort {
|
|
354
|
+
dispatchUnary(method: string, payload: Uint8Array): Promise<UnaryResult>;
|
|
355
|
+
dispatchStream(method: string, payload: Uint8Array): AsyncIterable<StreamItem>;
|
|
356
|
+
captureMode(method: string): CaptureMode | undefined;
|
|
357
|
+
}
|
|
358
|
+
interface UnaryResult {
|
|
359
|
+
payload: Uint8Array;
|
|
360
|
+
errorCode?: string;
|
|
361
|
+
errorMessage?: string;
|
|
362
|
+
}
|
|
363
|
+
interface StreamItem {
|
|
364
|
+
payload?: Uint8Array;
|
|
365
|
+
errorCode?: string;
|
|
366
|
+
errorMessage?: string;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
interface JsonSchemaFileSpec {
|
|
370
|
+
schemaFile: string;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
interface ProtoFileSpec {
|
|
374
|
+
protoFile: string;
|
|
375
|
+
input?: string;
|
|
376
|
+
output?: string;
|
|
377
|
+
method?: string;
|
|
378
|
+
}
|
|
379
|
+
type SchemaSpec = ProtoFileSpec | JsonSchemaFileSpec;
|
|
380
|
+
interface Serializer {
|
|
381
|
+
encode(value: unknown): Uint8Array;
|
|
382
|
+
decode(bytes: Uint8Array): unknown;
|
|
383
|
+
contractHash(): string;
|
|
384
|
+
toJsonSchema(): Record<string, unknown>;
|
|
385
|
+
}
|
|
386
|
+
interface SchemaPair {
|
|
387
|
+
input: Serializer;
|
|
388
|
+
output: Serializer;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
interface RpcHandlerOpts {
|
|
392
|
+
schema: SchemaSpec;
|
|
393
|
+
captureMode?: CaptureMode;
|
|
394
|
+
}
|
|
395
|
+
interface WorkflowHandlerOpts {
|
|
396
|
+
input?: Record<string, unknown>;
|
|
397
|
+
}
|
|
398
|
+
interface ServiceDeps {
|
|
399
|
+
rpc?: string[];
|
|
400
|
+
workflows?: string[];
|
|
401
|
+
http?: string[];
|
|
402
|
+
}
|
|
403
|
+
type RpcHandlerFn<Req = unknown, Res = unknown> = (req: Req) => Promise<Res> | Res;
|
|
404
|
+
type RpcStreamHandlerFn<Req = unknown, Chunk = unknown> = (req: Req) => AsyncIterable<Chunk>;
|
|
405
|
+
interface HandlerEntry {
|
|
406
|
+
type: MethodType;
|
|
407
|
+
name: string;
|
|
408
|
+
inputSchemaJson: Buffer | null;
|
|
409
|
+
outputSchemaJson: Buffer | null;
|
|
410
|
+
fn: unknown;
|
|
411
|
+
streaming?: boolean;
|
|
412
|
+
schemaPair?: SchemaPair;
|
|
413
|
+
contractHashOverride?: string;
|
|
414
|
+
captureMode?: CaptureMode;
|
|
415
|
+
}
|
|
416
|
+
interface PublishedEntry {
|
|
417
|
+
name: string;
|
|
418
|
+
inputSchemaJson: Buffer | null;
|
|
419
|
+
contractHash: string;
|
|
420
|
+
schemaPair?: SchemaPair;
|
|
421
|
+
spec?: SchemaSpec;
|
|
422
|
+
}
|
|
423
|
+
declare class Handle {
|
|
424
|
+
readonly _entries: HandlerEntry[];
|
|
425
|
+
readonly _published: PublishedEntry[];
|
|
426
|
+
private pending;
|
|
427
|
+
rpc<Req = unknown, Res = unknown>(name: string, fn: RpcHandlerFn<Req, Res>, opts: RpcHandlerOpts): void;
|
|
428
|
+
stream<Req = unknown, Chunk = unknown>(name: string, fn: RpcStreamHandlerFn<Req, Chunk>, opts: RpcHandlerOpts): void;
|
|
429
|
+
_declareForTests(name: string, streaming?: boolean): void;
|
|
430
|
+
private registerRpc;
|
|
431
|
+
publishEvent(name: string, spec?: SchemaSpec): void;
|
|
432
|
+
getPublishedEvent(name: string): {
|
|
433
|
+
contractHash: string;
|
|
434
|
+
pair: SchemaPair;
|
|
435
|
+
} | undefined;
|
|
436
|
+
_declarePublishedEventForTests(name: string): void;
|
|
437
|
+
event(name: string, fn: unknown): void;
|
|
438
|
+
workflow(name: string, steps: unknown, opts?: WorkflowHandlerOpts, graphJson?: Buffer, contractHash?: string): void;
|
|
439
|
+
job(name: string, contractHash: string, specJson: string, fn: unknown): void;
|
|
440
|
+
finalize(): Promise<void>;
|
|
441
|
+
incomingMethods(): IncomingMethod[];
|
|
442
|
+
publishedEvents(): PublishedEvent[];
|
|
443
|
+
asDispatchPort(): DispatchPort;
|
|
444
|
+
}
|
|
445
|
+
declare class Registry {
|
|
446
|
+
readonly _handle: Handle;
|
|
447
|
+
/**
|
|
448
|
+
* Public-but-undocumented route collector. Используется только интеграциями
|
|
449
|
+
* `servicebridge/{express,fastify,hono}`. Прикладной код пишет роуты в свой
|
|
450
|
+
* фреймворк, не сюда. См. ADR 0001 и userDocs/integrations.md.
|
|
451
|
+
*/
|
|
452
|
+
readonly routes: RouteCollector;
|
|
453
|
+
private readonly _outgoing;
|
|
454
|
+
/**
|
|
455
|
+
* @param onRestart — вызывается из `routes.publishHttp(...)` после записи
|
|
456
|
+
* нового endpoint'а. ServiceBridge подставляет туда рестарт Registry-watch
|
|
457
|
+
* стрима. До `sb.start()` callback ожидает no-op.
|
|
458
|
+
*/
|
|
459
|
+
constructor(onRestart?: () => void);
|
|
460
|
+
service(serviceName: string, deps: ServiceDeps): void;
|
|
461
|
+
buildRegisterRequest(): RegisterRequest;
|
|
462
|
+
setCallEndpoint(endpoint: string): void;
|
|
463
|
+
private _callEndpoint;
|
|
464
|
+
private _httpEndpoint;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
declare enum PublishStatus {
|
|
468
|
+
PUBLISH_STATUS_UNSPECIFIED = 0,
|
|
469
|
+
PUBLISH_STATUS_ACCEPTED = 1,
|
|
470
|
+
PUBLISH_STATUS_REJECTED_DUPLICATE = 3,
|
|
471
|
+
PUBLISH_STATUS_REJECTED_INVALID_NAME = 5,
|
|
472
|
+
/**
|
|
473
|
+
* PUBLISH_STATUS_REJECTED_FORBIDDEN - ADR-0014: publisher does not have event.publish action rule matching this
|
|
474
|
+
* event name (or its capability is disabled). Per-envelope reject — other
|
|
475
|
+
* events in the batch proceed.
|
|
476
|
+
*/
|
|
477
|
+
PUBLISH_STATUS_REJECTED_FORBIDDEN = 6,
|
|
478
|
+
UNRECOGNIZED = -1
|
|
479
|
+
}
|
|
480
|
+
interface EventEnvelope {
|
|
481
|
+
id: string;
|
|
482
|
+
name: string;
|
|
483
|
+
payload: Buffer;
|
|
484
|
+
contractHash: string;
|
|
485
|
+
partitionKey: string;
|
|
486
|
+
idempotencyKey: string;
|
|
487
|
+
fireAndForget: boolean;
|
|
488
|
+
headers: {
|
|
489
|
+
[key: string]: string;
|
|
490
|
+
};
|
|
491
|
+
occurredAtUnixMs: number;
|
|
492
|
+
/** X-SB-Trace propagation: carried in EventEnvelope for publisher→consumer. */
|
|
493
|
+
xSbTrace: string;
|
|
494
|
+
/**
|
|
495
|
+
* payload_json — JSON-encoded view of the same payload, populated by the
|
|
496
|
+
* publisher SDK alongside the canonical protobuf `payload`. Used by the
|
|
497
|
+
* workflow signal router to evaluate JSON-path `wait_event` filters
|
|
498
|
+
* without decoding the protobuf form (runtime treats payload as opaque
|
|
499
|
+
* bytes per ADR-0013). Empty when publisher cannot produce JSON.
|
|
500
|
+
*/
|
|
501
|
+
payloadJson: Buffer;
|
|
502
|
+
}
|
|
503
|
+
declare const EventEnvelope: MessageFns$4<EventEnvelope>;
|
|
504
|
+
interface PublishRequest {
|
|
505
|
+
publisherServiceId: string;
|
|
506
|
+
publisherInstanceId: string;
|
|
507
|
+
events: EventEnvelope[];
|
|
508
|
+
}
|
|
509
|
+
declare const PublishRequest: MessageFns$4<PublishRequest>;
|
|
510
|
+
interface PublishStatusEntry {
|
|
511
|
+
eventId: string;
|
|
512
|
+
status: PublishStatus;
|
|
513
|
+
message: string;
|
|
514
|
+
}
|
|
515
|
+
declare const PublishStatusEntry: MessageFns$4<PublishStatusEntry>;
|
|
516
|
+
interface PublishResponse {
|
|
517
|
+
results: PublishStatusEntry[];
|
|
518
|
+
}
|
|
519
|
+
declare const PublishResponse: MessageFns$4<PublishResponse>;
|
|
520
|
+
interface SubscribeInit {
|
|
521
|
+
subscriberServiceId: string;
|
|
522
|
+
subscriberInstanceId: string;
|
|
523
|
+
maxInFlight: number;
|
|
524
|
+
}
|
|
525
|
+
declare const SubscribeInit: MessageFns$4<SubscribeInit>;
|
|
526
|
+
interface Ack {
|
|
527
|
+
deliveryId: string;
|
|
528
|
+
eventId: Buffer;
|
|
529
|
+
}
|
|
530
|
+
declare const Ack: MessageFns$4<Ack>;
|
|
531
|
+
interface Nack {
|
|
532
|
+
deliveryId: string;
|
|
533
|
+
errorMessage: string;
|
|
534
|
+
eventId: Buffer;
|
|
535
|
+
}
|
|
536
|
+
declare const Nack: MessageFns$4<Nack>;
|
|
537
|
+
interface SubscribeClientMessage {
|
|
538
|
+
init?: SubscribeInit | undefined;
|
|
539
|
+
ack?: Ack | undefined;
|
|
540
|
+
nack?: Nack | undefined;
|
|
541
|
+
}
|
|
542
|
+
declare const SubscribeClientMessage: MessageFns$4<SubscribeClientMessage>;
|
|
543
|
+
interface EventDelivery {
|
|
544
|
+
deliveryId: string;
|
|
545
|
+
envelope?: EventEnvelope | undefined;
|
|
546
|
+
attempt: number;
|
|
547
|
+
}
|
|
548
|
+
declare const EventDelivery: MessageFns$4<EventDelivery>;
|
|
549
|
+
interface SubscribeServerMessage {
|
|
550
|
+
delivery?: EventDelivery | undefined;
|
|
551
|
+
}
|
|
552
|
+
declare const SubscribeServerMessage: MessageFns$4<SubscribeServerMessage>;
|
|
553
|
+
interface ReplayDlqRequest {
|
|
554
|
+
eventId: string;
|
|
555
|
+
}
|
|
556
|
+
declare const ReplayDlqRequest: MessageFns$4<ReplayDlqRequest>;
|
|
557
|
+
interface ReplayDlqResponse {
|
|
558
|
+
eventId: string;
|
|
559
|
+
}
|
|
560
|
+
declare const ReplayDlqResponse: MessageFns$4<ReplayDlqResponse>;
|
|
561
|
+
interface ListDlqRequest {
|
|
562
|
+
limit: number;
|
|
563
|
+
cursor: string;
|
|
564
|
+
}
|
|
565
|
+
declare const ListDlqRequest: MessageFns$4<ListDlqRequest>;
|
|
566
|
+
interface DlqEntry {
|
|
567
|
+
eventId: string;
|
|
568
|
+
eventName: string;
|
|
569
|
+
consumerService: string;
|
|
570
|
+
lastError: string;
|
|
571
|
+
dlqAtUnixMs: number;
|
|
572
|
+
replayCount: number;
|
|
573
|
+
totalAttempts: number;
|
|
574
|
+
}
|
|
575
|
+
declare const DlqEntry: MessageFns$4<DlqEntry>;
|
|
576
|
+
interface ListDlqResponse {
|
|
577
|
+
entries: DlqEntry[];
|
|
578
|
+
nextCursor: string;
|
|
579
|
+
}
|
|
580
|
+
declare const ListDlqResponse: MessageFns$4<ListDlqResponse>;
|
|
581
|
+
type EventsService = typeof EventsService;
|
|
582
|
+
declare const EventsService: {
|
|
583
|
+
readonly publish: {
|
|
584
|
+
readonly path: "/servicebridge.v1.Events/Publish";
|
|
585
|
+
readonly requestStream: false;
|
|
586
|
+
readonly responseStream: false;
|
|
587
|
+
readonly requestSerialize: (value: PublishRequest) => Buffer;
|
|
588
|
+
readonly requestDeserialize: (value: Buffer) => PublishRequest;
|
|
589
|
+
readonly responseSerialize: (value: PublishResponse) => Buffer;
|
|
590
|
+
readonly responseDeserialize: (value: Buffer) => PublishResponse;
|
|
591
|
+
};
|
|
592
|
+
readonly subscribe: {
|
|
593
|
+
readonly path: "/servicebridge.v1.Events/Subscribe";
|
|
594
|
+
readonly requestStream: true;
|
|
595
|
+
readonly responseStream: true;
|
|
596
|
+
readonly requestSerialize: (value: SubscribeClientMessage) => Buffer;
|
|
597
|
+
readonly requestDeserialize: (value: Buffer) => SubscribeClientMessage;
|
|
598
|
+
readonly responseSerialize: (value: SubscribeServerMessage) => Buffer;
|
|
599
|
+
readonly responseDeserialize: (value: Buffer) => SubscribeServerMessage;
|
|
600
|
+
};
|
|
601
|
+
readonly replayDlq: {
|
|
602
|
+
readonly path: "/servicebridge.v1.Events/ReplayDlq";
|
|
603
|
+
readonly requestStream: false;
|
|
604
|
+
readonly responseStream: false;
|
|
605
|
+
readonly requestSerialize: (value: ReplayDlqRequest) => Buffer;
|
|
606
|
+
readonly requestDeserialize: (value: Buffer) => ReplayDlqRequest;
|
|
607
|
+
readonly responseSerialize: (value: ReplayDlqResponse) => Buffer;
|
|
608
|
+
readonly responseDeserialize: (value: Buffer) => ReplayDlqResponse;
|
|
609
|
+
};
|
|
610
|
+
readonly listDlq: {
|
|
611
|
+
readonly path: "/servicebridge.v1.Events/ListDlq";
|
|
612
|
+
readonly requestStream: false;
|
|
613
|
+
readonly responseStream: false;
|
|
614
|
+
readonly requestSerialize: (value: ListDlqRequest) => Buffer;
|
|
615
|
+
readonly requestDeserialize: (value: Buffer) => ListDlqRequest;
|
|
616
|
+
readonly responseSerialize: (value: ListDlqResponse) => Buffer;
|
|
617
|
+
readonly responseDeserialize: (value: Buffer) => ListDlqResponse;
|
|
618
|
+
};
|
|
619
|
+
};
|
|
620
|
+
interface EventsClient extends Client {
|
|
621
|
+
publish(request: PublishRequest, callback: (error: ServiceError | null, response: PublishResponse) => void): ClientUnaryCall;
|
|
622
|
+
publish(request: PublishRequest, metadata: Metadata, callback: (error: ServiceError | null, response: PublishResponse) => void): ClientUnaryCall;
|
|
623
|
+
publish(request: PublishRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: PublishResponse) => void): ClientUnaryCall;
|
|
624
|
+
subscribe(): ClientDuplexStream<SubscribeClientMessage, SubscribeServerMessage>;
|
|
625
|
+
subscribe(options: Partial<CallOptions>): ClientDuplexStream<SubscribeClientMessage, SubscribeServerMessage>;
|
|
626
|
+
subscribe(metadata: Metadata, options?: Partial<CallOptions>): ClientDuplexStream<SubscribeClientMessage, SubscribeServerMessage>;
|
|
627
|
+
replayDlq(request: ReplayDlqRequest, callback: (error: ServiceError | null, response: ReplayDlqResponse) => void): ClientUnaryCall;
|
|
628
|
+
replayDlq(request: ReplayDlqRequest, metadata: Metadata, callback: (error: ServiceError | null, response: ReplayDlqResponse) => void): ClientUnaryCall;
|
|
629
|
+
replayDlq(request: ReplayDlqRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: ReplayDlqResponse) => void): ClientUnaryCall;
|
|
630
|
+
listDlq(request: ListDlqRequest, callback: (error: ServiceError | null, response: ListDlqResponse) => void): ClientUnaryCall;
|
|
631
|
+
listDlq(request: ListDlqRequest, metadata: Metadata, callback: (error: ServiceError | null, response: ListDlqResponse) => void): ClientUnaryCall;
|
|
632
|
+
listDlq(request: ListDlqRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: ListDlqResponse) => void): ClientUnaryCall;
|
|
633
|
+
}
|
|
634
|
+
declare const EventsClient: {
|
|
635
|
+
new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): EventsClient;
|
|
636
|
+
service: typeof EventsService;
|
|
637
|
+
serviceName: string;
|
|
638
|
+
};
|
|
639
|
+
type Builtin$4 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
640
|
+
type DeepPartial$4<T> = T extends Builtin$4 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$4<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$4<U>> : T extends {} ? {
|
|
641
|
+
[K in keyof T]?: DeepPartial$4<T[K]>;
|
|
642
|
+
} : Partial<T>;
|
|
643
|
+
type KeysOfUnion$4<T> = T extends T ? keyof T : never;
|
|
644
|
+
type Exact$4<P, I extends P> = P extends Builtin$4 ? P : P & {
|
|
645
|
+
[K in keyof P]: Exact$4<P[K], I[K]>;
|
|
646
|
+
} & {
|
|
647
|
+
[K in Exclude<keyof I, KeysOfUnion$4<P>>]: never;
|
|
648
|
+
};
|
|
649
|
+
interface MessageFns$4<T> {
|
|
650
|
+
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
651
|
+
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
652
|
+
create<I extends Exact$4<DeepPartial$4<T>, I>>(base?: I): T;
|
|
653
|
+
fromPartial<I extends Exact$4<DeepPartial$4<T>, I>>(object: I): T;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
interface StorageOpenOpts {
|
|
657
|
+
dataDir?: string;
|
|
658
|
+
}
|
|
659
|
+
interface SqliteStatement {
|
|
660
|
+
run(...params: unknown[]): unknown;
|
|
661
|
+
get(...params: unknown[]): unknown;
|
|
662
|
+
all(...params: unknown[]): unknown[];
|
|
663
|
+
}
|
|
664
|
+
declare class Storage {
|
|
665
|
+
private readonly db;
|
|
666
|
+
private constructor();
|
|
667
|
+
static open(opts?: StorageOpenOpts): Storage;
|
|
668
|
+
transaction<T>(fn: () => T): T;
|
|
669
|
+
prepare(sql: string): SqliteStatement;
|
|
670
|
+
close(): void;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
interface PublishOpts {
|
|
674
|
+
idempotencyKey?: string;
|
|
675
|
+
partitionKey?: string;
|
|
676
|
+
fireAndForget?: boolean;
|
|
677
|
+
headers?: Record<string, string>;
|
|
678
|
+
occurredAtMs?: number;
|
|
679
|
+
}
|
|
680
|
+
interface SchemaIndex {
|
|
681
|
+
get(name: string): {
|
|
682
|
+
contractHash: string;
|
|
683
|
+
pair: SchemaPair;
|
|
684
|
+
} | undefined;
|
|
685
|
+
}
|
|
686
|
+
interface DrainerHandle {
|
|
687
|
+
kick(): void;
|
|
688
|
+
}
|
|
689
|
+
interface Logger {
|
|
690
|
+
warn(msg: string, ...args: unknown[]): void;
|
|
691
|
+
error(msg: string, ...args: unknown[]): void;
|
|
692
|
+
}
|
|
693
|
+
interface PublisherDeps {
|
|
694
|
+
storage: Storage;
|
|
695
|
+
rpcClient: EventsClient;
|
|
696
|
+
schemaIndex: SchemaIndex;
|
|
697
|
+
drainer: DrainerHandle;
|
|
698
|
+
identity: () => Identity | null;
|
|
699
|
+
maxOutboxRows: number;
|
|
700
|
+
logger: Logger;
|
|
701
|
+
sb?: ServiceBridge;
|
|
702
|
+
xSbTraceFn: () => string;
|
|
703
|
+
}
|
|
704
|
+
declare class Publisher {
|
|
705
|
+
private readonly deps;
|
|
706
|
+
private readonly xSbTraceFn;
|
|
707
|
+
constructor(deps: PublisherDeps);
|
|
708
|
+
publish(name: string, payload: unknown, opts?: PublishOpts): Promise<{
|
|
709
|
+
eventId: string;
|
|
710
|
+
}>;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
declare class EventDomain {
|
|
714
|
+
private readonly registry;
|
|
715
|
+
private readonly getPublisher;
|
|
716
|
+
constructor(registry: Registry, getPublisher: () => Publisher | null);
|
|
717
|
+
define(name: string, spec?: SchemaSpec): void;
|
|
718
|
+
handle(pattern: string, fn: (payload: unknown) => Promise<void> | void): void;
|
|
719
|
+
publish<T = unknown>(name: string, payload: T, opts?: PublishOpts): Promise<{
|
|
720
|
+
eventId: string;
|
|
721
|
+
}>;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
type CronTrigger = {
|
|
725
|
+
cron: string;
|
|
726
|
+
tz?: string;
|
|
727
|
+
};
|
|
728
|
+
type DelayedTrigger = {
|
|
729
|
+
delayed: {
|
|
730
|
+
at: Date | string | number;
|
|
731
|
+
};
|
|
732
|
+
};
|
|
733
|
+
type IntervalTrigger = {
|
|
734
|
+
interval: number;
|
|
735
|
+
};
|
|
736
|
+
type Trigger = CronTrigger | DelayedTrigger | IntervalTrigger;
|
|
737
|
+
type CatchupPolicy = "skip" | "fire_once" | "fire_all";
|
|
738
|
+
type OverlapPolicy = "skip" | "allow" | "buffer_one";
|
|
739
|
+
type DeclaredDep = {
|
|
740
|
+
rpc: string;
|
|
741
|
+
} | {
|
|
742
|
+
event: string;
|
|
743
|
+
} | {
|
|
744
|
+
workflow: string;
|
|
745
|
+
};
|
|
746
|
+
interface JobHandlerCtx {
|
|
747
|
+
jobName: string;
|
|
748
|
+
executionId: string;
|
|
749
|
+
scheduledAt: Date;
|
|
750
|
+
localScheduledAt: Date;
|
|
751
|
+
attempt: number;
|
|
752
|
+
idempotencyKey: string;
|
|
753
|
+
signal: AbortSignal;
|
|
754
|
+
}
|
|
755
|
+
type JobHandler = (ctx: JobHandlerCtx) => Promise<void>;
|
|
756
|
+
interface RetryPolicy {
|
|
757
|
+
initialMs: number;
|
|
758
|
+
maxMs: number;
|
|
759
|
+
multiplier: number;
|
|
760
|
+
jitter: number;
|
|
761
|
+
}
|
|
762
|
+
interface JobOpts {
|
|
763
|
+
trigger: Trigger;
|
|
764
|
+
catchup?: CatchupPolicy;
|
|
765
|
+
overlap?: OverlapPolicy;
|
|
766
|
+
deps?: DeclaredDep[];
|
|
767
|
+
maxAttempts?: number;
|
|
768
|
+
leaseTtlMs?: number;
|
|
769
|
+
maxConcurrent?: number;
|
|
770
|
+
retry?: RetryPolicy;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
declare class JobDomain {
|
|
774
|
+
private readonly registry;
|
|
775
|
+
private readonly _byName;
|
|
776
|
+
constructor(registry: Registry);
|
|
777
|
+
handle(name: string, opts: JobOpts, fn: JobHandler): void;
|
|
778
|
+
/** @internal — used by JobSubscriber to dispatch incoming executions. */
|
|
779
|
+
lookup(name: string): {
|
|
780
|
+
opts: JobOpts;
|
|
781
|
+
fn: JobHandler;
|
|
782
|
+
} | undefined;
|
|
783
|
+
/** @internal — used by ServiceBridge to skip subscriber startup when empty. */
|
|
784
|
+
size(): number;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
interface OpenRequest {
|
|
788
|
+
}
|
|
789
|
+
declare const OpenRequest: MessageFns$3<OpenRequest>;
|
|
790
|
+
interface RefreshCertRequest {
|
|
791
|
+
csrDer: Buffer;
|
|
792
|
+
}
|
|
793
|
+
declare const RefreshCertRequest: MessageFns$3<RefreshCertRequest>;
|
|
794
|
+
interface RefreshCertResponse {
|
|
795
|
+
certDer: Buffer;
|
|
796
|
+
caChainDer: Buffer;
|
|
797
|
+
notAfterUnix: number;
|
|
798
|
+
instanceId: string;
|
|
799
|
+
}
|
|
800
|
+
declare const RefreshCertResponse: MessageFns$3<RefreshCertResponse>;
|
|
801
|
+
interface ServerControl {
|
|
802
|
+
welcome?: Welcome | undefined;
|
|
803
|
+
drain?: Drain | undefined;
|
|
804
|
+
}
|
|
805
|
+
declare const ServerControl: MessageFns$3<ServerControl>;
|
|
806
|
+
interface Welcome {
|
|
807
|
+
sessionId: string;
|
|
808
|
+
serviceId: string;
|
|
809
|
+
serviceName: string;
|
|
810
|
+
}
|
|
811
|
+
declare const Welcome: MessageFns$3<Welcome>;
|
|
812
|
+
interface Drain {
|
|
813
|
+
reason: string;
|
|
814
|
+
}
|
|
815
|
+
declare const Drain: MessageFns$3<Drain>;
|
|
816
|
+
/**
|
|
817
|
+
* Control plane stream. After Telemetry feature heartbeat moved out — Control
|
|
818
|
+
* несёт только server-driven signalling: Welcome (один раз) и Drain (при
|
|
819
|
+
* shutdown). Cert refresh — отдельным unary RPC.
|
|
820
|
+
*/
|
|
821
|
+
type ControlService = typeof ControlService;
|
|
822
|
+
declare const ControlService: {
|
|
823
|
+
readonly open: {
|
|
824
|
+
readonly path: "/servicebridge.v1.Control/Open";
|
|
825
|
+
readonly requestStream: false;
|
|
826
|
+
readonly responseStream: true;
|
|
827
|
+
readonly requestSerialize: (value: OpenRequest) => Buffer;
|
|
828
|
+
readonly requestDeserialize: (value: Buffer) => OpenRequest;
|
|
829
|
+
readonly responseSerialize: (value: ServerControl) => Buffer;
|
|
830
|
+
readonly responseDeserialize: (value: Buffer) => ServerControl;
|
|
831
|
+
};
|
|
832
|
+
/**
|
|
833
|
+
* RefreshCert reissues the caller's leaf cert via the existing mTLS
|
|
834
|
+
* session (SPIFFE from cert == source of truth, no argon2).
|
|
835
|
+
*/
|
|
836
|
+
readonly refreshCert: {
|
|
837
|
+
readonly path: "/servicebridge.v1.Control/RefreshCert";
|
|
838
|
+
readonly requestStream: false;
|
|
839
|
+
readonly responseStream: false;
|
|
840
|
+
readonly requestSerialize: (value: RefreshCertRequest) => Buffer;
|
|
841
|
+
readonly requestDeserialize: (value: Buffer) => RefreshCertRequest;
|
|
842
|
+
readonly responseSerialize: (value: RefreshCertResponse) => Buffer;
|
|
843
|
+
readonly responseDeserialize: (value: Buffer) => RefreshCertResponse;
|
|
844
|
+
};
|
|
845
|
+
};
|
|
846
|
+
interface ControlClient extends Client {
|
|
847
|
+
open(request: OpenRequest, options?: Partial<CallOptions>): ClientReadableStream<ServerControl>;
|
|
848
|
+
open(request: OpenRequest, metadata?: Metadata, options?: Partial<CallOptions>): ClientReadableStream<ServerControl>;
|
|
849
|
+
/**
|
|
850
|
+
* RefreshCert reissues the caller's leaf cert via the existing mTLS
|
|
851
|
+
* session (SPIFFE from cert == source of truth, no argon2).
|
|
852
|
+
*/
|
|
853
|
+
refreshCert(request: RefreshCertRequest, callback: (error: ServiceError | null, response: RefreshCertResponse) => void): ClientUnaryCall;
|
|
854
|
+
refreshCert(request: RefreshCertRequest, metadata: Metadata, callback: (error: ServiceError | null, response: RefreshCertResponse) => void): ClientUnaryCall;
|
|
855
|
+
refreshCert(request: RefreshCertRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: RefreshCertResponse) => void): ClientUnaryCall;
|
|
856
|
+
}
|
|
857
|
+
declare const ControlClient: {
|
|
858
|
+
new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): ControlClient;
|
|
859
|
+
service: typeof ControlService;
|
|
860
|
+
serviceName: string;
|
|
861
|
+
};
|
|
862
|
+
type Builtin$3 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
863
|
+
type DeepPartial$3<T> = T extends Builtin$3 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$3<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$3<U>> : T extends {} ? {
|
|
864
|
+
[K in keyof T]?: DeepPartial$3<T[K]>;
|
|
865
|
+
} : Partial<T>;
|
|
866
|
+
type KeysOfUnion$3<T> = T extends T ? keyof T : never;
|
|
867
|
+
type Exact$3<P, I extends P> = P extends Builtin$3 ? P : P & {
|
|
868
|
+
[K in keyof P]: Exact$3<P[K], I[K]>;
|
|
869
|
+
} & {
|
|
870
|
+
[K in Exclude<keyof I, KeysOfUnion$3<P>>]: never;
|
|
871
|
+
};
|
|
872
|
+
interface MessageFns$3<T> {
|
|
873
|
+
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
874
|
+
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
875
|
+
create<I extends Exact$3<DeepPartial$3<T>, I>>(base?: I): T;
|
|
876
|
+
fromPartial<I extends Exact$3<DeepPartial$3<T>, I>>(object: I): T;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
type State = "CLOSED" | "OPEN" | "HALF_OPEN";
|
|
880
|
+
declare class CircuitBreakerRegistry {
|
|
881
|
+
private map;
|
|
882
|
+
private now;
|
|
883
|
+
constructor(now?: () => number);
|
|
884
|
+
canCall(key: string): boolean;
|
|
885
|
+
recordSuccess(key: string): void;
|
|
886
|
+
recordFailure(key: string): void;
|
|
887
|
+
state(key: string): State;
|
|
888
|
+
reset(key: string): void;
|
|
889
|
+
private entry;
|
|
890
|
+
private maybeHalfOpen;
|
|
891
|
+
private resetWindow;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
interface DirectCredentials {
|
|
895
|
+
caChainDer: Buffer;
|
|
896
|
+
leafCertDer: Buffer;
|
|
897
|
+
privateKeyDer: Buffer;
|
|
898
|
+
notAfterUnix: bigint;
|
|
899
|
+
}
|
|
900
|
+
interface DirectTarget {
|
|
901
|
+
endpoint: string;
|
|
902
|
+
serviceId: string;
|
|
903
|
+
instanceId: string;
|
|
904
|
+
}
|
|
905
|
+
declare class DirectTransport {
|
|
906
|
+
private creds;
|
|
907
|
+
private cache;
|
|
908
|
+
private credsEpoch;
|
|
909
|
+
constructor(creds: DirectCredentials);
|
|
910
|
+
updateCredentials(creds: DirectCredentials): void;
|
|
911
|
+
close(): void;
|
|
912
|
+
callStream(target: DirectTarget, method: string, payload: Uint8Array, callerService: string, requestId: string, idempotencyKey: string, deadlineMs: number): AsyncIterable<Uint8Array>;
|
|
913
|
+
callUnary(target: DirectTarget, method: string, payload: Uint8Array, callerService: string, requestId: string, idempotencyKey: string, deadlineMs: number): Promise<Uint8Array>;
|
|
914
|
+
private clientFor;
|
|
915
|
+
private evict;
|
|
916
|
+
cacheSize(): number;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Channel classifies the transport/execution context of an operation.
|
|
921
|
+
* Mirrors the SQL CHECK constraint in migration 051.
|
|
922
|
+
* source of truth: migrations/051_operations.up.sql
|
|
923
|
+
*/
|
|
924
|
+
declare enum Channel {
|
|
925
|
+
CHANNEL_UNSPECIFIED = 0,
|
|
926
|
+
HTTP = 1,
|
|
927
|
+
RPC = 2,
|
|
928
|
+
EVENT = 3,
|
|
929
|
+
WORKFLOW = 4,
|
|
930
|
+
JOB = 5,
|
|
931
|
+
USER = 6,
|
|
932
|
+
UNRECOGNIZED = -1
|
|
933
|
+
}
|
|
934
|
+
/** Status represents the lifecycle state of an operation. */
|
|
935
|
+
declare enum Status {
|
|
936
|
+
STATUS_UNSPECIFIED = 0,
|
|
937
|
+
PENDING = 1,
|
|
938
|
+
SUCCESS = 2,
|
|
939
|
+
ERROR = 3,
|
|
940
|
+
TIMEOUT = 4,
|
|
941
|
+
ABANDONED = 5,
|
|
942
|
+
UNRECOGNIZED = -1
|
|
943
|
+
}
|
|
944
|
+
declare enum LogLevel {
|
|
945
|
+
LOG_LEVEL_UNSPECIFIED = 0,
|
|
946
|
+
LOG_LEVEL_DEBUG = 1,
|
|
947
|
+
LOG_LEVEL_INFO = 2,
|
|
948
|
+
LOG_LEVEL_WARN = 3,
|
|
949
|
+
LOG_LEVEL_ERROR = 4,
|
|
950
|
+
UNRECOGNIZED = -1
|
|
951
|
+
}
|
|
952
|
+
declare enum MetricKind {
|
|
953
|
+
METRIC_KIND_UNSPECIFIED = 0,
|
|
954
|
+
METRIC_KIND_COUNTER = 1,
|
|
955
|
+
METRIC_KIND_GAUGE = 2,
|
|
956
|
+
METRIC_KIND_HISTOGRAM = 3,
|
|
957
|
+
UNRECOGNIZED = -1
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* OpReport is a single operation lifecycle event.
|
|
961
|
+
* finished_at_ms absent = START frame; present = END frame (T-014).
|
|
962
|
+
* actor identity is taken from the mTLS cert on the server side (ADR-T-026).
|
|
963
|
+
* @public — см. ./README.md
|
|
964
|
+
*/
|
|
965
|
+
interface OpReport {
|
|
966
|
+
/** UUIDv7 canonical string */
|
|
967
|
+
traceId: string;
|
|
968
|
+
/** UUIDv7 canonical string */
|
|
969
|
+
opId: string;
|
|
970
|
+
/** empty for root */
|
|
971
|
+
parentOpId: string;
|
|
972
|
+
channel: Channel;
|
|
973
|
+
/** per-channel kind value; see enums.go */
|
|
974
|
+
kind: number;
|
|
975
|
+
/** T-019 format: "channel.kind:actor/target" */
|
|
976
|
+
subject: string;
|
|
977
|
+
/** UUID canonical string, optional */
|
|
978
|
+
peerServiceId: string;
|
|
979
|
+
/** idempotency/correlation key per kind */
|
|
980
|
+
businessKey: string;
|
|
981
|
+
attempt: number;
|
|
982
|
+
/** unix-ms */
|
|
983
|
+
startedAtMs: number;
|
|
984
|
+
/** unix-ms; absent = START, present = END */
|
|
985
|
+
finishedAtMs?: number | undefined;
|
|
986
|
+
status: Status;
|
|
987
|
+
statusMessage: string;
|
|
988
|
+
/** per-kind structured meta; cap 8KB */
|
|
989
|
+
metaJson: Buffer;
|
|
990
|
+
/** free-form key-value; cap 2KB */
|
|
991
|
+
attrsJson: Buffer;
|
|
992
|
+
}
|
|
993
|
+
declare const OpReport: MessageFns$2<OpReport>;
|
|
994
|
+
/**
|
|
995
|
+
* Log is a structured log entry.
|
|
996
|
+
* trace_id and op_id are optional UUID canonical strings.
|
|
997
|
+
* @public — см. ./README.md
|
|
998
|
+
*/
|
|
999
|
+
interface Log {
|
|
1000
|
+
atUnixMs: number;
|
|
1001
|
+
level: LogLevel;
|
|
1002
|
+
message: string;
|
|
1003
|
+
/** JSON-encoded Record<string, unknown> */
|
|
1004
|
+
fieldsJson: Buffer;
|
|
1005
|
+
/** UUID canonical, optional */
|
|
1006
|
+
traceId: string;
|
|
1007
|
+
/** UUID canonical, optional (renamed from span_id) */
|
|
1008
|
+
opId: string;
|
|
1009
|
+
instanceId: string;
|
|
1010
|
+
/** 'sdk' | 'console' | 'runtime' */
|
|
1011
|
+
source: string;
|
|
1012
|
+
}
|
|
1013
|
+
declare const Log: MessageFns$2<Log>;
|
|
1014
|
+
/**
|
|
1015
|
+
* MetricPoint is a single metric observation.
|
|
1016
|
+
* @public — см. ./README.md
|
|
1017
|
+
*/
|
|
1018
|
+
interface MetricPoint {
|
|
1019
|
+
atUnixMs: number;
|
|
1020
|
+
name: string;
|
|
1021
|
+
kind: MetricKind;
|
|
1022
|
+
labels: {
|
|
1023
|
+
[key: string]: string;
|
|
1024
|
+
};
|
|
1025
|
+
instanceId: string;
|
|
1026
|
+
value: number;
|
|
1027
|
+
/** UCUM: 's', 'By', '1' */
|
|
1028
|
+
unit: string;
|
|
1029
|
+
/** [{le, count}] JSON for histograms */
|
|
1030
|
+
bucketsJson: Buffer;
|
|
1031
|
+
}
|
|
1032
|
+
declare const MetricPoint: MessageFns$2<MetricPoint>;
|
|
1033
|
+
/**
|
|
1034
|
+
* PayloadAttachment carries a captured request/response payload.
|
|
1035
|
+
* @public — см. ./README.md
|
|
1036
|
+
*/
|
|
1037
|
+
interface PayloadAttachment {
|
|
1038
|
+
/** UUID canonical */
|
|
1039
|
+
traceId: string;
|
|
1040
|
+
/** UUID canonical */
|
|
1041
|
+
opId: string;
|
|
1042
|
+
/** 1=IN, 2=OUT */
|
|
1043
|
+
direction: number;
|
|
1044
|
+
bytes: Buffer;
|
|
1045
|
+
originalSize: number;
|
|
1046
|
+
contractHash: string;
|
|
1047
|
+
}
|
|
1048
|
+
declare const PayloadAttachment: MessageFns$2<PayloadAttachment>;
|
|
1049
|
+
type Builtin$2 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
1050
|
+
type DeepPartial$2<T> = T extends Builtin$2 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$2<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$2<U>> : T extends {} ? {
|
|
1051
|
+
[K in keyof T]?: DeepPartial$2<T[K]>;
|
|
1052
|
+
} : Partial<T>;
|
|
1053
|
+
type KeysOfUnion$2<T> = T extends T ? keyof T : never;
|
|
1054
|
+
type Exact$2<P, I extends P> = P extends Builtin$2 ? P : P & {
|
|
1055
|
+
[K in keyof P]: Exact$2<P[K], I[K]>;
|
|
1056
|
+
} & {
|
|
1057
|
+
[K in Exclude<keyof I, KeysOfUnion$2<P>>]: never;
|
|
1058
|
+
};
|
|
1059
|
+
interface MessageFns$2<T> {
|
|
1060
|
+
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
1061
|
+
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
1062
|
+
create<I extends Exact$2<DeepPartial$2<T>, I>>(base?: I): T;
|
|
1063
|
+
fromPartial<I extends Exact$2<DeepPartial$2<T>, I>>(object: I): T;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
type ChannelCaptureModes = Record<Channel, CaptureMode>;
|
|
1067
|
+
declare class WatchStream {
|
|
1068
|
+
private stream;
|
|
1069
|
+
private cache;
|
|
1070
|
+
private instances;
|
|
1071
|
+
private eventSubs;
|
|
1072
|
+
private outgoing;
|
|
1073
|
+
private policy;
|
|
1074
|
+
private _captureModes;
|
|
1075
|
+
private captureModeListeners;
|
|
1076
|
+
private onError;
|
|
1077
|
+
private instanceListeners;
|
|
1078
|
+
private policyListeners;
|
|
1079
|
+
private peersChangeListeners;
|
|
1080
|
+
start(req: RegisterRequest, client: RegistryClient, onError?: (err: Error) => void): void;
|
|
1081
|
+
stop(): void;
|
|
1082
|
+
restart(req: RegisterRequest, client: RegistryClient, onError?: (err: Error) => void): void;
|
|
1083
|
+
snapshot(): ReadonlyMap<string, MethodDescriptor>;
|
|
1084
|
+
instancesSnapshot(): Map<string, ServiceInstanceInfo>;
|
|
1085
|
+
eventSubscriptionsSnapshot(): Map<string, EventSubscriptionDescriptor>;
|
|
1086
|
+
outgoingCallsSnapshot(): Map<string, OutgoingCallDescriptor>;
|
|
1087
|
+
policyEvaluation(): PolicyEvaluation | null;
|
|
1088
|
+
captureModeForChannel(channel: Channel): CaptureMode;
|
|
1089
|
+
onCaptureModes(fn: (modes: ChannelCaptureModes) => void): () => void;
|
|
1090
|
+
private applyCaptureModes;
|
|
1091
|
+
onInstancesChange(fn: (added: ServiceInstanceInfo[], removed: ServiceInstanceInfo[]) => void): () => void;
|
|
1092
|
+
onPolicyEvaluation(fn: (policy: PolicyEvaluation) => void): () => void;
|
|
1093
|
+
onPeersChange(fn: (added: string[], removed: string[]) => void): () => void;
|
|
1094
|
+
private emitInstances;
|
|
1095
|
+
private emitPolicy;
|
|
1096
|
+
private handleEvent;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
interface Candidate {
|
|
1100
|
+
descriptor: MethodDescriptor;
|
|
1101
|
+
instance: ServiceInstanceInfo;
|
|
1102
|
+
isUnhealthyAt: Date | null;
|
|
1103
|
+
}
|
|
1104
|
+
declare class LoadBalancer {
|
|
1105
|
+
private readonly cb;
|
|
1106
|
+
private inflight;
|
|
1107
|
+
private now;
|
|
1108
|
+
private random;
|
|
1109
|
+
constructor(cb: CircuitBreakerRegistry, opts?: {
|
|
1110
|
+
now?: () => number;
|
|
1111
|
+
random?: () => number;
|
|
1112
|
+
});
|
|
1113
|
+
pick(candidates: Candidate[]): Candidate;
|
|
1114
|
+
acquire(instanceId: string): () => void;
|
|
1115
|
+
inflightOf(instanceId: string): number;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
declare class InstanceCache {
|
|
1119
|
+
private byService;
|
|
1120
|
+
private instances;
|
|
1121
|
+
private unsubscribe;
|
|
1122
|
+
private watch;
|
|
1123
|
+
bind(watch: WatchStream): void;
|
|
1124
|
+
dispose(): void;
|
|
1125
|
+
pickAll(serviceName: string, methodName: string): Candidate[];
|
|
1126
|
+
descriptorFor(serviceName: string, methodName: string): MethodDescriptor | null;
|
|
1127
|
+
private refresh;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
declare class ProxyTransport {
|
|
1131
|
+
private client;
|
|
1132
|
+
constructor(runtimeAddr: string, creds: ChannelCredentials);
|
|
1133
|
+
close(): void;
|
|
1134
|
+
callStream(targetServiceId: string, method: string, payload: Uint8Array, requestId: string, idempotencyKey: string, deadlineMs: number, contractHash: string): AsyncIterable<Uint8Array>;
|
|
1135
|
+
callUnary(targetServiceId: string, method: string, payload: Uint8Array, requestId: string, idempotencyKey: string, deadlineMs: number, contractHash: string): Promise<Uint8Array>;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
interface CallOpts {
|
|
1139
|
+
timeout?: string;
|
|
1140
|
+
requestId?: string;
|
|
1141
|
+
transport?: "direct" | "proxy" | "auto";
|
|
1142
|
+
idempotencyKey?: string;
|
|
1143
|
+
retry?: Partial<RetryOpts>;
|
|
1144
|
+
}
|
|
1145
|
+
interface RetryOpts {
|
|
1146
|
+
maxAttempts: number;
|
|
1147
|
+
baseDelayMs: number;
|
|
1148
|
+
factor: number;
|
|
1149
|
+
maxDelayMs: number;
|
|
1150
|
+
jitter: number;
|
|
1151
|
+
}
|
|
1152
|
+
interface CallerSchema {
|
|
1153
|
+
pair: SchemaPair;
|
|
1154
|
+
contractHash: string;
|
|
1155
|
+
}
|
|
1156
|
+
type SchemaResolver = (serviceName: string, methodName: string) => CallerSchema | undefined;
|
|
1157
|
+
declare class RpcClient {
|
|
1158
|
+
private readonly proxy;
|
|
1159
|
+
private readonly directTransport;
|
|
1160
|
+
private readonly instances;
|
|
1161
|
+
private readonly resolveSchema;
|
|
1162
|
+
private readonly callerService;
|
|
1163
|
+
private readonly cb;
|
|
1164
|
+
private readonly lb;
|
|
1165
|
+
private readonly sb;
|
|
1166
|
+
constructor(proxy: ProxyTransport, directTransport: DirectTransport | null, instances: InstanceCache, resolveSchema: SchemaResolver, callerService: string, cb: CircuitBreakerRegistry, lb: LoadBalancer, sb: ServiceBridge);
|
|
1167
|
+
stream<Req = unknown, Chunk = unknown>(serviceName: string, methodName: string, payload: Req, opts?: CallOpts): AsyncIterable<Chunk>;
|
|
1168
|
+
call<Req = unknown, Res = unknown>(serviceName: string, methodName: string, payload: Req, opts?: CallOpts): Promise<Res>;
|
|
1169
|
+
private pickCandidate;
|
|
1170
|
+
private shouldUseDirect;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
type PolicyViolationSink$1 = (v: {
|
|
1174
|
+
declaration: string;
|
|
1175
|
+
value: string;
|
|
1176
|
+
denySide: string;
|
|
1177
|
+
reason: string;
|
|
1178
|
+
}) => void;
|
|
1179
|
+
declare class RpcDomain {
|
|
1180
|
+
private readonly registry;
|
|
1181
|
+
private readonly getClient;
|
|
1182
|
+
private readonly onPolicyViolation?;
|
|
1183
|
+
constructor(registry: Registry, getClient: () => RpcClient | null, onPolicyViolation?: PolicyViolationSink$1 | undefined);
|
|
1184
|
+
handle<Req = unknown, Res = unknown>(name: string, fn: RpcHandlerFn<Req, Res>, opts: RpcHandlerOpts): void;
|
|
1185
|
+
handleStream<Req = unknown, Chunk = unknown>(name: string, fn: RpcStreamHandlerFn<Req, Chunk>, opts: RpcHandlerOpts): void;
|
|
1186
|
+
_declareForTests(name: string, streaming?: boolean): void;
|
|
1187
|
+
call<Req = unknown, Res = unknown>(serviceName: string, methodName: string, payload: Req, opts?: CallOpts): Promise<Res>;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
interface AdvertiseConfig {
|
|
1191
|
+
host: string;
|
|
1192
|
+
port: number;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
type TypedClient = Record<string, ((req: unknown, opts?: CallOpts) => Promise<unknown>) & ((req: unknown, opts?: CallOpts) => AsyncIterable<unknown>)>;
|
|
1196
|
+
|
|
1197
|
+
type RingKind = "ops" | "logs" | "metrics" | "payloads";
|
|
1198
|
+
type RingMessage = {
|
|
1199
|
+
ops: OpReport;
|
|
1200
|
+
logs: Log;
|
|
1201
|
+
metrics: MetricPoint;
|
|
1202
|
+
payloads: PayloadAttachment;
|
|
1203
|
+
};
|
|
1204
|
+
interface RingItem<K extends RingKind = RingKind> {
|
|
1205
|
+
id: number;
|
|
1206
|
+
kind: K;
|
|
1207
|
+
message: RingMessage[K];
|
|
1208
|
+
bytes: number;
|
|
1209
|
+
}
|
|
1210
|
+
type RingBudgets = Partial<Record<RingKind, number>>;
|
|
1211
|
+
declare class TelemetryRing {
|
|
1212
|
+
private readonly rings;
|
|
1213
|
+
constructor(budgets?: RingBudgets);
|
|
1214
|
+
push<K extends RingKind>(kind: K, message: RingMessage[K]): void;
|
|
1215
|
+
peek(maxPerKind?: number): RingItem[];
|
|
1216
|
+
commit(items: RingItem[]): void;
|
|
1217
|
+
dropCount(kind: RingKind): number;
|
|
1218
|
+
totalDropCount(): number;
|
|
1219
|
+
size(kind: RingKind): number;
|
|
1220
|
+
bytes(kind: RingKind): number;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
type LogFields = Record<string, unknown>;
|
|
1224
|
+
declare function makeLogger(ring: TelemetryRing, instanceId: string): {
|
|
1225
|
+
debug(message: string, fields?: LogFields): void;
|
|
1226
|
+
info(message: string, fields?: LogFields): void;
|
|
1227
|
+
warn(message: string, fields?: LogFields): void;
|
|
1228
|
+
error(message: string, fields?: LogFields): void;
|
|
1229
|
+
};
|
|
1230
|
+
|
|
1231
|
+
type Labels = Record<string, string>;
|
|
1232
|
+
declare function makeCounter(ring: TelemetryRing, instanceId: string, name: string, labels?: Labels): {
|
|
1233
|
+
inc(amount?: number): void;
|
|
1234
|
+
};
|
|
1235
|
+
declare function makeGauge(ring: TelemetryRing, instanceId: string, name: string, labels?: Labels): {
|
|
1236
|
+
set(value: number): void;
|
|
1237
|
+
};
|
|
1238
|
+
declare function makeHistogram(ring: TelemetryRing, instanceId: string, name: string, unit?: string, labels?: Labels): {
|
|
1239
|
+
observe(value: number): void;
|
|
1240
|
+
};
|
|
1241
|
+
|
|
1242
|
+
interface StartOpParams {
|
|
1243
|
+
/** Required when called directly without ALS context. Otherwise inherited. */
|
|
1244
|
+
traceId?: string;
|
|
1245
|
+
/** Auto-minted UUIDv7 when omitted. */
|
|
1246
|
+
opId?: string;
|
|
1247
|
+
/** Auto-resolved from currentTraceContext().parentOpId when omitted. */
|
|
1248
|
+
parentOpId?: string;
|
|
1249
|
+
channel: Channel;
|
|
1250
|
+
kind: number;
|
|
1251
|
+
subject: string;
|
|
1252
|
+
peerServiceId?: string;
|
|
1253
|
+
businessKey?: string;
|
|
1254
|
+
attempt?: number;
|
|
1255
|
+
startedAtMs?: number;
|
|
1256
|
+
metaJson?: Buffer;
|
|
1257
|
+
attrsJson?: Buffer;
|
|
1258
|
+
/**
|
|
1259
|
+
* Per-handler capture override. May only narrow the runtime-pushed effective
|
|
1260
|
+
* mode (privacy ordering none < errors < all), never widen it.
|
|
1261
|
+
*/
|
|
1262
|
+
captureMode?: CaptureMode;
|
|
1263
|
+
/**
|
|
1264
|
+
* Runtime-pushed effective capture mode (from the registry stream). The
|
|
1265
|
+
* single authority for what may be captured. Defaults to "none" until the
|
|
1266
|
+
* first registry snapshot arrives (fail-safe).
|
|
1267
|
+
*/
|
|
1268
|
+
effectiveCaptureMode?: CaptureMode;
|
|
1269
|
+
/**
|
|
1270
|
+
* Per-direction payload byte cap for captured payloads. Defaults to
|
|
1271
|
+
* DEFAULT_PAYLOAD_MAX_BYTES; threaded from ServiceBridgeOptions.payloadMaxBytes.
|
|
1272
|
+
*/
|
|
1273
|
+
payloadMaxBytes?: number;
|
|
1274
|
+
}
|
|
1275
|
+
declare class OpHandle {
|
|
1276
|
+
private readonly ring;
|
|
1277
|
+
private readonly params;
|
|
1278
|
+
private readonly startedAtMs;
|
|
1279
|
+
private ended;
|
|
1280
|
+
private readonly bufferedPayloads;
|
|
1281
|
+
private constructor();
|
|
1282
|
+
/**
|
|
1283
|
+
* Start an operation, enqueue the START frame, return a handle for END.
|
|
1284
|
+
* traceId / parentOpId default to the active TraceContext from ALS
|
|
1285
|
+
* (set via runWithTrace). opId is auto-minted as a fresh UUIDv7.
|
|
1286
|
+
*/
|
|
1287
|
+
static start(ring: TelemetryRing, params: StartOpParams): OpHandle;
|
|
1288
|
+
/** Op identifier for this in-flight op (UUIDv7). */
|
|
1289
|
+
get opId(): string;
|
|
1290
|
+
/**
|
|
1291
|
+
* Record the retry attempt count on this in-flight op. The END frame carries
|
|
1292
|
+
* the final value so a single RPC.CALL row reflects how many tries it took
|
|
1293
|
+
* (ADR-0037..0042). No new row is minted per attempt.
|
|
1294
|
+
*/
|
|
1295
|
+
setAttempt(attempt: number): void;
|
|
1296
|
+
/** Trace identifier this op belongs to. */
|
|
1297
|
+
get traceId(): string;
|
|
1298
|
+
/**
|
|
1299
|
+
* Capture the inbound (request/input) payload for this op. Direction = IN.
|
|
1300
|
+
* "all" emits immediately; "errors" buffers until end; "none" is a no-op.
|
|
1301
|
+
*/
|
|
1302
|
+
captureIn(bytes: Uint8Array, contractHash: string): void;
|
|
1303
|
+
/**
|
|
1304
|
+
* Capture the outbound (response/output) payload for this op. Direction = OUT.
|
|
1305
|
+
*/
|
|
1306
|
+
captureOut(bytes: Uint8Array, contractHash: string): void;
|
|
1307
|
+
private capture;
|
|
1308
|
+
private emitPayload;
|
|
1309
|
+
/**
|
|
1310
|
+
* End the operation, enqueue the END frame.
|
|
1311
|
+
* Idempotent — calling end() twice is a no-op.
|
|
1312
|
+
*/
|
|
1313
|
+
end(status: Status, statusMessage?: string): void;
|
|
1314
|
+
private flushBufferedPayloads;
|
|
1315
|
+
private enqueueStartFrame;
|
|
1316
|
+
private enqueueEndFrame;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/**
|
|
1320
|
+
* A generic empty message that you can re-use to avoid defining duplicated
|
|
1321
|
+
* empty messages in your APIs. A typical example is to use it as the request
|
|
1322
|
+
* or the response type of an API method. For instance:
|
|
1323
|
+
*
|
|
1324
|
+
* service Foo {
|
|
1325
|
+
* rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
|
|
1326
|
+
* }
|
|
1327
|
+
*/
|
|
1328
|
+
interface Empty {
|
|
1329
|
+
}
|
|
1330
|
+
declare const Empty: MessageFns$1<Empty>;
|
|
1331
|
+
type Builtin$1 = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
1332
|
+
type DeepPartial$1<T> = T extends Builtin$1 ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial$1<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial$1<U>> : T extends {} ? {
|
|
1333
|
+
[K in keyof T]?: DeepPartial$1<T[K]>;
|
|
1334
|
+
} : Partial<T>;
|
|
1335
|
+
type KeysOfUnion$1<T> = T extends T ? keyof T : never;
|
|
1336
|
+
type Exact$1<P, I extends P> = P extends Builtin$1 ? P : P & {
|
|
1337
|
+
[K in keyof P]: Exact$1<P[K], I[K]>;
|
|
1338
|
+
} & {
|
|
1339
|
+
[K in Exclude<keyof I, KeysOfUnion$1<P>>]: never;
|
|
1340
|
+
};
|
|
1341
|
+
interface MessageFns$1<T> {
|
|
1342
|
+
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
1343
|
+
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
1344
|
+
create<I extends Exact$1<DeepPartial$1<T>, I>>(base?: I): T;
|
|
1345
|
+
fromPartial<I extends Exact$1<DeepPartial$1<T>, I>>(object: I): T;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
interface StartRunRequest {
|
|
1349
|
+
workflowName: string;
|
|
1350
|
+
/** JSON-encoded workflow input */
|
|
1351
|
+
input: Buffer;
|
|
1352
|
+
idempotencyKey: string;
|
|
1353
|
+
/** 0 = no global timeout override */
|
|
1354
|
+
timeoutSec: number;
|
|
1355
|
+
/** X-SB-Trace propagation from caller. */
|
|
1356
|
+
xSbTrace: string;
|
|
1357
|
+
/**
|
|
1358
|
+
* parent_run_id — when non-empty, the request originates from a workflow
|
|
1359
|
+
* step on an in-flight parent run. Runtime enforces dynamic cycle
|
|
1360
|
+
* detection (ADR-W-019) by walking the ancestor chain via this id.
|
|
1361
|
+
* Empty for top-level starts initiated by external callers.
|
|
1362
|
+
*/
|
|
1363
|
+
parentRunId: string;
|
|
1364
|
+
}
|
|
1365
|
+
declare const StartRunRequest: MessageFns<StartRunRequest>;
|
|
1366
|
+
interface StartRunResponse {
|
|
1367
|
+
runId: string;
|
|
1368
|
+
}
|
|
1369
|
+
declare const StartRunResponse: MessageFns<StartRunResponse>;
|
|
1370
|
+
interface CancelRunRequest {
|
|
1371
|
+
runId: string;
|
|
1372
|
+
}
|
|
1373
|
+
declare const CancelRunRequest: MessageFns<CancelRunRequest>;
|
|
1374
|
+
interface SignalRunRequest {
|
|
1375
|
+
runId: string;
|
|
1376
|
+
signalName: string;
|
|
1377
|
+
payload: Buffer;
|
|
1378
|
+
}
|
|
1379
|
+
declare const SignalRunRequest: MessageFns<SignalRunRequest>;
|
|
1380
|
+
interface QueryRunRequest {
|
|
1381
|
+
runId: string;
|
|
1382
|
+
}
|
|
1383
|
+
declare const QueryRunRequest: MessageFns<QueryRunRequest>;
|
|
1384
|
+
interface QueryRunResponse {
|
|
1385
|
+
runId: string;
|
|
1386
|
+
status: string;
|
|
1387
|
+
/** JSON-encoded run state map */
|
|
1388
|
+
state: Buffer;
|
|
1389
|
+
steps: StepInfo[];
|
|
1390
|
+
}
|
|
1391
|
+
declare const QueryRunResponse: MessageFns<QueryRunResponse>;
|
|
1392
|
+
interface StepInfo {
|
|
1393
|
+
stepId: string;
|
|
1394
|
+
status: string;
|
|
1395
|
+
output: Buffer;
|
|
1396
|
+
lastError: string;
|
|
1397
|
+
/** step_id of the compensation step, if compensated */
|
|
1398
|
+
compensatedBy: string;
|
|
1399
|
+
}
|
|
1400
|
+
declare const StepInfo: MessageFns<StepInfo>;
|
|
1401
|
+
interface AwaitRunRequest {
|
|
1402
|
+
runId: string;
|
|
1403
|
+
}
|
|
1404
|
+
declare const AwaitRunRequest: MessageFns<AwaitRunRequest>;
|
|
1405
|
+
interface RunStatusUpdate {
|
|
1406
|
+
runId: string;
|
|
1407
|
+
status: string;
|
|
1408
|
+
/** JSON-encoded final state; non-empty only on terminal status */
|
|
1409
|
+
state: Buffer;
|
|
1410
|
+
}
|
|
1411
|
+
declare const RunStatusUpdate: MessageFns<RunStatusUpdate>;
|
|
1412
|
+
interface ReplayRunRequest {
|
|
1413
|
+
runId: string;
|
|
1414
|
+
fromStepId: string;
|
|
1415
|
+
}
|
|
1416
|
+
declare const ReplayRunRequest: MessageFns<ReplayRunRequest>;
|
|
1417
|
+
interface ReplayRunResponse {
|
|
1418
|
+
/** new run id */
|
|
1419
|
+
runId: string;
|
|
1420
|
+
}
|
|
1421
|
+
declare const ReplayRunResponse: MessageFns<ReplayRunResponse>;
|
|
1422
|
+
interface SubscribeRequest {
|
|
1423
|
+
/** UUID */
|
|
1424
|
+
serviceId: string;
|
|
1425
|
+
/** UUID */
|
|
1426
|
+
instanceId: string;
|
|
1427
|
+
}
|
|
1428
|
+
declare const SubscribeRequest: MessageFns<SubscribeRequest>;
|
|
1429
|
+
interface RunAssignment {
|
|
1430
|
+
runId: string;
|
|
1431
|
+
workflowName: string;
|
|
1432
|
+
fingerprint: string;
|
|
1433
|
+
/** canonical JSON graph */
|
|
1434
|
+
frozenPlan: Buffer;
|
|
1435
|
+
/** JSON-encoded workflow input */
|
|
1436
|
+
input: Buffer;
|
|
1437
|
+
/** JSON-encoded current state (checkpointed outputs) */
|
|
1438
|
+
state: Buffer;
|
|
1439
|
+
leaseEpoch: number;
|
|
1440
|
+
maxParallelism: number;
|
|
1441
|
+
/** X-SB-Trace propagation — workflow root op. */
|
|
1442
|
+
xSbTrace: string;
|
|
1443
|
+
/** Compensation: if set, SDK must execute compensation steps. */
|
|
1444
|
+
compensating: boolean;
|
|
1445
|
+
/** cancel_reason mirrors workflow_runs.cancel_reason. Values: '' | 'user_cancel' | 'step_failure'. */
|
|
1446
|
+
cancelReason: string;
|
|
1447
|
+
}
|
|
1448
|
+
declare const RunAssignment: MessageFns<RunAssignment>;
|
|
1449
|
+
interface BeginStepRequest {
|
|
1450
|
+
runId: string;
|
|
1451
|
+
stepId: string;
|
|
1452
|
+
/** empty for top-level steps */
|
|
1453
|
+
parentStepId: string;
|
|
1454
|
+
/** call|publish|sleep|wait_event|wait_signal|workflow|parallel|sequence|local */
|
|
1455
|
+
kind: string;
|
|
1456
|
+
/** JSON-encoded resolved inputs */
|
|
1457
|
+
inputSnapshot: Buffer;
|
|
1458
|
+
leaseEpoch: number;
|
|
1459
|
+
/** UUID of the claiming SDK instance */
|
|
1460
|
+
instanceId: string;
|
|
1461
|
+
}
|
|
1462
|
+
declare const BeginStepRequest: MessageFns<BeginStepRequest>;
|
|
1463
|
+
interface BeginStepResponse {
|
|
1464
|
+
/**
|
|
1465
|
+
* If the step was already completed (idempotent replay), cached_output is
|
|
1466
|
+
* non-nil and the SDK must use it without re-executing.
|
|
1467
|
+
*/
|
|
1468
|
+
cachedOutput: Buffer;
|
|
1469
|
+
alreadyDone: boolean;
|
|
1470
|
+
leaseEpoch: number;
|
|
1471
|
+
}
|
|
1472
|
+
declare const BeginStepResponse: MessageFns<BeginStepResponse>;
|
|
1473
|
+
interface CompleteStepRequest {
|
|
1474
|
+
runId: string;
|
|
1475
|
+
stepId: string;
|
|
1476
|
+
/** JSON-encoded step output */
|
|
1477
|
+
output: Buffer;
|
|
1478
|
+
leaseEpoch: number;
|
|
1479
|
+
}
|
|
1480
|
+
declare const CompleteStepRequest: MessageFns<CompleteStepRequest>;
|
|
1481
|
+
interface FailStepRequest {
|
|
1482
|
+
runId: string;
|
|
1483
|
+
stepId: string;
|
|
1484
|
+
errorCode: string;
|
|
1485
|
+
errorMessage: string;
|
|
1486
|
+
leaseEpoch: number;
|
|
1487
|
+
retriable: boolean;
|
|
1488
|
+
}
|
|
1489
|
+
declare const FailStepRequest: MessageFns<FailStepRequest>;
|
|
1490
|
+
interface FailStepResponse {
|
|
1491
|
+
/** Runtime's decision after the failure. */
|
|
1492
|
+
nextAction: string;
|
|
1493
|
+
retryDelaySec: number;
|
|
1494
|
+
}
|
|
1495
|
+
declare const FailStepResponse: MessageFns<FailStepResponse>;
|
|
1496
|
+
interface ParkRequest {
|
|
1497
|
+
runId: string;
|
|
1498
|
+
stepId: string;
|
|
1499
|
+
leaseEpoch: number;
|
|
1500
|
+
sleep?: SleepSpec | undefined;
|
|
1501
|
+
eventWait?: EventWaitSpec | undefined;
|
|
1502
|
+
signalWait?: SignalWaitSpec | undefined;
|
|
1503
|
+
nestedRun?: NestedRunSpec | undefined;
|
|
1504
|
+
}
|
|
1505
|
+
declare const ParkRequest: MessageFns<ParkRequest>;
|
|
1506
|
+
interface SleepSpec {
|
|
1507
|
+
durationSec: number;
|
|
1508
|
+
}
|
|
1509
|
+
declare const SleepSpec: MessageFns<SleepSpec>;
|
|
1510
|
+
interface EventWaitSpec {
|
|
1511
|
+
event: string;
|
|
1512
|
+
/** JSON-encoded {"$.path": "expected"} filter; empty = match all */
|
|
1513
|
+
filterJson: string;
|
|
1514
|
+
/** 0 = no timeout */
|
|
1515
|
+
timeoutSec: number;
|
|
1516
|
+
}
|
|
1517
|
+
declare const EventWaitSpec: MessageFns<EventWaitSpec>;
|
|
1518
|
+
interface SignalWaitSpec {
|
|
1519
|
+
signal: string;
|
|
1520
|
+
/** 0 = no timeout */
|
|
1521
|
+
timeoutSec: number;
|
|
1522
|
+
}
|
|
1523
|
+
declare const SignalWaitSpec: MessageFns<SignalWaitSpec>;
|
|
1524
|
+
interface NestedRunSpec {
|
|
1525
|
+
childRunId: string;
|
|
1526
|
+
}
|
|
1527
|
+
declare const NestedRunSpec: MessageFns<NestedRunSpec>;
|
|
1528
|
+
interface CompleteRunRequest {
|
|
1529
|
+
runId: string;
|
|
1530
|
+
/** JSON-encoded final state map (output of last step) */
|
|
1531
|
+
finalState: Buffer;
|
|
1532
|
+
leaseEpoch: number;
|
|
1533
|
+
/**
|
|
1534
|
+
* terminal_status: 'success' | 'failed_compensated' | 'cancelled'.
|
|
1535
|
+
* If empty, defaults to 'success'.
|
|
1536
|
+
*/
|
|
1537
|
+
terminalStatus: string;
|
|
1538
|
+
}
|
|
1539
|
+
declare const CompleteRunRequest: MessageFns<CompleteRunRequest>;
|
|
1540
|
+
interface HeartbeatRequest {
|
|
1541
|
+
runId: string;
|
|
1542
|
+
/** UUID */
|
|
1543
|
+
instanceId: string;
|
|
1544
|
+
leaseEpoch: number;
|
|
1545
|
+
}
|
|
1546
|
+
declare const HeartbeatRequest: MessageFns<HeartbeatRequest>;
|
|
1547
|
+
/**
|
|
1548
|
+
* Workflows — durable workflow execution service.
|
|
1549
|
+
* Caller-side RPCs: Start, Cancel, Signal, Query, Await, Replay.
|
|
1550
|
+
* Owner-side RPCs: Subscribe, BeginStep, CompleteStep, FailStep, Park, Heartbeat.
|
|
1551
|
+
*/
|
|
1552
|
+
type WorkflowsService = typeof WorkflowsService;
|
|
1553
|
+
declare const WorkflowsService: {
|
|
1554
|
+
/** Caller-side */
|
|
1555
|
+
readonly start: {
|
|
1556
|
+
readonly path: "/servicebridge.v1.Workflows/Start";
|
|
1557
|
+
readonly requestStream: false;
|
|
1558
|
+
readonly responseStream: false;
|
|
1559
|
+
readonly requestSerialize: (value: StartRunRequest) => Buffer;
|
|
1560
|
+
readonly requestDeserialize: (value: Buffer) => StartRunRequest;
|
|
1561
|
+
readonly responseSerialize: (value: StartRunResponse) => Buffer;
|
|
1562
|
+
readonly responseDeserialize: (value: Buffer) => StartRunResponse;
|
|
1563
|
+
};
|
|
1564
|
+
readonly cancel: {
|
|
1565
|
+
readonly path: "/servicebridge.v1.Workflows/Cancel";
|
|
1566
|
+
readonly requestStream: false;
|
|
1567
|
+
readonly responseStream: false;
|
|
1568
|
+
readonly requestSerialize: (value: CancelRunRequest) => Buffer;
|
|
1569
|
+
readonly requestDeserialize: (value: Buffer) => CancelRunRequest;
|
|
1570
|
+
readonly responseSerialize: (value: Empty) => Buffer;
|
|
1571
|
+
readonly responseDeserialize: (value: Buffer) => Empty;
|
|
1572
|
+
};
|
|
1573
|
+
readonly signal: {
|
|
1574
|
+
readonly path: "/servicebridge.v1.Workflows/Signal";
|
|
1575
|
+
readonly requestStream: false;
|
|
1576
|
+
readonly responseStream: false;
|
|
1577
|
+
readonly requestSerialize: (value: SignalRunRequest) => Buffer;
|
|
1578
|
+
readonly requestDeserialize: (value: Buffer) => SignalRunRequest;
|
|
1579
|
+
readonly responseSerialize: (value: Empty) => Buffer;
|
|
1580
|
+
readonly responseDeserialize: (value: Buffer) => Empty;
|
|
1581
|
+
};
|
|
1582
|
+
readonly query: {
|
|
1583
|
+
readonly path: "/servicebridge.v1.Workflows/Query";
|
|
1584
|
+
readonly requestStream: false;
|
|
1585
|
+
readonly responseStream: false;
|
|
1586
|
+
readonly requestSerialize: (value: QueryRunRequest) => Buffer;
|
|
1587
|
+
readonly requestDeserialize: (value: Buffer) => QueryRunRequest;
|
|
1588
|
+
readonly responseSerialize: (value: QueryRunResponse) => Buffer;
|
|
1589
|
+
readonly responseDeserialize: (value: Buffer) => QueryRunResponse;
|
|
1590
|
+
};
|
|
1591
|
+
readonly await: {
|
|
1592
|
+
readonly path: "/servicebridge.v1.Workflows/Await";
|
|
1593
|
+
readonly requestStream: false;
|
|
1594
|
+
readonly responseStream: true;
|
|
1595
|
+
readonly requestSerialize: (value: AwaitRunRequest) => Buffer;
|
|
1596
|
+
readonly requestDeserialize: (value: Buffer) => AwaitRunRequest;
|
|
1597
|
+
readonly responseSerialize: (value: RunStatusUpdate) => Buffer;
|
|
1598
|
+
readonly responseDeserialize: (value: Buffer) => RunStatusUpdate;
|
|
1599
|
+
};
|
|
1600
|
+
readonly replay: {
|
|
1601
|
+
readonly path: "/servicebridge.v1.Workflows/Replay";
|
|
1602
|
+
readonly requestStream: false;
|
|
1603
|
+
readonly responseStream: false;
|
|
1604
|
+
readonly requestSerialize: (value: ReplayRunRequest) => Buffer;
|
|
1605
|
+
readonly requestDeserialize: (value: Buffer) => ReplayRunRequest;
|
|
1606
|
+
readonly responseSerialize: (value: ReplayRunResponse) => Buffer;
|
|
1607
|
+
readonly responseDeserialize: (value: Buffer) => ReplayRunResponse;
|
|
1608
|
+
};
|
|
1609
|
+
/** Owner-side */
|
|
1610
|
+
readonly subscribe: {
|
|
1611
|
+
readonly path: "/servicebridge.v1.Workflows/Subscribe";
|
|
1612
|
+
readonly requestStream: false;
|
|
1613
|
+
readonly responseStream: true;
|
|
1614
|
+
readonly requestSerialize: (value: SubscribeRequest) => Buffer;
|
|
1615
|
+
readonly requestDeserialize: (value: Buffer) => SubscribeRequest;
|
|
1616
|
+
readonly responseSerialize: (value: RunAssignment) => Buffer;
|
|
1617
|
+
readonly responseDeserialize: (value: Buffer) => RunAssignment;
|
|
1618
|
+
};
|
|
1619
|
+
readonly beginStep: {
|
|
1620
|
+
readonly path: "/servicebridge.v1.Workflows/BeginStep";
|
|
1621
|
+
readonly requestStream: false;
|
|
1622
|
+
readonly responseStream: false;
|
|
1623
|
+
readonly requestSerialize: (value: BeginStepRequest) => Buffer;
|
|
1624
|
+
readonly requestDeserialize: (value: Buffer) => BeginStepRequest;
|
|
1625
|
+
readonly responseSerialize: (value: BeginStepResponse) => Buffer;
|
|
1626
|
+
readonly responseDeserialize: (value: Buffer) => BeginStepResponse;
|
|
1627
|
+
};
|
|
1628
|
+
readonly completeStep: {
|
|
1629
|
+
readonly path: "/servicebridge.v1.Workflows/CompleteStep";
|
|
1630
|
+
readonly requestStream: false;
|
|
1631
|
+
readonly responseStream: false;
|
|
1632
|
+
readonly requestSerialize: (value: CompleteStepRequest) => Buffer;
|
|
1633
|
+
readonly requestDeserialize: (value: Buffer) => CompleteStepRequest;
|
|
1634
|
+
readonly responseSerialize: (value: Empty) => Buffer;
|
|
1635
|
+
readonly responseDeserialize: (value: Buffer) => Empty;
|
|
1636
|
+
};
|
|
1637
|
+
readonly completeRun: {
|
|
1638
|
+
readonly path: "/servicebridge.v1.Workflows/CompleteRun";
|
|
1639
|
+
readonly requestStream: false;
|
|
1640
|
+
readonly responseStream: false;
|
|
1641
|
+
readonly requestSerialize: (value: CompleteRunRequest) => Buffer;
|
|
1642
|
+
readonly requestDeserialize: (value: Buffer) => CompleteRunRequest;
|
|
1643
|
+
readonly responseSerialize: (value: Empty) => Buffer;
|
|
1644
|
+
readonly responseDeserialize: (value: Buffer) => Empty;
|
|
1645
|
+
};
|
|
1646
|
+
readonly failStep: {
|
|
1647
|
+
readonly path: "/servicebridge.v1.Workflows/FailStep";
|
|
1648
|
+
readonly requestStream: false;
|
|
1649
|
+
readonly responseStream: false;
|
|
1650
|
+
readonly requestSerialize: (value: FailStepRequest) => Buffer;
|
|
1651
|
+
readonly requestDeserialize: (value: Buffer) => FailStepRequest;
|
|
1652
|
+
readonly responseSerialize: (value: FailStepResponse) => Buffer;
|
|
1653
|
+
readonly responseDeserialize: (value: Buffer) => FailStepResponse;
|
|
1654
|
+
};
|
|
1655
|
+
readonly park: {
|
|
1656
|
+
readonly path: "/servicebridge.v1.Workflows/Park";
|
|
1657
|
+
readonly requestStream: false;
|
|
1658
|
+
readonly responseStream: false;
|
|
1659
|
+
readonly requestSerialize: (value: ParkRequest) => Buffer;
|
|
1660
|
+
readonly requestDeserialize: (value: Buffer) => ParkRequest;
|
|
1661
|
+
readonly responseSerialize: (value: Empty) => Buffer;
|
|
1662
|
+
readonly responseDeserialize: (value: Buffer) => Empty;
|
|
1663
|
+
};
|
|
1664
|
+
readonly heartbeat: {
|
|
1665
|
+
readonly path: "/servicebridge.v1.Workflows/Heartbeat";
|
|
1666
|
+
readonly requestStream: false;
|
|
1667
|
+
readonly responseStream: false;
|
|
1668
|
+
readonly requestSerialize: (value: HeartbeatRequest) => Buffer;
|
|
1669
|
+
readonly requestDeserialize: (value: Buffer) => HeartbeatRequest;
|
|
1670
|
+
readonly responseSerialize: (value: Empty) => Buffer;
|
|
1671
|
+
readonly responseDeserialize: (value: Buffer) => Empty;
|
|
1672
|
+
};
|
|
1673
|
+
};
|
|
1674
|
+
interface WorkflowsClient extends Client {
|
|
1675
|
+
/** Caller-side */
|
|
1676
|
+
start(request: StartRunRequest, callback: (error: ServiceError | null, response: StartRunResponse) => void): ClientUnaryCall;
|
|
1677
|
+
start(request: StartRunRequest, metadata: Metadata, callback: (error: ServiceError | null, response: StartRunResponse) => void): ClientUnaryCall;
|
|
1678
|
+
start(request: StartRunRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: StartRunResponse) => void): ClientUnaryCall;
|
|
1679
|
+
cancel(request: CancelRunRequest, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1680
|
+
cancel(request: CancelRunRequest, metadata: Metadata, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1681
|
+
cancel(request: CancelRunRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1682
|
+
signal(request: SignalRunRequest, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1683
|
+
signal(request: SignalRunRequest, metadata: Metadata, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1684
|
+
signal(request: SignalRunRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1685
|
+
query(request: QueryRunRequest, callback: (error: ServiceError | null, response: QueryRunResponse) => void): ClientUnaryCall;
|
|
1686
|
+
query(request: QueryRunRequest, metadata: Metadata, callback: (error: ServiceError | null, response: QueryRunResponse) => void): ClientUnaryCall;
|
|
1687
|
+
query(request: QueryRunRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: QueryRunResponse) => void): ClientUnaryCall;
|
|
1688
|
+
await(request: AwaitRunRequest, options?: Partial<CallOptions>): ClientReadableStream<RunStatusUpdate>;
|
|
1689
|
+
await(request: AwaitRunRequest, metadata?: Metadata, options?: Partial<CallOptions>): ClientReadableStream<RunStatusUpdate>;
|
|
1690
|
+
replay(request: ReplayRunRequest, callback: (error: ServiceError | null, response: ReplayRunResponse) => void): ClientUnaryCall;
|
|
1691
|
+
replay(request: ReplayRunRequest, metadata: Metadata, callback: (error: ServiceError | null, response: ReplayRunResponse) => void): ClientUnaryCall;
|
|
1692
|
+
replay(request: ReplayRunRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: ReplayRunResponse) => void): ClientUnaryCall;
|
|
1693
|
+
/** Owner-side */
|
|
1694
|
+
subscribe(request: SubscribeRequest, options?: Partial<CallOptions>): ClientReadableStream<RunAssignment>;
|
|
1695
|
+
subscribe(request: SubscribeRequest, metadata?: Metadata, options?: Partial<CallOptions>): ClientReadableStream<RunAssignment>;
|
|
1696
|
+
beginStep(request: BeginStepRequest, callback: (error: ServiceError | null, response: BeginStepResponse) => void): ClientUnaryCall;
|
|
1697
|
+
beginStep(request: BeginStepRequest, metadata: Metadata, callback: (error: ServiceError | null, response: BeginStepResponse) => void): ClientUnaryCall;
|
|
1698
|
+
beginStep(request: BeginStepRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: BeginStepResponse) => void): ClientUnaryCall;
|
|
1699
|
+
completeStep(request: CompleteStepRequest, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1700
|
+
completeStep(request: CompleteStepRequest, metadata: Metadata, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1701
|
+
completeStep(request: CompleteStepRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1702
|
+
completeRun(request: CompleteRunRequest, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1703
|
+
completeRun(request: CompleteRunRequest, metadata: Metadata, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1704
|
+
completeRun(request: CompleteRunRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1705
|
+
failStep(request: FailStepRequest, callback: (error: ServiceError | null, response: FailStepResponse) => void): ClientUnaryCall;
|
|
1706
|
+
failStep(request: FailStepRequest, metadata: Metadata, callback: (error: ServiceError | null, response: FailStepResponse) => void): ClientUnaryCall;
|
|
1707
|
+
failStep(request: FailStepRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: FailStepResponse) => void): ClientUnaryCall;
|
|
1708
|
+
park(request: ParkRequest, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1709
|
+
park(request: ParkRequest, metadata: Metadata, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1710
|
+
park(request: ParkRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1711
|
+
heartbeat(request: HeartbeatRequest, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1712
|
+
heartbeat(request: HeartbeatRequest, metadata: Metadata, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1713
|
+
heartbeat(request: HeartbeatRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: Empty) => void): ClientUnaryCall;
|
|
1714
|
+
}
|
|
1715
|
+
declare const WorkflowsClient: {
|
|
1716
|
+
new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): WorkflowsClient;
|
|
1717
|
+
service: typeof WorkflowsService;
|
|
1718
|
+
serviceName: string;
|
|
1719
|
+
};
|
|
1720
|
+
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
|
1721
|
+
type DeepPartial<T> = T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
|
|
1722
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
1723
|
+
} : Partial<T>;
|
|
1724
|
+
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
1725
|
+
type Exact<P, I extends P> = P extends Builtin ? P : P & {
|
|
1726
|
+
[K in keyof P]: Exact<P[K], I[K]>;
|
|
1727
|
+
} & {
|
|
1728
|
+
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
|
1729
|
+
};
|
|
1730
|
+
interface MessageFns<T> {
|
|
1731
|
+
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
|
1732
|
+
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
|
1733
|
+
create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
|
|
1734
|
+
fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
type JsonExpression = string | number | boolean | null | {
|
|
1738
|
+
literal: string;
|
|
1739
|
+
} | JsonExpression[] | {
|
|
1740
|
+
[key: string]: JsonExpression;
|
|
1741
|
+
};
|
|
1742
|
+
type Predicate = string | {
|
|
1743
|
+
not: Predicate;
|
|
1744
|
+
} | {
|
|
1745
|
+
equals: [JsonExpression, JsonExpression];
|
|
1746
|
+
} | {
|
|
1747
|
+
in: [JsonExpression, JsonExpression];
|
|
1748
|
+
} | {
|
|
1749
|
+
and: Predicate[];
|
|
1750
|
+
} | {
|
|
1751
|
+
or: Predicate[];
|
|
1752
|
+
};
|
|
1753
|
+
|
|
1754
|
+
interface CompensateSpec {
|
|
1755
|
+
type?: "call" | "publish";
|
|
1756
|
+
service?: string;
|
|
1757
|
+
method?: string;
|
|
1758
|
+
event?: string;
|
|
1759
|
+
input: JsonExpression;
|
|
1760
|
+
retry?: Partial<RetryOpts>;
|
|
1761
|
+
idempotencyKey?: string;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
interface WorkflowStartOpts {
|
|
1765
|
+
idempotencyKey?: string;
|
|
1766
|
+
timeoutSec?: number;
|
|
1767
|
+
parentRunId?: string;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
type TemplatableOpts<T> = {
|
|
1771
|
+
[K in keyof T]: T[K] | JsonExpression;
|
|
1772
|
+
};
|
|
1773
|
+
type TemplatableCallOpts = TemplatableOpts<CallOpts>;
|
|
1774
|
+
type TemplatablePublishOpts = TemplatableOpts<PublishOpts>;
|
|
1775
|
+
type TemplatableWorkflowStartOpts = TemplatableOpts<WorkflowStartOpts>;
|
|
1776
|
+
interface StepControlFields {
|
|
1777
|
+
id: string;
|
|
1778
|
+
waitFor?: string[];
|
|
1779
|
+
when?: Predicate;
|
|
1780
|
+
compensate?: CompensateSpec;
|
|
1781
|
+
timeoutSec?: number;
|
|
1782
|
+
retry?: Partial<RetryOpts>;
|
|
1783
|
+
}
|
|
1784
|
+
interface CallStep extends StepControlFields {
|
|
1785
|
+
type: "call";
|
|
1786
|
+
service: string | JsonExpression;
|
|
1787
|
+
method: string | JsonExpression;
|
|
1788
|
+
input: JsonExpression;
|
|
1789
|
+
opts?: TemplatableCallOpts;
|
|
1790
|
+
}
|
|
1791
|
+
interface PublishStep extends StepControlFields {
|
|
1792
|
+
type: "publish";
|
|
1793
|
+
event: string | JsonExpression;
|
|
1794
|
+
input: JsonExpression;
|
|
1795
|
+
opts?: TemplatablePublishOpts;
|
|
1796
|
+
}
|
|
1797
|
+
interface SleepStep extends StepControlFields {
|
|
1798
|
+
type: "sleep";
|
|
1799
|
+
durationSec: number;
|
|
1800
|
+
}
|
|
1801
|
+
interface WaitEventStep extends StepControlFields {
|
|
1802
|
+
type: "wait_event";
|
|
1803
|
+
event: string;
|
|
1804
|
+
filter?: Record<string, JsonExpression>;
|
|
1805
|
+
}
|
|
1806
|
+
interface WaitSignalStep extends StepControlFields {
|
|
1807
|
+
type: "wait_signal";
|
|
1808
|
+
signal: string;
|
|
1809
|
+
}
|
|
1810
|
+
interface WorkflowStep extends StepControlFields {
|
|
1811
|
+
type: "workflow";
|
|
1812
|
+
workflow: string | JsonExpression;
|
|
1813
|
+
input: JsonExpression;
|
|
1814
|
+
opts?: TemplatableWorkflowStartOpts;
|
|
1815
|
+
}
|
|
1816
|
+
interface ForEachSpec {
|
|
1817
|
+
from: JsonExpression;
|
|
1818
|
+
as: string;
|
|
1819
|
+
}
|
|
1820
|
+
interface ParallelStep extends StepControlFields {
|
|
1821
|
+
type: "parallel";
|
|
1822
|
+
steps: Step[];
|
|
1823
|
+
forEach?: ForEachSpec;
|
|
1824
|
+
}
|
|
1825
|
+
interface SequenceStep extends StepControlFields {
|
|
1826
|
+
type: "sequence";
|
|
1827
|
+
steps: Step[];
|
|
1828
|
+
forEach?: ForEachSpec;
|
|
1829
|
+
}
|
|
1830
|
+
interface LocalStep extends StepControlFields {
|
|
1831
|
+
type: "local";
|
|
1832
|
+
fn: (state: Record<string, unknown>) => Promise<unknown>;
|
|
1833
|
+
}
|
|
1834
|
+
type Step = CallStep | PublishStep | SleepStep | WaitEventStep | WaitSignalStep | WorkflowStep | ParallelStep | SequenceStep | LocalStep;
|
|
1835
|
+
type SchemaShape = Record<string, unknown>;
|
|
1836
|
+
interface WorkflowDef {
|
|
1837
|
+
input?: SchemaShape;
|
|
1838
|
+
steps: Step[];
|
|
1839
|
+
retry?: Partial<RetryOpts>;
|
|
1840
|
+
maxParallelism?: number;
|
|
1841
|
+
timeoutSec?: number;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
type PolicyViolationSink = (v: {
|
|
1845
|
+
declaration: string;
|
|
1846
|
+
value: string;
|
|
1847
|
+
denySide: string;
|
|
1848
|
+
reason: string;
|
|
1849
|
+
}) => void;
|
|
1850
|
+
declare class WorkflowDomain {
|
|
1851
|
+
private readonly registry;
|
|
1852
|
+
private readonly onPolicyViolation?;
|
|
1853
|
+
private rpc;
|
|
1854
|
+
constructor(registry: Registry, onPolicyViolation?: PolicyViolationSink | undefined);
|
|
1855
|
+
_attachRpc(rpc: WorkflowsClient): void;
|
|
1856
|
+
handle(name: string, def: WorkflowDef, opts?: WorkflowHandlerOpts): void;
|
|
1857
|
+
start(name: string, input: unknown, opts?: WorkflowStartOpts): Promise<{
|
|
1858
|
+
runId: string;
|
|
1859
|
+
}>;
|
|
1860
|
+
signal(runId: string, signalName: string, payload: unknown): Promise<void>;
|
|
1861
|
+
cancel(runId: string): Promise<void>;
|
|
1862
|
+
await(runId: string): Promise<Record<string, unknown>>;
|
|
1863
|
+
query(runId: string): Promise<{
|
|
1864
|
+
status: string;
|
|
1865
|
+
state: Record<string, unknown>;
|
|
1866
|
+
steps: Array<{
|
|
1867
|
+
stepId: string;
|
|
1868
|
+
status: string;
|
|
1869
|
+
output: unknown;
|
|
1870
|
+
lastError: string;
|
|
1871
|
+
compensatedBy?: string;
|
|
1872
|
+
}>;
|
|
1873
|
+
}>;
|
|
1874
|
+
replay(runId: string, opts?: {
|
|
1875
|
+
fromStepId?: string;
|
|
1876
|
+
}): Promise<{
|
|
1877
|
+
runId: string;
|
|
1878
|
+
}>;
|
|
1879
|
+
private requireRpc;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
interface BootstrapKey {
|
|
1883
|
+
keyID: Buffer;
|
|
1884
|
+
secret: Buffer;
|
|
1885
|
+
caCertDer: Buffer;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
interface ProvisionResult {
|
|
1889
|
+
certDer: Buffer;
|
|
1890
|
+
caChainDer: Buffer;
|
|
1891
|
+
serviceId: string;
|
|
1892
|
+
serviceName: string;
|
|
1893
|
+
instanceId: string;
|
|
1894
|
+
notAfterUnix: bigint;
|
|
1895
|
+
privateKey: CryptoKey;
|
|
1896
|
+
privateKeyDer: Buffer;
|
|
1897
|
+
}
|
|
1898
|
+
/**
|
|
1899
|
+
* Runs the full Provision flow:
|
|
1900
|
+
* 1. Use the CA cert embedded in the bootstrap key as the trusted root.
|
|
1901
|
+
* 2. Generate keypair + CSR.
|
|
1902
|
+
* 3. Call Bootstrap.Provision over a gRPC channel rooted at that CA.
|
|
1903
|
+
*/
|
|
1904
|
+
declare function provision(url: string, key: BootstrapKey): Promise<ProvisionResult>;
|
|
1905
|
+
/**
|
|
1906
|
+
* Reissues a leaf cert via Control.RefreshCert under the existing mTLS channel.
|
|
1907
|
+
* No argon2 — identity is proven by the live client cert. The runtime generates
|
|
1908
|
+
* a fresh instance_id (preserving overlap-rotation semantics); the CA cert
|
|
1909
|
+
* and parent service identity carry over from the previous provision.
|
|
1910
|
+
*
|
|
1911
|
+
* Caller must reuse the existing mTLS ControlClient — RefreshCert is in the
|
|
1912
|
+
* default-deny set and rejects unauthenticated channels.
|
|
1913
|
+
*/
|
|
1914
|
+
declare function refresh(client: ControlClient, previous: ProvisionResult): Promise<ProvisionResult>;
|
|
1915
|
+
|
|
1916
|
+
/** @public см. ./README.md */
|
|
1917
|
+
declare class ServiceBridgeError extends Error {
|
|
1918
|
+
readonly code: number;
|
|
1919
|
+
constructor(scope: string, cause: unknown);
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
/**
|
|
1923
|
+
* Entry в карте `sb.serviceMap()`. Группирует видимые caller'у методы сервиса
|
|
1924
|
+
* (`methods`) и его текущих живых инстансов с их endpoint'ами (`instances`).
|
|
1925
|
+
* `httpEndpoint` поле каждого инстанса — публичный HTTP host:port пользователя
|
|
1926
|
+
* (ADR 0001), пустая строка если у инстанса нет HTTP-интеграции.
|
|
1927
|
+
*/
|
|
1928
|
+
interface ServiceMapEntry {
|
|
1929
|
+
methods: MethodDescriptor[];
|
|
1930
|
+
instances: ServiceInstanceInfo[];
|
|
1931
|
+
eventSubscriptions: EventSubscriptionDescriptor[];
|
|
1932
|
+
outgoingCalls: OutgoingCallDescriptor[];
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
/**
|
|
1936
|
+
* TelemetryAPI is the public surface for emitting telemetry from user code
|
|
1937
|
+
* and from internal subsystems (RPC, HTTP plugins, events, workflow, jobs).
|
|
1938
|
+
*
|
|
1939
|
+
* @public — см. ../telemetry/README.md
|
|
1940
|
+
*/
|
|
1941
|
+
interface TelemetryAPI {
|
|
1942
|
+
/** Start an op; returns a handle to `.end(status, message?)`. */
|
|
1943
|
+
startOp(params: StartOpParams): OpHandle;
|
|
1944
|
+
/**
|
|
1945
|
+
* Runtime-pushed effective payload capture mode for the given op channel.
|
|
1946
|
+
* "none" until the first registry snapshot arrives (fail-safe). Read-only
|
|
1947
|
+
* introspection — capture itself is applied automatically inside startOp.
|
|
1948
|
+
*/
|
|
1949
|
+
captureModeForChannel(channel: Channel): CaptureMode;
|
|
1950
|
+
log: ReturnType<typeof makeLogger>;
|
|
1951
|
+
counter(name: string, labels?: Labels): ReturnType<typeof makeCounter>;
|
|
1952
|
+
gauge(name: string, labels?: Labels): ReturnType<typeof makeGauge>;
|
|
1953
|
+
histogram(name: string, unit?: string, labels?: Labels): ReturnType<typeof makeHistogram>;
|
|
1954
|
+
}
|
|
1955
|
+
interface ConnectedEvent {
|
|
1956
|
+
sessionId: string;
|
|
1957
|
+
serviceId: string;
|
|
1958
|
+
serviceName: string;
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Identity of the current live session. Populated on Welcome (start + every
|
|
1962
|
+
* successful overlap rotation), cleared on stop / stream end. Read via
|
|
1963
|
+
* `ServiceBridge.identity()`.
|
|
1964
|
+
*/
|
|
1965
|
+
interface Identity {
|
|
1966
|
+
sessionId: string;
|
|
1967
|
+
serviceId: string;
|
|
1968
|
+
serviceName: string;
|
|
1969
|
+
instanceId: string;
|
|
1970
|
+
}
|
|
1971
|
+
interface ReconnectingEvent {
|
|
1972
|
+
attempt: number;
|
|
1973
|
+
delayMs: number;
|
|
1974
|
+
reason: string;
|
|
1975
|
+
}
|
|
1976
|
+
interface DisconnectedEvent {
|
|
1977
|
+
reason: string;
|
|
1978
|
+
error?: ServiceBridgeError;
|
|
1979
|
+
}
|
|
1980
|
+
/**
|
|
1981
|
+
* One violation reported by the runtime in `RegistrySnapshot.policy.warnings`.
|
|
1982
|
+
* Emitted via `sb.on("policy_violation", ...)` and logged via console.warn.
|
|
1983
|
+
*
|
|
1984
|
+
* Fields mirror `pb.PolicyViolation`:
|
|
1985
|
+
*
|
|
1986
|
+
* - `declaration` — what was declared, e.g. `rpc.call`, `event.handle`,
|
|
1987
|
+
* `event.publish`, `rpc.handle` (capability).
|
|
1988
|
+
* - `value` — concrete value, e.g. `payments/charge`, `orders.*`.
|
|
1989
|
+
* - `denySide` — `capability` | `self_egress` | `self_acceptance` | `peer_acceptance`.
|
|
1990
|
+
* - `reason` — human-readable explanation from the runtime.
|
|
1991
|
+
*/
|
|
1992
|
+
interface PolicyViolationEvent {
|
|
1993
|
+
declaration: string;
|
|
1994
|
+
value: string;
|
|
1995
|
+
denySide: string;
|
|
1996
|
+
reason: string;
|
|
1997
|
+
}
|
|
1998
|
+
type EventMap = {
|
|
1999
|
+
connected: ConnectedEvent;
|
|
2000
|
+
reconnecting: ReconnectingEvent;
|
|
2001
|
+
disconnected: DisconnectedEvent;
|
|
2002
|
+
/**
|
|
2003
|
+
* Fired once per warning when the runtime sends a PolicyEvaluation in the
|
|
2004
|
+
* registry snapshot (after `start()` or after operator changes policy).
|
|
2005
|
+
*/
|
|
2006
|
+
policy_violation: PolicyViolationEvent;
|
|
2007
|
+
};
|
|
2008
|
+
type Handler<K extends keyof EventMap> = (event: EventMap[K]) => void;
|
|
2009
|
+
/** Public configuration. Documented in `./README.md` (Public contract). */
|
|
2010
|
+
interface ServiceBridgeOptions {
|
|
2011
|
+
reconnectIntervalMs?: number;
|
|
2012
|
+
reconnectAttempts?: number;
|
|
2013
|
+
/**
|
|
2014
|
+
* Advertise config for the inbound Call RPC server.
|
|
2015
|
+
*
|
|
2016
|
+
* - `{ host, port }` — explicit (recommended for prod, required in k8s with POD_IP)
|
|
2017
|
+
* - `undefined` (default) — bind "127.0.0.1" on a free port. Local dev
|
|
2018
|
+
* friendly; logs a warning when falling back to loopback so cross-host
|
|
2019
|
+
* limitations are visible.
|
|
2020
|
+
* - `false` — explicit caller-only mode: do not bind any inbound server.
|
|
2021
|
+
* Set this when you know the instance never serves RPC.
|
|
2022
|
+
*/
|
|
2023
|
+
advertise?: AdvertiseConfig | false;
|
|
2024
|
+
/**
|
|
2025
|
+
* Default options applied to every `sb.rpc.call()` unless overridden.
|
|
2026
|
+
*/
|
|
2027
|
+
callDefaults?: CallOpts;
|
|
2028
|
+
/**
|
|
2029
|
+
* ADR-0014: when `true`, any policy violation reported by the runtime in
|
|
2030
|
+
* the registry snapshot's `PolicyEvaluation.warnings` makes `start()`
|
|
2031
|
+
* surface a `disconnected` event with reason='policy' and the SDK stops.
|
|
2032
|
+
* Default `false` — warnings only (logged via console.warn + emitted as
|
|
2033
|
+
* `policy_violation` events).
|
|
2034
|
+
*/
|
|
2035
|
+
failOnPolicyViolation?: boolean;
|
|
2036
|
+
/**
|
|
2037
|
+
* Emit telemetry (ops, logs, metrics) to the runtime. `false` fully disables
|
|
2038
|
+
* the telemetry transport — the ring still buffers but nothing is drained.
|
|
2039
|
+
* Default `true`.
|
|
2040
|
+
*/
|
|
2041
|
+
telemetry?: boolean;
|
|
2042
|
+
/** Ops-ring byte budget. Default 262144 (256 KiB). */
|
|
2043
|
+
telemetryRingSize?: number;
|
|
2044
|
+
/** Local SQLite outbox directory. Default "./.servicebridge". */
|
|
2045
|
+
dataDir?: string;
|
|
2046
|
+
/** Max rows kept in the event outbox before publish back-pressures. Default 100000. */
|
|
2047
|
+
maxOutboxRows?: number;
|
|
2048
|
+
/** Rows the events drainer pulls per tick. Default 50. */
|
|
2049
|
+
eventsDrainerBatch?: number;
|
|
2050
|
+
/** Max in-flight inbound events the subscriber processes concurrently. Default 32. */
|
|
2051
|
+
eventsMaxInFlight?: number;
|
|
2052
|
+
/** Per-direction captured-payload byte cap. Default 65536. */
|
|
2053
|
+
payloadMaxBytes?: number;
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* @internal см. ./README.md
|
|
2057
|
+
*/
|
|
2058
|
+
interface ServiceBridgeInternalHooks extends ServiceBridgeOptions {
|
|
2059
|
+
certRefreshLeadMs?: number;
|
|
2060
|
+
certRefreshJitterMs?: number;
|
|
2061
|
+
rotationHandshakeTimeoutMs?: number;
|
|
2062
|
+
provisionFn?: typeof provision;
|
|
2063
|
+
refreshFn?: typeof refresh;
|
|
2064
|
+
clientFactory?: (url: string, creds: grpc.ChannelCredentials) => ControlClient;
|
|
2065
|
+
registryClientFactory?: (url: string, creds: grpc.ChannelCredentials) => RegistryClient;
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* ServiceBridge manages the full connection lifecycle:
|
|
2069
|
+
* 1. Parse the bootstrap key.
|
|
2070
|
+
* 2. Provision (Bootstrap.Provision) to get a leaf cert.
|
|
2071
|
+
* 3. Open a mTLS gRPC channel with the cert.
|
|
2072
|
+
* 4. Open (Control.Open) for the server-streamed Welcome / Drain signals.
|
|
2073
|
+
* 5. Auto-reconnect with configurable attempts.
|
|
2074
|
+
* 6. Cert rotation: overlap — new channel up AND Welcome received on the new
|
|
2075
|
+
* stream before closing the old stream.
|
|
2076
|
+
*/
|
|
2077
|
+
declare class ServiceBridge {
|
|
2078
|
+
private readonly url;
|
|
2079
|
+
private readonly rawKey;
|
|
2080
|
+
private readonly opts;
|
|
2081
|
+
private readonly handlers;
|
|
2082
|
+
private stopped;
|
|
2083
|
+
private session;
|
|
2084
|
+
private controlClient;
|
|
2085
|
+
private lastProvision;
|
|
2086
|
+
private certRefreshTimer;
|
|
2087
|
+
private currentIdentity;
|
|
2088
|
+
private readonly _registry;
|
|
2089
|
+
private readonly _watchStream;
|
|
2090
|
+
private readonly _instanceCache;
|
|
2091
|
+
private readonly _schemaRegistry;
|
|
2092
|
+
private _started;
|
|
2093
|
+
private _callServer;
|
|
2094
|
+
private _proxyTransport;
|
|
2095
|
+
private _directTransport;
|
|
2096
|
+
private _rpcClient;
|
|
2097
|
+
private readonly _cb;
|
|
2098
|
+
private readonly _lb;
|
|
2099
|
+
private _eventsClient;
|
|
2100
|
+
private _storage;
|
|
2101
|
+
private _publisher;
|
|
2102
|
+
private _drainer;
|
|
2103
|
+
private _subscriber;
|
|
2104
|
+
private _workflowsClient;
|
|
2105
|
+
private _workflowSubscriber;
|
|
2106
|
+
private _jobsClient;
|
|
2107
|
+
private _jobSubscriber;
|
|
2108
|
+
private readonly _telemetryEnabled;
|
|
2109
|
+
private readonly _telemetryRing;
|
|
2110
|
+
private readonly _telemetryApi;
|
|
2111
|
+
private _telemetryClient;
|
|
2112
|
+
private _telemetryTransport;
|
|
2113
|
+
private _processSampler;
|
|
2114
|
+
private _telemetryInstanceId;
|
|
2115
|
+
private readonly _schemaIndexAdapter;
|
|
2116
|
+
/** RPC domain — incoming handlers and outgoing calls. */
|
|
2117
|
+
readonly rpc: RpcDomain;
|
|
2118
|
+
/** Event domain — define published events, subscribe, publish. */
|
|
2119
|
+
readonly event: EventDomain;
|
|
2120
|
+
/** Workflow domain — register workflow handlers (stub; full impl in workflows.md). */
|
|
2121
|
+
readonly workflow: WorkflowDomain;
|
|
2122
|
+
/** Job domain — register scheduled job handlers via `.handle(name, opts, fn)`. */
|
|
2123
|
+
readonly job: JobDomain;
|
|
2124
|
+
/** Declares outgoing dependencies (rpc/workflows/http). Call before start(). */
|
|
2125
|
+
service(serviceName: string, deps: ServiceDeps): void;
|
|
2126
|
+
constructor(url: string, key: string, options?: ServiceBridgeOptions | ServiceBridgeInternalHooks);
|
|
2127
|
+
/**
|
|
2128
|
+
* Surface a policy denial uniformly: log via console.warn and emit
|
|
2129
|
+
* `policy_violation`. Shared by the registration evaluation (gate #0
|
|
2130
|
+
* warnings) and call-time denials (rpc.call / workflow.run / event.publish).
|
|
2131
|
+
*/
|
|
2132
|
+
private emitPolicyViolation;
|
|
2133
|
+
/**
|
|
2134
|
+
* Route collector — для использования ТОЛЬКО HTTP-интеграциями
|
|
2135
|
+
* (`servicebridge/express`, `servicebridge/fastify`, `servicebridge/hono`).
|
|
2136
|
+
* Прикладной код не вызывает это напрямую: роуты живут в Express/Fastify/Hono.
|
|
2137
|
+
* См. ADR 0001 и userDocs/integrations.md.
|
|
2138
|
+
*/
|
|
2139
|
+
get routes(): RouteCollector;
|
|
2140
|
+
/**
|
|
2141
|
+
* Telemetry API surface — emit ops, logs, metrics from user code.
|
|
2142
|
+
* Resources buffer in the ring before start(); the transport drains once
|
|
2143
|
+
* Welcome arrives. parent_op_id/trace_id are inherited from the active
|
|
2144
|
+
* ALS TraceContext.
|
|
2145
|
+
*
|
|
2146
|
+
* @public — см. ../telemetry/README.md
|
|
2147
|
+
*/
|
|
2148
|
+
get telemetry(): TelemetryAPI;
|
|
2149
|
+
/**
|
|
2150
|
+
* Structured logger — auto-injects instance_id and trace_id/op_id from the
|
|
2151
|
+
* active context. Kept as a top-level convenience surface; equivalent to
|
|
2152
|
+
* `sb.telemetry.log`.
|
|
2153
|
+
*/
|
|
2154
|
+
get logger(): {
|
|
2155
|
+
debug(message: string, fields?: LogFields): void;
|
|
2156
|
+
info(message: string, fields?: LogFields): void;
|
|
2157
|
+
warn(message: string, fields?: LogFields): void;
|
|
2158
|
+
error(message: string, fields?: LogFields): void;
|
|
2159
|
+
};
|
|
2160
|
+
/**
|
|
2161
|
+
* Instance ID текущей сессии (`telemetry_spans.instance_id`) — 12-символьная
|
|
2162
|
+
* Crockford-base32 строка. До `start()` / до первого RegisterResponse
|
|
2163
|
+
* возвращает пустую строку. Используется HTTP-плагинами для автотрейсинга.
|
|
2164
|
+
* @public
|
|
2165
|
+
*/
|
|
2166
|
+
instanceIdString(): string;
|
|
2167
|
+
/**
|
|
2168
|
+
* Дёргается `RouteCollector.publishHttp(...)` после `sb.start()`, когда
|
|
2169
|
+
* интеграция узнала фактический host:port HTTP-сервера и хочет, чтобы
|
|
2170
|
+
* runtime увидел его моментально (а не ждал natural reconnect).
|
|
2171
|
+
*
|
|
2172
|
+
* Безопасно если `start()` ещё не вызван — endpoint просто оседает в
|
|
2173
|
+
* Registry и попадёт в первый RegisterRequest.
|
|
2174
|
+
*/
|
|
2175
|
+
private onRegistrationChanged;
|
|
2176
|
+
on<K extends keyof EventMap>(event: K, handler: Handler<K>): this;
|
|
2177
|
+
start(): Promise<void>;
|
|
2178
|
+
stop(): Promise<void>;
|
|
2179
|
+
/**
|
|
2180
|
+
* Registers a SchemaPair on the caller side for the given (service, method).
|
|
2181
|
+
* Must be called before `sb.rpc.call()` is invoked for that method. The schema
|
|
2182
|
+
* MUST match the one used by the target service (same .proto file).
|
|
2183
|
+
*
|
|
2184
|
+
* For an ergonomic alternative that handles dependency declaration, schema
|
|
2185
|
+
* loading and typed method calls in one shot — see `client()`.
|
|
2186
|
+
*/
|
|
2187
|
+
useSchema(serviceName: string, methodName: string, spec: SchemaSpec): Promise<void>;
|
|
2188
|
+
/**
|
|
2189
|
+
* High-level typed caller: reads the `.proto` file once, registers all
|
|
2190
|
+
* methods in its `service` block as outgoing dependencies, loads schemas,
|
|
2191
|
+
* and returns a proxy object with typed method calls.
|
|
2192
|
+
*
|
|
2193
|
+
* ```ts
|
|
2194
|
+
* const payment = await sb.client("payment-svc", "./payment.proto");
|
|
2195
|
+
* await sb.start();
|
|
2196
|
+
* const res = await payment.Charge({ userId: "u", amount: 100 });
|
|
2197
|
+
*
|
|
2198
|
+
* // streaming method auto-detected from `rpc Generate(...) returns (stream Chunk)`
|
|
2199
|
+
* for await (const chunk of payment.Generate({ prompt: "..." })) { ... }
|
|
2200
|
+
* ```
|
|
2201
|
+
*
|
|
2202
|
+
* Must be called BEFORE `start()` — declared dependencies are sent in the
|
|
2203
|
+
* initial RegisterRequest. Pass `methods` to bind only a subset; otherwise
|
|
2204
|
+
* every method in any service block is exposed.
|
|
2205
|
+
*/
|
|
2206
|
+
client(serviceName: string, protoFile: string, opts?: {
|
|
2207
|
+
methods?: string[];
|
|
2208
|
+
callDefaults?: CallOpts;
|
|
2209
|
+
}): Promise<TypedClient>;
|
|
2210
|
+
/**
|
|
2211
|
+
* Server-side streaming RPC. Returns an AsyncIterable of decoded chunks.
|
|
2212
|
+
* Cancelling the for-await loop (break/return) closes the underlying gRPC
|
|
2213
|
+
* stream which propagates to the callee.
|
|
2214
|
+
*/
|
|
2215
|
+
stream<Req = unknown, Chunk = unknown>(serviceName: string, methodName: string, payload: Req, opts?: CallOpts): AsyncIterable<Chunk>;
|
|
2216
|
+
/**
|
|
2217
|
+
* Returns the identity of the current live session, or `null` if not
|
|
2218
|
+
* connected (before first Welcome, during reconnect, or after stop()).
|
|
2219
|
+
*/
|
|
2220
|
+
identity(): Identity | null;
|
|
2221
|
+
/**
|
|
2222
|
+
* Live snapshot of the service registry grouped by serviceName. Each entry
|
|
2223
|
+
* carries both the method descriptors visible to this caller (subject to
|
|
2224
|
+
* outgoing-dep subscriptions) и список текущих живых инстансов с их
|
|
2225
|
+
* endpoint'ами (`callEndpoint` для gRPC, `httpEndpoint` для HTTP-сервера
|
|
2226
|
+
* пользователя по ADR 0001).
|
|
2227
|
+
*/
|
|
2228
|
+
serviceMap(): ReadonlyMap<string, ServiceMapEntry>;
|
|
2229
|
+
/**
|
|
2230
|
+
* ADR-0014: the caller's last-known PolicyEvaluation as pushed by the
|
|
2231
|
+
* runtime via `RegistrySnapshot.policy`. `null` until the first snapshot
|
|
2232
|
+
* frame arrives. Updated automatically when the operator edits policy and
|
|
2233
|
+
* Postgres NOTIFY fires → runtime re-emits.
|
|
2234
|
+
*/
|
|
2235
|
+
policyEvaluation(): PolicyEvaluation | null;
|
|
2236
|
+
private emit;
|
|
2237
|
+
private connect;
|
|
2238
|
+
private openSession;
|
|
2239
|
+
private ensureRpcReady;
|
|
2240
|
+
private buildMTLSCredentials;
|
|
2241
|
+
private maybeStartWorkflowSubscriber;
|
|
2242
|
+
private readonly runHandlerWithTrace;
|
|
2243
|
+
private maybeStartJobSubscriber;
|
|
2244
|
+
private handlersForSubscriber;
|
|
2245
|
+
private scheduleCertRefresh;
|
|
2246
|
+
/**
|
|
2247
|
+
* Overlap rotation:
|
|
2248
|
+
* 1. Re-provision (new cert).
|
|
2249
|
+
* 2. Open new mTLS channel + Control.Open stream.
|
|
2250
|
+
* 3. Wait for Welcome on the new stream.
|
|
2251
|
+
* 4. Only then close the old session.
|
|
2252
|
+
*
|
|
2253
|
+
* On failure: schedule a reconnect so the application sees a `reconnecting`
|
|
2254
|
+
* event; the next reconnect cycle will re-provision and proceed.
|
|
2255
|
+
*/
|
|
2256
|
+
private rotateCert;
|
|
2257
|
+
private scheduleReconnect;
|
|
2258
|
+
private clearTimers;
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
export { type AdvertiseConfig as A, type CallOpts as C, type DeclaredDep as D, EventDomain as E, type Identity as I, JobDomain as J, MethodDescriptor as M, type OverlapPolicy as O, type PolicyViolationEvent as P, type ReconnectingEvent as R, type SchemaSpec as S, type Trigger as T, WorkflowDomain as W, type CatchupPolicy as a, type ConnectedEvent as b, type CronTrigger as c, type DelayedTrigger as d, type DisconnectedEvent as e, type IntervalTrigger as f, type JobHandler as g, type JobHandlerCtx as h, type JobOpts as i, MethodType as j, type PublishOpts as k, type RetryOpts as l, type RetryPolicy as m, RpcDomain as n, type RpcHandlerOpts as o, ServiceBridge as p, ServiceBridgeError as q, type ServiceBridgeOptions as r, type ServiceDeps as s, type TypedClient as t, type WorkflowHandlerOpts as u, OpHandle as v };
|