@query-farm/vgi-rpc 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-log.d.ts +5 -0
- package/dist/access-log.d.ts.map +1 -1
- package/dist/auth.d.ts +5 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/client/connect.d.ts +10 -0
- package/dist/client/connect.d.ts.map +1 -1
- package/dist/client/introspect.d.ts +14 -0
- package/dist/client/introspect.d.ts.map +1 -1
- package/dist/client/oauth.d.ts +9 -0
- package/dist/client/oauth.d.ts.map +1 -1
- package/dist/client/pipe.d.ts +24 -0
- package/dist/client/pipe.d.ts.map +1 -1
- package/dist/client/stream.d.ts +8 -0
- package/dist/client/stream.d.ts.map +1 -1
- package/dist/client/types.d.ts +23 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/constants.d.ts +15 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/errors.d.ts +20 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/external.d.ts +2 -0
- package/dist/external.d.ts.map +1 -1
- package/dist/http/auth.d.ts +13 -0
- package/dist/http/auth.d.ts.map +1 -1
- package/dist/http/common.d.ts +1 -0
- package/dist/http/common.d.ts.map +1 -1
- package/dist/http/jwt.d.ts +1 -0
- package/dist/http/jwt.d.ts.map +1 -1
- package/dist/http/mtls.d.ts +7 -0
- package/dist/http/mtls.d.ts.map +1 -1
- package/dist/http/token.d.ts +5 -0
- package/dist/http/token.d.ts.map +1 -1
- package/dist/http/types.d.ts +2 -0
- package/dist/http/types.d.ts.map +1 -1
- package/dist/index.js +6993 -38
- package/dist/index.js.map +50 -12
- package/dist/launcher/serve-unix.d.ts +1 -0
- package/dist/launcher/serve-unix.d.ts.map +1 -1
- package/dist/launcher/state.d.ts +12 -0
- package/dist/launcher/state.d.ts.map +1 -1
- package/dist/protocol.d.ts +3 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/access-log.ts +5 -0
- package/src/auth.ts +5 -0
- package/src/client/connect.ts +10 -0
- package/src/client/introspect.ts +14 -0
- package/src/client/oauth.ts +9 -0
- package/src/client/pipe.ts +24 -0
- package/src/client/stream.ts +8 -0
- package/src/client/types.ts +23 -0
- package/src/constants.ts +16 -1
- package/src/errors.ts +13 -2
- package/src/external.ts +6 -1
- package/src/http/auth.ts +13 -0
- package/src/http/common.ts +1 -0
- package/src/http/jwt.ts +1 -0
- package/src/http/mtls.ts +7 -0
- package/src/http/token.ts +5 -0
- package/src/http/types.ts +2 -0
- package/src/launcher/serve-unix.ts +1 -0
- package/src/launcher/state.ts +12 -0
- package/src/protocol.ts +3 -0
- package/src/types.ts +54 -0
package/src/constants.ts
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
// © Copyright 2025-2026, Query.Farm LLC - https://query.farm
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Well-known metadata keys matching Python's metadata.py.
|
|
5
5
|
|
|
6
|
+
/** Batch-metadata key carrying the invoked RPC method name. */
|
|
6
7
|
export const RPC_METHOD_KEY = "vgi_rpc.method";
|
|
8
|
+
/** Batch-metadata key carrying a log batch's severity level. */
|
|
7
9
|
export const LOG_LEVEL_KEY = "vgi_rpc.log_level";
|
|
10
|
+
/** Batch-metadata key carrying a log batch's message text. */
|
|
8
11
|
export const LOG_MESSAGE_KEY = "vgi_rpc.log_message";
|
|
12
|
+
/** Batch-metadata key carrying a log batch's structured extra fields. */
|
|
9
13
|
export const LOG_EXTRA_KEY = "vgi_rpc.log_extra";
|
|
14
|
+
/** Batch-metadata key carrying the wire request-framing version. */
|
|
10
15
|
export const REQUEST_VERSION_KEY = "vgi_rpc.request_version";
|
|
16
|
+
/** Current wire request-framing version. Distinct from the application-level
|
|
17
|
+
* {@link PROTOCOL_VERSION_KEY protocol version}. */
|
|
11
18
|
export const REQUEST_VERSION = "1";
|
|
12
19
|
|
|
20
|
+
/** Batch-metadata key identifying the server instance that produced a batch. */
|
|
13
21
|
export const SERVER_ID_KEY = "vgi_rpc.server_id";
|
|
22
|
+
/** Batch-metadata key carrying the client-supplied request id. */
|
|
14
23
|
export const REQUEST_ID_KEY = "vgi_rpc.request_id";
|
|
15
24
|
|
|
25
|
+
/** Batch-metadata key carrying the service / protocol name. */
|
|
16
26
|
export const PROTOCOL_NAME_KEY = "vgi_rpc.protocol_name";
|
|
27
|
+
/** Batch-metadata key carrying the `__describe__` response schema version. */
|
|
17
28
|
export const DESCRIBE_VERSION_KEY = "vgi_rpc.describe_version";
|
|
18
29
|
export const PROTOCOL_HASH_KEY = "vgi_rpc.protocol_hash";
|
|
30
|
+
/** Current `__describe__` response schema version (the slim 8-column schema). */
|
|
19
31
|
export const DESCRIBE_VERSION = "4";
|
|
20
32
|
|
|
21
33
|
/** Application protocol surface version. Carried on every request batch from
|
|
@@ -26,14 +38,17 @@ export const DESCRIBE_VERSION = "4";
|
|
|
26
38
|
* (wire framing). Mirrors Python's `PROTOCOL_VERSION_KEY`. */
|
|
27
39
|
export const PROTOCOL_VERSION_KEY = "vgi_rpc.protocol_version";
|
|
28
40
|
|
|
41
|
+
/** Reserved method name for the introspection (`__describe__`) call. */
|
|
29
42
|
export const DESCRIBE_METHOD_NAME = "__describe__";
|
|
30
43
|
|
|
44
|
+
/** Batch-metadata key carrying the base64-encoded stream continuation/state token. */
|
|
31
45
|
export const STATE_KEY = "vgi_rpc.stream_state#b64";
|
|
32
46
|
export const CANCEL_KEY = "vgi_rpc.cancel";
|
|
33
47
|
|
|
34
48
|
export const LOCATION_KEY = "vgi_rpc.location";
|
|
35
49
|
export const LOCATION_SHA256_KEY = "vgi_rpc.location.sha256";
|
|
36
50
|
|
|
51
|
+
/** HTTP response header set when an RPC error is returned over the HTTP transport. */
|
|
37
52
|
export const RPC_ERROR_HEADER = "X-VGI-RPC-Error";
|
|
38
53
|
|
|
39
54
|
/** Top-level metadata key on an EXCEPTION batch identifying the error category.
|
package/src/errors.ts
CHANGED
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
/** Error thrown when the server encounters an RPC protocol error. */
|
|
5
5
|
export class RpcError extends Error {
|
|
6
6
|
constructor(
|
|
7
|
+
/** Remote error class name (e.g. `"ValueError"`). */
|
|
7
8
|
public readonly errorType: string,
|
|
9
|
+
/** Human-readable message from the remote error. */
|
|
8
10
|
public readonly errorMessage: string,
|
|
11
|
+
/** Remote stack-trace text, or an empty string when unavailable. */
|
|
9
12
|
public readonly remoteTraceback: string,
|
|
10
13
|
) {
|
|
11
14
|
super(`${errorType}: ${errorMessage}`);
|
|
@@ -21,10 +24,12 @@ export class VersionError extends Error {
|
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
/**
|
|
25
|
-
* Python's `vgi_rpc.metadata.ERROR_KIND_*` constants. */
|
|
27
|
+
/** `vgi_rpc.error_kind` batch-metadata value for {@link MethodNotImplementedError}.
|
|
28
|
+
* Mirrors Python's `vgi_rpc.metadata.ERROR_KIND_*` constants. */
|
|
26
29
|
export const ERROR_KIND_METHOD_NOT_IMPLEMENTED = "method_not_implemented";
|
|
30
|
+
/** `vgi_rpc.error_kind` batch-metadata value for {@link SessionLostError}. */
|
|
27
31
|
export const ERROR_KIND_SESSION_LOST = "session_lost";
|
|
32
|
+
/** `vgi_rpc.error_kind` batch-metadata value for {@link ServerDrainingError}. */
|
|
28
33
|
export const ERROR_KIND_SERVER_DRAINING = "server_draining";
|
|
29
34
|
export const ERROR_KIND_PROTOCOL_VERSION_MISMATCH = "protocol_version_mismatch";
|
|
30
35
|
|
|
@@ -68,7 +73,9 @@ export function parseProtocolVersion(value: string): [number, number, number] {
|
|
|
68
73
|
* string-matching the message.
|
|
69
74
|
*/
|
|
70
75
|
export class MethodNotImplementedError extends Error {
|
|
76
|
+
/** Typed `vgi_rpc.error_kind` marker for this error class. */
|
|
71
77
|
static readonly errorKind = ERROR_KIND_METHOD_NOT_IMPLEMENTED;
|
|
78
|
+
/** Typed `vgi_rpc.error_kind` marker hoisted onto the error batch metadata. */
|
|
72
79
|
readonly errorKind = ERROR_KIND_METHOD_NOT_IMPLEMENTED;
|
|
73
80
|
constructor(message: string) {
|
|
74
81
|
super(message);
|
|
@@ -79,7 +86,9 @@ export class MethodNotImplementedError extends Error {
|
|
|
79
86
|
/** Raised when a sticky session token is malformed, expired, evicted, or
|
|
80
87
|
* bound to a different worker / principal. HTTP-only. */
|
|
81
88
|
export class SessionLostError extends Error {
|
|
89
|
+
/** Typed `vgi_rpc.error_kind` marker for this error class. */
|
|
82
90
|
static readonly errorKind = ERROR_KIND_SESSION_LOST;
|
|
91
|
+
/** Typed `vgi_rpc.error_kind` marker hoisted onto the error batch metadata. */
|
|
83
92
|
readonly errorKind = ERROR_KIND_SESSION_LOST;
|
|
84
93
|
constructor(message: string) {
|
|
85
94
|
super(message);
|
|
@@ -89,7 +98,9 @@ export class SessionLostError extends Error {
|
|
|
89
98
|
|
|
90
99
|
/** Raised when `ctx.openSession` is called while the server is draining. */
|
|
91
100
|
export class ServerDrainingError extends Error {
|
|
101
|
+
/** Typed `vgi_rpc.error_kind` marker for this error class. */
|
|
92
102
|
static readonly errorKind = ERROR_KIND_SERVER_DRAINING;
|
|
103
|
+
/** Typed `vgi_rpc.error_kind` marker hoisted onto the error batch metadata. */
|
|
93
104
|
readonly errorKind = ERROR_KIND_SERVER_DRAINING;
|
|
94
105
|
constructor(message: string) {
|
|
95
106
|
super(message);
|
package/src/external.ts
CHANGED
|
@@ -54,7 +54,12 @@ export interface ExternalLocationConfig {
|
|
|
54
54
|
/** Minimum batch byte size to trigger externalization. Default: 1MB. */
|
|
55
55
|
externalizeThresholdBytes?: number;
|
|
56
56
|
/** Optional zstd compression for uploaded data. */
|
|
57
|
-
compression?: {
|
|
57
|
+
compression?: {
|
|
58
|
+
/** Compression algorithm; only `"zstd"` is currently supported. */
|
|
59
|
+
algorithm: "zstd";
|
|
60
|
+
/** zstd compression level. Default: 3. */
|
|
61
|
+
level?: number;
|
|
62
|
+
};
|
|
58
63
|
/** URL validator called before fetching. Throw to reject. Default: HTTPS-only. */
|
|
59
64
|
urlValidator?: ((url: string) => void) | null;
|
|
60
65
|
}
|
package/src/http/auth.ts
CHANGED
|
@@ -8,14 +8,27 @@ export type AuthenticateFn = (request: Request) => AuthContext | Promise<AuthCon
|
|
|
8
8
|
|
|
9
9
|
/** RFC 9728 OAuth Protected Resource Metadata. */
|
|
10
10
|
export interface OAuthResourceMetadata {
|
|
11
|
+
/** The protected resource's canonical URL. Doubles as the base for the
|
|
12
|
+
* `/_oauth/callback` redirect URI. */
|
|
11
13
|
resource: string;
|
|
14
|
+
/** Authorization-server issuer URLs. The PKCE flow uses
|
|
15
|
+
* `authorizationServers[0]` for OIDC discovery. */
|
|
12
16
|
authorizationServers: string[];
|
|
17
|
+
/** Scopes the resource advertises. When non-empty these become the PKCE
|
|
18
|
+
* authorization request's space-joined `scope`, taking precedence over
|
|
19
|
+
* {@link HttpHandlerOptions.oauthPkceScope}. */
|
|
13
20
|
scopesSupported?: string[];
|
|
21
|
+
/** Advertised bearer methods (e.g. `["header"]`). */
|
|
14
22
|
bearerMethodsSupported?: string[];
|
|
23
|
+
/** JWS algorithms the resource accepts. */
|
|
15
24
|
resourceSigningAlgValuesSupported?: string[];
|
|
25
|
+
/** Human-readable resource name. */
|
|
16
26
|
resourceName?: string;
|
|
27
|
+
/** Documentation URL for the resource. */
|
|
17
28
|
resourceDocumentation?: string;
|
|
29
|
+
/** Policy URL for the resource. */
|
|
18
30
|
resourcePolicyUri?: string;
|
|
31
|
+
/** Terms-of-service URL for the resource. */
|
|
19
32
|
resourceTosUri?: string;
|
|
20
33
|
/** OAuth client_id that clients should use with the authorization server. */
|
|
21
34
|
clientId?: string;
|
package/src/http/common.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { RPC_ERROR_HEADER } from "../constants.js";
|
|
12
12
|
import type { CookieSpec } from "../types.js";
|
|
13
13
|
|
|
14
|
+
/** MIME type for Arrow IPC stream request and response bodies. */
|
|
14
15
|
export const ARROW_CONTENT_TYPE = "application/vnd.apache.arrow.stream";
|
|
15
16
|
|
|
16
17
|
// Sticky session header conventions (HTTP-only). Mirrors Python's
|
package/src/http/jwt.ts
CHANGED
|
@@ -5,6 +5,7 @@ import * as oauth from "oauth4webapi";
|
|
|
5
5
|
import { AuthContext } from "../auth.js";
|
|
6
6
|
import type { AuthenticateFn } from "./auth.js";
|
|
7
7
|
|
|
8
|
+
/** Options for {@link jwtAuthenticate}, configuring JWT Bearer-token validation. */
|
|
8
9
|
export interface JwtAuthenticateOptions {
|
|
9
10
|
/** The expected `iss` claim (also used to discover AS metadata). */
|
|
10
11
|
issuer: string;
|
package/src/http/mtls.ts
CHANGED
|
@@ -24,11 +24,18 @@ function _loadNodeCrypto(): { X509Certificate: any; createHash: any } {
|
|
|
24
24
|
|
|
25
25
|
/** A single element from an `x-forwarded-client-cert` header. */
|
|
26
26
|
export interface XfccElement {
|
|
27
|
+
/** Hex SHA-256 digest of the client certificate (`Hash` key). */
|
|
27
28
|
hash: string | null;
|
|
29
|
+
/** URL-decoded PEM of the client certificate (`Cert` key), if the proxy
|
|
30
|
+
* forwarded it. */
|
|
28
31
|
cert: string | null;
|
|
32
|
+
/** Certificate Subject DN (`Subject` key). */
|
|
29
33
|
subject: string | null;
|
|
34
|
+
/** URL-decoded URI-type Subject Alternative Name (`URI` key). */
|
|
30
35
|
uri: string | null;
|
|
36
|
+
/** DNS-type Subject Alternative Names (`DNS` keys); may repeat in the header. */
|
|
31
37
|
dns: readonly string[];
|
|
38
|
+
/** URL-decoded URI of the proxy that presented the cert (`By` key). */
|
|
32
39
|
by: string | null;
|
|
33
40
|
}
|
|
34
41
|
|
package/src/http/token.ts
CHANGED
|
@@ -139,10 +139,15 @@ export function packStateToken(
|
|
|
139
139
|
return bytesToBase64(wire);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
/** Decrypted payload of a state token, as returned by {@link unpackStateToken}. */
|
|
142
143
|
export interface UnpackedToken {
|
|
144
|
+
/** Serialized stream-state bytes carried by the token. */
|
|
143
145
|
stateBytes: Uint8Array;
|
|
146
|
+
/** Serialized output-schema IPC bytes. */
|
|
144
147
|
schemaBytes: Uint8Array;
|
|
148
|
+
/** Serialized input-schema IPC bytes (exchange streams). */
|
|
145
149
|
inputSchemaBytes: Uint8Array;
|
|
150
|
+
/** Unix epoch seconds at which the token was minted (used for TTL checks). */
|
|
146
151
|
createdAt: number;
|
|
147
152
|
}
|
|
148
153
|
|
package/src/http/types.ts
CHANGED
|
@@ -112,7 +112,9 @@ export interface HttpHandlerOptions {
|
|
|
112
112
|
|
|
113
113
|
/** Serializer for stream state objects stored in state tokens. */
|
|
114
114
|
export interface StateSerializer {
|
|
115
|
+
/** Encode a stream-state object into the bytes sealed inside a state token. */
|
|
115
116
|
serialize(state: any): Uint8Array;
|
|
117
|
+
/** Decode the bytes recovered from a state token back into a state object. */
|
|
116
118
|
deserialize(bytes: Uint8Array): any;
|
|
117
119
|
}
|
|
118
120
|
|
|
@@ -79,6 +79,7 @@ export interface ServeUnixOptions {
|
|
|
79
79
|
|
|
80
80
|
/** Handle returned by {@link serveUnix} for callers that want to stop the server. */
|
|
81
81
|
export interface ServeUnixHandle {
|
|
82
|
+
/** Absolute path of the bound AF_UNIX socket the server is listening on. */
|
|
82
83
|
readonly socketPath: string;
|
|
83
84
|
/** Shut down the listener and unlink the socket file. */
|
|
84
85
|
stop(): Promise<void>;
|
package/src/launcher/state.ts
CHANGED
|
@@ -15,11 +15,15 @@ import { computeHash } from "./hash.js";
|
|
|
15
15
|
|
|
16
16
|
/** Filesystem layout for one worker tuple: `<state_dir>/<hash>.{lock,sock,meta}`. */
|
|
17
17
|
export interface SocketPaths {
|
|
18
|
+
/** Advisory lockfile path (`<hash>.lock`) guarding launch + liveness. */
|
|
18
19
|
lockPath: string;
|
|
20
|
+
/** AF_UNIX socket path (`<hash>.sock`) the worker binds. */
|
|
19
21
|
sockPath: string;
|
|
22
|
+
/** Launch-metadata JSON path (`<hash>.meta`) read by `--status`. */
|
|
20
23
|
metaPath: string;
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
/** Derive the lock/sock/meta path triple for a worker `hashId` under `stateDir`. */
|
|
23
27
|
export function socketPaths(stateDir: string, hashId: string): SocketPaths {
|
|
24
28
|
return {
|
|
25
29
|
lockPath: path.join(stateDir, `${hashId}.lock`),
|
|
@@ -97,15 +101,23 @@ export function writeMeta(metaPath: string, workerArgv: readonly string[], cwd:
|
|
|
97
101
|
// Status / GC
|
|
98
102
|
// ---------------------------------------------------------------------------
|
|
99
103
|
|
|
104
|
+
/** One row of `--status` output describing a launched worker tuple. */
|
|
100
105
|
export interface StatusRow {
|
|
106
|
+
/** Canonical hash identifying the worker tuple (the `<hash>` filename stem). */
|
|
101
107
|
hashId: string;
|
|
108
|
+
/** Worker argv recorded at launch, or `[]` when the meta file is missing. */
|
|
102
109
|
cmd: string[];
|
|
110
|
+
/** Working directory recorded at launch, or `""` when unknown. */
|
|
103
111
|
cwd: string;
|
|
112
|
+
/** AF_UNIX socket path the worker binds. */
|
|
104
113
|
socket: string;
|
|
114
|
+
/** Unix epoch seconds the worker was launched, or `null` when unknown. */
|
|
105
115
|
startedAt: number | null;
|
|
116
|
+
/** Whether a probe connection to {@link StatusRow.socket} currently succeeds. */
|
|
106
117
|
alive: boolean;
|
|
107
118
|
}
|
|
108
119
|
|
|
120
|
+
/** Outcome of a {@link gcStateDir} sweep. */
|
|
109
121
|
export interface GcResult {
|
|
110
122
|
/** Hash IDs of stale entries that were removed. */
|
|
111
123
|
cleaned: string[];
|
package/src/protocol.ts
CHANGED
|
@@ -23,6 +23,7 @@ const EMPTY_SCHEMA = makeSchema([]);
|
|
|
23
23
|
* Register unary, producer, and exchange methods, then pass to `VgiRpcServer`.
|
|
24
24
|
*/
|
|
25
25
|
export class Protocol {
|
|
26
|
+
/** Service / protocol name, exposed to clients via introspection. */
|
|
26
27
|
readonly name: string;
|
|
27
28
|
/**
|
|
28
29
|
* Application protocol surface version. When non-empty, the server enforces
|
|
@@ -162,6 +163,8 @@ export class Protocol {
|
|
|
162
163
|
return this;
|
|
163
164
|
}
|
|
164
165
|
|
|
166
|
+
/** Snapshot of the registered methods, keyed by method name. Returns a copy,
|
|
167
|
+
* so mutating it does not affect the protocol. */
|
|
165
168
|
getMethods(): Map<string, MethodDefinition> {
|
|
166
169
|
return new Map(this._methods);
|
|
167
170
|
}
|
package/src/types.ts
CHANGED
|
@@ -5,8 +5,14 @@ import { batchFromColumns, isBatch, type VgiBatch, type VgiSchema } from "./arro
|
|
|
5
5
|
import { AuthContext } from "./auth.js";
|
|
6
6
|
import { buildLogBatch, coerceInt64 } from "./wire/response.js";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Whether an RPC method is request/response or streaming. Mirrors Python's
|
|
10
|
+
* `MethodType` and is carried in the `__describe__` payload.
|
|
11
|
+
*/
|
|
8
12
|
export enum MethodType {
|
|
13
|
+
/** Single request batch in, single result batch out. */
|
|
9
14
|
UNARY = "unary",
|
|
15
|
+
/** Streamed batches — either a producer or an exchange stream. */
|
|
10
16
|
STREAM = "stream",
|
|
11
17
|
}
|
|
12
18
|
|
|
@@ -25,8 +31,11 @@ export enum MethodType {
|
|
|
25
31
|
* - `UNIX` — AF_UNIX socket handler (the launcher path).
|
|
26
32
|
*/
|
|
27
33
|
export enum TransportKind {
|
|
34
|
+
/** Stdio worker — the standalone {@link VgiRpcServer} loop. */
|
|
28
35
|
PIPE = "pipe",
|
|
36
|
+
/** Fetch-style HTTP handler (`createHttpHandler`). */
|
|
29
37
|
HTTP = "http",
|
|
38
|
+
/** AF_UNIX socket handler (the launcher path). */
|
|
30
39
|
UNIX = "unix",
|
|
31
40
|
}
|
|
32
41
|
|
|
@@ -46,6 +55,9 @@ export type ServeStartHook = (kind: TransportKind) => void | Promise<void>;
|
|
|
46
55
|
|
|
47
56
|
/** Logging interface available to handlers. */
|
|
48
57
|
export interface LogContext {
|
|
58
|
+
/** Emit a client-directed log message (sent as a zero-row log batch on the
|
|
59
|
+
* wire). `level` is a severity label such as `"info"`, `"warning"`, or
|
|
60
|
+
* `"error"`; `extra` carries optional structured string key/value pairs. */
|
|
49
61
|
clientLog(level: string, message: string, extra?: Record<string, string>): void;
|
|
50
62
|
}
|
|
51
63
|
|
|
@@ -90,6 +102,8 @@ export interface StickyContext {
|
|
|
90
102
|
|
|
91
103
|
/** Extended context with authentication info, available to handlers. */
|
|
92
104
|
export interface CallContext extends LogContext {
|
|
105
|
+
/** Authenticated principal for this call; {@link AuthContext.anonymous} when
|
|
106
|
+
* the request was not authenticated. */
|
|
93
107
|
readonly auth: AuthContext;
|
|
94
108
|
/** Coarse identifier of the bound transport, or `undefined` until the
|
|
95
109
|
* server begins serving (the value is committed by the lifecycle hook
|
|
@@ -200,23 +214,47 @@ export type HeaderInit = (params: Record<string, any>, state: any, ctx: LogConte
|
|
|
200
214
|
*/
|
|
201
215
|
export type OnCancelFn<S = any> = (state: S) => Promise<void> | void;
|
|
202
216
|
|
|
217
|
+
/**
|
|
218
|
+
* In-memory definition of one registered RPC method, produced by the
|
|
219
|
+
* {@link Protocol} builder and consumed by the dispatch layer. Which optional
|
|
220
|
+
* fields are populated depends on the method {@link type}: `handler` for unary
|
|
221
|
+
* methods, `producerInit`/`producerFn` for producer streams, and
|
|
222
|
+
* `exchangeInit`/`exchangeFn` for exchange streams.
|
|
223
|
+
*/
|
|
203
224
|
export interface MethodDefinition {
|
|
225
|
+
/** Method name as registered on the protocol. */
|
|
204
226
|
name: string;
|
|
227
|
+
/** Whether the method is unary or streaming. */
|
|
205
228
|
type: MethodType;
|
|
229
|
+
/** Schema of the request parameters batch. */
|
|
206
230
|
paramsSchema: VgiSchema;
|
|
231
|
+
/** Schema of the unary result batch (unused for streams). */
|
|
207
232
|
resultSchema: VgiSchema;
|
|
233
|
+
/** Schema of streamed output batches (producer and exchange streams). */
|
|
208
234
|
outputSchema?: VgiSchema;
|
|
235
|
+
/** Schema of streamed input batches (exchange streams only). */
|
|
209
236
|
inputSchema?: VgiSchema;
|
|
237
|
+
/** Implementation for unary methods. */
|
|
210
238
|
handler?: UnaryHandler;
|
|
239
|
+
/** Builds the initial state object for a producer stream. */
|
|
211
240
|
producerInit?: ProducerInit;
|
|
241
|
+
/** Produces output batches for a producer stream. */
|
|
212
242
|
producerFn?: ProducerFn;
|
|
243
|
+
/** Builds the initial state object for an exchange stream. */
|
|
213
244
|
exchangeInit?: ExchangeInit;
|
|
245
|
+
/** Handles each input batch of an exchange stream. */
|
|
214
246
|
exchangeFn?: ExchangeFn;
|
|
247
|
+
/** Schema of the optional per-stream header batch. */
|
|
215
248
|
headerSchema?: VgiSchema;
|
|
249
|
+
/** Builds the optional header batch emitted before the first output batch. */
|
|
216
250
|
headerInit?: HeaderInit;
|
|
251
|
+
/** Optional hook run when the client cancels a stream. */
|
|
217
252
|
onCancel?: OnCancelFn;
|
|
253
|
+
/** Human-readable method documentation, surfaced via introspection. */
|
|
218
254
|
doc?: string;
|
|
255
|
+
/** Default values applied to omitted request parameters. */
|
|
219
256
|
defaults?: Record<string, any>;
|
|
257
|
+
/** Human-readable parameter type names, surfaced via introspection. */
|
|
220
258
|
paramTypes?: Record<string, string>;
|
|
221
259
|
}
|
|
222
260
|
|
|
@@ -264,11 +302,17 @@ export interface DispatchInfo {
|
|
|
264
302
|
|
|
265
303
|
/** Per-call I/O counters, matching Python's CallStatistics. */
|
|
266
304
|
export interface CallStatistics {
|
|
305
|
+
/** Number of input batches read from the client. */
|
|
267
306
|
inputBatches: number;
|
|
307
|
+
/** Number of output batches written to the client. */
|
|
268
308
|
outputBatches: number;
|
|
309
|
+
/** Total rows across all input batches. */
|
|
269
310
|
inputRows: number;
|
|
311
|
+
/** Total rows across all output batches. */
|
|
270
312
|
outputRows: number;
|
|
313
|
+
/** Total serialized bytes of all input batches. */
|
|
271
314
|
inputBytes: number;
|
|
315
|
+
/** Total serialized bytes of all output batches. */
|
|
272
316
|
outputBytes: number;
|
|
273
317
|
}
|
|
274
318
|
|
|
@@ -280,7 +324,11 @@ export type HookToken = unknown;
|
|
|
280
324
|
* Implementations must be safe for concurrent use (HTTP transport is concurrent).
|
|
281
325
|
*/
|
|
282
326
|
export interface DispatchHook {
|
|
327
|
+
/** Invoked before the method runs. The returned {@link HookToken} is opaque
|
|
328
|
+
* to the framework and passed back to {@link onDispatchEnd}. */
|
|
283
329
|
onDispatchStart(info: DispatchInfo): HookToken;
|
|
330
|
+
/** Invoked after the method completes or throws. `stats` carries the per-call
|
|
331
|
+
* I/O counters; `error` is set only when the dispatch failed. */
|
|
284
332
|
onDispatchEnd(token: HookToken, info: DispatchInfo, stats: CallStatistics, error?: Error): void;
|
|
285
333
|
}
|
|
286
334
|
|
|
@@ -304,6 +352,8 @@ export class OutputCollector implements CallContext {
|
|
|
304
352
|
private _cookieSinkEnabled = false;
|
|
305
353
|
private _responseCookies: CookieSpec[] = [];
|
|
306
354
|
private _stickyContext: StickyContext | null = null;
|
|
355
|
+
/** Authenticated principal for this call; {@link AuthContext.anonymous} when
|
|
356
|
+
* the request was not authenticated. */
|
|
307
357
|
readonly auth: AuthContext;
|
|
308
358
|
readonly cookies: ReadonlyMap<string, string>;
|
|
309
359
|
readonly kind?: TransportKind;
|
|
@@ -423,14 +473,18 @@ export class OutputCollector implements CallContext {
|
|
|
423
473
|
sink.action = "close";
|
|
424
474
|
}
|
|
425
475
|
|
|
476
|
+
/** Schema of the data batches this collector emits. */
|
|
426
477
|
get outputSchema(): VgiSchema {
|
|
427
478
|
return this._outputSchema;
|
|
428
479
|
}
|
|
429
480
|
|
|
481
|
+
/** True once {@link finish} has been called (producer streams only). */
|
|
430
482
|
get finished(): boolean {
|
|
431
483
|
return this._finished;
|
|
432
484
|
}
|
|
433
485
|
|
|
486
|
+
/** Batches emitted so far this call — the single data batch plus any log
|
|
487
|
+
* batches, in emission order. Consumed by the dispatch layer. */
|
|
434
488
|
get batches(): EmittedBatch[] {
|
|
435
489
|
return this._batches;
|
|
436
490
|
}
|