@vived/app 6.3.0 → 6.4.0

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 (61) hide show
  1. package/dist/cjs/Procedure/Adapters/procedureAdapter.js +1 -0
  2. package/dist/cjs/Procedure/Adapters/procedureAdapter.js.map +1 -1
  3. package/dist/cjs/Procedure/Entities/ProcedureEntity.js +9 -0
  4. package/dist/cjs/Procedure/Entities/ProcedureEntity.js.map +1 -1
  5. package/dist/cjs/Procedure/Factories/ProcedureFeatureFactory.js +2 -0
  6. package/dist/cjs/Procedure/Factories/ProcedureFeatureFactory.js.map +1 -1
  7. package/dist/cjs/Procedure/Mocks/MockProcedureEntity.js +7 -0
  8. package/dist/cjs/Procedure/Mocks/MockProcedureEntity.js.map +1 -1
  9. package/dist/cjs/Procedure/PM/ProcedurePM.js +3 -0
  10. package/dist/cjs/Procedure/PM/ProcedurePM.js.map +1 -1
  11. package/dist/cjs/Procedure/PM/ProcedurePM.test.js +2 -0
  12. package/dist/cjs/Procedure/PM/ProcedurePM.test.js.map +1 -1
  13. package/dist/cjs/Procedure/UCs/RecordProcedureSessionUC.js +133 -0
  14. package/dist/cjs/Procedure/UCs/RecordProcedureSessionUC.js.map +1 -0
  15. package/dist/cjs/Procedure/UCs/RecordProcedureSessionUC.test.js +283 -0
  16. package/dist/cjs/Procedure/UCs/RecordProcedureSessionUC.test.js.map +1 -0
  17. package/dist/cjs/Procedure/UCs/SerializeProcedure.js +2 -1
  18. package/dist/cjs/Procedure/UCs/SerializeProcedure.js.map +1 -1
  19. package/dist/cjs/Procedure/UCs/index.js +1 -0
  20. package/dist/cjs/Procedure/UCs/index.js.map +1 -1
  21. package/dist/cjs/Procedure/types.js +2 -0
  22. package/dist/cjs/Procedure/types.js.map +1 -1
  23. package/dist/esm/Procedure/Adapters/procedureAdapter.js +1 -0
  24. package/dist/esm/Procedure/Adapters/procedureAdapter.js.map +1 -1
  25. package/dist/esm/Procedure/Entities/ProcedureEntity.js +9 -0
  26. package/dist/esm/Procedure/Entities/ProcedureEntity.js.map +1 -1
  27. package/dist/esm/Procedure/Factories/ProcedureFeatureFactory.js +2 -0
  28. package/dist/esm/Procedure/Factories/ProcedureFeatureFactory.js.map +1 -1
  29. package/dist/esm/Procedure/Mocks/MockProcedureEntity.js +7 -0
  30. package/dist/esm/Procedure/Mocks/MockProcedureEntity.js.map +1 -1
  31. package/dist/esm/Procedure/PM/ProcedurePM.js +3 -0
  32. package/dist/esm/Procedure/PM/ProcedurePM.js.map +1 -1
  33. package/dist/esm/Procedure/PM/ProcedurePM.test.js +2 -0
  34. package/dist/esm/Procedure/PM/ProcedurePM.test.js.map +1 -1
  35. package/dist/esm/Procedure/UCs/RecordProcedureSessionUC.js +128 -0
  36. package/dist/esm/Procedure/UCs/RecordProcedureSessionUC.js.map +1 -0
  37. package/dist/esm/Procedure/UCs/RecordProcedureSessionUC.test.js +281 -0
  38. package/dist/esm/Procedure/UCs/RecordProcedureSessionUC.test.js.map +1 -0
  39. package/dist/esm/Procedure/UCs/SerializeProcedure.js +2 -1
  40. package/dist/esm/Procedure/UCs/SerializeProcedure.js.map +1 -1
  41. package/dist/esm/Procedure/UCs/index.js +1 -0
  42. package/dist/esm/Procedure/UCs/index.js.map +1 -1
  43. package/dist/esm/Procedure/types.js +1 -1
  44. package/dist/esm/Procedure/types.js.map +1 -1
  45. package/dist/types/Procedure/Adapters/procedureAdapter.d.ts.map +1 -1
  46. package/dist/types/Procedure/Entities/ProcedureEntity.d.ts +2 -0
  47. package/dist/types/Procedure/Entities/ProcedureEntity.d.ts.map +1 -1
  48. package/dist/types/Procedure/Factories/ProcedureFeatureFactory.d.ts.map +1 -1
  49. package/dist/types/Procedure/Mocks/MockProcedureEntity.d.ts +3 -0
  50. package/dist/types/Procedure/Mocks/MockProcedureEntity.d.ts.map +1 -1
  51. package/dist/types/Procedure/UCs/RecordProcedureSessionUC.d.ts +9 -0
  52. package/dist/types/Procedure/UCs/RecordProcedureSessionUC.d.ts.map +1 -0
  53. package/dist/types/Procedure/UCs/RecordProcedureSessionUC.test.d.ts +2 -0
  54. package/dist/types/Procedure/UCs/RecordProcedureSessionUC.test.d.ts.map +1 -0
  55. package/dist/types/Procedure/UCs/SerializeProcedure.d.ts.map +1 -1
  56. package/dist/types/Procedure/UCs/index.d.ts +1 -0
  57. package/dist/types/Procedure/UCs/index.d.ts.map +1 -1
  58. package/dist/types/Procedure/types.d.ts +2 -0
  59. package/dist/types/Procedure/types.d.ts.map +1 -1
  60. package/package.json +1 -1
  61. package/src/Procedure/CONTEXT.md +21 -0
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@vived/core");
4
+ const BaseAppState_1 = require("../../BaseApp/Entity/BaseAppState");
5
+ const Mocks_1 = require("../../EventSystem/Mocks");
6
+ const Mocks_2 = require("../../StateMachine/Mocks");
7
+ const Mocks_3 = require("../../UndoRedo/Mocks");
8
+ const ProcedureEntity_1 = require("../Entities/ProcedureEntity");
9
+ const AddProcedureEventUC_1 = require("./AddProcedureEventUC");
10
+ const RecordProcedureSessionUC_1 = require("./RecordProcedureSessionUC");
11
+ const defaultSnapshot = {
12
+ version: 2,
13
+ systems: [
14
+ { name: "amtec", serializationVersion: 1, state: { powerIsOn: false } },
15
+ { name: "procedure", serializationVersion: 1, state: { events: [] } },
16
+ ],
17
+ };
18
+ class MockChallengeEntity extends core_1.AppObjectEntity {
19
+ get selectedChallenge() {
20
+ return this._selectedChallenge;
21
+ }
22
+ set selectedChallenge(id) {
23
+ this._selectedChallenge = id;
24
+ this.notifyObservers();
25
+ }
26
+ notifyObservers() {
27
+ this.observers.forEach((o) => o());
28
+ }
29
+ constructor(appObject) {
30
+ super(appObject, MockChallengeEntity.type);
31
+ this._selectedChallenge = "NONE";
32
+ this.observers = [];
33
+ this.addChangeObserver = (observer) => {
34
+ this.observers.push(observer);
35
+ };
36
+ this.removeChangeObserver = (observer) => {
37
+ const index = this.observers.indexOf(observer);
38
+ if (index >= 0)
39
+ this.observers.splice(index, 1);
40
+ };
41
+ }
42
+ }
43
+ MockChallengeEntity.type = "ChallengeEntity";
44
+ class MockAddProcedureEventUC extends AddProcedureEventUC_1.AddProcedureEventUC {
45
+ constructor(appObject) {
46
+ super(appObject, AddProcedureEventUC_1.AddProcedureEventUC.type);
47
+ this.addEvent = jest.fn();
48
+ }
49
+ }
50
+ function makeTestRig() {
51
+ const appObjects = (0, core_1.makeAppObjectRepo)();
52
+ const procedureAO = appObjects.getOrCreate("Procedure");
53
+ const baseAppState = (0, BaseAppState_1.makeBaseAppState)(appObjects.getOrCreate("App"));
54
+ baseAppState.isAuthoring = true;
55
+ const challengeEntity = new MockChallengeEntity(procedureAO);
56
+ challengeEntity.selectedChallenge = "PROCEDURE";
57
+ appObjects.registerSingleton(challengeEntity);
58
+ const procedureEntity = (0, ProcedureEntity_1.makeProcedureEntity)(procedureAO);
59
+ const mockEventEntity = (0, Mocks_1.makeMockEventEntity)(appObjects);
60
+ appObjects.registerSingleton(mockEventEntity);
61
+ const mockStateMachine = (0, Mocks_2.makeMockStateMachine)(appObjects);
62
+ mockStateMachine.getSerializedStates.mockReturnValue(defaultSnapshot);
63
+ appObjects.registerSingleton(mockStateMachine);
64
+ const mockUndoRedo = (0, Mocks_3.makeMockUndoRedo)(appObjects);
65
+ mockUndoRedo.clearStack = jest.fn();
66
+ appObjects.registerSingleton(mockUndoRedo);
67
+ const mockAddProcedureEventUC = new MockAddProcedureEventUC(procedureAO);
68
+ const uc = (0, RecordProcedureSessionUC_1.makeRecordProcedureSessionUC)(procedureAO);
69
+ return {
70
+ appObjects,
71
+ baseAppState,
72
+ challengeEntity,
73
+ procedureEntity,
74
+ mockEventEntity,
75
+ mockStateMachine,
76
+ mockUndoRedo,
77
+ mockAddProcedureEventUC,
78
+ uc,
79
+ };
80
+ }
81
+ describe("RecordProcedureSessionUC", () => {
82
+ it("gets the UC from appObjects", () => {
83
+ const { uc, appObjects } = makeTestRig();
84
+ expect(RecordProcedureSessionUC_1.RecordProcedureSessionUC.get(appObjects)).toEqual(uc);
85
+ });
86
+ it("starts recording and sets procedureEntity.isRecording to true", () => {
87
+ const { uc, procedureEntity } = makeTestRig();
88
+ uc.startRecording();
89
+ expect(procedureEntity.isRecording).toEqual(true);
90
+ });
91
+ it("registers an emission listener on EventEntity when recording starts", () => {
92
+ const { uc, mockEventEntity } = makeTestRig();
93
+ uc.startRecording();
94
+ expect(mockEventEntity.addEmissionListener).toHaveBeenCalled();
95
+ });
96
+ it("does not start recording when not authoring", () => {
97
+ const { uc, procedureEntity, baseAppState } = makeTestRig();
98
+ baseAppState.isAuthoring = false;
99
+ uc.startRecording();
100
+ expect(procedureEntity.isRecording).toEqual(false);
101
+ });
102
+ it("does not start recording when challenge is not PROCEDURE", () => {
103
+ const { uc, procedureEntity, challengeEntity } = makeTestRig();
104
+ challengeEntity.selectedChallenge = "NONE";
105
+ uc.startRecording();
106
+ expect(procedureEntity.isRecording).toEqual(false);
107
+ });
108
+ it("does not start recording if already recording", () => {
109
+ const { uc, mockEventEntity } = makeTestRig();
110
+ uc.startRecording();
111
+ uc.startRecording();
112
+ expect(mockEventEntity.addEmissionListener).toHaveBeenCalledTimes(1);
113
+ });
114
+ it("stops recording and sets procedureEntity.isRecording to false", () => {
115
+ const { uc, procedureEntity } = makeTestRig();
116
+ uc.startRecording();
117
+ uc.stopRecording();
118
+ expect(procedureEntity.isRecording).toEqual(false);
119
+ });
120
+ it("removes emission listener when recording stops", () => {
121
+ const { uc, mockEventEntity } = makeTestRig();
122
+ uc.startRecording();
123
+ uc.stopRecording();
124
+ expect(mockEventEntity.removeEmissionListener).toHaveBeenCalled();
125
+ });
126
+ it("does nothing when stopping if not recording", () => {
127
+ const { uc, procedureEntity, mockEventEntity } = makeTestRig();
128
+ uc.stopRecording();
129
+ expect(procedureEntity.isRecording).toEqual(false);
130
+ expect(mockEventEntity.removeEmissionListener).not.toHaveBeenCalled();
131
+ });
132
+ it("adds emitted events to the procedure while recording", () => {
133
+ const { uc, mockEventEntity, mockAddProcedureEventUC } = makeTestRig();
134
+ uc.startRecording();
135
+ const emissionCallback = mockEventEntity.addEmissionListener.mock.calls[0][0];
136
+ emissionCallback("master-on-pressed");
137
+ expect(mockAddProcedureEventUC.addEvent).toHaveBeenCalledWith("master-on-pressed");
138
+ });
139
+ it("adds multiple events including duplicates while recording", () => {
140
+ const { uc, mockEventEntity, mockAddProcedureEventUC } = makeTestRig();
141
+ uc.startRecording();
142
+ const emissionCallback = mockEventEntity.addEmissionListener.mock.calls[0][0];
143
+ emissionCallback("master-on-pressed");
144
+ emissionCallback("master-on-pressed");
145
+ emissionCallback("mode-switch-auto");
146
+ expect(mockAddProcedureEventUC.addEvent).toHaveBeenCalledTimes(3);
147
+ });
148
+ it("does not add events after stopping", () => {
149
+ const { uc, mockEventEntity, mockAddProcedureEventUC } = makeTestRig();
150
+ uc.startRecording();
151
+ uc.stopRecording();
152
+ const emissionCallback = mockEventEntity.addEmissionListener.mock.calls[0][0];
153
+ emissionCallback("test-event");
154
+ expect(mockAddProcedureEventUC.addEvent).not.toHaveBeenCalled();
155
+ });
156
+ it("auto-stops when isAuthoring becomes false", () => {
157
+ const { uc, procedureEntity, baseAppState } = makeTestRig();
158
+ uc.startRecording();
159
+ baseAppState.isAuthoring = false;
160
+ expect(procedureEntity.isRecording).toEqual(false);
161
+ });
162
+ it("auto-stops when challenge changes away from PROCEDURE", () => {
163
+ const { uc, procedureEntity, challengeEntity } = makeTestRig();
164
+ uc.startRecording();
165
+ challengeEntity.selectedChallenge = "NONE";
166
+ expect(procedureEntity.isRecording).toEqual(false);
167
+ });
168
+ it("does not stop when challenge remains PROCEDURE", () => {
169
+ const { uc, procedureEntity, challengeEntity } = makeTestRig();
170
+ uc.startRecording();
171
+ challengeEntity.selectedChallenge = "PROCEDURE";
172
+ expect(procedureEntity.isRecording).toEqual(true);
173
+ });
174
+ it("snapshot - captures a state snapshot when recording starts", () => {
175
+ const { uc, mockStateMachine } = makeTestRig();
176
+ uc.startRecording();
177
+ expect(mockStateMachine.getSerializedStates).toHaveBeenCalledTimes(1);
178
+ });
179
+ it("snapshot - does not capture a snapshot when guards prevent recording", () => {
180
+ const { uc, baseAppState, mockStateMachine } = makeTestRig();
181
+ baseAppState.isAuthoring = false;
182
+ uc.startRecording();
183
+ expect(mockStateMachine.getSerializedStates).not.toHaveBeenCalled();
184
+ });
185
+ it("snapshot - restores the snapshot when recording stops", () => {
186
+ const { uc, mockStateMachine } = makeTestRig();
187
+ uc.startRecording();
188
+ uc.stopRecording();
189
+ expect(mockStateMachine.setSerializedStates).toHaveBeenCalledWith(expect.objectContaining({ version: 2 }), mockStateMachine.restoreDurationS);
190
+ });
191
+ it("snapshot - preserves the current procedure system when restoring", () => {
192
+ const { uc, mockStateMachine } = makeTestRig();
193
+ const recordedProcedure = {
194
+ name: "procedure",
195
+ serializationVersion: 1,
196
+ state: { events: ["power-switch-turned-on"] },
197
+ };
198
+ mockStateMachine.getSerializedStates
199
+ .mockReturnValueOnce({
200
+ version: 2,
201
+ systems: [
202
+ { name: "amtec", serializationVersion: 1, state: { powerIsOn: false } },
203
+ { name: "procedure", serializationVersion: 1, state: { events: [] } },
204
+ ],
205
+ })
206
+ .mockReturnValueOnce({
207
+ version: 2,
208
+ systems: [
209
+ { name: "amtec", serializationVersion: 1, state: { powerIsOn: true } },
210
+ recordedProcedure,
211
+ ],
212
+ });
213
+ uc.startRecording();
214
+ uc.stopRecording();
215
+ const mergedState = mockStateMachine.setSerializedStates.mock.calls[0][0];
216
+ const procedureInMerge = mergedState.systems.find((s) => s.name === "procedure");
217
+ expect(procedureInMerge).toEqual(recordedProcedure);
218
+ });
219
+ it("snapshot - restores equipment state from the snapshot (not current state)", () => {
220
+ const { uc, mockStateMachine } = makeTestRig();
221
+ const snapshotAmtec = { name: "amtec", serializationVersion: 1, state: { powerIsOn: false } };
222
+ mockStateMachine.getSerializedStates
223
+ .mockReturnValueOnce({ version: 2, systems: [snapshotAmtec] })
224
+ .mockReturnValueOnce({
225
+ version: 2,
226
+ systems: [{ name: "amtec", serializationVersion: 1, state: { powerIsOn: true } }],
227
+ });
228
+ uc.startRecording();
229
+ uc.stopRecording();
230
+ const mergedState = mockStateMachine.setSerializedStates.mock.calls[0][0];
231
+ const amtecInMerge = mergedState.systems.find((s) => s.name === "amtec");
232
+ expect(amtecInMerge).toEqual(snapshotAmtec);
233
+ });
234
+ it("snapshot - restores on auto-stop when authoring mode exits", () => {
235
+ const { uc, baseAppState, mockStateMachine } = makeTestRig();
236
+ uc.startRecording();
237
+ baseAppState.isAuthoring = false;
238
+ expect(mockStateMachine.setSerializedStates).toHaveBeenCalled();
239
+ });
240
+ it("snapshot - restores on auto-stop when challenge type changes", () => {
241
+ const { uc, challengeEntity, mockStateMachine } = makeTestRig();
242
+ uc.startRecording();
243
+ challengeEntity.selectedChallenge = "NONE";
244
+ expect(mockStateMachine.setSerializedStates).toHaveBeenCalled();
245
+ });
246
+ it("snapshot - clears the undo stack after restoring", () => {
247
+ const { uc, mockUndoRedo } = makeTestRig();
248
+ uc.startRecording();
249
+ uc.stopRecording();
250
+ expect(mockUndoRedo.clearStack).toHaveBeenCalled();
251
+ });
252
+ it("snapshot - does not restore if no snapshot was captured", () => {
253
+ const { uc, mockStateMachine } = makeTestRig();
254
+ uc.stopRecording();
255
+ expect(mockStateMachine.setSerializedStates).not.toHaveBeenCalled();
256
+ });
257
+ it("snapshot - does not capture snapshot a second time on duplicate startRecording", () => {
258
+ const { uc, mockStateMachine } = makeTestRig();
259
+ uc.startRecording();
260
+ uc.startRecording();
261
+ expect(mockStateMachine.getSerializedStates).toHaveBeenCalledTimes(1);
262
+ });
263
+ it("snapshot - warns and still allows recording when StateMachineEntity is missing", () => {
264
+ const appObjects = (0, core_1.makeAppObjectRepo)();
265
+ const procedureAO = appObjects.getOrCreate("Procedure");
266
+ const baseAppState = (0, BaseAppState_1.makeBaseAppState)(appObjects.getOrCreate("App"));
267
+ baseAppState.isAuthoring = true;
268
+ const challengeEntity = new MockChallengeEntity(procedureAO);
269
+ challengeEntity.selectedChallenge = "PROCEDURE";
270
+ appObjects.registerSingleton(challengeEntity);
271
+ const procedureEntity = (0, ProcedureEntity_1.makeProcedureEntity)(procedureAO);
272
+ const mockEventEntity = (0, Mocks_1.makeMockEventEntity)(appObjects);
273
+ appObjects.registerSingleton(mockEventEntity);
274
+ // No StateMachineEntity registered
275
+ const warnSpy = jest.spyOn(console, "warn").mockImplementation(() => { });
276
+ const uc = (0, RecordProcedureSessionUC_1.makeRecordProcedureSessionUC)(procedureAO);
277
+ uc.startRecording();
278
+ expect(warnSpy).toHaveBeenCalled();
279
+ warnSpy.mockRestore();
280
+ expect(procedureEntity.isRecording).toEqual(true);
281
+ });
282
+ });
283
+ //# sourceMappingURL=RecordProcedureSessionUC.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecordProcedureSessionUC.test.js","sourceRoot":"","sources":["../../../../src/Procedure/UCs/RecordProcedureSessionUC.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n\tAppObject,\r\n\tAppObjectEntity,\r\n\tAppObjectRepo,\r\n\tmakeAppObjectRepo,\r\n} from \"@vived/core\";\r\nimport { makeBaseAppState } from \"../../BaseApp/Entity/BaseAppState\";\r\nimport { makeMockEventEntity } from \"../../EventSystem/Mocks\";\r\nimport { makeMockStateMachine } from \"../../StateMachine/Mocks\";\r\nimport { makeMockUndoRedo } from \"../../UndoRedo/Mocks\";\r\nimport { makeProcedureEntity } from \"../Entities/ProcedureEntity\";\r\nimport { AddProcedureEventUC } from \"./AddProcedureEventUC\";\r\nimport {\r\n\tmakeRecordProcedureSessionUC,\r\n\tRecordProcedureSessionUC,\r\n} from \"./RecordProcedureSessionUC\";\r\n\r\nconst defaultSnapshot = {\r\n\tversion: 2,\r\n\tsystems: [\r\n\t\t{ name: \"amtec\", serializationVersion: 1, state: { powerIsOn: false } },\r\n\t\t{ name: \"procedure\", serializationVersion: 1, state: { events: [] } },\r\n\t],\r\n};\r\n\r\nclass MockChallengeEntity extends AppObjectEntity\r\n{\r\n\tstatic readonly type = \"ChallengeEntity\";\r\n\tprivate _selectedChallenge = \"NONE\";\r\n\tprivate observers: (() => void)[] = [];\r\n\r\n\tget selectedChallenge(): string\r\n\t{\r\n\t\treturn this._selectedChallenge;\r\n\t}\r\n\r\n\tset selectedChallenge(id: string)\r\n\t{\r\n\t\tthis._selectedChallenge = id;\r\n\t\tthis.notifyObservers();\r\n\t}\r\n\r\n\taddChangeObserver = (observer: () => void): void =>\r\n\t{\r\n\t\tthis.observers.push(observer);\r\n\t};\r\n\r\n\tremoveChangeObserver = (observer: () => void): void =>\r\n\t{\r\n\t\tconst index = this.observers.indexOf(observer);\r\n\t\tif (index >= 0) this.observers.splice(index, 1);\r\n\t};\r\n\r\n\tprivate notifyObservers(): void\r\n\t{\r\n\t\tthis.observers.forEach((o) => o());\r\n\t}\r\n\r\n\tconstructor(appObject: AppObject)\r\n\t{\r\n\t\tsuper(appObject, MockChallengeEntity.type);\r\n\t}\r\n}\r\n\r\nclass MockAddProcedureEventUC extends AddProcedureEventUC\r\n{\r\n\taddEvent = jest.fn();\r\n\r\n\tconstructor(appObject: AppObject)\r\n\t{\r\n\t\tsuper(appObject, AddProcedureEventUC.type);\r\n\t}\r\n}\r\n\r\nfunction makeTestRig()\r\n{\r\n\tconst appObjects = makeAppObjectRepo();\r\n\tconst procedureAO = appObjects.getOrCreate(\"Procedure\");\r\n\r\n\tconst baseAppState = makeBaseAppState(appObjects.getOrCreate(\"App\"));\r\n\tbaseAppState.isAuthoring = true;\r\n\r\n\tconst challengeEntity = new MockChallengeEntity(procedureAO);\r\n\tchallengeEntity.selectedChallenge = \"PROCEDURE\";\r\n\tappObjects.registerSingleton(challengeEntity);\r\n\r\n\tconst procedureEntity = makeProcedureEntity(procedureAO);\r\n\r\n\tconst mockEventEntity = makeMockEventEntity(appObjects);\r\n\tappObjects.registerSingleton(mockEventEntity);\r\n\r\n\tconst mockStateMachine = makeMockStateMachine(appObjects);\r\n\tmockStateMachine.getSerializedStates.mockReturnValue(defaultSnapshot);\r\n\tappObjects.registerSingleton(mockStateMachine);\r\n\r\n\tconst mockUndoRedo = makeMockUndoRedo(appObjects);\r\n\tmockUndoRedo.clearStack = jest.fn();\r\n\tappObjects.registerSingleton(mockUndoRedo);\r\n\r\n\tconst mockAddProcedureEventUC = new MockAddProcedureEventUC(procedureAO);\r\n\r\n\tconst uc = makeRecordProcedureSessionUC(procedureAO);\r\n\r\n\treturn {\r\n\t\tappObjects,\r\n\t\tbaseAppState,\r\n\t\tchallengeEntity,\r\n\t\tprocedureEntity,\r\n\t\tmockEventEntity,\r\n\t\tmockStateMachine,\r\n\t\tmockUndoRedo,\r\n\t\tmockAddProcedureEventUC,\r\n\t\tuc,\r\n\t};\r\n}\r\n\r\ndescribe(\"RecordProcedureSessionUC\", () => {\r\n\tit(\"gets the UC from appObjects\", () => {\r\n\t\tconst { uc, appObjects } = makeTestRig();\r\n\t\texpect(RecordProcedureSessionUC.get(appObjects)).toEqual(uc);\r\n\t});\r\n\r\n\tit(\"starts recording and sets procedureEntity.isRecording to true\", () => {\r\n\t\tconst { uc, procedureEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\texpect(procedureEntity.isRecording).toEqual(true);\r\n\t});\r\n\r\n\tit(\"registers an emission listener on EventEntity when recording starts\", () => {\r\n\t\tconst { uc, mockEventEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\texpect(mockEventEntity.addEmissionListener).toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"does not start recording when not authoring\", () => {\r\n\t\tconst { uc, procedureEntity, baseAppState } = makeTestRig();\r\n\t\tbaseAppState.isAuthoring = false;\r\n\t\tuc.startRecording();\r\n\t\texpect(procedureEntity.isRecording).toEqual(false);\r\n\t});\r\n\r\n\tit(\"does not start recording when challenge is not PROCEDURE\", () => {\r\n\t\tconst { uc, procedureEntity, challengeEntity } = makeTestRig();\r\n\t\tchallengeEntity.selectedChallenge = \"NONE\";\r\n\t\tuc.startRecording();\r\n\t\texpect(procedureEntity.isRecording).toEqual(false);\r\n\t});\r\n\r\n\tit(\"does not start recording if already recording\", () => {\r\n\t\tconst { uc, mockEventEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.startRecording();\r\n\t\texpect(mockEventEntity.addEmissionListener).toHaveBeenCalledTimes(1);\r\n\t});\r\n\r\n\tit(\"stops recording and sets procedureEntity.isRecording to false\", () => {\r\n\t\tconst { uc, procedureEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\t\texpect(procedureEntity.isRecording).toEqual(false);\r\n\t});\r\n\r\n\tit(\"removes emission listener when recording stops\", () => {\r\n\t\tconst { uc, mockEventEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\t\texpect(mockEventEntity.removeEmissionListener).toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"does nothing when stopping if not recording\", () => {\r\n\t\tconst { uc, procedureEntity, mockEventEntity } = makeTestRig();\r\n\t\tuc.stopRecording();\r\n\t\texpect(procedureEntity.isRecording).toEqual(false);\r\n\t\texpect(mockEventEntity.removeEmissionListener).not.toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"adds emitted events to the procedure while recording\", () => {\r\n\t\tconst { uc, mockEventEntity, mockAddProcedureEventUC } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tconst emissionCallback = mockEventEntity.addEmissionListener.mock.calls[0][0];\r\n\t\temissionCallback(\"master-on-pressed\");\r\n\t\texpect(mockAddProcedureEventUC.addEvent).toHaveBeenCalledWith(\"master-on-pressed\");\r\n\t});\r\n\r\n\tit(\"adds multiple events including duplicates while recording\", () => {\r\n\t\tconst { uc, mockEventEntity, mockAddProcedureEventUC } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tconst emissionCallback = mockEventEntity.addEmissionListener.mock.calls[0][0];\r\n\t\temissionCallback(\"master-on-pressed\");\r\n\t\temissionCallback(\"master-on-pressed\");\r\n\t\temissionCallback(\"mode-switch-auto\");\r\n\t\texpect(mockAddProcedureEventUC.addEvent).toHaveBeenCalledTimes(3);\r\n\t});\r\n\r\n\tit(\"does not add events after stopping\", () => {\r\n\t\tconst { uc, mockEventEntity, mockAddProcedureEventUC } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\t\tconst emissionCallback = mockEventEntity.addEmissionListener.mock.calls[0][0];\r\n\t\temissionCallback(\"test-event\");\r\n\t\texpect(mockAddProcedureEventUC.addEvent).not.toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"auto-stops when isAuthoring becomes false\", () => {\r\n\t\tconst { uc, procedureEntity, baseAppState } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tbaseAppState.isAuthoring = false;\r\n\t\texpect(procedureEntity.isRecording).toEqual(false);\r\n\t});\r\n\r\n\tit(\"auto-stops when challenge changes away from PROCEDURE\", () => {\r\n\t\tconst { uc, procedureEntity, challengeEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tchallengeEntity.selectedChallenge = \"NONE\";\r\n\t\texpect(procedureEntity.isRecording).toEqual(false);\r\n\t});\r\n\r\n\tit(\"does not stop when challenge remains PROCEDURE\", () => {\r\n\t\tconst { uc, procedureEntity, challengeEntity } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tchallengeEntity.selectedChallenge = \"PROCEDURE\";\r\n\t\texpect(procedureEntity.isRecording).toEqual(true);\r\n\t});\r\n\r\n\tit(\"snapshot - captures a state snapshot when recording starts\", () => {\r\n\t\tconst { uc, mockStateMachine } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\texpect(mockStateMachine.getSerializedStates).toHaveBeenCalledTimes(1);\r\n\t});\r\n\r\n\tit(\"snapshot - does not capture a snapshot when guards prevent recording\", () => {\r\n\t\tconst { uc, baseAppState, mockStateMachine } = makeTestRig();\r\n\t\tbaseAppState.isAuthoring = false;\r\n\t\tuc.startRecording();\r\n\t\texpect(mockStateMachine.getSerializedStates).not.toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"snapshot - restores the snapshot when recording stops\", () => {\r\n\t\tconst { uc, mockStateMachine } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\t\texpect(mockStateMachine.setSerializedStates).toHaveBeenCalledWith(\r\n\t\t\texpect.objectContaining({ version: 2 }),\r\n\t\t\tmockStateMachine.restoreDurationS\r\n\t\t);\r\n\t});\r\n\r\n\tit(\"snapshot - preserves the current procedure system when restoring\", () => {\r\n\t\tconst { uc, mockStateMachine } = makeTestRig();\r\n\t\tconst recordedProcedure = {\r\n\t\t\tname: \"procedure\",\r\n\t\t\tserializationVersion: 1,\r\n\t\t\tstate: { events: [\"power-switch-turned-on\"] },\r\n\t\t};\r\n\t\tmockStateMachine.getSerializedStates\r\n\t\t\t.mockReturnValueOnce({\r\n\t\t\t\tversion: 2,\r\n\t\t\t\tsystems: [\r\n\t\t\t\t\t{ name: \"amtec\", serializationVersion: 1, state: { powerIsOn: false } },\r\n\t\t\t\t\t{ name: \"procedure\", serializationVersion: 1, state: { events: [] } },\r\n\t\t\t\t],\r\n\t\t\t})\r\n\t\t\t.mockReturnValueOnce({\r\n\t\t\t\tversion: 2,\r\n\t\t\t\tsystems: [\r\n\t\t\t\t\t{ name: \"amtec\", serializationVersion: 1, state: { powerIsOn: true } },\r\n\t\t\t\t\trecordedProcedure,\r\n\t\t\t\t],\r\n\t\t\t});\r\n\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\r\n\t\tconst mergedState = mockStateMachine.setSerializedStates.mock.calls[0][0];\r\n\t\tconst procedureInMerge = mergedState.systems.find(\r\n\t\t\t(s: { name: string }) => s.name === \"procedure\"\r\n\t\t);\r\n\t\texpect(procedureInMerge).toEqual(recordedProcedure);\r\n\t});\r\n\r\n\tit(\"snapshot - restores equipment state from the snapshot (not current state)\", () => {\r\n\t\tconst { uc, mockStateMachine } = makeTestRig();\r\n\t\tconst snapshotAmtec = { name: \"amtec\", serializationVersion: 1, state: { powerIsOn: false } };\r\n\t\tmockStateMachine.getSerializedStates\r\n\t\t\t.mockReturnValueOnce({ version: 2, systems: [snapshotAmtec] })\r\n\t\t\t.mockReturnValueOnce({\r\n\t\t\t\tversion: 2,\r\n\t\t\t\tsystems: [{ name: \"amtec\", serializationVersion: 1, state: { powerIsOn: true } }],\r\n\t\t\t});\r\n\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\r\n\t\tconst mergedState = mockStateMachine.setSerializedStates.mock.calls[0][0];\r\n\t\tconst amtecInMerge = mergedState.systems.find(\r\n\t\t\t(s: { name: string }) => s.name === \"amtec\"\r\n\t\t);\r\n\t\texpect(amtecInMerge).toEqual(snapshotAmtec);\r\n\t});\r\n\r\n\tit(\"snapshot - restores on auto-stop when authoring mode exits\", () => {\r\n\t\tconst { uc, baseAppState, mockStateMachine } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tbaseAppState.isAuthoring = false;\r\n\t\texpect(mockStateMachine.setSerializedStates).toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"snapshot - restores on auto-stop when challenge type changes\", () => {\r\n\t\tconst { uc, challengeEntity, mockStateMachine } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tchallengeEntity.selectedChallenge = \"NONE\";\r\n\t\texpect(mockStateMachine.setSerializedStates).toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"snapshot - clears the undo stack after restoring\", () => {\r\n\t\tconst { uc, mockUndoRedo } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.stopRecording();\r\n\t\texpect(mockUndoRedo.clearStack).toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"snapshot - does not restore if no snapshot was captured\", () => {\r\n\t\tconst { uc, mockStateMachine } = makeTestRig();\r\n\t\tuc.stopRecording();\r\n\t\texpect(mockStateMachine.setSerializedStates).not.toHaveBeenCalled();\r\n\t});\r\n\r\n\tit(\"snapshot - does not capture snapshot a second time on duplicate startRecording\", () => {\r\n\t\tconst { uc, mockStateMachine } = makeTestRig();\r\n\t\tuc.startRecording();\r\n\t\tuc.startRecording();\r\n\t\texpect(mockStateMachine.getSerializedStates).toHaveBeenCalledTimes(1);\r\n\t});\r\n\r\n\tit(\"snapshot - warns and still allows recording when StateMachineEntity is missing\", () => {\r\n\t\tconst appObjects = makeAppObjectRepo();\r\n\t\tconst procedureAO = appObjects.getOrCreate(\"Procedure\");\r\n\r\n\t\tconst baseAppState = makeBaseAppState(appObjects.getOrCreate(\"App\"));\r\n\t\tbaseAppState.isAuthoring = true;\r\n\r\n\t\tconst challengeEntity = new MockChallengeEntity(procedureAO);\r\n\t\tchallengeEntity.selectedChallenge = \"PROCEDURE\";\r\n\t\tappObjects.registerSingleton(challengeEntity);\r\n\r\n\t\tconst procedureEntity = makeProcedureEntity(procedureAO);\r\n\r\n\t\tconst mockEventEntity = makeMockEventEntity(appObjects);\r\n\t\tappObjects.registerSingleton(mockEventEntity);\r\n\r\n\t\t// No StateMachineEntity registered\r\n\t\tconst warnSpy = jest.spyOn(console, \"warn\").mockImplementation(() => {});\r\n\r\n\t\tconst uc = makeRecordProcedureSessionUC(procedureAO);\r\n\t\tuc.startRecording();\r\n\r\n\t\texpect(warnSpy).toHaveBeenCalled();\r\n\t\twarnSpy.mockRestore();\r\n\t\texpect(procedureEntity.isRecording).toEqual(true);\r\n\t});\r\n});\r\n"]}
@@ -5,10 +5,11 @@ exports.makeSerializeProcedure = makeSerializeProcedure;
5
5
  const core_1 = require("@vived/core");
6
6
  const StateMachine_1 = require("../../StateMachine");
7
7
  const ProcedureEntity_1 = require("../Entities/ProcedureEntity");
8
+ const types_1 = require("../types");
8
9
  class SerializeProcedure extends core_1.AppObjectUC {
9
10
  constructor() {
10
11
  super(...arguments);
11
- this.name = "procedure";
12
+ this.name = types_1.PROCEDURE_SYSTEM_NAME;
12
13
  this.serializationVersion = 1;
13
14
  }
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SerializeProcedure.js","sourceRoot":"","sources":["../../../../src/Procedure/UCs/SerializeProcedure.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AppObject,\r\n AppObjectUC,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n} from \"@vived/core\";\r\nimport { StateMachineEntity } from \"../../StateMachine\";\r\nimport { SerializedSystem } from \"../../StateMachine/Entities/StateMachineEntity\";\r\nimport { ProcedureEntity } from \"../Entities/ProcedureEntity\";\r\nimport { SerializeProcedureStateV1 } from \"../types\";\r\n\r\nexport abstract class SerializeProcedure\r\n extends AppObjectUC\r\n implements SerializedSystem\r\n{\r\n static readonly type = \"SerializeProcedure\";\r\n\r\n readonly name = \"procedure\";\r\n readonly serializationVersion = 1;\r\n\r\n abstract getSystemState(): object | undefined;\r\n abstract applySystemState(\r\n state: object,\r\n version: number,\r\n transitionDuration: number,\r\n ): void;\r\n abstract applyDefaultState(transitionDuration: number): void;\r\n\r\n static get = (appObjects: AppObjectRepo): SerializeProcedure | undefined =>\r\n getSingletonComponent(SerializeProcedure.type, appObjects);\r\n}\r\n\r\nexport function makeSerializeProcedure(\r\n appObject: AppObject,\r\n): SerializeProcedure {\r\n return new SerializeProcedureImp(appObject);\r\n}\r\n\r\nclass SerializeProcedureImp extends SerializeProcedure {\r\n private get procedureEntity(): ProcedureEntity | undefined {\r\n return ProcedureEntity.get(this.appObjects);\r\n }\r\n\r\n private get stateMachineEntity(): StateMachineEntity | undefined {\r\n return StateMachineEntity.get(this.appObjects);\r\n }\r\n\r\n getSystemState(): object | undefined {\r\n const entity = this.procedureEntity;\r\n if (!entity) {\r\n this.warn(\"ProcedureEntity not found - cannot get system state\");\r\n return undefined;\r\n }\r\n\r\n try {\r\n const state: SerializeProcedureStateV1 = {\r\n eventIds: entity.eventIds,\r\n orderMatters: entity.orderMatters,\r\n showHints: entity.showHints,\r\n isQuiz: entity.isQuiz,\r\n };\r\n return state;\r\n } catch (error) {\r\n this.warn(`Error getting procedure state: ${error}`);\r\n return undefined;\r\n }\r\n }\r\n\r\n applySystemState(\r\n state: object,\r\n version: number,\r\n transitionDuration: number,\r\n ): void {\r\n const entity = this.procedureEntity;\r\n if (!entity) {\r\n this.warn(\"ProcedureEntity not found - cannot apply system state\");\r\n return;\r\n }\r\n\r\n try {\r\n if (version !== 1) {\r\n this.warn(\r\n `Unsupported serialization version ${version}, falling back to default state`,\r\n );\r\n this.applyDefaultState(transitionDuration);\r\n return;\r\n }\r\n\r\n const procedureData = state as SerializeProcedureStateV1;\r\n if (!this.isValidV1Data(procedureData)) {\r\n this.warn(\r\n \"Invalid procedure data format, falling back to default state\",\r\n );\r\n this.applyDefaultState(transitionDuration);\r\n return;\r\n }\r\n\r\n entity.clearEventIds();\r\n procedureData.eventIds.forEach((eventId) => entity.addEventId(eventId));\r\n entity.setOrderMatters(procedureData.orderMatters);\r\n entity.setShowHints(procedureData.showHints);\r\n entity.setIsQuiz(procedureData.isQuiz);\r\n\r\n entity.reset();\r\n } catch (error) {\r\n this.warn(\r\n `Error applying procedure state: ${error}, falling back to default state`,\r\n );\r\n this.applyDefaultState(transitionDuration);\r\n }\r\n }\r\n\r\n applyDefaultState(_transitionDuration: number): void {\r\n const entity = this.procedureEntity;\r\n if (!entity) {\r\n this.warn(\"ProcedureEntity not found - cannot apply default state\");\r\n return;\r\n }\r\n\r\n try {\r\n entity.clearEventIds();\r\n entity.setOrderMatters(true);\r\n entity.setShowHints(true);\r\n entity.setIsQuiz(false);\r\n entity.reset();\r\n } catch (error) {\r\n this.warn(`Error applying default procedure state: ${error}`);\r\n }\r\n }\r\n\r\n private isValidV1Data(data: any): data is SerializeProcedureStateV1 {\r\n return (\r\n data &&\r\n typeof data === \"object\" &&\r\n Array.isArray(data.eventIds) &&\r\n data.eventIds.every((id: any) => typeof id === \"string\") &&\r\n typeof data.orderMatters === \"boolean\" &&\r\n typeof data.showHints === \"boolean\" &&\r\n typeof data.isQuiz === \"boolean\"\r\n );\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, SerializeProcedure.type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n\r\n const stateMachine = this.stateMachineEntity;\r\n if (stateMachine) {\r\n stateMachine.registerSerializedSystem(this);\r\n } else {\r\n this.warn(\r\n \"StateMachineEntity not found - procedure state will not persist\",\r\n );\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"SerializeProcedure.js","sourceRoot":"","sources":["../../../../src/Procedure/UCs/SerializeProcedure.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AppObject,\r\n AppObjectUC,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n} from \"@vived/core\";\r\nimport { StateMachineEntity } from \"../../StateMachine\";\r\nimport { SerializedSystem } from \"../../StateMachine/Entities/StateMachineEntity\";\r\nimport { ProcedureEntity } from \"../Entities/ProcedureEntity\";\r\nimport { SerializeProcedureStateV1, PROCEDURE_SYSTEM_NAME } from \"../types\";\r\n\r\nexport abstract class SerializeProcedure\r\n extends AppObjectUC\r\n implements SerializedSystem\r\n{\r\n static readonly type = \"SerializeProcedure\";\r\n\r\n readonly name = PROCEDURE_SYSTEM_NAME;\r\n readonly serializationVersion = 1;\r\n\r\n abstract getSystemState(): object | undefined;\r\n abstract applySystemState(\r\n state: object,\r\n version: number,\r\n transitionDuration: number,\r\n ): void;\r\n abstract applyDefaultState(transitionDuration: number): void;\r\n\r\n static get = (appObjects: AppObjectRepo): SerializeProcedure | undefined =>\r\n getSingletonComponent(SerializeProcedure.type, appObjects);\r\n}\r\n\r\nexport function makeSerializeProcedure(\r\n appObject: AppObject,\r\n): SerializeProcedure {\r\n return new SerializeProcedureImp(appObject);\r\n}\r\n\r\nclass SerializeProcedureImp extends SerializeProcedure {\r\n private get procedureEntity(): ProcedureEntity | undefined {\r\n return ProcedureEntity.get(this.appObjects);\r\n }\r\n\r\n private get stateMachineEntity(): StateMachineEntity | undefined {\r\n return StateMachineEntity.get(this.appObjects);\r\n }\r\n\r\n getSystemState(): object | undefined {\r\n const entity = this.procedureEntity;\r\n if (!entity) {\r\n this.warn(\"ProcedureEntity not found - cannot get system state\");\r\n return undefined;\r\n }\r\n\r\n try {\r\n const state: SerializeProcedureStateV1 = {\r\n eventIds: entity.eventIds,\r\n orderMatters: entity.orderMatters,\r\n showHints: entity.showHints,\r\n isQuiz: entity.isQuiz,\r\n };\r\n return state;\r\n } catch (error) {\r\n this.warn(`Error getting procedure state: ${error}`);\r\n return undefined;\r\n }\r\n }\r\n\r\n applySystemState(\r\n state: object,\r\n version: number,\r\n transitionDuration: number,\r\n ): void {\r\n const entity = this.procedureEntity;\r\n if (!entity) {\r\n this.warn(\"ProcedureEntity not found - cannot apply system state\");\r\n return;\r\n }\r\n\r\n try {\r\n if (version !== 1) {\r\n this.warn(\r\n `Unsupported serialization version ${version}, falling back to default state`,\r\n );\r\n this.applyDefaultState(transitionDuration);\r\n return;\r\n }\r\n\r\n const procedureData = state as SerializeProcedureStateV1;\r\n if (!this.isValidV1Data(procedureData)) {\r\n this.warn(\r\n \"Invalid procedure data format, falling back to default state\",\r\n );\r\n this.applyDefaultState(transitionDuration);\r\n return;\r\n }\r\n\r\n entity.clearEventIds();\r\n procedureData.eventIds.forEach((eventId) => entity.addEventId(eventId));\r\n entity.setOrderMatters(procedureData.orderMatters);\r\n entity.setShowHints(procedureData.showHints);\r\n entity.setIsQuiz(procedureData.isQuiz);\r\n\r\n entity.reset();\r\n } catch (error) {\r\n this.warn(\r\n `Error applying procedure state: ${error}, falling back to default state`,\r\n );\r\n this.applyDefaultState(transitionDuration);\r\n }\r\n }\r\n\r\n applyDefaultState(_transitionDuration: number): void {\r\n const entity = this.procedureEntity;\r\n if (!entity) {\r\n this.warn(\"ProcedureEntity not found - cannot apply default state\");\r\n return;\r\n }\r\n\r\n try {\r\n entity.clearEventIds();\r\n entity.setOrderMatters(true);\r\n entity.setShowHints(true);\r\n entity.setIsQuiz(false);\r\n entity.reset();\r\n } catch (error) {\r\n this.warn(`Error applying default procedure state: ${error}`);\r\n }\r\n }\r\n\r\n private isValidV1Data(data: any): data is SerializeProcedureStateV1 {\r\n return (\r\n data &&\r\n typeof data === \"object\" &&\r\n Array.isArray(data.eventIds) &&\r\n data.eventIds.every((id: any) => typeof id === \"string\") &&\r\n typeof data.orderMatters === \"boolean\" &&\r\n typeof data.showHints === \"boolean\" &&\r\n typeof data.isQuiz === \"boolean\"\r\n );\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, SerializeProcedure.type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n\r\n const stateMachine = this.stateMachineEntity;\r\n if (stateMachine) {\r\n stateMachine.registerSerializedSystem(this);\r\n } else {\r\n this.warn(\r\n \"StateMachineEntity not found - procedure state will not persist\",\r\n );\r\n }\r\n }\r\n}\r\n"]}
@@ -26,4 +26,5 @@ __exportStar(require("./SetProcedureIsQuizUC"), exports);
26
26
  __exportStar(require("./SubmitProcedureQuizUC"), exports);
27
27
  __exportStar(require("./SerializeProcedure"), exports);
28
28
  __exportStar(require("./UpdateProcedureEventsUCHook"), exports);
29
+ __exportStar(require("./RecordProcedureSessionUC"), exports);
29
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/Procedure/UCs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,2DAAyC;AACzC,6DAA2C;AAC3C,2DAAyC;AACzC,2DAAyC;AACzC,6DAA2C;AAC3C,+DAA6C;AAC7C,4DAA0C;AAC1C,yDAAuC;AACvC,0DAAwC;AACxC,uDAAqC;AACrC,gEAA8C","sourcesContent":["export * from \"./AddProcedureEventUC\";\r\nexport * from \"./RecordProcedureEventUC\";\r\nexport * from \"./ResetProcedureProgressUC\";\r\nexport * from \"./RemoveProcedureEventUC\";\r\nexport * from \"./MoveProcedureEventUpUC\";\r\nexport * from \"./MoveProcedureEventDownUC\";\r\nexport * from \"./SetProcedureOrderMattersUC\";\r\nexport * from \"./SetProcedureShowHintsUC\";\r\nexport * from \"./SetProcedureIsQuizUC\";\r\nexport * from \"./SubmitProcedureQuizUC\";\r\nexport * from \"./SerializeProcedure\";\r\nexport * from \"./UpdateProcedureEventsUCHook\";\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/Procedure/UCs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,2DAAyC;AACzC,6DAA2C;AAC3C,2DAAyC;AACzC,2DAAyC;AACzC,6DAA2C;AAC3C,+DAA6C;AAC7C,4DAA0C;AAC1C,yDAAuC;AACvC,0DAAwC;AACxC,uDAAqC;AACrC,gEAA8C;AAC9C,6DAA2C","sourcesContent":["export * from \"./AddProcedureEventUC\";\r\nexport * from \"./RecordProcedureEventUC\";\r\nexport * from \"./ResetProcedureProgressUC\";\r\nexport * from \"./RemoveProcedureEventUC\";\r\nexport * from \"./MoveProcedureEventUpUC\";\r\nexport * from \"./MoveProcedureEventDownUC\";\r\nexport * from \"./SetProcedureOrderMattersUC\";\r\nexport * from \"./SetProcedureShowHintsUC\";\r\nexport * from \"./SetProcedureIsQuizUC\";\r\nexport * from \"./SubmitProcedureQuizUC\";\r\nexport * from \"./SerializeProcedure\";\r\nexport * from \"./UpdateProcedureEventsUCHook\";\r\nexport * from \"./RecordProcedureSessionUC\";\r\n"]}
@@ -1,3 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROCEDURE_SYSTEM_NAME = void 0;
4
+ exports.PROCEDURE_SYSTEM_NAME = "procedure";
3
5
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/Procedure/types.ts"],"names":[],"mappings":"","sourcesContent":["import { EventDefinition } from \"../EventSystem/types\";\r\n\r\n/**\r\n * Serialization format for Procedure state persistence (Version 1)\r\n */\r\nexport interface SerializeProcedureStateV1 {\r\n eventIds: string[];\r\n orderMatters: boolean;\r\n showHints: boolean;\r\n isQuiz: boolean;\r\n}\r\n\r\n/**\r\n * View Model interface for Procedure presentation\r\n */\r\nexport interface ProcedureVM {\r\n eventIds: string[];\r\n orderMatters: boolean;\r\n showHints: boolean;\r\n isQuiz: boolean;\r\n userEventLog: string[];\r\n currentStepIndex: number;\r\n isComplete: boolean;\r\n validationMessage: string | null;\r\n nextExpectedEvent: string | null;\r\n progressPercentage: number;\r\n availableEvents: EventDefinition[];\r\n authoringValidationMessage: string | null;\r\n score: {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null;\r\n isSubmitted: boolean;\r\n}\r\n\r\n\r\n/** Fields needed by the Babylon hint view */\r\nexport interface ProcedureHintVM {\r\n showHints: boolean;\r\n nextExpectedEvent: string | null;\r\n}\r\n\r\n/** Fields needed by the runtime step checklist and slide content */\r\nexport interface ProcedureProgressVM {\r\n eventIds: string[];\r\n availableEvents: EventDefinition[];\r\n userEventLog: string[];\r\n currentStepIndex: number;\r\n isComplete: boolean;\r\n orderMatters: boolean;\r\n progressPercentage: number;\r\n isQuiz: boolean;\r\n isSubmitted: boolean;\r\n}\r\n\r\n/** Fields needed by the quiz review / score screen */\r\nexport interface ProcedureQuizResultVM {\r\n isComplete: boolean;\r\n isQuiz: boolean;\r\n progressPercentage: number;\r\n eventIds: string[];\r\n availableEvents: EventDefinition[];\r\n orderMatters: boolean;\r\n userEventLog: string[];\r\n score: {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null;\r\n isSubmitted: boolean;\r\n}\r\n/** Fields needed by the authoring inspector UI */\r\nexport interface ProcedureAuthoringVM {\r\n eventIds: string[];\r\n availableEvents: EventDefinition[];\r\n authoringValidationMessage: string | null;\r\n orderMatters: boolean;\r\n showHints: boolean;\r\n isQuiz: boolean;\r\n}\r\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/Procedure/types.ts"],"names":[],"mappings":";;;AAEa,QAAA,qBAAqB,GAAG,WAAW,CAAC","sourcesContent":["import { EventDefinition } from \"../EventSystem/types\";\r\n\r\nexport const PROCEDURE_SYSTEM_NAME = \"procedure\";\r\n\r\n/**\r\n * Serialization format for Procedure state persistence (Version 1)\r\n */\r\nexport interface SerializeProcedureStateV1 {\r\n eventIds: string[];\r\n orderMatters: boolean;\r\n showHints: boolean;\r\n isQuiz: boolean;\r\n}\r\n\r\n/**\r\n * View Model interface for Procedure presentation\r\n */\r\nexport interface ProcedureVM {\r\n eventIds: string[];\r\n orderMatters: boolean;\r\n showHints: boolean;\r\n isQuiz: boolean;\r\n isRecording: boolean;\r\n userEventLog: string[];\r\n currentStepIndex: number;\r\n isComplete: boolean;\r\n validationMessage: string | null;\r\n nextExpectedEvent: string | null;\r\n progressPercentage: number;\r\n availableEvents: EventDefinition[];\r\n authoringValidationMessage: string | null;\r\n score: {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null;\r\n isSubmitted: boolean;\r\n}\r\n\r\n\r\n/** Fields needed by the Babylon hint view */\r\nexport interface ProcedureHintVM {\r\n showHints: boolean;\r\n nextExpectedEvent: string | null;\r\n}\r\n\r\n/** Fields needed by the runtime step checklist and slide content */\r\nexport interface ProcedureProgressVM {\r\n eventIds: string[];\r\n availableEvents: EventDefinition[];\r\n userEventLog: string[];\r\n currentStepIndex: number;\r\n isComplete: boolean;\r\n orderMatters: boolean;\r\n progressPercentage: number;\r\n isQuiz: boolean;\r\n isSubmitted: boolean;\r\n}\r\n\r\n/** Fields needed by the quiz review / score screen */\r\nexport interface ProcedureQuizResultVM {\r\n isComplete: boolean;\r\n isQuiz: boolean;\r\n progressPercentage: number;\r\n eventIds: string[];\r\n availableEvents: EventDefinition[];\r\n orderMatters: boolean;\r\n userEventLog: string[];\r\n score: {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null;\r\n isSubmitted: boolean;\r\n}\r\n/** Fields needed by the authoring inspector UI */\r\nexport interface ProcedureAuthoringVM {\r\n eventIds: string[];\r\n availableEvents: EventDefinition[];\r\n authoringValidationMessage: string | null;\r\n orderMatters: boolean;\r\n showHints: boolean;\r\n isQuiz: boolean;\r\n}\r\n"]}
@@ -6,6 +6,7 @@ class ProcedureAdapter {
6
6
  orderMatters: true,
7
7
  showHints: true,
8
8
  isQuiz: false,
9
+ isRecording: false,
9
10
  userEventLog: [],
10
11
  currentStepIndex: 0,
11
12
  isComplete: false,
@@ -1 +1 @@
1
- {"version":3,"file":"procedureAdapter.js","sourceRoot":"","sources":["../../../../src/Procedure/Adapters/procedureAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,gBAAgB;IAAtB;QACE,cAAS,GAAgB;YACvB,QAAQ,EAAE,EAAE;YACZ,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,EAAE;YAChB,gBAAgB,EAAE,CAAC;YACnB,UAAU,EAAE,KAAK;YACjB,iBAAiB,EAAE,IAAI;YACvB,iBAAiB,EAAE,IAAI;YACvB,kBAAkB,EAAE,CAAC;YACrB,eAAe,EAAE,EAAE;YACnB,0BAA0B,EACxB,mDAAmD;YACrD,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,KAAK;SACnB,CAAC;IAmBJ,CAAC;IAjBC,SAAS,CAAC,UAAyB,EAAE,KAAgC;QACnE,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,WAAW,CAAC,MAAM;gBAAE,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,WAAW,CACT,UAAyB,EACzB,KAAgC;QAEhC,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC","sourcesContent":["import { SingletonPmAdapter, AppObjectRepo } from \"@vived/core\";\r\nimport { ProcedurePM } from \"../PM/ProcedurePM\";\r\nimport { ProcedureVM } from \"../types\";\r\n\r\nclass ProcedureAdapter implements SingletonPmAdapter<ProcedureVM> {\r\n defaultVM: ProcedureVM = {\r\n eventIds: [],\r\n orderMatters: true,\r\n showHints: true,\r\n isQuiz: false,\r\n userEventLog: [],\r\n currentStepIndex: 0,\r\n isComplete: false,\r\n validationMessage: null,\r\n nextExpectedEvent: null,\r\n progressPercentage: 0,\r\n availableEvents: [],\r\n authoringValidationMessage:\r\n \"At least one event must be added to the procedure\",\r\n score: null,\r\n isSubmitted: false,\r\n };\r\n\r\n subscribe(appObjects: AppObjectRepo, setVM: (vm: ProcedureVM) => void): void {\r\n const procedurePM = ProcedurePM.get(appObjects);\r\n if (procedurePM) {\r\n procedurePM.addView(setVM);\r\n if (procedurePM.lastVM) setVM(procedurePM.lastVM);\r\n }\r\n }\r\n\r\n unsubscribe(\r\n appObjects: AppObjectRepo,\r\n setVM: (vm: ProcedureVM) => void,\r\n ): void {\r\n const procedurePM = ProcedurePM.get(appObjects);\r\n if (procedurePM) {\r\n procedurePM.removeView(setVM);\r\n }\r\n }\r\n}\r\n\r\nexport const procedureAdapter = new ProcedureAdapter();\r\n"]}
1
+ {"version":3,"file":"procedureAdapter.js","sourceRoot":"","sources":["../../../../src/Procedure/Adapters/procedureAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,gBAAgB;IAAtB;QACE,cAAS,GAAgB;YACvB,QAAQ,EAAE,EAAE;YACZ,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,KAAK;YAClB,YAAY,EAAE,EAAE;YAChB,gBAAgB,EAAE,CAAC;YACnB,UAAU,EAAE,KAAK;YACjB,iBAAiB,EAAE,IAAI;YACvB,iBAAiB,EAAE,IAAI;YACvB,kBAAkB,EAAE,CAAC;YACrB,eAAe,EAAE,EAAE;YACnB,0BAA0B,EACxB,mDAAmD;YACrD,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,KAAK;SACnB,CAAC;IAmBJ,CAAC;IAjBC,SAAS,CAAC,UAAyB,EAAE,KAAgC;QACnE,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,WAAW,CAAC,MAAM;gBAAE,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,WAAW,CACT,UAAyB,EACzB,KAAgC;QAEhC,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC","sourcesContent":["import { SingletonPmAdapter, AppObjectRepo } from \"@vived/core\";\r\nimport { ProcedurePM } from \"../PM/ProcedurePM\";\r\nimport { ProcedureVM } from \"../types\";\r\n\r\nclass ProcedureAdapter implements SingletonPmAdapter<ProcedureVM> {\r\n defaultVM: ProcedureVM = {\r\n eventIds: [],\r\n orderMatters: true,\r\n showHints: true,\r\n isQuiz: false,\r\n isRecording: false,\r\n userEventLog: [],\r\n currentStepIndex: 0,\r\n isComplete: false,\r\n validationMessage: null,\r\n nextExpectedEvent: null,\r\n progressPercentage: 0,\r\n availableEvents: [],\r\n authoringValidationMessage:\r\n \"At least one event must be added to the procedure\",\r\n score: null,\r\n isSubmitted: false,\r\n };\r\n\r\n subscribe(appObjects: AppObjectRepo, setVM: (vm: ProcedureVM) => void): void {\r\n const procedurePM = ProcedurePM.get(appObjects);\r\n if (procedurePM) {\r\n procedurePM.addView(setVM);\r\n if (procedurePM.lastVM) setVM(procedurePM.lastVM);\r\n }\r\n }\r\n\r\n unsubscribe(\r\n appObjects: AppObjectRepo,\r\n setVM: (vm: ProcedureVM) => void,\r\n ): void {\r\n const procedurePM = ProcedurePM.get(appObjects);\r\n if (procedurePM) {\r\n procedurePM.removeView(setVM);\r\n }\r\n }\r\n}\r\n\r\nexport const procedureAdapter = new ProcedureAdapter();\r\n"]}
@@ -180,6 +180,13 @@ class ProcedureEntityImp extends ProcedureEntity {
180
180
  this._isQuiz = isQuiz;
181
181
  this.updateState();
182
182
  }
183
+ get isRecording() {
184
+ return this._isRecording;
185
+ }
186
+ setIsRecording(value) {
187
+ this._isRecording = value;
188
+ this.updateState();
189
+ }
183
190
  getProgressPercentage() {
184
191
  if (this._eventIds.length === 0)
185
192
  return 0;
@@ -252,6 +259,7 @@ class ProcedureEntityImp extends ProcedureEntity {
252
259
  validationMessage: this._validationMessage,
253
260
  score: this._score,
254
261
  isSubmitted: this._isSubmitted,
262
+ isRecording: this._isRecording,
255
263
  });
256
264
  this.memoizedState.val = stateHash;
257
265
  }
@@ -261,6 +269,7 @@ class ProcedureEntityImp extends ProcedureEntity {
261
269
  this._orderMatters = true;
262
270
  this._showHints = true;
263
271
  this._isQuiz = false;
272
+ this._isRecording = false;
264
273
  this._userEventLog = [];
265
274
  this._currentStepIndex = 0;
266
275
  this._validationMessage = null;
@@ -1 +1 @@
1
- {"version":3,"file":"ProcedureEntity.js","sourceRoot":"","sources":["../../../../src/Procedure/Entities/ProcedureEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n MemoizedString,\r\n} from \"@vived/core\";\r\nimport { Challenge } from \"../../Challenge\";\r\n\r\nexport abstract class ProcedureEntity\r\n extends AppObjectEntity\r\n implements Challenge\r\n{\r\n static readonly type = \"ProcedureEntity\";\r\n\r\n readonly challengeID = \"PROCEDURE\";\r\n name = \"Procedure\";\r\n abstract get helpHeading(): string;\r\n abstract get consumerHelpText(): string;\r\n authorHelpText =\r\n \"Create step-by-step procedures by selecting events that users must emit.\";\r\n\r\n abstract get eventIds(): string[];\r\n abstract get orderMatters(): boolean;\r\n abstract get showHints(): boolean;\r\n abstract get isQuiz(): boolean;\r\n abstract get userEventLog(): string[];\r\n abstract get currentStepIndex(): number;\r\n abstract get isComplete(): boolean;\r\n abstract get validationMessage(): string | null;\r\n abstract get score(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null;\r\n abstract get isSubmitted(): boolean;\r\n\r\n abstract addEventId(eventId: string): void;\r\n abstract removeEventId(eventId: string): void;\r\n abstract clearEventIds(): void;\r\n abstract recordUserEvent(eventId: string): void;\r\n abstract validateProgress(): string | null;\r\n abstract getNextExpectedEvent(): string | null;\r\n abstract reset(): void;\r\n abstract moveEventUp(index: number): void;\r\n abstract moveEventDown(index: number): void;\r\n abstract getAuthoringValidationMessage(): string | null;\r\n\r\n abstract setOrderMatters(orderMatters: boolean): void;\r\n abstract setShowHints(showHints: boolean): void;\r\n abstract setIsQuiz(isQuiz: boolean): void;\r\n\r\n abstract getProgressPercentage(): number;\r\n abstract calculateScore(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n };\r\n abstract submit(): void;\r\n\r\n static get = (appObjects: AppObjectRepo): ProcedureEntity | undefined =>\r\n getSingletonComponent(ProcedureEntity.type, appObjects);\r\n}\r\n\r\nexport function makeProcedureEntity(appObject: AppObject): ProcedureEntity {\r\n return new ProcedureEntityImp(appObject);\r\n}\r\n\r\nclass ProcedureEntityImp extends ProcedureEntity {\r\n private _eventIds: string[] = [];\r\n private _orderMatters = true;\r\n private _showHints = true;\r\n private _isQuiz = false;\r\n private _userEventLog: string[] = [];\r\n private _currentStepIndex = 0;\r\n private _validationMessage: string | null = null;\r\n private _score: {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null = null;\r\n private _isSubmitted = false;\r\n\r\n get helpHeading(): string {\r\n if (this._isQuiz) return \"Procedure Challenge\";\r\n else return \"Procedure Training\";\r\n }\r\n\r\n get consumerHelpText(): string {\r\n if (this._isQuiz)\r\n return \"Complete the procedure challenge on your own and get scored after submitting.\";\r\n else return \"Follow the steps in order to complete the training procedure.\";\r\n }\r\n\r\n private memoizedState = new MemoizedString(\"\", this.notifyOnChange);\r\n\r\n get eventIds(): string[] {\r\n return [...this._eventIds];\r\n }\r\n\r\n get orderMatters(): boolean {\r\n return this._orderMatters;\r\n }\r\n\r\n get showHints(): boolean {\r\n return this._showHints;\r\n }\r\n\r\n get isQuiz(): boolean {\r\n return this._isQuiz;\r\n }\r\n\r\n get userEventLog(): string[] {\r\n return [...this._userEventLog];\r\n }\r\n\r\n get currentStepIndex(): number {\r\n return this._currentStepIndex;\r\n }\r\n\r\n get isComplete(): boolean {\r\n if (this._eventIds.length === 0) return false;\r\n\r\n if (this._orderMatters) {\r\n return this._currentStepIndex >= this._eventIds.length;\r\n } else {\r\n const requiredEvents = new Set(this._eventIds);\r\n const emittedEvents = new Set(this._userEventLog);\r\n return Array.from(requiredEvents).every((event) =>\r\n emittedEvents.has(event),\r\n );\r\n }\r\n }\r\n\r\n get validationMessage(): string | null {\r\n return this._validationMessage;\r\n }\r\n\r\n get score(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null {\r\n return this._score;\r\n }\r\n\r\n get isSubmitted(): boolean {\r\n return this._isSubmitted;\r\n }\r\n\r\n addEventId(eventId: string): void {\r\n if (this._eventIds.includes(eventId)) {\r\n this._validationMessage = `Event '${eventId}' is already in the procedure`;\r\n this.updateState();\r\n return;\r\n }\r\n\r\n this._eventIds.push(eventId);\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n removeEventId(eventId: string): void {\r\n const index = this._eventIds.indexOf(eventId);\r\n if (index === -1) {\r\n this._validationMessage = `Event '${eventId}' is not in the procedure`;\r\n this.updateState();\r\n return;\r\n }\r\n\r\n this._eventIds.splice(index, 1);\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n clearEventIds(): void {\r\n this._eventIds = [];\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n moveEventUp(index: number): void {\r\n if (index <= 0 || index >= this._eventIds.length) {\r\n this._validationMessage = \"Cannot move event up - invalid position\";\r\n this.updateState();\r\n return;\r\n }\r\n\r\n const temp = this._eventIds[index];\r\n this._eventIds[index] = this._eventIds[index - 1];\r\n this._eventIds[index - 1] = temp;\r\n\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n moveEventDown(index: number): void {\r\n if (index < 0 || index >= this._eventIds.length - 1) {\r\n this._validationMessage = \"Cannot move event down - invalid position\";\r\n this.updateState();\r\n return;\r\n }\r\n\r\n const temp = this._eventIds[index];\r\n this._eventIds[index] = this._eventIds[index + 1];\r\n this._eventIds[index + 1] = temp;\r\n\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n recordUserEvent(eventId: string): void {\r\n if (!this._eventIds.includes(eventId)) {\r\n return;\r\n }\r\n\r\n this._userEventLog.push(eventId);\r\n\r\n if (this._orderMatters) {\r\n if (this._currentStepIndex < this._eventIds.length) {\r\n const expectedEvent = this._eventIds[this._currentStepIndex];\r\n if (eventId === expectedEvent) {\r\n this._currentStepIndex++;\r\n this._validationMessage = null;\r\n } else {\r\n this._validationMessage = `Expected '${expectedEvent}', but got '${eventId}'`;\r\n }\r\n }\r\n }\r\n\r\n this.updateState();\r\n }\r\n\r\n validateProgress(): string | null {\r\n if (this._eventIds.length === 0) {\r\n return \"At least one event must be added to the procedure\";\r\n }\r\n\r\n if (this.isComplete) {\r\n return null;\r\n }\r\n\r\n if (this._orderMatters && this._validationMessage) {\r\n return this._validationMessage;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n getNextExpectedEvent(): string | null {\r\n if (!this._showHints || this._eventIds.length === 0) {\r\n return null;\r\n }\r\n\r\n if (this._orderMatters) {\r\n if (this._currentStepIndex < this._eventIds.length) {\r\n return this._eventIds[this._currentStepIndex];\r\n }\r\n } else {\r\n const emittedEvents = new Set(this._userEventLog);\r\n return (\r\n this._eventIds.find((eventId) => !emittedEvents.has(eventId)) || null\r\n );\r\n }\r\n\r\n return null;\r\n }\r\n\r\n reset(): void {\r\n this._userEventLog = [];\r\n this._currentStepIndex = 0;\r\n this._validationMessage = null;\r\n this._score = null;\r\n this._isSubmitted = false;\r\n this.updateState();\r\n }\r\n\r\n setOrderMatters(orderMatters: boolean): void {\r\n this._orderMatters = orderMatters;\r\n this.updateState();\r\n }\r\n\r\n setShowHints(showHints: boolean): void {\r\n this._showHints = showHints;\r\n this.updateState();\r\n }\r\n\r\n setIsQuiz(isQuiz: boolean): void {\r\n this._isQuiz = isQuiz;\r\n this.updateState();\r\n }\r\n\r\n getProgressPercentage(): number {\r\n if (this._eventIds.length === 0) return 0;\r\n\r\n if (this._orderMatters) {\r\n return Math.round((this._currentStepIndex / this._eventIds.length) * 100);\r\n } else {\r\n const requiredEvents = new Set(this._eventIds);\r\n const emittedEvents = new Set(this._userEventLog);\r\n const completedCount = Array.from(requiredEvents).filter((event) =>\r\n emittedEvents.has(event),\r\n ).length;\r\n return Math.round((completedCount / this._eventIds.length) * 100);\r\n }\r\n }\r\n\r\n calculateScore(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } {\r\n if (this._eventIds.length === 0) {\r\n return { percentage: 0, comparison: [] };\r\n }\r\n\r\n const comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[] = [];\r\n let correctCount = 0;\r\n\r\n if (this._orderMatters) {\r\n for (let i = 0; i < this._eventIds.length; i++) {\r\n const eventId = this._eventIds[i];\r\n const expected = true;\r\n const actual =\r\n i < this._userEventLog.length && this._userEventLog[i] === eventId;\r\n const correct = actual;\r\n\r\n comparison.push({ eventId, expected, actual, correct });\r\n if (correct) correctCount++;\r\n }\r\n } else {\r\n const emittedEvents = new Set(this._userEventLog);\r\n for (const eventId of this._eventIds) {\r\n const expected = true;\r\n const actual = emittedEvents.has(eventId);\r\n const correct = actual;\r\n\r\n comparison.push({ eventId, expected, actual, correct });\r\n if (correct) correctCount++;\r\n }\r\n }\r\n\r\n const percentage = Math.round(\r\n (correctCount / this._eventIds.length) * 100,\r\n );\r\n return { percentage, comparison };\r\n }\r\n\r\n submit(): void {\r\n if (!this._isQuiz) {\r\n this._validationMessage = \"Cannot submit: not in quiz mode\";\r\n this.updateState();\r\n return;\r\n }\r\n\r\n this._score = this.calculateScore();\r\n this._isSubmitted = true;\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n getAuthoringValidationMessage(): string | null {\r\n if (this._eventIds.length === 0) {\r\n return \"At least one event must be added to the procedure\";\r\n }\r\n return this._validationMessage;\r\n }\r\n\r\n private updateState(): void {\r\n const stateHash = JSON.stringify({\r\n eventIds: this._eventIds,\r\n orderMatters: this._orderMatters,\r\n showHints: this._showHints,\r\n isQuiz: this._isQuiz,\r\n userEventLog: this._userEventLog,\r\n currentStepIndex: this._currentStepIndex,\r\n validationMessage: this._validationMessage,\r\n score: this._score,\r\n isSubmitted: this._isSubmitted,\r\n });\r\n\r\n this.memoizedState.val = stateHash;\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, ProcedureEntity.type);\r\n this.appObjects.registerSingleton(this);\r\n this.updateState();\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ProcedureEntity.js","sourceRoot":"","sources":["../../../../src/Procedure/Entities/ProcedureEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo,\r\n getSingletonComponent,\r\n MemoizedString,\r\n} from \"@vived/core\";\r\nimport { Challenge } from \"../../Challenge\";\r\n\r\nexport abstract class ProcedureEntity\r\n extends AppObjectEntity\r\n implements Challenge\r\n{\r\n static readonly type = \"ProcedureEntity\";\r\n\r\n readonly challengeID = \"PROCEDURE\";\r\n name = \"Procedure\";\r\n abstract get helpHeading(): string;\r\n abstract get consumerHelpText(): string;\r\n authorHelpText =\r\n \"Create step-by-step procedures by selecting events that users must emit.\";\r\n\r\n abstract get eventIds(): string[];\r\n abstract get orderMatters(): boolean;\r\n abstract get showHints(): boolean;\r\n abstract get isQuiz(): boolean;\r\n abstract get userEventLog(): string[];\r\n abstract get currentStepIndex(): number;\r\n abstract get isComplete(): boolean;\r\n abstract get validationMessage(): string | null;\r\n abstract get score(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null;\r\n abstract get isSubmitted(): boolean;\r\n\r\n abstract addEventId(eventId: string): void;\r\n abstract removeEventId(eventId: string): void;\r\n abstract clearEventIds(): void;\r\n abstract recordUserEvent(eventId: string): void;\r\n abstract validateProgress(): string | null;\r\n abstract getNextExpectedEvent(): string | null;\r\n abstract reset(): void;\r\n abstract moveEventUp(index: number): void;\r\n abstract moveEventDown(index: number): void;\r\n abstract getAuthoringValidationMessage(): string | null;\r\n\r\n abstract setOrderMatters(orderMatters: boolean): void;\r\n abstract setShowHints(showHints: boolean): void;\r\n abstract setIsQuiz(isQuiz: boolean): void;\r\n\r\n abstract get isRecording(): boolean;\r\n abstract setIsRecording(value: boolean): void;\r\n\r\n abstract getProgressPercentage(): number;\r\n abstract calculateScore(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n };\r\n abstract submit(): void;\r\n\r\n static get = (appObjects: AppObjectRepo): ProcedureEntity | undefined =>\r\n getSingletonComponent(ProcedureEntity.type, appObjects);\r\n}\r\n\r\nexport function makeProcedureEntity(appObject: AppObject): ProcedureEntity {\r\n return new ProcedureEntityImp(appObject);\r\n}\r\n\r\nclass ProcedureEntityImp extends ProcedureEntity {\r\n private _eventIds: string[] = [];\r\n private _orderMatters = true;\r\n private _showHints = true;\r\n private _isQuiz = false;\r\n private _isRecording = false;\r\n private _userEventLog: string[] = [];\r\n private _currentStepIndex = 0;\r\n private _validationMessage: string | null = null;\r\n private _score: {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null = null;\r\n private _isSubmitted = false;\r\n\r\n get helpHeading(): string {\r\n if (this._isQuiz) return \"Procedure Challenge\";\r\n else return \"Procedure Training\";\r\n }\r\n\r\n get consumerHelpText(): string {\r\n if (this._isQuiz)\r\n return \"Complete the procedure challenge on your own and get scored after submitting.\";\r\n else return \"Follow the steps in order to complete the training procedure.\";\r\n }\r\n\r\n private memoizedState = new MemoizedString(\"\", this.notifyOnChange);\r\n\r\n get eventIds(): string[] {\r\n return [...this._eventIds];\r\n }\r\n\r\n get orderMatters(): boolean {\r\n return this._orderMatters;\r\n }\r\n\r\n get showHints(): boolean {\r\n return this._showHints;\r\n }\r\n\r\n get isQuiz(): boolean {\r\n return this._isQuiz;\r\n }\r\n\r\n get userEventLog(): string[] {\r\n return [...this._userEventLog];\r\n }\r\n\r\n get currentStepIndex(): number {\r\n return this._currentStepIndex;\r\n }\r\n\r\n get isComplete(): boolean {\r\n if (this._eventIds.length === 0) return false;\r\n\r\n if (this._orderMatters) {\r\n return this._currentStepIndex >= this._eventIds.length;\r\n } else {\r\n const requiredEvents = new Set(this._eventIds);\r\n const emittedEvents = new Set(this._userEventLog);\r\n return Array.from(requiredEvents).every((event) =>\r\n emittedEvents.has(event),\r\n );\r\n }\r\n }\r\n\r\n get validationMessage(): string | null {\r\n return this._validationMessage;\r\n }\r\n\r\n get score(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } | null {\r\n return this._score;\r\n }\r\n\r\n get isSubmitted(): boolean {\r\n return this._isSubmitted;\r\n }\r\n\r\n addEventId(eventId: string): void {\r\n if (this._eventIds.includes(eventId)) {\r\n this._validationMessage = `Event '${eventId}' is already in the procedure`;\r\n this.updateState();\r\n return;\r\n }\r\n\r\n this._eventIds.push(eventId);\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n removeEventId(eventId: string): void {\r\n const index = this._eventIds.indexOf(eventId);\r\n if (index === -1) {\r\n this._validationMessage = `Event '${eventId}' is not in the procedure`;\r\n this.updateState();\r\n return;\r\n }\r\n\r\n this._eventIds.splice(index, 1);\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n clearEventIds(): void {\r\n this._eventIds = [];\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n moveEventUp(index: number): void {\r\n if (index <= 0 || index >= this._eventIds.length) {\r\n this._validationMessage = \"Cannot move event up - invalid position\";\r\n this.updateState();\r\n return;\r\n }\r\n\r\n const temp = this._eventIds[index];\r\n this._eventIds[index] = this._eventIds[index - 1];\r\n this._eventIds[index - 1] = temp;\r\n\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n moveEventDown(index: number): void {\r\n if (index < 0 || index >= this._eventIds.length - 1) {\r\n this._validationMessage = \"Cannot move event down - invalid position\";\r\n this.updateState();\r\n return;\r\n }\r\n\r\n const temp = this._eventIds[index];\r\n this._eventIds[index] = this._eventIds[index + 1];\r\n this._eventIds[index + 1] = temp;\r\n\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n recordUserEvent(eventId: string): void {\r\n if (!this._eventIds.includes(eventId)) {\r\n return;\r\n }\r\n\r\n this._userEventLog.push(eventId);\r\n\r\n if (this._orderMatters) {\r\n if (this._currentStepIndex < this._eventIds.length) {\r\n const expectedEvent = this._eventIds[this._currentStepIndex];\r\n if (eventId === expectedEvent) {\r\n this._currentStepIndex++;\r\n this._validationMessage = null;\r\n } else {\r\n this._validationMessage = `Expected '${expectedEvent}', but got '${eventId}'`;\r\n }\r\n }\r\n }\r\n\r\n this.updateState();\r\n }\r\n\r\n validateProgress(): string | null {\r\n if (this._eventIds.length === 0) {\r\n return \"At least one event must be added to the procedure\";\r\n }\r\n\r\n if (this.isComplete) {\r\n return null;\r\n }\r\n\r\n if (this._orderMatters && this._validationMessage) {\r\n return this._validationMessage;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n getNextExpectedEvent(): string | null {\r\n if (!this._showHints || this._eventIds.length === 0) {\r\n return null;\r\n }\r\n\r\n if (this._orderMatters) {\r\n if (this._currentStepIndex < this._eventIds.length) {\r\n return this._eventIds[this._currentStepIndex];\r\n }\r\n } else {\r\n const emittedEvents = new Set(this._userEventLog);\r\n return (\r\n this._eventIds.find((eventId) => !emittedEvents.has(eventId)) || null\r\n );\r\n }\r\n\r\n return null;\r\n }\r\n\r\n reset(): void {\r\n this._userEventLog = [];\r\n this._currentStepIndex = 0;\r\n this._validationMessage = null;\r\n this._score = null;\r\n this._isSubmitted = false;\r\n this.updateState();\r\n }\r\n\r\n setOrderMatters(orderMatters: boolean): void {\r\n this._orderMatters = orderMatters;\r\n this.updateState();\r\n }\r\n\r\n setShowHints(showHints: boolean): void {\r\n this._showHints = showHints;\r\n this.updateState();\r\n }\r\n\r\n setIsQuiz(isQuiz: boolean): void {\r\n this._isQuiz = isQuiz;\r\n this.updateState();\r\n }\r\n\r\n get isRecording(): boolean {\r\n return this._isRecording;\r\n }\r\n\r\n setIsRecording(value: boolean): void {\r\n this._isRecording = value;\r\n this.updateState();\r\n }\r\n\r\n getProgressPercentage(): number {\r\n if (this._eventIds.length === 0) return 0;\r\n\r\n if (this._orderMatters) {\r\n return Math.round((this._currentStepIndex / this._eventIds.length) * 100);\r\n } else {\r\n const requiredEvents = new Set(this._eventIds);\r\n const emittedEvents = new Set(this._userEventLog);\r\n const completedCount = Array.from(requiredEvents).filter((event) =>\r\n emittedEvents.has(event),\r\n ).length;\r\n return Math.round((completedCount / this._eventIds.length) * 100);\r\n }\r\n }\r\n\r\n calculateScore(): {\r\n percentage: number;\r\n comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[];\r\n } {\r\n if (this._eventIds.length === 0) {\r\n return { percentage: 0, comparison: [] };\r\n }\r\n\r\n const comparison: {eventId: string; expected: boolean; actual: boolean; correct: boolean}[] = [];\r\n let correctCount = 0;\r\n\r\n if (this._orderMatters) {\r\n for (let i = 0; i < this._eventIds.length; i++) {\r\n const eventId = this._eventIds[i];\r\n const expected = true;\r\n const actual =\r\n i < this._userEventLog.length && this._userEventLog[i] === eventId;\r\n const correct = actual;\r\n\r\n comparison.push({ eventId, expected, actual, correct });\r\n if (correct) correctCount++;\r\n }\r\n } else {\r\n const emittedEvents = new Set(this._userEventLog);\r\n for (const eventId of this._eventIds) {\r\n const expected = true;\r\n const actual = emittedEvents.has(eventId);\r\n const correct = actual;\r\n\r\n comparison.push({ eventId, expected, actual, correct });\r\n if (correct) correctCount++;\r\n }\r\n }\r\n\r\n const percentage = Math.round(\r\n (correctCount / this._eventIds.length) * 100,\r\n );\r\n return { percentage, comparison };\r\n }\r\n\r\n submit(): void {\r\n if (!this._isQuiz) {\r\n this._validationMessage = \"Cannot submit: not in quiz mode\";\r\n this.updateState();\r\n return;\r\n }\r\n\r\n this._score = this.calculateScore();\r\n this._isSubmitted = true;\r\n this._validationMessage = null;\r\n this.updateState();\r\n }\r\n\r\n getAuthoringValidationMessage(): string | null {\r\n if (this._eventIds.length === 0) {\r\n return \"At least one event must be added to the procedure\";\r\n }\r\n return this._validationMessage;\r\n }\r\n\r\n private updateState(): void {\r\n const stateHash = JSON.stringify({\r\n eventIds: this._eventIds,\r\n orderMatters: this._orderMatters,\r\n showHints: this._showHints,\r\n isQuiz: this._isQuiz,\r\n userEventLog: this._userEventLog,\r\n currentStepIndex: this._currentStepIndex,\r\n validationMessage: this._validationMessage,\r\n score: this._score,\r\n isSubmitted: this._isSubmitted,\r\n isRecording: this._isRecording,\r\n });\r\n\r\n this.memoizedState.val = stateHash;\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, ProcedureEntity.type);\r\n this.appObjects.registerSingleton(this);\r\n this.updateState();\r\n }\r\n}\r\n"]}
@@ -14,6 +14,7 @@ import { makeSetProcedureShowHintsUC } from "../UCs/SetProcedureShowHintsUC";
14
14
  import { makeSetProcedureIsQuizUC } from "../UCs/SetProcedureIsQuizUC";
15
15
  import { makeSubmitProcedureQuizUC } from "../UCs/SubmitProcedureQuizUC";
16
16
  import { makeUpdateProcedureEventsUCHook } from "../UCs/UpdateProcedureEventsUCHook";
17
+ import { makeRecordProcedureSessionUC } from "../UCs/RecordProcedureSessionUC";
17
18
  import { makeProcedurePM, ProcedurePM } from "../PM/ProcedurePM";
18
19
  export class ProcedureFeatureFactory extends DomainFactory {
19
20
  constructor() {
@@ -37,6 +38,7 @@ export class ProcedureFeatureFactory extends DomainFactory {
37
38
  makeSetProcedureIsQuizUC(this.appObject);
38
39
  makeSubmitProcedureQuizUC(this.appObject);
39
40
  makeUpdateProcedureEventsUCHook(this.appObject);
41
+ makeRecordProcedureSessionUC(this.appObject);
40
42
  }
41
43
  setupPMs() {
42
44
  makeProcedurePM(this.appObject);