@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
@@ -2284,7 +2284,84 @@ function normalizeSchemaPath(path) {
2284
2284
 
2285
2285
  // src/codec/asd.ts
2286
2286
  function encodeASD(schema, obj) {
2287
- return serializeBatch(batchFromRows([obj], schema));
2287
+ return serializeBatch(batchFromRows([sortMapsForSchema(schema, obj)], schema));
2288
+ }
2289
+ function compareCodePoints(a, b) {
2290
+ const n = Math.min(a.length, b.length);
2291
+ for (let i = 0;i < n; i++) {
2292
+ const x = a.charCodeAt(i);
2293
+ const y = b.charCodeAt(i);
2294
+ if (x === y)
2295
+ continue;
2296
+ const xs = x >= 55296 && x <= 57343;
2297
+ const ys = y >= 55296 && y <= 57343;
2298
+ if (xs !== ys)
2299
+ return xs ? 1 : -1;
2300
+ return x - y;
2301
+ }
2302
+ return a.length - b.length;
2303
+ }
2304
+ function mapPairs(raw) {
2305
+ if (Array.isArray(raw))
2306
+ return raw.map((e) => Array.isArray(e) ? [e[0], e[1]] : [e?.key, e?.value]);
2307
+ if (raw instanceof Map)
2308
+ return Array.from(raw.entries());
2309
+ if (typeof raw[Symbol.iterator] === "function")
2310
+ return Array.from(raw);
2311
+ return Object.entries(raw);
2312
+ }
2313
+ function compareKeys(a, b) {
2314
+ if (typeof a === "string" && typeof b === "string")
2315
+ return compareCodePoints(a, b);
2316
+ if ((typeof a === "number" || typeof a === "bigint") && (typeof b === "number" || typeof b === "bigint")) {
2317
+ return a < b ? -1 : a > b ? 1 : 0;
2318
+ }
2319
+ return compareCodePoints(String(a), String(b));
2320
+ }
2321
+ var HAS_MAP = new WeakMap;
2322
+ function typeHasMap(type) {
2323
+ const cached = HAS_MAP.get(type);
2324
+ if (cached !== undefined)
2325
+ return cached;
2326
+ let has = isMap(type);
2327
+ if (!has && (isList(type) || isStruct(type))) {
2328
+ has = type.children.some((c) => typeHasMap(c.type));
2329
+ }
2330
+ HAS_MAP.set(type, has);
2331
+ return has;
2332
+ }
2333
+ function sortMapsForType(type, value) {
2334
+ if (value == null || !typeHasMap(type))
2335
+ return value;
2336
+ if (isMap(type)) {
2337
+ const entries = type.children[0].type;
2338
+ const valueType = entries.children[1].type;
2339
+ return mapPairs(value).map(([k, v]) => [k, sortMapsForType(valueType, v)]).sort((x, y) => compareKeys(x[0], y[0]));
2340
+ }
2341
+ if (isList(type)) {
2342
+ const child = type.children[0].type;
2343
+ return Array.from(value, (v) => sortMapsForType(child, v));
2344
+ }
2345
+ if (isStruct(type)) {
2346
+ const out = { ...value };
2347
+ for (const cf of type.children)
2348
+ out[cf.name] = sortMapsForType(cf.type, value[cf.name]);
2349
+ return out;
2350
+ }
2351
+ return value;
2352
+ }
2353
+ function sortMapsForSchema(schema, obj) {
2354
+ let out = null;
2355
+ for (const f of schema.fields) {
2356
+ if (!typeHasMap(f.type))
2357
+ continue;
2358
+ const v = obj[f.name];
2359
+ if (v == null)
2360
+ continue;
2361
+ out ??= { ...obj };
2362
+ out[f.name] = sortMapsForType(f.type, v);
2363
+ }
2364
+ return out ?? obj;
2288
2365
  }
2289
2366
  function decodeASD(schema, bytes) {
2290
2367
  const batch = deserializeBatch(bytes);
@@ -2311,21 +2388,23 @@ function normalizeValue(raw, type) {
2311
2388
  return out;
2312
2389
  }
2313
2390
  if (isMap(type)) {
2391
+ const entries = type.children[0].type;
2392
+ const valueType = entries.children[1].type;
2314
2393
  const out = {};
2394
+ const put = (k, v) => {
2395
+ out[String(k)] = normalizeValue(v, valueType);
2396
+ };
2315
2397
  if (raw[Symbol.iterator]) {
2316
2398
  for (const entry of raw) {
2317
2399
  if (Array.isArray(entry)) {
2318
- out[String(entry[0])] = String(entry[1] ?? "");
2400
+ put(entry[0], entry[1]);
2319
2401
  } else if (entry && typeof entry === "object") {
2320
- const k = entry.key ?? entry[0];
2321
- const v = entry.value ?? entry[1];
2322
- out[String(k)] = v == null ? "" : String(v);
2402
+ put(entry.key ?? entry[0], entry.value ?? entry[1]);
2323
2403
  }
2324
2404
  }
2325
2405
  } else if (typeof raw === "object") {
2326
- for (const [k, v] of Object.entries(raw)) {
2327
- out[String(k)] = v == null ? "" : String(v);
2328
- }
2406
+ for (const [k, v] of Object.entries(raw))
2407
+ put(k, v);
2329
2408
  }
2330
2409
  return out;
2331
2410
  }
@@ -2540,6 +2619,18 @@ var ForeignKeyInfoSchema = schema2([
2540
2619
  field2("referenced_table", utf82(), false),
2541
2620
  field2("referenced_schema_path", list2(field2("item", utf82(), true)), false)
2542
2621
  ]);
2622
+ var SchemaContentsSchema = schema2([
2623
+ field2("path", list2(field2("item", utf82(), true)), false),
2624
+ field2("schema", binary2(), false),
2625
+ field2("tables", list2(field2("item", binary2(), true)), false),
2626
+ field2("views", list2(field2("item", binary2(), true)), false),
2627
+ field2("scalar_functions", list2(field2("item", binary2(), true)), false),
2628
+ field2("aggregate_functions", list2(field2("item", binary2(), true)), false),
2629
+ field2("table_functions", list2(field2("item", binary2(), true)), false),
2630
+ field2("scalar_macros", list2(field2("item", binary2(), true)), false),
2631
+ field2("table_macros", list2(field2("item", binary2(), true)), false),
2632
+ field2("indexes", list2(field2("item", binary2(), true)), false)
2633
+ ]);
2543
2634
  var AggregateBindRequestSchema = schema2([
2544
2635
  field2("function_name", utf82(), false),
2545
2636
  field2("arguments", binary2(), false),
@@ -2862,11 +2953,18 @@ var CatalogAttachResultSchema = schema2([
2862
2953
  field2("global_functions", list2(field2("item", binary2(), true)), false),
2863
2954
  field2("global_function_prefix", utf82(), false),
2864
2955
  field2("resolved_data_version", utf82(), true),
2865
- field2("resolved_implementation_version", utf82(), true)
2956
+ field2("resolved_implementation_version", utf82(), true),
2957
+ field2("supports_catalog_contents", bool2(), false)
2866
2958
  ]);
2867
2959
  var CatalogCatalogsResultSchema = schema2([
2868
2960
  field2("items", list2(field2("item", binary2(), true)), false)
2869
2961
  ]);
2962
+ var CatalogContentsResultSchema = schema2([
2963
+ field2("catalog_version", int642(), false),
2964
+ field2("etag", utf82(), true),
2965
+ field2("not_modified", bool2(), false),
2966
+ 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)
2967
+ ]);
2870
2968
  var CatalogCopyFromFormatsResultSchema = schema2([
2871
2969
  field2("items", list2(field2("item", binary2(), true)), false)
2872
2970
  ]);
@@ -2985,6 +3083,10 @@ var CatalogAttachParamsSchema = schema2([
2985
3083
  field2("request", binary2(), false)
2986
3084
  ]);
2987
3085
  var CatalogCatalogsParamsSchema = schema2([]);
3086
+ var CatalogContentsParamsSchema = schema2([
3087
+ field2("attach_opaque_data", binary2(), false),
3088
+ field2("if_none_match", utf82(), true)
3089
+ ]);
2988
3090
  var CatalogCopyFromFormatsParamsSchema = schema2([
2989
3091
  field2("attach_opaque_data", binary2(), false),
2990
3092
  field2("transaction_opaque_data", binary2(), true)
@@ -3315,10 +3417,14 @@ var TableFunctionStatisticsParamsSchema = schema2([
3315
3417
  field2("request", binary2(), false)
3316
3418
  ]);
3317
3419
 
3420
+ // src/generated/vgi-protocol-types.ts
3421
+ var decodeCatalogContentsResponse = (b) => decodeASD(CatalogContentsResultSchema, b);
3422
+
3318
3423
  // src/generated/vgi-client.ts
3319
3424
  var decodeCatalogInfo = (b) => decodeASD(CatalogInfoSchema, b);
3320
3425
  var encodeFunctionInfo = (v) => encodeASD(FunctionInfoSchema, v);
3321
3426
  var decodeFunctionInfo = (b) => decodeASD(FunctionInfoSchema, b);
3427
+ var decodeIndexInfo = (b) => decodeASD(IndexInfoSchema, b);
3322
3428
  var encodeMacroInfo = (v) => encodeASD(MacroInfoSchema, v);
3323
3429
  var decodeMacroInfo = (b) => decodeASD(MacroInfoSchema, b);
3324
3430
  var encodeSchemaInfo = (v) => encodeASD(SchemaInfoSchema, v);
@@ -3833,7 +3939,118 @@ class VgiClient {
3833
3939
  global_functions: inner.global_functions ? (Array.isArray(inner.global_functions) ? inner.global_functions : [...inner.global_functions]).map(toUint8Array) : [],
3834
3940
  global_function_prefix: inner.global_function_prefix ?? "",
3835
3941
  resolved_data_version: inner.resolved_data_version ?? null,
3836
- resolved_implementation_version: inner.resolved_implementation_version ?? null
3942
+ resolved_implementation_version: inner.resolved_implementation_version ?? null,
3943
+ supports_catalog_contents: inner.supports_catalog_contents ?? false
3944
+ };
3945
+ }
3946
+ async catalogContents(attachOpaqueData, ifNoneMatch = null) {
3947
+ const result = await this.rpc.call("catalog_contents", {
3948
+ attach_opaque_data: attachOpaqueData,
3949
+ if_none_match: ifNoneMatch
3950
+ });
3951
+ if (!result)
3952
+ throw new VgiClientError("catalog_contents returned null");
3953
+ const response = decodeCatalogContentsResponse(toUint8Array(result.result));
3954
+ const schemas = response.schemas.map((c) => {
3955
+ const schema = decodeSchemaInfo(c.schema);
3956
+ if (JSON.stringify(c.path) !== JSON.stringify(schema.path)) {
3957
+ throw new VgiClientError(`catalog_contents: SchemaContents.path ${JSON.stringify(c.path)} != SchemaInfo.path ${JSON.stringify(schema.path)}`);
3958
+ }
3959
+ return {
3960
+ schema,
3961
+ tables: c.tables.map(decodeTableInfo),
3962
+ views: c.views.map(decodeViewInfo),
3963
+ scalar_functions: c.scalar_functions.map(decodeFunctionInfo),
3964
+ aggregate_functions: c.aggregate_functions.map(decodeFunctionInfo),
3965
+ table_functions: c.table_functions.map(decodeFunctionInfo),
3966
+ scalar_macros: c.scalar_macros.map(decodeMacroInfo),
3967
+ table_macros: c.table_macros.map(decodeMacroInfo),
3968
+ indexes: c.indexes.map(decodeIndexInfo)
3969
+ };
3970
+ });
3971
+ return {
3972
+ catalog_version: Number(response.catalog_version ?? 0),
3973
+ etag: response.etag ?? null,
3974
+ not_modified: Boolean(response.not_modified),
3975
+ schemas
3976
+ };
3977
+ }
3978
+ async loadCatalog(attach, opts) {
3979
+ const attachOpaqueData = attach.attach_opaque_data;
3980
+ const previous = opts?.previous ?? null;
3981
+ const useContents = attach.supports_catalog_contents === true && opts?.useCatalogContents !== false && opts?.transactionOpaqueData == null;
3982
+ if (!useContents) {
3983
+ return this._loadCatalogPerSchema(attachOpaqueData, opts?.transactionOpaqueData, null);
3984
+ }
3985
+ let fallbackError = null;
3986
+ const ifNoneMatch = previous?.etag ?? null;
3987
+ const knownVersion = previous?.catalog_version ?? 0;
3988
+ for (let attempt = 0;attempt < 2; attempt++) {
3989
+ let response;
3990
+ try {
3991
+ response = await this.catalogContents(attachOpaqueData, ifNoneMatch);
3992
+ } catch (err) {
3993
+ fallbackError = err instanceof Error ? err.message : String(err);
3994
+ break;
3995
+ }
3996
+ if (response.not_modified) {
3997
+ if (previous == null || ifNoneMatch == null) {
3998
+ fallbackError = "catalog_contents answered not_modified to an unconditional request";
3999
+ break;
4000
+ }
4001
+ return {
4002
+ ...previous,
4003
+ catalog_version: response.catalog_version !== 0 ? response.catalog_version : previous.catalog_version,
4004
+ etag: response.etag ?? ifNoneMatch,
4005
+ not_modified: true,
4006
+ fallback_error: null
4007
+ };
4008
+ }
4009
+ if (response.catalog_version !== 0 && knownVersion !== 0 && response.catalog_version < knownVersion) {
4010
+ fallbackError = `catalog_contents snapshot version ${response.catalog_version} is older than the known version ${knownVersion}`;
4011
+ continue;
4012
+ }
4013
+ return {
4014
+ catalog_version: response.catalog_version,
4015
+ etag: response.etag,
4016
+ source: "catalog_contents",
4017
+ not_modified: false,
4018
+ fallback_error: null,
4019
+ schemas: response.schemas
4020
+ };
4021
+ }
4022
+ return this._loadCatalogPerSchema(attachOpaqueData, undefined, fallbackError);
4023
+ }
4024
+ async _loadCatalogPerSchema(attachOpaqueData, transactionOpaqueData, fallbackError) {
4025
+ const schemas = await this.schemas(attachOpaqueData, transactionOpaqueData);
4026
+ const out = [];
4027
+ for (const schema of schemas) {
4028
+ const counts = schema.estimated_object_count ?? {};
4029
+ const path = schema.path;
4030
+ const has = (kind) => {
4031
+ const n = counts[kind];
4032
+ return n == null || Number(n) !== 0;
4033
+ };
4034
+ const t = transactionOpaqueData;
4035
+ out.push({
4036
+ schema,
4037
+ tables: has("table") ? await this.schemaContentsTables(attachOpaqueData, path, t) : [],
4038
+ views: has("view") ? await this.schemaContentsViews(attachOpaqueData, path, t) : [],
4039
+ scalar_functions: has("scalar_function") ? await this.schemaContentsFunctions(attachOpaqueData, path, "SCALAR_FUNCTION", t) : [],
4040
+ aggregate_functions: has("aggregate_function") ? await this.schemaContentsFunctions(attachOpaqueData, path, "AGGREGATE_FUNCTION", t) : [],
4041
+ table_functions: has("table_function") ? await this.schemaContentsFunctions(attachOpaqueData, path, "TABLE_FUNCTION", t) : [],
4042
+ scalar_macros: has("macro") ? await this.schemaContentsMacros(attachOpaqueData, path, "SCALAR_MACRO", t) : [],
4043
+ table_macros: has("macro") ? await this.schemaContentsMacros(attachOpaqueData, path, "TABLE_MACRO", t) : [],
4044
+ indexes: has("index") ? await this.schemaContentsIndexes(attachOpaqueData, path, t) : []
4045
+ });
4046
+ }
4047
+ return {
4048
+ catalog_version: null,
4049
+ etag: null,
4050
+ source: "per_schema",
4051
+ not_modified: false,
4052
+ fallback_error: fallbackError,
4053
+ schemas: out
3837
4054
  };
3838
4055
  }
3839
4056
  async catalogDetach(attachOpaqueData) {
@@ -3974,6 +4191,17 @@ class VgiClient {
3974
4191
  const inner = unwrapResult(result);
3975
4192
  return deserializeInfoList(inner.items, decodeFunctionInfo);
3976
4193
  }
4194
+ async schemaContentsIndexes(attachOpaqueData, path, transactionOpaqueData) {
4195
+ const result = await this.rpc.call("catalog_schema_contents_indexes", {
4196
+ attach_opaque_data: attachOpaqueData,
4197
+ path: normalizeSchemaPath(path),
4198
+ transaction_opaque_data: transactionOpaqueData ?? null
4199
+ });
4200
+ if (!result)
4201
+ return [];
4202
+ const inner = unwrapResult(result);
4203
+ return deserializeInfoList(inner.items, decodeIndexInfo);
4204
+ }
3977
4205
  async tableGet(attachOpaqueData, schemaPath, name, transactionOpaqueData) {
3978
4206
  const result = await this.rpc.call("catalog_table_get", {
3979
4207
  attach_opaque_data: attachOpaqueData,
@@ -4412,4 +4640,4 @@ export {
4412
4640
  typeSignature
4413
4641
  };
4414
4642
 
4415
- //# debugId=8BECE39CB65F6AD764756E2164756E21
4643
+ //# debugId=A700197CD6EACFA764756E2164756E21