@visactor/vbi 0.4.17 → 0.4.19

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 (30) hide show
  1. package/dist/builder/adapters/index.d.ts +1 -0
  2. package/dist/builder/adapters/vquery-vseed/build-vquery.d.ts +3 -0
  3. package/dist/builder/adapters/vquery-vseed/build-vseed.d.ts +3 -0
  4. package/dist/builder/adapters/vquery-vseed/index.d.ts +7 -0
  5. package/dist/builder/adapters/vquery-vseed/types.d.ts +4 -0
  6. package/dist/builder/{vbi-builder.d.ts → builder.d.ts} +7 -7
  7. package/dist/builder/features/havingFilter/having-node-builder.d.ts +10 -1
  8. package/dist/builder/index.d.ts +2 -1
  9. package/dist/builder/modules/index.d.ts +0 -3
  10. package/dist/index.cjs +142 -60
  11. package/dist/index.d.ts +5 -2
  12. package/dist/index.js +131 -58
  13. package/dist/pipeline/vqueryDSL/aggregateMap.d.ts +30 -0
  14. package/dist/pipeline/vqueryDSL/index.d.ts +2 -3
  15. package/dist/pipeline/vqueryDSL/types.d.ts +2 -3
  16. package/dist/types/builder/VBIInterface.d.ts +4 -5
  17. package/dist/types/builder/adapter.d.ts +21 -0
  18. package/dist/types/builder/index.d.ts +1 -0
  19. package/dist/types/dsl/havingFilter/having.d.ts +19 -0
  20. package/dist/types/dsl/index.d.ts +1 -1
  21. package/dist/types/dsl/measures/aggregate.d.ts +14 -2
  22. package/dist/types/dsl/measures/measures.d.ts +26 -4
  23. package/dist/types/dsl/vbi/vbi.d.ts +13 -2
  24. package/dist/vbi/create-vbi.d.ts +15 -14
  25. package/dist/vbi/from/from-vbi-dsl-input.d.ts +3 -2
  26. package/dist/vbi.d.ts +1 -14
  27. package/package.json +5 -5
  28. package/dist/builder/modules/build-vquery.d.ts +0 -4
  29. package/dist/builder/modules/build-vseed.d.ts +0 -8
  30. package/dist/builder/modules/create-builder-features.d.ts +0 -14
@@ -0,0 +1 @@
1
+ export * from './vquery-vseed';
@@ -0,0 +1,3 @@
1
+ import type { VBIQueryBuilder } from '../../../types';
2
+ import type { DefaultVBIQueryDSL } from './types';
3
+ export declare const buildVQueryDSL: VBIQueryBuilder<DefaultVBIQueryDSL>;
@@ -0,0 +1,3 @@
1
+ import type { VBISeedBuilder } from '../../../types';
2
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from './types';
3
+ export declare const buildVSeedDSL: VBISeedBuilder<DefaultVBIQueryDSL, DefaultVBISeedDSL>;
@@ -0,0 +1,7 @@
1
+ import type { VBIBuilderAdapters } from '../../../types';
2
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from './types';
3
+ export type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from './types';
4
+ export { buildVQueryDSL } from './build-vquery';
5
+ export { buildVSeedDSL } from './build-vseed';
6
+ export declare const defaultVBIBuilderAdapters: VBIBuilderAdapters<DefaultVBIQueryDSL, DefaultVBISeedDSL>;
7
+ export declare const resolveVBIBuilderAdapters: <TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL>(adapters?: Partial<VBIBuilderAdapters<TQueryDSL, TSeedDSL>>) => VBIBuilderAdapters<TQueryDSL, TSeedDSL>;
@@ -0,0 +1,4 @@
1
+ import type { VSeedDSL } from '@visactor/vseed';
2
+ import type { VQueryDSL } from '@visactor/vquery';
3
+ export type DefaultVBIQueryDSL = VQueryDSL;
4
+ export type DefaultVBISeedDSL = VSeedDSL;
@@ -1,11 +1,11 @@
1
1
  import * as Y from 'yjs';
2
- import type { VSeedDSL } from '@visactor/vseed';
3
- import type { VQueryDSL } from '@visactor/vquery';
2
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from './adapters/vquery-vseed';
4
3
  import { DimensionsBuilder, MeasuresBuilder, HavingFilterBuilder, WhereFilterBuilder, ChartTypeBuilder, ThemeBuilder, LocaleBuilder, LimitBuilder, UndoManager } from './features';
5
- import type { VBIDSL, VBIBuilderInterface } from '../types';
6
- export declare class VBIBuilder implements VBIBuilderInterface {
4
+ import type { VBIDSL, VBIBuilderAdapters, VBIBuilderInterface, VBIBuilderOptions } from '../types';
5
+ export declare class VBIBuilder<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> implements VBIBuilderInterface<TQueryDSL, TSeedDSL> {
7
6
  doc: Y.Doc;
8
7
  dsl: Y.Map<any>;
8
+ adapters: VBIBuilderAdapters<TQueryDSL, TSeedDSL>;
9
9
  chartType: ChartTypeBuilder;
10
10
  measures: MeasuresBuilder;
11
11
  dimensions: DimensionsBuilder;
@@ -15,11 +15,11 @@ export declare class VBIBuilder implements VBIBuilderInterface {
15
15
  locale: LocaleBuilder;
16
16
  limit: LimitBuilder;
17
17
  undoManager: UndoManager;
18
- constructor(doc: Y.Doc);
18
+ constructor(doc: Y.Doc, options?: VBIBuilderOptions<TQueryDSL, TSeedDSL>);
19
19
  applyUpdate: (update: Uint8Array, transactionOrigin?: any) => void;
20
20
  encodeStateAsUpdate: (targetStateVector?: Uint8Array) => Uint8Array<ArrayBufferLike>;
21
- buildVSeed: () => Promise<VSeedDSL>;
22
- buildVQuery: () => VQueryDSL;
21
+ buildVSeed: () => Promise<TSeedDSL>;
22
+ buildVQuery: () => TQueryDSL;
23
23
  build: () => VBIDSL;
24
24
  isEmpty: () => boolean;
25
25
  getSchema: () => Promise<{
@@ -1,5 +1,5 @@
1
1
  import * as Y from 'yjs';
2
- import { VBIHavingFilter } from '../../../types';
2
+ import { VBIHavingFilter, VBIHavingAggregate } from '../../../types';
3
3
  /**
4
4
  * @description Having 过滤节点构建器,用于配置单个 Having 过滤条件
5
5
  */
@@ -18,6 +18,10 @@ export declare class HavingFilterNodeBuilder {
18
18
  * @description 获取过滤操作符
19
19
  */
20
20
  getOperator(): string | undefined;
21
+ /**
22
+ * @description 获取聚合配置
23
+ */
24
+ getAggregate(): VBIHavingAggregate | undefined;
21
25
  /**
22
26
  * @description 设置过滤条件的值
23
27
  * @param value - 过滤值
@@ -28,6 +32,11 @@ export declare class HavingFilterNodeBuilder {
28
32
  * @param operator - 操作符
29
33
  */
30
34
  setOperator(operator: string): this;
35
+ /**
36
+ * @description 设置聚合配置
37
+ * @param aggregate - 聚合配置
38
+ */
39
+ setAggregate(aggregate: VBIHavingAggregate): this;
31
40
  /**
32
41
  * @description 导出为 JSON
33
42
  */
@@ -1,3 +1,4 @@
1
- export { VBIBuilder } from './vbi-builder';
1
+ export { VBIBuilder } from './builder';
2
2
  export { VBI } from '../vbi';
3
+ export * from './adapters';
3
4
  export { MeasuresBuilder, DimensionsBuilder, ChartTypeBuilder, HavingFilterBuilder, WhereFilterBuilder, ThemeBuilder, LocaleBuilder, LimitBuilder, UndoManager, } from './features';
@@ -1,8 +1,5 @@
1
1
  export { applyUpdateToDoc } from './apply-update';
2
2
  export { encodeDocStateAsUpdate } from './encode-state-as-update';
3
3
  export { buildVBIDSL } from './build';
4
- export { buildVQueryDSL } from './build-vquery';
5
- export { buildVSeedDSL } from './build-vseed';
6
4
  export { isEmptyVBIDSL } from './is-empty';
7
5
  export { getBuilderSchema } from './get-schema';
8
- export { createBuilderFeatures } from './create-builder-features';
package/dist/index.cjs CHANGED
@@ -27,12 +27,15 @@ __webpack_require__.d(__webpack_exports__, {
27
27
  HavingFilterBuilder: ()=>HavingFilterBuilder,
28
28
  WhereFilterBuilder: ()=>WhereFilterBuilder,
29
29
  isVBIHavingGroup: ()=>isVBIHavingGroup,
30
+ resolveVBIBuilderAdapters: ()=>resolveVBIBuilderAdapters,
30
31
  VBIBuilder: ()=>VBIBuilder,
31
32
  VBI: ()=>VBI,
32
33
  isVBIHavingFilter: ()=>isVBIHavingFilter,
33
- findTreeNodesBy: ()=>vseed_namespaceObject.findTreeNodesBy,
34
34
  ThemeBuilder: ()=>ThemeBuilder,
35
+ findTreeNodesBy: ()=>vseed_namespaceObject.findTreeNodesBy,
35
36
  id: ()=>id_id,
37
+ createVBI: ()=>createVBI,
38
+ defaultVBIBuilderAdapters: ()=>defaultVBIBuilderAdapters,
36
39
  MeasuresBuilder: ()=>MeasuresBuilder,
37
40
  LimitBuilder: ()=>LimitBuilder,
38
41
  DimensionsBuilder: ()=>DimensionsBuilder,
@@ -55,12 +58,28 @@ const getConnector = async (id)=>{
55
58
  return connector;
56
59
  };
57
60
  const external_yjs_namespaceObject = require("yjs");
58
- const applyUpdateToDoc = (doc, update, transactionOrigin)=>{
59
- external_yjs_namespaceObject.applyUpdate(doc, update, transactionOrigin);
60
- };
61
- const encodeDocStateAsUpdate = (doc, targetStateVector)=>external_yjs_namespaceObject.encodeStateAsUpdate(doc, targetStateVector);
62
- const buildVBIDSL = (dsl)=>dsl.toJSON();
63
61
  const external_remeda_namespaceObject = require("remeda");
62
+ const VBI_TO_VQUERY_AGGR_FUNC_MAP = {
63
+ count: 'count',
64
+ countDistinct: 'count_distinct',
65
+ sum: 'sum',
66
+ avg: 'avg',
67
+ min: 'min',
68
+ max: 'max',
69
+ variance: 'variance',
70
+ variancePop: 'variance_pop',
71
+ stddev: 'stddev',
72
+ median: 'median',
73
+ quantile: 'quantile'
74
+ };
75
+ const mapAggregateForVQuery = (aggregate)=>{
76
+ if (!aggregate) return aggregate;
77
+ const mappedFunc = VBI_TO_VQUERY_AGGR_FUNC_MAP[aggregate.func] ?? aggregate.func;
78
+ return {
79
+ ...aggregate,
80
+ func: mappedFunc
81
+ };
82
+ };
64
83
  const buildSelect = (queryDSL, context)=>{
65
84
  const { vbiDSL } = context;
66
85
  const measures = vbiDSL.measures;
@@ -72,14 +91,17 @@ const buildSelect = (queryDSL, context)=>{
72
91
  const measureSelects = measureNodes.map((measure)=>({
73
92
  field: measure.field,
74
93
  alias: measure.alias,
75
- aggr: measure.aggregate
94
+ aggr: mapAggregateForVQuery(measure.aggregate)
76
95
  }));
77
96
  const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
78
97
  const dimensionSelects = dimensionNodes.map((dimension)=>({
79
98
  field: dimension.field,
80
99
  alias: dimension.alias
81
100
  }));
82
- result.select = measureSelects.concat(dimensionSelects);
101
+ result.select = [
102
+ ...measureSelects,
103
+ ...dimensionSelects
104
+ ];
83
105
  return result;
84
106
  };
85
107
  const buildGroupBy = (queryDSL, context)=>{
@@ -190,6 +212,9 @@ function handleSimpleFilter(filter) {
190
212
  }
191
213
  ];
192
214
  }
215
+ const DEFAULT_HAVING_AGGREGATE = {
216
+ func: 'sum'
217
+ };
193
218
  const buildHaving = (queryDSL, context)=>{
194
219
  const { vbiDSL } = context;
195
220
  const havingFilter = vbiDSL.havingFilter;
@@ -219,15 +244,25 @@ function buildHaving_mapGroupToCondition(group) {
219
244
  };
220
245
  }
221
246
  function buildHaving_mapFilterToCondition(filter) {
222
- const mappedOp = filter.op ?? '=';
247
+ const mappedOp = normalizeOperator(filter.op, filter.value);
248
+ const aggregate = mapAggregateForVQuery(filter.aggregate ?? DEFAULT_HAVING_AGGREGATE);
223
249
  return [
224
250
  {
225
251
  field: filter.field,
252
+ aggr: aggregate,
226
253
  op: mappedOp,
227
254
  value: filter.value
228
255
  }
229
256
  ];
230
257
  }
258
+ function normalizeOperator(op, value) {
259
+ let mappedOp = op ?? '=';
260
+ if (Array.isArray(value)) {
261
+ if ('=' === mappedOp) mappedOp = 'in';
262
+ if ('!=' === mappedOp) mappedOp = 'not in';
263
+ }
264
+ return mappedOp;
265
+ }
231
266
  const buildLimit = (queryDSL, context)=>{
232
267
  const result = {
233
268
  ...queryDSL
@@ -243,10 +278,7 @@ const buildVQuery = (vbiDSL, builder)=>{
243
278
  });
244
279
  return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
245
280
  };
246
- const buildVQueryDSL = (dsl, builder)=>{
247
- const vbiDSL = buildVBIDSL(dsl);
248
- return buildVQuery(vbiDSL, builder);
249
- };
281
+ const buildVQueryDSL = ({ vbiDSL, builder })=>buildVQuery(vbiDSL, builder);
250
282
  const buildVSeedDSL = async ({ vbiDSL, queryDSL })=>{
251
283
  const connectorId = vbiDSL.connectorId;
252
284
  const connector = await getConnector(connectorId);
@@ -263,21 +295,14 @@ const buildVSeedDSL = async ({ vbiDSL, queryDSL })=>{
263
295
  locale: vbiDSL.locale
264
296
  };
265
297
  };
266
- const getCollectionLength = (value)=>{
267
- if (value instanceof external_yjs_namespaceObject.Array) return value.length;
268
- if (Array.isArray(value)) return value.length;
269
- return 0;
270
- };
271
- const isEmptyVBIDSL = (dsl)=>{
272
- const dimensionsLength = getCollectionLength(dsl.get('dimensions'));
273
- const measuresLength = getCollectionLength(dsl.get('measures'));
274
- return 0 === dimensionsLength && 0 === measuresLength;
275
- };
276
- const getBuilderSchema = async (dsl)=>{
277
- const connectorId = dsl.get('connectorId');
278
- const connector = await getConnector(connectorId);
279
- return connector.discoverSchema();
298
+ const defaultVBIBuilderAdapters = {
299
+ buildVQuery: buildVQueryDSL,
300
+ buildVSeed: buildVSeedDSL
280
301
  };
302
+ const resolveVBIBuilderAdapters = (adapters)=>({
303
+ buildVQuery: adapters?.buildVQuery ?? defaultVBIBuilderAdapters.buildVQuery,
304
+ buildVSeed: adapters?.buildVSeed ?? defaultVBIBuilderAdapters.buildVSeed
305
+ });
281
306
  class MeasureNodeBuilder {
282
307
  yMap;
283
308
  constructor(yMap){
@@ -818,6 +843,9 @@ class HavingFilterNodeBuilder {
818
843
  getOperator() {
819
844
  return this.yMap.get('op');
820
845
  }
846
+ getAggregate() {
847
+ return this.yMap.get('aggregate');
848
+ }
821
849
  setValue(value) {
822
850
  this.yMap.set('value', value);
823
851
  return this;
@@ -826,6 +854,10 @@ class HavingFilterNodeBuilder {
826
854
  this.yMap.set('op', operator);
827
855
  return this;
828
856
  }
857
+ setAggregate(aggregate) {
858
+ this.yMap.set('aggregate', aggregate);
859
+ return this;
860
+ }
829
861
  toJSON() {
830
862
  return this.yMap.toJSON();
831
863
  }
@@ -852,6 +884,9 @@ class HavingGroupBuilder {
852
884
  const yMap = new external_yjs_namespaceObject.Map();
853
885
  yMap.set('id', id_id.uuid());
854
886
  yMap.set('field', field);
887
+ yMap.set('aggregate', {
888
+ func: 'sum'
889
+ });
855
890
  this.getConditions().push([
856
891
  yMap
857
892
  ]);
@@ -909,6 +944,9 @@ class HavingFilterBuilder {
909
944
  const yMap = new external_yjs_namespaceObject.Map();
910
945
  yMap.set('id', id_id.uuid());
911
946
  yMap.set('field', field);
947
+ yMap.set('aggregate', {
948
+ func: 'sum'
949
+ });
912
950
  this.getConditions().push([
913
951
  yMap
914
952
  ]);
@@ -1085,20 +1123,30 @@ class UndoManager {
1085
1123
  this.manager.clear(clearUndoStack, clearRedoStack);
1086
1124
  }
1087
1125
  }
1088
- const createBuilderFeatures = (doc, dsl)=>({
1089
- undoManager: new UndoManager(dsl),
1090
- chartType: new ChartTypeBuilder(doc, dsl),
1091
- measures: new MeasuresBuilder(doc, dsl),
1092
- dimensions: new DimensionsBuilder(doc, dsl),
1093
- havingFilter: new HavingFilterBuilder(doc, dsl),
1094
- whereFilter: new WhereFilterBuilder(doc, dsl),
1095
- theme: new ThemeBuilder(doc, dsl),
1096
- locale: new LocaleBuilder(doc, dsl),
1097
- limit: new LimitBuilder(doc, dsl)
1098
- });
1126
+ const applyUpdateToDoc = (doc, update, transactionOrigin)=>{
1127
+ external_yjs_namespaceObject.applyUpdate(doc, update, transactionOrigin);
1128
+ };
1129
+ const encodeDocStateAsUpdate = (doc, targetStateVector)=>external_yjs_namespaceObject.encodeStateAsUpdate(doc, targetStateVector);
1130
+ const buildVBIDSL = (dsl)=>dsl.toJSON();
1131
+ const getCollectionLength = (value)=>{
1132
+ if (value instanceof external_yjs_namespaceObject.Array) return value.length;
1133
+ if (Array.isArray(value)) return value.length;
1134
+ return 0;
1135
+ };
1136
+ const isEmptyVBIDSL = (dsl)=>{
1137
+ const dimensionsLength = getCollectionLength(dsl.get('dimensions'));
1138
+ const measuresLength = getCollectionLength(dsl.get('measures'));
1139
+ return 0 === dimensionsLength && 0 === measuresLength;
1140
+ };
1141
+ const getBuilderSchema = async (dsl)=>{
1142
+ const connectorId = dsl.get('connectorId');
1143
+ const connector = await getConnector(connectorId);
1144
+ return connector.discoverSchema();
1145
+ };
1099
1146
  class VBIBuilder {
1100
1147
  doc;
1101
1148
  dsl;
1149
+ adapters;
1102
1150
  chartType;
1103
1151
  measures;
1104
1152
  dimensions;
@@ -1108,31 +1156,44 @@ class VBIBuilder {
1108
1156
  locale;
1109
1157
  limit;
1110
1158
  undoManager;
1111
- constructor(doc){
1159
+ constructor(doc, options){
1112
1160
  this.doc = doc;
1113
1161
  this.dsl = doc.getMap('dsl');
1114
- const features = createBuilderFeatures(doc, this.dsl);
1115
- this.undoManager = features.undoManager;
1116
- this.chartType = features.chartType;
1117
- this.measures = features.measures;
1118
- this.dimensions = features.dimensions;
1119
- this.havingFilter = features.havingFilter;
1120
- this.whereFilter = features.whereFilter;
1121
- this.theme = features.theme;
1122
- this.locale = features.locale;
1123
- this.limit = features.limit;
1162
+ this.adapters = resolveVBIBuilderAdapters(options?.adapters);
1163
+ this.undoManager = new UndoManager(this.dsl);
1164
+ this.chartType = new ChartTypeBuilder(doc, this.dsl);
1165
+ this.measures = new MeasuresBuilder(doc, this.dsl);
1166
+ this.dimensions = new DimensionsBuilder(doc, this.dsl);
1167
+ this.havingFilter = new HavingFilterBuilder(doc, this.dsl);
1168
+ this.whereFilter = new WhereFilterBuilder(doc, this.dsl);
1169
+ this.theme = new ThemeBuilder(doc, this.dsl);
1170
+ this.locale = new LocaleBuilder(doc, this.dsl);
1171
+ this.limit = new LimitBuilder(doc, this.dsl);
1124
1172
  }
1125
1173
  applyUpdate = (update, transactionOrigin)=>applyUpdateToDoc(this.doc, update, transactionOrigin);
1126
1174
  encodeStateAsUpdate = (targetStateVector)=>encodeDocStateAsUpdate(this.doc, targetStateVector);
1127
1175
  buildVSeed = async ()=>{
1128
1176
  const vbiDSL = this.build();
1129
- const queryDSL = this.buildVQuery();
1130
- return buildVSeedDSL({
1177
+ const queryDSL = this.adapters.buildVQuery({
1178
+ dsl: this.dsl,
1131
1179
  vbiDSL,
1132
- queryDSL
1180
+ builder: this
1181
+ });
1182
+ return this.adapters.buildVSeed({
1183
+ dsl: this.dsl,
1184
+ vbiDSL,
1185
+ queryDSL,
1186
+ builder: this
1187
+ });
1188
+ };
1189
+ buildVQuery = ()=>{
1190
+ const vbiDSL = this.build();
1191
+ return this.adapters.buildVQuery({
1192
+ dsl: this.dsl,
1193
+ vbiDSL,
1194
+ builder: this
1133
1195
  });
1134
1196
  };
1135
- buildVQuery = ()=>buildVQueryDSL(this.dsl, this);
1136
1197
  build = ()=>buildVBIDSL(this.dsl);
1137
1198
  isEmpty = ()=>isEmptyVBIDSL(this.dsl);
1138
1199
  getSchema = async ()=>getBuilderSchema(this.dsl);
@@ -1243,7 +1304,7 @@ const setBaseDSLFields = (dsl, vbi)=>{
1243
1304
  if (vbi.locale) dsl.set('locale', vbi.locale);
1244
1305
  if (void 0 !== vbi.version) dsl.set('version', vbi.version);
1245
1306
  };
1246
- const fromVBIDSLInput = (vbi)=>{
1307
+ const fromVBIDSLInput = (vbi, options)=>{
1247
1308
  const doc = new external_yjs_namespaceObject.Doc();
1248
1309
  const dsl = doc.getMap('dsl');
1249
1310
  doc.transact(()=>{
@@ -1253,7 +1314,7 @@ const fromVBIDSLInput = (vbi)=>{
1253
1314
  dsl.set('measures', ensureYArray(vbi.measures, 'field'));
1254
1315
  dsl.set('dimensions', ensureYArray(vbi.dimensions, 'field'));
1255
1316
  });
1256
- return new VBIBuilder(doc);
1317
+ return new VBIBuilder(doc, options);
1257
1318
  };
1258
1319
  const generateEmptyDSL = (connectorId)=>({
1259
1320
  connectorId,
@@ -1274,14 +1335,29 @@ const generateEmptyDSL = (connectorId)=>({
1274
1335
  locale: 'zh-CN',
1275
1336
  version: 0
1276
1337
  });
1277
- const createVBI = ()=>({
1338
+ const mergeBuilderOptions = (base, overrides)=>{
1339
+ if (!base) return overrides;
1340
+ if (!overrides) return base;
1341
+ return {
1342
+ ...base,
1343
+ ...overrides,
1344
+ adapters: {
1345
+ ...base.adapters,
1346
+ ...overrides.adapters
1347
+ }
1348
+ };
1349
+ };
1350
+ function createVBI(defaultBuilderOptions) {
1351
+ const from = (vbi, builderOptions)=>fromVBIDSLInput(vbi, mergeBuilderOptions(defaultBuilderOptions, builderOptions));
1352
+ return {
1278
1353
  connectorMap: connectorMap,
1279
1354
  registerConnector: registerConnector,
1280
1355
  getConnector: getConnector,
1281
1356
  generateEmptyDSL: generateEmptyDSL,
1282
- from: fromVBIDSLInput,
1283
- create: fromVBIDSLInput
1284
- });
1357
+ from,
1358
+ create: from
1359
+ };
1360
+ }
1285
1361
  const VBI = createVBI();
1286
1362
  exports.ChartTypeBuilder = __webpack_exports__.ChartTypeBuilder;
1287
1363
  exports.DimensionsBuilder = __webpack_exports__.DimensionsBuilder;
@@ -1295,6 +1371,8 @@ exports.VBI = __webpack_exports__.VBI;
1295
1371
  exports.VBIBuilder = __webpack_exports__.VBIBuilder;
1296
1372
  exports.WhereFilterBuilder = __webpack_exports__.WhereFilterBuilder;
1297
1373
  exports.buildVQuery = __webpack_exports__.buildVQuery;
1374
+ exports.createVBI = __webpack_exports__.createVBI;
1375
+ exports.defaultVBIBuilderAdapters = __webpack_exports__.defaultVBIBuilderAdapters;
1298
1376
  exports.findTreeNodesBy = __webpack_exports__.findTreeNodesBy;
1299
1377
  exports.id = __webpack_exports__.id;
1300
1378
  exports.isVBIFilter = __webpack_exports__.isVBIFilter;
@@ -1302,6 +1380,7 @@ exports.isVBIHavingFilter = __webpack_exports__.isVBIHavingFilter;
1302
1380
  exports.isVBIHavingGroup = __webpack_exports__.isVBIHavingGroup;
1303
1381
  exports.isVBIWhereGroup = __webpack_exports__.isVBIWhereGroup;
1304
1382
  exports.preorderTraverse = __webpack_exports__.preorderTraverse;
1383
+ exports.resolveVBIBuilderAdapters = __webpack_exports__.resolveVBIBuilderAdapters;
1305
1384
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1306
1385
  "ChartTypeBuilder",
1307
1386
  "DimensionsBuilder",
@@ -1315,13 +1394,16 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1315
1394
  "VBIBuilder",
1316
1395
  "WhereFilterBuilder",
1317
1396
  "buildVQuery",
1397
+ "createVBI",
1398
+ "defaultVBIBuilderAdapters",
1318
1399
  "findTreeNodesBy",
1319
1400
  "id",
1320
1401
  "isVBIFilter",
1321
1402
  "isVBIHavingFilter",
1322
1403
  "isVBIHavingGroup",
1323
1404
  "isVBIWhereGroup",
1324
- "preorderTraverse"
1405
+ "preorderTraverse",
1406
+ "resolveVBIBuilderAdapters"
1325
1407
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
1326
1408
  Object.defineProperty(exports, '__esModule', {
1327
1409
  value: true
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export { VBI } from './vbi';
2
+ export { createVBI } from './vbi/create-vbi';
3
+ export type { VBIInstance } from './vbi/create-vbi';
2
4
  export { VBIBuilder } from './builder';
5
+ export { defaultVBIBuilderAdapters, resolveVBIBuilderAdapters } from './builder/adapters';
3
6
  export { MeasuresBuilder, DimensionsBuilder, ChartTypeBuilder, WhereFilterBuilder, HavingFilterBuilder, ThemeBuilder, LocaleBuilder, LimitBuilder, UndoManager, } from './builder';
4
7
  export * from './types';
5
- export * from './utils';
6
- export * from './pipeline';
8
+ export { id, isVBIFilter, isVBIHavingFilter, isVBIHavingGroup, isVBIWhereGroup, preorderTraverse, findTreeNodesBy, } from './utils';
9
+ export { buildVQuery } from './pipeline';
package/dist/index.js CHANGED
@@ -12,11 +12,27 @@ const getConnector = async (id)=>{
12
12
  if ('function' == typeof connector) return connector();
13
13
  return connector;
14
14
  };
15
- const applyUpdateToDoc = (doc, update, transactionOrigin)=>{
16
- applyUpdate(doc, update, transactionOrigin);
15
+ const VBI_TO_VQUERY_AGGR_FUNC_MAP = {
16
+ count: 'count',
17
+ countDistinct: 'count_distinct',
18
+ sum: 'sum',
19
+ avg: 'avg',
20
+ min: 'min',
21
+ max: 'max',
22
+ variance: 'variance',
23
+ variancePop: 'variance_pop',
24
+ stddev: 'stddev',
25
+ median: 'median',
26
+ quantile: 'quantile'
27
+ };
28
+ const mapAggregateForVQuery = (aggregate)=>{
29
+ if (!aggregate) return aggregate;
30
+ const mappedFunc = VBI_TO_VQUERY_AGGR_FUNC_MAP[aggregate.func] ?? aggregate.func;
31
+ return {
32
+ ...aggregate,
33
+ func: mappedFunc
34
+ };
17
35
  };
18
- const encodeDocStateAsUpdate = (doc, targetStateVector)=>encodeStateAsUpdate(doc, targetStateVector);
19
- const buildVBIDSL = (dsl)=>dsl.toJSON();
20
36
  const buildSelect = (queryDSL, context)=>{
21
37
  const { vbiDSL } = context;
22
38
  const measures = vbiDSL.measures;
@@ -28,14 +44,17 @@ const buildSelect = (queryDSL, context)=>{
28
44
  const measureSelects = measureNodes.map((measure)=>({
29
45
  field: measure.field,
30
46
  alias: measure.alias,
31
- aggr: measure.aggregate
47
+ aggr: mapAggregateForVQuery(measure.aggregate)
32
48
  }));
33
49
  const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
34
50
  const dimensionSelects = dimensionNodes.map((dimension)=>({
35
51
  field: dimension.field,
36
52
  alias: dimension.alias
37
53
  }));
38
- result.select = measureSelects.concat(dimensionSelects);
54
+ result.select = [
55
+ ...measureSelects,
56
+ ...dimensionSelects
57
+ ];
39
58
  return result;
40
59
  };
41
60
  const buildGroupBy = (queryDSL, context)=>{
@@ -146,6 +165,9 @@ function handleSimpleFilter(filter) {
146
165
  }
147
166
  ];
148
167
  }
168
+ const DEFAULT_HAVING_AGGREGATE = {
169
+ func: 'sum'
170
+ };
149
171
  const buildHaving = (queryDSL, context)=>{
150
172
  const { vbiDSL } = context;
151
173
  const havingFilter = vbiDSL.havingFilter;
@@ -175,15 +197,25 @@ function buildHaving_mapGroupToCondition(group) {
175
197
  };
176
198
  }
177
199
  function buildHaving_mapFilterToCondition(filter) {
178
- const mappedOp = filter.op ?? '=';
200
+ const mappedOp = normalizeOperator(filter.op, filter.value);
201
+ const aggregate = mapAggregateForVQuery(filter.aggregate ?? DEFAULT_HAVING_AGGREGATE);
179
202
  return [
180
203
  {
181
204
  field: filter.field,
205
+ aggr: aggregate,
182
206
  op: mappedOp,
183
207
  value: filter.value
184
208
  }
185
209
  ];
186
210
  }
211
+ function normalizeOperator(op, value) {
212
+ let mappedOp = op ?? '=';
213
+ if (Array.isArray(value)) {
214
+ if ('=' === mappedOp) mappedOp = 'in';
215
+ if ('!=' === mappedOp) mappedOp = 'not in';
216
+ }
217
+ return mappedOp;
218
+ }
187
219
  const buildLimit = (queryDSL, context)=>{
188
220
  const result = {
189
221
  ...queryDSL
@@ -199,10 +231,7 @@ const buildVQuery = (vbiDSL, builder)=>{
199
231
  });
200
232
  return pipe({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
201
233
  };
202
- const buildVQueryDSL = (dsl, builder)=>{
203
- const vbiDSL = buildVBIDSL(dsl);
204
- return buildVQuery(vbiDSL, builder);
205
- };
234
+ const buildVQueryDSL = ({ vbiDSL, builder })=>buildVQuery(vbiDSL, builder);
206
235
  const buildVSeedDSL = async ({ vbiDSL, queryDSL })=>{
207
236
  const connectorId = vbiDSL.connectorId;
208
237
  const connector = await getConnector(connectorId);
@@ -219,21 +248,14 @@ const buildVSeedDSL = async ({ vbiDSL, queryDSL })=>{
219
248
  locale: vbiDSL.locale
220
249
  };
221
250
  };
222
- const getCollectionLength = (value)=>{
223
- if (value instanceof external_yjs_Array) return value.length;
224
- if (Array.isArray(value)) return value.length;
225
- return 0;
226
- };
227
- const isEmptyVBIDSL = (dsl)=>{
228
- const dimensionsLength = getCollectionLength(dsl.get('dimensions'));
229
- const measuresLength = getCollectionLength(dsl.get('measures'));
230
- return 0 === dimensionsLength && 0 === measuresLength;
231
- };
232
- const getBuilderSchema = async (dsl)=>{
233
- const connectorId = dsl.get('connectorId');
234
- const connector = await getConnector(connectorId);
235
- return connector.discoverSchema();
251
+ const defaultVBIBuilderAdapters = {
252
+ buildVQuery: buildVQueryDSL,
253
+ buildVSeed: buildVSeedDSL
236
254
  };
255
+ const resolveVBIBuilderAdapters = (adapters)=>({
256
+ buildVQuery: adapters?.buildVQuery ?? defaultVBIBuilderAdapters.buildVQuery,
257
+ buildVSeed: adapters?.buildVSeed ?? defaultVBIBuilderAdapters.buildVSeed
258
+ });
237
259
  class MeasureNodeBuilder {
238
260
  yMap;
239
261
  constructor(yMap){
@@ -772,6 +794,9 @@ class HavingFilterNodeBuilder {
772
794
  getOperator() {
773
795
  return this.yMap.get('op');
774
796
  }
797
+ getAggregate() {
798
+ return this.yMap.get('aggregate');
799
+ }
775
800
  setValue(value) {
776
801
  this.yMap.set('value', value);
777
802
  return this;
@@ -780,6 +805,10 @@ class HavingFilterNodeBuilder {
780
805
  this.yMap.set('op', operator);
781
806
  return this;
782
807
  }
808
+ setAggregate(aggregate) {
809
+ this.yMap.set('aggregate', aggregate);
810
+ return this;
811
+ }
783
812
  toJSON() {
784
813
  return this.yMap.toJSON();
785
814
  }
@@ -806,6 +835,9 @@ class HavingGroupBuilder {
806
835
  const yMap = new external_yjs_Map();
807
836
  yMap.set('id', id_id.uuid());
808
837
  yMap.set('field', field);
838
+ yMap.set('aggregate', {
839
+ func: 'sum'
840
+ });
809
841
  this.getConditions().push([
810
842
  yMap
811
843
  ]);
@@ -863,6 +895,9 @@ class HavingFilterBuilder {
863
895
  const yMap = new external_yjs_Map();
864
896
  yMap.set('id', id_id.uuid());
865
897
  yMap.set('field', field);
898
+ yMap.set('aggregate', {
899
+ func: 'sum'
900
+ });
866
901
  this.getConditions().push([
867
902
  yMap
868
903
  ]);
@@ -1039,20 +1074,30 @@ class undo_manager_UndoManager {
1039
1074
  this.manager.clear(clearUndoStack, clearRedoStack);
1040
1075
  }
1041
1076
  }
1042
- const createBuilderFeatures = (doc, dsl)=>({
1043
- undoManager: new undo_manager_UndoManager(dsl),
1044
- chartType: new ChartTypeBuilder(doc, dsl),
1045
- measures: new MeasuresBuilder(doc, dsl),
1046
- dimensions: new DimensionsBuilder(doc, dsl),
1047
- havingFilter: new HavingFilterBuilder(doc, dsl),
1048
- whereFilter: new WhereFilterBuilder(doc, dsl),
1049
- theme: new ThemeBuilder(doc, dsl),
1050
- locale: new LocaleBuilder(doc, dsl),
1051
- limit: new LimitBuilder(doc, dsl)
1052
- });
1077
+ const applyUpdateToDoc = (doc, update, transactionOrigin)=>{
1078
+ applyUpdate(doc, update, transactionOrigin);
1079
+ };
1080
+ const encodeDocStateAsUpdate = (doc, targetStateVector)=>encodeStateAsUpdate(doc, targetStateVector);
1081
+ const buildVBIDSL = (dsl)=>dsl.toJSON();
1082
+ const getCollectionLength = (value)=>{
1083
+ if (value instanceof external_yjs_Array) return value.length;
1084
+ if (Array.isArray(value)) return value.length;
1085
+ return 0;
1086
+ };
1087
+ const isEmptyVBIDSL = (dsl)=>{
1088
+ const dimensionsLength = getCollectionLength(dsl.get('dimensions'));
1089
+ const measuresLength = getCollectionLength(dsl.get('measures'));
1090
+ return 0 === dimensionsLength && 0 === measuresLength;
1091
+ };
1092
+ const getBuilderSchema = async (dsl)=>{
1093
+ const connectorId = dsl.get('connectorId');
1094
+ const connector = await getConnector(connectorId);
1095
+ return connector.discoverSchema();
1096
+ };
1053
1097
  class VBIBuilder {
1054
1098
  doc;
1055
1099
  dsl;
1100
+ adapters;
1056
1101
  chartType;
1057
1102
  measures;
1058
1103
  dimensions;
@@ -1062,31 +1107,44 @@ class VBIBuilder {
1062
1107
  locale;
1063
1108
  limit;
1064
1109
  undoManager;
1065
- constructor(doc){
1110
+ constructor(doc, options){
1066
1111
  this.doc = doc;
1067
1112
  this.dsl = doc.getMap('dsl');
1068
- const features = createBuilderFeatures(doc, this.dsl);
1069
- this.undoManager = features.undoManager;
1070
- this.chartType = features.chartType;
1071
- this.measures = features.measures;
1072
- this.dimensions = features.dimensions;
1073
- this.havingFilter = features.havingFilter;
1074
- this.whereFilter = features.whereFilter;
1075
- this.theme = features.theme;
1076
- this.locale = features.locale;
1077
- this.limit = features.limit;
1113
+ this.adapters = resolveVBIBuilderAdapters(options?.adapters);
1114
+ this.undoManager = new undo_manager_UndoManager(this.dsl);
1115
+ this.chartType = new ChartTypeBuilder(doc, this.dsl);
1116
+ this.measures = new MeasuresBuilder(doc, this.dsl);
1117
+ this.dimensions = new DimensionsBuilder(doc, this.dsl);
1118
+ this.havingFilter = new HavingFilterBuilder(doc, this.dsl);
1119
+ this.whereFilter = new WhereFilterBuilder(doc, this.dsl);
1120
+ this.theme = new ThemeBuilder(doc, this.dsl);
1121
+ this.locale = new LocaleBuilder(doc, this.dsl);
1122
+ this.limit = new LimitBuilder(doc, this.dsl);
1078
1123
  }
1079
1124
  applyUpdate = (update, transactionOrigin)=>applyUpdateToDoc(this.doc, update, transactionOrigin);
1080
1125
  encodeStateAsUpdate = (targetStateVector)=>encodeDocStateAsUpdate(this.doc, targetStateVector);
1081
1126
  buildVSeed = async ()=>{
1082
1127
  const vbiDSL = this.build();
1083
- const queryDSL = this.buildVQuery();
1084
- return buildVSeedDSL({
1128
+ const queryDSL = this.adapters.buildVQuery({
1129
+ dsl: this.dsl,
1130
+ vbiDSL,
1131
+ builder: this
1132
+ });
1133
+ return this.adapters.buildVSeed({
1134
+ dsl: this.dsl,
1135
+ vbiDSL,
1136
+ queryDSL,
1137
+ builder: this
1138
+ });
1139
+ };
1140
+ buildVQuery = ()=>{
1141
+ const vbiDSL = this.build();
1142
+ return this.adapters.buildVQuery({
1143
+ dsl: this.dsl,
1085
1144
  vbiDSL,
1086
- queryDSL
1145
+ builder: this
1087
1146
  });
1088
1147
  };
1089
- buildVQuery = ()=>buildVQueryDSL(this.dsl, this);
1090
1148
  build = ()=>buildVBIDSL(this.dsl);
1091
1149
  isEmpty = ()=>isEmptyVBIDSL(this.dsl);
1092
1150
  getSchema = async ()=>getBuilderSchema(this.dsl);
@@ -1197,7 +1255,7 @@ const setBaseDSLFields = (dsl, vbi)=>{
1197
1255
  if (vbi.locale) dsl.set('locale', vbi.locale);
1198
1256
  if (void 0 !== vbi.version) dsl.set('version', vbi.version);
1199
1257
  };
1200
- const fromVBIDSLInput = (vbi)=>{
1258
+ const fromVBIDSLInput = (vbi, options)=>{
1201
1259
  const doc = new Doc();
1202
1260
  const dsl = doc.getMap('dsl');
1203
1261
  doc.transact(()=>{
@@ -1207,7 +1265,7 @@ const fromVBIDSLInput = (vbi)=>{
1207
1265
  dsl.set('measures', ensureYArray(vbi.measures, 'field'));
1208
1266
  dsl.set('dimensions', ensureYArray(vbi.dimensions, 'field'));
1209
1267
  });
1210
- return new VBIBuilder(doc);
1268
+ return new VBIBuilder(doc, options);
1211
1269
  };
1212
1270
  const generateEmptyDSL = (connectorId)=>({
1213
1271
  connectorId,
@@ -1228,13 +1286,28 @@ const generateEmptyDSL = (connectorId)=>({
1228
1286
  locale: 'zh-CN',
1229
1287
  version: 0
1230
1288
  });
1231
- const createVBI = ()=>({
1289
+ const mergeBuilderOptions = (base, overrides)=>{
1290
+ if (!base) return overrides;
1291
+ if (!overrides) return base;
1292
+ return {
1293
+ ...base,
1294
+ ...overrides,
1295
+ adapters: {
1296
+ ...base.adapters,
1297
+ ...overrides.adapters
1298
+ }
1299
+ };
1300
+ };
1301
+ function createVBI(defaultBuilderOptions) {
1302
+ const from = (vbi, builderOptions)=>fromVBIDSLInput(vbi, mergeBuilderOptions(defaultBuilderOptions, builderOptions));
1303
+ return {
1232
1304
  connectorMap: connectorMap,
1233
1305
  registerConnector: registerConnector,
1234
1306
  getConnector: getConnector,
1235
1307
  generateEmptyDSL: generateEmptyDSL,
1236
- from: fromVBIDSLInput,
1237
- create: fromVBIDSLInput
1238
- });
1308
+ from,
1309
+ create: from
1310
+ };
1311
+ }
1239
1312
  const VBI = createVBI();
1240
- export { ChartTypeBuilder, DimensionsBuilder, HavingFilterBuilder, LimitBuilder, LocaleBuilder, MeasuresBuilder, ThemeBuilder, undo_manager_UndoManager as UndoManager, VBI, VBIBuilder, WhereFilterBuilder, buildVQuery, findTreeNodesBy, id_id as id, isVBIFilter, isVBIHavingFilter, isVBIHavingGroup, isVBIWhereGroup, preorderTraverse };
1313
+ export { ChartTypeBuilder, DimensionsBuilder, HavingFilterBuilder, LimitBuilder, LocaleBuilder, MeasuresBuilder, ThemeBuilder, undo_manager_UndoManager as UndoManager, VBI, VBIBuilder, WhereFilterBuilder, buildVQuery, createVBI, defaultVBIBuilderAdapters, findTreeNodesBy, id_id as id, isVBIFilter, isVBIHavingFilter, isVBIHavingGroup, isVBIWhereGroup, preorderTraverse, resolveVBIBuilderAdapters };
@@ -0,0 +1,30 @@
1
+ export type VQueryAggregateFunc = 'count' | 'count_distinct' | 'sum' | 'avg' | 'min' | 'max' | 'variance' | 'variance_pop' | 'stddev' | 'median' | 'quantile';
2
+ export type VQueryAggregate = {
3
+ func: VQueryAggregateFunc;
4
+ quantile?: number;
5
+ };
6
+ export type VBIAggregateInput = {
7
+ func: 'count';
8
+ } | {
9
+ func: 'countDistinct';
10
+ } | {
11
+ func: 'sum';
12
+ } | {
13
+ func: 'avg';
14
+ } | {
15
+ func: 'min';
16
+ } | {
17
+ func: 'max';
18
+ } | {
19
+ func: 'variance';
20
+ } | {
21
+ func: 'variancePop';
22
+ } | {
23
+ func: 'stddev';
24
+ } | {
25
+ func: 'median';
26
+ } | {
27
+ func: 'quantile';
28
+ quantile?: number;
29
+ };
30
+ export declare const mapAggregateForVQuery: (aggregate: VBIAggregateInput | undefined) => VQueryAggregate | undefined;
@@ -1,4 +1,3 @@
1
1
  import type { VQueryDSL } from '@visactor/vquery';
2
- import type { VBIDSL } from '../../types';
3
- import type { VBIBuilder } from '../../builder';
4
- export declare const buildVQuery: (vbiDSL: VBIDSL, builder: VBIBuilder) => VQueryDSL;
2
+ import type { VBIBuilderInterface, VBIDSL } from '../../types';
3
+ export declare const buildVQuery: (vbiDSL: VBIDSL, builder: VBIBuilderInterface<any, any>) => VQueryDSL;
@@ -1,7 +1,6 @@
1
1
  import type { VQueryDSL } from '@visactor/vquery';
2
- import type { VBIDSL } from '../../types';
3
- import type { VBIBuilder } from '../../builder';
2
+ import type { VBIBuilderInterface, VBIDSL } from '../../types';
4
3
  export type buildPipe = (queryDSL: VQueryDSL, context: {
5
4
  vbiDSL: VBIDSL;
6
- builder: VBIBuilder;
5
+ builder: VBIBuilderInterface<any, any>;
7
6
  }) => VQueryDSL;
@@ -1,9 +1,8 @@
1
- import type { VQueryDSL } from '@visactor/vquery';
1
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from '../../builder/adapters/vquery-vseed/types';
2
2
  import type { VBIDSL } from '../dsl';
3
- import type { VSeedDSL } from '@visactor/vseed';
4
3
  import type { MeasuresBuilder, DimensionsBuilder, ChartTypeBuilder, HavingFilterBuilder, WhereFilterBuilder, ThemeBuilder, LocaleBuilder, LimitBuilder, UndoManager } from '../../builder/features';
5
4
  import type { Map, Doc } from 'yjs';
6
- export interface VBIBuilderInterface {
5
+ export interface VBIBuilderInterface<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> {
7
6
  doc: Doc;
8
7
  dsl: Map<any>;
9
8
  undoManager: UndoManager;
@@ -17,8 +16,8 @@ export interface VBIBuilderInterface {
17
16
  limit: LimitBuilder;
18
17
  applyUpdate: (update: Uint8Array, origin?: any) => void;
19
18
  encodeStateAsUpdate: (targetStateVector?: Uint8Array) => Uint8Array;
20
- buildVSeed: () => Promise<VSeedDSL>;
21
- buildVQuery: () => VQueryDSL;
19
+ buildVSeed: () => Promise<TSeedDSL>;
20
+ buildVQuery: () => TQueryDSL;
22
21
  build: () => VBIDSL;
23
22
  isEmpty: () => boolean;
24
23
  }
@@ -0,0 +1,21 @@
1
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from '../../builder/adapters/vquery-vseed/types';
2
+ import type { Map } from 'yjs';
3
+ import type { VBIDSL } from '../dsl';
4
+ import type { VBIBuilderInterface } from './VBIInterface';
5
+ export interface VBIBuildVQueryContext<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> {
6
+ dsl: Map<any>;
7
+ vbiDSL: VBIDSL;
8
+ builder: VBIBuilderInterface<TQueryDSL, TSeedDSL>;
9
+ }
10
+ export interface VBIBuildVSeedContext<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> extends VBIBuildVQueryContext<TQueryDSL, TSeedDSL> {
11
+ queryDSL: TQueryDSL;
12
+ }
13
+ export type VBIQueryBuilder<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> = (context: VBIBuildVQueryContext<TQueryDSL, TSeedDSL>) => TQueryDSL;
14
+ export type VBISeedBuilder<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> = (context: VBIBuildVSeedContext<TQueryDSL, TSeedDSL>) => Promise<TSeedDSL> | TSeedDSL;
15
+ export interface VBIBuilderAdapters<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> {
16
+ buildVQuery: VBIQueryBuilder<TQueryDSL, TSeedDSL>;
17
+ buildVSeed: VBISeedBuilder<TQueryDSL, TSeedDSL>;
18
+ }
19
+ export interface VBIBuilderOptions<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> {
20
+ adapters?: Partial<VBIBuilderAdapters<TQueryDSL, TSeedDSL>>;
21
+ }
@@ -1,2 +1,3 @@
1
1
  export type { VBIBuilderInterface } from './VBIInterface';
2
+ export type { VBIBuildVQueryContext, VBIBuildVSeedContext, VBIQueryBuilder, VBISeedBuilder, VBIBuilderAdapters, VBIBuilderOptions, } from './adapter';
2
3
  export type { ObserveCallback } from './observe';
@@ -1,11 +1,30 @@
1
1
  import { z } from 'zod';
2
+ import { zAggregate } from '../measures/aggregate';
2
3
  declare const zHavingLogicalOperator: z.ZodEnum<{
3
4
  and: "and";
4
5
  or: "or";
5
6
  }>;
7
+ export type VBIHavingAggregate = z.infer<typeof zAggregate>;
6
8
  export declare const zVBIHavingFilter: z.ZodObject<{
7
9
  id: z.ZodString;
8
10
  field: z.ZodString;
11
+ aggregate: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
12
+ func: z.ZodEnum<{
13
+ count: "count";
14
+ countDistinct: "countDistinct";
15
+ sum: "sum";
16
+ avg: "avg";
17
+ min: "min";
18
+ max: "max";
19
+ variance: "variance";
20
+ variancePop: "variancePop";
21
+ stddev: "stddev";
22
+ median: "median";
23
+ }>;
24
+ }, z.core.$strip>, z.ZodObject<{
25
+ func: z.ZodLiteral<"quantile">;
26
+ quantile: z.ZodOptional<z.ZodNumber>;
27
+ }, z.core.$strip>], "func">>;
9
28
  op: z.ZodOptional<z.ZodString>;
10
29
  value: z.ZodOptional<z.ZodAny>;
11
30
  }, z.core.$strip>;
@@ -1,7 +1,7 @@
1
1
  export type { VBIDimensionTree, VBIDimensionGroup, VBIDimension } from './dimensions/dimensions';
2
2
  export type { VBIMeasureTree, VBIMeasureGroup, VBIMeasure } from './measures/measures';
3
3
  export type { VBIFilter, VBIWhereGroup, VBIWhereClause } from './whereFilter/filters';
4
- export type { VBIHavingFilter, VBIHavingGroup, VBIHavingClause } from './havingFilter/having';
4
+ export type { VBIHavingFilter, VBIHavingGroup, VBIHavingClause, VBIHavingAggregate } from './havingFilter/having';
5
5
  export type { VBIDSLTheme } from './theme/theme';
6
6
  export type { VBIDSLLocale } from './locale/locale';
7
7
  export type { VBIDSL, VBIDSLInput } from './vbi/vbi';
@@ -1,7 +1,19 @@
1
1
  import { z } from 'zod';
2
+ export declare const VBI_MEASURE_SIMPLE_AGGREGATE_FUNCS: readonly ["count", "countDistinct", "sum", "avg", "min", "max", "variance", "variancePop", "stddev", "median"];
2
3
  export declare const zAggregate: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
- func: z.ZodLiteral<"sum" | "count" | "avg" | "min" | "max">;
4
+ func: z.ZodEnum<{
5
+ count: "count";
6
+ countDistinct: "countDistinct";
7
+ sum: "sum";
8
+ avg: "avg";
9
+ min: "min";
10
+ max: "max";
11
+ variance: "variance";
12
+ variancePop: "variancePop";
13
+ stddev: "stddev";
14
+ median: "median";
15
+ }>;
4
16
  }, z.core.$strip>, z.ZodObject<{
5
17
  func: z.ZodLiteral<"quantile">;
6
- quantile: z.ZodNumber;
18
+ quantile: z.ZodOptional<z.ZodNumber>;
7
19
  }, z.core.$strip>], "func">;
@@ -12,10 +12,21 @@ export declare const zVBIMeasure: z.ZodObject<{
12
12
  size: "size";
13
13
  }>;
14
14
  aggregate: z.ZodDiscriminatedUnion<[z.ZodObject<{
15
- func: z.ZodLiteral<"sum" | "count" | "avg" | "min" | "max">;
15
+ func: z.ZodEnum<{
16
+ count: "count";
17
+ countDistinct: "countDistinct";
18
+ sum: "sum";
19
+ avg: "avg";
20
+ min: "min";
21
+ max: "max";
22
+ variance: "variance";
23
+ variancePop: "variancePop";
24
+ stddev: "stddev";
25
+ median: "median";
26
+ }>;
16
27
  }, z.core.$strip>, z.ZodObject<{
17
28
  func: z.ZodLiteral<"quantile">;
18
- quantile: z.ZodNumber;
29
+ quantile: z.ZodOptional<z.ZodNumber>;
19
30
  }, z.core.$strip>], "func">;
20
31
  }, z.core.$strip>;
21
32
  export declare const zVBIMeasureGroup: z.ZodType<VBIMeasureGroup>;
@@ -32,10 +43,21 @@ export declare const zVBIMeasureTree: z.ZodArray<z.ZodUnion<readonly [z.ZodObjec
32
43
  size: "size";
33
44
  }>;
34
45
  aggregate: z.ZodDiscriminatedUnion<[z.ZodObject<{
35
- func: z.ZodLiteral<"sum" | "count" | "avg" | "min" | "max">;
46
+ func: z.ZodEnum<{
47
+ count: "count";
48
+ countDistinct: "countDistinct";
49
+ sum: "sum";
50
+ avg: "avg";
51
+ min: "min";
52
+ max: "max";
53
+ variance: "variance";
54
+ variancePop: "variancePop";
55
+ stddev: "stddev";
56
+ median: "median";
57
+ }>;
36
58
  }, z.core.$strip>, z.ZodObject<{
37
59
  func: z.ZodLiteral<"quantile">;
38
- quantile: z.ZodNumber;
60
+ quantile: z.ZodOptional<z.ZodNumber>;
39
61
  }, z.core.$strip>], "func">;
40
62
  }, z.core.$strip>, z.ZodType<VBIMeasureGroup, unknown, z.core.$ZodTypeInternals<VBIMeasureGroup, unknown>>]>>;
41
63
  export type VBIMeasure = z.infer<typeof zVBIMeasure>;
@@ -20,10 +20,21 @@ export declare const zVBIDSL: z.ZodObject<{
20
20
  size: "size";
21
21
  }>;
22
22
  aggregate: z.ZodDiscriminatedUnion<[z.ZodObject<{
23
- func: z.ZodLiteral<"sum" | "count" | "avg" | "min" | "max">;
23
+ func: z.ZodEnum<{
24
+ count: "count";
25
+ countDistinct: "countDistinct";
26
+ sum: "sum";
27
+ avg: "avg";
28
+ min: "min";
29
+ max: "max";
30
+ variance: "variance";
31
+ variancePop: "variancePop";
32
+ stddev: "stddev";
33
+ median: "median";
34
+ }>;
24
35
  }, z.core.$strip>, z.ZodObject<{
25
36
  func: z.ZodLiteral<"quantile">;
26
- quantile: z.ZodNumber;
37
+ quantile: z.ZodOptional<z.ZodNumber>;
27
38
  }, z.core.$strip>], "func">;
28
39
  }, z.core.$strip>, z.ZodType<import("..").VBIMeasureGroup, unknown, z.core.$ZodTypeInternals<import("..").VBIMeasureGroup, unknown>>]>>;
29
40
  havingFilter: z.ZodDefault<z.ZodOptional<z.ZodType<{
@@ -1,14 +1,15 @@
1
- export declare const createVBI: () => {
2
- connectorMap: Map<string, {
3
- discoverSchema: () => Promise<import("..").VBISchema>;
4
- query: (queryProps: import("..").VBIQueryProps) => Promise<import("..").VBIQueryResult>;
5
- } | (() => Promise<import("..").VBIConnector>)>;
6
- registerConnector: (id: import("../types/connector/connector").VBIConnectorId, connector: import("..").VBIConnector | (() => Promise<import("..").VBIConnector>)) => void;
7
- getConnector: (id: import("../types/connector/connector").VBIConnectorId) => Promise<{
8
- discoverSchema: () => Promise<import("..").VBISchema>;
9
- query: (queryProps: import("..").VBIQueryProps) => Promise<import("..").VBIQueryResult>;
10
- }>;
11
- generateEmptyDSL: (connectorId: import("../types/connector/connector").VBIConnectorId) => import("..").VBIDSL;
12
- from: (vbi: import("..").VBIDSLInput) => import("..").VBIBuilder;
13
- create: (vbi: import("..").VBIDSLInput) => import("..").VBIBuilder;
14
- };
1
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from '../builder/adapters/vquery-vseed/types';
2
+ import { connectorMap, getConnector, registerConnector } from '../builder/connector';
3
+ import type { VBIBuilder } from '../builder/builder';
4
+ import type { VBIDSLInput, VBIBuilderOptions } from '../types';
5
+ import { generateEmptyDSL } from './generate-empty-dsl';
6
+ export interface VBIInstance<TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL> {
7
+ connectorMap: typeof connectorMap;
8
+ registerConnector: typeof registerConnector;
9
+ getConnector: typeof getConnector;
10
+ generateEmptyDSL: typeof generateEmptyDSL;
11
+ from: (vbi: VBIDSLInput, builderOptions?: VBIBuilderOptions<TQueryDSL, TSeedDSL>) => VBIBuilder<TQueryDSL, TSeedDSL>;
12
+ create: (vbi: VBIDSLInput, builderOptions?: VBIBuilderOptions<TQueryDSL, TSeedDSL>) => VBIBuilder<TQueryDSL, TSeedDSL>;
13
+ }
14
+ export declare function createVBI(): VBIInstance<DefaultVBIQueryDSL, DefaultVBISeedDSL>;
15
+ export declare function createVBI<TQueryDSL, TSeedDSL>(defaultBuilderOptions: VBIBuilderOptions<TQueryDSL, TSeedDSL>): VBIInstance<TQueryDSL, TSeedDSL>;
@@ -1,3 +1,4 @@
1
- import type { VBIDSLInput } from '../../types';
1
+ import type { DefaultVBIQueryDSL, DefaultVBISeedDSL } from '../../builder/adapters/vquery-vseed/types';
2
+ import type { VBIDSLInput, VBIBuilderOptions } from '../../types';
2
3
  import { VBIBuilder } from '../../builder';
3
- export declare const fromVBIDSLInput: (vbi: VBIDSLInput) => VBIBuilder;
4
+ export declare const fromVBIDSLInput: <TQueryDSL = DefaultVBIQueryDSL, TSeedDSL = DefaultVBISeedDSL>(vbi: VBIDSLInput, options?: VBIBuilderOptions<TQueryDSL, TSeedDSL>) => VBIBuilder<TQueryDSL, TSeedDSL>;
package/dist/vbi.d.ts CHANGED
@@ -1,14 +1 @@
1
- export declare const VBI: {
2
- connectorMap: Map<string, {
3
- discoverSchema: () => Promise<import("./types").VBISchema>;
4
- query: (queryProps: import("./types").VBIQueryProps) => Promise<import("./types").VBIQueryResult>;
5
- } | (() => Promise<import("./types").VBIConnector>)>;
6
- registerConnector: (id: import("./types/connector/connector").VBIConnectorId, connector: import("./types").VBIConnector | (() => Promise<import("./types").VBIConnector>)) => void;
7
- getConnector: (id: import("./types/connector/connector").VBIConnectorId) => Promise<{
8
- discoverSchema: () => Promise<import("./types").VBISchema>;
9
- query: (queryProps: import("./types").VBIQueryProps) => Promise<import("./types").VBIQueryResult>;
10
- }>;
11
- generateEmptyDSL: (connectorId: import("./types/connector/connector").VBIConnectorId) => import("./types").VBIDSL;
12
- from: (vbi: import("./types").VBIDSLInput) => import("./builder").VBIBuilder;
13
- create: (vbi: import("./types").VBIDSLInput) => import("./builder").VBIBuilder;
14
- };
1
+ export declare const VBI: import(".").VBIInstance<import("./builder").DefaultVBIQueryDSL, import("@visactor/vseed").VSeed>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visactor/vbi",
3
- "version": "0.4.17",
3
+ "version": "0.4.19",
4
4
  "license": "MIT",
5
5
  "homepage": "https://visactor.github.io/VBI",
6
6
  "bugs": "https://github.com/VisActor/VBI/issues",
@@ -33,11 +33,11 @@
33
33
  "uuid": "13.0.0",
34
34
  "yjs": "13.6.28",
35
35
  "zod": "4.0.17",
36
- "@visactor/vseed": "0.4.17"
36
+ "@visactor/vseed": "0.4.19"
37
37
  },
38
38
  "optionalDependencies": {
39
- "@visactor/vquery": "0.4.17",
40
- "@visactor/vseed": "0.4.17"
39
+ "@visactor/vquery": "0.4.19",
40
+ "@visactor/vseed": "0.4.19"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@eslint/js": "9.39.0",
@@ -51,7 +51,7 @@
51
51
  "ts-morph": "26.0.0",
52
52
  "typescript": "5.9.3",
53
53
  "typescript-eslint": "8.48.0",
54
- "@visactor/vquery": "0.4.17"
54
+ "@visactor/vquery": "0.4.19"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "rslib build",
@@ -1,4 +0,0 @@
1
- import * as Y from 'yjs';
2
- import type { VQueryDSL } from '@visactor/vquery';
3
- import type { VBIBuilder } from '../vbi-builder';
4
- export declare const buildVQueryDSL: (dsl: Y.Map<any>, builder: VBIBuilder) => VQueryDSL;
@@ -1,8 +0,0 @@
1
- import type { VSeedDSL } from '@visactor/vseed';
2
- import type { VQueryDSL } from '@visactor/vquery';
3
- import type { VBIDSL } from '../../types';
4
- export interface BuildVSeedInput {
5
- vbiDSL: VBIDSL;
6
- queryDSL: VQueryDSL;
7
- }
8
- export declare const buildVSeedDSL: ({ vbiDSL, queryDSL }: BuildVSeedInput) => Promise<VSeedDSL>;
@@ -1,14 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { DimensionsBuilder, MeasuresBuilder, HavingFilterBuilder, WhereFilterBuilder, ChartTypeBuilder, ThemeBuilder, LocaleBuilder, LimitBuilder, UndoManager } from '../features';
3
- export interface BuilderFeatureInstances {
4
- chartType: ChartTypeBuilder;
5
- measures: MeasuresBuilder;
6
- dimensions: DimensionsBuilder;
7
- havingFilter: HavingFilterBuilder;
8
- whereFilter: WhereFilterBuilder;
9
- theme: ThemeBuilder;
10
- locale: LocaleBuilder;
11
- limit: LimitBuilder;
12
- undoManager: UndoManager;
13
- }
14
- export declare const createBuilderFeatures: (doc: Y.Doc, dsl: Y.Map<any>) => BuilderFeatureInstances;