@query-farm/vgi 0.37.1 → 0.39.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 +74 -0
- package/dist/catalog/composite.d.ts +23 -1
- package/dist/catalog/contents-digest.d.ts +25 -0
- package/dist/catalog/interface.d.ts +107 -2
- package/dist/catalog/read-only.d.ts +45 -1
- package/dist/client/client.d.ts +49 -2
- package/dist/client/types.d.ts +56 -1
- package/dist/client-entry.js +239 -11
- package/dist/client-entry.js.map +9 -8
- package/dist/codec/asd.d.ts +8 -0
- package/dist/functions/copy-to.d.ts +1 -1
- package/dist/generated/vgi-client.d.ts +19 -0
- package/dist/generated/vgi-protocol-schemas.d.ts +3 -0
- package/dist/generated/vgi-protocol-types.d.ts +26 -0
- package/dist/http/fetch.d.ts +2 -1
- package/dist/index.core.d.ts +6 -3
- package/dist/index.js +672 -43
- package/dist/index.js.map +21 -17
- package/dist/protocol/handlers/catalog/contents.d.ts +27 -0
- package/dist/rpc-server.d.ts +97 -0
- package/dist/serve-entry.d.ts +2 -1
- package/dist/serve-entry.js +405 -25
- package/dist/serve-entry.js.map +18 -14
- package/dist/worker-cf-entry.d.ts +3 -0
- package/dist/worker-cf-entry.js +528 -31
- package/dist/worker-cf-entry.js.map +20 -16
- package/dist/worker.d.ts +9 -1
- package/package.json +3 -3
- package/src/catalog/composite.ts +81 -0
- package/src/catalog/contents-digest.ts +78 -0
- package/src/catalog/interface.ts +167 -5
- package/src/catalog/read-only.ts +68 -6
- package/src/client/client.ts +201 -0
- package/src/client/types.ts +58 -1
- package/src/codec/asd.ts +108 -9
- package/src/functions/copy-to.ts +1 -1
- package/src/generated/vgi-client.ts +22 -1
- package/src/generated/vgi-protocol-schemas.ts +30 -1
- package/src/generated/vgi-protocol-types.ts +126 -0
- package/src/http/fetch.ts +10 -2
- package/src/index.core.ts +23 -2
- package/src/protocol/dispatch.ts +1 -1
- package/src/protocol/handlers/catalog/admin.ts +35 -26
- package/src/protocol/handlers/catalog/contents.ts +162 -0
- package/src/protocol/handlers/catalog/macro.ts +2 -1
- package/src/protocol/handlers/catalog/shared.ts +12 -1
- package/src/rpc-server.ts +273 -0
- package/src/serve-entry.ts +7 -1
- package/src/worker-cf-entry.ts +8 -0
- package/src/worker.ts +24 -6
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type CatalogContentsResponse } from "../../../generated/vgi-protocol-types.js";
|
|
2
|
+
import type { AttachOpaqueData, CatalogInterface } from "../../../catalog/interface.js";
|
|
3
|
+
type Wire = {
|
|
4
|
+
result: Uint8Array;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Ask the catalog for its contents and shape the typed wire response.
|
|
8
|
+
*
|
|
9
|
+
* Enforces the revalidation rules: `not_modified` needs an etag equal to
|
|
10
|
+
* `ifNoneMatch` and no schemas; a catalog with no etag never yields
|
|
11
|
+
* `not_modified` (and so ignores `ifNoneMatch`). Validates the schema paths
|
|
12
|
+
* (unique, parent present) and orders them parent-first. Every item is
|
|
13
|
+
* encoded with the SAME encoder its per-schema RPC uses, so items are
|
|
14
|
+
* byte-identical to catalog_schemas / catalog_schema_contents_* items.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildCatalogContents(cat: CatalogInterface, owner: CatalogInterface, attach: AttachOpaqueData, version: number, ifNoneMatch: string | null): Promise<CatalogContentsResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* Serve one catalog_contents call (the attach value is already opened).
|
|
19
|
+
*
|
|
20
|
+
* Caching: a catalog whose `catalogContentsCacheable()` is true (by default:
|
|
21
|
+
* version frozen and contents attach-independent; ReadOnlyCatalogInterface) is
|
|
22
|
+
* built once per (catalog instance, version); every later call reuses the same
|
|
23
|
+
* serialized response bytes. A conditional call matching the cached etag is
|
|
24
|
+
* answered `not_modified` without touching the snapshot.
|
|
25
|
+
*/
|
|
26
|
+
export declare function serveCatalogContents(cat: CatalogInterface, attach: AttachOpaqueData, ifNoneMatch: string | null): Promise<Wire>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type GrantMinter, type Protocol, type TokenResolver, VgiRpcServer } from "@query-farm/vgi-rpc";
|
|
2
|
+
/** The transport a server is being built for. Only `"http"` changes what is
|
|
3
|
+
* hosted (identity); the rest are recorded so the decision lives here rather
|
|
4
|
+
* than at each call site. `"iroh"` is the raw TCP upstream of a
|
|
5
|
+
* `vgi-iroh-bridge`; `"stream"` a caller-provided byte-stream pair. */
|
|
6
|
+
export type ServerTransport = "pipe" | "unix" | "tcp" | "iroh" | "stream" | "http";
|
|
7
|
+
/** Environment variable naming the principals allowed to call `introspect_token`. */
|
|
8
|
+
export declare const INTROSPECT_PRINCIPALS_ENV = "VGI_INTROSPECT_PRINCIPALS";
|
|
9
|
+
/**
|
|
10
|
+
* What a worker hosts beyond `vgi.v2`, and whether it opts into identity.
|
|
11
|
+
*
|
|
12
|
+
* Accepted by `new Worker({...})`, `serveVgiWorker`, `createVgiWorkerFetch`
|
|
13
|
+
* and `createVgiFetch` (Cloudflare Workers) alike, so one worker definition
|
|
14
|
+
* hosts the same set on every transport.
|
|
15
|
+
*/
|
|
16
|
+
export interface HostingOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Additional vgi-rpc protocols to host beside `vgi.v2`, on the **same**
|
|
19
|
+
* listener, whatever the transport.
|
|
20
|
+
*
|
|
21
|
+
* A vgi-rpc `Protocol` carries its handlers, so each entry is a whole
|
|
22
|
+
* `(protocol, implementation)` pair. Called **once**, when the server is
|
|
23
|
+
* built; it may consult configuration or the environment, but the answer is
|
|
24
|
+
* fixed for the life of the process, so reflection output and protocol
|
|
25
|
+
* hashes stay stable. Hosted after `vgi.v2`, in the order returned.
|
|
26
|
+
*
|
|
27
|
+
* The protocol is the unit of optionality: there is no way to host a subset
|
|
28
|
+
* of a protocol's methods. A capability that is optional is its own
|
|
29
|
+
* protocol, returned here or not.
|
|
30
|
+
*
|
|
31
|
+
* Each needs a distinct wire name, which may not be `vgi.v2` and may not
|
|
32
|
+
* use the reserved `vgi_rpc.` prefix: reflection is hosted automatically and
|
|
33
|
+
* `vgi_rpc.Identity.v1` is enabled through {@link resolveToken} /
|
|
34
|
+
* {@link mintGrant}. Violations are a startup error naming this hook.
|
|
35
|
+
*/
|
|
36
|
+
hostedProtocols?: () => Iterable<Protocol>;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve an opaque bearer credential to the identity it authenticates as.
|
|
39
|
+
* Supplying it hosts `vgi_rpc.Identity.v1`'s `introspect_token` -- on HTTP,
|
|
40
|
+
* the transport that authenticates callers. Absent, the method is absent
|
|
41
|
+
* (not hosted-and-refusing), which keeps a dependency upgrade from growing a
|
|
42
|
+
* credential-to-identity oracle on every existing worker.
|
|
43
|
+
*
|
|
44
|
+
* Return `null` for "the store answered and this credential is unknown".
|
|
45
|
+
* For "I could not find out" (a store or sidecar outage, a timeout, a 5xx)
|
|
46
|
+
* throw `AuthUnavailableError` from `@query-farm/vgi-rpc` -- the same error
|
|
47
|
+
* an `authenticate` callback throws for an outage. The framework translates
|
|
48
|
+
* it to `identity_unavailable` with that error's retry hint
|
|
49
|
+
* (`vgi_rpc.RetryInfo`), so callers know to retry rather than cache a
|
|
50
|
+
* refusal. `IdentityUnavailableError` works too. Never throw a plain
|
|
51
|
+
* `Error` for an outage: a caller cannot tell it from a definitive answer.
|
|
52
|
+
*
|
|
53
|
+
* Requires {@link introspectPrincipals} (or `VGI_INTROSPECT_PRINCIPALS`);
|
|
54
|
+
* there is no permissive default, and a worker without one refuses to start.
|
|
55
|
+
*/
|
|
56
|
+
resolveToken?: TokenResolver;
|
|
57
|
+
/**
|
|
58
|
+
* Mint a standing delegation credential for the *calling* user. Supplying
|
|
59
|
+
* it hosts `issue_grant` (HTTP only). Throw `GrantRefusedError` to decline,
|
|
60
|
+
* and `AuthUnavailableError` for a transient failure (translated as for
|
|
61
|
+
* {@link resolveToken}). Needs no allowlist: it is not an oracle about
|
|
62
|
+
* anybody else.
|
|
63
|
+
*/
|
|
64
|
+
mintGrant?: GrantMinter;
|
|
65
|
+
/**
|
|
66
|
+
* Principals permitted to call `introspect_token`. When omitted,
|
|
67
|
+
* `VGI_INTROSPECT_PRINCIPALS` (comma-separated) is read. Only consulted when
|
|
68
|
+
* {@link resolveToken} is supplied.
|
|
69
|
+
*/
|
|
70
|
+
introspectPrincipals?: Iterable<string>;
|
|
71
|
+
/** Maximum age of the caller's authentication for `issue_grant`, in
|
|
72
|
+
* seconds. vgi-rpc's default when omitted. */
|
|
73
|
+
maxAuthAge?: number;
|
|
74
|
+
}
|
|
75
|
+
/** Server-level options passed through to `VgiRpcServer`. */
|
|
76
|
+
export interface BuildRpcServerOptions {
|
|
77
|
+
/** Which transport this server will serve. */
|
|
78
|
+
transport: ServerTransport;
|
|
79
|
+
/** Server identifier, surfaced through reflection. */
|
|
80
|
+
serverId?: string;
|
|
81
|
+
/** Environment to read `VGI_INTROSPECT_PRINCIPALS` from. Default
|
|
82
|
+
* `process.env` where it exists (not on Cloudflare Workers). */
|
|
83
|
+
env?: Record<string, string | undefined>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Build the vgi-rpc server for a worker's `vgi.v2` protocol on `transport`.
|
|
87
|
+
*
|
|
88
|
+
* Calls `hosting.hostedProtocols()` exactly once and hosts the result beside
|
|
89
|
+
* `primary`; see the module comment for the full hosted set.
|
|
90
|
+
*
|
|
91
|
+
* @throws TypeError `hostedProtocols()` returned something other than an
|
|
92
|
+
* iterable of vgi-rpc `Protocol`s.
|
|
93
|
+
* @throws Error A hosted protocol's name is invalid, reserved, `vgi.v2`'s, or
|
|
94
|
+
* repeated; the transport is unknown; or the worker supplies `resolveToken`
|
|
95
|
+
* on HTTP with no introspector allowlist.
|
|
96
|
+
*/
|
|
97
|
+
export declare function buildRpcServer(primary: Protocol, hosting: HostingOptions, options: BuildRpcServerOptions): VgiRpcServer;
|
package/dist/serve-entry.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CatalogInterface } from "./catalog/interface.js";
|
|
2
2
|
import type { FunctionRegistry } from "./functions/registry.js";
|
|
3
3
|
import { type AuthenticateFn, type PeerResolutionOptions } from "@query-farm/vgi-rpc";
|
|
4
|
+
import type { HostingOptions } from "./rpc-server.js";
|
|
4
5
|
/** Environment variables `serveVgiWorker` reads. Injectable for testing. */
|
|
5
6
|
export interface ServeEnv {
|
|
6
7
|
PORT?: string;
|
|
@@ -26,7 +27,7 @@ export interface IrohHttpBridgeOptions {
|
|
|
26
27
|
*/
|
|
27
28
|
peerResolutionContext?: (request: Request) => PeerResolutionOptions | Promise<PeerResolutionOptions>;
|
|
28
29
|
}
|
|
29
|
-
export interface ServeVgiWorkerOptions {
|
|
30
|
+
export interface ServeVgiWorkerOptions extends HostingOptions {
|
|
30
31
|
/** Short worker name shown on the landing page, e.g. "ishares". */
|
|
31
32
|
name: string;
|
|
32
33
|
/** One-line description of what the worker serves. */
|