@query-farm/vgi 0.37.1 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +74 -0
  2. package/dist/catalog/composite.d.ts +23 -1
  3. package/dist/catalog/contents-digest.d.ts +25 -0
  4. package/dist/catalog/interface.d.ts +107 -2
  5. package/dist/catalog/read-only.d.ts +45 -1
  6. package/dist/client/client.d.ts +49 -2
  7. package/dist/client/types.d.ts +56 -1
  8. package/dist/client-entry.js +239 -11
  9. package/dist/client-entry.js.map +9 -8
  10. package/dist/codec/asd.d.ts +8 -0
  11. package/dist/functions/copy-to.d.ts +1 -1
  12. package/dist/generated/vgi-client.d.ts +19 -0
  13. package/dist/generated/vgi-protocol-schemas.d.ts +3 -0
  14. package/dist/generated/vgi-protocol-types.d.ts +26 -0
  15. package/dist/http/fetch.d.ts +2 -1
  16. package/dist/index.core.d.ts +6 -3
  17. package/dist/index.js +672 -43
  18. package/dist/index.js.map +21 -17
  19. package/dist/protocol/handlers/catalog/contents.d.ts +27 -0
  20. package/dist/rpc-server.d.ts +97 -0
  21. package/dist/serve-entry.d.ts +2 -1
  22. package/dist/serve-entry.js +405 -25
  23. package/dist/serve-entry.js.map +18 -14
  24. package/dist/worker-cf-entry.d.ts +3 -0
  25. package/dist/worker-cf-entry.js +528 -31
  26. package/dist/worker-cf-entry.js.map +20 -16
  27. package/dist/worker.d.ts +9 -1
  28. package/package.json +3 -3
  29. package/src/catalog/composite.ts +81 -0
  30. package/src/catalog/contents-digest.ts +78 -0
  31. package/src/catalog/interface.ts +167 -5
  32. package/src/catalog/read-only.ts +68 -6
  33. package/src/client/client.ts +201 -0
  34. package/src/client/types.ts +58 -1
  35. package/src/codec/asd.ts +108 -9
  36. package/src/functions/copy-to.ts +1 -1
  37. package/src/generated/vgi-client.ts +22 -1
  38. package/src/generated/vgi-protocol-schemas.ts +30 -1
  39. package/src/generated/vgi-protocol-types.ts +126 -0
  40. package/src/http/fetch.ts +10 -2
  41. package/src/index.core.ts +23 -2
  42. package/src/protocol/dispatch.ts +1 -1
  43. package/src/protocol/handlers/catalog/admin.ts +35 -26
  44. package/src/protocol/handlers/catalog/contents.ts +162 -0
  45. package/src/protocol/handlers/catalog/macro.ts +2 -1
  46. package/src/protocol/handlers/catalog/shared.ts +12 -1
  47. package/src/rpc-server.ts +273 -0
  48. package/src/serve-entry.ts +7 -1
  49. package/src/worker-cf-entry.ts +8 -0
  50. package/src/worker.ts +24 -6
package/dist/index.js CHANGED
@@ -7035,7 +7035,84 @@ function schemaPathDisplay(path) {
7035
7035
  // src/codec/asd.ts
7036
7036
  init_arrow();
7037
7037
  function encodeASD(schema, obj) {
7038
- return serializeBatch(batchFromRows([obj], schema));
7038
+ return serializeBatch(batchFromRows([sortMapsForSchema(schema, obj)], schema));
7039
+ }
7040
+ function compareCodePoints(a, b) {
7041
+ const n = Math.min(a.length, b.length);
7042
+ for (let i = 0;i < n; i++) {
7043
+ const x = a.charCodeAt(i);
7044
+ const y = b.charCodeAt(i);
7045
+ if (x === y)
7046
+ continue;
7047
+ const xs = x >= 55296 && x <= 57343;
7048
+ const ys = y >= 55296 && y <= 57343;
7049
+ if (xs !== ys)
7050
+ return xs ? 1 : -1;
7051
+ return x - y;
7052
+ }
7053
+ return a.length - b.length;
7054
+ }
7055
+ function mapPairs(raw) {
7056
+ if (Array.isArray(raw))
7057
+ return raw.map((e) => Array.isArray(e) ? [e[0], e[1]] : [e?.key, e?.value]);
7058
+ if (raw instanceof Map)
7059
+ return Array.from(raw.entries());
7060
+ if (typeof raw[Symbol.iterator] === "function")
7061
+ return Array.from(raw);
7062
+ return Object.entries(raw);
7063
+ }
7064
+ function compareKeys(a, b) {
7065
+ if (typeof a === "string" && typeof b === "string")
7066
+ return compareCodePoints(a, b);
7067
+ if ((typeof a === "number" || typeof a === "bigint") && (typeof b === "number" || typeof b === "bigint")) {
7068
+ return a < b ? -1 : a > b ? 1 : 0;
7069
+ }
7070
+ return compareCodePoints(String(a), String(b));
7071
+ }
7072
+ var HAS_MAP = new WeakMap;
7073
+ function typeHasMap(type) {
7074
+ const cached = HAS_MAP.get(type);
7075
+ if (cached !== undefined)
7076
+ return cached;
7077
+ let has = isMap(type);
7078
+ if (!has && (isList(type) || isStruct(type))) {
7079
+ has = type.children.some((c) => typeHasMap(c.type));
7080
+ }
7081
+ HAS_MAP.set(type, has);
7082
+ return has;
7083
+ }
7084
+ function sortMapsForType(type, value) {
7085
+ if (value == null || !typeHasMap(type))
7086
+ return value;
7087
+ if (isMap(type)) {
7088
+ const entries = type.children[0].type;
7089
+ const valueType = entries.children[1].type;
7090
+ return mapPairs(value).map(([k, v]) => [k, sortMapsForType(valueType, v)]).sort((x, y) => compareKeys(x[0], y[0]));
7091
+ }
7092
+ if (isList(type)) {
7093
+ const child = type.children[0].type;
7094
+ return Array.from(value, (v) => sortMapsForType(child, v));
7095
+ }
7096
+ if (isStruct(type)) {
7097
+ const out = { ...value };
7098
+ for (const cf of type.children)
7099
+ out[cf.name] = sortMapsForType(cf.type, value[cf.name]);
7100
+ return out;
7101
+ }
7102
+ return value;
7103
+ }
7104
+ function sortMapsForSchema(schema, obj) {
7105
+ let out = null;
7106
+ for (const f of schema.fields) {
7107
+ if (!typeHasMap(f.type))
7108
+ continue;
7109
+ const v = obj[f.name];
7110
+ if (v == null)
7111
+ continue;
7112
+ out ??= { ...obj };
7113
+ out[f.name] = sortMapsForType(f.type, v);
7114
+ }
7115
+ return out ?? obj;
7039
7116
  }
7040
7117
  function decodeASD(schema, bytes) {
7041
7118
  const batch = deserializeBatch(bytes);
@@ -7062,21 +7139,23 @@ function normalizeValue(raw, type) {
7062
7139
  return out;
7063
7140
  }
7064
7141
  if (isMap(type)) {
7142
+ const entries = type.children[0].type;
7143
+ const valueType = entries.children[1].type;
7065
7144
  const out = {};
7145
+ const put = (k, v) => {
7146
+ out[String(k)] = normalizeValue(v, valueType);
7147
+ };
7066
7148
  if (raw[Symbol.iterator]) {
7067
7149
  for (const entry of raw) {
7068
7150
  if (Array.isArray(entry)) {
7069
- out[String(entry[0])] = String(entry[1] ?? "");
7151
+ put(entry[0], entry[1]);
7070
7152
  } else if (entry && typeof entry === "object") {
7071
- const k = entry.key ?? entry[0];
7072
- const v = entry.value ?? entry[1];
7073
- out[String(k)] = v == null ? "" : String(v);
7153
+ put(entry.key ?? entry[0], entry.value ?? entry[1]);
7074
7154
  }
7075
7155
  }
7076
7156
  } else if (typeof raw === "object") {
7077
- for (const [k, v] of Object.entries(raw)) {
7078
- out[String(k)] = v == null ? "" : String(v);
7079
- }
7157
+ for (const [k, v] of Object.entries(raw))
7158
+ put(k, v);
7080
7159
  }
7081
7160
  return out;
7082
7161
  }
@@ -7292,6 +7371,18 @@ var ForeignKeyInfoSchema = schema2([
7292
7371
  field2("referenced_table", utf82(), false),
7293
7372
  field2("referenced_schema_path", list2(field2("item", utf82(), true)), false)
7294
7373
  ]);
7374
+ var SchemaContentsSchema = schema2([
7375
+ field2("path", list2(field2("item", utf82(), true)), false),
7376
+ field2("schema", binary2(), false),
7377
+ field2("tables", list2(field2("item", binary2(), true)), false),
7378
+ field2("views", list2(field2("item", binary2(), true)), false),
7379
+ field2("scalar_functions", list2(field2("item", binary2(), true)), false),
7380
+ field2("aggregate_functions", list2(field2("item", binary2(), true)), false),
7381
+ field2("table_functions", list2(field2("item", binary2(), true)), false),
7382
+ field2("scalar_macros", list2(field2("item", binary2(), true)), false),
7383
+ field2("table_macros", list2(field2("item", binary2(), true)), false),
7384
+ field2("indexes", list2(field2("item", binary2(), true)), false)
7385
+ ]);
7295
7386
  var AggregateBindRequestSchema = schema2([
7296
7387
  field2("function_name", utf82(), false),
7297
7388
  field2("arguments", binary2(), false),
@@ -7614,11 +7705,18 @@ var CatalogAttachResultSchema = schema2([
7614
7705
  field2("global_functions", list2(field2("item", binary2(), true)), false),
7615
7706
  field2("global_function_prefix", utf82(), false),
7616
7707
  field2("resolved_data_version", utf82(), true),
7617
- field2("resolved_implementation_version", utf82(), true)
7708
+ field2("resolved_implementation_version", utf82(), true),
7709
+ field2("supports_catalog_contents", bool2(), false)
7618
7710
  ]);
7619
7711
  var CatalogCatalogsResultSchema = schema2([
7620
7712
  field2("items", list2(field2("item", binary2(), true)), false)
7621
7713
  ]);
7714
+ var CatalogContentsResultSchema = schema2([
7715
+ field2("catalog_version", int642(), false),
7716
+ field2("etag", utf82(), true),
7717
+ field2("not_modified", bool2(), false),
7718
+ field2("schemas", list2(field2("item", struct2([field2("path", list2(field2("item", utf82(), true)), false), field2("schema", binary2(), false), field2("tables", list2(field2("item", binary2(), true)), false), field2("views", list2(field2("item", binary2(), true)), false), field2("scalar_functions", list2(field2("item", binary2(), true)), false), field2("aggregate_functions", list2(field2("item", binary2(), true)), false), field2("table_functions", list2(field2("item", binary2(), true)), false), field2("scalar_macros", list2(field2("item", binary2(), true)), false), field2("table_macros", list2(field2("item", binary2(), true)), false), field2("indexes", list2(field2("item", binary2(), true)), false)]), true)), false)
7719
+ ]);
7622
7720
  var CatalogCopyFromFormatsResultSchema = schema2([
7623
7721
  field2("items", list2(field2("item", binary2(), true)), false)
7624
7722
  ]);
@@ -7737,6 +7835,10 @@ var CatalogAttachParamsSchema = schema2([
7737
7835
  field2("request", binary2(), false)
7738
7836
  ]);
7739
7837
  var CatalogCatalogsParamsSchema = schema2([]);
7838
+ var CatalogContentsParamsSchema = schema2([
7839
+ field2("attach_opaque_data", binary2(), false),
7840
+ field2("if_none_match", utf82(), true)
7841
+ ]);
7740
7842
  var CatalogCopyFromFormatsParamsSchema = schema2([
7741
7843
  field2("attach_opaque_data", binary2(), false),
7742
7844
  field2("transaction_opaque_data", binary2(), true)
@@ -8067,12 +8169,59 @@ var TableFunctionStatisticsParamsSchema = schema2([
8067
8169
  field2("request", binary2(), false)
8068
8170
  ]);
8069
8171
 
8172
+ // src/generated/vgi-protocol-types.ts
8173
+ function buildCatalogAttachResult(init) {
8174
+ return {
8175
+ attach_opaque_data: init.attach_opaque_data,
8176
+ supports_transactions: init.supports_transactions,
8177
+ supports_time_travel: init.supports_time_travel,
8178
+ catalog_version_frozen: init.catalog_version_frozen,
8179
+ catalog_version: init.catalog_version,
8180
+ attach_opaque_data_required: init.attach_opaque_data_required ?? true,
8181
+ default_schema: init.default_schema ?? "main",
8182
+ settings: init.settings ?? [],
8183
+ secret_types: init.secret_types ?? [],
8184
+ attach_catalogs: init.attach_catalogs ?? [],
8185
+ comment: init.comment ?? null,
8186
+ tags: init.tags ?? {},
8187
+ supports_column_statistics: init.supports_column_statistics ?? false,
8188
+ global_functions: init.global_functions ?? [],
8189
+ global_function_prefix: init.global_function_prefix ?? "",
8190
+ resolved_data_version: init.resolved_data_version ?? null,
8191
+ resolved_implementation_version: init.resolved_implementation_version ?? null,
8192
+ supports_catalog_contents: init.supports_catalog_contents ?? false
8193
+ };
8194
+ }
8195
+ function buildSchemaContents(init) {
8196
+ return {
8197
+ path: init.path,
8198
+ schema: init.schema,
8199
+ tables: init.tables ?? [],
8200
+ views: init.views ?? [],
8201
+ scalar_functions: init.scalar_functions ?? [],
8202
+ aggregate_functions: init.aggregate_functions ?? [],
8203
+ table_functions: init.table_functions ?? [],
8204
+ scalar_macros: init.scalar_macros ?? [],
8205
+ table_macros: init.table_macros ?? [],
8206
+ indexes: init.indexes ?? []
8207
+ };
8208
+ }
8209
+ function buildCatalogContentsResponse(init) {
8210
+ return {
8211
+ catalog_version: init.catalog_version,
8212
+ etag: init.etag ?? null,
8213
+ not_modified: init.not_modified ?? false,
8214
+ schemas: init.schemas ?? []
8215
+ };
8216
+ }
8217
+ var decodeCatalogContentsResponse = (b) => decodeASD(CatalogContentsResultSchema, b);
8070
8218
  // src/generated/vgi-client.ts
8071
8219
  var encodeCatalogInfo = (v) => encodeASD(CatalogInfoSchema, v);
8072
8220
  var decodeCatalogInfo = (b) => decodeASD(CatalogInfoSchema, b);
8073
8221
  var encodeFunctionInfo = (v) => encodeASD(FunctionInfoSchema, v);
8074
8222
  var decodeFunctionInfo = (b) => decodeASD(FunctionInfoSchema, b);
8075
8223
  var encodeIndexInfo = (v) => encodeASD(IndexInfoSchema, v);
8224
+ var decodeIndexInfo = (b) => decodeASD(IndexInfoSchema, b);
8076
8225
  var encodeMacroInfo = (v) => encodeASD(MacroInfoSchema, v);
8077
8226
  var decodeMacroInfo = (b) => decodeASD(MacroInfoSchema, b);
8078
8227
  var encodeSchemaInfo = (v) => encodeASD(SchemaInfoSchema, v);
@@ -8215,6 +8364,9 @@ function isPromise(v) {
8215
8364
  }
8216
8365
 
8217
8366
  class CatalogInterface {
8367
+ catalogContentsEtag = null;
8368
+ catalogContentsAttachIndependent = false;
8369
+ catalogVersionFrozen = false;
8218
8370
  catalogNameForAttach(_attachOpaqueData) {
8219
8371
  const names = this.catalogs();
8220
8372
  return names.length === 1 ? names[0] : null;
@@ -8332,6 +8484,42 @@ class CatalogInterface {
8332
8484
  copyFromFormats(attachOpaqueData, transactionOpaqueData) {
8333
8485
  return [];
8334
8486
  }
8487
+ async catalogContents(attachOpaqueData, _ifNoneMatch) {
8488
+ const schemas = await this.schemas(attachOpaqueData, undefined);
8489
+ const contents = await Promise.all(schemas.map(async (schema) => {
8490
+ const counts = schema.estimated_object_count ?? {};
8491
+ const path = schema.path;
8492
+ const kind = async (countKey, list) => (counts[countKey] ?? 1) === 0 ? [] : [...await list()];
8493
+ const [tables, views, scalarFunctions, aggregateFunctions, tableFunctions, scalarMacros, tableMacros, indexes] = await Promise.all([
8494
+ kind("table", () => this.schemaContentsTables(attachOpaqueData, path)),
8495
+ kind("view", () => this.schemaContentsViews(attachOpaqueData, path)),
8496
+ kind("scalar_function", () => this.schemaContentsFunctions(attachOpaqueData, path, "scalar_function")),
8497
+ kind("aggregate_function", () => this.schemaContentsFunctions(attachOpaqueData, path, "aggregate_function")),
8498
+ kind("table_function", () => this.schemaContentsFunctions(attachOpaqueData, path, "table_function")),
8499
+ kind("macro", () => this.schemaContentsMacros(attachOpaqueData, path, "scalar_macro")),
8500
+ kind("macro", () => this.schemaContentsMacros(attachOpaqueData, path, "table_macro")),
8501
+ kind("index", () => this.schemaContentsIndexes(attachOpaqueData, path))
8502
+ ]);
8503
+ return {
8504
+ schema,
8505
+ tables,
8506
+ views,
8507
+ scalar_functions: scalarFunctions,
8508
+ aggregate_functions: aggregateFunctions,
8509
+ table_functions: tableFunctions,
8510
+ scalar_macros: scalarMacros,
8511
+ table_macros: tableMacros,
8512
+ indexes
8513
+ };
8514
+ }));
8515
+ return { schemas: contents };
8516
+ }
8517
+ catalogContentsCacheable() {
8518
+ return this.catalogContentsAttachIndependent && this.catalogVersionFrozen;
8519
+ }
8520
+ catalogContentsOwner(_attachOpaqueData) {
8521
+ return this;
8522
+ }
8335
8523
  transactionBegin(attachOpaqueData) {
8336
8524
  return null;
8337
8525
  }
@@ -8594,17 +8782,25 @@ function encodeFunctionInfoOnce(info) {
8594
8782
  }
8595
8783
 
8596
8784
  // src/catalog/read-only.ts
8785
+ var READ_ONLY_ITEM_ATTACH_ID = new TextEncoder().encode("readonly-catalog-");
8786
+
8597
8787
  class ReadOnlyCatalogInterface extends CatalogInterface {
8788
+ supportsCatalogContents = true;
8789
+ catalogVersionFrozen = true;
8790
+ perAttachItemIds = false;
8791
+ catalogContentsAttachIndependent = true;
8598
8792
  _descriptor;
8599
8793
  _registry;
8600
8794
  _attachments = new Map;
8601
8795
  _version = 1;
8602
8796
  _functionListings = new Map;
8603
8797
  _functionInfos = new Map;
8604
- constructor(descriptor, registry) {
8798
+ constructor(descriptor, registry, options = {}) {
8605
8799
  super();
8606
8800
  this._descriptor = descriptor;
8607
8801
  this._registry = registry;
8802
+ if (options.perAttachItemIds)
8803
+ this.perAttachItemIds = true;
8608
8804
  for (const sch of descriptor.schemas ?? []) {
8609
8805
  for (const fn of sch.functions ?? [])
8610
8806
  registry.registerInSchema(fn, schemaDescriptorPath(sch), descriptor.name);
@@ -8652,7 +8848,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8652
8848
  const secretTypes = (this._descriptor.secretTypes ?? []).map((s) => serializeSecretType(s));
8653
8849
  const attachCatalogs = (this._descriptor.attachCatalogs ?? []).map((c) => encodeAttachCatalogInfo(c));
8654
8850
  const hasTimeTravel = this._descriptor.schemas.some((s) => s.tables?.some((t) => t.supportsTimeTravel) ?? false);
8655
- return {
8851
+ return buildCatalogAttachResult({
8656
8852
  attach_opaque_data: attachOpaqueData,
8657
8853
  supports_transactions: false,
8658
8854
  supports_time_travel: hasTimeTravel,
@@ -8669,8 +8865,9 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8669
8865
  global_functions: this._globalFunctionInfos().map(encodeFunctionInfoOnce),
8670
8866
  global_function_prefix: this._descriptor.globalFunctionPrefix ?? "",
8671
8867
  resolved_data_version: null,
8672
- resolved_implementation_version: null
8673
- };
8868
+ resolved_implementation_version: null,
8869
+ supports_catalog_contents: this.supportsCatalogContents
8870
+ });
8674
8871
  }
8675
8872
  detach(attachOpaqueData) {
8676
8873
  for (const [name, id] of this._attachments) {
@@ -8683,9 +8880,15 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8683
8880
  version(attachOpaqueData, transactionOpaqueData) {
8684
8881
  return this._version;
8685
8882
  }
8883
+ itemAttachId(attachOpaqueData) {
8884
+ return this.perAttachItemIds ? attachOpaqueData : READ_ONLY_ITEM_ATTACH_ID;
8885
+ }
8886
+ catalogContentsCacheable() {
8887
+ return super.catalogContentsCacheable() && !this.perAttachItemIds;
8888
+ }
8686
8889
  schemas(attachOpaqueData, transactionOpaqueData) {
8687
8890
  return this._descriptor.schemas.map((s) => ({
8688
- attach_opaque_data: attachOpaqueData,
8891
+ attach_opaque_data: this.itemAttachId(attachOpaqueData),
8689
8892
  path: schemaDescriptorPath(s),
8690
8893
  comment: s.comment ?? null,
8691
8894
  tags: s.tags ?? {},
@@ -8717,7 +8920,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8717
8920
  if (!desc)
8718
8921
  return null;
8719
8922
  return {
8720
- attach_opaque_data: attachOpaqueData,
8923
+ attach_opaque_data: this.itemAttachId(attachOpaqueData),
8721
8924
  path: schemaDescriptorPath(desc),
8722
8925
  comment: desc.comment ?? null,
8723
8926
  tags: desc.tags ?? {},
@@ -8743,7 +8946,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
8743
8946
  input_schema: null,
8744
8947
  settings: null,
8745
8948
  secrets: null,
8746
- attach_opaque_data: attachOpaqueData,
8949
+ attach_opaque_data: this.itemAttachId(attachOpaqueData),
8747
8950
  transaction_opaque_data: null,
8748
8951
  resolved_secrets_provided: false
8749
8952
  };
@@ -9417,6 +9620,72 @@ class CompositeCatalogInterface extends CatalogInterface {
9417
9620
  async macroGet(attachOpaqueData, schemaPath, name, transactionOpaqueData) {
9418
9621
  return await this._route(attachOpaqueData).macroGet(attachOpaqueData, schemaPath, name, transactionOpaqueData);
9419
9622
  }
9623
+ async schemaCreate(...args) {
9624
+ await this._route(args[0]).schemaCreate(...args);
9625
+ }
9626
+ async schemaDrop(...args) {
9627
+ await this._route(args[0]).schemaDrop(...args);
9628
+ }
9629
+ async tableCreate(...args) {
9630
+ await this._route(args[0]).tableCreate(...args);
9631
+ }
9632
+ async tableDrop(...args) {
9633
+ await this._route(args[0]).tableDrop(...args);
9634
+ }
9635
+ async tableCommentSet(...args) {
9636
+ await this._route(args[0]).tableCommentSet(...args);
9637
+ }
9638
+ async tableRename(...args) {
9639
+ await this._route(args[0]).tableRename(...args);
9640
+ }
9641
+ async tableColumnAdd(...args) {
9642
+ await this._route(args[0]).tableColumnAdd(...args);
9643
+ }
9644
+ async tableColumnDrop(...args) {
9645
+ await this._route(args[0]).tableColumnDrop(...args);
9646
+ }
9647
+ async tableColumnRename(...args) {
9648
+ await this._route(args[0]).tableColumnRename(...args);
9649
+ }
9650
+ async tableColumnDefaultSet(...args) {
9651
+ await this._route(args[0]).tableColumnDefaultSet(...args);
9652
+ }
9653
+ async tableColumnDefaultDrop(...args) {
9654
+ await this._route(args[0]).tableColumnDefaultDrop(...args);
9655
+ }
9656
+ async tableColumnTypeChange(...args) {
9657
+ await this._route(args[0]).tableColumnTypeChange(...args);
9658
+ }
9659
+ async tableNotNullSet(...args) {
9660
+ await this._route(args[0]).tableNotNullSet(...args);
9661
+ }
9662
+ async tableNotNullDrop(...args) {
9663
+ await this._route(args[0]).tableNotNullDrop(...args);
9664
+ }
9665
+ async viewCreate(...args) {
9666
+ await this._route(args[0]).viewCreate(...args);
9667
+ }
9668
+ async viewDrop(...args) {
9669
+ await this._route(args[0]).viewDrop(...args);
9670
+ }
9671
+ async viewRename(...args) {
9672
+ await this._route(args[0]).viewRename(...args);
9673
+ }
9674
+ async viewCommentSet(...args) {
9675
+ await this._route(args[0]).viewCommentSet(...args);
9676
+ }
9677
+ async macroCreate(...args) {
9678
+ await this._route(args[0]).macroCreate(...args);
9679
+ }
9680
+ async macroDrop(...args) {
9681
+ await this._route(args[0]).macroDrop(...args);
9682
+ }
9683
+ async catalogContents(attachOpaqueData, ifNoneMatch) {
9684
+ return await this._route(attachOpaqueData).catalogContents(attachOpaqueData, ifNoneMatch);
9685
+ }
9686
+ catalogContentsOwner(attachOpaqueData) {
9687
+ return this._route(attachOpaqueData).catalogContentsOwner(attachOpaqueData);
9688
+ }
9420
9689
  async copyFromFormats(attachOpaqueData, transactionOpaqueData) {
9421
9690
  return await this._route(attachOpaqueData).copyFromFormats(attachOpaqueData, transactionOpaqueData);
9422
9691
  }
@@ -10819,6 +11088,9 @@ function catalogUnary(protocol, signingKey, name, config) {
10819
11088
  result: config.result,
10820
11089
  doc: config.doc,
10821
11090
  handler: async (params, ctx) => {
11091
+ if (params.request != null && params.attach_opaque_data === undefined && params.name === undefined) {
11092
+ params = unwrapRequest(params.request);
11093
+ }
10822
11094
  normalizeRequestSchemaPaths(params);
10823
11095
  await unwrapParamsOpaque(params, ctx, signingKey);
10824
11096
  return config.handler(params, ctx);
@@ -11672,6 +11944,134 @@ function hex(buf) {
11672
11944
  return Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("");
11673
11945
  }
11674
11946
 
11947
+ // src/catalog/contents-digest.ts
11948
+ var KINDS = [
11949
+ "tables",
11950
+ "views",
11951
+ "scalar_functions",
11952
+ "aggregate_functions",
11953
+ "table_functions",
11954
+ "scalar_macros",
11955
+ "table_macros",
11956
+ "indexes"
11957
+ ];
11958
+ async function catalogContentsDigest(schemas) {
11959
+ const utf8 = new TextEncoder;
11960
+ const parts = [];
11961
+ let total = 0;
11962
+ const count = (n) => {
11963
+ const b = new Uint8Array(8);
11964
+ new DataView(b.buffer).setBigUint64(0, BigInt(n), true);
11965
+ parts.push(b);
11966
+ total += 8;
11967
+ };
11968
+ const chunk = (data) => {
11969
+ count(data.byteLength);
11970
+ parts.push(data);
11971
+ total += data.byteLength;
11972
+ };
11973
+ const chunks = (values) => {
11974
+ count(values.length);
11975
+ for (const v of values)
11976
+ chunk(v);
11977
+ };
11978
+ count(schemas.length);
11979
+ for (const entry of schemas) {
11980
+ chunks(entry.path.map((p) => utf8.encode(p)));
11981
+ chunk(entry.schema);
11982
+ for (const kind of KINDS)
11983
+ chunks(entry[kind]);
11984
+ }
11985
+ const buf = new Uint8Array(total);
11986
+ let off = 0;
11987
+ for (const p of parts) {
11988
+ buf.set(p, off);
11989
+ off += p.byteLength;
11990
+ }
11991
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", buf));
11992
+ let hex = "";
11993
+ for (const b of digest)
11994
+ hex += b.toString(16).padStart(2, "0");
11995
+ return hex;
11996
+ }
11997
+
11998
+ // src/protocol/handlers/catalog/contents.ts
11999
+ var CACHE = new WeakMap;
12000
+ async function buildCatalogContents(cat, owner, attach, version, ifNoneMatch) {
12001
+ const result = await cat.catalogContents(attach, ifNoneMatch);
12002
+ const etag0 = result.etag ?? null;
12003
+ if (result.not_modified) {
12004
+ if (etag0 === null || ifNoneMatch === null || etag0 !== ifNoneMatch) {
12005
+ throw new Error("catalog_contents returned not_modified, but only a catalog whose etag equals " + "if_none_match may (and it must return that etag)");
12006
+ }
12007
+ if (result.schemas && result.schemas.length > 0) {
12008
+ throw new Error("catalog_contents returned not_modified with schemas; it must return none");
12009
+ }
12010
+ return buildCatalogContentsResponse({ catalog_version: version, etag: etag0, not_modified: true });
12011
+ }
12012
+ const infos = [...result.schemas ?? []];
12013
+ const keys = infos.map((c) => schemaPathKey(c.schema.path));
12014
+ const keySet = new Set(keys);
12015
+ if (keySet.size !== keys.length)
12016
+ throw new Error("catalog_contents returned duplicate schema paths");
12017
+ for (const c of infos) {
12018
+ if (c.schema.path.length > 1 && !keySet.has(schemaPathKey(c.schema.path.slice(0, -1)))) {
12019
+ throw new Error(`catalog_contents returned schema path ${JSON.stringify(c.schema.path)} without its parent`);
12020
+ }
12021
+ }
12022
+ const schemas = infos.sort((a, b) => a.schema.path.length - b.schema.path.length).map((c) => buildSchemaContents({
12023
+ path: [...c.schema.path],
12024
+ schema: encodeSchemaInfo(c.schema),
12025
+ tables: c.tables.map((t) => encodeTableInfo(t)),
12026
+ views: c.views.map((v) => encodeViewInfo(v)),
12027
+ scalar_functions: c.scalar_functions.map((f) => encodeFunctionInfoOnce(f)),
12028
+ aggregate_functions: c.aggregate_functions.map((f) => encodeFunctionInfoOnce(f)),
12029
+ table_functions: c.table_functions.map((f) => encodeFunctionInfoOnce(f)),
12030
+ scalar_macros: c.scalar_macros.map((m) => encodeMacroInfo(m)),
12031
+ table_macros: c.table_macros.map((m) => encodeMacroInfo(m)),
12032
+ indexes: c.indexes.map((i) => encodeIndexInfo(i))
12033
+ }));
12034
+ let etag = etag0;
12035
+ if (etag === null && owner.catalogContentsEtag === "content-hash") {
12036
+ etag = await catalogContentsDigest(schemas);
12037
+ }
12038
+ if (etag !== null && ifNoneMatch !== null && etag === ifNoneMatch) {
12039
+ return buildCatalogContentsResponse({ catalog_version: version, etag, not_modified: true });
12040
+ }
12041
+ return buildCatalogContentsResponse({ catalog_version: version, etag, schemas });
12042
+ }
12043
+ async function serveCatalogContents(cat, attach, ifNoneMatch) {
12044
+ const owner = cat.catalogContentsOwner(attach);
12045
+ const version = Number(await cat.version(attach));
12046
+ if (owner.catalogContentsCacheable()) {
12047
+ let pending = CACHE.get(owner);
12048
+ let snapshot = pending ? await pending.catch(() => null) : null;
12049
+ if (!snapshot || snapshot.version !== version) {
12050
+ pending = (async () => {
12051
+ const built = await buildCatalogContents(cat, owner, attach, version, null);
12052
+ return {
12053
+ version,
12054
+ etag: built.etag ?? null,
12055
+ wire: wrapResult(built, CatalogContentsResultSchema)
12056
+ };
12057
+ })();
12058
+ CACHE.set(owner, pending);
12059
+ try {
12060
+ snapshot = await pending;
12061
+ } catch (err) {
12062
+ if (CACHE.get(owner) === pending)
12063
+ CACHE.delete(owner);
12064
+ throw err;
12065
+ }
12066
+ }
12067
+ if (ifNoneMatch !== null && snapshot.etag !== null && ifNoneMatch === snapshot.etag) {
12068
+ return wrapResult(buildCatalogContentsResponse({ catalog_version: version, etag: snapshot.etag, not_modified: true }), CatalogContentsResultSchema);
12069
+ }
12070
+ return snapshot.wire;
12071
+ }
12072
+ return wrapResult(await buildCatalogContents(cat, owner, attach, version, ifNoneMatch), CatalogContentsResultSchema);
12073
+ }
12074
+
11675
12075
  // src/protocol/handlers/catalog/admin.ts
11676
12076
  function registerCatalogAdminMethods(protocol, getCatalog, signingKey) {
11677
12077
  catalogUnary(protocol, signingKey, "catalog_catalogs", {
@@ -11699,25 +12099,11 @@ function registerCatalogAdminMethods(protocol, getCatalog, signingKey) {
11699
12099
  const optionsDict = decodeOptionsBatch(innerParams.options);
11700
12100
  const result = await cat.attach(innerParams.name, optionsDict, innerParams.data_version_spec ?? null, innerParams.implementation_version ?? null);
11701
12101
  const sealedAttach = await sealAttach(toUint8Array(result.attach_opaque_data), ctx?.auth, signingKey);
11702
- return wrapResult({
12102
+ return wrapResult(buildCatalogAttachResult({
12103
+ ...result,
11703
12104
  attach_opaque_data: sealedAttach,
11704
- supports_transactions: result.supports_transactions,
11705
- supports_time_travel: result.supports_time_travel,
11706
- catalog_version_frozen: result.catalog_version_frozen,
11707
- catalog_version: result.catalog_version,
11708
- attach_opaque_data_required: result.attach_opaque_data_required ?? true,
11709
- default_schema: result.default_schema ?? "main",
11710
- settings: result.settings ?? [],
11711
- secret_types: result.secret_types ?? [],
11712
- attach_catalogs: result.attach_catalogs ?? [],
11713
- comment: result.comment ?? null,
11714
- tags: result.tags ?? {},
11715
- supports_column_statistics: result.supports_column_statistics ?? true,
11716
- global_functions: result.global_functions ?? [],
11717
- global_function_prefix: result.global_function_prefix ?? "",
11718
- resolved_data_version: result.resolved_data_version ?? null,
11719
- resolved_implementation_version: result.resolved_implementation_version ?? null
11720
- }, CatalogAttachResultSchema);
12105
+ supports_column_statistics: result.supports_column_statistics ?? true
12106
+ }), CatalogAttachResultSchema);
11721
12107
  }
11722
12108
  });
11723
12109
  catalogUnary(protocol, signingKey, "catalog_detach", {
@@ -11798,6 +12184,14 @@ function registerCatalogAdminMethods(protocol, getCatalog, signingKey) {
11798
12184
  }, CatalogSchemasResultSchema);
11799
12185
  }
11800
12186
  });
12187
+ catalogUnary(protocol, signingKey, "catalog_contents", {
12188
+ params: CatalogContentsParamsSchema,
12189
+ result: RESULT_BINARY_SCHEMA,
12190
+ handler: async (params) => {
12191
+ const ifNoneMatch = params.if_none_match == null ? null : String(params.if_none_match);
12192
+ return serveCatalogContents(getCatalog(), toUint8Array(params.attach_opaque_data), ifNoneMatch);
12193
+ }
12194
+ });
11801
12195
  catalogUnary(protocol, signingKey, "catalog_copy_from_formats", {
11802
12196
  params: CatalogCopyFromFormatsParamsSchema,
11803
12197
  result: RESULT_BINARY_SCHEMA,
@@ -12092,7 +12486,7 @@ function registerCatalogMacroMethods(protocol, getCatalog, signingKey) {
12092
12486
  result: emptyResultSchema,
12093
12487
  handler: async (params) => {
12094
12488
  const cat = getCatalog();
12095
- const innerParams = unwrapRequest(params.request);
12489
+ const innerParams = params;
12096
12490
  await cat.macroCreate(toUint8Array(innerParams.attach_opaque_data), innerParams.schema_path, innerParams.name, innerParams.macro_type, innerParams.parameters ? Array.isArray(innerParams.parameters) ? innerParams.parameters : [...innerParams.parameters] : [], innerParams.definition, innerParams.on_conflict, innerParams.parameter_default_values ? toUint8Array(innerParams.parameter_default_values) : null, innerParams.arguments_schema ? toUint8Array(innerParams.arguments_schema) : null, innerParams.transaction_opaque_data ? toUint8Array(innerParams.transaction_opaque_data) : undefined);
12097
12491
  return {};
12098
12492
  }
@@ -12158,7 +12552,7 @@ function registerCatalogMethods(protocol, catalog, _catalogName, signingKey) {
12158
12552
  // src/protocol/dispatch.ts
12159
12553
  var VGI_PROTOCOL_NAME = "vgi.v2";
12160
12554
  function buildVgiProtocol(config) {
12161
- const protocol = new Protocol(VGI_PROTOCOL_NAME, { protocolVersion: "2.0.0" });
12555
+ const protocol = new Protocol(VGI_PROTOCOL_NAME, { protocolVersion: "2.1.0" });
12162
12556
  registerFunctionMethods(protocol, {
12163
12557
  registry: config.registry,
12164
12558
  signingKey: config.signingKey,
@@ -12798,7 +13192,118 @@ class VgiClient {
12798
13192
  global_functions: inner.global_functions ? (Array.isArray(inner.global_functions) ? inner.global_functions : [...inner.global_functions]).map(toUint8Array) : [],
12799
13193
  global_function_prefix: inner.global_function_prefix ?? "",
12800
13194
  resolved_data_version: inner.resolved_data_version ?? null,
12801
- resolved_implementation_version: inner.resolved_implementation_version ?? null
13195
+ resolved_implementation_version: inner.resolved_implementation_version ?? null,
13196
+ supports_catalog_contents: inner.supports_catalog_contents ?? false
13197
+ };
13198
+ }
13199
+ async catalogContents(attachOpaqueData, ifNoneMatch = null) {
13200
+ const result = await this.rpc.call("catalog_contents", {
13201
+ attach_opaque_data: attachOpaqueData,
13202
+ if_none_match: ifNoneMatch
13203
+ });
13204
+ if (!result)
13205
+ throw new VgiClientError("catalog_contents returned null");
13206
+ const response = decodeCatalogContentsResponse(toUint8Array(result.result));
13207
+ const schemas = response.schemas.map((c) => {
13208
+ const schema = decodeSchemaInfo(c.schema);
13209
+ if (JSON.stringify(c.path) !== JSON.stringify(schema.path)) {
13210
+ throw new VgiClientError(`catalog_contents: SchemaContents.path ${JSON.stringify(c.path)} != SchemaInfo.path ${JSON.stringify(schema.path)}`);
13211
+ }
13212
+ return {
13213
+ schema,
13214
+ tables: c.tables.map(decodeTableInfo),
13215
+ views: c.views.map(decodeViewInfo),
13216
+ scalar_functions: c.scalar_functions.map(decodeFunctionInfo),
13217
+ aggregate_functions: c.aggregate_functions.map(decodeFunctionInfo),
13218
+ table_functions: c.table_functions.map(decodeFunctionInfo),
13219
+ scalar_macros: c.scalar_macros.map(decodeMacroInfo),
13220
+ table_macros: c.table_macros.map(decodeMacroInfo),
13221
+ indexes: c.indexes.map(decodeIndexInfo)
13222
+ };
13223
+ });
13224
+ return {
13225
+ catalog_version: Number(response.catalog_version ?? 0),
13226
+ etag: response.etag ?? null,
13227
+ not_modified: Boolean(response.not_modified),
13228
+ schemas
13229
+ };
13230
+ }
13231
+ async loadCatalog(attach, opts) {
13232
+ const attachOpaqueData = attach.attach_opaque_data;
13233
+ const previous = opts?.previous ?? null;
13234
+ const useContents = attach.supports_catalog_contents === true && opts?.useCatalogContents !== false && opts?.transactionOpaqueData == null;
13235
+ if (!useContents) {
13236
+ return this._loadCatalogPerSchema(attachOpaqueData, opts?.transactionOpaqueData, null);
13237
+ }
13238
+ let fallbackError = null;
13239
+ const ifNoneMatch = previous?.etag ?? null;
13240
+ const knownVersion = previous?.catalog_version ?? 0;
13241
+ for (let attempt = 0;attempt < 2; attempt++) {
13242
+ let response;
13243
+ try {
13244
+ response = await this.catalogContents(attachOpaqueData, ifNoneMatch);
13245
+ } catch (err) {
13246
+ fallbackError = err instanceof Error ? err.message : String(err);
13247
+ break;
13248
+ }
13249
+ if (response.not_modified) {
13250
+ if (previous == null || ifNoneMatch == null) {
13251
+ fallbackError = "catalog_contents answered not_modified to an unconditional request";
13252
+ break;
13253
+ }
13254
+ return {
13255
+ ...previous,
13256
+ catalog_version: response.catalog_version !== 0 ? response.catalog_version : previous.catalog_version,
13257
+ etag: response.etag ?? ifNoneMatch,
13258
+ not_modified: true,
13259
+ fallback_error: null
13260
+ };
13261
+ }
13262
+ if (response.catalog_version !== 0 && knownVersion !== 0 && response.catalog_version < knownVersion) {
13263
+ fallbackError = `catalog_contents snapshot version ${response.catalog_version} is older than the known version ${knownVersion}`;
13264
+ continue;
13265
+ }
13266
+ return {
13267
+ catalog_version: response.catalog_version,
13268
+ etag: response.etag,
13269
+ source: "catalog_contents",
13270
+ not_modified: false,
13271
+ fallback_error: null,
13272
+ schemas: response.schemas
13273
+ };
13274
+ }
13275
+ return this._loadCatalogPerSchema(attachOpaqueData, undefined, fallbackError);
13276
+ }
13277
+ async _loadCatalogPerSchema(attachOpaqueData, transactionOpaqueData, fallbackError) {
13278
+ const schemas = await this.schemas(attachOpaqueData, transactionOpaqueData);
13279
+ const out = [];
13280
+ for (const schema of schemas) {
13281
+ const counts = schema.estimated_object_count ?? {};
13282
+ const path = schema.path;
13283
+ const has = (kind) => {
13284
+ const n = counts[kind];
13285
+ return n == null || Number(n) !== 0;
13286
+ };
13287
+ const t = transactionOpaqueData;
13288
+ out.push({
13289
+ schema,
13290
+ tables: has("table") ? await this.schemaContentsTables(attachOpaqueData, path, t) : [],
13291
+ views: has("view") ? await this.schemaContentsViews(attachOpaqueData, path, t) : [],
13292
+ scalar_functions: has("scalar_function") ? await this.schemaContentsFunctions(attachOpaqueData, path, "SCALAR_FUNCTION", t) : [],
13293
+ aggregate_functions: has("aggregate_function") ? await this.schemaContentsFunctions(attachOpaqueData, path, "AGGREGATE_FUNCTION", t) : [],
13294
+ table_functions: has("table_function") ? await this.schemaContentsFunctions(attachOpaqueData, path, "TABLE_FUNCTION", t) : [],
13295
+ scalar_macros: has("macro") ? await this.schemaContentsMacros(attachOpaqueData, path, "SCALAR_MACRO", t) : [],
13296
+ table_macros: has("macro") ? await this.schemaContentsMacros(attachOpaqueData, path, "TABLE_MACRO", t) : [],
13297
+ indexes: has("index") ? await this.schemaContentsIndexes(attachOpaqueData, path, t) : []
13298
+ });
13299
+ }
13300
+ return {
13301
+ catalog_version: null,
13302
+ etag: null,
13303
+ source: "per_schema",
13304
+ not_modified: false,
13305
+ fallback_error: fallbackError,
13306
+ schemas: out
12802
13307
  };
12803
13308
  }
12804
13309
  async catalogDetach(attachOpaqueData) {
@@ -12939,6 +13444,17 @@ class VgiClient {
12939
13444
  const inner = unwrapResult(result);
12940
13445
  return deserializeInfoList(inner.items, decodeFunctionInfo);
12941
13446
  }
13447
+ async schemaContentsIndexes(attachOpaqueData, path, transactionOpaqueData) {
13448
+ const result = await this.rpc.call("catalog_schema_contents_indexes", {
13449
+ attach_opaque_data: attachOpaqueData,
13450
+ path: normalizeSchemaPath(path),
13451
+ transaction_opaque_data: transactionOpaqueData ?? null
13452
+ });
13453
+ if (!result)
13454
+ return [];
13455
+ const inner = unwrapResult(result);
13456
+ return deserializeInfoList(inner.items, decodeIndexInfo);
13457
+ }
12942
13458
  async tableGet(attachOpaqueData, schemaPath, name, transactionOpaqueData) {
12943
13459
  const result = await this.rpc.call("catalog_table_get", {
12944
13460
  attach_opaque_data: attachOpaqueData,
@@ -13203,9 +13719,103 @@ class VgiClient {
13203
13719
  // src/index.core.ts
13204
13720
  import { str, bytes, int as int3, int32 as int323, float, float32 as float323, bool as bool3, toSchema, OutputCollector, AuthContext } from "@query-farm/vgi-rpc";
13205
13721
  import { subprocessConnect, httpConnect, tcpConnect } from "@query-farm/vgi-rpc";
13722
+
13723
+ // src/rpc-server.ts
13724
+ import {
13725
+ IdentityImpl,
13726
+ VgiRpcServer
13727
+ } from "@query-farm/vgi-rpc";
13728
+ var TRANSPORTS = new Set(["pipe", "unix", "tcp", "iroh", "stream", "http"]);
13729
+ var IDENTITY_TRANSPORTS = new Set(["http"]);
13730
+ var RESERVED_PREFIX = "vgi_rpc.";
13731
+ var INTROSPECT_PRINCIPALS_ENV = "VGI_INTROSPECT_PRINCIPALS";
13732
+ function buildRpcServer(primary, hosting, options) {
13733
+ if (!TRANSPORTS.has(options.transport)) {
13734
+ throw new Error(`Unknown transport ${JSON.stringify(options.transport)}; expected one of ${[...TRANSPORTS].join(", ")}.`);
13735
+ }
13736
+ const protocols = validatedHostedProtocols(hosting, primary);
13737
+ const identity = IDENTITY_TRANSPORTS.has(options.transport) ? buildIdentity(hosting, options.env) : undefined;
13738
+ return new VgiRpcServer(primary, {
13739
+ serverId: options.serverId,
13740
+ protocols,
13741
+ identity
13742
+ });
13743
+ }
13744
+ function validatedHostedProtocols(hosting, primary) {
13745
+ if (hosting.hostedProtocols === undefined)
13746
+ return [];
13747
+ const owner = "hostedProtocols()";
13748
+ if (typeof hosting.hostedProtocols !== "function") {
13749
+ throw new TypeError(`${owner} must be a function returning vgi-rpc Protocols, got ${typeof hosting.hostedProtocols}.`);
13750
+ }
13751
+ const raw = hosting.hostedProtocols();
13752
+ if (raw == null || typeof raw[Symbol.iterator] !== "function" || typeof raw === "string") {
13753
+ throw new TypeError(`${owner} must return an iterable of vgi-rpc Protocols, got ${String(raw)}.`);
13754
+ }
13755
+ const seen = new Set;
13756
+ const out = [];
13757
+ let index = 0;
13758
+ for (const proto of raw) {
13759
+ const p = proto;
13760
+ if (p == null || typeof p.name !== "string" || typeof p.getMethod !== "function") {
13761
+ throw new TypeError(`${owner} entry ${index} must be a vgi-rpc Protocol, got ${String(proto)}.`);
13762
+ }
13763
+ const name = p.name;
13764
+ if (name.startsWith(RESERVED_PREFIX)) {
13765
+ throw new Error(`${owner} entry ${index} is named '${name}', which claims the reserved '${RESERVED_PREFIX}' prefix. ` + "Framework protocols are not supplied through this hook: reflection is hosted automatically, and " + "vgi_rpc.Identity.v1 is enabled by supplying resolveToken and/or mintGrant.");
13766
+ }
13767
+ if (!/^[A-Za-z_][A-Za-z0-9_.]*$/.test(name)) {
13768
+ throw new Error(`${owner} entry ${index}: protocol name '${name}' is not an identifier, optionally dot-qualified ` + "(e.g. 'acme.Reports.v1').");
13769
+ }
13770
+ if (name === primary.name) {
13771
+ throw new Error(`${owner} entry ${index} is named '${name}', the worker's own protocol. Give it a distinct name.`);
13772
+ }
13773
+ if (seen.has(name)) {
13774
+ throw new Error(`${owner} lists protocol name '${name}' twice. The name is the routing key, so each hosted protocol ` + "needs a distinct name.");
13775
+ }
13776
+ seen.add(name);
13777
+ out.push(proto);
13778
+ index++;
13779
+ }
13780
+ return out;
13781
+ }
13782
+ function buildIdentity(hosting, env) {
13783
+ const { resolveToken, mintGrant } = hosting;
13784
+ if (!resolveToken && !mintGrant)
13785
+ return;
13786
+ return new IdentityImpl({
13787
+ resolveToken,
13788
+ mintGrant,
13789
+ introspectPrincipals: resolveToken ? resolveIntrospectPrincipals(hosting.introspectPrincipals, env) : undefined,
13790
+ maxAuthAge: hosting.maxAuthAge
13791
+ });
13792
+ }
13793
+ function resolveIntrospectPrincipals(explicit, env) {
13794
+ let principals;
13795
+ if (explicit !== undefined) {
13796
+ principals = [...explicit].map((p) => p.trim()).filter((p) => p !== "");
13797
+ } else {
13798
+ const source = env ?? globalThis.process?.env;
13799
+ const raw = source?.[INTROSPECT_PRINCIPALS_ENV] ?? "";
13800
+ principals = raw.split(",").map((p) => p.trim()).filter((p) => p !== "");
13801
+ }
13802
+ if (principals.length === 0) {
13803
+ throw new Error("This worker supplies resolveToken, which hosts the vgi_rpc.Identity.v1 protocol, but no " + `introspector allowlist was configured. Set ${INTROSPECT_PRINCIPALS_ENV} (comma-separated) or pass ` + `introspectPrincipals.
13804
+
13805
+ ` + "There is no permissive default on purpose: introspection is a separate capability from " + "authentication, and allowing every authenticated caller lets any user resolve any other user's " + "credential to its owner. Remove resolveToken to leave the protocol unhosted entirely.");
13806
+ }
13807
+ return principals;
13808
+ }
13809
+
13810
+ // src/index.core.ts
13811
+ import {
13812
+ AuthUnavailableError,
13813
+ GrantRefusedError,
13814
+ IdentityUnavailableError,
13815
+ StatusError
13816
+ } from "@query-farm/vgi-rpc";
13206
13817
  // src/worker.ts
13207
13818
  import {
13208
- VgiRpcServer,
13209
13819
  observePeerIdentity,
13210
13820
  peerIdentityPrimary,
13211
13821
  serveUnix,
@@ -13269,11 +13879,19 @@ function parseLauncherArgs(argv) {
13269
13879
 
13270
13880
  class Worker {
13271
13881
  _registry;
13882
+ _hosting;
13272
13883
  _catalogInterface;
13273
13884
  _catalogName;
13274
13885
  constructor(config) {
13275
13886
  this._registry = config.registry ?? new FunctionRegistry;
13276
13887
  this._catalogName = config.catalogName;
13888
+ this._hosting = {
13889
+ hostedProtocols: config.hostedProtocols,
13890
+ resolveToken: config.resolveToken,
13891
+ mintGrant: config.mintGrant,
13892
+ introspectPrincipals: config.introspectPrincipals,
13893
+ maxAuthAge: config.maxAuthAge
13894
+ };
13277
13895
  if (config.functions) {
13278
13896
  for (const func of config.functions) {
13279
13897
  this._registry.register(func);
@@ -13313,7 +13931,7 @@ class Worker {
13313
13931
  const envOverride = process.env.VGI_WORKER_IDLE_TIMEOUT;
13314
13932
  const idleTimeout = envOverride !== undefined && envOverride !== "" ? Number(envOverride) : launcher.idleTimeout;
13315
13933
  debug(() => `[worker] AF_UNIX mode: ${launcher.unixPath} idle=${idleTimeout ?? 300}s${envOverride !== undefined && envOverride !== "" ? " (env override)" : ""}`);
13316
- serveUnix(protocol, {
13934
+ serveUnix(this.buildServer(protocol, "unix"), {
13317
13935
  unixPath: launcher.unixPath,
13318
13936
  idleTimeout
13319
13937
  }).then((handle) => handle.done).then(() => {
@@ -13330,7 +13948,7 @@ ${err.stack}
13330
13948
  const envOverride = process.env.VGI_WORKER_IDLE_TIMEOUT;
13331
13949
  const idleTimeout = envOverride !== undefined && envOverride !== "" ? Number(envOverride) : launcher.idleTimeout;
13332
13950
  debug(() => `[worker] TCP mode: ${launcher.tcpHost}:${launcher.tcpPort} idle=${idleTimeout ?? 300}s${envOverride !== undefined && envOverride !== "" ? " (env override)" : ""}`);
13333
- serveTcp(protocol, {
13951
+ serveTcp(this.buildServer(protocol, launcher.irohRawUpstream ? "iroh" : "tcp"), {
13334
13952
  host: launcher.tcpHost,
13335
13953
  port: launcher.tcpPort,
13336
13954
  idleTimeout,
@@ -13350,7 +13968,7 @@ ${err.stack}
13350
13968
  });
13351
13969
  return;
13352
13970
  }
13353
- const server = new VgiRpcServer(protocol);
13971
+ const server = this.buildServer(protocol, "pipe");
13354
13972
  debug(() => `[worker] server created, calling run()`);
13355
13973
  server.run().then(() => {
13356
13974
  debug(() => `[worker] server.run() resolved cleanly`);
@@ -13367,6 +13985,9 @@ ${err.stack}
13367
13985
  process.exit(1);
13368
13986
  }
13369
13987
  }
13988
+ buildServer(protocol, transport) {
13989
+ return buildRpcServer(protocol, this._hosting, { transport });
13990
+ }
13370
13991
  buildProtocol() {
13371
13992
  return buildVgiProtocol({
13372
13993
  registry: this._registry,
@@ -13375,7 +13996,7 @@ ${err.stack}
13375
13996
  });
13376
13997
  }
13377
13998
  async serveStream(readable, writable) {
13378
- await serveStreamRpc(this.buildProtocol(), { readable, writable });
13999
+ await serveStreamRpc(this.buildServer(this.buildProtocol(), "stream"), { readable, writable });
13379
14000
  }
13380
14001
  }
13381
14002
  export {
@@ -13383,6 +14004,7 @@ export {
13383
14004
  ArgumentValidationError,
13384
14005
  Arguments,
13385
14006
  AuthContext,
14007
+ AuthUnavailableError,
13386
14008
  BindResultSchema,
13387
14009
  BoundStorage,
13388
14010
  CACHE_ETAG_KEY,
@@ -13420,6 +14042,9 @@ export {
13420
14042
  FunctionStorageSqlite,
13421
14043
  FunctionType,
13422
14044
  GROUP_COLUMN_NAME,
14045
+ GrantRefusedError,
14046
+ INTROSPECT_PRINCIPALS_ENV,
14047
+ IdentityUnavailableError,
13423
14048
  IntervalUnit2 as IntervalUnit,
13424
14049
  NoCatalogError,
13425
14050
  NullHandling,
@@ -13428,9 +14053,11 @@ export {
13428
14053
  OutputCollector,
13429
14054
  PARENT_ROW_METADATA_KEY,
13430
14055
  PushdownFilters,
14056
+ READ_ONLY_ITEM_ATTACH_ID,
13431
14057
  ReadOnlyCatalogInterface,
13432
14058
  RowCountMismatchError,
13433
14059
  ScanFunctionResultSchema,
14060
+ StatusError,
13434
14061
  TableInOutPhase,
13435
14062
  TimeUnit2 as TimeUnit,
13436
14063
  TypeId,
@@ -13468,7 +14095,9 @@ export {
13468
14095
  batchToSecretDict,
13469
14096
  binary2 as binary,
13470
14097
  bool3 as bool,
14098
+ buildCatalogAttachResult,
13471
14099
  buildJoinKeysLookup,
14100
+ buildRpcServer,
13472
14101
  buildScanBranchesResult,
13473
14102
  buildVgiProtocol,
13474
14103
  bytes,
@@ -13621,4 +14250,4 @@ export {
13621
14250
  utf82 as utf8
13622
14251
  };
13623
14252
 
13624
- //# debugId=2D7783DC9EE1AD4F64756E2164756E21
14253
+ //# debugId=03676B1C4ED9A21664756E2164756E21