Skip to content

Commit 6c1cd71

Browse files
authored
Move modeled and modified method state to store (#2861)
1 parent 93251f8 commit 6c1cd71

File tree

5 files changed

+213
-59
lines changed

5 files changed

+213
-59
lines changed

extensions/ql-vscode/src/common/interface-types.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -500,14 +500,14 @@ interface SetMethodsMessage {
500500
methods: Method[];
501501
}
502502

503-
interface LoadModeledMethodsMessage {
504-
t: "loadModeledMethods";
505-
modeledMethods: Record<string, ModeledMethod>;
503+
interface SetModeledMethodsMessage {
504+
t: "setModeledMethods";
505+
methods: Record<string, ModeledMethod>;
506506
}
507507

508-
interface AddModeledMethodsMessage {
509-
t: "addModeledMethods";
510-
modeledMethods: Record<string, ModeledMethod>;
508+
interface SetModifiedMethodsMessage {
509+
t: "setModifiedMethods";
510+
methodSignatures: string[];
511511
}
512512

513513
interface SetInProgressMethodsMessage {
@@ -570,11 +570,16 @@ interface HideModeledMethodsMessage {
570570
hideModeledMethods: boolean;
571571
}
572572

573+
interface SetModeledMethodMessage {
574+
t: "setModeledMethod";
575+
method: ModeledMethod;
576+
}
577+
573578
export type ToModelEditorMessage =
574579
| SetExtensionPackStateMessage
575580
| SetMethodsMessage
576-
| LoadModeledMethodsMessage
577-
| AddModeledMethodsMessage
581+
| SetModeledMethodsMessage
582+
| SetModifiedMethodsMessage
578583
| SetInProgressMethodsMessage;
579584

580585
export type FromModelEditorMessage =
@@ -589,7 +594,8 @@ export type FromModelEditorMessage =
589594
| GenerateMethodsFromLlmMessage
590595
| StopGeneratingMethodsFromLlmMessage
591596
| ModelDependencyMessage
592-
| HideModeledMethodsMessage;
597+
| HideModeledMethodsMessage
598+
| SetModeledMethodMessage;
593599

594600
export type FromMethodModelingMessage =
595601
| TelemetryMessage

extensions/ql-vscode/src/model-editor/model-editor-view.ts

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export class ModelEditorView extends AbstractWebview<
8585
});
8686
},
8787
async (modeledMethods) => {
88-
await this.postMessage({ t: "addModeledMethods", modeledMethods });
88+
this.addModeledMethods(modeledMethods);
8989
},
9090
);
9191
}
@@ -257,6 +257,12 @@ export class ModelEditorView extends AbstractWebview<
257257
cancellable: false,
258258
},
259259
);
260+
261+
this.modelingStore.removeModifiedMethods(
262+
this.databaseItem,
263+
Object.keys(msg.modeledMethods),
264+
);
265+
260266
void telemetryListener?.sendUIInteraction(
261267
"model-editor-save-modeled-methods",
262268
);
@@ -316,6 +322,10 @@ export class ModelEditorView extends AbstractWebview<
316322
"model-editor-hide-modeled-methods",
317323
);
318324
break;
325+
case "setModeledMethod": {
326+
this.setModeledMethod(msg.method);
327+
break;
328+
}
319329
default:
320330
assertNever(msg);
321331
}
@@ -360,10 +370,7 @@ export class ModelEditorView extends AbstractWebview<
360370
this.cliServer,
361371
this.app.logger,
362372
);
363-
await this.postMessage({
364-
t: "loadModeledMethods",
365-
modeledMethods,
366-
});
373+
this.modelingStore.setModeledMethods(this.databaseItem, modeledMethods);
367374
} catch (e: unknown) {
368375
void showAndLogErrorMessage(
369376
this.app.logger,
@@ -441,10 +448,7 @@ export class ModelEditorView extends AbstractWebview<
441448
modeledMethodsByName[modeledMethod.signature] = modeledMethod;
442449
}
443450

444-
await this.postMessage({
445-
t: "addModeledMethods",
446-
modeledMethods: modeledMethodsByName,
447-
});
451+
this.addModeledMethods(modeledMethodsByName);
448452
},
449453
progress,
450454
token: tokenSource.token,
@@ -597,5 +601,46 @@ export class ModelEditorView extends AbstractWebview<
597601
}
598602
}),
599603
);
604+
605+
this.push(
606+
this.modelingStore.onModeledMethodsChanged(async (event) => {
607+
if (event.dbUri === this.databaseItem.databaseUri.toString()) {
608+
await this.postMessage({
609+
t: "setModeledMethods",
610+
methods: event.modeledMethods,
611+
});
612+
}
613+
}),
614+
);
615+
616+
this.push(
617+
this.modelingStore.onModifiedMethodsChanged(async (event) => {
618+
if (event.dbUri === this.databaseItem.databaseUri.toString()) {
619+
await this.postMessage({
620+
t: "setModifiedMethods",
621+
methodSignatures: [...event.modifiedMethods],
622+
});
623+
}
624+
}),
625+
);
626+
}
627+
628+
private addModeledMethods(modeledMethods: Record<string, ModeledMethod>) {
629+
this.modelingStore.addModeledMethods(this.databaseItem, modeledMethods);
630+
631+
this.modelingStore.addModifiedMethods(
632+
this.databaseItem,
633+
new Set(Object.keys(modeledMethods)),
634+
);
635+
}
636+
637+
private setModeledMethod(method: ModeledMethod) {
638+
const state = this.modelingStore.getStateForActiveDb();
639+
if (!state) {
640+
throw new Error("Attempting to set modeled method without active db");
641+
}
642+
643+
this.modelingStore.updateModeledMethod(state.databaseItem, method);
644+
this.modelingStore.addModifiedMethod(state.databaseItem, method.signature);
600645
}
601646
}

extensions/ql-vscode/src/model-editor/modeling-store.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import { DisposableObject } from "../common/disposable-object";
33
import { AppEvent, AppEventEmitter } from "../common/events";
44
import { DatabaseItem } from "../databases/local-databases";
55
import { Method } from "./method";
6+
import { ModeledMethod } from "./modeled-method";
67
import { INITIAL_HIDE_MODELED_METHODS_VALUE } from "./shared/hide-modeled-methods";
78

89
interface DbModelingState {
910
databaseItem: DatabaseItem;
1011
methods: Method[];
1112
hideModeledMethods: boolean;
13+
modeledMethods: Record<string, ModeledMethod>;
14+
modifiedMethodSignatures: Set<string>;
1215
}
1316

1417
interface MethodsChangedEvent {
@@ -22,11 +25,25 @@ interface HideModeledMethodsChangedEvent {
2225
isActiveDb: boolean;
2326
}
2427

28+
interface ModeledMethodsChangedEvent {
29+
modeledMethods: Record<string, ModeledMethod>;
30+
dbUri: string;
31+
isActiveDb: boolean;
32+
}
33+
34+
interface ModifiedMethodsChangedEvent {
35+
modifiedMethods: Set<string>;
36+
dbUri: string;
37+
isActiveDb: boolean;
38+
}
39+
2540
export class ModelingStore extends DisposableObject {
2641
public readonly onActiveDbChanged: AppEvent<void>;
2742
public readonly onDbClosed: AppEvent<string>;
2843
public readonly onMethodsChanged: AppEvent<MethodsChangedEvent>;
2944
public readonly onHideModeledMethodsChanged: AppEvent<HideModeledMethodsChangedEvent>;
45+
public readonly onModeledMethodsChanged: AppEvent<ModeledMethodsChangedEvent>;
46+
public readonly onModifiedMethodsChanged: AppEvent<ModifiedMethodsChangedEvent>;
3047

3148
private readonly state: Map<string, DbModelingState>;
3249
private activeDb: string | undefined;
@@ -35,6 +52,8 @@ export class ModelingStore extends DisposableObject {
3552
private readonly onDbClosedEventEmitter: AppEventEmitter<string>;
3653
private readonly onMethodsChangedEventEmitter: AppEventEmitter<MethodsChangedEvent>;
3754
private readonly onHideModeledMethodsChangedEventEmitter: AppEventEmitter<HideModeledMethodsChangedEvent>;
55+
private readonly onModeledMethodsChangedEventEmitter: AppEventEmitter<ModeledMethodsChangedEvent>;
56+
private readonly onModifiedMethodsChangedEventEmitter: AppEventEmitter<ModifiedMethodsChangedEvent>;
3857

3958
constructor(app: App) {
4059
super();
@@ -61,6 +80,18 @@ export class ModelingStore extends DisposableObject {
6180
);
6281
this.onHideModeledMethodsChanged =
6382
this.onHideModeledMethodsChangedEventEmitter.event;
83+
84+
this.onModeledMethodsChangedEventEmitter = this.push(
85+
app.createEventEmitter<ModeledMethodsChangedEvent>(),
86+
);
87+
this.onModeledMethodsChanged =
88+
this.onModeledMethodsChangedEventEmitter.event;
89+
90+
this.onModifiedMethodsChangedEventEmitter = this.push(
91+
app.createEventEmitter<ModifiedMethodsChangedEvent>(),
92+
);
93+
this.onModifiedMethodsChanged =
94+
this.onModifiedMethodsChangedEventEmitter.event;
6495
}
6596

6697
public initializeStateForDb(databaseItem: DatabaseItem) {
@@ -69,6 +100,8 @@ export class ModelingStore extends DisposableObject {
69100
databaseItem,
70101
methods: [],
71102
hideModeledMethods: INITIAL_HIDE_MODELED_METHODS_VALUE,
103+
modeledMethods: {},
104+
modifiedMethodSignatures: new Set(),
72105
});
73106
}
74107

@@ -129,6 +162,73 @@ export class ModelingStore extends DisposableObject {
129162
});
130163
}
131164

165+
public addModeledMethods(
166+
dbItem: DatabaseItem,
167+
methods: Record<string, ModeledMethod>,
168+
) {
169+
this.changeModeledMethods(dbItem, (state) => {
170+
const newModeledMethods = {
171+
...methods,
172+
...Object.fromEntries(
173+
Object.entries(state.modeledMethods).filter(
174+
([_, value]) => value.type !== "none",
175+
),
176+
),
177+
};
178+
state.modeledMethods = newModeledMethods;
179+
});
180+
}
181+
182+
public setModeledMethods(
183+
dbItem: DatabaseItem,
184+
methods: Record<string, ModeledMethod>,
185+
) {
186+
this.changeModeledMethods(dbItem, (state) => {
187+
state.modeledMethods = methods;
188+
});
189+
}
190+
191+
public updateModeledMethod(dbItem: DatabaseItem, method: ModeledMethod) {
192+
this.changeModeledMethods(dbItem, (state) => {
193+
state.modeledMethods[method.signature] = method;
194+
});
195+
}
196+
197+
public setModifiedMethods(
198+
dbItem: DatabaseItem,
199+
methodSignatures: Set<string>,
200+
) {
201+
this.changeModifiedMethods(dbItem, (state) => {
202+
state.modifiedMethodSignatures = methodSignatures;
203+
});
204+
}
205+
206+
public addModifiedMethods(
207+
dbItem: DatabaseItem,
208+
methodSignatures: Iterable<string>,
209+
) {
210+
this.changeModifiedMethods(dbItem, (state) => {
211+
for (const signature of methodSignatures) {
212+
state.modifiedMethodSignatures.add(signature);
213+
}
214+
});
215+
}
216+
217+
public addModifiedMethod(dbItem: DatabaseItem, methodSignature: string) {
218+
this.addModifiedMethods(dbItem, [methodSignature]);
219+
}
220+
221+
public removeModifiedMethods(
222+
dbItem: DatabaseItem,
223+
methodSignatures: string[],
224+
) {
225+
this.changeModifiedMethods(dbItem, (state) => {
226+
methodSignatures.forEach((signature) => {
227+
state.modifiedMethodSignatures.delete(signature);
228+
});
229+
});
230+
}
231+
132232
private getState(databaseItem: DatabaseItem): DbModelingState {
133233
if (!this.state.has(databaseItem.databaseUri.toString())) {
134234
throw Error(
@@ -138,4 +238,34 @@ export class ModelingStore extends DisposableObject {
138238

139239
return this.state.get(databaseItem.databaseUri.toString())!;
140240
}
241+
242+
private changeModifiedMethods(
243+
dbItem: DatabaseItem,
244+
updateState: (state: DbModelingState) => void,
245+
) {
246+
const state = this.getState(dbItem);
247+
248+
updateState(state);
249+
250+
this.onModifiedMethodsChangedEventEmitter.fire({
251+
modifiedMethods: state.modifiedMethodSignatures,
252+
dbUri: dbItem.databaseUri.toString(),
253+
isActiveDb: dbItem.databaseUri.toString() === this.activeDb,
254+
});
255+
}
256+
257+
private changeModeledMethods(
258+
dbItem: DatabaseItem,
259+
updateState: (state: DbModelingState) => void,
260+
) {
261+
const state = this.getState(dbItem);
262+
263+
updateState(state);
264+
265+
this.onModeledMethodsChangedEventEmitter.fire({
266+
modeledMethods: state.modeledMethods,
267+
dbUri: dbItem.databaseUri.toString(),
268+
isActiveDb: dbItem.databaseUri.toString() === this.activeDb,
269+
});
270+
}
141271
}

0 commit comments

Comments
 (0)