@query-farm/vgi 0.28.0 → 0.29.1

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 (121) hide show
  1. package/README.md +52 -8
  2. package/dist/arguments/argument-spec.d.ts +57 -2
  3. package/dist/arrow/impl-arrowjs/index.d.ts +1 -1
  4. package/dist/arrow/impl-arrowjs/iterate.d.ts +10 -1
  5. package/dist/arrow/impl-arrowjs/schema.d.ts +2 -0
  6. package/dist/arrow/impl-flechette/index.d.ts +1 -1
  7. package/dist/arrow/impl-flechette/iterate.d.ts +10 -1
  8. package/dist/arrow/impl-flechette/schema.d.ts +2 -0
  9. package/dist/arrow/index.d.ts +1 -1
  10. package/dist/arrow/schema-types.d.ts +3 -1
  11. package/dist/arrow/types.d.ts +39 -3
  12. package/dist/catalog/composite.d.ts +13 -13
  13. package/dist/catalog/descriptors.d.ts +7 -3
  14. package/dist/catalog/interface.d.ts +108 -38
  15. package/dist/catalog/read-only.d.ts +32 -15
  16. package/dist/client/client.d.ts +37 -30
  17. package/dist/client/types.d.ts +2 -0
  18. package/dist/client-entry.d.ts +1 -1
  19. package/dist/client-entry.js +791 -447
  20. package/dist/client-entry.js.map +18 -17
  21. package/dist/filter-pushdown/capabilities.d.ts +3 -0
  22. package/dist/filter-pushdown/deserialize.d.ts +14 -15
  23. package/dist/filter-pushdown/evaluate.d.ts +14 -44
  24. package/dist/filter-pushdown/index.d.ts +2 -2
  25. package/dist/filter-pushdown/types.d.ts +120 -68
  26. package/dist/functions/aggregate.d.ts +4 -0
  27. package/dist/functions/registry.d.ts +5 -5
  28. package/dist/functions/scalar.d.ts +6 -1
  29. package/dist/functions/table-buffering.d.ts +9 -0
  30. package/dist/functions/table-in-out.d.ts +13 -0
  31. package/dist/functions/table.d.ts +72 -2
  32. package/dist/functions/types.d.ts +60 -2
  33. package/dist/generated/vgi-client.d.ts +114 -26
  34. package/dist/generated/vgi-protocol-schemas.d.ts +34 -0
  35. package/dist/http/fetch.d.ts +16 -0
  36. package/dist/index.core.d.ts +4 -3
  37. package/dist/index.js +3396 -2064
  38. package/dist/index.js.map +55 -49
  39. package/dist/metadata/types.d.ts +15 -2
  40. package/dist/protocol/handlers/catalog/shared.d.ts +0 -8
  41. package/dist/protocol/handlers/function.d.ts +11 -0
  42. package/dist/protocol/handlers/shared.d.ts +3 -1
  43. package/dist/protocol/serializers/bind.d.ts +1 -2
  44. package/dist/protocol/serializers/cardinality.d.ts +1 -2
  45. package/dist/protocol/serializers/splits.d.ts +126 -0
  46. package/dist/protocol/types.d.ts +36 -3
  47. package/dist/request-auth.d.ts +28 -0
  48. package/dist/schema-path.d.ts +7 -0
  49. package/dist/serve-entry.d.ts +25 -0
  50. package/dist/serve-entry.js +1129 -569
  51. package/dist/serve-entry.js.map +36 -32
  52. package/dist/split-token.d.ts +88 -0
  53. package/dist/types.d.ts +8 -0
  54. package/dist/worker-cf-entry.js +2928 -1689
  55. package/dist/worker-cf-entry.js.map +51 -44
  56. package/dist/worker.d.ts +1 -1
  57. package/package.json +3 -3
  58. package/src/arguments/argument-spec.ts +93 -4
  59. package/src/arguments/arguments.ts +0 -1
  60. package/src/arrow/impl-arrowjs/index.ts +1 -1
  61. package/src/arrow/impl-arrowjs/iterate.ts +21 -0
  62. package/src/arrow/impl-arrowjs/schema.ts +4 -0
  63. package/src/arrow/impl-flechette/index.ts +1 -1
  64. package/src/arrow/impl-flechette/iterate.ts +24 -1
  65. package/src/arrow/impl-flechette/schema.ts +4 -0
  66. package/src/arrow/index.ts +1 -1
  67. package/src/arrow/schema-types.ts +4 -0
  68. package/src/arrow/types.ts +39 -3
  69. package/src/catalog/composite.ts +26 -26
  70. package/src/catalog/descriptors.ts +12 -3
  71. package/src/catalog/interface.ts +217 -72
  72. package/src/catalog/read-only.ts +141 -84
  73. package/src/client/client.ts +97 -73
  74. package/src/client/types.ts +2 -0
  75. package/src/client-entry.ts +2 -1
  76. package/src/filter-pushdown/capabilities.ts +13 -0
  77. package/src/filter-pushdown/collector.ts +22 -35
  78. package/src/filter-pushdown/deserialize.ts +657 -221
  79. package/src/filter-pushdown/evaluate.ts +410 -499
  80. package/src/filter-pushdown/index.ts +16 -2
  81. package/src/filter-pushdown/types.ts +88 -71
  82. package/src/functions/aggregate.ts +12 -1
  83. package/src/functions/copy-from.ts +2 -1
  84. package/src/functions/copy-to.ts +2 -1
  85. package/src/functions/registry.ts +24 -22
  86. package/src/functions/scalar.ts +37 -0
  87. package/src/functions/table-buffering.ts +48 -6
  88. package/src/functions/table-in-out.ts +194 -33
  89. package/src/functions/table.ts +187 -22
  90. package/src/functions/types.ts +64 -1
  91. package/src/generated/vgi-client.ts +122 -28
  92. package/src/generated/vgi-protocol-schemas.ts +455 -58
  93. package/src/http/fetch.ts +129 -2
  94. package/src/index.core.ts +4 -2
  95. package/src/metadata/resolve.ts +43 -1
  96. package/src/metadata/serialize.ts +43 -5
  97. package/src/metadata/types.ts +17 -1
  98. package/src/protocol/dispatch.ts +1 -1
  99. package/src/protocol/handlers/aggregate.ts +23 -12
  100. package/src/protocol/handlers/catalog/admin.ts +47 -54
  101. package/src/protocol/handlers/catalog/index_methods.ts +6 -13
  102. package/src/protocol/handlers/catalog/macro.ts +12 -20
  103. package/src/protocol/handlers/catalog/shared.ts +12 -57
  104. package/src/protocol/handlers/catalog/table.ts +49 -112
  105. package/src/protocol/handlers/catalog/view.ts +18 -22
  106. package/src/protocol/handlers/function.ts +311 -18
  107. package/src/protocol/handlers/shared.ts +12 -3
  108. package/src/protocol/handlers/table-buffering.ts +11 -8
  109. package/src/protocol/serializers/bind.ts +69 -67
  110. package/src/protocol/serializers/cardinality.ts +7 -7
  111. package/src/protocol/serializers/init.ts +52 -10
  112. package/src/protocol/serializers/splits.ts +221 -0
  113. package/src/protocol/state-serializer.ts +55 -1
  114. package/src/protocol/types.ts +36 -3
  115. package/src/request-auth.ts +73 -0
  116. package/src/schema-path.ts +25 -0
  117. package/src/serve-entry.ts +69 -2
  118. package/src/split-token.ts +297 -0
  119. package/src/types.ts +9 -0
  120. package/src/worker-cf-entry.ts +2 -1
  121. package/src/worker.ts +79 -14
@@ -47,6 +47,9 @@ import { wrapRequest, unwrapResult } from "./protocol.js";
47
47
  import { toUint8Array } from "../util/bytes.js";
48
48
  import { serializeAttachOptions } from "../catalog/attach-options.js";
49
49
  import { VgiClientError, wrapRpcWithErrorEnrichment } from "./errors.js";
50
+ import { normalizeSchemaPath } from "../schema-path.js";
51
+ import { encodeASD } from "../codec/asd.js";
52
+ import { ClientCapabilitiesSchema, MacroCreateRequestSchema } from "../generated/vgi-protocol-schemas.js";
50
53
  import { deserializeInfoList, deserializeTags, toAsyncIterator } from "./helpers.js";
51
54
 
52
55
  export { VgiClientError };
@@ -70,7 +73,7 @@ import type {
70
73
  * Works with any RpcClient transport (subprocess or HTTP):
71
74
  * ```ts
72
75
  * import { subprocessConnect } from "@query-farm/vgi-rpc";
73
- * import { VgiClient, Arguments } from "vgi";
76
+ * import { VgiClient, Arguments } from "@query-farm/vgi";
74
77
  *
75
78
  * const rpc = subprocessConnect(["./my-worker"]);
76
79
  * const client = new VgiClient(rpc);
@@ -102,6 +105,32 @@ export class VgiClient {
102
105
  this.defaultAttachOpaqueData = options?.attachOpaqueData ?? null;
103
106
  }
104
107
 
108
+ /**
109
+ * Connect the high-level client to a canonical `iroh://` or `httpi://`
110
+ * endpoint. Native Node/Bun connectors are selected from the URI scheme.
111
+ * Browser callers may inject the connector exported by the browser Iroh
112
+ * package without changing the VGI client API.
113
+ */
114
+ static async fromIroh(
115
+ endpoint: string,
116
+ options: Record<string, unknown> = {},
117
+ clientOptions?: VgiClientOptions,
118
+ connector?: (endpoint: string, options: Record<string, unknown>) => Promise<RpcClient>,
119
+ ): Promise<VgiClient> {
120
+ if (!/^(iroh|httpi):\/\//.test(endpoint)) {
121
+ throw new TypeError("VgiClient.fromIroh requires an iroh:// or httpi:// endpoint");
122
+ }
123
+ let selected = connector;
124
+ if (!selected) {
125
+ const rpc = await import("@query-farm/vgi-rpc");
126
+ selected = endpoint.startsWith("iroh://")
127
+ ? (rpc.irohConnect as unknown as NonNullable<typeof selected>)
128
+ : (rpc.httpiConnect as unknown as NonNullable<typeof selected>);
129
+ }
130
+ if (!selected) throw new TypeError("no Iroh connector is available in this runtime");
131
+ return new VgiClient(await selected(endpoint, options), clientOptions);
132
+ }
133
+
105
134
  // ==========================================================================
106
135
  // Private helpers
107
136
  // ==========================================================================
@@ -157,6 +186,10 @@ export class VgiClient {
157
186
  bind_call: bindRequest,
158
187
  output_schema: bindResponse.output_schema,
159
188
  bind_opaque_data: bindResponse.opaque_data,
189
+ // This client does not plan scans, so it never redeems a split, and it
190
+ // pushes no limit down.
191
+ split_tokens: null,
192
+ row_limit: null,
160
193
  projection_ids: opts?.projectionIds ?? null,
161
194
  pushdown_filters: opts?.pushdownFilters ?? null,
162
195
  join_keys: opts?.joinKeys ?? [],
@@ -595,6 +628,7 @@ export class VgiClient {
595
628
  field("options", binary(), true),
596
629
  field("data_version_spec", utf8(), true),
597
630
  field("implementation_version", utf8(), true),
631
+ field("client_capabilities", binary(), true),
598
632
  ]);
599
633
  const innerBatch = batchFromColumns(
600
634
  {
@@ -602,6 +636,9 @@ export class VgiClient {
602
636
  options: [wireOptions],
603
637
  data_version_spec: [opts?.dataVersionSpec ?? null],
604
638
  implementation_version: [opts?.implementationVersion ?? null],
639
+ client_capabilities: [opts?.clientCapabilities
640
+ ? encodeASD(ClientCapabilitiesSchema, opts.clientCapabilities)
641
+ : null],
605
642
  },
606
643
  schema,
607
644
  );
@@ -753,12 +790,12 @@ export class VgiClient {
753
790
  /** Get a schema by name, or null if not found. */
754
791
  async schemaGet(
755
792
  attachOpaqueData: AttachOpaqueData,
756
- name: string,
793
+ path: string[] | string,
757
794
  transactionOpaqueData?: TransactionOpaqueData,
758
795
  ): Promise<SchemaInfo | null> {
759
796
  const result = await this.rpc.call("catalog_schema_get", {
760
797
  attach_opaque_data: attachOpaqueData,
761
- name,
798
+ path: normalizeSchemaPath(path),
762
799
  transaction_opaque_data: transactionOpaqueData ?? null,
763
800
  });
764
801
  if (!result) return null;
@@ -770,7 +807,7 @@ export class VgiClient {
770
807
  /** Create a new schema. */
771
808
  async schemaCreate(
772
809
  attachOpaqueData: AttachOpaqueData,
773
- name: string,
810
+ path: string[] | string,
774
811
  opts?: {
775
812
  onConflict?: OnCreateConflict;
776
813
  comment?: string | null;
@@ -783,7 +820,7 @@ export class VgiClient {
783
820
  : null;
784
821
  await this.rpc.call("catalog_schema_create", {
785
822
  attach_opaque_data: attachOpaqueData,
786
- name,
823
+ path: normalizeSchemaPath(path),
787
824
  on_conflict: opts?.onConflict ?? "error",
788
825
  comment: opts?.comment ?? null,
789
826
  tags: tagsMap,
@@ -794,14 +831,14 @@ export class VgiClient {
794
831
  /** Drop a schema by name. */
795
832
  async schemaDrop(
796
833
  attachOpaqueData: AttachOpaqueData,
797
- name: string,
834
+ path: string[] | string,
798
835
  ignoreNotFound?: boolean,
799
836
  cascade?: boolean,
800
837
  transactionOpaqueData?: TransactionOpaqueData,
801
838
  ): Promise<void> {
802
839
  await this.rpc.call("catalog_schema_drop", {
803
840
  attach_opaque_data: attachOpaqueData,
804
- name,
841
+ path: normalizeSchemaPath(path),
805
842
  ignore_not_found: ignoreNotFound ?? false,
806
843
  cascade: cascade ?? false,
807
844
  transaction_opaque_data: transactionOpaqueData ?? null,
@@ -811,12 +848,12 @@ export class VgiClient {
811
848
  /** List tables in a schema. */
812
849
  async schemaContentsTables(
813
850
  attachOpaqueData: AttachOpaqueData,
814
- name: string,
851
+ path: string[] | string,
815
852
  transactionOpaqueData?: TransactionOpaqueData,
816
853
  ): Promise<TableInfo[]> {
817
854
  const result = await this.rpc.call("catalog_schema_contents_tables", {
818
855
  attach_opaque_data: attachOpaqueData,
819
- name,
856
+ path: normalizeSchemaPath(path),
820
857
  transaction_opaque_data: transactionOpaqueData ?? null,
821
858
  });
822
859
  if (!result) return [];
@@ -827,12 +864,12 @@ export class VgiClient {
827
864
  /** List views in a schema. */
828
865
  async schemaContentsViews(
829
866
  attachOpaqueData: AttachOpaqueData,
830
- name: string,
867
+ path: string[] | string,
831
868
  transactionOpaqueData?: TransactionOpaqueData,
832
869
  ): Promise<ViewInfo[]> {
833
870
  const result = await this.rpc.call("catalog_schema_contents_views", {
834
871
  attach_opaque_data: attachOpaqueData,
835
- name,
872
+ path: normalizeSchemaPath(path),
836
873
  transaction_opaque_data: transactionOpaqueData ?? null,
837
874
  });
838
875
  if (!result) return [];
@@ -843,13 +880,13 @@ export class VgiClient {
843
880
  /** List functions in a schema, filtered by type. */
844
881
  async schemaContentsFunctions(
845
882
  attachOpaqueData: AttachOpaqueData,
846
- name: string,
883
+ path: string[] | string,
847
884
  type: CatalogFunctionType,
848
885
  transactionOpaqueData?: TransactionOpaqueData,
849
886
  ): Promise<FunctionInfo[]> {
850
887
  const result = await this.rpc.call("catalog_schema_contents_functions", {
851
888
  attach_opaque_data: attachOpaqueData,
852
- name,
889
+ path: normalizeSchemaPath(path),
853
890
  type,
854
891
  transaction_opaque_data: transactionOpaqueData ?? null,
855
892
  });
@@ -861,13 +898,13 @@ export class VgiClient {
861
898
  /** Get a table by name, or null if not found. */
862
899
  async tableGet(
863
900
  attachOpaqueData: AttachOpaqueData,
864
- schemaName: string,
901
+ schemaPath: string[] | string,
865
902
  name: string,
866
903
  transactionOpaqueData?: TransactionOpaqueData,
867
904
  ): Promise<TableInfo | null> {
868
905
  const result = await this.rpc.call("catalog_table_get", {
869
906
  attach_opaque_data: attachOpaqueData,
870
- schema_name: schemaName,
907
+ schema_path: normalizeSchemaPath(schemaPath),
871
908
  name,
872
909
  transaction_opaque_data: transactionOpaqueData ?? null,
873
910
  });
@@ -880,7 +917,7 @@ export class VgiClient {
880
917
  /** Create a new table. */
881
918
  async tableCreate(
882
919
  attachOpaqueData: AttachOpaqueData,
883
- schemaName: string,
920
+ schemaPath: string[] | string,
884
921
  name: string,
885
922
  columns: Uint8Array,
886
923
  onConflict: OnCreateConflict,
@@ -891,7 +928,7 @@ export class VgiClient {
891
928
  ): Promise<void> {
892
929
  await this.rpc.call("catalog_table_create", {
893
930
  attach_opaque_data: attachOpaqueData,
894
- schema_name: schemaName,
931
+ schema_path: normalizeSchemaPath(schemaPath),
895
932
  name,
896
933
  columns,
897
934
  on_conflict: onConflict,
@@ -905,7 +942,7 @@ export class VgiClient {
905
942
  /** Drop a table by name. */
906
943
  async tableDrop(
907
944
  attachOpaqueData: AttachOpaqueData,
908
- schemaName: string,
945
+ schemaPath: string[] | string,
909
946
  name: string,
910
947
  ignoreNotFound?: boolean,
911
948
  cascade?: boolean,
@@ -913,7 +950,7 @@ export class VgiClient {
913
950
  ): Promise<void> {
914
951
  await this.rpc.call("catalog_table_drop", {
915
952
  attach_opaque_data: attachOpaqueData,
916
- schema_name: schemaName,
953
+ schema_path: normalizeSchemaPath(schemaPath),
917
954
  name,
918
955
  ignore_not_found: ignoreNotFound ?? false,
919
956
  cascade: cascade ?? false,
@@ -928,7 +965,7 @@ export class VgiClient {
928
965
  */
929
966
  async tableScanFunctionGet(
930
967
  attachOpaqueData: AttachOpaqueData,
931
- schemaName: string,
968
+ schemaPath: string[] | string,
932
969
  name: string,
933
970
  atUnit?: string | null,
934
971
  atValue?: string | null,
@@ -936,7 +973,7 @@ export class VgiClient {
936
973
  ): Promise<ScanFunctionResult> {
937
974
  const result = await this.rpc.call("catalog_table_scan_function_get", {
938
975
  attach_opaque_data: attachOpaqueData,
939
- schema_name: schemaName,
976
+ schema_path: normalizeSchemaPath(schemaPath),
940
977
  name,
941
978
  at_unit: atUnit ?? null,
942
979
  at_value: atValue ?? null,
@@ -949,7 +986,7 @@ export class VgiClient {
949
986
  /** Set or clear the comment on a table. */
950
987
  async tableCommentSet(
951
988
  attachOpaqueData: AttachOpaqueData,
952
- schemaName: string,
989
+ schemaPath: string[] | string,
953
990
  name: string,
954
991
  comment?: string | null,
955
992
  ignoreNotFound?: boolean,
@@ -957,7 +994,7 @@ export class VgiClient {
957
994
  ): Promise<void> {
958
995
  await this.rpc.call("catalog_table_comment_set", {
959
996
  attach_opaque_data: attachOpaqueData,
960
- schema_name: schemaName,
997
+ schema_path: normalizeSchemaPath(schemaPath),
961
998
  name,
962
999
  comment: comment ?? null,
963
1000
  ignore_not_found: ignoreNotFound ?? null,
@@ -968,7 +1005,7 @@ export class VgiClient {
968
1005
  /** Rename a table. */
969
1006
  async tableRename(
970
1007
  attachOpaqueData: AttachOpaqueData,
971
- schemaName: string,
1008
+ schemaPath: string[] | string,
972
1009
  name: string,
973
1010
  newName: string,
974
1011
  ignoreNotFound?: boolean,
@@ -976,7 +1013,7 @@ export class VgiClient {
976
1013
  ): Promise<void> {
977
1014
  await this.rpc.call("catalog_table_rename", {
978
1015
  attach_opaque_data: attachOpaqueData,
979
- schema_name: schemaName,
1016
+ schema_path: normalizeSchemaPath(schemaPath),
980
1017
  name,
981
1018
  new_name: newName,
982
1019
  ignore_not_found: ignoreNotFound ?? null,
@@ -987,7 +1024,7 @@ export class VgiClient {
987
1024
  /** Add a column to a table. */
988
1025
  async tableColumnAdd(
989
1026
  attachOpaqueData: AttachOpaqueData,
990
- schemaName: string,
1027
+ schemaPath: string[] | string,
991
1028
  name: string,
992
1029
  columnName: string,
993
1030
  columnType: string,
@@ -997,7 +1034,7 @@ export class VgiClient {
997
1034
  ): Promise<void> {
998
1035
  await this.rpc.call("catalog_table_column_add", {
999
1036
  attach_opaque_data: attachOpaqueData,
1000
- schema_name: schemaName,
1037
+ schema_path: normalizeSchemaPath(schemaPath),
1001
1038
  name,
1002
1039
  column_name: columnName,
1003
1040
  column_type: columnType,
@@ -1010,7 +1047,7 @@ export class VgiClient {
1010
1047
  /** Drop a column from a table. */
1011
1048
  async tableColumnDrop(
1012
1049
  attachOpaqueData: AttachOpaqueData,
1013
- schemaName: string,
1050
+ schemaPath: string[] | string,
1014
1051
  name: string,
1015
1052
  columnName: string,
1016
1053
  ignoreNotFound?: boolean,
@@ -1018,7 +1055,7 @@ export class VgiClient {
1018
1055
  ): Promise<void> {
1019
1056
  await this.rpc.call("catalog_table_column_drop", {
1020
1057
  attach_opaque_data: attachOpaqueData,
1021
- schema_name: schemaName,
1058
+ schema_path: normalizeSchemaPath(schemaPath),
1022
1059
  name,
1023
1060
  column_name: columnName,
1024
1061
  ignore_not_found: ignoreNotFound ?? null,
@@ -1029,7 +1066,7 @@ export class VgiClient {
1029
1066
  /** Rename a column in a table. */
1030
1067
  async tableColumnRename(
1031
1068
  attachOpaqueData: AttachOpaqueData,
1032
- schemaName: string,
1069
+ schemaPath: string[] | string,
1033
1070
  name: string,
1034
1071
  columnName: string,
1035
1072
  newName: string,
@@ -1038,7 +1075,7 @@ export class VgiClient {
1038
1075
  ): Promise<void> {
1039
1076
  await this.rpc.call("catalog_table_column_rename", {
1040
1077
  attach_opaque_data: attachOpaqueData,
1041
- schema_name: schemaName,
1078
+ schema_path: normalizeSchemaPath(schemaPath),
1042
1079
  name,
1043
1080
  column_name: columnName,
1044
1081
  new_name: newName,
@@ -1050,7 +1087,7 @@ export class VgiClient {
1050
1087
  /** Set the default value for a column. */
1051
1088
  async tableColumnDefaultSet(
1052
1089
  attachOpaqueData: AttachOpaqueData,
1053
- schemaName: string,
1090
+ schemaPath: string[] | string,
1054
1091
  name: string,
1055
1092
  columnName: string,
1056
1093
  defaultValue: string,
@@ -1059,7 +1096,7 @@ export class VgiClient {
1059
1096
  ): Promise<void> {
1060
1097
  await this.rpc.call("catalog_table_column_default_set", {
1061
1098
  attach_opaque_data: attachOpaqueData,
1062
- schema_name: schemaName,
1099
+ schema_path: normalizeSchemaPath(schemaPath),
1063
1100
  name,
1064
1101
  column_name: columnName,
1065
1102
  default_value: defaultValue,
@@ -1071,7 +1108,7 @@ export class VgiClient {
1071
1108
  /** Remove the default value from a column. */
1072
1109
  async tableColumnDefaultDrop(
1073
1110
  attachOpaqueData: AttachOpaqueData,
1074
- schemaName: string,
1111
+ schemaPath: string[] | string,
1075
1112
  name: string,
1076
1113
  columnName: string,
1077
1114
  ignoreNotFound?: boolean,
@@ -1079,7 +1116,7 @@ export class VgiClient {
1079
1116
  ): Promise<void> {
1080
1117
  await this.rpc.call("catalog_table_column_default_drop", {
1081
1118
  attach_opaque_data: attachOpaqueData,
1082
- schema_name: schemaName,
1119
+ schema_path: normalizeSchemaPath(schemaPath),
1083
1120
  name,
1084
1121
  column_name: columnName,
1085
1122
  ignore_not_found: ignoreNotFound ?? null,
@@ -1096,7 +1133,7 @@ export class VgiClient {
1096
1133
  */
1097
1134
  async tableColumnTypeChange(
1098
1135
  attachOpaqueData: AttachOpaqueData,
1099
- schemaName: string,
1136
+ schemaPath: string[] | string,
1100
1137
  name: string,
1101
1138
  columnDefinition: Uint8Array,
1102
1139
  expression?: string | null,
@@ -1105,7 +1142,7 @@ export class VgiClient {
1105
1142
  ): Promise<void> {
1106
1143
  await this.rpc.call("catalog_table_column_type_change", {
1107
1144
  attach_opaque_data: attachOpaqueData,
1108
- schema_name: schemaName,
1145
+ schema_path: normalizeSchemaPath(schemaPath),
1109
1146
  name,
1110
1147
  column_definition: columnDefinition,
1111
1148
  expression: expression ?? null,
@@ -1117,7 +1154,7 @@ export class VgiClient {
1117
1154
  /** Set a NOT NULL constraint on a column. */
1118
1155
  async tableNotNullSet(
1119
1156
  attachOpaqueData: AttachOpaqueData,
1120
- schemaName: string,
1157
+ schemaPath: string[] | string,
1121
1158
  name: string,
1122
1159
  columnName: string,
1123
1160
  ignoreNotFound?: boolean,
@@ -1125,7 +1162,7 @@ export class VgiClient {
1125
1162
  ): Promise<void> {
1126
1163
  await this.rpc.call("catalog_table_not_null_set", {
1127
1164
  attach_opaque_data: attachOpaqueData,
1128
- schema_name: schemaName,
1165
+ schema_path: normalizeSchemaPath(schemaPath),
1129
1166
  name,
1130
1167
  column_name: columnName,
1131
1168
  ignore_not_found: ignoreNotFound ?? null,
@@ -1136,7 +1173,7 @@ export class VgiClient {
1136
1173
  /** Remove a NOT NULL constraint from a column. */
1137
1174
  async tableNotNullDrop(
1138
1175
  attachOpaqueData: AttachOpaqueData,
1139
- schemaName: string,
1176
+ schemaPath: string[] | string,
1140
1177
  name: string,
1141
1178
  columnName: string,
1142
1179
  ignoreNotFound?: boolean,
@@ -1144,7 +1181,7 @@ export class VgiClient {
1144
1181
  ): Promise<void> {
1145
1182
  await this.rpc.call("catalog_table_not_null_drop", {
1146
1183
  attach_opaque_data: attachOpaqueData,
1147
- schema_name: schemaName,
1184
+ schema_path: normalizeSchemaPath(schemaPath),
1148
1185
  name,
1149
1186
  column_name: columnName,
1150
1187
  ignore_not_found: ignoreNotFound ?? null,
@@ -1155,13 +1192,13 @@ export class VgiClient {
1155
1192
  /** Get a view by name, or null if not found. */
1156
1193
  async viewGet(
1157
1194
  attachOpaqueData: AttachOpaqueData,
1158
- schemaName: string,
1195
+ schemaPath: string[] | string,
1159
1196
  name: string,
1160
1197
  transactionOpaqueData?: TransactionOpaqueData,
1161
1198
  ): Promise<ViewInfo | null> {
1162
1199
  const result = await this.rpc.call("catalog_view_get", {
1163
1200
  attach_opaque_data: attachOpaqueData,
1164
- schema_name: schemaName,
1201
+ schema_path: normalizeSchemaPath(schemaPath),
1165
1202
  name,
1166
1203
  transaction_opaque_data: transactionOpaqueData ?? null,
1167
1204
  });
@@ -1174,7 +1211,7 @@ export class VgiClient {
1174
1211
  /** Create a new view. */
1175
1212
  async viewCreate(
1176
1213
  attachOpaqueData: AttachOpaqueData,
1177
- schemaName: string,
1214
+ schemaPath: string[] | string,
1178
1215
  name: string,
1179
1216
  definition: string,
1180
1217
  onConflict: OnCreateConflict,
@@ -1182,7 +1219,7 @@ export class VgiClient {
1182
1219
  ): Promise<void> {
1183
1220
  await this.rpc.call("catalog_view_create", {
1184
1221
  attach_opaque_data: attachOpaqueData,
1185
- schema_name: schemaName,
1222
+ schema_path: normalizeSchemaPath(schemaPath),
1186
1223
  name,
1187
1224
  definition,
1188
1225
  on_conflict: onConflict,
@@ -1193,7 +1230,7 @@ export class VgiClient {
1193
1230
  /** Drop a view by name. */
1194
1231
  async viewDrop(
1195
1232
  attachOpaqueData: AttachOpaqueData,
1196
- schemaName: string,
1233
+ schemaPath: string[] | string,
1197
1234
  name: string,
1198
1235
  ignoreNotFound?: boolean,
1199
1236
  cascade?: boolean,
@@ -1201,7 +1238,7 @@ export class VgiClient {
1201
1238
  ): Promise<void> {
1202
1239
  await this.rpc.call("catalog_view_drop", {
1203
1240
  attach_opaque_data: attachOpaqueData,
1204
- schema_name: schemaName,
1241
+ schema_path: normalizeSchemaPath(schemaPath),
1205
1242
  name,
1206
1243
  ignore_not_found: ignoreNotFound ?? false,
1207
1244
  cascade: cascade ?? false,
@@ -1212,7 +1249,7 @@ export class VgiClient {
1212
1249
  /** Rename a view. */
1213
1250
  async viewRename(
1214
1251
  attachOpaqueData: AttachOpaqueData,
1215
- schemaName: string,
1252
+ schemaPath: string[] | string,
1216
1253
  name: string,
1217
1254
  newName: string,
1218
1255
  ignoreNotFound?: boolean,
@@ -1220,7 +1257,7 @@ export class VgiClient {
1220
1257
  ): Promise<void> {
1221
1258
  await this.rpc.call("catalog_view_rename", {
1222
1259
  attach_opaque_data: attachOpaqueData,
1223
- schema_name: schemaName,
1260
+ schema_path: normalizeSchemaPath(schemaPath),
1224
1261
  name,
1225
1262
  new_name: newName,
1226
1263
  ignore_not_found: ignoreNotFound ?? null,
@@ -1231,7 +1268,7 @@ export class VgiClient {
1231
1268
  /** Set or clear the comment on a view. */
1232
1269
  async viewCommentSet(
1233
1270
  attachOpaqueData: AttachOpaqueData,
1234
- schemaName: string,
1271
+ schemaPath: string[] | string,
1235
1272
  name: string,
1236
1273
  comment?: string | null,
1237
1274
  ignoreNotFound?: boolean,
@@ -1239,7 +1276,7 @@ export class VgiClient {
1239
1276
  ): Promise<void> {
1240
1277
  await this.rpc.call("catalog_view_comment_set", {
1241
1278
  attach_opaque_data: attachOpaqueData,
1242
- schema_name: schemaName,
1279
+ schema_path: normalizeSchemaPath(schemaPath),
1243
1280
  name,
1244
1281
  comment: comment ?? null,
1245
1282
  ignore_not_found: ignoreNotFound ?? null,
@@ -1254,13 +1291,13 @@ export class VgiClient {
1254
1291
  /** Get a macro by name, or null if not found. */
1255
1292
  async macroGet(
1256
1293
  attachOpaqueData: AttachOpaqueData,
1257
- schemaName: string,
1294
+ schemaPath: string[] | string,
1258
1295
  name: string,
1259
1296
  transactionOpaqueData?: TransactionOpaqueData,
1260
1297
  ): Promise<MacroInfo | null> {
1261
1298
  const result = await this.rpc.call("catalog_macro_get", {
1262
1299
  attach_opaque_data: attachOpaqueData,
1263
- schema_name: schemaName,
1300
+ schema_path: normalizeSchemaPath(schemaPath),
1264
1301
  name,
1265
1302
  transaction_opaque_data: transactionOpaqueData ?? null,
1266
1303
  });
@@ -1273,13 +1310,13 @@ export class VgiClient {
1273
1310
  /** List macros in a schema, filtered by type. */
1274
1311
  async schemaContentsMacros(
1275
1312
  attachOpaqueData: AttachOpaqueData,
1276
- name: string,
1313
+ path: string[] | string,
1277
1314
  type: CatalogMacroType,
1278
1315
  transactionOpaqueData?: TransactionOpaqueData,
1279
1316
  ): Promise<MacroInfo[]> {
1280
1317
  const result = await this.rpc.call("catalog_schema_contents_macros", {
1281
1318
  attach_opaque_data: attachOpaqueData,
1282
- name,
1319
+ path: normalizeSchemaPath(path),
1283
1320
  type,
1284
1321
  transaction_opaque_data: transactionOpaqueData ?? null,
1285
1322
  });
@@ -1291,7 +1328,7 @@ export class VgiClient {
1291
1328
  /** Create a new macro. */
1292
1329
  async macroCreate(
1293
1330
  attachOpaqueData: AttachOpaqueData,
1294
- schemaName: string,
1331
+ schemaPath: string[] | string,
1295
1332
  name: string,
1296
1333
  macroType: MacroType,
1297
1334
  parameters: string[],
@@ -1301,22 +1338,10 @@ export class VgiClient {
1301
1338
  argumentsSchema?: Uint8Array | null,
1302
1339
  transactionOpaqueData?: TransactionOpaqueData,
1303
1340
  ): Promise<void> {
1304
- const schema = schema_([
1305
- field("attach_opaque_data", binary(), true),
1306
- field("schema_name", utf8(), false),
1307
- field("name", utf8(), false),
1308
- field("macro_type", utf8(), false),
1309
- field("parameters", list(field("item", utf8(), false)), false),
1310
- field("definition", utf8(), false),
1311
- field("on_conflict", utf8(), false),
1312
- field("parameter_default_values", binary(), true),
1313
- field("arguments_schema", binary(), true),
1314
- field("transaction_opaque_data", binary(), true),
1315
- ]);
1316
1341
  const innerBatch = batchFromColumns(
1317
1342
  {
1318
1343
  attach_opaque_data: [attachOpaqueData],
1319
- schema_name: [schemaName],
1344
+ schema_path: [normalizeSchemaPath(schemaPath)],
1320
1345
  name: [name],
1321
1346
  macro_type: [macroType],
1322
1347
  parameters: [parameters],
@@ -1326,7 +1351,7 @@ export class VgiClient {
1326
1351
  arguments_schema: [argumentsSchema ?? null],
1327
1352
  transaction_opaque_data: [transactionOpaqueData ?? null],
1328
1353
  },
1329
- schema,
1354
+ MacroCreateRequestSchema,
1330
1355
  );
1331
1356
  await this.rpc.call("catalog_macro_create", wrapRequest(innerBatch));
1332
1357
  }
@@ -1334,14 +1359,14 @@ export class VgiClient {
1334
1359
  /** Drop a macro by name. */
1335
1360
  async macroDrop(
1336
1361
  attachOpaqueData: AttachOpaqueData,
1337
- schemaName: string,
1362
+ schemaPath: string[] | string,
1338
1363
  name: string,
1339
1364
  ignoreNotFound?: boolean,
1340
1365
  transactionOpaqueData?: TransactionOpaqueData,
1341
1366
  ): Promise<void> {
1342
1367
  await this.rpc.call("catalog_macro_drop", {
1343
1368
  attach_opaque_data: attachOpaqueData,
1344
- schema_name: schemaName,
1369
+ schema_path: normalizeSchemaPath(schemaPath),
1345
1370
  name,
1346
1371
  ignore_not_found: ignoreNotFound ?? false,
1347
1372
  transaction_opaque_data: transactionOpaqueData ?? null,
@@ -1353,4 +1378,3 @@ export class VgiClient {
1353
1378
  this.rpc.close();
1354
1379
  }
1355
1380
  }
1356
-
@@ -48,6 +48,8 @@ export interface CatalogAttachOptions {
48
48
  optionsBytes?: Uint8Array;
49
49
  dataVersionSpec?: string | null;
50
50
  implementationVersion?: string | null;
51
+ /** Engine capabilities serialized into the protocol's named inner record. */
52
+ clientCapabilities?: import("../generated/vgi-client.js").ClientCapabilities | null;
51
53
  }
52
54
 
53
55
  /** Conflict resolution strategy for create operations. */
@@ -8,7 +8,7 @@
8
8
  //
9
9
  // Usage:
10
10
  // import { VgiClient, Arguments } from "vgi/client";
11
- // import { httpConnect } from "@query-farm/vgi-rpc"; // or your own RpcClient
11
+ // import { httpConnect } from "@query-farm/vgi-rpc"; // or VgiClient.fromIroh(...)
12
12
  //
13
13
  // const rpc = httpConnect("https://my-vgi-server/");
14
14
  // const client = new VgiClient(rpc);
@@ -37,6 +37,7 @@ export {
37
37
  FunctionType,
38
38
  FunctionStability,
39
39
  NullHandling,
40
+ ArgumentMonotonicity,
40
41
  OrderPreservation,
41
42
  OrderDependence,
42
43
  DistinctDependence,
@@ -0,0 +1,13 @@
1
+ // Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ import type { FunctionIdentity } from "./types.js";
4
+
5
+ const SUPPORTED_EXTENSION_FUNCTIONS = new Set(["duckdb.spatial/intersects_extent@1"]);
6
+
7
+ export function filterFunctionIdentityKey(identity: FunctionIdentity): string {
8
+ return `${identity.namespace}/${identity.name}@${identity.version}`;
9
+ }
10
+
11
+ export function supportsExtensionFilterFunction(identity: FunctionIdentity): boolean {
12
+ return SUPPORTED_EXTENSION_FUNCTIONS.has(filterFunctionIdentityKey(identity));
13
+ }