@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
@@ -4860,6 +4860,18 @@ var ForeignKeyInfoSchema = schema2([
4860
4860
  field2("referenced_table", utf82(), false),
4861
4861
  field2("referenced_schema_path", list2(field2("item", utf82(), true)), false)
4862
4862
  ]);
4863
+ var SchemaContentsSchema = schema2([
4864
+ field2("path", list2(field2("item", utf82(), true)), false),
4865
+ field2("schema", binary2(), false),
4866
+ field2("tables", list2(field2("item", binary2(), true)), false),
4867
+ field2("views", list2(field2("item", binary2(), true)), false),
4868
+ field2("scalar_functions", list2(field2("item", binary2(), true)), false),
4869
+ field2("aggregate_functions", list2(field2("item", binary2(), true)), false),
4870
+ field2("table_functions", list2(field2("item", binary2(), true)), false),
4871
+ field2("scalar_macros", list2(field2("item", binary2(), true)), false),
4872
+ field2("table_macros", list2(field2("item", binary2(), true)), false),
4873
+ field2("indexes", list2(field2("item", binary2(), true)), false)
4874
+ ]);
4863
4875
  var AggregateBindRequestSchema = schema2([
4864
4876
  field2("function_name", utf82(), false),
4865
4877
  field2("arguments", binary2(), false),
@@ -5182,11 +5194,18 @@ var CatalogAttachResultSchema = schema2([
5182
5194
  field2("global_functions", list2(field2("item", binary2(), true)), false),
5183
5195
  field2("global_function_prefix", utf82(), false),
5184
5196
  field2("resolved_data_version", utf82(), true),
5185
- field2("resolved_implementation_version", utf82(), true)
5197
+ field2("resolved_implementation_version", utf82(), true),
5198
+ field2("supports_catalog_contents", bool2(), false)
5186
5199
  ]);
5187
5200
  var CatalogCatalogsResultSchema = schema2([
5188
5201
  field2("items", list2(field2("item", binary2(), true)), false)
5189
5202
  ]);
5203
+ var CatalogContentsResultSchema = schema2([
5204
+ field2("catalog_version", int642(), false),
5205
+ field2("etag", utf82(), true),
5206
+ field2("not_modified", bool2(), false),
5207
+ 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)
5208
+ ]);
5190
5209
  var CatalogCopyFromFormatsResultSchema = schema2([
5191
5210
  field2("items", list2(field2("item", binary2(), true)), false)
5192
5211
  ]);
@@ -5305,6 +5324,10 @@ var CatalogAttachParamsSchema = schema2([
5305
5324
  field2("request", binary2(), false)
5306
5325
  ]);
5307
5326
  var CatalogCatalogsParamsSchema = schema2([]);
5327
+ var CatalogContentsParamsSchema = schema2([
5328
+ field2("attach_opaque_data", binary2(), false),
5329
+ field2("if_none_match", utf82(), true)
5330
+ ]);
5308
5331
  var CatalogCopyFromFormatsParamsSchema = schema2([
5309
5332
  field2("attach_opaque_data", binary2(), false),
5310
5333
  field2("transaction_opaque_data", binary2(), true)
@@ -6578,6 +6601,9 @@ function catalogUnary(protocol, signingKey, name, config) {
6578
6601
  result: config.result,
6579
6602
  doc: config.doc,
6580
6603
  handler: async (params, ctx) => {
6604
+ if (params.request != null && params.attach_opaque_data === undefined && params.name === undefined) {
6605
+ params = unwrapRequest(params.request);
6606
+ }
6581
6607
  normalizeRequestSchemaPaths(params);
6582
6608
  await unwrapParamsOpaque(params, ctx, signingKey);
6583
6609
  return config.handler(params, ctx);
@@ -7881,7 +7907,84 @@ function hex(buf) {
7881
7907
  // src/codec/asd.ts
7882
7908
  init_arrow();
7883
7909
  function encodeASD(schema, obj) {
7884
- return serializeBatch(batchFromRows([obj], schema));
7910
+ return serializeBatch(batchFromRows([sortMapsForSchema(schema, obj)], schema));
7911
+ }
7912
+ function compareCodePoints(a, b) {
7913
+ const n = Math.min(a.length, b.length);
7914
+ for (let i = 0;i < n; i++) {
7915
+ const x = a.charCodeAt(i);
7916
+ const y = b.charCodeAt(i);
7917
+ if (x === y)
7918
+ continue;
7919
+ const xs = x >= 55296 && x <= 57343;
7920
+ const ys = y >= 55296 && y <= 57343;
7921
+ if (xs !== ys)
7922
+ return xs ? 1 : -1;
7923
+ return x - y;
7924
+ }
7925
+ return a.length - b.length;
7926
+ }
7927
+ function mapPairs(raw) {
7928
+ if (Array.isArray(raw))
7929
+ return raw.map((e) => Array.isArray(e) ? [e[0], e[1]] : [e?.key, e?.value]);
7930
+ if (raw instanceof Map)
7931
+ return Array.from(raw.entries());
7932
+ if (typeof raw[Symbol.iterator] === "function")
7933
+ return Array.from(raw);
7934
+ return Object.entries(raw);
7935
+ }
7936
+ function compareKeys(a, b) {
7937
+ if (typeof a === "string" && typeof b === "string")
7938
+ return compareCodePoints(a, b);
7939
+ if ((typeof a === "number" || typeof a === "bigint") && (typeof b === "number" || typeof b === "bigint")) {
7940
+ return a < b ? -1 : a > b ? 1 : 0;
7941
+ }
7942
+ return compareCodePoints(String(a), String(b));
7943
+ }
7944
+ var HAS_MAP = new WeakMap;
7945
+ function typeHasMap(type) {
7946
+ const cached = HAS_MAP.get(type);
7947
+ if (cached !== undefined)
7948
+ return cached;
7949
+ let has = isMap(type);
7950
+ if (!has && (isList(type) || isStruct(type))) {
7951
+ has = type.children.some((c) => typeHasMap(c.type));
7952
+ }
7953
+ HAS_MAP.set(type, has);
7954
+ return has;
7955
+ }
7956
+ function sortMapsForType(type, value) {
7957
+ if (value == null || !typeHasMap(type))
7958
+ return value;
7959
+ if (isMap(type)) {
7960
+ const entries = type.children[0].type;
7961
+ const valueType = entries.children[1].type;
7962
+ return mapPairs(value).map(([k, v]) => [k, sortMapsForType(valueType, v)]).sort((x, y) => compareKeys(x[0], y[0]));
7963
+ }
7964
+ if (isList(type)) {
7965
+ const child = type.children[0].type;
7966
+ return Array.from(value, (v) => sortMapsForType(child, v));
7967
+ }
7968
+ if (isStruct(type)) {
7969
+ const out = { ...value };
7970
+ for (const cf of type.children)
7971
+ out[cf.name] = sortMapsForType(cf.type, value[cf.name]);
7972
+ return out;
7973
+ }
7974
+ return value;
7975
+ }
7976
+ function sortMapsForSchema(schema, obj) {
7977
+ let out = null;
7978
+ for (const f of schema.fields) {
7979
+ if (!typeHasMap(f.type))
7980
+ continue;
7981
+ const v = obj[f.name];
7982
+ if (v == null)
7983
+ continue;
7984
+ out ??= { ...obj };
7985
+ out[f.name] = sortMapsForType(f.type, v);
7986
+ }
7987
+ return out ?? obj;
7885
7988
  }
7886
7989
 
7887
7990
  // src/generated/vgi-client.ts
@@ -7893,6 +7996,52 @@ var encodeSchemaInfo = (v) => encodeASD(SchemaInfoSchema, v);
7893
7996
  var encodeTableInfo = (v) => encodeASD(TableInfoSchema, v);
7894
7997
  var encodeViewInfo = (v) => encodeASD(ViewInfoSchema, v);
7895
7998
 
7999
+ // src/generated/vgi-protocol-types.ts
8000
+ function buildCatalogAttachResult(init) {
8001
+ return {
8002
+ attach_opaque_data: init.attach_opaque_data,
8003
+ supports_transactions: init.supports_transactions,
8004
+ supports_time_travel: init.supports_time_travel,
8005
+ catalog_version_frozen: init.catalog_version_frozen,
8006
+ catalog_version: init.catalog_version,
8007
+ attach_opaque_data_required: init.attach_opaque_data_required ?? true,
8008
+ default_schema: init.default_schema ?? "main",
8009
+ settings: init.settings ?? [],
8010
+ secret_types: init.secret_types ?? [],
8011
+ attach_catalogs: init.attach_catalogs ?? [],
8012
+ comment: init.comment ?? null,
8013
+ tags: init.tags ?? {},
8014
+ supports_column_statistics: init.supports_column_statistics ?? false,
8015
+ global_functions: init.global_functions ?? [],
8016
+ global_function_prefix: init.global_function_prefix ?? "",
8017
+ resolved_data_version: init.resolved_data_version ?? null,
8018
+ resolved_implementation_version: init.resolved_implementation_version ?? null,
8019
+ supports_catalog_contents: init.supports_catalog_contents ?? false
8020
+ };
8021
+ }
8022
+ function buildSchemaContents(init) {
8023
+ return {
8024
+ path: init.path,
8025
+ schema: init.schema,
8026
+ tables: init.tables ?? [],
8027
+ views: init.views ?? [],
8028
+ scalar_functions: init.scalar_functions ?? [],
8029
+ aggregate_functions: init.aggregate_functions ?? [],
8030
+ table_functions: init.table_functions ?? [],
8031
+ scalar_macros: init.scalar_macros ?? [],
8032
+ table_macros: init.table_macros ?? [],
8033
+ indexes: init.indexes ?? []
8034
+ };
8035
+ }
8036
+ function buildCatalogContentsResponse(init) {
8037
+ return {
8038
+ catalog_version: init.catalog_version,
8039
+ etag: init.etag ?? null,
8040
+ not_modified: init.not_modified ?? false,
8041
+ schemas: init.schemas ?? []
8042
+ };
8043
+ }
8044
+
7896
8045
  // src/catalog/item-encoding.ts
7897
8046
  var ENCODED = new WeakMap;
7898
8047
  function freezeCatalogItem(item) {
@@ -7920,6 +8069,133 @@ function encodeFunctionInfoOnce(info) {
7920
8069
  return encoded;
7921
8070
  }
7922
8071
 
8072
+ // src/catalog/contents-digest.ts
8073
+ var KINDS = [
8074
+ "tables",
8075
+ "views",
8076
+ "scalar_functions",
8077
+ "aggregate_functions",
8078
+ "table_functions",
8079
+ "scalar_macros",
8080
+ "table_macros",
8081
+ "indexes"
8082
+ ];
8083
+ async function catalogContentsDigest(schemas) {
8084
+ const utf8 = new TextEncoder;
8085
+ const parts = [];
8086
+ let total = 0;
8087
+ const count = (n) => {
8088
+ const b = new Uint8Array(8);
8089
+ new DataView(b.buffer).setBigUint64(0, BigInt(n), true);
8090
+ parts.push(b);
8091
+ total += 8;
8092
+ };
8093
+ const chunk = (data) => {
8094
+ count(data.byteLength);
8095
+ parts.push(data);
8096
+ total += data.byteLength;
8097
+ };
8098
+ const chunks = (values) => {
8099
+ count(values.length);
8100
+ for (const v of values)
8101
+ chunk(v);
8102
+ };
8103
+ count(schemas.length);
8104
+ for (const entry of schemas) {
8105
+ chunks(entry.path.map((p) => utf8.encode(p)));
8106
+ chunk(entry.schema);
8107
+ for (const kind of KINDS)
8108
+ chunks(entry[kind]);
8109
+ }
8110
+ const buf = new Uint8Array(total);
8111
+ let off = 0;
8112
+ for (const p of parts) {
8113
+ buf.set(p, off);
8114
+ off += p.byteLength;
8115
+ }
8116
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", buf));
8117
+ let hex = "";
8118
+ for (const b of digest)
8119
+ hex += b.toString(16).padStart(2, "0");
8120
+ return hex;
8121
+ }
8122
+
8123
+ // src/protocol/handlers/catalog/contents.ts
8124
+ var CACHE = new WeakMap;
8125
+ async function buildCatalogContents(cat, owner, attach, version, ifNoneMatch) {
8126
+ const result = await cat.catalogContents(attach, ifNoneMatch);
8127
+ const etag0 = result.etag ?? null;
8128
+ if (result.not_modified) {
8129
+ if (etag0 === null || ifNoneMatch === null || etag0 !== ifNoneMatch) {
8130
+ 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)");
8131
+ }
8132
+ if (result.schemas && result.schemas.length > 0) {
8133
+ throw new Error("catalog_contents returned not_modified with schemas; it must return none");
8134
+ }
8135
+ return buildCatalogContentsResponse({ catalog_version: version, etag: etag0, not_modified: true });
8136
+ }
8137
+ const infos = [...result.schemas ?? []];
8138
+ const keys = infos.map((c) => schemaPathKey(c.schema.path));
8139
+ const keySet = new Set(keys);
8140
+ if (keySet.size !== keys.length)
8141
+ throw new Error("catalog_contents returned duplicate schema paths");
8142
+ for (const c of infos) {
8143
+ if (c.schema.path.length > 1 && !keySet.has(schemaPathKey(c.schema.path.slice(0, -1)))) {
8144
+ throw new Error(`catalog_contents returned schema path ${JSON.stringify(c.schema.path)} without its parent`);
8145
+ }
8146
+ }
8147
+ const schemas = infos.sort((a, b) => a.schema.path.length - b.schema.path.length).map((c) => buildSchemaContents({
8148
+ path: [...c.schema.path],
8149
+ schema: encodeSchemaInfo(c.schema),
8150
+ tables: c.tables.map((t) => encodeTableInfo(t)),
8151
+ views: c.views.map((v) => encodeViewInfo(v)),
8152
+ scalar_functions: c.scalar_functions.map((f) => encodeFunctionInfoOnce(f)),
8153
+ aggregate_functions: c.aggregate_functions.map((f) => encodeFunctionInfoOnce(f)),
8154
+ table_functions: c.table_functions.map((f) => encodeFunctionInfoOnce(f)),
8155
+ scalar_macros: c.scalar_macros.map((m) => encodeMacroInfo(m)),
8156
+ table_macros: c.table_macros.map((m) => encodeMacroInfo(m)),
8157
+ indexes: c.indexes.map((i) => encodeIndexInfo(i))
8158
+ }));
8159
+ let etag = etag0;
8160
+ if (etag === null && owner.catalogContentsEtag === "content-hash") {
8161
+ etag = await catalogContentsDigest(schemas);
8162
+ }
8163
+ if (etag !== null && ifNoneMatch !== null && etag === ifNoneMatch) {
8164
+ return buildCatalogContentsResponse({ catalog_version: version, etag, not_modified: true });
8165
+ }
8166
+ return buildCatalogContentsResponse({ catalog_version: version, etag, schemas });
8167
+ }
8168
+ async function serveCatalogContents(cat, attach, ifNoneMatch) {
8169
+ const owner = cat.catalogContentsOwner(attach);
8170
+ const version = Number(await cat.version(attach));
8171
+ if (owner.catalogContentsCacheable()) {
8172
+ let pending = CACHE.get(owner);
8173
+ let snapshot = pending ? await pending.catch(() => null) : null;
8174
+ if (!snapshot || snapshot.version !== version) {
8175
+ pending = (async () => {
8176
+ const built = await buildCatalogContents(cat, owner, attach, version, null);
8177
+ return {
8178
+ version,
8179
+ etag: built.etag ?? null,
8180
+ wire: wrapResult(built, CatalogContentsResultSchema)
8181
+ };
8182
+ })();
8183
+ CACHE.set(owner, pending);
8184
+ try {
8185
+ snapshot = await pending;
8186
+ } catch (err) {
8187
+ if (CACHE.get(owner) === pending)
8188
+ CACHE.delete(owner);
8189
+ throw err;
8190
+ }
8191
+ }
8192
+ if (ifNoneMatch !== null && snapshot.etag !== null && ifNoneMatch === snapshot.etag) {
8193
+ return wrapResult(buildCatalogContentsResponse({ catalog_version: version, etag: snapshot.etag, not_modified: true }), CatalogContentsResultSchema);
8194
+ }
8195
+ return snapshot.wire;
8196
+ }
8197
+ return wrapResult(await buildCatalogContents(cat, owner, attach, version, ifNoneMatch), CatalogContentsResultSchema);
8198
+ }
7923
8199
  // src/catalog/interface.ts
7924
8200
  var encodeCopyFromFormatInfo = (v) => encodeASD(CopyFromFormatInfoSchema, {
7925
8201
  comment: v.comment ?? null,
@@ -7980,6 +8256,9 @@ function isPromise(v) {
7980
8256
  }
7981
8257
 
7982
8258
  class CatalogInterface {
8259
+ catalogContentsEtag = null;
8260
+ catalogContentsAttachIndependent = false;
8261
+ catalogVersionFrozen = false;
7983
8262
  catalogNameForAttach(_attachOpaqueData) {
7984
8263
  const names = this.catalogs();
7985
8264
  return names.length === 1 ? names[0] : null;
@@ -8097,6 +8376,42 @@ class CatalogInterface {
8097
8376
  copyFromFormats(attachOpaqueData, transactionOpaqueData) {
8098
8377
  return [];
8099
8378
  }
8379
+ async catalogContents(attachOpaqueData, _ifNoneMatch) {
8380
+ const schemas = await this.schemas(attachOpaqueData, undefined);
8381
+ const contents = await Promise.all(schemas.map(async (schema) => {
8382
+ const counts = schema.estimated_object_count ?? {};
8383
+ const path = schema.path;
8384
+ const kind = async (countKey, list) => (counts[countKey] ?? 1) === 0 ? [] : [...await list()];
8385
+ const [tables, views, scalarFunctions, aggregateFunctions, tableFunctions, scalarMacros, tableMacros, indexes] = await Promise.all([
8386
+ kind("table", () => this.schemaContentsTables(attachOpaqueData, path)),
8387
+ kind("view", () => this.schemaContentsViews(attachOpaqueData, path)),
8388
+ kind("scalar_function", () => this.schemaContentsFunctions(attachOpaqueData, path, "scalar_function")),
8389
+ kind("aggregate_function", () => this.schemaContentsFunctions(attachOpaqueData, path, "aggregate_function")),
8390
+ kind("table_function", () => this.schemaContentsFunctions(attachOpaqueData, path, "table_function")),
8391
+ kind("macro", () => this.schemaContentsMacros(attachOpaqueData, path, "scalar_macro")),
8392
+ kind("macro", () => this.schemaContentsMacros(attachOpaqueData, path, "table_macro")),
8393
+ kind("index", () => this.schemaContentsIndexes(attachOpaqueData, path))
8394
+ ]);
8395
+ return {
8396
+ schema,
8397
+ tables,
8398
+ views,
8399
+ scalar_functions: scalarFunctions,
8400
+ aggregate_functions: aggregateFunctions,
8401
+ table_functions: tableFunctions,
8402
+ scalar_macros: scalarMacros,
8403
+ table_macros: tableMacros,
8404
+ indexes
8405
+ };
8406
+ }));
8407
+ return { schemas: contents };
8408
+ }
8409
+ catalogContentsCacheable() {
8410
+ return this.catalogContentsAttachIndependent && this.catalogVersionFrozen;
8411
+ }
8412
+ catalogContentsOwner(_attachOpaqueData) {
8413
+ return this;
8414
+ }
8100
8415
  transactionBegin(attachOpaqueData) {
8101
8416
  return null;
8102
8417
  }
@@ -8131,25 +8446,11 @@ function registerCatalogAdminMethods(protocol, getCatalog, signingKey) {
8131
8446
  const optionsDict = decodeOptionsBatch(innerParams.options);
8132
8447
  const result = await cat.attach(innerParams.name, optionsDict, innerParams.data_version_spec ?? null, innerParams.implementation_version ?? null);
8133
8448
  const sealedAttach = await sealAttach(toUint8Array(result.attach_opaque_data), ctx?.auth, signingKey);
8134
- return wrapResult({
8449
+ return wrapResult(buildCatalogAttachResult({
8450
+ ...result,
8135
8451
  attach_opaque_data: sealedAttach,
8136
- supports_transactions: result.supports_transactions,
8137
- supports_time_travel: result.supports_time_travel,
8138
- catalog_version_frozen: result.catalog_version_frozen,
8139
- catalog_version: result.catalog_version,
8140
- attach_opaque_data_required: result.attach_opaque_data_required ?? true,
8141
- default_schema: result.default_schema ?? "main",
8142
- settings: result.settings ?? [],
8143
- secret_types: result.secret_types ?? [],
8144
- attach_catalogs: result.attach_catalogs ?? [],
8145
- comment: result.comment ?? null,
8146
- tags: result.tags ?? {},
8147
- supports_column_statistics: result.supports_column_statistics ?? true,
8148
- global_functions: result.global_functions ?? [],
8149
- global_function_prefix: result.global_function_prefix ?? "",
8150
- resolved_data_version: result.resolved_data_version ?? null,
8151
- resolved_implementation_version: result.resolved_implementation_version ?? null
8152
- }, CatalogAttachResultSchema);
8452
+ supports_column_statistics: result.supports_column_statistics ?? true
8453
+ }), CatalogAttachResultSchema);
8153
8454
  }
8154
8455
  });
8155
8456
  catalogUnary(protocol, signingKey, "catalog_detach", {
@@ -8230,6 +8531,14 @@ function registerCatalogAdminMethods(protocol, getCatalog, signingKey) {
8230
8531
  }, CatalogSchemasResultSchema);
8231
8532
  }
8232
8533
  });
8534
+ catalogUnary(protocol, signingKey, "catalog_contents", {
8535
+ params: CatalogContentsParamsSchema,
8536
+ result: RESULT_BINARY_SCHEMA,
8537
+ handler: async (params) => {
8538
+ const ifNoneMatch = params.if_none_match == null ? null : String(params.if_none_match);
8539
+ return serveCatalogContents(getCatalog(), toUint8Array(params.attach_opaque_data), ifNoneMatch);
8540
+ }
8541
+ });
8233
8542
  catalogUnary(protocol, signingKey, "catalog_copy_from_formats", {
8234
8543
  params: CatalogCopyFromFormatsParamsSchema,
8235
8544
  result: RESULT_BINARY_SCHEMA,
@@ -8524,7 +8833,7 @@ function registerCatalogMacroMethods(protocol, getCatalog, signingKey) {
8524
8833
  result: emptyResultSchema,
8525
8834
  handler: async (params) => {
8526
8835
  const cat = getCatalog();
8527
- const innerParams = unwrapRequest(params.request);
8836
+ const innerParams = params;
8528
8837
  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);
8529
8838
  return {};
8530
8839
  }
@@ -8590,7 +8899,7 @@ function registerCatalogMethods(protocol, catalog, _catalogName, signingKey) {
8590
8899
  // src/protocol/dispatch.ts
8591
8900
  var VGI_PROTOCOL_NAME = "vgi.v2";
8592
8901
  function buildVgiProtocol(config) {
8593
- const protocol = new Protocol(VGI_PROTOCOL_NAME, { protocolVersion: "2.0.0" });
8902
+ const protocol = new Protocol(VGI_PROTOCOL_NAME, { protocolVersion: "2.1.0" });
8594
8903
  registerFunctionMethods(protocol, {
8595
8904
  registry: config.registry,
8596
8905
  signingKey: config.signingKey,
@@ -8705,6 +9014,93 @@ function createLandingRoutes(info) {
8705
9014
  };
8706
9015
  }
8707
9016
 
9017
+ // src/rpc-server.ts
9018
+ import {
9019
+ IdentityImpl,
9020
+ VgiRpcServer
9021
+ } from "@query-farm/vgi-rpc";
9022
+ var TRANSPORTS = new Set(["pipe", "unix", "tcp", "iroh", "stream", "http"]);
9023
+ var IDENTITY_TRANSPORTS = new Set(["http"]);
9024
+ var RESERVED_PREFIX = "vgi_rpc.";
9025
+ var INTROSPECT_PRINCIPALS_ENV = "VGI_INTROSPECT_PRINCIPALS";
9026
+ function buildRpcServer(primary, hosting, options) {
9027
+ if (!TRANSPORTS.has(options.transport)) {
9028
+ throw new Error(`Unknown transport ${JSON.stringify(options.transport)}; expected one of ${[...TRANSPORTS].join(", ")}.`);
9029
+ }
9030
+ const protocols = validatedHostedProtocols(hosting, primary);
9031
+ const identity = IDENTITY_TRANSPORTS.has(options.transport) ? buildIdentity(hosting, options.env) : undefined;
9032
+ return new VgiRpcServer(primary, {
9033
+ serverId: options.serverId,
9034
+ protocols,
9035
+ identity
9036
+ });
9037
+ }
9038
+ function validatedHostedProtocols(hosting, primary) {
9039
+ if (hosting.hostedProtocols === undefined)
9040
+ return [];
9041
+ const owner = "hostedProtocols()";
9042
+ if (typeof hosting.hostedProtocols !== "function") {
9043
+ throw new TypeError(`${owner} must be a function returning vgi-rpc Protocols, got ${typeof hosting.hostedProtocols}.`);
9044
+ }
9045
+ const raw = hosting.hostedProtocols();
9046
+ if (raw == null || typeof raw[Symbol.iterator] !== "function" || typeof raw === "string") {
9047
+ throw new TypeError(`${owner} must return an iterable of vgi-rpc Protocols, got ${String(raw)}.`);
9048
+ }
9049
+ const seen = new Set;
9050
+ const out = [];
9051
+ let index = 0;
9052
+ for (const proto of raw) {
9053
+ const p = proto;
9054
+ if (p == null || typeof p.name !== "string" || typeof p.getMethod !== "function") {
9055
+ throw new TypeError(`${owner} entry ${index} must be a vgi-rpc Protocol, got ${String(proto)}.`);
9056
+ }
9057
+ const name = p.name;
9058
+ if (name.startsWith(RESERVED_PREFIX)) {
9059
+ 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.");
9060
+ }
9061
+ if (!/^[A-Za-z_][A-Za-z0-9_.]*$/.test(name)) {
9062
+ throw new Error(`${owner} entry ${index}: protocol name '${name}' is not an identifier, optionally dot-qualified ` + "(e.g. 'acme.Reports.v1').");
9063
+ }
9064
+ if (name === primary.name) {
9065
+ throw new Error(`${owner} entry ${index} is named '${name}', the worker's own protocol. Give it a distinct name.`);
9066
+ }
9067
+ if (seen.has(name)) {
9068
+ throw new Error(`${owner} lists protocol name '${name}' twice. The name is the routing key, so each hosted protocol ` + "needs a distinct name.");
9069
+ }
9070
+ seen.add(name);
9071
+ out.push(proto);
9072
+ index++;
9073
+ }
9074
+ return out;
9075
+ }
9076
+ function buildIdentity(hosting, env) {
9077
+ const { resolveToken, mintGrant } = hosting;
9078
+ if (!resolveToken && !mintGrant)
9079
+ return;
9080
+ return new IdentityImpl({
9081
+ resolveToken,
9082
+ mintGrant,
9083
+ introspectPrincipals: resolveToken ? resolveIntrospectPrincipals(hosting.introspectPrincipals, env) : undefined,
9084
+ maxAuthAge: hosting.maxAuthAge
9085
+ });
9086
+ }
9087
+ function resolveIntrospectPrincipals(explicit, env) {
9088
+ let principals;
9089
+ if (explicit !== undefined) {
9090
+ principals = [...explicit].map((p) => p.trim()).filter((p) => p !== "");
9091
+ } else {
9092
+ const source = env ?? globalThis.process?.env;
9093
+ const raw = source?.[INTROSPECT_PRINCIPALS_ENV] ?? "";
9094
+ principals = raw.split(",").map((p) => p.trim()).filter((p) => p !== "");
9095
+ }
9096
+ if (principals.length === 0) {
9097
+ 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.
9098
+
9099
+ ` + "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.");
9100
+ }
9101
+ return principals;
9102
+ }
9103
+
8708
9104
  // src/http/fetch.ts
8709
9105
  var requestAuthStorage;
8710
9106
  var requestAuthStoragePending;
@@ -8743,7 +9139,8 @@ function createVgiFetch(opts) {
8743
9139
  signingKey: opts.signingKey,
8744
9140
  ...opts.protocol
8745
9141
  });
8746
- const handler = createHttpHandler(protocol, {
9142
+ const server = buildRpcServer(protocol, opts, { transport: "http", serverId });
9143
+ const handler = createHttpHandler(server, {
8747
9144
  prefix,
8748
9145
  serverId,
8749
9146
  tokenKey: opts.signingKey,
@@ -8766,6 +9163,15 @@ function createVgiFetch(opts) {
8766
9163
  return storage.run({}, () => handler(req));
8767
9164
  };
8768
9165
  }
9166
+
9167
+ // src/worker-cf-entry.ts
9168
+ import {
9169
+ AuthUnavailableError as AuthUnavailableError2,
9170
+ GrantRefusedError as GrantRefusedError2,
9171
+ IdentityUnavailableError as IdentityUnavailableError2,
9172
+ StatusError as StatusError2
9173
+ } from "@query-farm/vgi-rpc";
9174
+
8769
9175
  // src/cache-control.ts
8770
9176
  var CACHE_TTL_KEY = "vgi.cache.ttl";
8771
9177
  var CACHE_EXPIRES_KEY = "vgi.cache.expires";
@@ -9954,17 +10360,25 @@ function validateRequiredAttachOptions(catalogName, specs, options) {
9954
10360
  }
9955
10361
 
9956
10362
  // src/catalog/read-only.ts
10363
+ var READ_ONLY_ITEM_ATTACH_ID = new TextEncoder().encode("readonly-catalog-");
10364
+
9957
10365
  class ReadOnlyCatalogInterface extends CatalogInterface {
10366
+ supportsCatalogContents = true;
10367
+ catalogVersionFrozen = true;
10368
+ perAttachItemIds = false;
10369
+ catalogContentsAttachIndependent = true;
9958
10370
  _descriptor;
9959
10371
  _registry;
9960
10372
  _attachments = new Map;
9961
10373
  _version = 1;
9962
10374
  _functionListings = new Map;
9963
10375
  _functionInfos = new Map;
9964
- constructor(descriptor, registry) {
10376
+ constructor(descriptor, registry, options = {}) {
9965
10377
  super();
9966
10378
  this._descriptor = descriptor;
9967
10379
  this._registry = registry;
10380
+ if (options.perAttachItemIds)
10381
+ this.perAttachItemIds = true;
9968
10382
  for (const sch of descriptor.schemas ?? []) {
9969
10383
  for (const fn of sch.functions ?? [])
9970
10384
  registry.registerInSchema(fn, schemaDescriptorPath(sch), descriptor.name);
@@ -10012,7 +10426,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
10012
10426
  const secretTypes = (this._descriptor.secretTypes ?? []).map((s) => serializeSecretType(s));
10013
10427
  const attachCatalogs = (this._descriptor.attachCatalogs ?? []).map((c) => encodeAttachCatalogInfo(c));
10014
10428
  const hasTimeTravel = this._descriptor.schemas.some((s) => s.tables?.some((t) => t.supportsTimeTravel) ?? false);
10015
- return {
10429
+ return buildCatalogAttachResult({
10016
10430
  attach_opaque_data: attachOpaqueData,
10017
10431
  supports_transactions: false,
10018
10432
  supports_time_travel: hasTimeTravel,
@@ -10029,8 +10443,9 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
10029
10443
  global_functions: this._globalFunctionInfos().map(encodeFunctionInfoOnce),
10030
10444
  global_function_prefix: this._descriptor.globalFunctionPrefix ?? "",
10031
10445
  resolved_data_version: null,
10032
- resolved_implementation_version: null
10033
- };
10446
+ resolved_implementation_version: null,
10447
+ supports_catalog_contents: this.supportsCatalogContents
10448
+ });
10034
10449
  }
10035
10450
  detach(attachOpaqueData) {
10036
10451
  for (const [name, id] of this._attachments) {
@@ -10043,9 +10458,15 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
10043
10458
  version(attachOpaqueData, transactionOpaqueData) {
10044
10459
  return this._version;
10045
10460
  }
10461
+ itemAttachId(attachOpaqueData) {
10462
+ return this.perAttachItemIds ? attachOpaqueData : READ_ONLY_ITEM_ATTACH_ID;
10463
+ }
10464
+ catalogContentsCacheable() {
10465
+ return super.catalogContentsCacheable() && !this.perAttachItemIds;
10466
+ }
10046
10467
  schemas(attachOpaqueData, transactionOpaqueData) {
10047
10468
  return this._descriptor.schemas.map((s) => ({
10048
- attach_opaque_data: attachOpaqueData,
10469
+ attach_opaque_data: this.itemAttachId(attachOpaqueData),
10049
10470
  path: schemaDescriptorPath(s),
10050
10471
  comment: s.comment ?? null,
10051
10472
  tags: s.tags ?? {},
@@ -10077,7 +10498,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
10077
10498
  if (!desc)
10078
10499
  return null;
10079
10500
  return {
10080
- attach_opaque_data: attachOpaqueData,
10501
+ attach_opaque_data: this.itemAttachId(attachOpaqueData),
10081
10502
  path: schemaDescriptorPath(desc),
10082
10503
  comment: desc.comment ?? null,
10083
10504
  tags: desc.tags ?? {},
@@ -10103,7 +10524,7 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
10103
10524
  input_schema: null,
10104
10525
  settings: null,
10105
10526
  secrets: null,
10106
- attach_opaque_data: attachOpaqueData,
10527
+ attach_opaque_data: this.itemAttachId(attachOpaqueData),
10107
10528
  transaction_opaque_data: null,
10108
10529
  resolved_secrets_provided: false
10109
10530
  };
@@ -10777,6 +11198,72 @@ class CompositeCatalogInterface extends CatalogInterface {
10777
11198
  async macroGet(attachOpaqueData, schemaPath, name, transactionOpaqueData) {
10778
11199
  return await this._route(attachOpaqueData).macroGet(attachOpaqueData, schemaPath, name, transactionOpaqueData);
10779
11200
  }
11201
+ async schemaCreate(...args) {
11202
+ await this._route(args[0]).schemaCreate(...args);
11203
+ }
11204
+ async schemaDrop(...args) {
11205
+ await this._route(args[0]).schemaDrop(...args);
11206
+ }
11207
+ async tableCreate(...args) {
11208
+ await this._route(args[0]).tableCreate(...args);
11209
+ }
11210
+ async tableDrop(...args) {
11211
+ await this._route(args[0]).tableDrop(...args);
11212
+ }
11213
+ async tableCommentSet(...args) {
11214
+ await this._route(args[0]).tableCommentSet(...args);
11215
+ }
11216
+ async tableRename(...args) {
11217
+ await this._route(args[0]).tableRename(...args);
11218
+ }
11219
+ async tableColumnAdd(...args) {
11220
+ await this._route(args[0]).tableColumnAdd(...args);
11221
+ }
11222
+ async tableColumnDrop(...args) {
11223
+ await this._route(args[0]).tableColumnDrop(...args);
11224
+ }
11225
+ async tableColumnRename(...args) {
11226
+ await this._route(args[0]).tableColumnRename(...args);
11227
+ }
11228
+ async tableColumnDefaultSet(...args) {
11229
+ await this._route(args[0]).tableColumnDefaultSet(...args);
11230
+ }
11231
+ async tableColumnDefaultDrop(...args) {
11232
+ await this._route(args[0]).tableColumnDefaultDrop(...args);
11233
+ }
11234
+ async tableColumnTypeChange(...args) {
11235
+ await this._route(args[0]).tableColumnTypeChange(...args);
11236
+ }
11237
+ async tableNotNullSet(...args) {
11238
+ await this._route(args[0]).tableNotNullSet(...args);
11239
+ }
11240
+ async tableNotNullDrop(...args) {
11241
+ await this._route(args[0]).tableNotNullDrop(...args);
11242
+ }
11243
+ async viewCreate(...args) {
11244
+ await this._route(args[0]).viewCreate(...args);
11245
+ }
11246
+ async viewDrop(...args) {
11247
+ await this._route(args[0]).viewDrop(...args);
11248
+ }
11249
+ async viewRename(...args) {
11250
+ await this._route(args[0]).viewRename(...args);
11251
+ }
11252
+ async viewCommentSet(...args) {
11253
+ await this._route(args[0]).viewCommentSet(...args);
11254
+ }
11255
+ async macroCreate(...args) {
11256
+ await this._route(args[0]).macroCreate(...args);
11257
+ }
11258
+ async macroDrop(...args) {
11259
+ await this._route(args[0]).macroDrop(...args);
11260
+ }
11261
+ async catalogContents(attachOpaqueData, ifNoneMatch) {
11262
+ return await this._route(attachOpaqueData).catalogContents(attachOpaqueData, ifNoneMatch);
11263
+ }
11264
+ catalogContentsOwner(attachOpaqueData) {
11265
+ return this._route(attachOpaqueData).catalogContentsOwner(attachOpaqueData);
11266
+ }
10780
11267
  async copyFromFormats(attachOpaqueData, transactionOpaqueData) {
10781
11268
  return await this._route(attachOpaqueData).copyFromFormats(attachOpaqueData, transactionOpaqueData);
10782
11269
  }
@@ -11077,6 +11564,12 @@ class FunctionRegistry {
11077
11564
  // src/index.core.ts
11078
11565
  import { str, bytes, int as int3, int32 as int323, float, float32 as float323, bool as bool3, toSchema, OutputCollector, AuthContext as AuthContext2 } from "@query-farm/vgi-rpc";
11079
11566
  import { subprocessConnect, httpConnect, tcpConnect } from "@query-farm/vgi-rpc";
11567
+ import {
11568
+ AuthUnavailableError,
11569
+ GrantRefusedError,
11570
+ IdentityUnavailableError,
11571
+ StatusError
11572
+ } from "@query-farm/vgi-rpc";
11080
11573
 
11081
11574
  // src/worker-cf-entry.ts
11082
11575
  init_arrow();
@@ -11084,6 +11577,7 @@ import { OutputCollector as OutputCollector2, AuthContext as AuthContext3 } from
11084
11577
  export {
11085
11578
  Arguments,
11086
11579
  AuthContext3 as AuthContext,
11580
+ AuthUnavailableError2 as AuthUnavailableError,
11087
11581
  BindResultSchema,
11088
11582
  CatalogInterface,
11089
11583
  CompositeCatalogInterface,
@@ -11091,11 +11585,14 @@ export {
11091
11585
  EXCHANGE_STATE_SCHEMA,
11092
11586
  FunctionRegistry,
11093
11587
  FunctionType,
11588
+ GrantRefusedError2 as GrantRefusedError,
11589
+ IdentityUnavailableError2 as IdentityUnavailableError,
11094
11590
  IntervalUnit2 as IntervalUnit,
11095
11591
  OutputCollector2 as OutputCollector,
11096
11592
  PARENT_ROW_METADATA_KEY,
11097
11593
  ReadOnlyCatalogInterface,
11098
11594
  ScanFunctionResultSchema,
11595
+ StatusError2 as StatusError,
11099
11596
  TimeUnit2 as TimeUnit,
11100
11597
  TypeId,
11101
11598
  UnionMode2 as UnionMode,
@@ -11194,4 +11691,4 @@ export {
11194
11691
  utf82 as utf8
11195
11692
  };
11196
11693
 
11197
- //# debugId=A3BC949F5D8B96A764756E2164756E21
11694
+ //# debugId=41BE8762862D859564756E2164756E21