@visactor/vbi 0.4.16 → 0.4.17

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 (38) hide show
  1. package/dist/builder/features/dimensions/dim-builder.d.ts +10 -10
  2. package/dist/builder/features/dimensions/dim-node-builder.d.ts +4 -0
  3. package/dist/builder/features/dimensions/dimension-utils.d.ts +4 -0
  4. package/dist/builder/features/havingFilter/having-builder.d.ts +3 -3
  5. package/dist/builder/features/measures/mea-builder.d.ts +9 -9
  6. package/dist/builder/features/measures/mea-node-builder.d.ts +4 -0
  7. package/dist/builder/features/measures/measure-utils.d.ts +4 -0
  8. package/dist/builder/features/whereFilter/where-builder.d.ts +3 -3
  9. package/dist/builder/index.d.ts +1 -1
  10. package/dist/builder/modules/apply-update.d.ts +2 -0
  11. package/dist/builder/modules/build-vquery.d.ts +4 -0
  12. package/dist/builder/modules/build-vseed.d.ts +8 -0
  13. package/dist/builder/modules/build.d.ts +3 -0
  14. package/dist/builder/modules/create-builder-features.d.ts +14 -0
  15. package/dist/builder/modules/encode-state-as-update.d.ts +2 -0
  16. package/dist/builder/modules/get-schema.d.ts +5 -0
  17. package/dist/builder/modules/index.d.ts +8 -0
  18. package/dist/builder/modules/is-empty.d.ts +2 -0
  19. package/dist/builder/vbi-builder.d.ts +7 -6
  20. package/dist/index.cjs +548 -412
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.js +546 -410
  23. package/dist/types/builder/VBIInterface.d.ts +1 -0
  24. package/dist/types/dsl/dimensions/dimensions.d.ts +2 -0
  25. package/dist/types/dsl/measures/measures.d.ts +2 -0
  26. package/dist/types/dsl/vbi/vbi.d.ts +2 -0
  27. package/dist/vbi/create-vbi.d.ts +14 -0
  28. package/dist/vbi/from/from-vbi-dsl-input.d.ts +3 -0
  29. package/dist/vbi/from/set-base-dsl-fields.d.ts +3 -0
  30. package/dist/vbi/generate-empty-dsl.d.ts +3 -0
  31. package/dist/vbi/normalize/ensure-having-group.d.ts +2 -0
  32. package/dist/vbi/normalize/ensure-where-group.d.ts +2 -0
  33. package/dist/vbi/normalize/ensure-y-array.d.ts +3 -0
  34. package/dist/vbi/normalize/to-y-map.d.ts +3 -0
  35. package/dist/vbi/normalize/types.d.ts +5 -0
  36. package/dist/vbi.d.ts +14 -0
  37. package/package.json +5 -5
  38. package/dist/builder/vbi.d.ts +0 -16
package/dist/index.cjs CHANGED
@@ -44,12 +44,248 @@ __webpack_require__.d(__webpack_exports__, {
44
44
  LocaleBuilder: ()=>LocaleBuilder,
45
45
  UndoManager: ()=>UndoManager
46
46
  });
47
+ const connectorMap = new Map();
48
+ const registerConnector = (id, connector)=>{
49
+ connectorMap.set(id, connector);
50
+ };
51
+ const getConnector = async (id)=>{
52
+ const connector = connectorMap.get(id);
53
+ if (!connector) throw new Error(`connector ${id} not registered`);
54
+ if ('function' == typeof connector) return connector();
55
+ return connector;
56
+ };
47
57
  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
+ const external_remeda_namespaceObject = require("remeda");
64
+ const buildSelect = (queryDSL, context)=>{
65
+ const { vbiDSL } = context;
66
+ const measures = vbiDSL.measures;
67
+ const dimensions = vbiDSL.dimensions;
68
+ const result = {
69
+ ...queryDSL
70
+ };
71
+ const measureNodes = measures.filter((measure)=>MeasuresBuilder.isMeasureNode(measure));
72
+ const measureSelects = measureNodes.map((measure)=>({
73
+ field: measure.field,
74
+ alias: measure.alias,
75
+ aggr: measure.aggregate
76
+ }));
77
+ const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
78
+ const dimensionSelects = dimensionNodes.map((dimension)=>({
79
+ field: dimension.field,
80
+ alias: dimension.alias
81
+ }));
82
+ result.select = measureSelects.concat(dimensionSelects);
83
+ return result;
84
+ };
85
+ const buildGroupBy = (queryDSL, context)=>{
86
+ const result = {
87
+ ...queryDSL
88
+ };
89
+ const { vbiDSL } = context;
90
+ const dimensions = vbiDSL.dimensions;
91
+ const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
92
+ result.groupBy = dimensionNodes.map((dimension)=>dimension.field);
93
+ return result;
94
+ };
95
+ const buildWhere = (queryDSL, context)=>{
96
+ const { vbiDSL } = context;
97
+ const whereFilter = vbiDSL.whereFilter;
98
+ if (!whereFilter || 0 === whereFilter.conditions.length) return queryDSL;
99
+ const result = {
100
+ ...queryDSL
101
+ };
102
+ result.where = mapGroupToCondition(whereFilter);
103
+ return result;
104
+ };
105
+ function isWhereGroup(clause) {
106
+ return 'op' in clause && 'conditions' in clause;
107
+ }
108
+ function mapClauseToCondition(clause) {
109
+ if (isWhereGroup(clause)) return [
110
+ mapGroupToCondition(clause)
111
+ ];
112
+ return mapFilterToCondition(clause);
113
+ }
114
+ function mapGroupToCondition(group) {
115
+ return {
116
+ op: group.op,
117
+ conditions: group.conditions.flatMap(mapClauseToCondition)
118
+ };
119
+ }
120
+ function mapFilterToCondition(filter) {
121
+ if ('between' === filter.op || 'not between' === filter.op) return handleBetweenFilter(filter);
122
+ return handleSimpleFilter(filter);
123
+ }
124
+ function handleBetweenFilter(filter) {
125
+ const value = normalizeBetweenValue(filter.value);
126
+ const lowerCondition = void 0 !== value.min && null !== value.min && '' !== value.min ? {
127
+ field: filter.field,
128
+ op: '<' === value.leftOp ? '>' : '>=',
129
+ value: value.min
130
+ } : void 0;
131
+ const upperCondition = void 0 !== value.max && null !== value.max && '' !== value.max ? {
132
+ field: filter.field,
133
+ op: '<' === value.rightOp ? '<' : '<=',
134
+ value: value.max
135
+ } : void 0;
136
+ if ('not between' === filter.op) {
137
+ const outsideConditions = [
138
+ lowerCondition && invertLowerBound(lowerCondition),
139
+ upperCondition && invertUpperBound(upperCondition)
140
+ ].filter(Boolean);
141
+ if (outsideConditions.length <= 1) return outsideConditions;
142
+ return [
143
+ {
144
+ op: 'or',
145
+ conditions: outsideConditions
146
+ }
147
+ ];
148
+ }
149
+ return [
150
+ lowerCondition,
151
+ upperCondition
152
+ ].filter(Boolean);
153
+ }
154
+ function normalizeBetweenValue(value) {
155
+ if (Array.isArray(value)) return {
156
+ min: value[0],
157
+ max: value[1],
158
+ leftOp: '<=',
159
+ rightOp: '<='
160
+ };
161
+ if ('object' == typeof value && null !== value) return value;
162
+ return {};
163
+ }
164
+ function invertLowerBound(condition) {
165
+ return {
166
+ field: condition.field,
167
+ op: '>' === condition.op ? '<=' : '<',
168
+ value: condition.value
169
+ };
170
+ }
171
+ function invertUpperBound(condition) {
172
+ return {
173
+ field: condition.field,
174
+ op: '<' === condition.op ? '>=' : '>',
175
+ value: condition.value
176
+ };
177
+ }
178
+ function handleSimpleFilter(filter) {
179
+ let mappedOp = filter.op ?? '=';
180
+ const value = filter.value;
181
+ if (Array.isArray(value)) {
182
+ if ('=' === mappedOp) mappedOp = 'in';
183
+ if ('!=' === mappedOp) mappedOp = 'not in';
184
+ }
185
+ return [
186
+ {
187
+ field: filter.field,
188
+ op: mappedOp,
189
+ value
190
+ }
191
+ ];
192
+ }
193
+ const buildHaving = (queryDSL, context)=>{
194
+ const { vbiDSL } = context;
195
+ const havingFilter = vbiDSL.havingFilter;
196
+ if (!havingFilter || 0 === havingFilter.conditions.length) return queryDSL;
197
+ const result = {
198
+ ...queryDSL
199
+ };
200
+ result.having = {
201
+ op: havingFilter.op,
202
+ conditions: havingFilter.conditions.flatMap(buildHaving_mapClauseToCondition)
203
+ };
204
+ return result;
205
+ };
206
+ function isHavingGroup(clause) {
207
+ return 'op' in clause && 'conditions' in clause;
208
+ }
209
+ function buildHaving_mapClauseToCondition(clause) {
210
+ if (isHavingGroup(clause)) return [
211
+ buildHaving_mapGroupToCondition(clause)
212
+ ];
213
+ return buildHaving_mapFilterToCondition(clause);
214
+ }
215
+ function buildHaving_mapGroupToCondition(group) {
216
+ return {
217
+ op: group.op,
218
+ conditions: group.conditions.flatMap(buildHaving_mapClauseToCondition)
219
+ };
220
+ }
221
+ function buildHaving_mapFilterToCondition(filter) {
222
+ const mappedOp = filter.op ?? '=';
223
+ return [
224
+ {
225
+ field: filter.field,
226
+ op: mappedOp,
227
+ value: filter.value
228
+ }
229
+ ];
230
+ }
231
+ const buildLimit = (queryDSL, context)=>{
232
+ const result = {
233
+ ...queryDSL
234
+ };
235
+ const limit = context.vbiDSL.limit ?? 1000;
236
+ result.limit = limit;
237
+ return result;
238
+ };
239
+ const buildVQuery = (vbiDSL, builder)=>{
240
+ const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
241
+ vbiDSL,
242
+ builder
243
+ });
244
+ return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
245
+ };
246
+ const buildVQueryDSL = (dsl, builder)=>{
247
+ const vbiDSL = buildVBIDSL(dsl);
248
+ return buildVQuery(vbiDSL, builder);
249
+ };
250
+ const buildVSeedDSL = async ({ vbiDSL, queryDSL })=>{
251
+ const connectorId = vbiDSL.connectorId;
252
+ const connector = await getConnector(connectorId);
253
+ const schema = await connector.discoverSchema();
254
+ const queryResult = await connector.query({
255
+ queryDSL,
256
+ schema,
257
+ connectorId
258
+ });
259
+ return {
260
+ chartType: vbiDSL.chartType,
261
+ dataset: queryResult.dataset,
262
+ theme: vbiDSL.theme,
263
+ locale: vbiDSL.locale
264
+ };
265
+ };
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();
280
+ };
48
281
  class MeasureNodeBuilder {
49
282
  yMap;
50
283
  constructor(yMap){
51
284
  this.yMap = yMap;
52
285
  }
286
+ getId() {
287
+ return this.yMap.get('id');
288
+ }
53
289
  getField() {
54
290
  return this.yMap.get('field');
55
291
  }
@@ -69,13 +305,48 @@ class MeasureNodeBuilder {
69
305
  return this.yMap.toJSON();
70
306
  }
71
307
  }
308
+ const vseed_namespaceObject = require("@visactor/vseed");
309
+ const external_uuid_namespaceObject = require("uuid");
310
+ const id_id = {
311
+ uuid: ()=>(0, external_uuid_namespaceObject.v4)()
312
+ };
313
+ function isVBIFilter(clause) {
314
+ return 'field' in clause;
315
+ }
316
+ function isVBIWhereGroup(clause) {
317
+ return 'conditions' in clause;
318
+ }
319
+ function isVBIHavingFilter(clause) {
320
+ return 'field' in clause;
321
+ }
322
+ function isVBIHavingGroup(clause) {
323
+ return 'conditions' in clause;
324
+ }
325
+ const getOrCreateMeasures = (dsl)=>{
326
+ const measures = dsl.get('measures');
327
+ if (measures instanceof external_yjs_namespaceObject.Array) return measures;
328
+ const yMeasures = new external_yjs_namespaceObject.Array();
329
+ dsl.set('measures', yMeasures);
330
+ return yMeasures;
331
+ };
332
+ const normalizeMeasureNodeIds = (measures)=>{
333
+ measures.toArray().forEach((item)=>{
334
+ if (item instanceof external_yjs_namespaceObject.Map && 'string' == typeof item.get('field') && !item.get('id')) item.set('id', id_id.uuid());
335
+ });
336
+ };
337
+ const locateMeasureIndexById = (measures, measureId)=>measures.toArray().findIndex((item)=>item.get('id') === measureId);
72
338
  class MeasuresBuilder {
73
339
  dsl;
74
- constructor(_doc, dsl){
340
+ constructor(doc, dsl){
75
341
  this.dsl = dsl;
342
+ doc.transact(()=>{
343
+ const measures = getOrCreateMeasures(this.dsl);
344
+ normalizeMeasureNodeIds(measures);
345
+ });
76
346
  }
77
347
  add(field, callback) {
78
348
  const measure = {
349
+ id: id_id.uuid(),
79
350
  alias: field,
80
351
  field,
81
352
  encoding: 'yAxis',
@@ -85,45 +356,50 @@ class MeasuresBuilder {
85
356
  };
86
357
  const yMap = new external_yjs_namespaceObject.Map();
87
358
  for (const [key, value] of Object.entries(measure))yMap.set(key, value);
88
- this.dsl.get('measures').push([
359
+ const measures = getOrCreateMeasures(this.dsl);
360
+ measures.push([
89
361
  yMap
90
362
  ]);
91
363
  const node = new MeasureNodeBuilder(yMap);
92
364
  callback(node);
93
365
  return this;
94
366
  }
95
- remove(field) {
96
- const measures = this.dsl.get('measures');
97
- const index = measures.toArray().findIndex((item)=>item.get('field') === field);
98
- if (-1 !== index) this.dsl.get('measures').delete(index, 1);
367
+ remove(id) {
368
+ const measures = getOrCreateMeasures(this.dsl);
369
+ const index = locateMeasureIndexById(measures, id);
370
+ if (-1 !== index) measures.delete(index, 1);
99
371
  return this;
100
372
  }
101
- update(field, callback) {
102
- const measures = this.dsl.get('measures');
103
- const index = measures.toArray().findIndex((item)=>item.get('field') === field);
104
- if (-1 === index) throw new Error(`Measure with field "${field}" not found`);
373
+ update(id, callback) {
374
+ const measures = getOrCreateMeasures(this.dsl);
375
+ const index = locateMeasureIndexById(measures, id);
376
+ if (-1 === index) throw new Error(`Measure with id "${id}" not found`);
105
377
  const measureYMap = measures.get(index);
106
378
  const node = new MeasureNodeBuilder(measureYMap);
107
379
  callback(node);
108
380
  return this;
109
381
  }
110
- find(field) {
111
- const measures = this.dsl.get('measures');
112
- const index = measures.toArray().findIndex((item)=>item.get('field') === field);
113
- if (-1 === index) return;
114
- return new MeasureNodeBuilder(measures.get(index));
382
+ find(predicate) {
383
+ const measures = getOrCreateMeasures(this.dsl);
384
+ const items = measures.toArray();
385
+ for(let index = 0; index < items.length; index++){
386
+ const node = new MeasureNodeBuilder(items[index]);
387
+ if (predicate(node, index)) return node;
388
+ }
115
389
  }
116
390
  findAll() {
117
- const measures = this.dsl.get('measures');
391
+ const measures = getOrCreateMeasures(this.dsl);
118
392
  return measures.toArray().map((yMap)=>new MeasureNodeBuilder(yMap));
119
393
  }
120
394
  toJSON() {
121
- return this.dsl.get('measures').toJSON();
395
+ const measures = getOrCreateMeasures(this.dsl);
396
+ return measures.toJSON();
122
397
  }
123
398
  observe(callback) {
124
- this.dsl.get('measures').observe(callback);
399
+ const measures = getOrCreateMeasures(this.dsl);
400
+ measures.observe(callback);
125
401
  return ()=>{
126
- this.dsl.get('measures').unobserve(callback);
402
+ measures.unobserve(callback);
127
403
  };
128
404
  }
129
405
  static isMeasureNode(node) {
@@ -138,6 +414,9 @@ class DimensionNodeBuilder {
138
414
  constructor(yMap){
139
415
  this.yMap = yMap;
140
416
  }
417
+ getId() {
418
+ return this.yMap.get('id');
419
+ }
141
420
  getField() {
142
421
  return this.yMap.get('field');
143
422
  }
@@ -149,57 +428,80 @@ class DimensionNodeBuilder {
149
428
  return this.yMap.toJSON();
150
429
  }
151
430
  }
431
+ const getOrCreateDimensions = (dsl)=>{
432
+ const dimensions = dsl.get('dimensions');
433
+ if (dimensions instanceof external_yjs_namespaceObject.Array) return dimensions;
434
+ const yDimensions = new external_yjs_namespaceObject.Array();
435
+ dsl.set('dimensions', yDimensions);
436
+ return yDimensions;
437
+ };
438
+ const normalizeDimensionNodeIds = (dimensions)=>{
439
+ dimensions.toArray().forEach((item)=>{
440
+ if (item instanceof external_yjs_namespaceObject.Map && 'string' == typeof item.get('field') && !item.get('id')) item.set('id', id_id.uuid());
441
+ });
442
+ };
443
+ const locateDimensionIndexById = (dimensions, dimensionId)=>dimensions.toArray().findIndex((item)=>item.get('id') === dimensionId);
152
444
  class DimensionsBuilder {
153
445
  dsl;
154
- constructor(_doc, dsl){
446
+ constructor(doc, dsl){
155
447
  this.dsl = dsl;
448
+ doc.transact(()=>{
449
+ const dimensions = getOrCreateDimensions(this.dsl);
450
+ normalizeDimensionNodeIds(dimensions);
451
+ });
156
452
  }
157
453
  add(field, callback) {
158
454
  const dimension = {
455
+ id: id_id.uuid(),
159
456
  alias: field,
160
457
  field
161
458
  };
162
459
  const yMap = new external_yjs_namespaceObject.Map();
163
460
  for (const [key, value] of Object.entries(dimension))yMap.set(key, value);
164
- this.dsl.get('dimensions').push([
461
+ const dimensions = getOrCreateDimensions(this.dsl);
462
+ dimensions.push([
165
463
  yMap
166
464
  ]);
167
465
  const node = new DimensionNodeBuilder(yMap);
168
466
  callback(node);
169
467
  return this;
170
468
  }
171
- remove(field) {
172
- const dimensions = this.dsl.get('dimensions');
173
- const index = dimensions.toArray().findIndex((item)=>item.get('field') === field);
174
- if (-1 !== index) this.dsl.get('dimensions').delete(index, 1);
469
+ remove(id) {
470
+ const dimensions = getOrCreateDimensions(this.dsl);
471
+ const index = locateDimensionIndexById(dimensions, id);
472
+ if (-1 !== index) dimensions.delete(index, 1);
175
473
  return this;
176
474
  }
177
- update(field, callback) {
178
- const dimensions = this.dsl.get('dimensions');
179
- const index = dimensions.toArray().findIndex((item)=>item.get('field') === field);
180
- if (-1 === index) throw new Error(`Dimension with field "${field}" not found`);
475
+ update(id, callback) {
476
+ const dimensions = getOrCreateDimensions(this.dsl);
477
+ const index = locateDimensionIndexById(dimensions, id);
478
+ if (-1 === index) throw new Error(`Dimension with id "${id}" not found`);
181
479
  const dimensionYMap = dimensions.get(index);
182
480
  const node = new DimensionNodeBuilder(dimensionYMap);
183
481
  callback(node);
184
482
  return this;
185
483
  }
186
- find(field) {
187
- const dimensions = this.dsl.get('dimensions');
188
- const index = dimensions.toArray().findIndex((item)=>item.get('field') === field);
189
- if (-1 === index) return;
190
- return new DimensionNodeBuilder(dimensions.get(index));
484
+ find(predicate) {
485
+ const dimensions = getOrCreateDimensions(this.dsl);
486
+ const items = dimensions.toArray();
487
+ for(let index = 0; index < items.length; index++){
488
+ const node = new DimensionNodeBuilder(items[index]);
489
+ if (predicate(node, index)) return node;
490
+ }
191
491
  }
192
492
  findAll() {
193
- const dimensions = this.dsl.get('dimensions');
493
+ const dimensions = getOrCreateDimensions(this.dsl);
194
494
  return dimensions.toArray().map((yMap)=>new DimensionNodeBuilder(yMap));
195
495
  }
196
496
  toJSON() {
197
- return this.dsl.get('dimensions').toJSON();
497
+ const dimensions = getOrCreateDimensions(this.dsl);
498
+ return dimensions.toJSON();
198
499
  }
199
500
  observe(callback) {
200
- this.dsl.get('dimensions').observe(callback);
501
+ const dimensions = getOrCreateDimensions(this.dsl);
502
+ dimensions.observe(callback);
201
503
  return ()=>{
202
- this.dsl.get('dimensions').unobserve(callback);
504
+ dimensions.unobserve(callback);
203
505
  };
204
506
  }
205
507
  static isDimensionNode(node) {
@@ -209,7 +511,6 @@ class DimensionsBuilder {
209
511
  return 'children' in node;
210
512
  }
211
513
  }
212
- const vseed_namespaceObject = require("@visactor/vseed");
213
514
  class ChartTypeBuilder {
214
515
  dsl;
215
516
  constructor(_doc, dsl){
@@ -259,22 +560,6 @@ class ChartTypeBuilder {
259
560
  ];
260
561
  }
261
562
  }
262
- const external_uuid_namespaceObject = require("uuid");
263
- const id_id = {
264
- uuid: ()=>(0, external_uuid_namespaceObject.v4)()
265
- };
266
- function isVBIFilter(clause) {
267
- return 'field' in clause;
268
- }
269
- function isVBIWhereGroup(clause) {
270
- return 'conditions' in clause;
271
- }
272
- function isVBIHavingFilter(clause) {
273
- return 'field' in clause;
274
- }
275
- function isVBIHavingGroup(clause) {
276
- return 'conditions' in clause;
277
- }
278
563
  function createWhereGroup(op = 'and', groupId = 'root') {
279
564
  const yMap = new external_yjs_namespaceObject.Map();
280
565
  yMap.set('id', groupId);
@@ -282,7 +567,7 @@ function createWhereGroup(op = 'and', groupId = 'root') {
282
567
  yMap.set('conditions', new external_yjs_namespaceObject.Array());
283
568
  return yMap;
284
569
  }
285
- function isWhereGroup(yMap) {
570
+ function where_utils_isWhereGroup(yMap) {
286
571
  return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
287
572
  }
288
573
  function findEntry(collection, entryId) {
@@ -294,7 +579,7 @@ function findEntry(collection, entryId) {
294
579
  index,
295
580
  item
296
581
  };
297
- if (isWhereGroup(item)) {
582
+ if (where_utils_isWhereGroup(item)) {
298
583
  const nestedCollection = item.get('conditions');
299
584
  const nestedMatch = findEntry(nestedCollection, entryId);
300
585
  if (nestedMatch) return nestedMatch;
@@ -456,13 +741,21 @@ class WhereFilterBuilder {
456
741
  }
457
742
  return this;
458
743
  }
459
- find(id) {
460
- const conditions = this.getConditions();
461
- const match = findEntry(conditions, id);
462
- const yMap = match?.item;
463
- if (!yMap) return;
464
- if (WhereFilterBuilder.isGroup(yMap)) return new WhereGroupBuilder(yMap);
465
- return new WhereFilterNodeBuilder(yMap);
744
+ find(predicate) {
745
+ const traverse = (collection)=>{
746
+ const items = collection.toArray();
747
+ for(let index = 0; index < items.length; index++){
748
+ const yMap = items[index];
749
+ const entry = WhereFilterBuilder.isGroup(yMap) ? new WhereGroupBuilder(yMap) : new WhereFilterNodeBuilder(yMap);
750
+ if (predicate(entry, index)) return entry;
751
+ if (WhereFilterBuilder.isGroup(yMap)) {
752
+ const nestedCollection = yMap.get('conditions');
753
+ const nestedMatch = traverse(nestedCollection);
754
+ if (nestedMatch) return nestedMatch;
755
+ }
756
+ }
757
+ };
758
+ return traverse(this.getConditions());
466
759
  }
467
760
  clear() {
468
761
  const conditions = this.getConditions();
@@ -479,7 +772,7 @@ class WhereFilterBuilder {
479
772
  };
480
773
  }
481
774
  static isGroup(yMap) {
482
- return isWhereGroup(yMap);
775
+ return where_utils_isWhereGroup(yMap);
483
776
  }
484
777
  static isNode(yMap) {
485
778
  return void 0 !== yMap.get('field');
@@ -492,7 +785,7 @@ function createHavingGroup(op = 'and', groupId = 'root') {
492
785
  yMap.set('conditions', new external_yjs_namespaceObject.Array());
493
786
  return yMap;
494
787
  }
495
- function isHavingGroup(yMap) {
788
+ function having_utils_isHavingGroup(yMap) {
496
789
  return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
497
790
  }
498
791
  function having_utils_findEntry(collection, entryId) {
@@ -504,7 +797,7 @@ function having_utils_findEntry(collection, entryId) {
504
797
  index,
505
798
  item
506
799
  };
507
- if (isHavingGroup(item)) {
800
+ if (having_utils_isHavingGroup(item)) {
508
801
  const nestedCollection = item.get('conditions');
509
802
  const nestedMatch = having_utils_findEntry(nestedCollection, entryId);
510
803
  if (nestedMatch) return nestedMatch;
@@ -662,13 +955,21 @@ class HavingFilterBuilder {
662
955
  }
663
956
  return this;
664
957
  }
665
- find(id) {
666
- const conditions = this.getConditions();
667
- const match = having_utils_findEntry(conditions, id);
668
- const yMap = match?.item;
669
- if (!yMap) return;
670
- if (HavingFilterBuilder.isGroup(yMap)) return new HavingGroupBuilder(yMap);
671
- return new HavingFilterNodeBuilder(yMap);
958
+ find(predicate) {
959
+ const traverse = (collection)=>{
960
+ const items = collection.toArray();
961
+ for(let index = 0; index < items.length; index++){
962
+ const yMap = items[index];
963
+ const entry = HavingFilterBuilder.isGroup(yMap) ? new HavingGroupBuilder(yMap) : new HavingFilterNodeBuilder(yMap);
964
+ if (predicate(entry, index)) return entry;
965
+ if (HavingFilterBuilder.isGroup(yMap)) {
966
+ const nestedCollection = yMap.get('conditions');
967
+ const nestedMatch = traverse(nestedCollection);
968
+ if (nestedMatch) return nestedMatch;
969
+ }
970
+ }
971
+ };
972
+ return traverse(this.getConditions());
672
973
  }
673
974
  clear() {
674
975
  const conditions = this.getConditions();
@@ -685,7 +986,7 @@ class HavingFilterBuilder {
685
986
  };
686
987
  }
687
988
  static isGroup(yMap) {
688
- return isHavingGroup(yMap);
989
+ return having_utils_isHavingGroup(yMap);
689
990
  }
690
991
  static isNode(yMap) {
691
992
  return void 0 !== yMap.get('field');
@@ -784,203 +1085,20 @@ class UndoManager {
784
1085
  this.manager.clear(clearUndoStack, clearRedoStack);
785
1086
  }
786
1087
  }
787
- const external_remeda_namespaceObject = require("remeda");
788
- const buildSelect = (queryDSL, context)=>{
789
- const { vbiDSL } = context;
790
- const measures = vbiDSL.measures;
791
- const dimensions = vbiDSL.dimensions;
792
- const result = {
793
- ...queryDSL
794
- };
795
- const measureNodes = measures.filter((measure)=>MeasuresBuilder.isMeasureNode(measure));
796
- const measureSelects = measureNodes.map((measure)=>({
797
- field: measure.field,
798
- alias: measure.alias,
799
- aggr: measure.aggregate
800
- }));
801
- const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
802
- const dimensionSelects = dimensionNodes.map((dimension)=>({
803
- field: dimension.field,
804
- alias: dimension.alias
805
- }));
806
- result.select = measureSelects.concat(dimensionSelects);
807
- return result;
808
- };
809
- const buildGroupBy = (queryDSL, context)=>{
810
- const result = {
811
- ...queryDSL
812
- };
813
- const { vbiDSL } = context;
814
- const dimensions = vbiDSL.dimensions;
815
- const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
816
- result.groupBy = dimensionNodes.map((dimension)=>dimension.field);
817
- return result;
818
- };
819
- const buildWhere = (queryDSL, context)=>{
820
- const { vbiDSL } = context;
821
- const whereFilter = vbiDSL.whereFilter;
822
- if (!whereFilter || 0 === whereFilter.conditions.length) return queryDSL;
823
- const result = {
824
- ...queryDSL
825
- };
826
- result.where = mapGroupToCondition(whereFilter);
827
- return result;
828
- };
829
- function buildWhere_isWhereGroup(clause) {
830
- return 'op' in clause && 'conditions' in clause;
831
- }
832
- function mapClauseToCondition(clause) {
833
- if (buildWhere_isWhereGroup(clause)) return [
834
- mapGroupToCondition(clause)
835
- ];
836
- return mapFilterToCondition(clause);
837
- }
838
- function mapGroupToCondition(group) {
839
- return {
840
- op: group.op,
841
- conditions: group.conditions.flatMap(mapClauseToCondition)
842
- };
843
- }
844
- function mapFilterToCondition(filter) {
845
- if ('between' === filter.op || 'not between' === filter.op) return handleBetweenFilter(filter);
846
- return handleSimpleFilter(filter);
847
- }
848
- function handleBetweenFilter(filter) {
849
- const value = normalizeBetweenValue(filter.value);
850
- const lowerCondition = void 0 !== value.min && null !== value.min && '' !== value.min ? {
851
- field: filter.field,
852
- op: '<' === value.leftOp ? '>' : '>=',
853
- value: value.min
854
- } : void 0;
855
- const upperCondition = void 0 !== value.max && null !== value.max && '' !== value.max ? {
856
- field: filter.field,
857
- op: '<' === value.rightOp ? '<' : '<=',
858
- value: value.max
859
- } : void 0;
860
- if ('not between' === filter.op) {
861
- const outsideConditions = [
862
- lowerCondition && invertLowerBound(lowerCondition),
863
- upperCondition && invertUpperBound(upperCondition)
864
- ].filter(Boolean);
865
- if (outsideConditions.length <= 1) return outsideConditions;
866
- return [
867
- {
868
- op: 'or',
869
- conditions: outsideConditions
870
- }
871
- ];
872
- }
873
- return [
874
- lowerCondition,
875
- upperCondition
876
- ].filter(Boolean);
877
- }
878
- function normalizeBetweenValue(value) {
879
- if (Array.isArray(value)) return {
880
- min: value[0],
881
- max: value[1],
882
- leftOp: '<=',
883
- rightOp: '<='
884
- };
885
- if ('object' == typeof value && null !== value) return value;
886
- return {};
887
- }
888
- function invertLowerBound(condition) {
889
- return {
890
- field: condition.field,
891
- op: '>' === condition.op ? '<=' : '<',
892
- value: condition.value
893
- };
894
- }
895
- function invertUpperBound(condition) {
896
- return {
897
- field: condition.field,
898
- op: '<' === condition.op ? '>=' : '>',
899
- value: condition.value
900
- };
901
- }
902
- function handleSimpleFilter(filter) {
903
- let mappedOp = filter.op ?? '=';
904
- const value = filter.value;
905
- if (Array.isArray(value)) {
906
- if ('=' === mappedOp) mappedOp = 'in';
907
- if ('!=' === mappedOp) mappedOp = 'not in';
908
- }
909
- return [
910
- {
911
- field: filter.field,
912
- op: mappedOp,
913
- value
914
- }
915
- ];
916
- }
917
- const buildHaving = (queryDSL, context)=>{
918
- const { vbiDSL } = context;
919
- const havingFilter = vbiDSL.havingFilter;
920
- if (!havingFilter || 0 === havingFilter.conditions.length) return queryDSL;
921
- const result = {
922
- ...queryDSL
923
- };
924
- result.having = {
925
- op: havingFilter.op,
926
- conditions: havingFilter.conditions.flatMap(buildHaving_mapClauseToCondition)
927
- };
928
- return result;
929
- };
930
- function buildHaving_isHavingGroup(clause) {
931
- return 'op' in clause && 'conditions' in clause;
932
- }
933
- function buildHaving_mapClauseToCondition(clause) {
934
- if (buildHaving_isHavingGroup(clause)) return [
935
- buildHaving_mapGroupToCondition(clause)
936
- ];
937
- return buildHaving_mapFilterToCondition(clause);
938
- }
939
- function buildHaving_mapGroupToCondition(group) {
940
- return {
941
- op: group.op,
942
- conditions: group.conditions.flatMap(buildHaving_mapClauseToCondition)
943
- };
944
- }
945
- function buildHaving_mapFilterToCondition(filter) {
946
- const mappedOp = filter.op ?? '=';
947
- return [
948
- {
949
- field: filter.field,
950
- op: mappedOp,
951
- value: filter.value
952
- }
953
- ];
954
- }
955
- const buildLimit = (queryDSL, context)=>{
956
- const result = {
957
- ...queryDSL
958
- };
959
- const limit = context.vbiDSL.limit ?? 1000;
960
- result.limit = limit;
961
- return result;
962
- };
963
- const buildVQuery = (vbiDSL, builder)=>{
964
- const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
965
- vbiDSL,
966
- builder
967
- });
968
- return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
969
- };
970
- const connectorMap = new Map();
971
- const registerConnector = (id, connector)=>{
972
- connectorMap.set(id, connector);
973
- };
974
- const getConnector = async (id)=>{
975
- const connector = connectorMap.get(id);
976
- if (!connector) throw new Error(`connector ${id} not registered`);
977
- if ('function' == typeof connector) return connector();
978
- return connector;
979
- };
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
+ });
980
1099
  class VBIBuilder {
981
1100
  doc;
982
1101
  dsl;
983
- undoManager;
984
1102
  chartType;
985
1103
  measures;
986
1104
  dimensions;
@@ -989,162 +1107,180 @@ class VBIBuilder {
989
1107
  theme;
990
1108
  locale;
991
1109
  limit;
1110
+ undoManager;
992
1111
  constructor(doc){
993
1112
  this.doc = doc;
994
1113
  this.dsl = doc.getMap('dsl');
995
- this.undoManager = new UndoManager(this.dsl);
996
- this.chartType = new ChartTypeBuilder(doc, this.dsl);
997
- this.measures = new MeasuresBuilder(doc, this.dsl);
998
- this.dimensions = new DimensionsBuilder(doc, this.dsl);
999
- this.havingFilter = new HavingFilterBuilder(doc, this.dsl);
1000
- this.whereFilter = new WhereFilterBuilder(doc, this.dsl);
1001
- this.theme = new ThemeBuilder(doc, this.dsl);
1002
- this.locale = new LocaleBuilder(doc, this.dsl);
1003
- this.limit = new LimitBuilder(doc, this.dsl);
1004
- }
1005
- applyUpdate(update) {
1006
- external_yjs_namespaceObject.applyUpdate(this.doc, update);
1007
- }
1008
- encodeStateAsUpdate(targetStateVector) {
1009
- return external_yjs_namespaceObject.encodeStateAsUpdate(this.doc, targetStateVector);
1010
- }
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;
1124
+ }
1125
+ applyUpdate = (update, transactionOrigin)=>applyUpdateToDoc(this.doc, update, transactionOrigin);
1126
+ encodeStateAsUpdate = (targetStateVector)=>encodeDocStateAsUpdate(this.doc, targetStateVector);
1011
1127
  buildVSeed = async ()=>{
1012
1128
  const vbiDSL = this.build();
1013
- const connectorId = vbiDSL.connectorId;
1014
- const connector = await getConnector(vbiDSL.connectorId);
1015
1129
  const queryDSL = this.buildVQuery();
1016
- const schema = await connector.discoverSchema();
1017
- const queryResult = await connector.query({
1018
- queryDSL,
1019
- schema,
1020
- connectorId
1130
+ return buildVSeedDSL({
1131
+ vbiDSL,
1132
+ queryDSL
1021
1133
  });
1022
- return {
1023
- chartType: vbiDSL.chartType,
1024
- dataset: queryResult.dataset,
1025
- theme: vbiDSL.theme,
1026
- locale: vbiDSL.locale
1027
- };
1028
- };
1029
- buildVQuery = ()=>{
1030
- const vbiDSL = this.build();
1031
- return buildVQuery(vbiDSL, this);
1032
- };
1033
- build = ()=>this.dsl.toJSON();
1034
- getSchema = async ()=>{
1035
- const connectorId = this.dsl.get('connectorId');
1036
- const con = await getConnector(connectorId);
1037
- const result = await con.discoverSchema();
1038
- return result;
1039
1134
  };
1135
+ buildVQuery = ()=>buildVQueryDSL(this.dsl, this);
1136
+ build = ()=>buildVBIDSL(this.dsl);
1137
+ isEmpty = ()=>isEmptyVBIDSL(this.dsl);
1138
+ getSchema = async ()=>getBuilderSchema(this.dsl);
1040
1139
  }
1140
+ const shouldEnsureIdForObject = (obj, ensureId)=>{
1141
+ if (true === ensureId) return true;
1142
+ if ('field' === ensureId) return 'string' == typeof obj.field;
1143
+ return false;
1144
+ };
1145
+ const toYMap = (obj, ensureId = false)=>{
1146
+ const yMap = new external_yjs_namespaceObject.Map();
1147
+ if (shouldEnsureIdForObject(obj, ensureId) && !obj.id) yMap.set('id', id_id.uuid());
1148
+ for (const [key, value] of Object.entries(obj)){
1149
+ if (('conditions' === key || 'children' === key) && Array.isArray(value)) {
1150
+ const yArr = new external_yjs_namespaceObject.Array();
1151
+ for (const child of value){
1152
+ if (child instanceof external_yjs_namespaceObject.Map) {
1153
+ yArr.push([
1154
+ child
1155
+ ]);
1156
+ continue;
1157
+ }
1158
+ if ('object' == typeof child && null !== child) {
1159
+ yArr.push([
1160
+ toYMap(child, ensureId)
1161
+ ]);
1162
+ continue;
1163
+ }
1164
+ yArr.push([
1165
+ child
1166
+ ]);
1167
+ }
1168
+ yMap.set(key, yArr);
1169
+ continue;
1170
+ }
1171
+ yMap.set(key, value);
1172
+ }
1173
+ return yMap;
1174
+ };
1175
+ const ensureYArray = (arr, ensureId = false)=>{
1176
+ if (!arr) return new external_yjs_namespaceObject.Array();
1177
+ if (arr instanceof external_yjs_namespaceObject.Array) return arr;
1178
+ const yArr = new external_yjs_namespaceObject.Array();
1179
+ for (const item of arr){
1180
+ if (item instanceof external_yjs_namespaceObject.Map) {
1181
+ yArr.push([
1182
+ item
1183
+ ]);
1184
+ continue;
1185
+ }
1186
+ if ('object' == typeof item && null !== item) {
1187
+ yArr.push([
1188
+ toYMap(item, ensureId)
1189
+ ]);
1190
+ continue;
1191
+ }
1192
+ yArr.push([
1193
+ item
1194
+ ]);
1195
+ }
1196
+ return yArr;
1197
+ };
1198
+ const getDefaultWhereFilter = ()=>({
1199
+ id: 'root',
1200
+ op: 'and',
1201
+ conditions: []
1202
+ });
1203
+ const isFilterGroupInput = (value)=>'object' == typeof value && null !== value;
1204
+ const ensureWhereGroup = (whereFilter)=>{
1205
+ const sourceWhereFilter = whereFilter instanceof external_yjs_namespaceObject.Map || isFilterGroupInput(whereFilter) ? whereFilter : getDefaultWhereFilter();
1206
+ const whereGroup = sourceWhereFilter instanceof external_yjs_namespaceObject.Map ? sourceWhereFilter : createWhereGroup();
1207
+ if (sourceWhereFilter instanceof external_yjs_namespaceObject.Map) {
1208
+ if (!(whereGroup.get('conditions') instanceof external_yjs_namespaceObject.Array)) whereGroup.set('conditions', new external_yjs_namespaceObject.Array());
1209
+ if (!whereGroup.get('id')) whereGroup.set('id', 'root');
1210
+ if (!whereGroup.get('op')) whereGroup.set('op', 'and');
1211
+ return whereGroup;
1212
+ }
1213
+ whereGroup.set('id', sourceWhereFilter.id ?? 'root');
1214
+ whereGroup.set('op', sourceWhereFilter.op ?? 'and');
1215
+ whereGroup.set('conditions', ensureYArray(sourceWhereFilter.conditions, true));
1216
+ return whereGroup;
1217
+ };
1218
+ const getDefaultHavingFilter = ()=>({
1219
+ id: 'root',
1220
+ op: 'and',
1221
+ conditions: []
1222
+ });
1223
+ const ensure_having_group_isFilterGroupInput = (value)=>'object' == typeof value && null !== value;
1224
+ const ensureHavingGroup = (havingFilter)=>{
1225
+ const sourceHavingFilter = havingFilter instanceof external_yjs_namespaceObject.Map || ensure_having_group_isFilterGroupInput(havingFilter) ? havingFilter : getDefaultHavingFilter();
1226
+ const havingGroup = sourceHavingFilter instanceof external_yjs_namespaceObject.Map ? sourceHavingFilter : createHavingGroup();
1227
+ if (sourceHavingFilter instanceof external_yjs_namespaceObject.Map) {
1228
+ if (!(havingGroup.get('conditions') instanceof external_yjs_namespaceObject.Array)) havingGroup.set('conditions', new external_yjs_namespaceObject.Array());
1229
+ if (!havingGroup.get('id')) havingGroup.set('id', 'root');
1230
+ if (!havingGroup.get('op')) havingGroup.set('op', 'and');
1231
+ return havingGroup;
1232
+ }
1233
+ havingGroup.set('id', sourceHavingFilter.id ?? 'root');
1234
+ havingGroup.set('op', sourceHavingFilter.op ?? 'and');
1235
+ havingGroup.set('conditions', ensureYArray(sourceHavingFilter.conditions, true));
1236
+ return havingGroup;
1237
+ };
1238
+ const setBaseDSLFields = (dsl, vbi)=>{
1239
+ if (vbi.connectorId) dsl.set('connectorId', vbi.connectorId);
1240
+ if (vbi.chartType) dsl.set('chartType', vbi.chartType);
1241
+ if (vbi.theme) dsl.set('theme', vbi.theme);
1242
+ if (vbi.limit) dsl.set('limit', vbi.limit);
1243
+ if (vbi.locale) dsl.set('locale', vbi.locale);
1244
+ if (void 0 !== vbi.version) dsl.set('version', vbi.version);
1245
+ };
1246
+ const fromVBIDSLInput = (vbi)=>{
1247
+ const doc = new external_yjs_namespaceObject.Doc();
1248
+ const dsl = doc.getMap('dsl');
1249
+ doc.transact(()=>{
1250
+ setBaseDSLFields(dsl, vbi);
1251
+ dsl.set('whereFilter', ensureWhereGroup(vbi.whereFilter));
1252
+ dsl.set('havingFilter', ensureHavingGroup(vbi.havingFilter));
1253
+ dsl.set('measures', ensureYArray(vbi.measures, 'field'));
1254
+ dsl.set('dimensions', ensureYArray(vbi.dimensions, 'field'));
1255
+ });
1256
+ return new VBIBuilder(doc);
1257
+ };
1258
+ const generateEmptyDSL = (connectorId)=>({
1259
+ connectorId,
1260
+ chartType: 'table',
1261
+ measures: [],
1262
+ dimensions: [],
1263
+ whereFilter: {
1264
+ id: 'root',
1265
+ op: 'and',
1266
+ conditions: []
1267
+ },
1268
+ havingFilter: {
1269
+ id: 'root',
1270
+ op: 'and',
1271
+ conditions: []
1272
+ },
1273
+ theme: 'light',
1274
+ locale: 'zh-CN',
1275
+ version: 0
1276
+ });
1041
1277
  const createVBI = ()=>({
1042
1278
  connectorMap: connectorMap,
1043
1279
  registerConnector: registerConnector,
1044
1280
  getConnector: getConnector,
1045
- generateEmptyDSL: (connectorId)=>({
1046
- connectorId: connectorId,
1047
- chartType: 'table',
1048
- measures: [],
1049
- dimensions: [],
1050
- whereFilter: {
1051
- id: 'root',
1052
- op: 'and',
1053
- conditions: []
1054
- },
1055
- havingFilter: {
1056
- id: 'root',
1057
- op: 'and',
1058
- conditions: []
1059
- },
1060
- theme: 'light',
1061
- locale: 'zh-CN',
1062
- version: 0
1063
- }),
1064
- from: (vbi)=>{
1065
- const doc = new external_yjs_namespaceObject.Doc();
1066
- const dsl = doc.getMap('dsl');
1067
- doc.transact(()=>{
1068
- if (vbi.connectorId) dsl.set('connectorId', vbi.connectorId);
1069
- if (vbi.chartType) dsl.set('chartType', vbi.chartType);
1070
- if (vbi.theme) dsl.set('theme', vbi.theme);
1071
- if (vbi.limit) dsl.set('limit', vbi.limit);
1072
- if (vbi.locale) dsl.set('locale', vbi.locale);
1073
- if (void 0 !== vbi.version) dsl.set('version', vbi.version);
1074
- const toYMap = (obj, ensureId = false)=>{
1075
- const yMap = new external_yjs_namespaceObject.Map();
1076
- if (ensureId && !obj.id) yMap.set('id', id_id.uuid());
1077
- for (const [key, value] of Object.entries(obj))if ('conditions' === key && Array.isArray(value)) {
1078
- const yArr = new external_yjs_namespaceObject.Array();
1079
- value.forEach((child)=>{
1080
- if (child instanceof external_yjs_namespaceObject.Map) yArr.push([
1081
- child
1082
- ]);
1083
- else if ('object' == typeof child && null !== child) yArr.push([
1084
- toYMap(child, true)
1085
- ]);
1086
- else yArr.push([
1087
- child
1088
- ]);
1089
- });
1090
- yMap.set(key, yArr);
1091
- } else yMap.set(key, value);
1092
- return yMap;
1093
- };
1094
- const ensureYArray = (arr, ensureId = false)=>{
1095
- if (!arr) return new external_yjs_namespaceObject.Array();
1096
- if (arr instanceof external_yjs_namespaceObject.Array) return arr;
1097
- const yArr = new external_yjs_namespaceObject.Array();
1098
- arr.forEach((item)=>{
1099
- if (item instanceof external_yjs_namespaceObject.Map) yArr.push([
1100
- item
1101
- ]);
1102
- else if ('object' == typeof item && null !== item) yArr.push([
1103
- toYMap(item, ensureId)
1104
- ]);
1105
- else yArr.push([
1106
- item
1107
- ]);
1108
- });
1109
- return yArr;
1110
- };
1111
- const whereFilter = vbi.whereFilter ?? {
1112
- id: 'root',
1113
- op: 'and',
1114
- conditions: []
1115
- };
1116
- const whereGroup = whereFilter instanceof external_yjs_namespaceObject.Map ? whereFilter : createWhereGroup();
1117
- if (whereFilter instanceof external_yjs_namespaceObject.Map) {
1118
- if (!(whereGroup.get('conditions') instanceof external_yjs_namespaceObject.Array)) whereGroup.set('conditions', new external_yjs_namespaceObject.Array());
1119
- if (!whereGroup.get('id')) whereGroup.set('id', 'root');
1120
- if (!whereGroup.get('op')) whereGroup.set('op', 'and');
1121
- } else {
1122
- whereGroup.set('id', whereFilter.id ?? 'root');
1123
- whereGroup.set('op', whereFilter.op ?? 'and');
1124
- whereGroup.set('conditions', ensureYArray(whereFilter.conditions, true));
1125
- }
1126
- dsl.set('whereFilter', whereGroup);
1127
- const havingFilter = vbi.havingFilter ?? {
1128
- id: 'root',
1129
- op: 'and',
1130
- conditions: []
1131
- };
1132
- const havingGroup = havingFilter instanceof external_yjs_namespaceObject.Map ? havingFilter : createHavingGroup();
1133
- if (havingFilter instanceof external_yjs_namespaceObject.Map) {
1134
- if (!(havingGroup.get('conditions') instanceof external_yjs_namespaceObject.Array)) havingGroup.set('conditions', new external_yjs_namespaceObject.Array());
1135
- if (!havingGroup.get('id')) havingGroup.set('id', 'root');
1136
- if (!havingGroup.get('op')) havingGroup.set('op', 'and');
1137
- } else {
1138
- havingGroup.set('id', havingFilter.id ?? 'root');
1139
- havingGroup.set('op', havingFilter.op ?? 'and');
1140
- havingGroup.set('conditions', ensureYArray(havingFilter.conditions, true));
1141
- }
1142
- dsl.set('havingFilter', havingGroup);
1143
- dsl.set('measures', ensureYArray(vbi.measures));
1144
- dsl.set('dimensions', ensureYArray(vbi.dimensions));
1145
- });
1146
- return new VBIBuilder(doc);
1147
- }
1281
+ generateEmptyDSL: generateEmptyDSL,
1282
+ from: fromVBIDSLInput,
1283
+ create: fromVBIDSLInput
1148
1284
  });
1149
1285
  const VBI = createVBI();
1150
1286
  exports.ChartTypeBuilder = __webpack_exports__.ChartTypeBuilder;