@query-farm/vgi 0.31.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.
Files changed (44) hide show
  1. package/dist/catalog/item-encoding.d.ts +17 -0
  2. package/dist/catalog/read-only.d.ts +16 -0
  3. package/dist/filter-pushdown/evaluate.d.ts +9 -0
  4. package/dist/filter-pushdown/history.d.ts +66 -0
  5. package/dist/filter-pushdown/index.d.ts +1 -0
  6. package/dist/functions/storage-cf-do.d.ts +2 -2
  7. package/dist/functions/storage.d.ts +39 -3
  8. package/dist/functions/table-in-out.d.ts +13 -8
  9. package/dist/functions/types.d.ts +14 -1
  10. package/dist/http/fetch.d.ts +1 -1
  11. package/dist/index.core.d.ts +1 -1
  12. package/dist/index.js +1325 -988
  13. package/dist/index.js.map +20 -16
  14. package/dist/protocol/carried-init-request.d.ts +28 -0
  15. package/dist/protocol/dispatch.d.ts +0 -7
  16. package/dist/protocol/handlers/function.d.ts +0 -1
  17. package/dist/protocol/handlers/shared.d.ts +0 -7
  18. package/dist/protocol/state-serializer.d.ts +29 -2
  19. package/dist/serve-entry.js +393 -190
  20. package/dist/serve-entry.js.map +16 -12
  21. package/dist/util/zstd-sync.d.ts +7 -0
  22. package/dist/worker-cf-entry.js +5045 -4712
  23. package/dist/worker-cf-entry.js.map +25 -21
  24. package/package.json +1 -1
  25. package/src/catalog/item-encoding.ts +59 -0
  26. package/src/catalog/read-only.ts +87 -19
  27. package/src/filter-pushdown/evaluate.ts +55 -8
  28. package/src/filter-pushdown/history.ts +239 -0
  29. package/src/filter-pushdown/index.ts +8 -0
  30. package/src/functions/storage-cf-do.ts +7 -12
  31. package/src/functions/storage.ts +54 -11
  32. package/src/functions/table-buffering.ts +0 -1
  33. package/src/functions/table-in-out.ts +99 -60
  34. package/src/functions/table.ts +41 -38
  35. package/src/functions/types.ts +14 -1
  36. package/src/http/fetch.ts +2 -17
  37. package/src/index.core.ts +1 -0
  38. package/src/protocol/carried-init-request.ts +139 -0
  39. package/src/protocol/dispatch.ts +0 -8
  40. package/src/protocol/handlers/catalog/admin.ts +5 -2
  41. package/src/protocol/handlers/function.ts +18 -15
  42. package/src/protocol/handlers/shared.ts +0 -22
  43. package/src/protocol/state-serializer.ts +109 -37
  44. package/src/util/zstd-sync.ts +50 -0
package/dist/index.js CHANGED
@@ -2008,8 +2008,8 @@ class FunctionStorageCfDo {
2008
2008
  fetch: this._fetch
2009
2009
  });
2010
2010
  }
2011
- async workerPut(executionId, workerId, state) {
2012
- await this._statePutMany(executionId, NS_WORKER, [[int64Key(workerId), state]]);
2011
+ async workerPut(executionId, worker, state) {
2012
+ await this._statePutMany(executionId, NS_WORKER, [[workerStateKey(worker), state]]);
2013
2013
  }
2014
2014
  async workerCollect(executionId) {
2015
2015
  const rows = await this._statePaged("state_drain", executionId, NS_WORKER, newAttemptId());
@@ -2154,11 +2154,6 @@ function newAttemptId() {
2154
2154
  s += b[i].toString(16).padStart(2, "0");
2155
2155
  return s;
2156
2156
  }
2157
- function int64Key(v) {
2158
- const b = new Uint8Array(8);
2159
- new DataView(b.buffer).setBigInt64(0, BigInt(v), false);
2160
- return b;
2161
- }
2162
2157
  function int64FromKey(b) {
2163
2158
  if (b.length !== 8)
2164
2159
  return 0;
@@ -2231,11 +2226,14 @@ function getDefaultDbPath() {
2231
2226
  mkdirSync(stateDir, { recursive: true });
2232
2227
  return join(stateDir, "vgi_storage.db");
2233
2228
  }
2234
- function int64Key2(v) {
2229
+ function int64Key(v) {
2235
2230
  const b = new Uint8Array(8);
2236
2231
  new DataView(b.buffer).setBigInt64(0, BigInt(v), false);
2237
2232
  return b;
2238
2233
  }
2234
+ function workerStateKey(worker) {
2235
+ return typeof worker === "number" ? int64Key(worker) : worker;
2236
+ }
2239
2237
  function int64FromKey2(b) {
2240
2238
  if (b.length !== 8)
2241
2239
  return 0;
@@ -2336,8 +2334,8 @@ class FunctionStorageSqlite {
2336
2334
  total += this._db.prepare("DELETE FROM function_state_log WHERE scope_id = ?").run(eid).changes;
2337
2335
  return total;
2338
2336
  }
2339
- async workerPut(executionId, workerId, state) {
2340
- this._db.prepare("INSERT OR REPLACE INTO function_state (scope_id, ns, key, value) VALUES (?, ?, ?, ?)").run(bufferArg(executionId), bufferArg(NS_WORKER2), bufferArg(int64Key2(workerId)), bufferArg(state));
2337
+ async workerPut(executionId, worker, state) {
2338
+ this._db.prepare("INSERT OR REPLACE INTO function_state (scope_id, ns, key, value) VALUES (?, ?, ?, ?)").run(bufferArg(executionId), bufferArg(NS_WORKER2), bufferArg(workerStateKey(worker)), bufferArg(state));
2341
2339
  }
2342
2340
  async workerCollect(executionId) {
2343
2341
  const rows = this._db.prepare("DELETE FROM function_state WHERE scope_id = ? AND ns = ? RETURNING value").all(bufferArg(executionId), bufferArg(NS_WORKER2));
@@ -2374,12 +2372,14 @@ class FunctionStorageSqlite {
2374
2372
  class BoundStorage {
2375
2373
  _base;
2376
2374
  _executionId;
2377
- constructor(storage, executionId) {
2375
+ _substreamId;
2376
+ constructor(storage, executionId, substreamId = null) {
2378
2377
  this._base = storage;
2379
2378
  this._executionId = executionId;
2379
+ this._substreamId = substreamId;
2380
2380
  }
2381
2381
  put(state) {
2382
- return this._base.workerPut(this._executionId, process.pid, state);
2382
+ return this._base.workerPut(this._executionId, this._substreamId ?? process.pid, state);
2383
2383
  }
2384
2384
  collect() {
2385
2385
  return this._base.workerCollect(this._executionId);
@@ -3808,9 +3808,24 @@ function buildJoinKeysLookup(joinKeyBatches) {
3808
3808
  }
3809
3809
 
3810
3810
  // src/filter-pushdown/evaluate.ts
3811
- function readCell(batch, index, row) {
3812
- const column = batch.getChildAt(index);
3813
- return column ? readCanonicalValue(batch.schema.fields[index].type, column, row) : null;
3811
+ var RESOLVED_COLUMNS = new WeakMap;
3812
+ function resolveColumn(batch, columnName) {
3813
+ let byName = RESOLVED_COLUMNS.get(batch);
3814
+ if (!byName) {
3815
+ byName = new Map;
3816
+ RESOLVED_COLUMNS.set(batch, byName);
3817
+ }
3818
+ let resolved = byName.get(columnName);
3819
+ if (resolved === undefined) {
3820
+ const index = batch.schema.fields.findIndex((field) => field.name === columnName);
3821
+ if (index < 0) {
3822
+ throw new FilterV2Error(`filter column ${columnName} is unavailable in emitted batch`);
3823
+ }
3824
+ const column = batch.getChildAt(index);
3825
+ resolved = column ? { type: batch.schema.fields[index].type, column } : null;
3826
+ byName.set(columnName, resolved);
3827
+ }
3828
+ return resolved;
3814
3829
  }
3815
3830
  function deepEqual(left, right) {
3816
3831
  if (typeof left === "number" && typeof right === "number") {
@@ -4104,11 +4119,8 @@ function evaluateCall(expression, args) {
4104
4119
  function evaluateExpression(expression, batch, row, context) {
4105
4120
  switch (expression.node) {
4106
4121
  case "column_ref": {
4107
- const projectedIndex = batch.schema.fields.findIndex((field) => field.name === expression.columnName);
4108
- if (projectedIndex < 0) {
4109
- throw new FilterV2Error(`filter column ${expression.columnName} is unavailable in emitted batch`);
4110
- }
4111
- return readCell(batch, projectedIndex, row);
4122
+ const resolved = resolveColumn(batch, expression.columnName);
4123
+ return resolved ? readCanonicalValue(resolved.type, resolved.column, row) : null;
4112
4124
  }
4113
4125
  case "field_ref": {
4114
4126
  const parent = evaluateExpression(expression.expression, batch, row, context);
@@ -4242,6 +4254,17 @@ class PushdownFilters {
4242
4254
  applyDelta(batch) {
4243
4255
  return applyFilterDelta(this, batch);
4244
4256
  }
4257
+ withPredicateOrder(order) {
4258
+ const predicates = this.predicates;
4259
+ if (predicates.length === order.length && predicates.every((predicate, i) => predicate.id === order[i])) {
4260
+ return this;
4261
+ }
4262
+ const byId = new Map(predicates.map((predicate) => [predicate.id, predicate]));
4263
+ if (order.length !== byId.size || new Set(order).size !== order.length || !order.every((id) => byId.has(id))) {
4264
+ throw new FilterV2Error("recorded predicate order does not match the replayed filter state");
4265
+ }
4266
+ return new PushdownFilters(order.map((id) => byId.get(id)), this.evaluationContext, this.options, new Map(this.revisions), new Set(this.requiredIds));
4267
+ }
4245
4268
  evaluate(batch) {
4246
4269
  const mask = new Uint8Array(batch.numRows);
4247
4270
  mask.fill(1);
@@ -4346,6 +4369,148 @@ function expressionToSql(expression) {
4346
4369
  return `${filterFunctionIdentityKey(expression.algorithm)}(${expressionToSql(expression.input)})`;
4347
4370
  }
4348
4371
  }
4372
+ // src/filter-pushdown/history.ts
4373
+ init_arrow();
4374
+ var MAX_ENCODED_DELTA_BYTES = 24 << 20;
4375
+ var MAX_DELTA_IPC_BYTES = 17 << 20;
4376
+ var BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
4377
+ var EMPTY_FILTER_HISTORY = Object.freeze({
4378
+ deltas: Object.freeze([]),
4379
+ order: Object.freeze([])
4380
+ });
4381
+ function decodeDynamicFilterMetadata(encoded) {
4382
+ if (new TextEncoder().encode(encoded).byteLength > MAX_ENCODED_DELTA_BYTES) {
4383
+ throw new Error("base64 dynamic filter metadata exceeds the encoded-size limit");
4384
+ }
4385
+ if (encoded.length % 4 !== 0 || !BASE64.test(encoded)) {
4386
+ throw new Error("dynamic filter metadata is not valid base64");
4387
+ }
4388
+ const binary = globalThis.atob ? globalThis.atob(encoded) : Buffer.from(encoded, "base64").toString("binary");
4389
+ const bytes = new Uint8Array(binary.length);
4390
+ for (let i = 0;i < binary.length; i++)
4391
+ bytes[i] = binary.charCodeAt(i);
4392
+ if (bytes.byteLength > MAX_DELTA_IPC_BYTES) {
4393
+ throw new Error("dynamic filter IPC payload exceeds the encoded-size limit");
4394
+ }
4395
+ return bytes;
4396
+ }
4397
+ function decodeFilterDelta(bytes) {
4398
+ if (bytes.byteLength > MAX_DELTA_IPC_BYTES) {
4399
+ throw new Error("dynamic filter IPC payload exceeds the encoded-size limit");
4400
+ }
4401
+ const batch = bytes.byteLength > 0 ? deserializeBatch(bytes) : null;
4402
+ if (!batch || batch.numRows === 0 && batch.schema.fields.length === 0) {
4403
+ throw new Error("dynamic filter metadata must contain one RecordBatch");
4404
+ }
4405
+ return batch;
4406
+ }
4407
+ function deltaRevisionKeys(batch) {
4408
+ const column = batch.getChildAt(0);
4409
+ if (!column)
4410
+ throw new FilterV2Error("delta document has no filter_spec column");
4411
+ const raw = readCanonicalValue(batch.schema.fields[0].type, column, 0);
4412
+ const document = JSON.parse(String(raw));
4413
+ return (document.updates ?? []).map((update) => revisionKey(update.id, update.revision));
4414
+ }
4415
+ function revisionKey(id, revision) {
4416
+ return `${id}\x00${revision}`;
4417
+ }
4418
+ function recordFilterDelta(current, history, deltaBytes) {
4419
+ const incoming = decodeFilterDelta(deltaBytes);
4420
+ const filters = current.applyDelta(incoming);
4421
+ const wanted = new Set;
4422
+ for (const [id, revision] of filters.revisions)
4423
+ wanted.add(revisionKey(id, revision));
4424
+ const deltas = [];
4425
+ const consider = (bytes, batch) => {
4426
+ let carries = false;
4427
+ for (const key of deltaRevisionKeys(batch)) {
4428
+ if (wanted.delete(key))
4429
+ carries = true;
4430
+ }
4431
+ if (carries)
4432
+ deltas.push(bytes);
4433
+ };
4434
+ for (const bytes of history.deltas)
4435
+ consider(bytes, decodeFilterDelta(bytes));
4436
+ consider(deltaBytes, incoming);
4437
+ return { filters, history: { deltas, order: filters.predicates.map((predicate) => predicate.id) } };
4438
+ }
4439
+ var HISTORY_FORMAT_VERSION = 1;
4440
+ var UTF8_ENCODER = new TextEncoder;
4441
+ var UTF8_DECODER = new TextDecoder("utf-8", { fatal: true });
4442
+ function encodeFilterHistory(history) {
4443
+ if (!history || history.deltas.length === 0)
4444
+ return null;
4445
+ const ids = history.order.map((id) => UTF8_ENCODER.encode(id));
4446
+ let size = 1 + 4 + 4;
4447
+ for (const delta of history.deltas)
4448
+ size += 4 + delta.byteLength;
4449
+ for (const id of ids)
4450
+ size += 4 + id.byteLength;
4451
+ const out = new Uint8Array(size);
4452
+ const view = new DataView(out.buffer);
4453
+ let offset = 0;
4454
+ out[offset++] = HISTORY_FORMAT_VERSION;
4455
+ const put = (chunks) => {
4456
+ view.setUint32(offset, chunks.length, true);
4457
+ offset += 4;
4458
+ for (const chunk of chunks) {
4459
+ view.setUint32(offset, chunk.byteLength, true);
4460
+ offset += 4;
4461
+ out.set(chunk, offset);
4462
+ offset += chunk.byteLength;
4463
+ }
4464
+ };
4465
+ put(history.deltas);
4466
+ put(ids);
4467
+ return out;
4468
+ }
4469
+ function decodeFilterHistory(bytes) {
4470
+ if (!bytes || bytes.byteLength === 0)
4471
+ return EMPTY_FILTER_HISTORY;
4472
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
4473
+ let offset = 0;
4474
+ const need = (n) => {
4475
+ if (offset + n > bytes.byteLength)
4476
+ throw new Error("dynamic filter history in the state token is truncated");
4477
+ };
4478
+ need(1);
4479
+ if (bytes[offset++] !== HISTORY_FORMAT_VERSION) {
4480
+ throw new Error("dynamic filter history in the state token has an unknown format");
4481
+ }
4482
+ const take = () => {
4483
+ need(4);
4484
+ const count = view.getUint32(offset, true);
4485
+ offset += 4;
4486
+ const chunks = [];
4487
+ for (let i = 0;i < count; i++) {
4488
+ need(4);
4489
+ const length = view.getUint32(offset, true);
4490
+ offset += 4;
4491
+ need(length);
4492
+ chunks.push(bytes.slice(offset, offset + length));
4493
+ offset += length;
4494
+ }
4495
+ return chunks;
4496
+ };
4497
+ const deltas = take();
4498
+ const order = take().map((id) => UTF8_DECODER.decode(id));
4499
+ if (offset !== bytes.byteLength)
4500
+ throw new Error("dynamic filter history in the state token has trailing bytes");
4501
+ return { deltas, order };
4502
+ }
4503
+ function replayFilterHistory(filters, history) {
4504
+ if (!history || history.deltas.length === 0)
4505
+ return filters;
4506
+ if (!filters)
4507
+ throw new Error("dynamic filter history carried without an initial snapshot");
4508
+ let replayed = filters;
4509
+ for (const bytes of history.deltas)
4510
+ replayed = replayed.applyDelta(decodeFilterDelta(bytes));
4511
+ return replayed.withPredicateOrder(history.order);
4512
+ }
4513
+
4349
4514
  // src/filter-pushdown/collector.ts
4350
4515
  init_arrow();
4351
4516
  function formatPushedFilters(filters) {
@@ -4453,27 +4618,6 @@ class FilteringOutputCollector {
4453
4618
  }
4454
4619
  // src/functions/table.ts
4455
4620
  init_storage();
4456
- function base64Decode(s) {
4457
- if (new TextEncoder().encode(s).byteLength > 24 << 20) {
4458
- throw new Error("base64 dynamic filter metadata exceeds the encoded-size limit");
4459
- }
4460
- if (s.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(s)) {
4461
- throw new Error("dynamic filter metadata is not valid base64");
4462
- }
4463
- const bin = globalThis.atob ? globalThis.atob(s) : Buffer.from(s, "base64").toString("binary");
4464
- const out = new Uint8Array(bin.length);
4465
- for (let i = 0;i < bin.length; i++)
4466
- out[i] = bin.charCodeAt(i);
4467
- if (out.byteLength > 17 << 20)
4468
- throw new Error("dynamic filter IPC payload exceeds the encoded-size limit");
4469
- return out;
4470
- }
4471
- function deserializeFilterBatch(bytes) {
4472
- if (!bytes || bytes.length === 0)
4473
- return null;
4474
- const batch = deserializeBatch(bytes);
4475
- return batch.numRows === 0 && batch.schema.fields.length === 0 ? null : batch;
4476
- }
4477
4621
  function makeProjectingCollector(inner, targetSchema) {
4478
4622
  function alreadyMatches(batch) {
4479
4623
  if (batch.schema.fields.length !== targetSchema.fields.length)
@@ -4654,7 +4798,7 @@ function defineTableFunction(config) {
4654
4798
  opaque_data: null
4655
4799
  };
4656
4800
  },
4657
- createStreamHandlers(request, response) {
4801
+ createStreamHandlers(request, response, filterHistory) {
4658
4802
  const args = extractArgs(request.bind_call);
4659
4803
  const settings = batchToScalarDict(request.bind_call.settings);
4660
4804
  const secrets = batchToSecretDict(request.bind_call.secrets);
@@ -4667,7 +4811,8 @@ function defineTableFunction(config) {
4667
4811
  runtimeAlgorithms: meta.runtimeFilterAlgorithms,
4668
4812
  evaluationContexts: meta.filterEvaluationContexts
4669
4813
  };
4670
- const pushdownFilters = request.pushdown_filters ? deserializeFilters(request.pushdown_filters, filterOptions) : undefined;
4814
+ const carriedFilterHistory = filterHistory ?? EMPTY_FILTER_HISTORY;
4815
+ const pushdownFilters = replayFilterHistory(request.pushdown_filters ? deserializeFilters(request.pushdown_filters, filterOptions) : undefined, carriedFilterHistory);
4671
4816
  const boundStorage = new BoundStorage(storage, response.execution_id);
4672
4817
  const processParams = {
4673
4818
  args,
@@ -4688,7 +4833,11 @@ function defineTableFunction(config) {
4688
4833
  const state = config.initialState ? config.initialState(processParams) : null;
4689
4834
  return {
4690
4835
  outputSchema,
4691
- producerInit: () => ({ state, processParams }),
4836
+ producerInit: () => ({
4837
+ state,
4838
+ processParams,
4839
+ filterHistory: carriedFilterHistory
4840
+ }),
4692
4841
  onTick: (pState, tickMetadata) => {
4693
4842
  if (!tickMetadata)
4694
4843
  return;
@@ -4704,11 +4853,9 @@ function defineTableFunction(config) {
4704
4853
  const current = pState.processParams.pushdownFilters;
4705
4854
  if (!current)
4706
4855
  throw new Error("dynamic filter delta received without an initial snapshot");
4707
- const bytes = base64Decode(encoded);
4708
- const filterBatch = deserializeFilterBatch(bytes);
4709
- if (!filterBatch)
4710
- throw new Error("dynamic filter metadata must contain one RecordBatch");
4711
- pState.processParams.pushdownFilters = current.applyDelta(filterBatch);
4856
+ const recorded = recordFilterDelta(current, pState.filterHistory, decodeDynamicFilterMetadata(encoded));
4857
+ pState.processParams.pushdownFilters = recorded.filters;
4858
+ pState.filterHistory = recorded.history;
4712
4859
  },
4713
4860
  producerFn: async (pState, out) => {
4714
4861
  const current = pState.processParams.pushdownFilters;
@@ -4960,725 +5107,133 @@ function toUint8Array(val) {
4960
5107
  return new Uint8Array(0);
4961
5108
  }
4962
5109
 
4963
- // src/protocol/state-serializer.ts
4964
- var EXCHANGE_STATE_SCHEMA = schema2([
4965
- field2("function_name", binary2(), false),
4966
- field2("init_request", binary2(), false),
4967
- field2("execution_id", binary2(), false),
4968
- field2("max_workers", int642(), false),
4969
- field2("opaque_data", binary2(), true),
4970
- field2("is_producer", bool2(), false),
4971
- field2("user_state", binary2(), true)
4972
- ]);
4973
- var TEXT_ENCODER = new TextEncoder;
4974
- var TEXT_DECODER = new TextDecoder;
4975
- var LIST_CHILD_NAME = "item";
4976
- var emptyListElementType = () => utf82();
4977
- function inferElementType(values) {
4978
- let elementType = null;
4979
- let elementSig = "";
4980
- for (const v of values) {
4981
- if (v === null || v === undefined)
4982
- continue;
4983
- const t = inferFieldType(v);
4984
- const sig = typeSignature(t);
4985
- if (elementType === null) {
4986
- elementType = t;
4987
- elementSig = sig;
4988
- continue;
4989
- }
4990
- if (sig !== elementSig) {
4991
- throw new Error(`inferFieldType: arrays in userState must be homogeneous; ` + `found both '${elementSig}' and '${sig}' in the same array ` + `(split the values into separate fields, or normalize them to one type)`);
4992
- }
5110
+ // src/protocol/carried-init-request.ts
5111
+ init_arrow();
5112
+
5113
+ // src/util/zstd-sync.ts
5114
+ var LEVEL = 3;
5115
+ function resolveZstdSync() {
5116
+ const bun = globalThis.Bun;
5117
+ if (typeof bun?.zstdCompressSync === "function" && typeof bun?.zstdDecompressSync === "function") {
5118
+ return {
5119
+ compress: (data) => new Uint8Array(bun.zstdCompressSync(data, { level: LEVEL })),
5120
+ decompress: (data) => new Uint8Array(bun.zstdDecompressSync(data))
5121
+ };
4993
5122
  }
4994
- return elementType ?? emptyListElementType();
5123
+ let zlib = null;
5124
+ try {
5125
+ zlib = globalThis.process?.getBuiltinModule?.("node:zlib") ?? null;
5126
+ } catch {
5127
+ zlib = null;
5128
+ }
5129
+ if (typeof zlib?.zstdCompressSync === "function" && typeof zlib?.zstdDecompressSync === "function") {
5130
+ const params = { [zlib.constants.ZSTD_c_compressionLevel]: LEVEL };
5131
+ return {
5132
+ compress: (data) => new Uint8Array(zlib.zstdCompressSync(data, { params })),
5133
+ decompress: (data) => new Uint8Array(zlib.zstdDecompressSync(data))
5134
+ };
5135
+ }
5136
+ return null;
4995
5137
  }
4996
- function inferFieldType(value) {
4997
- if (value === null || value === undefined)
4998
- return nullType2();
4999
- switch (typeof value) {
5000
- case "number":
5001
- return float642();
5002
- case "bigint":
5003
- return int642();
5004
- case "string":
5005
- return utf82();
5006
- case "boolean":
5007
- return bool2();
5008
- case "object":
5009
- if (value instanceof Uint8Array || value instanceof ArrayBuffer)
5010
- return binary2();
5011
- if (ArrayBuffer.isView(value))
5012
- return binary2();
5013
- if (Array.isArray(value)) {
5014
- return list2(field2(LIST_CHILD_NAME, inferElementType(value), true));
5015
- }
5016
- if (value instanceof Map) {
5017
- throw new Error(`inferFieldType: Map is not supported in userState (use a plain object instead)`);
5018
- }
5019
- if (value instanceof Set) {
5020
- throw new Error(`inferFieldType: Set is not supported in userState (use an array or plain object instead)`);
5021
- }
5022
- if (value instanceof Date) {
5023
- throw new Error(`inferFieldType: Date is not supported in userState (use a number (epoch ms) or ISO string instead)`);
5138
+ var resolved;
5139
+ function zstdSync() {
5140
+ if (resolved === undefined)
5141
+ resolved = resolveZstdSync();
5142
+ return resolved;
5143
+ }
5144
+
5145
+ // src/protocol/serializers/arguments.ts
5146
+ init_arrow();
5147
+ init_registry();
5148
+
5149
+ // src/arguments/arguments.ts
5150
+ class Arguments {
5151
+ positional;
5152
+ named;
5153
+ argumentsSchema;
5154
+ constructor(positional = [], named = new Map, argumentsSchema = null) {
5155
+ this.positional = positional;
5156
+ this.named = named;
5157
+ this.argumentsSchema = argumentsSchema;
5158
+ }
5159
+ get(position, defaultValue) {
5160
+ if (typeof position === "number") {
5161
+ if (position < this.positional.length) {
5162
+ const val = this.positional[position];
5163
+ if (val === null || val === undefined) {
5164
+ return defaultValue !== undefined ? defaultValue : null;
5165
+ }
5166
+ return unwrapScalar(val);
5024
5167
  }
5025
- if (value instanceof RegExp) {
5026
- throw new Error(`inferFieldType: RegExp is not supported in userState (use a string pattern instead)`);
5168
+ if (defaultValue !== undefined)
5169
+ return defaultValue;
5170
+ throw new Error(`Positional argument ${position} not found`);
5171
+ }
5172
+ if (this.named.has(position)) {
5173
+ const val = this.named.get(position);
5174
+ if (val === null || val === undefined) {
5175
+ return defaultValue !== undefined ? defaultValue : null;
5027
5176
  }
5028
- const fields = Object.entries(value).map(([k, v]) => field2(k, inferFieldType(v), true));
5029
- return struct2(fields);
5030
- default:
5031
- throw new Error(`inferFieldType: unsupported type '${typeof value}'`);
5177
+ return unwrapScalar(val);
5178
+ }
5179
+ if (defaultValue !== undefined)
5180
+ return defaultValue;
5181
+ throw new Error(`Named argument '${position}' not found`);
5182
+ }
5183
+ get length() {
5184
+ return this.positional.length;
5032
5185
  }
5033
5186
  }
5034
- function serializeUserState(userState) {
5035
- if (userState == null)
5187
+ function unwrapScalar(val) {
5188
+ if (val === null || val === undefined)
5036
5189
  return null;
5037
- const entries = Object.entries(userState);
5038
- if (entries.length === 0) {
5039
- return serializeBatch(batchFromColumns({}, schema2([])));
5040
- }
5041
- const fields = entries.map(([k, v]) => field2(k, inferFieldType(v), true));
5042
- const sch = schema2(fields);
5043
- const columns = {};
5044
- for (const [key, val] of entries) {
5045
- columns[key] = [val];
5190
+ if (typeof val !== "object")
5191
+ return val;
5192
+ if (typeof val.valueOf === "function") {
5193
+ let v;
5194
+ try {
5195
+ v = val.valueOf();
5196
+ } catch {
5197
+ return val;
5198
+ }
5199
+ if (typeof v === "bigint") {
5200
+ if (v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) {
5201
+ return Number(v);
5202
+ }
5203
+ return v;
5204
+ }
5205
+ return v;
5046
5206
  }
5047
- return serializeBatch(batchFromColumns(columns, sch));
5048
- }
5049
- function extractTypedValue(col, index, type) {
5050
- return codecFor(type).canonicalToRich(readCanonicalValue(type, col, index));
5207
+ return val;
5051
5208
  }
5052
- function deserializeUserState(bytes) {
5053
- if (bytes == null)
5054
- return null;
5055
- const batch = deserializeBatch(bytes);
5056
- if (batch.numRows === 0 && batch.schema.fields.length === 0) {
5057
- return {};
5209
+
5210
+ // src/protocol/serializers/arguments.ts
5211
+ function serializeArguments(args) {
5212
+ const structFields = [];
5213
+ const structValues = {};
5214
+ for (let i = 0;i < args.positional.length; i++) {
5215
+ const val = args.positional[i];
5216
+ const fieldName = `positional_${i}`;
5217
+ structFields.push(field2(fieldName, inferScalarType(val), true));
5218
+ structValues[fieldName] = val;
5058
5219
  }
5059
- if (batch.numRows === 0)
5060
- return null;
5061
- const result = {};
5062
- for (const f of batch.schema.fields) {
5063
- const col = batch.getChild(f.name);
5064
- if (!col) {
5065
- result[f.name] = null;
5066
- continue;
5220
+ for (const [name, val] of args.named) {
5221
+ const fieldName = `named_${name}`;
5222
+ structFields.push(field2(fieldName, inferScalarType(val), true));
5223
+ structValues[fieldName] = val;
5224
+ }
5225
+ const structType = struct2(structFields);
5226
+ const sch = schema2([field2("args", structType, true)]);
5227
+ const structRow = {};
5228
+ for (const f of structFields) {
5229
+ let val = structValues[f.name];
5230
+ if (isInt(f.type) && f.type.bitWidth === 64 && typeof val === "number") {
5231
+ val = BigInt(val);
5067
5232
  }
5068
- result[f.name] = extractTypedValue(col, 0, f.type);
5233
+ structRow[f.name] = val;
5069
5234
  }
5070
- return result;
5071
- }
5072
- var arrowStateSerializer = {
5073
- serialize(state) {
5074
- const columns = {
5075
- function_name: [TEXT_ENCODER.encode(state.functionName)],
5076
- init_request: [state.initRequestIpc],
5077
- execution_id: [state.executionId],
5078
- max_workers: [state.maxWorkers],
5079
- opaque_data: [state.opaqueData ?? null],
5080
- is_producer: [state.isProducer],
5081
- user_state: [serializeUserState(state.userState)]
5082
- };
5083
- const batch = batchFromColumns(columns, EXCHANGE_STATE_SCHEMA);
5084
- return serializeBatch(batch);
5085
- },
5086
- deserialize(bytes) {
5087
- const batch = deserializeBatch(bytes);
5088
- const fieldByName = new Map(batch.schema.fields.map((f) => [f.name, f]));
5089
- const get = (name) => {
5090
- const col = batch.getChild(name);
5091
- const f = fieldByName.get(name);
5092
- if (!col || !f)
5093
- return null;
5094
- const type = f.type;
5095
- return codecFor(type).canonicalToRich(readCanonicalValue(type, col, 0));
5096
- };
5097
- const isProducer = get("is_producer");
5098
- const opaqueDataRaw = get("opaque_data");
5099
- const fnNameRaw = get("function_name");
5100
- return {
5101
- functionName: fnNameRaw != null ? TEXT_DECODER.decode(toUint8Array(fnNameRaw)) : "",
5102
- initRequestIpc: toUint8Array(get("init_request")),
5103
- executionId: toUint8Array(get("execution_id")),
5104
- maxWorkers: Number(get("max_workers")),
5105
- opaqueData: opaqueDataRaw != null ? toUint8Array(opaqueDataRaw) : null,
5106
- isProducer,
5107
- __isProducer: isProducer,
5108
- userState: deserializeUserState(get("user_state") != null ? toUint8Array(get("user_state")) : null)
5109
- };
5110
- }
5111
- };
5112
-
5113
- // src/functions/table-in-out.ts
5114
- var STREAMING_FINALIZE_KEY = new Uint8Array(0);
5115
- function defineTableInOutFunction(config) {
5116
- assertArrowTypes(config.args, `defineTableInOutFunction("${config.name}"): args`);
5117
- const specs = [];
5118
- let posIdx = 0;
5119
- if (config.args) {
5120
- for (const [name, type] of Object.entries(config.args)) {
5121
- specs.push({
5122
- name,
5123
- position: posIdx++,
5124
- arrowType: type,
5125
- doc: config.argDocs?.[name],
5126
- ...constraintSpecFields(config.argConstraints?.[name], config.argDefaults?.[name])
5127
- });
5128
- }
5129
- }
5130
- specs.push({
5131
- name: "data",
5132
- position: posIdx++,
5133
- arrowType: nullType2(),
5134
- isTableInput: true
5135
- });
5136
- if (config.namedArgs) {
5137
- for (const [name, type] of Object.entries(config.namedArgs)) {
5138
- specs.push({
5139
- name,
5140
- position: name,
5141
- arrowType: type,
5142
- doc: config.argDocs?.[name],
5143
- ...constraintSpecFields(config.argConstraints?.[name], config.argDefaults?.[name])
5144
- });
5145
- }
5146
- }
5147
- const meta = {
5148
- name: config.name,
5149
- description: config.description,
5150
- stability: config.stability,
5151
- projectionPushdown: config.projectionPushdown,
5152
- filterPushdown: config.filterPushdown,
5153
- autoApplyFilters: config.autoApplyFilters,
5154
- examples: config.examples,
5155
- categories: config.categories,
5156
- tags: config.tags,
5157
- parameterDefaultValues: config.parameterDefaultValues,
5158
- maxWorkers: config.maxWorkers,
5159
- requiredSettings: config.requiredSettings,
5160
- requiredSecrets: config.requiredSecrets,
5161
- hasFinalize: !!config.finalize
5162
- };
5163
- function extractArgs(request) {
5164
- const args = {};
5165
- for (const spec of specs) {
5166
- if (spec.isTableInput)
5167
- continue;
5168
- const defaultVal = config.argDefaults?.[spec.name] !== undefined ? config.argDefaults[spec.name] : undefined;
5169
- let val = request.arguments.get(spec.position, defaultVal);
5170
- val = narrowArgValue(val);
5171
- const constraints = config.argConstraints?.[spec.name];
5172
- if (constraints)
5173
- validateConstConstraints(spec.name, constraints, val);
5174
- args[spec.name] = val;
5175
- }
5176
- return args;
5177
- }
5178
- return {
5179
- kind: "table_in_out",
5180
- meta,
5181
- argumentSpecs: specs,
5182
- async bind(request) {
5183
- if (config.onBind) {
5184
- const args = extractArgs(request);
5185
- const settings = batchToScalarDict(request.settings);
5186
- const secrets = batchToSecretDict(request.secrets);
5187
- const result = await config.onBind({
5188
- args,
5189
- bindCall: request,
5190
- settings,
5191
- secrets,
5192
- argumentNames: request.argument_names ?? null
5193
- });
5194
- return {
5195
- output_schema: result.outputSchema,
5196
- opaque_data: result.opaqueData ?? null
5197
- };
5198
- }
5199
- return {
5200
- output_schema: request.input_schema ?? schema2([]),
5201
- opaque_data: null
5202
- };
5203
- },
5204
- async globalInit(request) {
5205
- const executionId = new Uint8Array(16);
5206
- crypto.getRandomValues(executionId);
5207
- if (request.execution_id) {
5208
- return {
5209
- max_workers: DEFAULT_MAX_WORKERS,
5210
- execution_id: request.execution_id,
5211
- opaque_data: null
5212
- };
5213
- }
5214
- if (config.onInit) {
5215
- const args = extractArgs(request.bind_call);
5216
- return await config.onInit({
5217
- args,
5218
- initCall: request,
5219
- outputSchema: request.output_schema,
5220
- executionId
5221
- });
5222
- }
5223
- return {
5224
- max_workers: config.maxWorkers ?? 1,
5225
- execution_id: executionId,
5226
- opaque_data: null
5227
- };
5228
- },
5229
- createStreamHandlers(request, response, accumulatedState) {
5230
- const args = extractArgs(request.bind_call);
5231
- const settings = batchToScalarDict(request.bind_call.settings);
5232
- const secrets = batchToSecretDict(request.bind_call.secrets);
5233
- const projIds = request.projection_ids && meta.projectionPushdown ? request.projection_ids : null;
5234
- const outputSchema = projIds ? projectSchema(projIds, request.output_schema) : request.output_schema;
5235
- const pushdownFilters = request.pushdown_filters ? deserializeFilters(request.pushdown_filters, {
5236
- outputSchema: request.output_schema,
5237
- joinKeyBatches: request.join_keys,
5238
- extensionFunctions: meta.additionalFilterFunctions,
5239
- runtimeAlgorithms: meta.runtimeFilterAlgorithms,
5240
- evaluationContexts: meta.filterEvaluationContexts
5241
- }) : undefined;
5242
- const boundStorage = new BoundStorage(storage, response.execution_id ?? new Uint8Array(16));
5243
- const processParams = {
5244
- args,
5245
- initCall: request,
5246
- initResponse: response,
5247
- outputSchema,
5248
- settings,
5249
- secrets,
5250
- pushdownFilters,
5251
- storage: boundStorage,
5252
- substreamId: request.substream_id ?? null
5253
- };
5254
- const phase = request.phase;
5255
- if (phase === "FINALIZE" /* FINALIZE */) {
5256
- const finalizeLogKey = STREAMING_FINALIZE_KEY;
5257
- return {
5258
- outputSchema,
5259
- producerInit: () => ({ state: { cursor: -1, materialized: false } }),
5260
- producerFn: async (pState, out) => {
5261
- if (!pState.state.materialized) {
5262
- const finalizeStates = [];
5263
- if (accumulatedState != null) {
5264
- finalizeStates.push(accumulatedState);
5265
- }
5266
- const stored = await boundStorage.collect();
5267
- for (const bytes of stored) {
5268
- finalizeStates.push(deserializeUserState(bytes));
5269
- }
5270
- if (finalizeStates.length === 0) {
5271
- finalizeStates.push(config.initialState ? config.initialState(processParams) : null);
5272
- }
5273
- const batches = config.finalize ? await config.finalize(processParams, finalizeStates) : [];
5274
- for (const batch of batches) {
5275
- await boundStorage.stateAppend(FrameworkNS.STREAMING_FINALIZE, finalizeLogKey, serializeBatch(batch));
5276
- }
5277
- pState.state.materialized = true;
5278
- }
5279
- const rows = await boundStorage.stateLogScan(FrameworkNS.STREAMING_FINALIZE, finalizeLogKey, pState.state.cursor, 1);
5280
- if (rows.length === 0) {
5281
- out.finish();
5282
- return;
5283
- }
5284
- const [logId, bytes] = rows[0];
5285
- out.emit(deserializeBatch(bytes));
5286
- pState.state.cursor = logId;
5287
- }
5288
- };
5289
- }
5290
- if (request.bind_call.input_schema == null) {
5291
- throw new Error(`${config.name}: is a table-in-out function (it requires an input row ` + `stream) but no input schema was supplied -- call it via ` + `table_in_out_function(input=...), not table_function().`);
5292
- }
5293
- const state = config.initialState ? config.initialState(processParams) : null;
5294
- const processFn = config.process ?? ((_params, _state, batch, out) => {
5295
- out.emit(projIds ? projectBatch(projIds, batch) : batch);
5296
- });
5297
- return {
5298
- outputSchema,
5299
- inputSchema: request.bind_call.input_schema,
5300
- exchangeInit: () => ({ state, processParams }),
5301
- exchangeFn: async (eState, input, out) => {
5302
- applyRevalidationValidators(eState.processParams, input);
5303
- applyDynamicFilterUpdate(eState.processParams, input);
5304
- let wrappedOut = makeMetadataBakingCollector(out);
5305
- if (projIds) {
5306
- wrappedOut = makeSchemaReconcilingCollector(wrappedOut, outputSchema);
5307
- }
5308
- const currentFilters = eState.processParams.pushdownFilters;
5309
- if (config.autoApplyFilters && currentFilters) {
5310
- wrappedOut = new FilteringOutputCollector(wrappedOut, currentFilters);
5311
- }
5312
- await processFn(eState.processParams, eState.state, input, wrappedOut);
5313
- if (eState.state != null) {
5314
- const serialized = serializeUserState(eState.state);
5315
- if (serialized != null) {
5316
- await boundStorage.put(serialized);
5317
- }
5318
- }
5319
- }
5320
- };
5321
- }
5322
- };
5323
- }
5324
- function applyRevalidationValidators(params, input) {
5325
- const md = input?.metadata;
5326
- params.ifNoneMatch = md?.get(CACHE_IF_NONE_MATCH_KEY);
5327
- params.ifModifiedSince = md?.get(CACHE_IF_MODIFIED_SINCE_KEY);
5328
- }
5329
- function applyDynamicFilterUpdate(params, input) {
5330
- const encoded = input?.metadata?.get("vgi_pushdown_filters");
5331
- if (!encoded)
5332
- return;
5333
- if (!params.pushdownFilters)
5334
- throw new Error("dynamic filter delta received without an initial snapshot");
5335
- if (new TextEncoder().encode(encoded).byteLength > 24 << 20) {
5336
- throw new Error("base64 dynamic filter metadata exceeds the encoded-size limit");
5337
- }
5338
- if (encoded.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(encoded)) {
5339
- throw new Error("dynamic filter metadata is not valid base64");
5340
- }
5341
- const binary = globalThis.atob ? globalThis.atob(encoded) : Buffer.from(encoded, "base64").toString("binary");
5342
- const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
5343
- if (bytes.byteLength > 17 << 20)
5344
- throw new Error("dynamic filter IPC payload exceeds the encoded-size limit");
5345
- const current = params.pushdownFilters;
5346
- params.pushdownFilters = current.applyDelta(deserializeBatch(bytes));
5347
- }
5348
- function makeMetadataBakingCollector(inner) {
5349
- return new Proxy(inner, {
5350
- get(target, prop, receiver) {
5351
- if (prop === "emit") {
5352
- return function(batchOrColumns, metadata) {
5353
- if (batchOrColumns && typeof batchOrColumns.getChild === "function" && metadata && metadata.size > 0) {
5354
- const batch = batchOrColumns;
5355
- const merged = new Map(batch.metadata ?? []);
5356
- for (const [k, v] of metadata)
5357
- merged.set(k, v);
5358
- return target.emit(withBatchMetadata(batch, merged), merged);
5359
- }
5360
- return target.emit(batchOrColumns, metadata);
5361
- };
5362
- }
5363
- const v = Reflect.get(target, prop, receiver);
5364
- return typeof v === "function" ? v.bind(target) : v;
5365
- }
5366
- });
5367
- }
5368
- function makeSchemaReconcilingCollector(inner, targetSchema) {
5369
- function reconcile(batch) {
5370
- const batchFields = batch.schema.fields;
5371
- if (batchFields.length === targetSchema.fields.length && targetSchema.fields.every((f, i) => batchFields[i].name === f.name)) {
5372
- return batch;
5373
- }
5374
- const ids = [];
5375
- for (const f of targetSchema.fields) {
5376
- const idx = batchFields.findIndex((bf) => bf.name === f.name);
5377
- if (idx < 0) {
5378
- throw new Error(`emitted batch is missing projected output column '${f.name}' ` + `(emitted: [${batchFields.map((bf) => bf.name).join(", ")}])`);
5379
- }
5380
- ids.push(idx);
5381
- }
5382
- return projectBatch(ids, batch);
5383
- }
5384
- return new Proxy(inner, {
5385
- get(target, prop, receiver) {
5386
- if (prop === "emit") {
5387
- return function(batchOrColumns, metadata) {
5388
- if (batchOrColumns && typeof batchOrColumns.getChild === "function") {
5389
- return target.emit(reconcile(batchOrColumns), metadata);
5390
- }
5391
- return target.emit(batchOrColumns, metadata);
5392
- };
5393
- }
5394
- const v = Reflect.get(target, prop, receiver);
5395
- return typeof v === "function" ? v.bind(target) : v;
5396
- }
5397
- });
5398
- }
5399
- var PARENT_ROW_METADATA_KEY = "vgi_rpc.parent_row#b64";
5400
- function parentRowsMetadata(parentRows, outputRows, extra) {
5401
- if (parentRows.length !== outputRows) {
5402
- throw new Error(`parentRowsMetadata: length ${parentRows.length} != output rows ${outputRows}; ` + `parentRows must carry exactly one input-row index per emitted output row`);
5403
- }
5404
- const md = new Map(extra ?? []);
5405
- if (outputRows === 0) {
5406
- return md;
5407
- }
5408
- const raw = new Uint8Array(parentRows.length * 4);
5409
- const dv = new DataView(raw.buffer);
5410
- for (let i = 0;i < parentRows.length; i++) {
5411
- dv.setInt32(i * 4, parentRows[i], true);
5412
- }
5413
- md.set(PARENT_ROW_METADATA_KEY, base64Encode(raw));
5414
- return md;
5415
- }
5416
- function base64Encode(bytes) {
5417
- if (typeof globalThis.Buffer !== "undefined") {
5418
- return globalThis.Buffer.from(bytes).toString("base64");
5419
- }
5420
- let bin = "";
5421
- for (let i = 0;i < bytes.length; i++)
5422
- bin += String.fromCharCode(bytes[i]);
5423
- return globalThis.btoa(bin);
5424
- }
5425
- function defineRowTransformFunction(config) {
5426
- const numPositional = Object.keys(config.args ?? {}).length + (config.varargs ? 1 : 0);
5427
- if (numPositional === 0) {
5428
- throw new Error(`${config.name}: a blended row-transform function needs at least one ` + `positional arg (its per-row input column); found none.`);
5429
- }
5430
- const specs = [];
5431
- let posIdx = 0;
5432
- if (config.args) {
5433
- for (const [name, type] of Object.entries(config.args)) {
5434
- specs.push({
5435
- name,
5436
- position: posIdx++,
5437
- arrowType: type,
5438
- doc: config.argDocs?.[name],
5439
- ...constraintSpecFields(config.argConstraints?.[name])
5440
- });
5441
- }
5442
- }
5443
- if (config.varargs) {
5444
- specs.push({
5445
- name: config.varargs.name,
5446
- position: posIdx++,
5447
- arrowType: config.varargs.type,
5448
- isVarargs: true,
5449
- doc: config.varargs.doc ?? config.argDocs?.[config.varargs.name],
5450
- ...constraintSpecFields(config.argConstraints?.[config.varargs.name])
5451
- });
5452
- }
5453
- if (config.namedArgs) {
5454
- for (const [name, type] of Object.entries(config.namedArgs)) {
5455
- specs.push({
5456
- name,
5457
- position: name,
5458
- arrowType: type,
5459
- doc: config.argDocs?.[name],
5460
- ...constraintSpecFields(config.argConstraints?.[name], config.argDefaults?.[name])
5461
- });
5462
- }
5463
- }
5464
- const meta = {
5465
- name: config.name,
5466
- description: config.description,
5467
- stability: config.stability,
5468
- projectionPushdown: config.projectionPushdown,
5469
- filterPushdown: config.filterPushdown,
5470
- autoApplyFilters: config.autoApplyFilters,
5471
- examples: config.examples,
5472
- categories: config.categories,
5473
- tags: config.tags,
5474
- parameterDefaultValues: config.parameterDefaultValues,
5475
- maxWorkers: config.maxWorkers,
5476
- requiredSettings: config.requiredSettings,
5477
- requiredSecrets: config.requiredSecrets,
5478
- hasFinalize: false,
5479
- inputFromArgs: true
5480
- };
5481
- function extractArgs(request) {
5482
- const args = {};
5483
- for (const spec of specs) {
5484
- if (typeof spec.position !== "string")
5485
- continue;
5486
- const defaultVal = config.argDefaults?.[spec.name] !== undefined ? config.argDefaults[spec.name] : undefined;
5487
- let val = request.arguments.get(spec.position, defaultVal ?? null);
5488
- val = narrowArgValue(val);
5489
- const constraints = config.argConstraints?.[spec.name];
5490
- if (constraints)
5491
- validateConstConstraints(spec.name, constraints, val);
5492
- args[spec.name] = val;
5493
- }
5494
- return args;
5495
- }
5496
- return {
5497
- kind: "table_in_out",
5498
- meta,
5499
- argumentSpecs: specs,
5500
- async bind(request) {
5501
- const args = extractArgs(request);
5502
- const settings = batchToScalarDict(request.settings);
5503
- const secrets = batchToSecretDict(request.secrets);
5504
- const result = await config.onBind({
5505
- args,
5506
- bindCall: request,
5507
- settings,
5508
- secrets,
5509
- argumentNames: request.argument_names ?? null
5510
- });
5511
- return {
5512
- output_schema: result.outputSchema,
5513
- opaque_data: result.opaqueData ?? null
5514
- };
5515
- },
5516
- async globalInit(request) {
5517
- if (request.execution_id) {
5518
- return {
5519
- max_workers: DEFAULT_MAX_WORKERS,
5520
- execution_id: request.execution_id,
5521
- opaque_data: null
5522
- };
5523
- }
5524
- const executionId = new Uint8Array(16);
5525
- crypto.getRandomValues(executionId);
5526
- return {
5527
- max_workers: config.maxWorkers ?? 1,
5528
- execution_id: executionId,
5529
- opaque_data: null
5530
- };
5531
- },
5532
- createStreamHandlers(request, response, _accumulatedState) {
5533
- const args = extractArgs(request.bind_call);
5534
- const settings = batchToScalarDict(request.bind_call.settings);
5535
- const secrets = batchToSecretDict(request.bind_call.secrets);
5536
- const projIds = request.projection_ids && meta.projectionPushdown ? request.projection_ids : null;
5537
- const outputSchema = projIds ? projectSchema(projIds, request.output_schema) : request.output_schema;
5538
- const pushdownFilters = request.pushdown_filters ? deserializeFilters(request.pushdown_filters, {
5539
- outputSchema: request.output_schema,
5540
- joinKeyBatches: request.join_keys,
5541
- extensionFunctions: meta.additionalFilterFunctions,
5542
- runtimeAlgorithms: meta.runtimeFilterAlgorithms,
5543
- evaluationContexts: meta.filterEvaluationContexts
5544
- }) : undefined;
5545
- const boundStorage = new BoundStorage(storage, response.execution_id ?? new Uint8Array(16));
5546
- const processParams = {
5547
- args,
5548
- initCall: request,
5549
- initResponse: response,
5550
- outputSchema,
5551
- settings,
5552
- secrets,
5553
- pushdownFilters,
5554
- storage: boundStorage,
5555
- substreamId: request.substream_id ?? null
5556
- };
5557
- if (request.phase === "FINALIZE" /* FINALIZE */) {
5558
- throw new Error(`${config.name}: a blended row-transform function has no FINALIZE ` + `phase (it is a per-row map; has_finalize is advertised false).`);
5559
- }
5560
- if (request.bind_call.input_schema == null) {
5561
- throw new Error(`${config.name}: is a table-in-out function (its positional args are ` + `per-row input columns) but no input schema was supplied -- call it ` + `via table_in_out_function(input=...), not table_function().`);
5562
- }
5563
- return {
5564
- outputSchema,
5565
- inputSchema: request.bind_call.input_schema,
5566
- exchangeInit: () => ({ state: null, processParams }),
5567
- exchangeFn: async (eState, input, out) => {
5568
- applyRevalidationValidators(eState.processParams, input);
5569
- applyDynamicFilterUpdate(eState.processParams, input);
5570
- let wrappedOut = makeMetadataBakingCollector(out);
5571
- if (projIds) {
5572
- wrappedOut = makeSchemaReconcilingCollector(wrappedOut, outputSchema);
5573
- }
5574
- const currentFilters = eState.processParams.pushdownFilters;
5575
- if (config.autoApplyFilters && currentFilters) {
5576
- wrappedOut = new FilteringOutputCollector(wrappedOut, currentFilters);
5577
- }
5578
- await config.process(eState.processParams, input, wrappedOut);
5579
- }
5580
- };
5581
- }
5582
- };
5583
- }
5584
- // src/functions/table-buffering.ts
5585
- init_arrow();
5586
- init_arrow();
5587
- init_registry();
5588
- init_storage();
5589
-
5590
- // src/protocol/serializers/arguments.ts
5591
- init_arrow();
5592
- init_registry();
5593
-
5594
- // src/arguments/arguments.ts
5595
- class Arguments {
5596
- positional;
5597
- named;
5598
- argumentsSchema;
5599
- constructor(positional = [], named = new Map, argumentsSchema = null) {
5600
- this.positional = positional;
5601
- this.named = named;
5602
- this.argumentsSchema = argumentsSchema;
5603
- }
5604
- get(position, defaultValue) {
5605
- if (typeof position === "number") {
5606
- if (position < this.positional.length) {
5607
- const val = this.positional[position];
5608
- if (val === null || val === undefined) {
5609
- return defaultValue !== undefined ? defaultValue : null;
5610
- }
5611
- return unwrapScalar(val);
5612
- }
5613
- if (defaultValue !== undefined)
5614
- return defaultValue;
5615
- throw new Error(`Positional argument ${position} not found`);
5616
- }
5617
- if (this.named.has(position)) {
5618
- const val = this.named.get(position);
5619
- if (val === null || val === undefined) {
5620
- return defaultValue !== undefined ? defaultValue : null;
5621
- }
5622
- return unwrapScalar(val);
5623
- }
5624
- if (defaultValue !== undefined)
5625
- return defaultValue;
5626
- throw new Error(`Named argument '${position}' not found`);
5627
- }
5628
- get length() {
5629
- return this.positional.length;
5630
- }
5631
- }
5632
- function unwrapScalar(val) {
5633
- if (val === null || val === undefined)
5634
- return null;
5635
- if (typeof val !== "object")
5636
- return val;
5637
- if (typeof val.valueOf === "function") {
5638
- let v;
5639
- try {
5640
- v = val.valueOf();
5641
- } catch {
5642
- return val;
5643
- }
5644
- if (typeof v === "bigint") {
5645
- if (v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) {
5646
- return Number(v);
5647
- }
5648
- return v;
5649
- }
5650
- return v;
5651
- }
5652
- return val;
5653
- }
5654
-
5655
- // src/protocol/serializers/arguments.ts
5656
- function serializeArguments(args) {
5657
- const structFields = [];
5658
- const structValues = {};
5659
- for (let i = 0;i < args.positional.length; i++) {
5660
- const val = args.positional[i];
5661
- const fieldName = `positional_${i}`;
5662
- structFields.push(field2(fieldName, inferScalarType(val), true));
5663
- structValues[fieldName] = val;
5664
- }
5665
- for (const [name, val] of args.named) {
5666
- const fieldName = `named_${name}`;
5667
- structFields.push(field2(fieldName, inferScalarType(val), true));
5668
- structValues[fieldName] = val;
5669
- }
5670
- const structType = struct2(structFields);
5671
- const sch = schema2([field2("args", structType, true)]);
5672
- const structRow = {};
5673
- for (const f of structFields) {
5674
- let val = structValues[f.name];
5675
- if (isInt(f.type) && f.type.bitWidth === 64 && typeof val === "number") {
5676
- val = BigInt(val);
5677
- }
5678
- structRow[f.name] = val;
5679
- }
5680
- const batch = batchFromColumns({ args: [structRow] }, sch);
5681
- return serializeBatch(batch);
5235
+ const batch = batchFromColumns({ args: [structRow] }, sch);
5236
+ return serializeBatch(batch);
5682
5237
  }
5683
5238
  function inferScalarType(val) {
5684
5239
  if (val === null || val === undefined)
@@ -5901,229 +5456,959 @@ function serializeBindResponse(resp) {
5901
5456
  lookup_names: resp.lookup_names ?? []
5902
5457
  };
5903
5458
  }
5904
- function deserializeBindResponse(params) {
5905
- const toStrArray = (val) => {
5906
- if (!val)
5907
- return [];
5908
- const arr = Array.isArray(val) ? val : [...val];
5909
- return arr.filter((v) => v != null).map(String);
5910
- };
5459
+ function deserializeBindResponse(params) {
5460
+ const toStrArray = (val) => {
5461
+ if (!val)
5462
+ return [];
5463
+ const arr = Array.isArray(val) ? val : [...val];
5464
+ return arr.filter((v) => v != null).map(String);
5465
+ };
5466
+ return {
5467
+ output_schema: deserializeSchema(toUint8Array2(params.output_schema)),
5468
+ opaque_data: params.opaque_data ? toUint8Array2(params.opaque_data) : null,
5469
+ lookup_secret_types: toStrArray(params.lookup_secret_types),
5470
+ lookup_scopes: toStrArray(params.lookup_scopes),
5471
+ lookup_names: toStrArray(params.lookup_names)
5472
+ };
5473
+ }
5474
+ // src/protocol/serializers/init.ts
5475
+ init_arrow();
5476
+ var INIT_REQUEST_SCHEMA = schema2([
5477
+ field2("bind_call", binary2(), false),
5478
+ field2("output_schema", binary2(), false),
5479
+ field2("bind_opaque_data", binary2(), true),
5480
+ field2("projection_ids", list2(field2("item", int642(), true)), true),
5481
+ field2("pushdown_filters", largeBinary2(), true),
5482
+ field2("join_keys", list2(field2("item", largeBinary2(), true)), true),
5483
+ field2("split_tokens", list2(field2("item", largeBinary2(), true)), true),
5484
+ field2("row_limit", int642(), true),
5485
+ field2("phase", dictionary2(utf82(), int162()), true),
5486
+ field2("finalize_state_id", binary2(), true),
5487
+ field2("execution_id", binary2(), true),
5488
+ field2("init_opaque_data", binary2(), true),
5489
+ field2("substream_id", binary2(), true),
5490
+ field2("order_by_column_name", utf82(), true),
5491
+ field2("order_by_direction", dictionary2(utf82(), int162()), true),
5492
+ field2("order_by_null_order", dictionary2(utf82(), int162()), true),
5493
+ field2("order_by_limit", int642(), true),
5494
+ field2("tablesample_percentage", float642(), true),
5495
+ field2("tablesample_seed", int642(), true)
5496
+ ]);
5497
+ var GLOBAL_INIT_RESPONSE_SCHEMA = schema2([
5498
+ field2("execution_id", binary2(), false),
5499
+ field2("opaque_data", binary2(), true),
5500
+ field2("max_workers", int642(), false)
5501
+ ]);
5502
+ function serializeInitRequest(req) {
5503
+ const bindCallBatch = serializeBindRequest(req.bind_call);
5504
+ const bindCallBytes = serializeBatch(bindCallBatch);
5505
+ const row = {
5506
+ bind_call: bindCallBytes,
5507
+ output_schema: serializeSchema(req.output_schema),
5508
+ bind_opaque_data: req.bind_opaque_data ?? null,
5509
+ projection_ids: req.projection_ids?.map((n) => BigInt(n)) ?? null,
5510
+ pushdown_filters: req.pushdown_filters ? serializeBatch(req.pushdown_filters) : null,
5511
+ join_keys: (req.join_keys ?? []).map((b) => serializeBatch(b)),
5512
+ split_tokens: req.split_tokens ?? null,
5513
+ row_limit: req.row_limit ?? null,
5514
+ phase: req.phase ?? null,
5515
+ finalize_state_id: req.finalize_state_id ?? null,
5516
+ execution_id: req.execution_id ?? null,
5517
+ init_opaque_data: req.init_opaque_data ?? null,
5518
+ substream_id: req.substream_id ?? null,
5519
+ order_by_column_name: req.order_by_column_name ?? null,
5520
+ order_by_direction: req.order_by_direction ?? null,
5521
+ order_by_null_order: req.order_by_null_order ?? null,
5522
+ order_by_limit: req.order_by_limit ?? null,
5523
+ tablesample_percentage: req.tablesample_percentage ?? null,
5524
+ tablesample_seed: req.tablesample_seed ?? null
5525
+ };
5526
+ return buildSingleRowBatch(INIT_REQUEST_SCHEMA, row);
5527
+ }
5528
+ function deserializeInitRequest(params) {
5529
+ const bindCallBytes = toUint8Array2(params.bind_call);
5530
+ const bindCallBatch = deserializeBatch(bindCallBytes);
5531
+ const bindParams = batchToScalarDict(bindCallBatch);
5532
+ const bindCall = deserializeBindRequest(bindParams);
5533
+ let projectionIds = null;
5534
+ if (params.projection_ids != null) {
5535
+ const raw = params.projection_ids;
5536
+ if (Array.isArray(raw)) {
5537
+ projectionIds = raw.map(Number);
5538
+ } else if (raw && typeof raw[Symbol.iterator] === "function") {
5539
+ projectionIds = [...raw].map(Number);
5540
+ }
5541
+ }
5542
+ let phase = null;
5543
+ const phaseRaw = decodeDictValue(params.phase);
5544
+ if (phaseRaw != null) {
5545
+ const phaseStr = String(phaseRaw);
5546
+ if (phaseStr === "INPUT") {
5547
+ phase = "INPUT" /* INPUT */;
5548
+ } else if (phaseStr === "FINALIZE") {
5549
+ phase = "FINALIZE" /* FINALIZE */;
5550
+ } else if (phaseStr === "TABLE_BUFFERING") {
5551
+ phase = "TABLE_BUFFERING" /* TABLE_BUFFERING */;
5552
+ } else if (phaseStr === "TABLE_BUFFERING_FINALIZE") {
5553
+ phase = "TABLE_BUFFERING_FINALIZE" /* TABLE_BUFFERING_FINALIZE */;
5554
+ }
5555
+ }
5556
+ const joinKeys = [];
5557
+ if (params.join_keys != null) {
5558
+ const raw = params.join_keys;
5559
+ const iter = Array.isArray(raw) ? raw : typeof raw[Symbol.iterator] === "function" ? raw : [];
5560
+ for (const entry of iter) {
5561
+ if (entry == null)
5562
+ continue;
5563
+ try {
5564
+ joinKeys.push(deserializeBatch(toUint8Array2(entry)));
5565
+ } catch {}
5566
+ }
5567
+ }
5568
+ return {
5569
+ bind_call: bindCall,
5570
+ output_schema: deserializeSchema(toUint8Array2(params.output_schema)),
5571
+ bind_opaque_data: params.bind_opaque_data ? toUint8Array2(params.bind_opaque_data) : null,
5572
+ projection_ids: projectionIds,
5573
+ row_limit: params.row_limit == null ? null : Number(params.row_limit),
5574
+ pushdown_filters: params.pushdown_filters ? deserializeBatch(toUint8Array2(params.pushdown_filters)) : null,
5575
+ join_keys: joinKeys,
5576
+ phase,
5577
+ finalize_state_id: params.finalize_state_id ? toUint8Array2(params.finalize_state_id) : null,
5578
+ split_tokens: (() => {
5579
+ const raw = params.split_tokens;
5580
+ if (raw == null)
5581
+ return null;
5582
+ const iter = Array.isArray(raw) ? raw : typeof raw[Symbol.iterator] === "function" ? raw : [];
5583
+ const tokens = [...iter].filter((e) => e != null).map((e) => toUint8Array2(e));
5584
+ return tokens.length > 0 ? tokens : null;
5585
+ })(),
5586
+ execution_id: params.execution_id ? toUint8Array2(params.execution_id) : null,
5587
+ init_opaque_data: params.init_opaque_data ? toUint8Array2(params.init_opaque_data) : null,
5588
+ substream_id: params.substream_id ? toUint8Array2(params.substream_id) : null,
5589
+ order_by_column_name: parseEnum(decodeDictValue(params.order_by_column_name)) ?? null,
5590
+ order_by_direction: parseDirection(decodeDictValue(params.order_by_direction)),
5591
+ order_by_null_order: parseNullOrder(decodeDictValue(params.order_by_null_order)),
5592
+ order_by_limit: parseBigInt(params.order_by_limit),
5593
+ tablesample_percentage: parseNumber(params.tablesample_percentage),
5594
+ tablesample_seed: parseBigInt(params.tablesample_seed)
5595
+ };
5596
+ }
5597
+ function parseEnum(v) {
5598
+ if (v === null || v === undefined)
5599
+ return null;
5600
+ return String(v);
5601
+ }
5602
+ function parseDirection(v) {
5603
+ if (v === null || v === undefined)
5604
+ return null;
5605
+ const s = String(v);
5606
+ if (s === "ASC")
5607
+ return "ASC" /* ASC */;
5608
+ if (s === "DESC")
5609
+ return "DESC" /* DESC */;
5610
+ return null;
5611
+ }
5612
+ function parseNullOrder(v) {
5613
+ if (v === null || v === undefined)
5614
+ return null;
5615
+ const s = String(v);
5616
+ if (s === "NULLS_FIRST")
5617
+ return "NULLS_FIRST" /* NULLS_FIRST */;
5618
+ if (s === "NULLS_LAST")
5619
+ return "NULLS_LAST" /* NULLS_LAST */;
5620
+ return null;
5621
+ }
5622
+ function parseBigInt(v) {
5623
+ if (v === null || v === undefined)
5624
+ return null;
5625
+ if (typeof v === "bigint")
5626
+ return v;
5627
+ if (typeof v === "number")
5628
+ return BigInt(v);
5629
+ try {
5630
+ return BigInt(String(v));
5631
+ } catch {
5632
+ return null;
5633
+ }
5634
+ }
5635
+ function parseNumber(v) {
5636
+ if (v === null || v === undefined)
5637
+ return null;
5638
+ if (typeof v === "number")
5639
+ return v;
5640
+ if (typeof v === "bigint")
5641
+ return Number(v);
5642
+ const n = Number(v);
5643
+ return Number.isNaN(n) ? null : n;
5644
+ }
5645
+ function serializeGlobalInitResponse(resp) {
5646
+ return {
5647
+ execution_id: resp.execution_id,
5648
+ opaque_data: resp.opaque_data ?? null,
5649
+ max_workers: resp.max_workers
5650
+ };
5651
+ }
5652
+ function deserializeGlobalInitResponse(params) {
5653
+ return {
5654
+ execution_id: toUint8Array2(params.execution_id),
5655
+ opaque_data: params.opaque_data ? toUint8Array2(params.opaque_data) : null,
5656
+ max_workers: Number(params.max_workers)
5657
+ };
5658
+ }
5659
+ // src/protocol/serializers/cardinality.ts
5660
+ init_arrow();
5661
+ var TABLE_FUNCTION_CARDINALITY_REQUEST_SCHEMA = schema2([
5662
+ field2("bind_call", binary2(), false),
5663
+ field2("bind_opaque_data", binary2(), true)
5664
+ ]);
5665
+ function deserializeCardinalityRequest(params) {
5666
+ const bindCallBytes = toUint8Array2(params.bind_call);
5667
+ const bindCallBatch = deserializeBatch(bindCallBytes);
5668
+ const bindParams = batchToScalarDict(bindCallBatch);
5669
+ const bindCall = deserializeBindRequest(bindParams);
5670
+ return {
5671
+ bind_call: bindCall,
5672
+ bind_opaque_data: params.bind_opaque_data ? toUint8Array2(params.bind_opaque_data) : null
5673
+ };
5674
+ }
5675
+ function serializeTableCardinality(card) {
5676
+ return {
5677
+ estimate: card.estimate,
5678
+ max: card.max
5679
+ };
5680
+ }
5681
+ // src/protocol/carried-init-request.ts
5682
+ var RAW = 0;
5683
+ var ZSTD = 1;
5684
+ function packInitRequest(ipc) {
5685
+ const codec = zstdSync();
5686
+ const compressed = codec ? codec.compress(ipc) : null;
5687
+ const useZstd = compressed !== null && compressed.byteLength < ipc.byteLength;
5688
+ const payload = useZstd ? compressed : ipc;
5689
+ const packed = new Uint8Array(payload.byteLength + 1);
5690
+ packed[0] = useZstd ? ZSTD : RAW;
5691
+ packed.set(payload, 1);
5692
+ return packed;
5693
+ }
5694
+ function unpackInitRequest(packed) {
5695
+ if (packed.byteLength === 0)
5696
+ throw new Error("state token carries no init request");
5697
+ switch (packed[0]) {
5698
+ case RAW:
5699
+ return packed.slice(1);
5700
+ case ZSTD: {
5701
+ const codec = zstdSync();
5702
+ if (!codec) {
5703
+ throw new Error("state token carries a zstd-compressed init request, and this runtime has no synchronous zstd " + "(it was minted by a worker running under Bun or Node >= 22.15 with the same signing key)");
5704
+ }
5705
+ return codec.decompress(packed.subarray(1));
5706
+ }
5707
+ default:
5708
+ throw new Error(`state token carries an init request with unknown codec ${packed[0]}`);
5709
+ }
5710
+ }
5711
+ var MAX_ENTRIES = 128;
5712
+ var parsed = new Map;
5713
+ var stats = { parses: 0, hits: 0 };
5714
+ function hashBytes(bytes) {
5715
+ let h = 2166136261 ^ bytes.byteLength;
5716
+ for (let i = 0;i < bytes.byteLength; i++) {
5717
+ h ^= bytes[i];
5718
+ h = Math.imul(h, 16777619);
5719
+ }
5720
+ return h >>> 0;
5721
+ }
5722
+ function sameBytes(a, b) {
5723
+ if (a.byteLength !== b.byteLength)
5724
+ return false;
5725
+ for (let i = 0;i < a.byteLength; i++)
5726
+ if (a[i] !== b[i])
5727
+ return false;
5728
+ return true;
5729
+ }
5730
+ function parseCarriedInitRequest(packed) {
5731
+ const key = hashBytes(packed);
5732
+ let entry = parsed.get(key);
5733
+ if (entry && sameBytes(entry.packed, packed)) {
5734
+ parsed.delete(key);
5735
+ parsed.set(key, entry);
5736
+ stats.hits++;
5737
+ } else {
5738
+ const dict = batchToScalarDict(deserializeBatch(unpackInitRequest(packed)));
5739
+ stats.parses++;
5740
+ entry = { packed: packed.slice(), request: deserializeInitRequest(dict), bindCallIpc: dict.bind_call };
5741
+ parsed.delete(key);
5742
+ if (parsed.size >= MAX_ENTRIES)
5743
+ parsed.delete(parsed.keys().next().value);
5744
+ parsed.set(key, entry);
5745
+ }
5911
5746
  return {
5912
- output_schema: deserializeSchema(toUint8Array2(params.output_schema)),
5913
- opaque_data: params.opaque_data ? toUint8Array2(params.opaque_data) : null,
5914
- lookup_secret_types: toStrArray(params.lookup_secret_types),
5915
- lookup_scopes: toStrArray(params.lookup_scopes),
5916
- lookup_names: toStrArray(params.lookup_names)
5747
+ request: { ...entry.request, bind_call: { ...entry.request.bind_call } },
5748
+ bindCallIpc: entry.bindCallIpc
5917
5749
  };
5918
5750
  }
5919
- // src/protocol/serializers/init.ts
5920
- init_arrow();
5921
- var INIT_REQUEST_SCHEMA = schema2([
5922
- field2("bind_call", binary2(), false),
5923
- field2("output_schema", binary2(), false),
5924
- field2("bind_opaque_data", binary2(), true),
5925
- field2("projection_ids", list2(field2("item", int642(), true)), true),
5926
- field2("pushdown_filters", largeBinary2(), true),
5927
- field2("join_keys", list2(field2("item", largeBinary2(), true)), true),
5928
- field2("split_tokens", list2(field2("item", largeBinary2(), true)), true),
5929
- field2("row_limit", int642(), true),
5930
- field2("phase", dictionary2(utf82(), int162()), true),
5931
- field2("finalize_state_id", binary2(), true),
5932
- field2("execution_id", binary2(), true),
5933
- field2("init_opaque_data", binary2(), true),
5934
- field2("substream_id", binary2(), true),
5935
- field2("order_by_column_name", utf82(), true),
5936
- field2("order_by_direction", dictionary2(utf82(), int162()), true),
5937
- field2("order_by_null_order", dictionary2(utf82(), int162()), true),
5938
- field2("order_by_limit", int642(), true),
5939
- field2("tablesample_percentage", float642(), true),
5940
- field2("tablesample_seed", int642(), true)
5941
- ]);
5942
- var GLOBAL_INIT_RESPONSE_SCHEMA = schema2([
5751
+
5752
+ // src/protocol/state-serializer.ts
5753
+ var EXCHANGE_STATE_SCHEMA = schema2([
5754
+ field2("function_name", binary2(), false),
5755
+ field2("init_request", binary2(), false),
5943
5756
  field2("execution_id", binary2(), false),
5757
+ field2("max_workers", int642(), false),
5944
5758
  field2("opaque_data", binary2(), true),
5945
- field2("max_workers", int642(), false)
5759
+ field2("is_producer", bool2(), false),
5760
+ field2("user_state", binary2(), true),
5761
+ field2("filter_history", binary2(), true)
5946
5762
  ]);
5947
- function serializeInitRequest(req) {
5948
- const bindCallBatch = serializeBindRequest(req.bind_call);
5949
- const bindCallBytes = serializeBatch(bindCallBatch);
5950
- const row = {
5951
- bind_call: bindCallBytes,
5952
- output_schema: serializeSchema(req.output_schema),
5953
- bind_opaque_data: req.bind_opaque_data ?? null,
5954
- projection_ids: req.projection_ids?.map((n) => BigInt(n)) ?? null,
5955
- pushdown_filters: req.pushdown_filters ? serializeBatch(req.pushdown_filters) : null,
5956
- join_keys: (req.join_keys ?? []).map((b) => serializeBatch(b)),
5957
- split_tokens: req.split_tokens ?? null,
5958
- row_limit: req.row_limit ?? null,
5959
- phase: req.phase ?? null,
5960
- finalize_state_id: req.finalize_state_id ?? null,
5961
- execution_id: req.execution_id ?? null,
5962
- init_opaque_data: req.init_opaque_data ?? null,
5963
- substream_id: req.substream_id ?? null,
5964
- order_by_column_name: req.order_by_column_name ?? null,
5965
- order_by_direction: req.order_by_direction ?? null,
5966
- order_by_null_order: req.order_by_null_order ?? null,
5967
- order_by_limit: req.order_by_limit ?? null,
5968
- tablesample_percentage: req.tablesample_percentage ?? null,
5969
- tablesample_seed: req.tablesample_seed ?? null
5970
- };
5971
- return buildSingleRowBatch(INIT_REQUEST_SCHEMA, row);
5763
+ var TEXT_ENCODER = new TextEncoder;
5764
+ var TEXT_DECODER = new TextDecoder;
5765
+ var STATE_FORMAT_VERSION = 1;
5766
+ var FLAG_PRODUCER = 1;
5767
+ var FLAG_OPAQUE_DATA = 2;
5768
+ var FLAG_USER_STATE = 4;
5769
+ var FLAG_FILTER_HISTORY = 8;
5770
+ var LIST_CHILD_NAME = "item";
5771
+ var emptyListElementType = () => utf82();
5772
+ function inferElementType(values) {
5773
+ let elementType = null;
5774
+ let elementSig = "";
5775
+ for (const v of values) {
5776
+ if (v === null || v === undefined)
5777
+ continue;
5778
+ const t = inferFieldType(v);
5779
+ const sig = typeSignature(t);
5780
+ if (elementType === null) {
5781
+ elementType = t;
5782
+ elementSig = sig;
5783
+ continue;
5784
+ }
5785
+ if (sig !== elementSig) {
5786
+ throw new Error(`inferFieldType: arrays in userState must be homogeneous; ` + `found both '${elementSig}' and '${sig}' in the same array ` + `(split the values into separate fields, or normalize them to one type)`);
5787
+ }
5788
+ }
5789
+ return elementType ?? emptyListElementType();
5972
5790
  }
5973
- function deserializeInitRequest(params) {
5974
- const bindCallBytes = toUint8Array2(params.bind_call);
5975
- const bindCallBatch = deserializeBatch(bindCallBytes);
5976
- const bindParams = batchToScalarDict(bindCallBatch);
5977
- const bindCall = deserializeBindRequest(bindParams);
5978
- let projectionIds = null;
5979
- if (params.projection_ids != null) {
5980
- const raw = params.projection_ids;
5981
- if (Array.isArray(raw)) {
5982
- projectionIds = raw.map(Number);
5983
- } else if (raw && typeof raw[Symbol.iterator] === "function") {
5984
- projectionIds = [...raw].map(Number);
5791
+ function inferFieldType(value) {
5792
+ if (value === null || value === undefined)
5793
+ return nullType2();
5794
+ switch (typeof value) {
5795
+ case "number":
5796
+ return float642();
5797
+ case "bigint":
5798
+ return int642();
5799
+ case "string":
5800
+ return utf82();
5801
+ case "boolean":
5802
+ return bool2();
5803
+ case "object":
5804
+ if (value instanceof Uint8Array || value instanceof ArrayBuffer)
5805
+ return binary2();
5806
+ if (ArrayBuffer.isView(value))
5807
+ return binary2();
5808
+ if (Array.isArray(value)) {
5809
+ return list2(field2(LIST_CHILD_NAME, inferElementType(value), true));
5810
+ }
5811
+ if (value instanceof Map) {
5812
+ throw new Error(`inferFieldType: Map is not supported in userState (use a plain object instead)`);
5813
+ }
5814
+ if (value instanceof Set) {
5815
+ throw new Error(`inferFieldType: Set is not supported in userState (use an array or plain object instead)`);
5816
+ }
5817
+ if (value instanceof Date) {
5818
+ throw new Error(`inferFieldType: Date is not supported in userState (use a number (epoch ms) or ISO string instead)`);
5819
+ }
5820
+ if (value instanceof RegExp) {
5821
+ throw new Error(`inferFieldType: RegExp is not supported in userState (use a string pattern instead)`);
5822
+ }
5823
+ const fields = Object.entries(value).map(([k, v]) => field2(k, inferFieldType(v), true));
5824
+ return struct2(fields);
5825
+ default:
5826
+ throw new Error(`inferFieldType: unsupported type '${typeof value}'`);
5827
+ }
5828
+ }
5829
+ function serializeUserState(userState) {
5830
+ if (userState == null)
5831
+ return null;
5832
+ const entries = Object.entries(userState);
5833
+ if (entries.length === 0) {
5834
+ return serializeBatch(batchFromColumns({}, schema2([])));
5835
+ }
5836
+ const fields = entries.map(([k, v]) => field2(k, inferFieldType(v), true));
5837
+ const sch = schema2(fields);
5838
+ const columns = {};
5839
+ for (const [key, val] of entries) {
5840
+ columns[key] = [val];
5841
+ }
5842
+ return serializeBatch(batchFromColumns(columns, sch));
5843
+ }
5844
+ function extractTypedValue(col, index, type) {
5845
+ return codecFor(type).canonicalToRich(readCanonicalValue(type, col, index));
5846
+ }
5847
+ function deserializeUserState(bytes) {
5848
+ if (bytes == null)
5849
+ return null;
5850
+ const batch = deserializeBatch(bytes);
5851
+ if (batch.numRows === 0 && batch.schema.fields.length === 0) {
5852
+ return {};
5853
+ }
5854
+ if (batch.numRows === 0)
5855
+ return null;
5856
+ const result = {};
5857
+ for (const f of batch.schema.fields) {
5858
+ const col = batch.getChild(f.name);
5859
+ if (!col) {
5860
+ result[f.name] = null;
5861
+ continue;
5985
5862
  }
5863
+ result[f.name] = extractTypedValue(col, 0, f.type);
5986
5864
  }
5987
- let phase = null;
5988
- const phaseRaw = decodeDictValue(params.phase);
5989
- if (phaseRaw != null) {
5990
- const phaseStr = String(phaseRaw);
5991
- if (phaseStr === "INPUT") {
5992
- phase = "INPUT" /* INPUT */;
5993
- } else if (phaseStr === "FINALIZE") {
5994
- phase = "FINALIZE" /* FINALIZE */;
5995
- } else if (phaseStr === "TABLE_BUFFERING") {
5996
- phase = "TABLE_BUFFERING" /* TABLE_BUFFERING */;
5997
- } else if (phaseStr === "TABLE_BUFFERING_FINALIZE") {
5998
- phase = "TABLE_BUFFERING_FINALIZE" /* TABLE_BUFFERING_FINALIZE */;
5865
+ return result;
5866
+ }
5867
+ var arrowStateSerializer = {
5868
+ serialize(state) {
5869
+ const functionName = TEXT_ENCODER.encode(state.functionName ?? "");
5870
+ const initRequest = state.initRequestPacked ?? packInitRequest(state.initRequestIpc);
5871
+ const executionId = toUint8Array(state.executionId);
5872
+ const opaqueData = state.opaqueData != null ? toUint8Array(state.opaqueData) : null;
5873
+ const userState = serializeUserState(state.userState);
5874
+ const filterHistory = encodeFilterHistory(state.filterHistory);
5875
+ const flags = (state.isProducer ? FLAG_PRODUCER : 0) | (opaqueData ? FLAG_OPAQUE_DATA : 0) | (userState ? FLAG_USER_STATE : 0) | (filterHistory ? FLAG_FILTER_HISTORY : 0);
5876
+ const chunks = [functionName, initRequest, executionId];
5877
+ if (opaqueData)
5878
+ chunks.push(opaqueData);
5879
+ if (userState)
5880
+ chunks.push(userState);
5881
+ if (filterHistory)
5882
+ chunks.push(filterHistory);
5883
+ let size = 2 + 8;
5884
+ for (const chunk of chunks)
5885
+ size += 4 + chunk.byteLength;
5886
+ const out = new Uint8Array(size);
5887
+ const view = new DataView(out.buffer);
5888
+ out[0] = STATE_FORMAT_VERSION;
5889
+ out[1] = flags;
5890
+ view.setFloat64(2, Number(state.maxWorkers ?? 1), true);
5891
+ let offset = 10;
5892
+ for (const chunk of chunks) {
5893
+ view.setUint32(offset, chunk.byteLength, true);
5894
+ out.set(chunk, offset + 4);
5895
+ offset += 4 + chunk.byteLength;
5999
5896
  }
5897
+ return out;
5898
+ },
5899
+ deserialize(bytes) {
5900
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
5901
+ if (bytes.byteLength < 10 || bytes[0] !== STATE_FORMAT_VERSION) {
5902
+ throw new Error("exchange state has an unknown format (minted by another build of this worker?)");
5903
+ }
5904
+ const flags = bytes[1];
5905
+ const maxWorkers = view.getFloat64(2, true);
5906
+ let offset = 10;
5907
+ const take = () => {
5908
+ if (offset + 4 > bytes.byteLength)
5909
+ throw new Error("exchange state is truncated");
5910
+ const length = view.getUint32(offset, true);
5911
+ offset += 4;
5912
+ if (offset + length > bytes.byteLength)
5913
+ throw new Error("exchange state is truncated");
5914
+ const chunk = bytes.slice(offset, offset + length);
5915
+ offset += length;
5916
+ return chunk;
5917
+ };
5918
+ const functionName = TEXT_DECODER.decode(take());
5919
+ const initRequestPacked = take();
5920
+ const executionId = take();
5921
+ const opaqueData = flags & FLAG_OPAQUE_DATA ? take() : null;
5922
+ const userStateBytes = flags & FLAG_USER_STATE ? take() : null;
5923
+ const filterHistoryBytes = flags & FLAG_FILTER_HISTORY ? take() : null;
5924
+ if (offset !== bytes.byteLength)
5925
+ throw new Error("exchange state has trailing bytes");
5926
+ const isProducer = (flags & FLAG_PRODUCER) !== 0;
5927
+ return {
5928
+ functionName,
5929
+ initRequestPacked,
5930
+ executionId,
5931
+ maxWorkers,
5932
+ opaqueData,
5933
+ isProducer,
5934
+ __isProducer: isProducer,
5935
+ userState: deserializeUserState(userStateBytes),
5936
+ filterHistory: decodeFilterHistory(filterHistoryBytes)
5937
+ };
6000
5938
  }
6001
- const joinKeys = [];
6002
- if (params.join_keys != null) {
6003
- const raw = params.join_keys;
6004
- const iter = Array.isArray(raw) ? raw : typeof raw[Symbol.iterator] === "function" ? raw : [];
6005
- for (const entry of iter) {
6006
- if (entry == null)
5939
+ };
5940
+
5941
+ // src/functions/table-in-out.ts
5942
+ var STREAMING_FINALIZE_KEY = new Uint8Array(0);
5943
+ function defineTableInOutFunction(config) {
5944
+ assertArrowTypes(config.args, `defineTableInOutFunction("${config.name}"): args`);
5945
+ const specs = [];
5946
+ let posIdx = 0;
5947
+ if (config.args) {
5948
+ for (const [name, type] of Object.entries(config.args)) {
5949
+ specs.push({
5950
+ name,
5951
+ position: posIdx++,
5952
+ arrowType: type,
5953
+ doc: config.argDocs?.[name],
5954
+ ...constraintSpecFields(config.argConstraints?.[name], config.argDefaults?.[name])
5955
+ });
5956
+ }
5957
+ }
5958
+ specs.push({
5959
+ name: "data",
5960
+ position: posIdx++,
5961
+ arrowType: nullType2(),
5962
+ isTableInput: true
5963
+ });
5964
+ if (config.namedArgs) {
5965
+ for (const [name, type] of Object.entries(config.namedArgs)) {
5966
+ specs.push({
5967
+ name,
5968
+ position: name,
5969
+ arrowType: type,
5970
+ doc: config.argDocs?.[name],
5971
+ ...constraintSpecFields(config.argConstraints?.[name], config.argDefaults?.[name])
5972
+ });
5973
+ }
5974
+ }
5975
+ const meta = {
5976
+ name: config.name,
5977
+ description: config.description,
5978
+ stability: config.stability,
5979
+ projectionPushdown: config.projectionPushdown,
5980
+ filterPushdown: config.filterPushdown,
5981
+ autoApplyFilters: config.autoApplyFilters,
5982
+ examples: config.examples,
5983
+ categories: config.categories,
5984
+ tags: config.tags,
5985
+ parameterDefaultValues: config.parameterDefaultValues,
5986
+ maxWorkers: config.maxWorkers,
5987
+ requiredSettings: config.requiredSettings,
5988
+ requiredSecrets: config.requiredSecrets,
5989
+ hasFinalize: !!config.finalize
5990
+ };
5991
+ function extractArgs(request) {
5992
+ const args = {};
5993
+ for (const spec of specs) {
5994
+ if (spec.isTableInput)
6007
5995
  continue;
6008
- try {
6009
- joinKeys.push(deserializeBatch(toUint8Array2(entry)));
6010
- } catch {}
5996
+ const defaultVal = config.argDefaults?.[spec.name] !== undefined ? config.argDefaults[spec.name] : undefined;
5997
+ let val = request.arguments.get(spec.position, defaultVal);
5998
+ val = narrowArgValue(val);
5999
+ const constraints = config.argConstraints?.[spec.name];
6000
+ if (constraints)
6001
+ validateConstConstraints(spec.name, constraints, val);
6002
+ args[spec.name] = val;
6011
6003
  }
6004
+ return args;
6012
6005
  }
6013
6006
  return {
6014
- bind_call: bindCall,
6015
- output_schema: deserializeSchema(toUint8Array2(params.output_schema)),
6016
- bind_opaque_data: params.bind_opaque_data ? toUint8Array2(params.bind_opaque_data) : null,
6017
- projection_ids: projectionIds,
6018
- row_limit: params.row_limit == null ? null : Number(params.row_limit),
6019
- pushdown_filters: params.pushdown_filters ? deserializeBatch(toUint8Array2(params.pushdown_filters)) : null,
6020
- join_keys: joinKeys,
6021
- phase,
6022
- finalize_state_id: params.finalize_state_id ? toUint8Array2(params.finalize_state_id) : null,
6023
- split_tokens: (() => {
6024
- const raw = params.split_tokens;
6025
- if (raw == null)
6026
- return null;
6027
- const iter = Array.isArray(raw) ? raw : typeof raw[Symbol.iterator] === "function" ? raw : [];
6028
- const tokens = [...iter].filter((e) => e != null).map((e) => toUint8Array2(e));
6029
- return tokens.length > 0 ? tokens : null;
6030
- })(),
6031
- execution_id: params.execution_id ? toUint8Array2(params.execution_id) : null,
6032
- init_opaque_data: params.init_opaque_data ? toUint8Array2(params.init_opaque_data) : null,
6033
- substream_id: params.substream_id ? toUint8Array2(params.substream_id) : null,
6034
- order_by_column_name: parseEnum(decodeDictValue(params.order_by_column_name)) ?? null,
6035
- order_by_direction: parseDirection(decodeDictValue(params.order_by_direction)),
6036
- order_by_null_order: parseNullOrder(decodeDictValue(params.order_by_null_order)),
6037
- order_by_limit: parseBigInt(params.order_by_limit),
6038
- tablesample_percentage: parseNumber(params.tablesample_percentage),
6039
- tablesample_seed: parseBigInt(params.tablesample_seed)
6007
+ kind: "table_in_out",
6008
+ meta,
6009
+ argumentSpecs: specs,
6010
+ async bind(request) {
6011
+ if (config.onBind) {
6012
+ const args = extractArgs(request);
6013
+ const settings = batchToScalarDict(request.settings);
6014
+ const secrets = batchToSecretDict(request.secrets);
6015
+ const result = await config.onBind({
6016
+ args,
6017
+ bindCall: request,
6018
+ settings,
6019
+ secrets,
6020
+ argumentNames: request.argument_names ?? null
6021
+ });
6022
+ return {
6023
+ output_schema: result.outputSchema,
6024
+ opaque_data: result.opaqueData ?? null
6025
+ };
6026
+ }
6027
+ return {
6028
+ output_schema: request.input_schema ?? schema2([]),
6029
+ opaque_data: null
6030
+ };
6031
+ },
6032
+ async globalInit(request) {
6033
+ const executionId = new Uint8Array(16);
6034
+ crypto.getRandomValues(executionId);
6035
+ if (request.execution_id) {
6036
+ return {
6037
+ max_workers: DEFAULT_MAX_WORKERS,
6038
+ execution_id: request.execution_id,
6039
+ opaque_data: null
6040
+ };
6041
+ }
6042
+ if (config.onInit) {
6043
+ const args = extractArgs(request.bind_call);
6044
+ return await config.onInit({
6045
+ args,
6046
+ initCall: request,
6047
+ outputSchema: request.output_schema,
6048
+ executionId
6049
+ });
6050
+ }
6051
+ return {
6052
+ max_workers: config.maxWorkers ?? 1,
6053
+ execution_id: executionId,
6054
+ opaque_data: null
6055
+ };
6056
+ },
6057
+ createStreamHandlers(request, response, filterHistory) {
6058
+ const args = extractArgs(request.bind_call);
6059
+ const settings = batchToScalarDict(request.bind_call.settings);
6060
+ const secrets = batchToSecretDict(request.bind_call.secrets);
6061
+ const projIds = request.projection_ids && meta.projectionPushdown ? request.projection_ids : null;
6062
+ const outputSchema = projIds ? projectSchema(projIds, request.output_schema) : request.output_schema;
6063
+ const carriedFilterHistory = filterHistory ?? EMPTY_FILTER_HISTORY;
6064
+ const pushdownFilters = replayFilterHistory(request.pushdown_filters ? deserializeFilters(request.pushdown_filters, {
6065
+ outputSchema: request.output_schema,
6066
+ joinKeyBatches: request.join_keys,
6067
+ extensionFunctions: meta.additionalFilterFunctions,
6068
+ runtimeAlgorithms: meta.runtimeFilterAlgorithms,
6069
+ evaluationContexts: meta.filterEvaluationContexts
6070
+ }) : undefined, carriedFilterHistory);
6071
+ const boundStorage = new BoundStorage(storage, response.execution_id ?? new Uint8Array(16), request.substream_id ?? null);
6072
+ const processParams = {
6073
+ args,
6074
+ initCall: request,
6075
+ initResponse: response,
6076
+ outputSchema,
6077
+ settings,
6078
+ secrets,
6079
+ pushdownFilters,
6080
+ storage: boundStorage,
6081
+ substreamId: request.substream_id ?? null
6082
+ };
6083
+ const phase = request.phase;
6084
+ if (phase === "FINALIZE" /* FINALIZE */) {
6085
+ const finalizeLogKey = STREAMING_FINALIZE_KEY;
6086
+ return {
6087
+ outputSchema,
6088
+ producerInit: () => ({ state: { cursor: -1, materialized: false } }),
6089
+ producerFn: async (pState, out) => {
6090
+ if (!pState.state.materialized) {
6091
+ const finalizeStates = [];
6092
+ const stored = await boundStorage.collect();
6093
+ for (const bytes of stored) {
6094
+ finalizeStates.push(deserializeUserState(bytes));
6095
+ }
6096
+ if (finalizeStates.length === 0) {
6097
+ finalizeStates.push(config.initialState ? config.initialState(processParams) : null);
6098
+ }
6099
+ const batches = config.finalize ? await config.finalize(processParams, finalizeStates) : [];
6100
+ for (const batch of batches) {
6101
+ await boundStorage.stateAppend(FrameworkNS.STREAMING_FINALIZE, finalizeLogKey, serializeBatch(batch));
6102
+ }
6103
+ pState.state.materialized = true;
6104
+ }
6105
+ const rows = await boundStorage.stateLogScan(FrameworkNS.STREAMING_FINALIZE, finalizeLogKey, pState.state.cursor, 1);
6106
+ if (rows.length === 0) {
6107
+ out.finish();
6108
+ return;
6109
+ }
6110
+ const [logId, bytes] = rows[0];
6111
+ out.emit(deserializeBatch(bytes));
6112
+ pState.state.cursor = logId;
6113
+ }
6114
+ };
6115
+ }
6116
+ if (request.bind_call.input_schema == null) {
6117
+ throw new Error(`${config.name}: is a table-in-out function (it requires an input row ` + `stream) but no input schema was supplied -- call it via ` + `table_in_out_function(input=...), not table_function().`);
6118
+ }
6119
+ const state = config.initialState ? config.initialState(processParams) : null;
6120
+ const processFn = config.process ?? ((_params, _state, batch, out) => {
6121
+ out.emit(projIds ? projectBatch(projIds, batch) : batch);
6122
+ });
6123
+ return {
6124
+ outputSchema,
6125
+ inputSchema: request.bind_call.input_schema,
6126
+ exchangeInit: () => ({ state, processParams, filterHistory: carriedFilterHistory }),
6127
+ exchangeFn: async (eState, input, out) => {
6128
+ applyRevalidationValidators(eState.processParams, input);
6129
+ applyDynamicFilterUpdate(eState, input);
6130
+ let wrappedOut = makeMetadataBakingCollector(out);
6131
+ if (projIds) {
6132
+ wrappedOut = makeSchemaReconcilingCollector(wrappedOut, outputSchema);
6133
+ }
6134
+ const currentFilters = eState.processParams.pushdownFilters;
6135
+ if (config.autoApplyFilters && currentFilters) {
6136
+ wrappedOut = new FilteringOutputCollector(wrappedOut, currentFilters);
6137
+ }
6138
+ await processFn(eState.processParams, eState.state, input, wrappedOut);
6139
+ if (eState.state != null) {
6140
+ const serialized = serializeUserState(eState.state);
6141
+ if (serialized != null) {
6142
+ await boundStorage.put(serialized);
6143
+ }
6144
+ }
6145
+ }
6146
+ };
6147
+ }
6040
6148
  };
6041
6149
  }
6042
- function parseEnum(v) {
6043
- if (v === null || v === undefined)
6044
- return null;
6045
- return String(v);
6150
+ function applyRevalidationValidators(params, input) {
6151
+ const md = input?.metadata;
6152
+ params.ifNoneMatch = md?.get(CACHE_IF_NONE_MATCH_KEY);
6153
+ params.ifModifiedSince = md?.get(CACHE_IF_MODIFIED_SINCE_KEY);
6046
6154
  }
6047
- function parseDirection(v) {
6048
- if (v === null || v === undefined)
6049
- return null;
6050
- const s = String(v);
6051
- if (s === "ASC")
6052
- return "ASC" /* ASC */;
6053
- if (s === "DESC")
6054
- return "DESC" /* DESC */;
6055
- return null;
6155
+ function applyDynamicFilterUpdate(eState, input) {
6156
+ const encoded = input?.metadata?.get("vgi_pushdown_filters");
6157
+ if (!encoded)
6158
+ return;
6159
+ const current = eState.processParams.pushdownFilters;
6160
+ if (!current)
6161
+ throw new Error("dynamic filter delta received without an initial snapshot");
6162
+ const recorded = recordFilterDelta(current, eState.filterHistory, decodeDynamicFilterMetadata(encoded));
6163
+ eState.processParams.pushdownFilters = recorded.filters;
6164
+ eState.filterHistory = recorded.history;
6056
6165
  }
6057
- function parseNullOrder(v) {
6058
- if (v === null || v === undefined)
6059
- return null;
6060
- const s = String(v);
6061
- if (s === "NULLS_FIRST")
6062
- return "NULLS_FIRST" /* NULLS_FIRST */;
6063
- if (s === "NULLS_LAST")
6064
- return "NULLS_LAST" /* NULLS_LAST */;
6065
- return null;
6166
+ function makeMetadataBakingCollector(inner) {
6167
+ return new Proxy(inner, {
6168
+ get(target, prop, receiver) {
6169
+ if (prop === "emit") {
6170
+ return function(batchOrColumns, metadata) {
6171
+ if (batchOrColumns && typeof batchOrColumns.getChild === "function" && metadata && metadata.size > 0) {
6172
+ const batch = batchOrColumns;
6173
+ const merged = new Map(batch.metadata ?? []);
6174
+ for (const [k, v] of metadata)
6175
+ merged.set(k, v);
6176
+ return target.emit(withBatchMetadata(batch, merged), merged);
6177
+ }
6178
+ return target.emit(batchOrColumns, metadata);
6179
+ };
6180
+ }
6181
+ const v = Reflect.get(target, prop, receiver);
6182
+ return typeof v === "function" ? v.bind(target) : v;
6183
+ }
6184
+ });
6066
6185
  }
6067
- function parseBigInt(v) {
6068
- if (v === null || v === undefined)
6069
- return null;
6070
- if (typeof v === "bigint")
6071
- return v;
6072
- if (typeof v === "number")
6073
- return BigInt(v);
6074
- try {
6075
- return BigInt(String(v));
6076
- } catch {
6077
- return null;
6186
+ function makeSchemaReconcilingCollector(inner, targetSchema) {
6187
+ function reconcile(batch) {
6188
+ const batchFields = batch.schema.fields;
6189
+ if (batchFields.length === targetSchema.fields.length && targetSchema.fields.every((f, i) => batchFields[i].name === f.name)) {
6190
+ return batch;
6191
+ }
6192
+ const ids = [];
6193
+ for (const f of targetSchema.fields) {
6194
+ const idx = batchFields.findIndex((bf) => bf.name === f.name);
6195
+ if (idx < 0) {
6196
+ throw new Error(`emitted batch is missing projected output column '${f.name}' ` + `(emitted: [${batchFields.map((bf) => bf.name).join(", ")}])`);
6197
+ }
6198
+ ids.push(idx);
6199
+ }
6200
+ return projectBatch(ids, batch);
6078
6201
  }
6202
+ return new Proxy(inner, {
6203
+ get(target, prop, receiver) {
6204
+ if (prop === "emit") {
6205
+ return function(batchOrColumns, metadata) {
6206
+ if (batchOrColumns && typeof batchOrColumns.getChild === "function") {
6207
+ return target.emit(reconcile(batchOrColumns), metadata);
6208
+ }
6209
+ return target.emit(batchOrColumns, metadata);
6210
+ };
6211
+ }
6212
+ const v = Reflect.get(target, prop, receiver);
6213
+ return typeof v === "function" ? v.bind(target) : v;
6214
+ }
6215
+ });
6079
6216
  }
6080
- function parseNumber(v) {
6081
- if (v === null || v === undefined)
6082
- return null;
6083
- if (typeof v === "number")
6084
- return v;
6085
- if (typeof v === "bigint")
6086
- return Number(v);
6087
- const n = Number(v);
6088
- return Number.isNaN(n) ? null : n;
6089
- }
6090
- function serializeGlobalInitResponse(resp) {
6091
- return {
6092
- execution_id: resp.execution_id,
6093
- opaque_data: resp.opaque_data ?? null,
6094
- max_workers: resp.max_workers
6095
- };
6217
+ var PARENT_ROW_METADATA_KEY = "vgi_rpc.parent_row#b64";
6218
+ function parentRowsMetadata(parentRows, outputRows, extra) {
6219
+ if (parentRows.length !== outputRows) {
6220
+ throw new Error(`parentRowsMetadata: length ${parentRows.length} != output rows ${outputRows}; ` + `parentRows must carry exactly one input-row index per emitted output row`);
6221
+ }
6222
+ const md = new Map(extra ?? []);
6223
+ if (outputRows === 0) {
6224
+ return md;
6225
+ }
6226
+ const raw = new Uint8Array(parentRows.length * 4);
6227
+ const dv = new DataView(raw.buffer);
6228
+ for (let i = 0;i < parentRows.length; i++) {
6229
+ dv.setInt32(i * 4, parentRows[i], true);
6230
+ }
6231
+ md.set(PARENT_ROW_METADATA_KEY, base64Encode(raw));
6232
+ return md;
6096
6233
  }
6097
- function deserializeGlobalInitResponse(params) {
6098
- return {
6099
- execution_id: toUint8Array2(params.execution_id),
6100
- opaque_data: params.opaque_data ? toUint8Array2(params.opaque_data) : null,
6101
- max_workers: Number(params.max_workers)
6102
- };
6234
+ function base64Encode(bytes) {
6235
+ if (typeof globalThis.Buffer !== "undefined") {
6236
+ return globalThis.Buffer.from(bytes).toString("base64");
6237
+ }
6238
+ let bin = "";
6239
+ for (let i = 0;i < bytes.length; i++)
6240
+ bin += String.fromCharCode(bytes[i]);
6241
+ return globalThis.btoa(bin);
6103
6242
  }
6104
- // src/protocol/serializers/cardinality.ts
6105
- init_arrow();
6106
- var TABLE_FUNCTION_CARDINALITY_REQUEST_SCHEMA = schema2([
6107
- field2("bind_call", binary2(), false),
6108
- field2("bind_opaque_data", binary2(), true)
6109
- ]);
6110
- function deserializeCardinalityRequest(params) {
6111
- const bindCallBytes = toUint8Array2(params.bind_call);
6112
- const bindCallBatch = deserializeBatch(bindCallBytes);
6113
- const bindParams = batchToScalarDict(bindCallBatch);
6114
- const bindCall = deserializeBindRequest(bindParams);
6115
- return {
6116
- bind_call: bindCall,
6117
- bind_opaque_data: params.bind_opaque_data ? toUint8Array2(params.bind_opaque_data) : null
6243
+ function defineRowTransformFunction(config) {
6244
+ const numPositional = Object.keys(config.args ?? {}).length + (config.varargs ? 1 : 0);
6245
+ if (numPositional === 0) {
6246
+ throw new Error(`${config.name}: a blended row-transform function needs at least one ` + `positional arg (its per-row input column); found none.`);
6247
+ }
6248
+ const specs = [];
6249
+ let posIdx = 0;
6250
+ if (config.args) {
6251
+ for (const [name, type] of Object.entries(config.args)) {
6252
+ const isAny = isNull(type);
6253
+ specs.push({
6254
+ name,
6255
+ position: posIdx++,
6256
+ arrowType: isAny ? nullType2() : type,
6257
+ isAnyType: isAny,
6258
+ doc: config.argDocs?.[name],
6259
+ ...constraintSpecFields(config.argConstraints?.[name])
6260
+ });
6261
+ }
6262
+ }
6263
+ if (config.varargs) {
6264
+ const isAny = isNull(config.varargs.type);
6265
+ specs.push({
6266
+ name: config.varargs.name,
6267
+ position: posIdx++,
6268
+ arrowType: isAny ? nullType2() : config.varargs.type,
6269
+ isAnyType: isAny,
6270
+ isVarargs: true,
6271
+ doc: config.varargs.doc ?? config.argDocs?.[config.varargs.name],
6272
+ ...constraintSpecFields(config.argConstraints?.[config.varargs.name])
6273
+ });
6274
+ }
6275
+ if (config.namedArgs) {
6276
+ for (const [name, type] of Object.entries(config.namedArgs)) {
6277
+ specs.push({
6278
+ name,
6279
+ position: name,
6280
+ arrowType: type,
6281
+ doc: config.argDocs?.[name],
6282
+ ...constraintSpecFields(config.argConstraints?.[name], config.argDefaults?.[name])
6283
+ });
6284
+ }
6285
+ }
6286
+ const meta = {
6287
+ name: config.name,
6288
+ description: config.description,
6289
+ stability: config.stability,
6290
+ projectionPushdown: config.projectionPushdown,
6291
+ filterPushdown: config.filterPushdown,
6292
+ autoApplyFilters: config.autoApplyFilters,
6293
+ examples: config.examples,
6294
+ categories: config.categories,
6295
+ tags: config.tags,
6296
+ parameterDefaultValues: config.parameterDefaultValues,
6297
+ maxWorkers: config.maxWorkers,
6298
+ requiredSettings: config.requiredSettings,
6299
+ requiredSecrets: config.requiredSecrets,
6300
+ hasFinalize: false,
6301
+ inputFromArgs: true
6118
6302
  };
6119
- }
6120
- function serializeTableCardinality(card) {
6303
+ function extractArgs(request) {
6304
+ const args = {};
6305
+ for (const spec of specs) {
6306
+ if (typeof spec.position !== "string")
6307
+ continue;
6308
+ const defaultVal = config.argDefaults?.[spec.name] !== undefined ? config.argDefaults[spec.name] : undefined;
6309
+ let val = request.arguments.get(spec.position, defaultVal ?? null);
6310
+ val = narrowArgValue(val);
6311
+ const constraints = config.argConstraints?.[spec.name];
6312
+ if (constraints)
6313
+ validateConstConstraints(spec.name, constraints, val);
6314
+ args[spec.name] = val;
6315
+ }
6316
+ return args;
6317
+ }
6121
6318
  return {
6122
- estimate: card.estimate,
6123
- max: card.max
6319
+ kind: "table_in_out",
6320
+ meta,
6321
+ argumentSpecs: specs,
6322
+ async bind(request) {
6323
+ const args = extractArgs(request);
6324
+ const settings = batchToScalarDict(request.settings);
6325
+ const secrets = batchToSecretDict(request.secrets);
6326
+ const result = await config.onBind({
6327
+ args,
6328
+ bindCall: request,
6329
+ settings,
6330
+ secrets,
6331
+ argumentNames: request.argument_names ?? null
6332
+ });
6333
+ return {
6334
+ output_schema: result.outputSchema,
6335
+ opaque_data: result.opaqueData ?? null
6336
+ };
6337
+ },
6338
+ async globalInit(request) {
6339
+ if (request.execution_id) {
6340
+ return {
6341
+ max_workers: DEFAULT_MAX_WORKERS,
6342
+ execution_id: request.execution_id,
6343
+ opaque_data: null
6344
+ };
6345
+ }
6346
+ const executionId = new Uint8Array(16);
6347
+ crypto.getRandomValues(executionId);
6348
+ return {
6349
+ max_workers: config.maxWorkers ?? 1,
6350
+ execution_id: executionId,
6351
+ opaque_data: null
6352
+ };
6353
+ },
6354
+ createStreamHandlers(request, response, filterHistory) {
6355
+ const args = extractArgs(request.bind_call);
6356
+ const settings = batchToScalarDict(request.bind_call.settings);
6357
+ const secrets = batchToSecretDict(request.bind_call.secrets);
6358
+ const projIds = request.projection_ids && meta.projectionPushdown ? request.projection_ids : null;
6359
+ const outputSchema = projIds ? projectSchema(projIds, request.output_schema) : request.output_schema;
6360
+ const carriedFilterHistory = filterHistory ?? EMPTY_FILTER_HISTORY;
6361
+ const pushdownFilters = replayFilterHistory(request.pushdown_filters ? deserializeFilters(request.pushdown_filters, {
6362
+ outputSchema: request.output_schema,
6363
+ joinKeyBatches: request.join_keys,
6364
+ extensionFunctions: meta.additionalFilterFunctions,
6365
+ runtimeAlgorithms: meta.runtimeFilterAlgorithms,
6366
+ evaluationContexts: meta.filterEvaluationContexts
6367
+ }) : undefined, carriedFilterHistory);
6368
+ const boundStorage = new BoundStorage(storage, response.execution_id ?? new Uint8Array(16), request.substream_id ?? null);
6369
+ const processParams = {
6370
+ args,
6371
+ initCall: request,
6372
+ initResponse: response,
6373
+ outputSchema,
6374
+ settings,
6375
+ secrets,
6376
+ pushdownFilters,
6377
+ storage: boundStorage,
6378
+ substreamId: request.substream_id ?? null
6379
+ };
6380
+ if (request.phase === "FINALIZE" /* FINALIZE */) {
6381
+ throw new Error(`${config.name}: a blended row-transform function has no FINALIZE ` + `phase (it is a per-row map; has_finalize is advertised false).`);
6382
+ }
6383
+ if (request.bind_call.input_schema == null) {
6384
+ throw new Error(`${config.name}: is a table-in-out function (its positional args are ` + `per-row input columns) but no input schema was supplied -- call it ` + `via table_in_out_function(input=...), not table_function().`);
6385
+ }
6386
+ return {
6387
+ outputSchema,
6388
+ inputSchema: request.bind_call.input_schema,
6389
+ exchangeInit: () => ({ state: null, processParams, filterHistory: carriedFilterHistory }),
6390
+ exchangeFn: async (eState, input, out) => {
6391
+ applyRevalidationValidators(eState.processParams, input);
6392
+ applyDynamicFilterUpdate(eState, input);
6393
+ let wrappedOut = makeMetadataBakingCollector(out);
6394
+ if (projIds) {
6395
+ wrappedOut = makeSchemaReconcilingCollector(wrappedOut, outputSchema);
6396
+ }
6397
+ const currentFilters = eState.processParams.pushdownFilters;
6398
+ if (config.autoApplyFilters && currentFilters) {
6399
+ wrappedOut = new FilteringOutputCollector(wrappedOut, currentFilters);
6400
+ }
6401
+ await config.process(eState.processParams, input, wrappedOut);
6402
+ }
6403
+ };
6404
+ }
6124
6405
  };
6125
6406
  }
6126
6407
  // src/functions/table-buffering.ts
6408
+ init_arrow();
6409
+ init_arrow();
6410
+ init_registry();
6411
+ init_storage();
6127
6412
  function defineTableBufferingFunction(config) {
6128
6413
  assertArrowTypes(config.args, `defineTableBufferingFunction("${config.name}"): args`);
6129
6414
  if (config.sinkOrderDependent && config.requiresInputBatchIndex) {
@@ -6245,7 +6530,7 @@ function defineTableBufferingFunction(config) {
6245
6530
  }
6246
6531
  return response;
6247
6532
  },
6248
- createStreamHandlers(request, response, _accumulatedState) {
6533
+ createStreamHandlers(request, response) {
6249
6534
  const args = extractArgs(request.bind_call);
6250
6535
  const settings = batchToScalarDict(request.bind_call.settings);
6251
6536
  const secrets = batchToSecretDict(request.bind_call.secrets);
@@ -8217,12 +8502,41 @@ function validateRequiredAttachOptions(catalogName, specs, options) {
8217
8502
  }
8218
8503
  }
8219
8504
 
8505
+ // src/catalog/item-encoding.ts
8506
+ var ENCODED = new WeakMap;
8507
+ function freezeCatalogItem(item) {
8508
+ deepFreeze(item);
8509
+ return item;
8510
+ }
8511
+ function deepFreeze(value) {
8512
+ if (value === null || typeof value !== "object" || Object.isFrozen(value) || ArrayBuffer.isView(value))
8513
+ return;
8514
+ const proto = Object.getPrototypeOf(value);
8515
+ if (proto !== Object.prototype && proto !== Array.prototype && proto !== null)
8516
+ return;
8517
+ for (const child of Object.values(value))
8518
+ deepFreeze(child);
8519
+ Object.freeze(value);
8520
+ }
8521
+ function encodeFunctionInfoOnce(info) {
8522
+ if (!Object.isFrozen(info))
8523
+ return encodeFunctionInfo(info);
8524
+ let encoded = ENCODED.get(info);
8525
+ if (encoded === undefined) {
8526
+ encoded = encodeFunctionInfo(info);
8527
+ ENCODED.set(info, encoded);
8528
+ }
8529
+ return encoded;
8530
+ }
8531
+
8220
8532
  // src/catalog/read-only.ts
8221
8533
  class ReadOnlyCatalogInterface extends CatalogInterface {
8222
8534
  _descriptor;
8223
8535
  _registry;
8224
8536
  _attachments = new Map;
8225
8537
  _version = 1;
8538
+ _functionListings = new Map;
8539
+ _functionInfos = new Map;
8226
8540
  constructor(descriptor, registry) {
8227
8541
  super();
8228
8542
  this._descriptor = descriptor;
@@ -8288,7 +8602,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8288
8602
  comment: this._descriptor.comment ?? null,
8289
8603
  tags: this._descriptor.tags ?? {},
8290
8604
  supports_column_statistics: true,
8291
- global_functions: this._globalFunctionInfos().map(encodeFunctionInfo),
8605
+ global_functions: this._globalFunctionInfos().map(encodeFunctionInfoOnce),
8292
8606
  global_function_prefix: this._descriptor.globalFunctionPrefix ?? "",
8293
8607
  resolved_data_version: null,
8294
8608
  resolved_implementation_version: null
@@ -8464,16 +8778,35 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8464
8778
  const schema = this._descriptor.schemas.find((s) => schemaPathsEqual(schemaDescriptorPath(s), path));
8465
8779
  if (!schema || !schema.functions)
8466
8780
  return [];
8467
- return schema.functions.filter((f) => {
8468
- const t = String(type ?? "").toUpperCase();
8469
- if (t === "SCALAR_FUNCTION")
8470
- return f.kind === "scalar";
8471
- if (t === "TABLE_FUNCTION")
8472
- return f.kind === "table" || f.kind === "table_in_out" || f.kind === "table_buffering";
8473
- if (t === "AGGREGATE_FUNCTION")
8474
- return f.kind === "aggregate";
8475
- return true;
8476
- }).map((f) => this._functionToInfo(f, path));
8781
+ const kind = functionListingKind(type);
8782
+ const canonicalPath = schemaDescriptorPath(schema);
8783
+ if (!sameSpelling(path, canonicalPath)) {
8784
+ return schema.functions.filter((f) => inListing(f, kind)).map((f) => this._functionToInfo(f, path));
8785
+ }
8786
+ let listings = this._functionListings.get(schema);
8787
+ if (!listings) {
8788
+ listings = new Map;
8789
+ this._functionListings.set(schema, listings);
8790
+ }
8791
+ let listing = listings.get(kind);
8792
+ if (!listing) {
8793
+ listing = Object.freeze(schema.functions.filter((f) => inListing(f, kind)).map((f) => this._sharedFunctionInfo(schema, f)));
8794
+ listings.set(kind, listing);
8795
+ }
8796
+ return listing.slice();
8797
+ }
8798
+ _sharedFunctionInfo(schema, f) {
8799
+ let infos = this._functionInfos.get(schema);
8800
+ if (!infos) {
8801
+ infos = new Map;
8802
+ this._functionInfos.set(schema, infos);
8803
+ }
8804
+ let info = infos.get(f);
8805
+ if (!info) {
8806
+ info = freezeCatalogItem(structuredClone(this._functionToInfo(f, schemaDescriptorPath(schema))));
8807
+ infos.set(f, info);
8808
+ }
8809
+ return info;
8477
8810
  }
8478
8811
  _functionToInfo(f, path) {
8479
8812
  const meta = resolveMetadata(f);
@@ -8574,15 +8907,15 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8574
8907
  for (const sch of this._descriptor.schemas) {
8575
8908
  for (const fn of sch.functions ?? []) {
8576
8909
  if (!schemaOf.has(fn))
8577
- schemaOf.set(fn, schemaDescriptorPath(sch));
8910
+ schemaOf.set(fn, sch);
8578
8911
  }
8579
8912
  }
8580
8913
  return globals.map((fn) => {
8581
- const schemaPath = schemaOf.get(fn);
8582
- if (schemaPath === undefined) {
8914
+ const schema = schemaOf.get(fn);
8915
+ if (schema === undefined) {
8583
8916
  throw new Error(`Catalog '${this._descriptor.name}': '${fn.meta.name}' is listed in ` + `globalFunctions but is not declared in any schema.`);
8584
8917
  }
8585
- return this._functionToInfo(fn, schemaPath);
8918
+ return this._sharedFunctionInfo(schema, fn);
8586
8919
  });
8587
8920
  }
8588
8921
  schemaContentsMacros(attachOpaqueData, path, type, transactionOpaqueData) {
@@ -8895,6 +9228,24 @@ function inlineScanFunction(func, args, schemaPath) {
8895
9228
  const argBytes = serializeArgsBatch(args ?? new Arguments, argSchema);
8896
9229
  return encodeScanFunctionResult(func.meta.name, argBytes, [], schemaPath);
8897
9230
  }
9231
+ function functionListingKind(type) {
9232
+ const t = String(type ?? "").toUpperCase();
9233
+ return t === "SCALAR_FUNCTION" || t === "TABLE_FUNCTION" || t === "AGGREGATE_FUNCTION" ? t : "ALL";
9234
+ }
9235
+ function inListing(f, kind) {
9236
+ if (kind === "SCALAR_FUNCTION")
9237
+ return f.kind === "scalar";
9238
+ if (kind === "TABLE_FUNCTION")
9239
+ return f.kind === "table" || f.kind === "table_in_out" || f.kind === "table_buffering";
9240
+ if (kind === "AGGREGATE_FUNCTION")
9241
+ return f.kind === "aggregate";
9242
+ return true;
9243
+ }
9244
+ function sameSpelling(left, right) {
9245
+ const a = normalizeSchemaPath(left);
9246
+ const b = normalizeSchemaPath(right);
9247
+ return a.length === b.length && a.every((part, i) => part === b[i]);
9248
+ }
8898
9249
  // src/catalog/composite.ts
8899
9250
  var ROUTE_BYTE = 0;
8900
9251
 
@@ -9569,17 +9920,6 @@ function overloadContext(req, catalogInterface) {
9569
9920
  catalogName
9570
9921
  };
9571
9922
  }
9572
- function recoverFinalizeState(request, recoverExchangeState) {
9573
- if (request.phase === "FINALIZE" /* FINALIZE */ && request.init_opaque_data && recoverExchangeState) {
9574
- try {
9575
- const recovered = recoverExchangeState(request.init_opaque_data);
9576
- return recovered?.userState;
9577
- } catch (e) {
9578
- throw new Error(`Failed to recover FINALIZE state from init_opaque_data: ${e.message}`);
9579
- }
9580
- }
9581
- return;
9582
- }
9583
9923
 
9584
9924
  // src/protocol/handlers/catalog/shared.ts
9585
9925
  init_arrow();
@@ -10722,8 +11062,7 @@ function registerFunctionMethods(protocol, config) {
10722
11062
  });
10723
11063
  const func = registry.get(request.bind_call.function_name, overloadContext(request.bind_call, catalogInterface));
10724
11064
  const initResponse = await func.globalInit(request);
10725
- const accumulatedState = recoverFinalizeState(request, config.recoverExchangeState);
10726
- const handlers = func.createStreamHandlers(request, initResponse, accumulatedState);
11065
+ const handlers = func.createStreamHandlers(request, initResponse);
10727
11066
  let handlerState;
10728
11067
  if (handlers.producerInit) {
10729
11068
  handlerState = handlers.producerInit();
@@ -10757,10 +11096,9 @@ function registerFunctionMethods(protocol, config) {
10757
11096
  handlers = state._handlers;
10758
11097
  handlerState = state._handlerState;
10759
11098
  } else {
10760
- const initRequestBatch = deserializeBatch(state.initRequestIpc);
10761
- const initRequestDict = batchToScalarDict(initRequestBatch);
10762
- const request = deserializeInitRequest(initRequestDict);
10763
- await resolveSplitPayloads(request, { bind_call: initRequestDict.bind_call }, {
11099
+ const carried = parseCarriedInitRequest(state.initRequestPacked);
11100
+ const request = carried.request;
11101
+ await resolveSplitPayloads(request, { bind_call: carried.bindCallIpc }, {
10764
11102
  auth: currentRequestAuth(),
10765
11103
  signingKey,
10766
11104
  catalogInterface,
@@ -10774,8 +11112,7 @@ function registerFunctionMethods(protocol, config) {
10774
11112
  max_workers: Number(state.maxWorkers ?? 1),
10775
11113
  opaque_data: opaqueData
10776
11114
  };
10777
- const recoveredState = recoverFinalizeState(request, config.recoverExchangeState);
10778
- handlers = func.createStreamHandlers(request, initResponse, recoveredState);
11115
+ handlers = func.createStreamHandlers(request, initResponse, state.filterHistory ?? null);
10779
11116
  if (handlers.producerInit) {
10780
11117
  handlerState = handlers.producerInit();
10781
11118
  } else if (handlers.exchangeInit) {
@@ -10799,6 +11136,7 @@ function registerFunctionMethods(protocol, config) {
10799
11136
  if (handlerState?.state !== undefined) {
10800
11137
  state.userState = handlerState.state;
10801
11138
  }
11139
+ state.filterHistory = handlerState?.filterHistory ?? null;
10802
11140
  },
10803
11141
  headerSchema: initHeaderSchema,
10804
11142
  headerInit: (params, state, ctx) => {
@@ -11465,7 +11803,7 @@ function registerCatalogAdminMethods(protocol, getCatalog, signingKey) {
11465
11803
  const cat = getCatalog();
11466
11804
  const funcs = await cat.schemaContentsFunctions(toUint8Array(params.attach_opaque_data), params.path, decodeDictValue(params.type), params.transaction_opaque_data ? toUint8Array(params.transaction_opaque_data) : undefined);
11467
11805
  return wrapResult({
11468
- items: funcs.map((f) => encodeFunctionInfo(f))
11806
+ items: funcs.map((f) => encodeFunctionInfoOnce(f))
11469
11807
  }, CatalogSchemaContentsFunctionsResultSchema);
11470
11808
  }
11471
11809
  });
@@ -11759,7 +12097,6 @@ function buildVgiProtocol(config) {
11759
12097
  const protocol = new Protocol(VGI_PROTOCOL_NAME, { protocolVersion: "2.0.0" });
11760
12098
  registerFunctionMethods(protocol, {
11761
12099
  registry: config.registry,
11762
- recoverExchangeState: config.recoverExchangeState,
11763
12100
  signingKey: config.signingKey,
11764
12101
  catalogInterface: config.catalogInterface
11765
12102
  });
@@ -13216,4 +13553,4 @@ export {
13216
13553
  utf82 as utf8
13217
13554
  };
13218
13555
 
13219
- //# debugId=F30A98CAD029B8EE64756E2164756E21
13556
+ //# debugId=D343450F0C99C4DF64756E2164756E21