@finos/legend-application-repl 0.0.8 → 0.0.10

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 (47) hide show
  1. package/lib/Const.d.ts +11 -5
  2. package/lib/Const.d.ts.map +1 -1
  3. package/lib/Const.js +13 -5
  4. package/lib/Const.js.map +1 -1
  5. package/lib/components/REPLGridClient.d.ts.map +1 -1
  6. package/lib/components/REPLGridClient.js +21 -10
  7. package/lib/components/REPLGridClient.js.map +1 -1
  8. package/lib/components/REPLQueryEditor.d.ts +29 -0
  9. package/lib/components/REPLQueryEditor.d.ts.map +1 -0
  10. package/lib/components/REPLQueryEditor.js +143 -0
  11. package/lib/components/REPLQueryEditor.js.map +1 -0
  12. package/lib/components/grid/TDSLambdaBuilder.d.ts +1 -1
  13. package/lib/components/grid/TDSLambdaBuilder.d.ts.map +1 -1
  14. package/lib/components/grid/TDSLambdaBuilder.js +38 -15
  15. package/lib/components/grid/TDSLambdaBuilder.js.map +1 -1
  16. package/lib/grid.css +1 -1
  17. package/lib/index.css +2 -2
  18. package/lib/index.css.map +1 -1
  19. package/lib/package.json +2 -1
  20. package/lib/repl.css +2 -2
  21. package/lib/repl.css.map +1 -1
  22. package/lib/server/REPLServerClient.d.ts +5 -1
  23. package/lib/server/REPLServerClient.d.ts.map +1 -1
  24. package/lib/server/REPLServerClient.js +8 -1
  25. package/lib/server/REPLServerClient.js.map +1 -1
  26. package/lib/stores/CompletionResult.d.ts +22 -0
  27. package/lib/stores/CompletionResult.d.ts.map +1 -0
  28. package/lib/stores/CompletionResult.js +26 -0
  29. package/lib/stores/CompletionResult.js.map +1 -0
  30. package/lib/stores/REPLGridClientStore.d.ts +6 -1
  31. package/lib/stores/REPLGridClientStore.d.ts.map +1 -1
  32. package/lib/stores/REPLGridClientStore.js +85 -11
  33. package/lib/stores/REPLGridClientStore.js.map +1 -1
  34. package/lib/stores/REPLGridState.d.ts +5 -3
  35. package/lib/stores/REPLGridState.d.ts.map +1 -1
  36. package/lib/stores/REPLGridState.js +12 -7
  37. package/lib/stores/REPLGridState.js.map +1 -1
  38. package/package.json +5 -4
  39. package/src/Const.ts +12 -5
  40. package/src/components/REPLGridClient.tsx +129 -59
  41. package/src/components/REPLQueryEditor.tsx +205 -0
  42. package/src/components/grid/TDSLambdaBuilder.ts +40 -21
  43. package/src/server/REPLServerClient.ts +35 -5
  44. package/src/stores/CompletionResult.ts +30 -0
  45. package/src/stores/REPLGridClientStore.ts +140 -9
  46. package/src/stores/REPLGridState.ts +14 -8
  47. package/tsconfig.json +3 -1
@@ -24,11 +24,17 @@ import {
24
24
  LogEvent,
25
25
  guaranteeNonNullable,
26
26
  guaranteeType,
27
+ ActionState,
28
+ HttpStatus,
29
+ NetworkClientError,
27
30
  } from '@finos/legend-shared';
28
31
  import type { TDSRequest } from '../components/grid/TDSRequest.js';
29
32
  import { flow, flowResult, makeObservable, observable } from 'mobx';
30
33
  import { REPLGridServerResult } from '../components/grid/REPLGridServerResult.js';
31
- import { LEGEND_REPL_EVENT } from '../Const.js';
34
+ import {
35
+ LEGEND_APPLICATION_REPL_SETTING_KEY,
36
+ LEGEND_REPL_EVENT,
37
+ } from '../Const.js';
32
38
  import { REPLGridState } from './REPLGridState.js';
33
39
  import { buildLambdaExpressions } from '../components/grid/TDSLambdaBuilder.js';
34
40
  import {
@@ -39,20 +45,33 @@ import {
39
45
  V1_deserializeValueSpecification,
40
46
  V1_serializeExecutionResult,
41
47
  V1_serializeValueSpecification,
48
+ V1_ParserError,
49
+ ParserError,
50
+ SourceInformation,
42
51
  } from '@finos/legend-graph';
52
+ import { CompletionItem } from './CompletionResult.js';
53
+ import {
54
+ languages as monacoLanguagesAPI,
55
+ type IPosition,
56
+ type editor as monacoEditorAPI,
57
+ } from 'monaco-editor';
43
58
 
44
59
  export class REPLGridClientStore {
45
60
  readonly applicationStore: LegendREPLGridClientApplicationStore;
46
61
  readonly client: REPLServerClient;
47
62
  replGridState!: REPLGridState;
63
+ executeAction = ActionState.create();
48
64
 
49
65
  constructor(applicationStore: LegendREPLGridClientApplicationStore) {
50
66
  makeObservable(this, {
51
67
  replGridState: observable,
68
+ executeAction: observable,
52
69
  getREPLGridServerResult: flow,
53
70
  getInitialQueryLambda: flow,
54
71
  getInitialREPLGridServerResult: flow,
55
72
  getLicenseKey: flow,
73
+ executeLambda: flow,
74
+ parseQuery: flow,
56
75
  });
57
76
  this.applicationStore = applicationStore;
58
77
  this.client = new REPLServerClient(
@@ -62,7 +81,11 @@ export class REPLGridClientStore {
62
81
  : this.applicationStore.config.replUrl,
63
82
  }),
64
83
  );
65
- this.replGridState = new REPLGridState();
84
+ const isPaginationEnabled =
85
+ applicationStore.settingService.getBooleanValue(
86
+ LEGEND_APPLICATION_REPL_SETTING_KEY.PAGINATION,
87
+ ) ?? true;
88
+ this.replGridState = new REPLGridState(isPaginationEnabled);
66
89
  }
67
90
 
68
91
  *getREPLGridServerResult(tdsRequest: TDSRequest): GeneratorFn<void> {
@@ -71,6 +94,7 @@ export class REPLGridClientStore {
71
94
  const lambda = buildLambdaExpressions(
72
95
  guaranteeNonNullable(this.replGridState.initialQueryLambda?.body[0]),
73
96
  tdsRequest,
97
+ this.replGridState.isPaginationEnabled,
74
98
  );
75
99
  const resultObj = (yield flowResult(
76
100
  this.client.getREPLGridServerResult(
@@ -91,7 +115,9 @@ export class REPLGridClientStore {
91
115
  if (isSubQuery) {
92
116
  this.replGridState.setCurrentSubQuery(replGridResult.currentQuery);
93
117
  } else {
94
- this.replGridState.setCurrentQuery(replGridResult.currentQuery);
118
+ this.replGridState.queryEditorState.setQuery(
119
+ replGridResult.currentQuery.substring(1),
120
+ );
95
121
  this.replGridState.setCurrentSubQuery(undefined);
96
122
  }
97
123
  } catch (error) {
@@ -104,6 +130,105 @@ export class REPLGridClientStore {
104
130
  }
105
131
  }
106
132
 
133
+ async getTypeaheadResults(
134
+ position: IPosition,
135
+ model: monacoEditorAPI.ITextModel,
136
+ ): Promise<monacoLanguagesAPI.CompletionItem[]> {
137
+ try {
138
+ const textUntilPosition = model.getValueInRange({
139
+ startLineNumber: 1,
140
+ startColumn: 1,
141
+ endLineNumber: position.lineNumber,
142
+ endColumn: position.column,
143
+ });
144
+ const resultObj =
145
+ await this.client.getTypeaheadResults(textUntilPosition);
146
+ const result = resultObj.map((res) =>
147
+ CompletionItem.serialization.fromJson(res),
148
+ );
149
+ const currentWord = model.getWordUntilPosition(position);
150
+ return result.map((res) => ({
151
+ label: res.display,
152
+ kind: monacoLanguagesAPI.CompletionItemKind.Text,
153
+ range: {
154
+ startLineNumber: position.lineNumber,
155
+ startColumn: currentWord.startColumn + 1,
156
+ endLineNumber: position.lineNumber,
157
+ endColumn: currentWord.endColumn + 1,
158
+ },
159
+ insertText: res.completion,
160
+ })) as monacoLanguagesAPI.CompletionItem[];
161
+ } catch (e) {
162
+ return [];
163
+ }
164
+ }
165
+
166
+ *executeLambda(): GeneratorFn<void> {
167
+ try {
168
+ this.executeAction.inProgress();
169
+ const resultObj = (yield this.client.executeLambda(
170
+ this.replGridState.queryEditorState.query,
171
+ this.replGridState.isPaginationEnabled,
172
+ )) as PlainObject<REPLGridServerResult>;
173
+ const replGridResult =
174
+ REPLGridServerResult.serialization.fromJson(resultObj);
175
+ const tdsResultObj = JSON.parse(
176
+ replGridResult.result,
177
+ ) as PlainObject<V1_TDSExecutionResult>;
178
+ const tdsResult = guaranteeType(
179
+ V1_buildExecutionResult(V1_serializeExecutionResult(tdsResultObj)),
180
+ TDSExecutionResult,
181
+ );
182
+ this.replGridState.setInitialResult(tdsResult);
183
+ this.replGridState.queryEditorState.setQuery(
184
+ replGridResult.currentQuery.substring(1),
185
+ );
186
+ this.replGridState.setCurrentSubQuery(undefined);
187
+ this.replGridState.setColumns(tdsResult.result.columns);
188
+
189
+ yield flowResult(this.getInitialQueryLambda());
190
+ this.executeAction.complete();
191
+ } catch (error) {
192
+ this.executeAction.fail();
193
+ assertErrorThrown(error);
194
+ this.applicationStore.notificationService.notifyError(error);
195
+ this.applicationStore.logService.error(
196
+ LogEvent.create(LEGEND_REPL_EVENT.FETCH_TDS_FAILURE),
197
+ error,
198
+ );
199
+ }
200
+ }
201
+
202
+ *parseQuery(): GeneratorFn<void> {
203
+ try {
204
+ this.replGridState.queryEditorState.setParserError(undefined);
205
+ yield flowResult(
206
+ this.client.parseQuery(`|${this.replGridState.queryEditorState.query}`),
207
+ );
208
+ } catch (error) {
209
+ assertErrorThrown(error);
210
+ if (
211
+ error instanceof NetworkClientError &&
212
+ error.response.status === HttpStatus.BAD_REQUEST
213
+ ) {
214
+ const protocol = V1_ParserError.serialization.fromJson(
215
+ error.payload as PlainObject<V1_ParserError>,
216
+ );
217
+ const parserError = new ParserError(protocol.message);
218
+ if (protocol.sourceInformation) {
219
+ parserError.sourceInformation = new SourceInformation(
220
+ protocol.sourceInformation.sourceId,
221
+ protocol.sourceInformation.startLine,
222
+ protocol.sourceInformation.startColumn,
223
+ protocol.sourceInformation.endLine,
224
+ protocol.sourceInformation.endColumn,
225
+ );
226
+ }
227
+ this.replGridState.queryEditorState.setParserError(parserError);
228
+ }
229
+ }
230
+ }
231
+
107
232
  *getInitialQueryLambda(): GeneratorFn<void> {
108
233
  const lambdaObj =
109
234
  (yield this.client.getIntialQueryLambda()) as PlainObject<V1_Lambda>;
@@ -115,14 +240,16 @@ export class REPLGridClientStore {
115
240
 
116
241
  *getInitialREPLGridServerResult(): GeneratorFn<void> {
117
242
  try {
243
+ this.executeAction.inProgress();
118
244
  if (!this.replGridState.licenseKey) {
119
245
  yield flowResult(this.getLicenseKey());
120
246
  }
121
- if (!this.replGridState.initialQueryLambda) {
122
- yield flowResult(this.getInitialQueryLambda());
123
- }
124
- const resultObj =
125
- (yield this.client.getInitialREPLGridServerResult()) as PlainObject<REPLGridServerResult>;
247
+
248
+ yield flowResult(this.getInitialQueryLambda());
249
+
250
+ const resultObj = (yield this.client.getInitialREPLGridServerResult(
251
+ this.replGridState.isPaginationEnabled,
252
+ )) as PlainObject<REPLGridServerResult>;
126
253
  const replGridResult =
127
254
  REPLGridServerResult.serialization.fromJson(resultObj);
128
255
  const tdsResultObj = JSON.parse(
@@ -133,10 +260,14 @@ export class REPLGridClientStore {
133
260
  TDSExecutionResult,
134
261
  );
135
262
  this.replGridState.setInitialResult(tdsResult);
136
- this.replGridState.setCurrentQuery(replGridResult.currentQuery);
263
+ this.replGridState.queryEditorState.setQuery(
264
+ replGridResult.currentQuery.substring(1),
265
+ );
137
266
  this.replGridState.setCurrentSubQuery(undefined);
138
267
  this.replGridState.setColumns(tdsResult.result.columns);
268
+ this.executeAction.complete();
139
269
  } catch (error) {
270
+ this.executeAction.fail();
140
271
  assertErrorThrown(error);
141
272
  this.applicationStore.notificationService.notifyError(error);
142
273
  this.applicationStore.logService.error(
@@ -23,45 +23,47 @@ import {
23
23
  import { action, computed, makeObservable, observable } from 'mobx';
24
24
  import type { ColDef } from '@ag-grid-community/core';
25
25
  import type { V1_Lambda, TDSExecutionResult } from '@finos/legend-graph';
26
+ import { QueryEditorState } from '../components/REPLQueryEditor.js';
26
27
 
27
28
  export class REPLGridState {
28
29
  initialResult?: TDSExecutionResult | undefined;
29
30
  currentResult?: TDSExecutionResult | undefined;
30
31
  columns?: string[] | undefined;
31
- currentQuery?: string | undefined;
32
+ queryEditorState: QueryEditorState;
32
33
  currentSubQuery?: string | undefined;
33
34
  licenseKey?: string | undefined;
34
35
  initialQueryLambda?: V1_Lambda | undefined;
36
+ isPaginationEnabled!: boolean;
35
37
 
36
- constructor() {
38
+ constructor(isPaginationEnabled: boolean) {
37
39
  makeObservable(this, {
38
40
  initialResult: observable,
39
41
  initialQueryLambda: observable,
40
42
  currentResult: observable,
41
- currentQuery: observable,
42
43
  currentSubQuery: observable,
43
44
  licenseKey: observable,
44
45
  columns: observable,
46
+ isPaginationEnabled: observable,
47
+ queryEditorState: observable,
45
48
  setInitialResult: action,
46
- setCurrentQuery: action,
47
49
  setCurrentSubQuery: action,
48
50
  setColumns: action,
49
51
  setInitialQueryLambda: action,
50
52
  setCurrentResult: action,
51
53
  setLicenseKey: action,
54
+ setIsPaginationEnabled: action,
52
55
  rowData: computed,
53
56
  columnDefs: computed,
54
57
  });
58
+
59
+ this.queryEditorState = new QueryEditorState('');
60
+ this.isPaginationEnabled = isPaginationEnabled;
55
61
  }
56
62
 
57
63
  setInitialQueryLambda(val: V1_Lambda | undefined): void {
58
64
  this.initialQueryLambda = val;
59
65
  }
60
66
 
61
- setCurrentQuery(val: string | undefined): void {
62
- this.currentQuery = val;
63
- }
64
-
65
67
  setCurrentSubQuery(val: string | undefined): void {
66
68
  this.currentSubQuery = val;
67
69
  }
@@ -82,6 +84,10 @@ export class REPLGridState {
82
84
  this.licenseKey = val;
83
85
  }
84
86
 
87
+ setIsPaginationEnabled(val: boolean): void {
88
+ this.isPaginationEnabled = val;
89
+ }
90
+
85
91
  get rowData(): TDSRowDataType[] {
86
92
  return this.initialResult ? getTDSRowData(this.initialResult.result) : [];
87
93
  }
package/tsconfig.json CHANGED
@@ -41,6 +41,7 @@
41
41
  "./src/components/grid/TDSLambdaBuilder.ts",
42
42
  "./src/components/grid/TDSRequest.ts",
43
43
  "./src/server/REPLServerClient.ts",
44
+ "./src/stores/CompletionResult.ts",
44
45
  "./src/stores/LegendREPLGridClientApplicationPlugin.ts",
45
46
  "./src/stores/LegendREPLGridClientBaseStore.ts",
46
47
  "./src/stores/REPLGridClientStore.ts",
@@ -52,7 +53,8 @@
52
53
  "./src/components/LegendREPLGridClientApplication.tsx",
53
54
  "./src/components/LegendREPLGridClientFrameworkProvider.tsx",
54
55
  "./src/components/REPLGridClient.tsx",
55
- "./src/components/REPLGridClientStoreProvider.tsx"
56
+ "./src/components/REPLGridClientStoreProvider.tsx",
57
+ "./src/components/REPLQueryEditor.tsx"
56
58
  ],
57
59
  "include": [
58
60
  "src/**/*.ts",