@query-farm/vgi 0.30.0 → 0.31.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/client-entry.js +19 -1
- package/dist/client-entry.js.map +3 -3
- package/dist/index.js +21 -2
- package/dist/index.js.map +4 -4
- package/dist/protocol/dispatch.d.ts +26 -0
- package/dist/serve-entry.js +7 -3
- package/dist/serve-entry.js.map +4 -4
- package/dist/worker-cf-entry.js +7 -3
- package/dist/worker-cf-entry.js.map +4 -4
- package/package.json +5 -4
- package/src/client/errors.ts +19 -0
- package/src/http/fetch.ts +10 -3
- package/src/protocol/dispatch.ts +28 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@query-farm/vgi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "TypeScript framework for extending DuckDB with user-defined functions via the Vector Gateway Interface (VGI) over Arrow IPC.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Query Farm LLC (https://query.farm)",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"./src/index.ts",
|
|
35
35
|
"./src/client-entry.ts",
|
|
36
36
|
"./src/worker-cf-entry.ts",
|
|
37
|
-
"./src/serve-entry.ts"
|
|
37
|
+
"./src/serve-entry.ts",
|
|
38
|
+
"./src/arrow/impl-flechette/compat.ts"
|
|
38
39
|
],
|
|
39
40
|
"main": "dist/index.js",
|
|
40
41
|
"types": "dist/index.d.ts",
|
|
@@ -90,12 +91,12 @@
|
|
|
90
91
|
},
|
|
91
92
|
"peerDependencies": {
|
|
92
93
|
"@query-farm/apache-arrow": "^21.1.1",
|
|
93
|
-
"@query-farm/vgi-rpc": ">=0.
|
|
94
|
+
"@query-farm/vgi-rpc": ">=0.24.0 <0.25.0"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
96
97
|
"@duckdb/node-api": "^1.5.5-r.4",
|
|
97
98
|
"@query-farm/apache-arrow": "^21.1.1",
|
|
98
|
-
"@query-farm/vgi-rpc": "^0.
|
|
99
|
+
"@query-farm/vgi-rpc": "^0.24.0",
|
|
99
100
|
"@types/bun": "latest",
|
|
100
101
|
"typescript": "^7.0.2"
|
|
101
102
|
},
|
package/src/client/errors.ts
CHANGED
|
@@ -63,6 +63,25 @@ export function wrapRpcWithErrorEnrichment(rpc: RpcClient): RpcClient {
|
|
|
63
63
|
throw e;
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
+
// The batch-level twins (vgi-rpc 0.24.0) get the same treatment: a caller
|
|
67
|
+
// holding encoded Arrow should still see the worker's traceback rather
|
|
68
|
+
// than a bare RpcError.
|
|
69
|
+
async callRaw(method, input) {
|
|
70
|
+
try {
|
|
71
|
+
return await rpc.callRaw(method, input);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
if (e instanceof RpcError) throw VgiClientError.fromRpcError(e);
|
|
74
|
+
throw e;
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
async streamRaw(method, input, options) {
|
|
78
|
+
try {
|
|
79
|
+
return await rpc.streamRaw(method, input, options);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
if (e instanceof RpcError) throw VgiClientError.fromRpcError(e);
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
84
|
+
},
|
|
66
85
|
describe: () => rpc.describe(),
|
|
67
86
|
close: () => rpc.close(),
|
|
68
87
|
};
|
package/src/http/fetch.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
type Protocol,
|
|
25
25
|
} from "@query-farm/vgi-rpc";
|
|
26
26
|
import { arrowStateSerializer } from "../protocol/state-serializer.js";
|
|
27
|
-
import { buildVgiProtocol, type ProtocolConfig } from "../protocol/dispatch.js";
|
|
27
|
+
import { buildVgiProtocol, VGI_PROTOCOL_NAME, type ProtocolConfig } from "../protocol/dispatch.js";
|
|
28
28
|
import { createLandingRoutes, type LandingInfo } from "./landing.js";
|
|
29
29
|
import { setRequestAuthScope, type RequestAuthHolder } from "../request-auth.js";
|
|
30
30
|
|
|
@@ -199,8 +199,15 @@ export function createVgiFetch(opts: VgiFetchOptions): (req: Request) => Promise
|
|
|
199
199
|
recoverExchangeState: async (opaqueData: Uint8Array) => {
|
|
200
200
|
const tokenString = new TextDecoder().decode(opaqueData);
|
|
201
201
|
// principal binding is enforced by the HTTP handler on the request that
|
|
202
|
-
// carried this token; the recovery path itself is not principal-scoped
|
|
203
|
-
|
|
202
|
+
// carried this token; the recovery path itself is not principal-scoped,
|
|
203
|
+
// so the scope names the protocol and leaves the identity anonymous.
|
|
204
|
+
// `protocol` is required since vgi-rpc 0.24.0: it is bound into the
|
|
205
|
+
// token's AEAD associated data, so a cursor minted under one hosted
|
|
206
|
+
// protocol cannot be opened under another.
|
|
207
|
+
const unpacked = await unpackStateToken(tokenString, opts.signingKey, tokenTtl, {
|
|
208
|
+
protocol: VGI_PROTOCOL_NAME,
|
|
209
|
+
principal: undefined,
|
|
210
|
+
});
|
|
204
211
|
return arrowStateSerializer.deserialize(unpacked.stateBytes);
|
|
205
212
|
},
|
|
206
213
|
});
|
package/src/protocol/dispatch.ts
CHANGED
|
@@ -36,8 +36,35 @@ export interface ProtocolConfig {
|
|
|
36
36
|
signingKey?: Uint8Array;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Wire name of the VGI protocol: the `vgi_rpc.protocol` routing key and the
|
|
41
|
+
* `{protocol}` HTTP path segment.
|
|
42
|
+
*
|
|
43
|
+
* The name carries the major version, so an incompatible major is a
|
|
44
|
+
* *different* protocol and therefore a 404 — an answer every proxy, WAF and
|
|
45
|
+
* load balancer understands without an Arrow parser, and one that lets
|
|
46
|
+
* `vgi.v2` and a future `vgi.v3` be served side by side while clients migrate.
|
|
47
|
+
* That matters for this consumer specifically: the DuckDB extension ships to
|
|
48
|
+
* users and cannot be flag-dayed.
|
|
49
|
+
*
|
|
50
|
+
* Declared rather than derived. Until the transports made the routing key
|
|
51
|
+
* required, each implementation's wire name defaulted to whatever its local
|
|
52
|
+
* type was called, which left the six ports disagreeing four ways — Python
|
|
53
|
+
* `VgiProtocol`, Java and C# `VgiService`, Go the framework default `Service`,
|
|
54
|
+
* this port `vgi` — so no client could address them all. The canonical name is
|
|
55
|
+
* decided in vgi-python and emitted by the DuckDB extension; this is that same
|
|
56
|
+
* string, not an independent choice.
|
|
57
|
+
*
|
|
58
|
+
* Since `@query-farm/vgi-rpc` 0.24.0 the name is also bound into the AEAD
|
|
59
|
+
* associated data of every state and call token (`TokenScope.protocol`), so a
|
|
60
|
+
* caller that opens a token minted by this protocol has to name it. Exported
|
|
61
|
+
* so the HTTP entry points build that scope from the same constant the
|
|
62
|
+
* protocol is registered under rather than a second copy of the literal.
|
|
63
|
+
*/
|
|
64
|
+
export const VGI_PROTOCOL_NAME = "vgi.v2";
|
|
65
|
+
|
|
39
66
|
export function buildVgiProtocol(config: ProtocolConfig): Protocol {
|
|
40
|
-
const protocol = new Protocol(
|
|
67
|
+
const protocol = new Protocol(VGI_PROTOCOL_NAME, { protocolVersion: "2.0.0" });
|
|
41
68
|
|
|
42
69
|
registerFunctionMethods(protocol, {
|
|
43
70
|
registry: config.registry,
|