aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/xtext
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-12 21:59:50 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-12 21:59:50 +0200
commita2a4696fdbd6440269d576aeba7b25b2ea40d9bf (patch)
tree5cbdf981a51a09fbe162e7748555d213ca518ff4 /subprojects/frontend/src/xtext
parentfix: avoid GLOP error message on stderr (diff)
downloadrefinery-a2a4696fdbd6440269d576aeba7b25b2ea40d9bf.tar.gz
refinery-a2a4696fdbd6440269d576aeba7b25b2ea40d9bf.tar.zst
refinery-a2a4696fdbd6440269d576aeba7b25b2ea40d9bf.zip
feat: connect model generator to UI
Diffstat (limited to 'subprojects/frontend/src/xtext')
-rw-r--r--subprojects/frontend/src/xtext/ModelGenerationService.ts46
-rw-r--r--subprojects/frontend/src/xtext/UpdateService.ts39
-rw-r--r--subprojects/frontend/src/xtext/XtextClient.ts21
-rw-r--r--subprojects/frontend/src/xtext/xtextMessages.ts1
-rw-r--r--subprojects/frontend/src/xtext/xtextServiceResults.ts24
5 files changed, 130 insertions, 1 deletions
diff --git a/subprojects/frontend/src/xtext/ModelGenerationService.ts b/subprojects/frontend/src/xtext/ModelGenerationService.ts
new file mode 100644
index 00000000..1e9f837a
--- /dev/null
+++ b/subprojects/frontend/src/xtext/ModelGenerationService.ts
@@ -0,0 +1,46 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6
7import type EditorStore from '../editor/EditorStore';
8
9import type UpdateService from './UpdateService';
10import { ModelGenerationResult } from './xtextServiceResults';
11
12export default class ModelGenerationService {
13 constructor(
14 private readonly store: EditorStore,
15 private readonly updateService: UpdateService,
16 ) {}
17
18 onPush(push: unknown): void {
19 const result = ModelGenerationResult.parse(push);
20 if ('status' in result) {
21 this.store.setGeneratedModelMessage(result.uuid, result.status);
22 } else if ('error' in result) {
23 this.store.setGeneratedModelError(result.uuid, result.error);
24 } else {
25 this.store.setGeneratedModelSemantics(result.uuid, result);
26 }
27 }
28
29 onDisconnect(): void {
30 this.store.modelGenerationCancelled();
31 }
32
33 async start(): Promise<void> {
34 const result = await this.updateService.startModelGeneration();
35 if (!result.cancelled) {
36 this.store.addGeneratedModel(result.data.uuid);
37 }
38 }
39
40 async cancel(): Promise<void> {
41 const result = await this.updateService.cancelModelGeneration();
42 if (!result.cancelled) {
43 this.store.modelGenerationCancelled();
44 }
45 }
46}
diff --git a/subprojects/frontend/src/xtext/UpdateService.ts b/subprojects/frontend/src/xtext/UpdateService.ts
index 1ac722e1..d1246d5e 100644
--- a/subprojects/frontend/src/xtext/UpdateService.ts
+++ b/subprojects/frontend/src/xtext/UpdateService.ts
@@ -22,6 +22,7 @@ import {
22 FormattingResult, 22 FormattingResult,
23 isConflictResult, 23 isConflictResult,
24 OccurrencesResult, 24 OccurrencesResult,
25 ModelGenerationStartedResult,
25} from './xtextServiceResults'; 26} from './xtextServiceResults';
26 27
27const UPDATE_TIMEOUT_MS = 500; 28const UPDATE_TIMEOUT_MS = 500;
@@ -341,4 +342,42 @@ export default class UpdateService {
341 } 342 }
342 return { cancelled: false, data: parsedOccurrencesResult }; 343 return { cancelled: false, data: parsedOccurrencesResult };
343 } 344 }
345
346 async startModelGeneration(): Promise<
347 CancellableResult<ModelGenerationStartedResult>
348 > {
349 try {
350 await this.updateOrThrow();
351 } catch (error) {
352 if (error instanceof CancelledError || error instanceof TimeoutError) {
353 return { cancelled: true };
354 }
355 throw error;
356 }
357 log.debug('Starting model generation');
358 const data = await this.webSocketClient.send({
359 resource: this.resourceName,
360 serviceType: 'modelGeneration',
361 requiredStateId: this.xtextStateId,
362 start: true,
363 });
364 if (isConflictResult(data)) {
365 return { cancelled: true };
366 }
367 const parsedResult = ModelGenerationStartedResult.parse(data);
368 return { cancelled: false, data: parsedResult };
369 }
370
371 async cancelModelGeneration(): Promise<CancellableResult<unknown>> {
372 log.debug('Cancelling model generation');
373 const data = await this.webSocketClient.send({
374 resource: this.resourceName,
375 serviceType: 'modelGeneration',
376 cancel: true,
377 });
378 if (isConflictResult(data)) {
379 return { cancelled: true };
380 }
381 return { cancelled: false, data };
382 }
344} 383}
diff --git a/subprojects/frontend/src/xtext/XtextClient.ts b/subprojects/frontend/src/xtext/XtextClient.ts
index 87778084..77980d35 100644
--- a/subprojects/frontend/src/xtext/XtextClient.ts
+++ b/subprojects/frontend/src/xtext/XtextClient.ts
@@ -16,6 +16,7 @@ import getLogger from '../utils/getLogger';
16 16
17import ContentAssistService from './ContentAssistService'; 17import ContentAssistService from './ContentAssistService';
18import HighlightingService from './HighlightingService'; 18import HighlightingService from './HighlightingService';
19import ModelGenerationService from './ModelGenerationService';
19import OccurrencesService from './OccurrencesService'; 20import OccurrencesService from './OccurrencesService';
20import SemanticsService from './SemanticsService'; 21import SemanticsService from './SemanticsService';
21import UpdateService from './UpdateService'; 22import UpdateService from './UpdateService';
@@ -40,6 +41,8 @@ export default class XtextClient {
40 41
41 private readonly semanticsService: SemanticsService; 42 private readonly semanticsService: SemanticsService;
42 43
44 private readonly modelGenerationService: ModelGenerationService;
45
43 constructor( 46 constructor(
44 private readonly store: EditorStore, 47 private readonly store: EditorStore,
45 private readonly pwaStore: PWAStore, 48 private readonly pwaStore: PWAStore,
@@ -58,6 +61,10 @@ export default class XtextClient {
58 this.validationService = new ValidationService(store, this.updateService); 61 this.validationService = new ValidationService(store, this.updateService);
59 this.occurrencesService = new OccurrencesService(store, this.updateService); 62 this.occurrencesService = new OccurrencesService(store, this.updateService);
60 this.semanticsService = new SemanticsService(store, this.validationService); 63 this.semanticsService = new SemanticsService(store, this.validationService);
64 this.modelGenerationService = new ModelGenerationService(
65 store,
66 this.updateService,
67 );
61 } 68 }
62 69
63 start(): void { 70 start(): void {
@@ -75,6 +82,7 @@ export default class XtextClient {
75 this.highlightingService.onDisconnect(); 82 this.highlightingService.onDisconnect();
76 this.validationService.onDisconnect(); 83 this.validationService.onDisconnect();
77 this.occurrencesService.onDisconnect(); 84 this.occurrencesService.onDisconnect();
85 this.modelGenerationService.onDisconnect();
78 } 86 }
79 87
80 onTransaction(transaction: Transaction): void { 88 onTransaction(transaction: Transaction): void {
@@ -101,7 +109,7 @@ export default class XtextClient {
101 ); 109 );
102 return; 110 return;
103 } 111 }
104 if (stateId !== xtextStateId) { 112 if (stateId !== xtextStateId && service !== 'modelGeneration') {
105 log.error( 113 log.error(
106 'Unexpected xtext state id: expected:', 114 'Unexpected xtext state id: expected:',
107 xtextStateId, 115 xtextStateId,
@@ -122,6 +130,9 @@ export default class XtextClient {
122 case 'semantics': 130 case 'semantics':
123 this.semanticsService.onPush(push); 131 this.semanticsService.onPush(push);
124 return; 132 return;
133 case 'modelGeneration':
134 this.modelGenerationService.onPush(push);
135 return;
125 default: 136 default:
126 throw new Error('Unknown service'); 137 throw new Error('Unknown service');
127 } 138 }
@@ -131,6 +142,14 @@ export default class XtextClient {
131 return this.contentAssistService.contentAssist(context); 142 return this.contentAssistService.contentAssist(context);
132 } 143 }
133 144
145 startModelGeneration(): Promise<void> {
146 return this.modelGenerationService.start();
147 }
148
149 cancelModelGeneration(): Promise<void> {
150 return this.modelGenerationService.cancel();
151 }
152
134 formatText(): void { 153 formatText(): void {
135 this.updateService.formatText().catch((e) => { 154 this.updateService.formatText().catch((e) => {
136 log.error('Error while formatting text', e); 155 log.error('Error while formatting text', e);
diff --git a/subprojects/frontend/src/xtext/xtextMessages.ts b/subprojects/frontend/src/xtext/xtextMessages.ts
index 971720e1..15831c5a 100644
--- a/subprojects/frontend/src/xtext/xtextMessages.ts
+++ b/subprojects/frontend/src/xtext/xtextMessages.ts
@@ -38,6 +38,7 @@ export const XtextWebPushService = z.enum([
38 'highlight', 38 'highlight',
39 'validate', 39 'validate',
40 'semantics', 40 'semantics',
41 'modelGeneration',
41]); 42]);
42 43
43export type XtextWebPushService = z.infer<typeof XtextWebPushService>; 44export type XtextWebPushService = z.infer<typeof XtextWebPushService>;
diff --git a/subprojects/frontend/src/xtext/xtextServiceResults.ts b/subprojects/frontend/src/xtext/xtextServiceResults.ts
index caf2cf0b..e473bd48 100644
--- a/subprojects/frontend/src/xtext/xtextServiceResults.ts
+++ b/subprojects/frontend/src/xtext/xtextServiceResults.ts
@@ -126,6 +126,14 @@ export const FormattingResult = DocumentStateResult.extend({
126 126
127export type FormattingResult = z.infer<typeof FormattingResult>; 127export type FormattingResult = z.infer<typeof FormattingResult>;
128 128
129export const ModelGenerationStartedResult = z.object({
130 uuid: z.string().nonempty(),
131});
132
133export type ModelGenerationStartedResult = z.infer<
134 typeof ModelGenerationStartedResult
135>;
136
129export const NodeMetadata = z.object({ 137export const NodeMetadata = z.object({
130 name: z.string(), 138 name: z.string(),
131 simpleName: z.string(), 139 simpleName: z.string(),
@@ -171,3 +179,19 @@ export const SemanticsResult = z.union([
171]); 179]);
172 180
173export type SemanticsResult = z.infer<typeof SemanticsResult>; 181export type SemanticsResult = z.infer<typeof SemanticsResult>;
182
183export const ModelGenerationResult = z.union([
184 z.object({
185 uuid: z.string().nonempty(),
186 status: z.string(),
187 }),
188 z.object({
189 uuid: z.string().nonempty(),
190 error: z.string(),
191 }),
192 SemanticsSuccessResult.extend({
193 uuid: z.string().nonempty(),
194 }),
195]);
196
197export type ModelGenerationResult = z.infer<typeof ModelGenerationResult>;