@query-farm/vgi 0.17.0 → 0.19.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.
Files changed (40) hide show
  1. package/dist/arrow/impl-arrowjs/index.d.ts +1 -0
  2. package/dist/arrow/impl-arrowjs/metadata.d.ts +12 -0
  3. package/dist/arrow/impl-flechette/index.d.ts +1 -0
  4. package/dist/arrow/impl-flechette/metadata.d.ts +13 -0
  5. package/dist/arrow/index.d.ts +1 -1
  6. package/dist/catalog/descriptors.d.ts +13 -7
  7. package/dist/client-entry.js +16 -5
  8. package/dist/client-entry.js.map +9 -8
  9. package/dist/functions/scalar.d.ts +10 -0
  10. package/dist/functions/table-in-out.d.ts +121 -0
  11. package/dist/functions/types.d.ts +12 -0
  12. package/dist/generated/vgi-client.d.ts +3 -1
  13. package/dist/index.core.d.ts +1 -1
  14. package/dist/index.js +310 -21
  15. package/dist/index.js.map +16 -15
  16. package/dist/protocol/types.d.ts +12 -0
  17. package/dist/serve-entry.js +14 -4
  18. package/dist/serve-entry.js.map +8 -7
  19. package/dist/worker-cf-entry.js +188 -26
  20. package/dist/worker-cf-entry.js.map +14 -13
  21. package/dist/worker.d.ts +1 -1
  22. package/package.json +3 -3
  23. package/src/arrow/impl-arrowjs/index.ts +1 -0
  24. package/src/arrow/impl-arrowjs/metadata.ts +20 -0
  25. package/src/arrow/impl-flechette/index.ts +1 -0
  26. package/src/arrow/impl-flechette/metadata.ts +25 -0
  27. package/src/arrow/index.ts +2 -0
  28. package/src/catalog/descriptors.ts +13 -7
  29. package/src/catalog/read-only.ts +31 -14
  30. package/src/client/client.ts +1 -0
  31. package/src/functions/registry.ts +53 -5
  32. package/src/functions/scalar.ts +17 -1
  33. package/src/functions/table-in-out.ts +480 -4
  34. package/src/functions/types.ts +12 -0
  35. package/src/generated/vgi-client.ts +4 -2
  36. package/src/generated/vgi-protocol-schemas.ts +3 -2
  37. package/src/index.core.ts +11 -1
  38. package/src/protocol/serializers/init.ts +7 -0
  39. package/src/protocol/types.ts +12 -0
  40. package/src/worker.ts +1 -1
@@ -3,6 +3,7 @@ import type { AuthContext } from "@query-farm/vgi-rpc";
3
3
  import { FunctionStability, NullHandling } from "../types.js";
4
4
  import type { BindRequest } from "../protocol/types.js";
5
5
  import type { VgiFunction, FunctionExample } from "./types.js";
6
+ import { type CacheControl } from "../cache-control.js";
6
7
  export interface ScalarBindParameters {
7
8
  /** Constant argument values (resolved at bind time) */
8
9
  constArgs: Record<string, any>;
@@ -108,5 +109,14 @@ export interface ScalarFunctionConfig<P extends Record<string, VgiDataType> = Re
108
109
  maxWorkers?: number;
109
110
  requiredSettings?: string[];
110
111
  requiredSecrets?: string[];
112
+ /**
113
+ * Result-cache opt-in: when set, this CacheControl's `vgi.cache.*` metadata
114
+ * rides every output batch's custom metadata (per-batch — NOT the schema,
115
+ * which the IPC stream fixes at open), so the extension can memoize the
116
+ * scalar's output per distinct input value. A pure, deterministic scalar
117
+ * only — advertising this on a non-pure scalar serves stale rows. Mirrors
118
+ * vgi-python's `ScalarFunction.CACHE_CONTROL`.
119
+ */
120
+ cacheControl?: CacheControl;
111
121
  }
112
122
  export declare function defineScalarFunction<P extends Record<string, VgiDataType> = Record<string, VgiDataType>, R extends VgiDataType = VgiDataType, M extends Repr = "rich">(config: ScalarFunctionConfig<P, R, M>): VgiFunction;
@@ -21,6 +21,28 @@ export interface TableInOutProcessParams<TArgs = Record<string, any>> {
21
21
  pushdownFilters?: PushdownFilters;
22
22
  /** Shared storage for cross-phase and cross-worker data (SQLite-backed). */
23
23
  storage: BoundStorage;
24
+ /**
25
+ * Stable client-minted id for this streaming table-in-out substream.
26
+ * Present (identical across init / every process() / finalize) when the
27
+ * client fanned this function out across per-substream workers; use it to
28
+ * key per-substream accumulated state in shared storage so a finalize()
29
+ * that lands on a different HTTP backend than the process() calls still
30
+ * finds it. `null`/`undefined` for the serial path or an old client.
31
+ * Mirrors vgi-python's `ProcessParams.substream_id`.
32
+ */
33
+ substreamId?: Uint8Array | null;
34
+ /**
35
+ * Conditional-revalidation validator (exchange-mode result cache): the
36
+ * client holds a stale cached result for THIS input unit and asks the
37
+ * worker to confirm freshness cheaply. When set, process() may answer with
38
+ * a 0-row `cacheControlMetadata({ notModified: true, ... })` batch instead
39
+ * of recomputing. Rides the input batch's custom metadata (attached by the
40
+ * C++ WriteInputBatch). Undefined on a normal call.
41
+ */
42
+ ifNoneMatch?: string;
43
+ /** RFC 3339 Last-Modified validator for conditional revalidation.
44
+ * Companion to {@link ifNoneMatch}. Undefined on a normal call. */
45
+ ifModifiedSince?: string;
24
46
  }
25
47
  export interface TableInOutConfig<TArgs = Record<string, any>, TState = null> {
26
48
  name: string;
@@ -62,3 +84,102 @@ export interface TableInOutConfig<TArgs = Record<string, any>, TState = null> {
62
84
  requiredSecrets?: string[];
63
85
  }
64
86
  export declare function defineTableInOutFunction<TArgs = Record<string, any>, TState = null>(config: TableInOutConfig<TArgs, TState>): VgiFunction;
87
+ /** Metadata key carrying per-output-row provenance: base64 of a raw
88
+ * little-endian int32[] mapping each output row to the input row that
89
+ * produced it. Shared by string with the C++ extension and vgi-python. */
90
+ export declare const PARENT_ROW_METADATA_KEY = "vgi_rpc.parent_row#b64";
91
+ /**
92
+ * Fold per-output-row provenance into an emit metadata map.
93
+ *
94
+ * Used by the **batched correlated LATERAL** operator (blended
95
+ * RowTransformFunction under `FROM t, f(t.x)` / `LATERAL`): the C++ extension
96
+ * ships a whole input chunk to the worker in ONE exchange and reads ONE
97
+ * output batch, then maps each output row back to the input row that produced
98
+ * it via this array — so a 1->N fan-out or 1->0 filter can be batched instead
99
+ * of driven row-by-row.
100
+ *
101
+ * `parentRows[i]` is the 0-based index (into the input batch) of the row that
102
+ * produced output row `i`. Encoded as a raw little-endian `int32` array (NOT
103
+ * Arrow IPC), base64-encoded, under `vgi_rpc.parent_row#b64`. Absent metadata
104
+ * means an identity 1->1 map (the common case: the extension assumes it, and
105
+ * requires output rows == input rows).
106
+ *
107
+ * Contract: `parentRows.length` MUST equal the emitted batch's row count (a
108
+ * mismatch is a worker bug that would corrupt the stamping). Values are
109
+ * range-checked against the input width on the C++ side. Mirrors vgi-python's
110
+ * `_merge_parent_rows` / `out.emit(..., parent_rows=[...])`.
111
+ */
112
+ export declare function parentRowsMetadata(parentRows: number[], outputRows: number, extra?: Map<string, string>): Map<string, string>;
113
+ /**
114
+ * Process params for a blended row-transform function. `args` carries only the
115
+ * NAMED (bind-time scalar) options — the positional args are the per-row input
116
+ * columns, read from `batch` in process() (by declared name for fixed args,
117
+ * positionally for varargs).
118
+ */
119
+ export type RowTransformProcessParams<TArgs = Record<string, any>> = TableInOutProcessParams<TArgs>;
120
+ export interface RowTransformConfig<TArgs = Record<string, any>> {
121
+ name: string;
122
+ description?: string;
123
+ /**
124
+ * Positional args = the per-row INPUT COLUMNS (real typed args on the wire,
125
+ * no synthetic TABLE placeholder). Read from `batch` by declared name in
126
+ * process(); NOT surfaced on `params.args`.
127
+ */
128
+ args?: Record<string, VgiDataType>;
129
+ /**
130
+ * Trailing VARARGS input columns: the per-row input is N columns of the
131
+ * declared type. A varargs blended function has no per-column declared
132
+ * names (the C++ bind names them col0..colN-1), so process() reads the
133
+ * columns POSITIONALLY off `batch`.
134
+ */
135
+ varargs?: {
136
+ name: string;
137
+ type: VgiDataType;
138
+ doc?: string;
139
+ };
140
+ /** Named (string-position) args stay bind-time scalars on `params.args`. */
141
+ namedArgs?: Record<string, VgiDataType>;
142
+ argDefaults?: Record<string, any>;
143
+ /** Per-argument descriptions keyed by arg name (surfaced as `vgi_doc`). */
144
+ argDocs?: Record<string, string>;
145
+ /** Bind: return the output schema. The input schema (the declared per-row
146
+ * columns, typed by the C++ bind) is on `params.bindCall.input_schema`. */
147
+ onBind: (params: TableInOutBindParams<TArgs>) => {
148
+ outputSchema: VgiSchema;
149
+ opaqueData?: Uint8Array;
150
+ } | Promise<{
151
+ outputSchema: VgiSchema;
152
+ opaqueData?: Uint8Array;
153
+ }>;
154
+ /**
155
+ * Per-row map: transform one input batch, emit exactly one output batch via
156
+ * `out`. 1->1, 1->N (with {@link parentRowsMetadata} provenance), and 1->0
157
+ * (a 0-row emit) all work. There is NO finalize — a blended function is a
158
+ * per-row map (DuckDB forbids FinalExecute under correlated LATERAL, one of
159
+ * the call shapes blended must serve). Accumulating functions use a classic
160
+ * TableInput table-in-out or a TableBufferingFunction.
161
+ */
162
+ process: (params: RowTransformProcessParams<TArgs>, batch: VgiBatch, out: OutputCollector) => void | Promise<void>;
163
+ projectionPushdown?: boolean;
164
+ filterPushdown?: boolean;
165
+ autoApplyFilters?: boolean;
166
+ stability?: FunctionStability;
167
+ examples?: FunctionExample[];
168
+ categories?: string[];
169
+ tags?: Record<string, string>;
170
+ maxWorkers?: number;
171
+ requiredSettings?: string[];
172
+ requiredSecrets?: string[];
173
+ }
174
+ /**
175
+ * Define a blended ("UNNEST-style") table-in-out function: its positional args
176
+ * ARE its per-row input columns, so ONE registration serves every call shape —
177
+ * `f(52, 13)` (literal -> one input row), `FROM t, f(t.x, t.y)` (columns ->
178
+ * streaming), and `LATERAL f(t.x, t.y)`. Mirrors vgi-python's
179
+ * `RowTransformFunction` (Phase B).
180
+ *
181
+ * Registers as a TABLE function with `FunctionInfo.input_from_args = true`;
182
+ * the worker's overload resolution matches blended overloads by INPUT-COLUMN
183
+ * count (the positional args are not on the wire). Map-shaped, no finalize.
184
+ */
185
+ export declare function defineRowTransformFunction<TArgs = Record<string, any>>(config: RowTransformConfig<TArgs>): VgiFunction;
@@ -48,6 +48,18 @@ export interface FunctionMeta {
48
48
  * otherwise calling FinalExecute is unsupported and crashes the C++ side.
49
49
  */
50
50
  hasFinalize?: boolean;
51
+ /**
52
+ * Blended ("UNNEST-style") table-in-out: the function's positional args ARE
53
+ * its per-row input columns (real typed args, no synthetic TABLE
54
+ * placeholder), so ONE registration serves f(52,13) (literal -> 1 input
55
+ * row), FROM t, f(t.x, t.y) (columns -> streaming), and LATERAL f(t.x,t.y).
56
+ * Set by {@link defineRowTransformFunction}; surfaces as
57
+ * FunctionInfo.input_from_args. The C++ extension reads it to enter the
58
+ * in-out registration branch with real-typed args and drive the literal
59
+ * single-row scan-mode. Mirrors vgi-python's RowTransformFunction /
60
+ * ResolvedMetadata.input_from_args.
61
+ */
62
+ inputFromArgs?: boolean;
51
63
  /**
52
64
  * table_buffering: force ParallelSink=false in the C++ operator
53
65
  * (single-thread, source-ordered ingest).
@@ -58,7 +58,7 @@ export interface TableInfo {
58
58
  cardinality_max?: number | null;
59
59
  column_statistics?: Uint8Array | null;
60
60
  bind_result?: Uint8Array | null;
61
- required_field_filter_paths: string[];
61
+ required_filters: string[][];
62
62
  }
63
63
  export interface ViewInfo {
64
64
  comment?: string | null;
@@ -108,6 +108,7 @@ export interface FunctionInfo {
108
108
  source_order_dependent: boolean;
109
109
  sink_order_dependent: boolean;
110
110
  requires_input_batch_index: boolean;
111
+ input_from_args: boolean;
111
112
  required_settings: string[];
112
113
  required_secrets: SecretLookupEntry[];
113
114
  }
@@ -394,6 +395,7 @@ export interface InitRequest {
394
395
  finalize_state_id?: Uint8Array | null;
395
396
  execution_id?: Uint8Array | null;
396
397
  init_opaque_data?: Uint8Array | null;
398
+ substream_id?: Uint8Array | null;
397
399
  order_by_column_name?: string | null;
398
400
  order_by_direction?: OrderByDirection | null;
399
401
  order_by_null_order?: OrderByNullOrder | null;
@@ -2,7 +2,7 @@ export { CACHE_ETAG_KEY, CACHE_EXPIRES_KEY, CACHE_IF_MODIFIED_SINCE_KEY, CACHE_I
2
2
  export { defineScalarFunction, type ScalarFunctionConfig, type ScalarBindParameters, type ScalarParameterDef } from "./functions/scalar.js";
3
3
  export { defineTableFunction, type TableFunctionConfig, type TableBindParams, type TableProcessParams } from "./functions/table.js";
4
4
  export { defineAggregate, GROUP_COLUMN_NAME, type AggregateFunctionConfig, type AggregateBindParams, type AggregateUpdateParams, type AggregateFinalizeParams, } from "./functions/aggregate.js";
5
- export { defineTableInOutFunction, type TableInOutConfig, type TableInOutBindParams, type TableInOutProcessParams } from "./functions/table-in-out.js";
5
+ export { defineTableInOutFunction, defineRowTransformFunction, parentRowsMetadata, PARENT_ROW_METADATA_KEY, type TableInOutConfig, type TableInOutBindParams, type TableInOutProcessParams, type RowTransformConfig, type RowTransformProcessParams, } from "./functions/table-in-out.js";
6
6
  export { defineTableBufferingFunction, type TableBufferingConfig, type TableBufferingBindParams, type TableBufferingParams, type TableBufferingVgiFunction, } from "./functions/table-buffering.js";
7
7
  export { defineCopyFromFunction, type CopyFromFunctionConfig, type CopyFromOption, type CopyFromReadParams, } from "./functions/copy-from.js";
8
8
  export { defineCopyToFunction, type CopyToFunctionConfig, type CopyToOption, type CopyToWriteParams, type CopyToCloseParams, } from "./functions/copy-to.js";