@finos/legend-application-data-cube 0.1.21 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/lib/__lib__/LegendDataCubeNavigation.d.ts +1 -1
  2. package/lib/__lib__/LegendDataCubeNavigation.d.ts.map +1 -1
  3. package/lib/components/LegendDataCubeWebApplication.d.ts.map +1 -1
  4. package/lib/components/LegendDataCubeWebApplication.js +1 -14
  5. package/lib/components/LegendDataCubeWebApplication.js.map +1 -1
  6. package/lib/components/query-builder/LegendDataCubeQueryBuilder.d.ts.map +1 -1
  7. package/lib/components/query-builder/LegendDataCubeQueryBuilder.js +24 -23
  8. package/lib/components/query-builder/LegendDataCubeQueryBuilder.js.map +1 -1
  9. package/lib/components/query-builder/source-builder/LegendQueryDataCubeSourceBuilder.d.ts.map +1 -1
  10. package/lib/components/query-builder/source-builder/LegendQueryDataCubeSourceBuilder.js +8 -1
  11. package/lib/components/query-builder/source-builder/LegendQueryDataCubeSourceBuilder.js.map +1 -1
  12. package/lib/index.css +1 -1
  13. package/lib/package.json +3 -2
  14. package/lib/stores/LegendDataCubeCacheManager.d.ts +34 -0
  15. package/lib/stores/LegendDataCubeCacheManager.d.ts.map +1 -0
  16. package/lib/stores/LegendDataCubeCacheManager.js +134 -0
  17. package/lib/stores/LegendDataCubeCacheManager.js.map +1 -0
  18. package/lib/stores/LegendDataCubeDataCubeEngine.d.ts +11 -3
  19. package/lib/stores/LegendDataCubeDataCubeEngine.d.ts.map +1 -1
  20. package/lib/stores/LegendDataCubeDataCubeEngine.js +152 -19
  21. package/lib/stores/LegendDataCubeDataCubeEngine.js.map +1 -1
  22. package/lib/stores/query-builder/LegendDataCubeNewQueryState.d.ts.map +1 -1
  23. package/lib/stores/query-builder/LegendDataCubeNewQueryState.js +10 -10
  24. package/lib/stores/query-builder/LegendDataCubeNewQueryState.js.map +1 -1
  25. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.d.ts +0 -1
  26. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.d.ts.map +1 -1
  27. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.js +18 -9
  28. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.js.map +1 -1
  29. package/lib/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.d.ts +1 -1
  30. package/lib/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.d.ts.map +1 -1
  31. package/lib/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.js +1 -1
  32. package/lib/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.js.map +1 -1
  33. package/lib/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.d.ts +4 -3
  34. package/lib/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.d.ts.map +1 -1
  35. package/lib/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.js +5 -2
  36. package/lib/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.js.map +1 -1
  37. package/lib/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.d.ts +3 -2
  38. package/lib/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.d.ts.map +1 -1
  39. package/lib/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.js +6 -1
  40. package/lib/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.js.map +1 -1
  41. package/package.json +13 -12
  42. package/src/__lib__/LegendDataCubeNavigation.ts +1 -1
  43. package/src/components/LegendDataCubeWebApplication.tsx +1 -25
  44. package/src/components/query-builder/LegendDataCubeQueryBuilder.tsx +27 -27
  45. package/src/components/query-builder/source-builder/LegendQueryDataCubeSourceBuilder.tsx +17 -1
  46. package/src/stores/DuckDBWASM.d.ts +22 -0
  47. package/src/stores/LegendDataCubeCacheManager.ts +170 -0
  48. package/src/stores/LegendDataCubeDataCubeEngine.ts +247 -26
  49. package/src/stores/query-builder/LegendDataCubeNewQueryState.tsx +12 -18
  50. package/src/stores/query-builder/LegendDataCubeQueryBuilderStore.tsx +26 -10
  51. package/src/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.ts +1 -1
  52. package/src/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.ts +8 -4
  53. package/src/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.ts +11 -2
  54. package/tsconfig.json +2 -0
@@ -13,9 +13,10 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { ActionState, type PlainObject } from '@finos/legend-shared';
16
+ import { type PlainObject } from '@finos/legend-shared';
17
17
  import type { LegendDataCubeApplicationStore } from '../../LegendDataCubeBaseStore.js';
18
18
  import type { LegendDataCubeDataCubeEngine } from '../../LegendDataCubeDataCubeEngine.js';
19
+ import type { DataCubeConfiguration } from '@finos/legend-data-cube';
19
20
  export declare enum LegendDataCubeSourceBuilderType {
20
21
  LEGEND_QUERY = "Legend Query",
21
22
  ADHOC_QUERY = "Ad hoc Query"
@@ -23,10 +24,10 @@ export declare enum LegendDataCubeSourceBuilderType {
23
24
  export declare abstract class LegendDataCubeSourceBuilderState {
24
25
  protected readonly _application: LegendDataCubeApplicationStore;
25
26
  protected readonly _engine: LegendDataCubeDataCubeEngine;
26
- readonly buildState: ActionState;
27
27
  constructor(application: LegendDataCubeApplicationStore, engine: LegendDataCubeDataCubeEngine);
28
28
  abstract get label(): LegendDataCubeSourceBuilderType;
29
29
  abstract get isValid(): boolean;
30
- abstract build(): Promise<PlainObject>;
30
+ abstract generateSourceData(): Promise<PlainObject>;
31
+ finalizeConfiguration(configuration: DataCubeConfiguration): void;
31
32
  }
32
33
  //# sourceMappingURL=LegendDataCubeSourceBuilderState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegendDataCubeSourceBuilderState.d.ts","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAE1F,oBAAY,+BAA+B;IACzC,YAAY,iBAAiB;IAC7B,WAAW,iBAAiB;CAC7B;AAED,8BAAsB,gCAAgC;IACpD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,8BAA8B,CAAC;IAChE,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC;IAEzD,QAAQ,CAAC,UAAU,cAAwB;gBAGzC,WAAW,EAAE,8BAA8B,EAC3C,MAAM,EAAE,4BAA4B;IAMtC,QAAQ,KAAK,KAAK,IAAI,+BAA+B,CAAC;IACtD,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC;IAChC,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;CACvC"}
1
+ {"version":3,"file":"LegendDataCubeSourceBuilderState.d.ts","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,oBAAY,+BAA+B;IACzC,YAAY,iBAAiB;IAC7B,WAAW,iBAAiB;CAC7B;AAED,8BAAsB,gCAAgC;IACpD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,8BAA8B,CAAC;IAChE,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC;gBAGvD,WAAW,EAAE,8BAA8B,EAC3C,MAAM,EAAE,4BAA4B;IAMtC,QAAQ,KAAK,KAAK,IAAI,+BAA+B,CAAC;IACtD,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC;IAChC,QAAQ,CAAC,kBAAkB,IAAI,OAAO,CAAC,WAAW,CAAC;IAGnD,qBAAqB,CAAC,aAAa,EAAE,qBAAqB;CAG3D"}
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { ActionState } from '@finos/legend-shared';
16
+ import {} from '@finos/legend-shared';
17
17
  export var LegendDataCubeSourceBuilderType;
18
18
  (function (LegendDataCubeSourceBuilderType) {
19
19
  LegendDataCubeSourceBuilderType["LEGEND_QUERY"] = "Legend Query";
@@ -22,10 +22,13 @@ export var LegendDataCubeSourceBuilderType;
22
22
  export class LegendDataCubeSourceBuilderState {
23
23
  _application;
24
24
  _engine;
25
- buildState = ActionState.create();
26
25
  constructor(application, engine) {
27
26
  this._application = application;
28
27
  this._engine = engine;
29
28
  }
29
+ /* Modifies the configuration of the finalized DataCube query based on the source builder */
30
+ finalizeConfiguration(configuration) {
31
+ // do nothing
32
+ }
30
33
  }
31
34
  //# sourceMappingURL=LegendDataCubeSourceBuilderState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegendDataCubeSourceBuilderState.js","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAoB,MAAM,sBAAsB,CAAC;AAIrE,MAAM,CAAN,IAAY,+BAGX;AAHD,WAAY,+BAA+B;IACzC,gEAA6B,CAAA;IAC7B,+DAA4B,CAAA;AAC9B,CAAC,EAHW,+BAA+B,KAA/B,+BAA+B,QAG1C;AAED,MAAM,OAAgB,gCAAgC;IACjC,YAAY,CAAiC;IAC7C,OAAO,CAA+B;IAEhD,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;IAE3C,YACE,WAA2C,EAC3C,MAAoC;QAEpC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;CAKF"}
1
+ {"version":3,"file":"LegendDataCubeSourceBuilderState.js","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAoB,MAAM,sBAAsB,CAAC;AAKxD,MAAM,CAAN,IAAY,+BAGX;AAHD,WAAY,+BAA+B;IACzC,gEAA6B,CAAA;IAC7B,+DAA4B,CAAA;AAC9B,CAAC,EAHW,+BAA+B,KAA/B,+BAA+B,QAG1C;AAED,MAAM,OAAgB,gCAAgC;IACjC,YAAY,CAAiC;IAC7C,OAAO,CAA+B;IAEzD,YACE,WAA2C,EAC3C,MAAoC;QAEpC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAMD,4FAA4F;IAC5F,qBAAqB,CAAC,aAAoC;QACxD,aAAa;IACf,CAAC;CACF"}
@@ -18,7 +18,7 @@ import { QueryLoaderState } from '@finos/legend-query-builder';
18
18
  import { LegendDataCubeSourceBuilderState, LegendDataCubeSourceBuilderType } from './LegendDataCubeSourceBuilderState.js';
19
19
  import type { LegendDataCubeDataCubeEngine } from '../../LegendDataCubeDataCubeEngine.js';
20
20
  import type { LegendDataCubeApplicationStore } from '../../LegendDataCubeBaseStore.js';
21
- import type { DataCubeAlertService } from '@finos/legend-data-cube';
21
+ import type { DataCubeAlertService, DataCubeConfiguration } from '@finos/legend-data-cube';
22
22
  export declare class LegendQueryDataCubeSourceBuilderState extends LegendDataCubeSourceBuilderState {
23
23
  private readonly _engineServerClient;
24
24
  private readonly _graphManager;
@@ -31,6 +31,7 @@ export declare class LegendQueryDataCubeSourceBuilderState extends LegendDataCub
31
31
  unsetQuery(): void;
32
32
  get label(): LegendDataCubeSourceBuilderType;
33
33
  get isValid(): boolean;
34
- build(): Promise<import("@finos/legend-shared").PlainObject<T>>;
34
+ generateSourceData(): Promise<import("@finos/legend-shared").PlainObject<T>>;
35
+ finalizeConfiguration(configuration: DataCubeConfiguration): void;
35
36
  }
36
37
  //# sourceMappingURL=LegendQueryDataCubeSourceBuilderState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegendQueryDataCubeSourceBuilderState.d.ts","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,gBAAgB,EACjB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,gCAAgC,EAChC,+BAA+B,EAChC,MAAM,uCAAuC,CAAC;AAG/C,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,qBAAa,qCAAsC,SAAQ,gCAAgC;IACzF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IAErD,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IAEvC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAG7B,WAAW,EAAE,8BAA8B,EAC3C,MAAM,EAAE,4BAA4B,EACpC,kBAAkB,EAAE,qBAAqB,EACzC,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,oBAAoB;IAqC9B,QAAQ,CAAC,UAAU,EAAE,UAAU;IA0BrC,UAAU,IAAI,IAAI;IAKlB,IAAa,KAAK,oCAEjB;IAED,IAAa,OAAO,IAAI,OAAO,CAE9B;IAEc,KAAK;CAQrB"}
1
+ {"version":3,"file":"LegendQueryDataCubeSourceBuilderState.d.ts","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,gBAAgB,EACjB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,gCAAgC,EAChC,+BAA+B,EAChC,MAAM,uCAAuC,CAAC;AAG/C,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,qCAAsC,SAAQ,gCAAgC;IACzF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IAErD,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IAEvC,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAG7B,WAAW,EAAE,8BAA8B,EAC3C,MAAM,EAAE,4BAA4B,EACpC,kBAAkB,EAAE,qBAAqB,EACzC,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,oBAAoB;IAqC9B,QAAQ,CAAC,UAAU,EAAE,UAAU;IA0BrC,UAAU,IAAI,IAAI;IAKlB,IAAa,KAAK,oCAEjB;IAED,IAAa,OAAO,IAAI,OAAO,CAE9B;IAEc,kBAAkB;IASxB,qBAAqB,CAAC,aAAa,EAAE,qBAAqB;CAKpE"}
@@ -78,7 +78,7 @@ export class LegendQueryDataCubeSourceBuilderState extends LegendDataCubeSourceB
78
78
  get isValid() {
79
79
  return Boolean(this.query);
80
80
  }
81
- async build() {
81
+ async generateSourceData() {
82
82
  if (!this.query) {
83
83
  throw new IllegalStateError('Query is missing');
84
84
  }
@@ -86,5 +86,10 @@ export class LegendQueryDataCubeSourceBuilderState extends LegendDataCubeSourceB
86
86
  source.queryId = this.query.id;
87
87
  return RawLegendQueryDataCubeSource.serialization.toJson(source);
88
88
  }
89
+ finalizeConfiguration(configuration) {
90
+ if (this.query) {
91
+ configuration.name = this.query.name;
92
+ }
93
+ }
89
94
  }
90
95
  //# sourceMappingURL=LegendQueryDataCubeSourceBuilderState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegendQueryDataCubeSourceBuilderState.js","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LegendQueryDataCubeSourceBuilderState.js","sourceRoot":"","sources":["../../../../src/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application-data-cube",
3
- "version": "0.1.21",
3
+ "version": "0.2.1",
4
4
  "description": "Legend DataCube application core",
5
5
  "keywords": [
6
6
  "legend",
@@ -42,25 +42,26 @@
42
42
  "test:watch": "jest --watch"
43
43
  },
44
44
  "dependencies": {
45
- "@finos/legend-application": "16.0.22",
46
- "@finos/legend-art": "7.1.79",
47
- "@finos/legend-code-editor": "2.0.41",
48
- "@finos/legend-data-cube": "0.0.48",
49
- "@finos/legend-graph": "32.0.9",
50
- "@finos/legend-query-builder": "4.15.46",
51
- "@finos/legend-server-depot": "6.0.78",
52
- "@finos/legend-shared": "11.0.1",
53
- "@finos/legend-storage": "3.0.120",
45
+ "@duckdb/duckdb-wasm": "1.29.0",
46
+ "@finos/legend-application": "16.0.23",
47
+ "@finos/legend-art": "7.1.80",
48
+ "@finos/legend-code-editor": "2.0.43",
49
+ "@finos/legend-data-cube": "0.1.1",
50
+ "@finos/legend-graph": "32.1.1",
51
+ "@finos/legend-query-builder": "4.16.1",
52
+ "@finos/legend-server-depot": "6.0.79",
53
+ "@finos/legend-shared": "11.0.2",
54
+ "@finos/legend-storage": "3.0.121",
54
55
  "@types/react": "19.0.8",
55
56
  "@types/react-dom": "19.0.3",
56
- "mobx": "6.13.5",
57
+ "mobx": "6.13.6",
57
58
  "mobx-react-lite": "4.1.0",
58
59
  "react": "19.0.0",
59
60
  "react-dom": "19.0.0",
60
61
  "serializr": "3.0.3"
61
62
  },
62
63
  "devDependencies": {
63
- "@finos/legend-dev-utils": "2.1.37",
64
+ "@finos/legend-dev-utils": "2.2.0",
64
65
  "@jest/globals": "29.7.0",
65
66
  "cross-env": "7.0.3",
66
67
  "eslint": "9.19.0",
@@ -25,7 +25,7 @@ export const LEGEND_DATA_CUBE_ROUTE_PATTERN = Object.freeze({
25
25
  QUERY_BUILDER: `/:${LEGEND_DATA_CUBE_ROUTE_PATTERN_TOKEN.QUERY_ID}?`,
26
26
  });
27
27
 
28
- export type LegendDataCubeQueryBuilderQueryPathParams = {
28
+ export type LegendDataCubeQueryBuilderPathParams = {
29
29
  [LEGEND_DATA_CUBE_ROUTE_PATTERN_TOKEN.QUERY_ID]: string;
30
30
  };
31
31
 
@@ -14,11 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import {
18
- APPLICATION_EVENT,
19
- BrowserEnvironmentProvider,
20
- useApplicationStore,
21
- } from '@finos/legend-application';
17
+ import { BrowserEnvironmentProvider } from '@finos/legend-application';
22
18
  import { Route, Routes } from '@finos/legend-application/browser';
23
19
  import {
24
20
  LegendDataCubeFrameworkProvider,
@@ -27,11 +23,9 @@ import {
27
23
  import { observer } from 'mobx-react-lite';
28
24
  import { LegendDataCubeQueryBuilder } from './query-builder/LegendDataCubeQueryBuilder.js';
29
25
  import { LEGEND_DATA_CUBE_ROUTE_PATTERN } from '../__lib__/LegendDataCubeNavigation.js';
30
- import { LogEvent } from '@finos/legend-shared';
31
26
  import { useEffect } from 'react';
32
27
 
33
28
  const LegendDataCubeWebApplicationRouter = observer(() => {
34
- const application = useApplicationStore();
35
29
  const store = useLegendDataCubeBaseStore();
36
30
 
37
31
  useEffect(() => {
@@ -40,24 +34,6 @@ const LegendDataCubeWebApplicationRouter = observer(() => {
40
34
  .catch((error) => store.alertService.alertUnhandledError(error));
41
35
  }, [store]);
42
36
 
43
- useEffect(() => {
44
- application.navigationService.navigator.blockNavigation(
45
- // Only block navigation in production
46
- // eslint-disable-next-line no-process-env
47
- [() => process.env.NODE_ENV === 'production'],
48
- undefined,
49
- () => {
50
- application.logService.warn(
51
- LogEvent.create(APPLICATION_EVENT.NAVIGATION_BLOCKED),
52
- `Navigation from the application is blocked`,
53
- );
54
- },
55
- );
56
- return (): void => {
57
- application.navigationService.navigator.unblockNavigation();
58
- };
59
- }, [application]);
60
-
61
37
  return (
62
38
  <div className="h-full">
63
39
  {store.initializeState.hasSucceeded && (
@@ -29,11 +29,10 @@ import {
29
29
  import { useParams } from '@finos/legend-application/browser';
30
30
  import {
31
31
  LEGEND_DATA_CUBE_ROUTE_PATTERN_TOKEN,
32
- type LegendDataCubeQueryBuilderQueryPathParams,
32
+ type LegendDataCubeQueryBuilderPathParams,
33
33
  } from '../../__lib__/LegendDataCubeNavigation.js';
34
34
  import { useEffect } from 'react';
35
35
  import { LegendDataCubeSettingStorageKey } from '../../__lib__/LegendDataCubeSetting.js';
36
- import { assertErrorThrown, type PlainObject } from '@finos/legend-shared';
37
36
 
38
37
  const LegendDataCubeQueryBuilderHeader = observer(() => {
39
38
  const store = useLegendDataCubeQueryBuilderStore();
@@ -67,37 +66,37 @@ export const LegendDataCubeQueryBuilder = withLegendDataCubeQueryBuilderStore(
67
66
  const store = useLegendDataCubeQueryBuilderStore();
68
67
  const builder = store.builder;
69
68
  const application = store.application;
70
- const params = useParams<LegendDataCubeQueryBuilderQueryPathParams>();
69
+ const params = useParams<LegendDataCubeQueryBuilderPathParams>();
71
70
  const queryId = params[LEGEND_DATA_CUBE_ROUTE_PATTERN_TOKEN.QUERY_ID];
72
- const sourceData =
73
- application.navigationService.navigator.getCurrentLocationParameterValue(
74
- LEGEND_DATA_CUBE_ROUTE_PATTERN_TOKEN.SOURCE_DATA,
71
+
72
+ useEffect(() => {
73
+ application.navigationService.navigator.blockNavigation(
74
+ // Only block navigation in production, in development, we should have
75
+ // the flexibility to reload the page quickly
76
+ // eslint-disable-next-line no-process-env
77
+ [() => process.env.NODE_ENV === 'production'],
75
78
  );
79
+ return (): void => {
80
+ application.navigationService.navigator.unblockNavigation();
81
+ };
82
+ }, [application]);
76
83
 
77
84
  useEffect(() => {
78
- if (sourceData) {
79
- try {
80
- const sourceDataJson = JSON.parse(
81
- decodeURIComponent(atob(sourceData)),
82
- ) as PlainObject;
83
- store.newQueryState
84
- .finalize(sourceDataJson)
85
- .catch((error) => store.alertService.alertUnhandledError(error));
86
- } catch (error) {
87
- assertErrorThrown(error);
88
- }
89
- } else if (queryId !== store.builder?.persistentQuery?.id) {
90
- store
91
- .loadQuery(queryId)
92
- .catch((error) => store.alertService.alertUnhandledError(error));
93
- }
94
- }, [store, queryId, sourceData]);
85
+ store
86
+ .loadQuery(queryId)
87
+ .catch((error) => store.alertService.alertUnhandledError(error));
88
+ }, [store, queryId]);
95
89
 
96
90
  useEffect(() => {
97
- if (!store.builder && !queryId && !sourceData) {
98
- store.loader.display.open();
99
- }
100
- }, [store, queryId, sourceData]);
91
+ store.engine
92
+ .initializeCacheManager()
93
+ .catch((error) => store.alertService.alertUnhandledError(error));
94
+ return () => {
95
+ store.engine
96
+ .disposeCacheManager()
97
+ .catch((error) => store.alertService.alertUnhandledError(error));
98
+ };
99
+ }, [store]);
101
100
 
102
101
  if (!builder) {
103
102
  return (
@@ -157,6 +156,7 @@ export const LegendDataCubeQueryBuilder = withLegendDataCubeQueryBuilderStore(
157
156
  );
158
157
  },
159
158
  documentationUrl: application.documentationService.url,
159
+ enableCache: true,
160
160
  }}
161
161
  />
162
162
  );
@@ -41,6 +41,7 @@ import {
41
41
  } from '@finos/legend-data-cube';
42
42
  import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
43
43
  import { useLegendDataCubeQueryBuilderStore } from '../LegendDataCubeQueryBuilderStoreProvider.js';
44
+ import { useApplicationStore } from '@finos/legend-application';
44
45
 
45
46
  const LegendQuerySearcher = observer((props: { state: QueryLoaderState }) => {
46
47
  const { state } = props;
@@ -252,6 +253,8 @@ const LegendQuerySearcher = observer((props: { state: QueryLoaderState }) => {
252
253
  export const LegendQueryDataCubeSourceBuilder = observer(
253
254
  (props: { sourceBuilder: LegendQueryDataCubeSourceBuilderState }) => {
254
255
  const { sourceBuilder } = props;
256
+ const application = useApplicationStore();
257
+ const store = useLegendDataCubeQueryBuilderStore();
255
258
  const query = sourceBuilder.query;
256
259
 
257
260
  if (!query) {
@@ -259,11 +262,24 @@ export const LegendQueryDataCubeSourceBuilder = observer(
259
262
  }
260
263
  return (
261
264
  <div className="h-full">
262
- <div className="mb-0.5 flex h-[60px] w-full border border-neutral-200 bg-neutral-100">
265
+ <div className="relative mb-0.5 flex h-[60px] w-full border border-neutral-200 bg-neutral-100">
263
266
  <div className="w-full">
264
267
  <div className="h-6 w-4/5 overflow-hidden text-ellipsis whitespace-nowrap px-1.5 leading-6">
265
268
  {query.name}
266
269
  </div>
270
+ <button
271
+ className="absolute right-1 top-1 flex aspect-square w-5 items-center justify-center text-neutral-500"
272
+ title="Copy ID to clipboard"
273
+ onClick={() => {
274
+ application.clipboardService
275
+ .copyTextToClipboard(query.id)
276
+ .catch((error) =>
277
+ store.alertService.alertUnhandledError(error),
278
+ );
279
+ }}
280
+ >
281
+ <DataCubeIcon.Clipboard />
282
+ </button>
267
283
  <div className="flex h-[18px] items-start justify-between px-1.5 text-sm text-neutral-500">
268
284
  {`[ ${generateGAVCoordinates(
269
285
  query.groupId,
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ declare module '*.wasm' {
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ const value: any;
20
+ // eslint-disable-next-line import/no-default-export
21
+ export default value;
22
+ }
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import * as duckdb from '@duckdb/duckdb-wasm';
18
+ import duckdb_wasm from '@duckdb/duckdb-wasm/dist/duckdb-mvp.wasm';
19
+ import duckdb_wasm_next from '@duckdb/duckdb-wasm/dist/duckdb-eh.wasm';
20
+ import {
21
+ PRIMITIVE_TYPE,
22
+ TDSExecutionResult,
23
+ TDSRow,
24
+ TabularDataSet,
25
+ } from '@finos/legend-graph';
26
+ import { assertNonNullable, guaranteeNonNullable } from '@finos/legend-shared';
27
+ import type { CachedDataCubeSource } from '@finos/legend-data-cube';
28
+
29
+ export class LegendDataCubeDataCubeCacheManager {
30
+ private static readonly DUCKDB_DEFAULT_SCHEMA_NAME = 'main'; // See https://duckdb.org/docs/sql/statements/use.html
31
+ private static readonly TABLE_NAME_PREFIX = 'cache';
32
+ private static tableCounter = 0;
33
+
34
+ private _database?: duckdb.AsyncDuckDB | undefined;
35
+
36
+ private get database(): duckdb.AsyncDuckDB {
37
+ return guaranteeNonNullable(
38
+ this._database,
39
+ `Cache manager database not initialized`,
40
+ );
41
+ }
42
+
43
+ async initialize() {
44
+ // Initialize DuckDB with WASM
45
+ // See: https://duckdb.org/docs/api/wasm/instantiation.html
46
+ const MANUAL_BUNDLES: duckdb.DuckDBBundles = {
47
+ mvp: {
48
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
49
+ mainModule: duckdb_wasm,
50
+ mainWorker: new URL(
51
+ '@duckdb/duckdb-wasm/dist/duckdb-browser-mvp.worker.js',
52
+ import.meta.url,
53
+ ).toString(),
54
+ },
55
+ eh: {
56
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
57
+ mainModule: duckdb_wasm_next,
58
+ mainWorker: new URL(
59
+ '@duckdb/duckdb-wasm/dist/duckdb-browser-eh.worker.js',
60
+ import.meta.url,
61
+ ).toString(),
62
+ },
63
+ };
64
+ // Select a bundle based on browser checks
65
+ const bundle = await duckdb.selectBundle(MANUAL_BUNDLES);
66
+ // Instantiate the asynchronus version of DuckDB-wasm
67
+ assertNonNullable(
68
+ bundle.mainWorker,
69
+ `Can't initialize cache manager: DuckDB main worker not initialized`,
70
+ );
71
+ const worker = new Worker(bundle.mainWorker);
72
+ const logger = new duckdb.ConsoleLogger();
73
+ const database = new duckdb.AsyncDuckDB(logger, worker);
74
+ await database.instantiate(bundle.mainModule, bundle.pthreadWorker);
75
+ this._database = database;
76
+ }
77
+
78
+ async cache(result: TDSExecutionResult) {
79
+ const schema =
80
+ LegendDataCubeDataCubeCacheManager.DUCKDB_DEFAULT_SCHEMA_NAME;
81
+ LegendDataCubeDataCubeCacheManager.tableCounter += 1;
82
+ const table = `${LegendDataCubeDataCubeCacheManager.TABLE_NAME_PREFIX}${LegendDataCubeDataCubeCacheManager.tableCounter}`;
83
+
84
+ const connection = await this.database.connect();
85
+
86
+ // TODO: review if we can improve performance here using CSV/Arrow for ingestion
87
+ const columns: string[] = [];
88
+ result.builder.columns.forEach((col) => {
89
+ let colType: string;
90
+ switch (col.type as string) {
91
+ case PRIMITIVE_TYPE.BOOLEAN: {
92
+ colType = 'BOOLEAN';
93
+ break;
94
+ }
95
+ case PRIMITIVE_TYPE.NUMBER: {
96
+ colType = 'DOUBLE';
97
+ break;
98
+ }
99
+ case PRIMITIVE_TYPE.INTEGER: {
100
+ colType = 'INTEGER';
101
+ break;
102
+ }
103
+ case PRIMITIVE_TYPE.DATE: {
104
+ colType = 'TIMESTAMP';
105
+ break;
106
+ }
107
+ case PRIMITIVE_TYPE.STRING:
108
+ default: {
109
+ colType = 'VARCHAR';
110
+ }
111
+ }
112
+ columns.push(`"${col.name}" ${colType}`);
113
+ });
114
+
115
+ const CREATE_TABLE_SQL = `CREATE TABLE ${schema}.${table} (${columns.join(',')})`;
116
+ await connection.query(CREATE_TABLE_SQL);
117
+
118
+ const rowString: string[] = [];
119
+
120
+ result.result.rows.forEach((row) => {
121
+ const updatedRows = row.values.map((val) => {
122
+ if (val !== null && typeof val === 'string') {
123
+ return `'${val.replaceAll(`'`, `''`)}'`;
124
+ } else if (val === null) {
125
+ return `NULL`;
126
+ }
127
+ return val;
128
+ });
129
+ rowString.push(`(${updatedRows.join(',')})`);
130
+ });
131
+
132
+ const INSERT_TABLE_SQL = `INSERT INTO ${schema}.${table} VALUES ${rowString.join(',')}`;
133
+
134
+ await connection.query(INSERT_TABLE_SQL);
135
+ await connection.close();
136
+
137
+ return { table, schema, rowCount: result.result.rows.length };
138
+ }
139
+
140
+ async runSQLQuery(sql: string) {
141
+ const connection = await this.database.connect();
142
+ const result = (await connection.query(sql)).toArray();
143
+ const columnNames = Object.keys(result.at(0));
144
+ const rows = result.map((row) => {
145
+ const values = new TDSRow();
146
+ values.values = columnNames.map(
147
+ (column) => row[column] as string | number | boolean | null,
148
+ );
149
+ return values;
150
+ });
151
+ const tdsExecutionResult = new TDSExecutionResult();
152
+ const tds = new TabularDataSet();
153
+ tds.columns = columnNames;
154
+ tds.rows = rows;
155
+ tdsExecutionResult.result = tds;
156
+ return tdsExecutionResult;
157
+ }
158
+
159
+ async disposeCache(source: CachedDataCubeSource) {
160
+ const connection = await this.database.connect();
161
+ const DROP_TABLE_SQL = `DROP TABLE IF EXISTS "${source.schema}.${source.table}"`;
162
+ await connection.query(DROP_TABLE_SQL);
163
+ await connection.close();
164
+ }
165
+
166
+ async dispose() {
167
+ await this._database?.flushFiles();
168
+ await this._database?.terminate();
169
+ }
170
+ }