@query-farm/vgi 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/catalog/item-encoding.d.ts +17 -0
- package/dist/catalog/read-only.d.ts +16 -0
- package/dist/client-entry.js +19 -1
- package/dist/client-entry.js.map +3 -3
- package/dist/filter-pushdown/evaluate.d.ts +9 -0
- package/dist/filter-pushdown/history.d.ts +66 -0
- package/dist/filter-pushdown/index.d.ts +1 -0
- package/dist/functions/storage-cf-do.d.ts +2 -2
- package/dist/functions/storage.d.ts +39 -3
- package/dist/functions/table-in-out.d.ts +13 -8
- package/dist/functions/types.d.ts +14 -1
- package/dist/http/fetch.d.ts +1 -1
- package/dist/index.core.d.ts +1 -1
- package/dist/index.js +1280 -924
- package/dist/index.js.map +21 -17
- package/dist/protocol/carried-init-request.d.ts +28 -0
- package/dist/protocol/dispatch.d.ts +26 -7
- package/dist/protocol/handlers/function.d.ts +0 -1
- package/dist/protocol/handlers/shared.d.ts +0 -7
- package/dist/protocol/state-serializer.d.ts +29 -2
- package/dist/serve-entry.js +395 -188
- package/dist/serve-entry.js.map +16 -12
- package/dist/util/zstd-sync.d.ts +7 -0
- package/dist/worker-cf-entry.js +5047 -4710
- package/dist/worker-cf-entry.js.map +25 -21
- package/package.json +5 -4
- package/src/catalog/item-encoding.ts +59 -0
- package/src/catalog/read-only.ts +87 -19
- package/src/client/errors.ts +19 -0
- package/src/filter-pushdown/evaluate.ts +55 -8
- package/src/filter-pushdown/history.ts +239 -0
- package/src/filter-pushdown/index.ts +8 -0
- package/src/functions/storage-cf-do.ts +7 -12
- package/src/functions/storage.ts +54 -11
- package/src/functions/table-buffering.ts +0 -1
- package/src/functions/table-in-out.ts +99 -60
- package/src/functions/table.ts +41 -38
- package/src/functions/types.ts +14 -1
- package/src/http/fetch.ts +1 -9
- package/src/index.core.ts +1 -0
- package/src/protocol/carried-init-request.ts +139 -0
- package/src/protocol/dispatch.ts +28 -9
- package/src/protocol/handlers/catalog/admin.ts +5 -2
- package/src/protocol/handlers/function.ts +18 -15
- package/src/protocol/handlers/shared.ts +0 -22
- package/src/protocol/state-serializer.ts +109 -37
- package/src/util/zstd-sync.ts +50 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { InitRequest } from "./types.js";
|
|
2
|
+
/** Pack an init request's IPC bytes for the cursor: `u8 codec | payload`. */
|
|
3
|
+
export declare function packInitRequest(ipc: Uint8Array): Uint8Array;
|
|
4
|
+
/** What a continuation needs from the carried init request. */
|
|
5
|
+
export interface CarriedInitRequest {
|
|
6
|
+
/**
|
|
7
|
+
* The parsed request -- a fresh top-level object with a fresh `bind_call`
|
|
8
|
+
* each call, so the per-turn assignments the dispatcher makes (split
|
|
9
|
+
* payloads) never reach the shared parse. The nested values (Arrow
|
|
10
|
+
* schemas and batches, arguments) are shared and must be treated as
|
|
11
|
+
* read-only, as they always were.
|
|
12
|
+
*/
|
|
13
|
+
request: InitRequest;
|
|
14
|
+
/** The raw bind-call IPC bytes, which the split-token fingerprint hashes. */
|
|
15
|
+
bindCallIpc: Uint8Array;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse the init request a cursor carries (as packed by
|
|
19
|
+
* {@link packInitRequest}), from the process memo when this stream's turns have
|
|
20
|
+
* been here before.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseCarriedInitRequest(packed: Uint8Array): CarriedInitRequest;
|
|
23
|
+
/** Cumulative parse / memo-hit counts for this process (observability and tests). */
|
|
24
|
+
export declare function carriedInitRequestStats(): {
|
|
25
|
+
parses: number;
|
|
26
|
+
hits: number;
|
|
27
|
+
entries: number;
|
|
28
|
+
};
|
|
@@ -5,13 +5,6 @@ export interface ProtocolConfig {
|
|
|
5
5
|
registry: FunctionRegistry;
|
|
6
6
|
catalogInterface?: CatalogInterface;
|
|
7
7
|
catalogName?: string;
|
|
8
|
-
/**
|
|
9
|
-
* Recover accumulated exchange state from FINALIZE init_opaque_data.
|
|
10
|
-
* For HTTP transport, this unpacks the state token that the C++ extension
|
|
11
|
-
* passes from the last INPUT exchange to the FINALIZE init request.
|
|
12
|
-
* Returns the deserialized VGI dispatch state object (with userState field).
|
|
13
|
-
*/
|
|
14
|
-
recoverExchangeState?: (opaqueData: Uint8Array) => any;
|
|
15
8
|
/**
|
|
16
9
|
* AEAD signing key for sealing catalog opaque-data envelopes. Pass the same
|
|
17
10
|
* 32-byte key used for HTTP state tokens. When omitted (subprocess / unix
|
|
@@ -20,4 +13,30 @@ export interface ProtocolConfig {
|
|
|
20
13
|
*/
|
|
21
14
|
signingKey?: Uint8Array;
|
|
22
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Wire name of the VGI protocol: the `vgi_rpc.protocol` routing key and the
|
|
18
|
+
* `{protocol}` HTTP path segment.
|
|
19
|
+
*
|
|
20
|
+
* The name carries the major version, so an incompatible major is a
|
|
21
|
+
* *different* protocol and therefore a 404 — an answer every proxy, WAF and
|
|
22
|
+
* load balancer understands without an Arrow parser, and one that lets
|
|
23
|
+
* `vgi.v2` and a future `vgi.v3` be served side by side while clients migrate.
|
|
24
|
+
* That matters for this consumer specifically: the DuckDB extension ships to
|
|
25
|
+
* users and cannot be flag-dayed.
|
|
26
|
+
*
|
|
27
|
+
* Declared rather than derived. Until the transports made the routing key
|
|
28
|
+
* required, each implementation's wire name defaulted to whatever its local
|
|
29
|
+
* type was called, which left the six ports disagreeing four ways — Python
|
|
30
|
+
* `VgiProtocol`, Java and C# `VgiService`, Go the framework default `Service`,
|
|
31
|
+
* this port `vgi` — so no client could address them all. The canonical name is
|
|
32
|
+
* decided in vgi-python and emitted by the DuckDB extension; this is that same
|
|
33
|
+
* string, not an independent choice.
|
|
34
|
+
*
|
|
35
|
+
* Since `@query-farm/vgi-rpc` 0.24.0 the name is also bound into the AEAD
|
|
36
|
+
* associated data of every state and call token (`TokenScope.protocol`), so a
|
|
37
|
+
* caller that opens a token minted by this protocol has to name it. Exported
|
|
38
|
+
* so the HTTP entry points build that scope from the same constant the
|
|
39
|
+
* protocol is registered under rather than a second copy of the literal.
|
|
40
|
+
*/
|
|
41
|
+
export declare const VGI_PROTOCOL_NAME = "vgi.v2";
|
|
23
42
|
export declare function buildVgiProtocol(config: ProtocolConfig): Protocol;
|
|
@@ -2,7 +2,6 @@ import { Protocol } from "@query-farm/vgi-rpc";
|
|
|
2
2
|
import type { FunctionRegistry } from "../../functions/registry.js";
|
|
3
3
|
export interface FunctionHandlerConfig {
|
|
4
4
|
registry: FunctionRegistry;
|
|
5
|
-
recoverExchangeState?: (opaqueData: Uint8Array) => any;
|
|
6
5
|
signingKey?: Uint8Array;
|
|
7
6
|
/**
|
|
8
7
|
* Used to map a bind's `attach_opaque_data` to its catalog, so resolution can
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type VgiSchema } from "../../arrow/index.js";
|
|
2
2
|
import type { OverloadContext } from "../../functions/registry.js";
|
|
3
|
-
import type { InitRequest } from "../types.js";
|
|
4
3
|
export declare const RESULT_BINARY_SCHEMA: VgiSchema;
|
|
5
4
|
export declare const REQUEST_PARAMS_SCHEMA: VgiSchema;
|
|
6
5
|
export declare const RESULT_BINARY_NULLABLE_SCHEMA: VgiSchema;
|
|
@@ -29,9 +28,3 @@ export declare function overloadContext(req: {
|
|
|
29
28
|
}, catalogInterface?: {
|
|
30
29
|
catalogNameForAttach(a: Uint8Array): string | null;
|
|
31
30
|
}): OverloadContext;
|
|
32
|
-
/**
|
|
33
|
-
* Recover accumulated exchange state from a FINALIZE init request.
|
|
34
|
-
* For HTTP transport, this unpacks the state token that the C++ extension
|
|
35
|
-
* passes from the last INPUT exchange to the FINALIZE init request.
|
|
36
|
-
*/
|
|
37
|
-
export declare function recoverFinalizeState(request: InitRequest, recoverExchangeState: ((opaqueData: Uint8Array) => any) | undefined): any;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { type VgiDataType } from "../arrow/index.js";
|
|
2
2
|
import type { StateSerializer } from "@query-farm/vgi-rpc";
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* The fields of the exchange state an HTTP cursor carries, by name and type.
|
|
5
|
+
*
|
|
6
|
+
* Descriptive: {@link arrowStateSerializer} writes them as a flat binary frame
|
|
7
|
+
* (see there), not as an Arrow batch of this schema. Kept exported for API
|
|
8
|
+
* stability.
|
|
9
|
+
*/
|
|
4
10
|
export declare const EXCHANGE_STATE_SCHEMA: import("../index.core.js").VgiSchema;
|
|
5
11
|
/** Infer an Arrow DataType from a JS value for user state serialization. */
|
|
6
12
|
export declare function inferFieldType(value: any): VgiDataType;
|
|
@@ -19,5 +25,26 @@ export declare function serializeUserState(userState: any): Uint8Array | null;
|
|
|
19
25
|
* Reconstructs a plain JS object, preserving BigInt for Int64 columns.
|
|
20
26
|
*/
|
|
21
27
|
export declare function deserializeUserState(bytes: Uint8Array | null): any;
|
|
22
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* The HTTP exchange state serializer: what a stream's cursor carries between
|
|
30
|
+
* turns.
|
|
31
|
+
*
|
|
32
|
+
* A flat, versioned binary frame, not an Arrow batch. The cursor is built and
|
|
33
|
+
* parsed on every turn of every HTTP stream, and wrapping eight scalars in a
|
|
34
|
+
* one-row Arrow batch cost ~0.4 ms a turn (a generic column builder per field,
|
|
35
|
+
* an IPC schema message each way) plus ~1 KB of framing that was then sealed
|
|
36
|
+
* and base64-encoded twice per turn. The fields are the ones
|
|
37
|
+
* {@link EXCHANGE_STATE_SCHEMA} names; `user_state` stays Arrow IPC inside the
|
|
38
|
+
* frame, because it carries typed user values.
|
|
39
|
+
*
|
|
40
|
+
* Layout (little-endian): `u8 version | u8 flags | f64 max_workers |
|
|
41
|
+
* bytes function_name | bytes init_request | bytes execution_id |
|
|
42
|
+
* [bytes opaque_data] [bytes user_state] [bytes filter_history]`, where
|
|
43
|
+
* `bytes` is `u32 length, payload` and a bracketed field is present only when
|
|
44
|
+
* its flag bit is set. The frame never leaves this worker unsealed, so the
|
|
45
|
+
* version byte exists to turn a token minted by another build into a clean
|
|
46
|
+
* refusal rather than a misread.
|
|
47
|
+
*
|
|
48
|
+
* The name is kept for API stability; the Arrow in it is the user state.
|
|
49
|
+
*/
|
|
23
50
|
export declare const arrowStateSerializer: StateSerializer;
|