hzl-core 0.1.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 (177) hide show
  1. package/dist/__tests__/backup/backup-restore.test.d.ts +2 -0
  2. package/dist/__tests__/backup/backup-restore.test.d.ts.map +1 -0
  3. package/dist/__tests__/backup/backup-restore.test.js +200 -0
  4. package/dist/__tests__/backup/backup-restore.test.js.map +1 -0
  5. package/dist/__tests__/backup/import-export.test.d.ts +2 -0
  6. package/dist/__tests__/backup/import-export.test.d.ts.map +1 -0
  7. package/dist/__tests__/backup/import-export.test.js +341 -0
  8. package/dist/__tests__/backup/import-export.test.js.map +1 -0
  9. package/dist/__tests__/concurrency/stress.test.d.ts +2 -0
  10. package/dist/__tests__/concurrency/stress.test.d.ts.map +1 -0
  11. package/dist/__tests__/concurrency/stress.test.js +274 -0
  12. package/dist/__tests__/concurrency/stress.test.js.map +1 -0
  13. package/dist/__tests__/concurrency/worker.d.ts +2 -0
  14. package/dist/__tests__/concurrency/worker.d.ts.map +1 -0
  15. package/dist/__tests__/concurrency/worker.js +84 -0
  16. package/dist/__tests__/concurrency/worker.js.map +1 -0
  17. package/dist/__tests__/migrations/upgrade.test.d.ts +2 -0
  18. package/dist/__tests__/migrations/upgrade.test.d.ts.map +1 -0
  19. package/dist/__tests__/migrations/upgrade.test.js +203 -0
  20. package/dist/__tests__/migrations/upgrade.test.js.map +1 -0
  21. package/dist/__tests__/projections/rebuild-equivalence.test.d.ts +2 -0
  22. package/dist/__tests__/projections/rebuild-equivalence.test.d.ts.map +1 -0
  23. package/dist/__tests__/projections/rebuild-equivalence.test.js +276 -0
  24. package/dist/__tests__/projections/rebuild-equivalence.test.js.map +1 -0
  25. package/dist/__tests__/properties/invariants.test.d.ts +2 -0
  26. package/dist/__tests__/properties/invariants.test.d.ts.map +1 -0
  27. package/dist/__tests__/properties/invariants.test.js +314 -0
  28. package/dist/__tests__/properties/invariants.test.js.map +1 -0
  29. package/dist/db/connection.d.ts +13 -0
  30. package/dist/db/connection.d.ts.map +1 -0
  31. package/dist/db/connection.js +52 -0
  32. package/dist/db/connection.js.map +1 -0
  33. package/dist/db/connection.test.d.ts +2 -0
  34. package/dist/db/connection.test.d.ts.map +1 -0
  35. package/dist/db/connection.test.js +63 -0
  36. package/dist/db/connection.test.js.map +1 -0
  37. package/dist/db/migrations/v2.d.ts +2 -0
  38. package/dist/db/migrations/v2.d.ts.map +1 -0
  39. package/dist/db/migrations/v2.js +4 -0
  40. package/dist/db/migrations/v2.js.map +1 -0
  41. package/dist/db/migrations.d.ts +4 -0
  42. package/dist/db/migrations.d.ts.map +1 -0
  43. package/dist/db/migrations.js +45 -0
  44. package/dist/db/migrations.js.map +1 -0
  45. package/dist/db/migrations.test.d.ts +2 -0
  46. package/dist/db/migrations.test.d.ts.map +1 -0
  47. package/dist/db/migrations.test.js +75 -0
  48. package/dist/db/migrations.test.js.map +1 -0
  49. package/dist/db/schema.d.ts +3 -0
  50. package/dist/db/schema.d.ts.map +1 -0
  51. package/dist/db/schema.js +114 -0
  52. package/dist/db/schema.js.map +1 -0
  53. package/dist/events/store.d.ts +33 -0
  54. package/dist/events/store.d.ts.map +1 -0
  55. package/dist/events/store.js +81 -0
  56. package/dist/events/store.js.map +1 -0
  57. package/dist/events/store.test.d.ts +2 -0
  58. package/dist/events/store.test.d.ts.map +1 -0
  59. package/dist/events/store.test.js +138 -0
  60. package/dist/events/store.test.js.map +1 -0
  61. package/dist/events/types.d.ts +106 -0
  62. package/dist/events/types.d.ts.map +1 -0
  63. package/dist/events/types.js +87 -0
  64. package/dist/events/types.js.map +1 -0
  65. package/dist/events/validation.test.d.ts +2 -0
  66. package/dist/events/validation.test.d.ts.map +1 -0
  67. package/dist/events/validation.test.js +83 -0
  68. package/dist/events/validation.test.js.map +1 -0
  69. package/dist/fixtures/sample-data.d.ts +16 -0
  70. package/dist/fixtures/sample-data.d.ts.map +1 -0
  71. package/dist/fixtures/sample-data.js +148 -0
  72. package/dist/fixtures/sample-data.js.map +1 -0
  73. package/dist/index.d.ts +27 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +44 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/index.test.d.ts +2 -0
  78. package/dist/index.test.d.ts.map +1 -0
  79. package/dist/index.test.js +102 -0
  80. package/dist/index.test.js.map +1 -0
  81. package/dist/projections/comments-checkpoints.d.ts +11 -0
  82. package/dist/projections/comments-checkpoints.d.ts.map +1 -0
  83. package/dist/projections/comments-checkpoints.js +33 -0
  84. package/dist/projections/comments-checkpoints.js.map +1 -0
  85. package/dist/projections/comments-checkpoints.test.d.ts +2 -0
  86. package/dist/projections/comments-checkpoints.test.d.ts.map +1 -0
  87. package/dist/projections/comments-checkpoints.test.js +72 -0
  88. package/dist/projections/comments-checkpoints.test.js.map +1 -0
  89. package/dist/projections/dependencies.d.ts +12 -0
  90. package/dist/projections/dependencies.d.ts.map +1 -0
  91. package/dist/projections/dependencies.js +39 -0
  92. package/dist/projections/dependencies.js.map +1 -0
  93. package/dist/projections/dependencies.test.d.ts +2 -0
  94. package/dist/projections/dependencies.test.d.ts.map +1 -0
  95. package/dist/projections/dependencies.test.js +97 -0
  96. package/dist/projections/dependencies.test.js.map +1 -0
  97. package/dist/projections/engine.d.ts +18 -0
  98. package/dist/projections/engine.d.ts.map +1 -0
  99. package/dist/projections/engine.js +56 -0
  100. package/dist/projections/engine.js.map +1 -0
  101. package/dist/projections/engine.test.d.ts +2 -0
  102. package/dist/projections/engine.test.d.ts.map +1 -0
  103. package/dist/projections/engine.test.js +92 -0
  104. package/dist/projections/engine.test.js.map +1 -0
  105. package/dist/projections/rebuild.d.ts +4 -0
  106. package/dist/projections/rebuild.d.ts.map +1 -0
  107. package/dist/projections/rebuild.js +26 -0
  108. package/dist/projections/rebuild.js.map +1 -0
  109. package/dist/projections/rebuild.test.d.ts +2 -0
  110. package/dist/projections/rebuild.test.d.ts.map +1 -0
  111. package/dist/projections/rebuild.test.js +59 -0
  112. package/dist/projections/rebuild.test.js.map +1 -0
  113. package/dist/projections/search.d.ts +11 -0
  114. package/dist/projections/search.d.ts.map +1 -0
  115. package/dist/projections/search.js +39 -0
  116. package/dist/projections/search.js.map +1 -0
  117. package/dist/projections/search.test.d.ts +2 -0
  118. package/dist/projections/search.test.d.ts.map +1 -0
  119. package/dist/projections/search.test.js +78 -0
  120. package/dist/projections/search.test.js.map +1 -0
  121. package/dist/projections/tags.d.ts +12 -0
  122. package/dist/projections/tags.d.ts.map +1 -0
  123. package/dist/projections/tags.js +41 -0
  124. package/dist/projections/tags.js.map +1 -0
  125. package/dist/projections/tags.test.d.ts +2 -0
  126. package/dist/projections/tags.test.d.ts.map +1 -0
  127. package/dist/projections/tags.test.js +69 -0
  128. package/dist/projections/tags.test.js.map +1 -0
  129. package/dist/projections/tasks-current.d.ts +14 -0
  130. package/dist/projections/tasks-current.d.ts.map +1 -0
  131. package/dist/projections/tasks-current.js +110 -0
  132. package/dist/projections/tasks-current.js.map +1 -0
  133. package/dist/projections/tasks-current.test.d.ts +2 -0
  134. package/dist/projections/tasks-current.test.d.ts.map +1 -0
  135. package/dist/projections/tasks-current.test.js +215 -0
  136. package/dist/projections/tasks-current.test.js.map +1 -0
  137. package/dist/projections/types.d.ts +13 -0
  138. package/dist/projections/types.d.ts.map +1 -0
  139. package/dist/projections/types.js +2 -0
  140. package/dist/projections/types.js.map +1 -0
  141. package/dist/services/backup-service.d.ts +16 -0
  142. package/dist/services/backup-service.d.ts.map +1 -0
  143. package/dist/services/backup-service.js +114 -0
  144. package/dist/services/backup-service.js.map +1 -0
  145. package/dist/services/search-service.d.ts +27 -0
  146. package/dist/services/search-service.d.ts.map +1 -0
  147. package/dist/services/search-service.js +33 -0
  148. package/dist/services/search-service.js.map +1 -0
  149. package/dist/services/search-service.test.d.ts +2 -0
  150. package/dist/services/search-service.test.d.ts.map +1 -0
  151. package/dist/services/search-service.test.js +66 -0
  152. package/dist/services/search-service.test.js.map +1 -0
  153. package/dist/services/task-service.d.ts +147 -0
  154. package/dist/services/task-service.d.ts.map +1 -0
  155. package/dist/services/task-service.js +442 -0
  156. package/dist/services/task-service.js.map +1 -0
  157. package/dist/services/task-service.test.d.ts +2 -0
  158. package/dist/services/task-service.test.d.ts.map +1 -0
  159. package/dist/services/task-service.test.js +399 -0
  160. package/dist/services/task-service.test.js.map +1 -0
  161. package/dist/services/validation-service.d.ts +29 -0
  162. package/dist/services/validation-service.d.ts.map +1 -0
  163. package/dist/services/validation-service.js +74 -0
  164. package/dist/services/validation-service.js.map +1 -0
  165. package/dist/services/validation-service.test.d.ts +2 -0
  166. package/dist/services/validation-service.test.d.ts.map +1 -0
  167. package/dist/services/validation-service.test.js +67 -0
  168. package/dist/services/validation-service.test.js.map +1 -0
  169. package/dist/utils/id.d.ts +3 -0
  170. package/dist/utils/id.d.ts.map +1 -0
  171. package/dist/utils/id.js +12 -0
  172. package/dist/utils/id.js.map +1 -0
  173. package/dist/utils/id.test.d.ts +2 -0
  174. package/dist/utils/id.test.d.ts.map +1 -0
  175. package/dist/utils/id.test.js +24 -0
  176. package/dist/utils/id.test.js.map +1 -0
  177. package/package.json +83 -0
@@ -0,0 +1,276 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { createConnection } from '../../db/connection.js';
6
+ import { EventStore } from '../../events/store.js';
7
+ import { ProjectionEngine } from '../../projections/engine.js';
8
+ import { TasksCurrentProjector } from '../../projections/tasks-current.js';
9
+ import { DependenciesProjector } from '../../projections/dependencies.js';
10
+ import { TagsProjector } from '../../projections/tags.js';
11
+ import { SearchProjector } from '../../projections/search.js';
12
+ import { CommentsCheckpointsProjector } from '../../projections/comments-checkpoints.js';
13
+ import { rebuildAllProjections } from '../../projections/rebuild.js';
14
+ import { TaskService } from '../../services/task-service.js';
15
+ import { TaskStatus } from '../../events/types.js';
16
+ describe('Projection Rebuild Equivalence Tests', () => {
17
+ let tempDir;
18
+ let dbPath;
19
+ let db;
20
+ let eventStore;
21
+ let projectionEngine;
22
+ let taskService;
23
+ function setupProjectors(engine) {
24
+ engine.register(new TasksCurrentProjector());
25
+ engine.register(new DependenciesProjector());
26
+ engine.register(new TagsProjector());
27
+ engine.register(new SearchProjector());
28
+ engine.register(new CommentsCheckpointsProjector());
29
+ }
30
+ function captureProjectionState(database) {
31
+ return {
32
+ tasks: database.prepare('SELECT * FROM tasks_current ORDER BY task_id').all(),
33
+ dependencies: database
34
+ .prepare('SELECT * FROM task_dependencies ORDER BY task_id, depends_on_id')
35
+ .all(),
36
+ tags: database.prepare('SELECT * FROM task_tags ORDER BY task_id, tag').all(),
37
+ comments: database.prepare('SELECT * FROM task_comments ORDER BY event_rowid').all(),
38
+ checkpoints: database
39
+ .prepare('SELECT * FROM task_checkpoints ORDER BY event_rowid')
40
+ .all(),
41
+ search: database
42
+ .prepare('SELECT task_id, title, description FROM task_search ORDER BY task_id')
43
+ .all(),
44
+ };
45
+ }
46
+ beforeEach(() => {
47
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'hzl-rebuild-'));
48
+ dbPath = path.join(tempDir, 'test.db');
49
+ db = createConnection(dbPath);
50
+ eventStore = new EventStore(db);
51
+ projectionEngine = new ProjectionEngine(db);
52
+ setupProjectors(projectionEngine);
53
+ taskService = new TaskService(db, eventStore, projectionEngine);
54
+ });
55
+ afterEach(() => {
56
+ db.close();
57
+ fs.rmSync(tempDir, { recursive: true, force: true });
58
+ });
59
+ describe('incremental vs full rebuild equivalence', () => {
60
+ it('full rebuild produces identical state to incremental application', () => {
61
+ const task1 = taskService.createTask({
62
+ title: 'Task 1',
63
+ project: 'inbox',
64
+ tags: ['urgent', 'backend'],
65
+ priority: 2,
66
+ });
67
+ const task2 = taskService.createTask({
68
+ title: 'Task 2',
69
+ project: 'inbox',
70
+ depends_on: [task1.task_id],
71
+ });
72
+ taskService.setStatus(task1.task_id, TaskStatus.Ready);
73
+ taskService.claimTask(task1.task_id, {
74
+ author: 'agent-1',
75
+ lease_until: '2026-02-01T00:00:00Z',
76
+ });
77
+ taskService.addComment(task1.task_id, 'Working on it');
78
+ taskService.addCheckpoint(task1.task_id, 'step1', { progress: 50 });
79
+ taskService.completeTask(task1.task_id);
80
+ taskService.setStatus(task2.task_id, TaskStatus.Ready);
81
+ taskService.claimTask(task2.task_id, { author: 'agent-2' });
82
+ const incrementalState = captureProjectionState(db);
83
+ db.exec('DELETE FROM tasks_current');
84
+ db.exec('DELETE FROM task_dependencies');
85
+ db.exec('DELETE FROM task_tags');
86
+ db.exec('DELETE FROM task_comments');
87
+ db.exec('DELETE FROM task_checkpoints');
88
+ db.exec('DELETE FROM task_search');
89
+ db.exec('DELETE FROM projection_state');
90
+ rebuildAllProjections(db, projectionEngine);
91
+ const rebuiltState = captureProjectionState(db);
92
+ expect(rebuiltState.tasks).toEqual(incrementalState.tasks);
93
+ expect(rebuiltState.dependencies).toEqual(incrementalState.dependencies);
94
+ expect(rebuiltState.tags).toEqual(incrementalState.tags);
95
+ expect(rebuiltState.comments).toEqual(incrementalState.comments);
96
+ expect(rebuiltState.checkpoints).toEqual(incrementalState.checkpoints);
97
+ expect(rebuiltState.search).toEqual(incrementalState.search);
98
+ });
99
+ it('handles complex event sequences correctly', () => {
100
+ const tasks = [];
101
+ for (let i = 0; i < 10; i++) {
102
+ const task = taskService.createTask({
103
+ title: `Task ${i}`,
104
+ project: i % 2 === 0 ? 'project-a' : 'project-b',
105
+ tags: [`tag${i % 3}`],
106
+ priority: i % 4,
107
+ });
108
+ tasks.push(task.task_id);
109
+ }
110
+ for (let i = 1; i < tasks.length; i++) {
111
+ db.prepare('INSERT INTO task_dependencies (task_id, depends_on_id) VALUES (?, ?)').run(tasks[i], tasks[i - 1]);
112
+ }
113
+ taskService.setStatus(tasks[0], TaskStatus.Ready);
114
+ taskService.claimTask(tasks[0], { author: 'agent-1' });
115
+ taskService.addComment(tasks[0], 'Comment 1');
116
+ taskService.addComment(tasks[0], 'Comment 2');
117
+ taskService.addCheckpoint(tasks[0], 'checkpoint1');
118
+ taskService.completeTask(tasks[0]);
119
+ taskService.setStatus(tasks[1], TaskStatus.Ready);
120
+ taskService.claimTask(tasks[1], { author: 'agent-2' });
121
+ taskService.releaseTask(tasks[1], { reason: 'Blocked' });
122
+ taskService.claimTask(tasks[1], { author: 'agent-3' });
123
+ taskService.archiveTask(tasks[5], { reason: 'No longer needed' });
124
+ const originalState = captureProjectionState(db);
125
+ db.exec('DELETE FROM tasks_current');
126
+ db.exec('DELETE FROM task_dependencies');
127
+ db.exec('DELETE FROM task_tags');
128
+ db.exec('DELETE FROM task_comments');
129
+ db.exec('DELETE FROM task_checkpoints');
130
+ db.exec('DELETE FROM task_search');
131
+ db.exec('DELETE FROM projection_state');
132
+ rebuildAllProjections(db, projectionEngine);
133
+ const rebuiltState = captureProjectionState(db);
134
+ expect(rebuiltState.tasks).toEqual(originalState.tasks);
135
+ expect(rebuiltState.comments).toEqual(originalState.comments);
136
+ expect(rebuiltState.checkpoints).toEqual(originalState.checkpoints);
137
+ });
138
+ });
139
+ describe('partial corruption recovery', () => {
140
+ it('recovers from corrupted tasks_current projection', () => {
141
+ const task = taskService.createTask({ title: 'Test', project: 'inbox' });
142
+ taskService.setStatus(task.task_id, TaskStatus.Ready);
143
+ db.exec('DELETE FROM tasks_current');
144
+ const corruptedCount = db
145
+ .prepare('SELECT COUNT(*) as count FROM tasks_current')
146
+ .get();
147
+ expect(corruptedCount.count).toBe(0);
148
+ rebuildAllProjections(db, projectionEngine);
149
+ const recoveredTask = db
150
+ .prepare('SELECT * FROM tasks_current WHERE task_id = ?')
151
+ .get(task.task_id);
152
+ expect(recoveredTask).toBeDefined();
153
+ expect(recoveredTask.status).toBe('ready');
154
+ });
155
+ it('recovers from corrupted dependencies projection', () => {
156
+ const task1 = taskService.createTask({ title: 'Task 1', project: 'inbox' });
157
+ const task2 = taskService.createTask({
158
+ title: 'Task 2',
159
+ project: 'inbox',
160
+ depends_on: [task1.task_id],
161
+ });
162
+ db.exec('DELETE FROM task_dependencies');
163
+ rebuildAllProjections(db, projectionEngine);
164
+ const dep = db
165
+ .prepare('SELECT * FROM task_dependencies WHERE task_id = ?')
166
+ .get(task2.task_id);
167
+ expect(dep).toBeDefined();
168
+ });
169
+ it('recovers from corrupted tags projection', () => {
170
+ const task = taskService.createTask({
171
+ title: 'Tagged',
172
+ project: 'inbox',
173
+ tags: ['tag1', 'tag2'],
174
+ });
175
+ db.exec('DELETE FROM task_tags');
176
+ rebuildAllProjections(db, projectionEngine);
177
+ const tags = db
178
+ .prepare('SELECT tag FROM task_tags WHERE task_id = ? ORDER BY tag')
179
+ .all(task.task_id);
180
+ expect(tags.map((t) => t.tag)).toEqual(['tag1', 'tag2']);
181
+ });
182
+ it('recovers from corrupted search index', () => {
183
+ const task = taskService.createTask({
184
+ title: 'Searchable task',
185
+ project: 'inbox',
186
+ description: 'With description',
187
+ });
188
+ db.exec('DELETE FROM task_search');
189
+ rebuildAllProjections(db, projectionEngine);
190
+ const results = db
191
+ .prepare("SELECT task_id FROM task_search WHERE task_search MATCH 'Searchable'")
192
+ .all();
193
+ expect(results.map((r) => r.task_id)).toContain(task.task_id);
194
+ });
195
+ });
196
+ describe('rebuild idempotency', () => {
197
+ it('multiple rebuilds produce identical results', () => {
198
+ const task = taskService.createTask({
199
+ title: 'Task',
200
+ project: 'inbox',
201
+ tags: ['tag'],
202
+ });
203
+ taskService.setStatus(task.task_id, TaskStatus.Ready);
204
+ taskService.addComment(task.task_id, 'Comment');
205
+ db.exec('DELETE FROM tasks_current');
206
+ db.exec('DELETE FROM task_tags');
207
+ db.exec('DELETE FROM task_comments');
208
+ db.exec('DELETE FROM projection_state');
209
+ rebuildAllProjections(db, projectionEngine);
210
+ const state1 = captureProjectionState(db);
211
+ db.exec('DELETE FROM tasks_current');
212
+ db.exec('DELETE FROM task_tags');
213
+ db.exec('DELETE FROM task_comments');
214
+ db.exec('DELETE FROM projection_state');
215
+ rebuildAllProjections(db, projectionEngine);
216
+ const state2 = captureProjectionState(db);
217
+ db.exec('DELETE FROM tasks_current');
218
+ db.exec('DELETE FROM task_tags');
219
+ db.exec('DELETE FROM task_comments');
220
+ db.exec('DELETE FROM projection_state');
221
+ rebuildAllProjections(db, projectionEngine);
222
+ const state3 = captureProjectionState(db);
223
+ expect(state1).toEqual(state2);
224
+ expect(state2).toEqual(state3);
225
+ });
226
+ });
227
+ describe('projection_state tracking', () => {
228
+ it('updates projection_state after rebuild', () => {
229
+ taskService.createTask({ title: 'Task', project: 'inbox' });
230
+ db.exec('DELETE FROM tasks_current');
231
+ db.exec('DELETE FROM projection_state');
232
+ rebuildAllProjections(db, projectionEngine);
233
+ const states = db
234
+ .prepare('SELECT * FROM projection_state ORDER BY name')
235
+ .all();
236
+ expect(states.length).toBeGreaterThan(0);
237
+ const lastEventIds = states.map((s) => s.last_event_id);
238
+ const uniqueIds = new Set(lastEventIds);
239
+ expect(uniqueIds.size).toBe(1);
240
+ });
241
+ it('incremental rebuild from last known position', () => {
242
+ const task1 = taskService.createTask({ title: 'Task 1', project: 'inbox' });
243
+ const position1 = db
244
+ .prepare('SELECT MAX(id) as max_id FROM events')
245
+ .get();
246
+ taskService.createTask({ title: 'Task 2', project: 'inbox' });
247
+ taskService.setStatus(task1.task_id, TaskStatus.Ready);
248
+ const baselineEvents = projectionEngine
249
+ .getEventsSince(0, 1000)
250
+ .filter((event) => event.rowid <= position1.max_id);
251
+ db.exec('DELETE FROM projection_state');
252
+ db.exec('DELETE FROM tasks_current');
253
+ db.exec('DELETE FROM task_dependencies');
254
+ db.exec('DELETE FROM task_tags');
255
+ db.exec('DELETE FROM task_comments');
256
+ db.exec('DELETE FROM task_checkpoints');
257
+ db.exec('DELETE FROM task_search');
258
+ for (const event of baselineEvents) {
259
+ projectionEngine.applyEvent(event);
260
+ }
261
+ for (const projector of projectionEngine.getProjectors()) {
262
+ db.prepare('INSERT INTO projection_state (name, last_event_id, updated_at) VALUES (?, ?, ?)').run(projector.name, position1.max_id, new Date().toISOString());
263
+ }
264
+ const newEvents = projectionEngine.getEventsSince(position1.max_id, 1000);
265
+ expect(newEvents.length).toBe(2);
266
+ for (const event of newEvents) {
267
+ projectionEngine.applyEvent(event);
268
+ }
269
+ const task1State = db
270
+ .prepare('SELECT status FROM tasks_current WHERE task_id = ?')
271
+ .get(task1.task_id);
272
+ expect(task1State.status).toBe('ready');
273
+ });
274
+ });
275
+ });
276
+ //# sourceMappingURL=rebuild-equivalence.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuild-equivalence.test.js","sourceRoot":"","sources":["../../../src/__tests__/projections/rebuild-equivalence.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=invariants.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariants.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/properties/invariants.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,314 @@
1
+ import { describe, it } from 'vitest';
2
+ import * as fc from 'fast-check';
3
+ import { createConnection } from '../../db/connection.js';
4
+ import { EventStore } from '../../events/store.js';
5
+ import { ProjectionEngine } from '../../projections/engine.js';
6
+ import { TasksCurrentProjector } from '../../projections/tasks-current.js';
7
+ import { DependenciesProjector } from '../../projections/dependencies.js';
8
+ import { TagsProjector } from '../../projections/tags.js';
9
+ import { rebuildAllProjections } from '../../projections/rebuild.js';
10
+ import { TaskService } from '../../services/task-service.js';
11
+ import { ValidationService } from '../../services/validation-service.js';
12
+ import { TaskStatus } from '../../events/types.js';
13
+ const taskTitleArb = fc
14
+ .string({ minLength: 1, maxLength: 100 })
15
+ .filter((s) => s.trim().length > 0);
16
+ const projectNameArb = fc
17
+ .string({ minLength: 1, maxLength: 50 })
18
+ .filter((s) => /^[a-z0-9-]+$/.test(s));
19
+ const tagArb = fc
20
+ .string({ minLength: 1, maxLength: 30 })
21
+ .filter((s) => /^[a-z0-9-]+$/.test(s));
22
+ const priorityArb = fc.integer({ min: 0, max: 3 });
23
+ describe('Property-Based Tests', () => {
24
+ function withIsolatedServices(fn) {
25
+ const db = createConnection(':memory:');
26
+ const eventStore = new EventStore(db);
27
+ const engine = new ProjectionEngine(db);
28
+ engine.register(new TasksCurrentProjector());
29
+ engine.register(new DependenciesProjector());
30
+ engine.register(new TagsProjector());
31
+ const taskService = new TaskService(db, eventStore, engine);
32
+ const validationService = new ValidationService(db);
33
+ try {
34
+ return fn({ db, taskService, validationService });
35
+ }
36
+ finally {
37
+ db.close();
38
+ }
39
+ }
40
+ describe('event replay determinism', () => {
41
+ it('replaying same events always produces same state', () => {
42
+ fc.assert(fc.property(fc.array(fc.record({
43
+ title: taskTitleArb,
44
+ project: projectNameArb,
45
+ tags: fc.array(tagArb, { maxLength: 5 }),
46
+ priority: priorityArb,
47
+ }), { minLength: 1, maxLength: 20 }), (taskSpecs) => withIsolatedServices(({ db, taskService }) => {
48
+ const taskIds = [];
49
+ for (const spec of taskSpecs) {
50
+ try {
51
+ const task = taskService.createTask({
52
+ title: spec.title,
53
+ project: spec.project || 'inbox',
54
+ tags: spec.tags,
55
+ priority: spec.priority,
56
+ });
57
+ taskIds.push(task.task_id);
58
+ }
59
+ catch {
60
+ continue;
61
+ }
62
+ }
63
+ if (taskIds.length === 0)
64
+ return true;
65
+ const state1 = db
66
+ .prepare('SELECT task_id, title, project, status, tags, priority FROM tasks_current ORDER BY task_id')
67
+ .all();
68
+ db.exec('DELETE FROM tasks_current');
69
+ db.exec('DELETE FROM task_tags');
70
+ db.exec('DELETE FROM projection_state');
71
+ const engine = new ProjectionEngine(db);
72
+ engine.register(new TasksCurrentProjector());
73
+ engine.register(new TagsProjector());
74
+ rebuildAllProjections(db, engine);
75
+ const state2 = db
76
+ .prepare('SELECT task_id, title, project, status, tags, priority FROM tasks_current ORDER BY task_id')
77
+ .all();
78
+ return JSON.stringify(state1) === JSON.stringify(state2);
79
+ })), { numRuns: 50 });
80
+ });
81
+ });
82
+ describe('invariant: no duplicate task IDs', () => {
83
+ it('task IDs are always unique', () => {
84
+ fc.assert(fc.property(fc.array(taskTitleArb, { minLength: 1, maxLength: 50 }), (titles) => withIsolatedServices(({ taskService }) => {
85
+ const taskIds = new Set();
86
+ for (const title of titles) {
87
+ try {
88
+ const task = taskService.createTask({ title, project: 'inbox' });
89
+ if (taskIds.has(task.task_id)) {
90
+ return false;
91
+ }
92
+ taskIds.add(task.task_id);
93
+ }
94
+ catch {
95
+ continue;
96
+ }
97
+ }
98
+ return true;
99
+ })), { numRuns: 100 });
100
+ });
101
+ });
102
+ describe('invariant: valid status transitions', () => {
103
+ it('status transitions follow state machine rules', () => {
104
+ fc.assert(fc.property(fc.array(fc.oneof(fc.constant('create'), fc.constant('setReady'), fc.constant('claim'), fc.constant('complete'), fc.constant('release'), fc.constant('archive')), { minLength: 1, maxLength: 30 }), (actions) => withIsolatedServices(({ taskService }) => {
105
+ const taskIds = [];
106
+ const taskStates = new Map();
107
+ for (const action of actions) {
108
+ try {
109
+ switch (action) {
110
+ case 'create': {
111
+ const task = taskService.createTask({ title: 'Task', project: 'inbox' });
112
+ taskIds.push(task.task_id);
113
+ taskStates.set(task.task_id, TaskStatus.Backlog);
114
+ break;
115
+ }
116
+ case 'setReady': {
117
+ if (taskIds.length === 0)
118
+ break;
119
+ const taskId = taskIds[Math.floor(Math.random() * taskIds.length)];
120
+ const currentStatus = taskStates.get(taskId);
121
+ if (currentStatus === TaskStatus.Backlog) {
122
+ taskService.setStatus(taskId, TaskStatus.Ready);
123
+ taskStates.set(taskId, TaskStatus.Ready);
124
+ }
125
+ break;
126
+ }
127
+ case 'claim': {
128
+ if (taskIds.length === 0)
129
+ break;
130
+ const taskId = taskIds[Math.floor(Math.random() * taskIds.length)];
131
+ const currentStatus = taskStates.get(taskId);
132
+ if (currentStatus === TaskStatus.Ready) {
133
+ taskService.claimTask(taskId, { author: 'agent' });
134
+ taskStates.set(taskId, TaskStatus.InProgress);
135
+ }
136
+ break;
137
+ }
138
+ case 'complete': {
139
+ if (taskIds.length === 0)
140
+ break;
141
+ const taskId = taskIds[Math.floor(Math.random() * taskIds.length)];
142
+ const currentStatus = taskStates.get(taskId);
143
+ if (currentStatus === TaskStatus.InProgress) {
144
+ taskService.completeTask(taskId);
145
+ taskStates.set(taskId, TaskStatus.Done);
146
+ }
147
+ break;
148
+ }
149
+ case 'release': {
150
+ if (taskIds.length === 0)
151
+ break;
152
+ const taskId = taskIds[Math.floor(Math.random() * taskIds.length)];
153
+ const currentStatus = taskStates.get(taskId);
154
+ if (currentStatus === TaskStatus.InProgress) {
155
+ taskService.releaseTask(taskId);
156
+ taskStates.set(taskId, TaskStatus.Ready);
157
+ }
158
+ break;
159
+ }
160
+ case 'archive': {
161
+ if (taskIds.length === 0)
162
+ break;
163
+ const taskId = taskIds[Math.floor(Math.random() * taskIds.length)];
164
+ const currentStatus = taskStates.get(taskId);
165
+ if (currentStatus !== TaskStatus.Archived) {
166
+ taskService.archiveTask(taskId);
167
+ taskStates.set(taskId, TaskStatus.Archived);
168
+ }
169
+ break;
170
+ }
171
+ }
172
+ }
173
+ catch {
174
+ continue;
175
+ }
176
+ }
177
+ for (const taskId of taskIds) {
178
+ const task = taskService.getTaskById(taskId);
179
+ if (task) {
180
+ const validStatuses = Object.values(TaskStatus);
181
+ if (!validStatuses.includes(task.status)) {
182
+ return false;
183
+ }
184
+ }
185
+ }
186
+ return true;
187
+ })), { numRuns: 100 });
188
+ });
189
+ });
190
+ describe('invariant: no dependency cycles', () => {
191
+ it('adding dependencies never creates cycles', () => {
192
+ const depAttemptArb = fc
193
+ .record({
194
+ taskIndex: fc.integer({ min: 1, max: 9 }),
195
+ depIndex: fc.integer({ min: 0, max: 8 }),
196
+ })
197
+ .map(({ taskIndex, depIndex }) => ({
198
+ taskIndex,
199
+ depIndex: Math.min(depIndex, taskIndex - 1),
200
+ }));
201
+ fc.assert(fc.property(fc.array(depAttemptArb, { minLength: 1, maxLength: 20 }), (depAttempts) => withIsolatedServices(({ db, taskService, validationService }) => {
202
+ const taskIds = [];
203
+ for (let i = 0; i < 10; i++) {
204
+ const task = taskService.createTask({ title: `Task ${i}`, project: 'inbox' });
205
+ taskIds.push(task.task_id);
206
+ }
207
+ for (const { taskIndex, depIndex } of depAttempts) {
208
+ if (taskIndex === depIndex)
209
+ continue;
210
+ const taskId = taskIds[taskIndex];
211
+ const depId = taskIds[depIndex];
212
+ try {
213
+ db.prepare('INSERT OR IGNORE INTO task_dependencies (task_id, depends_on_id) VALUES (?, ?)').run(taskId, depId);
214
+ }
215
+ catch {
216
+ continue;
217
+ }
218
+ }
219
+ const validation = validationService.validate();
220
+ return validation.cycles.length === 0;
221
+ })), { numRuns: 50 });
222
+ });
223
+ });
224
+ describe('invariant: claim requires ready status', () => {
225
+ it('only ready tasks can be claimed', () => {
226
+ fc.assert(fc.property(fc.array(fc.oneof(fc.constant('backlog'), fc.constant('ready'), fc.constant('in_progress'), fc.constant('done'), fc.constant('archived')), { minLength: 1, maxLength: 10 }), (statuses) => withIsolatedServices(({ taskService }) => {
227
+ for (const status of statuses) {
228
+ const task = taskService.createTask({ title: 'Task', project: 'inbox' });
229
+ try {
230
+ if (status !== 'backlog') {
231
+ taskService.setStatus(task.task_id, TaskStatus.Ready);
232
+ }
233
+ if (status === 'in_progress') {
234
+ taskService.claimTask(task.task_id, { author: 'agent' });
235
+ }
236
+ if (status === 'done') {
237
+ taskService.setStatus(task.task_id, TaskStatus.Ready);
238
+ taskService.claimTask(task.task_id, { author: 'agent' });
239
+ taskService.completeTask(task.task_id);
240
+ }
241
+ if (status === 'archived') {
242
+ taskService.archiveTask(task.task_id);
243
+ }
244
+ }
245
+ catch {
246
+ continue;
247
+ }
248
+ const canClaim = status === 'ready';
249
+ try {
250
+ taskService.claimTask(task.task_id, { author: 'new-agent' });
251
+ if (!canClaim) {
252
+ return false;
253
+ }
254
+ }
255
+ catch {
256
+ if (canClaim) {
257
+ return false;
258
+ }
259
+ }
260
+ }
261
+ return true;
262
+ })), { numRuns: 50 });
263
+ });
264
+ });
265
+ describe('invariant: event count matches operations', () => {
266
+ it('event count equals number of successful operations', () => {
267
+ fc.assert(fc.property(fc.integer({ min: 1, max: 50 }), (taskCount) => withIsolatedServices(({ db, taskService }) => {
268
+ let operationCount = 0;
269
+ for (let i = 0; i < taskCount; i++) {
270
+ try {
271
+ taskService.createTask({ title: `Task ${i}`, project: 'inbox' });
272
+ operationCount++;
273
+ }
274
+ catch {
275
+ continue;
276
+ }
277
+ }
278
+ const eventCount = db
279
+ .prepare('SELECT COUNT(*) as count FROM events')
280
+ .get();
281
+ return eventCount.count === operationCount;
282
+ })), { numRuns: 50 });
283
+ });
284
+ });
285
+ describe('invariant: projection consistency', () => {
286
+ it('tasks_current always reflects latest event state', () => {
287
+ fc.assert(fc.property(fc.array(taskTitleArb, { minLength: 1, maxLength: 20 }), (titles) => withIsolatedServices(({ db, taskService }) => {
288
+ const taskIds = [];
289
+ for (const title of titles) {
290
+ try {
291
+ const task = taskService.createTask({ title, project: 'inbox' });
292
+ taskIds.push(task.task_id);
293
+ }
294
+ catch {
295
+ continue;
296
+ }
297
+ }
298
+ for (const taskId of taskIds) {
299
+ const inProjection = db
300
+ .prepare('SELECT COUNT(*) as count FROM tasks_current WHERE task_id = ?')
301
+ .get(taskId);
302
+ if (inProjection.count !== 1) {
303
+ return false;
304
+ }
305
+ }
306
+ const projectionCount = db
307
+ .prepare('SELECT COUNT(*) as count FROM tasks_current')
308
+ .get();
309
+ return projectionCount.count === taskIds.length;
310
+ })), { numRuns: 50 });
311
+ });
312
+ });
313
+ });
314
+ //# sourceMappingURL=invariants.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariants.test.js","sourceRoot":"","sources":["../../../src/__tests__/properties/invariants.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAU,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,YAAY,GAAG,EAAE;KACpB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;KACxC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtC,MAAM,cAAc,GAAG,EAAE;KACtB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;KACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,MAAM,MAAM,GAAG,EAAE;KACd,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;KACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;AAEnD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,SAAS,oBAAoB,CAC3B,EAIO;QAEP,MAAM,EAAE,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CACN,EAAE,CAAC,MAAM,CAAC;gBACR,KAAK,EAAE,YAAY;gBACnB,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;gBACxC,QAAQ,EAAE,WAAW;aACtB,CAAC,EACF,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAChC,EACD,CAAC,SAAS,EAAE,EAAE,CACZ,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;gBAC3C,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;oBAC7B,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;4BAClC,KAAK,EAAE,IAAI,CAAC,KAAK;4BACjB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,OAAO;4BAChC,IAAI,EAAE,IAAI,CAAC,IAAI;4BACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;yBACxB,CAAC,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC7B,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAEtC,MAAM,MAAM,GAAG,EAAE;qBACd,OAAO,CACN,4FAA4F,CAC7F;qBACA,GAAG,EAAE,CAAC;gBAET,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;gBACrC,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBACjC,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;gBAExC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAC;gBACxC,MAAM,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;gBAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;gBACrC,qBAAqB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBAElC,MAAM,MAAM,GAAG,EAAE;qBACd,OAAO,CACN,4FAA4F,CAC7F;qBACA,GAAG,EAAE,CAAC;gBAET,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3D,CAAC,CAAC,CACL,EACD,EAAE,OAAO,EAAE,EAAE,EAAE,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAC9E,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;gBACvC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;gBAClC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;wBACjE,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;4BAC9B,OAAO,KAAK,CAAC;wBACf,CAAC;wBACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC5B,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CACH,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;QACnD,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CACN,EAAE,CAAC,KAAK,CACN,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACrB,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EACvB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EACpB,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EACvB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EACtB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CACvB,EACD,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAChC,EACD,CAAC,OAAO,EAAE,EAAE,CACV,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;gBACvC,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,MAAM,UAAU,GAA4B,IAAI,GAAG,EAAE,CAAC;gBAEtD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,IAAI,CAAC;wBACH,QAAQ,MAAM,EAAE,CAAC;4BACf,KAAK,QAAQ,CAAC,CAAC,CAAC;gCACd,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;gCACzE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gCAC3B,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;gCACjD,MAAM;4BACR,CAAC;4BACD,KAAK,UAAU,CAAC,CAAC,CAAC;gCAChB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oCAAE,MAAM;gCAChC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gCACnE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gCAC7C,IAAI,aAAa,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;oCACzC,WAAW,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;oCAChD,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;gCAC3C,CAAC;gCACD,MAAM;4BACR,CAAC;4BACD,KAAK,OAAO,CAAC,CAAC,CAAC;gCACb,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oCAAE,MAAM;gCAChC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gCACnE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gCAC7C,IAAI,aAAa,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;oCACvC,WAAW,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;oCACnD,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;gCAChD,CAAC;gCACD,MAAM;4BACR,CAAC;4BACD,KAAK,UAAU,CAAC,CAAC,CAAC;gCAChB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oCAAE,MAAM;gCAChC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gCACnE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gCAC7C,IAAI,aAAa,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;oCAC5C,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;oCACjC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;gCAC1C,CAAC;gCACD,MAAM;4BACR,CAAC;4BACD,KAAK,SAAS,CAAC,CAAC,CAAC;gCACf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oCAAE,MAAM;gCAChC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gCACnE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gCAC7C,IAAI,aAAa,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;oCAC5C,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oCAChC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;gCAC3C,CAAC;gCACD,MAAM;4BACR,CAAC;4BACD,KAAK,SAAS,CAAC,CAAC,CAAC;gCACf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oCAAE,MAAM;gCAChC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gCACnE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gCAC7C,IAAI,aAAa,KAAK,UAAU,CAAC,QAAQ,EAAE,CAAC;oCAC1C,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oCAChC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;gCAC9C,CAAC;gCACD,MAAM;4BACR,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBAC7C,IAAI,IAAI,EAAE,CAAC;wBACT,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;wBAChD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;4BACzC,OAAO,KAAK,CAAC;wBACf,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CACL,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC/C,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,aAAa,GAAG,EAAE;iBACrB,MAAM,CAAC;gBACN,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;gBACzC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;aACzC,CAAC;iBACD,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;gBACjC,SAAS;gBACT,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC;aAC5C,CAAC,CAAC,CAAC;YAEN,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EACxD,CAAC,WAAW,EAAE,EAAE,CACd,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,EAAE,EAAE;gBAC9D,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC9E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC7B,CAAC;gBAED,KAAK,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,WAAW,EAAE,CAAC;oBAClD,IAAI,SAAS,KAAK,QAAQ;wBAAE,SAAS;oBACrC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;oBAClC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAChC,IAAI,CAAC;wBACH,EAAE,CAAC,OAAO,CACR,gFAAgF,CACjF,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACvB,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC;gBAChD,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;YACxC,CAAC,CAAC,CACL,EACD,EAAE,OAAO,EAAE,EAAE,EAAE,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;QACtD,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CACN,EAAE,CAAC,KAAK,CACN,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EACtB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EACpB,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAC1B,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EACnB,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CACxB,EACD,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAChC,EACD,CAAC,QAAQ,EAAE,EAAE,CACX,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;gBACvC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;oBAEzE,IAAI,CAAC;wBACH,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;4BACzB,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;wBACxD,CAAC;wBACD,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;4BAC7B,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;wBAC3D,CAAC;wBACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;4BACtB,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;4BACtD,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;4BACzD,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBACzC,CAAC;wBACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;4BAC1B,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBACxC,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;oBAED,MAAM,QAAQ,GAAG,MAAM,KAAK,OAAO,CAAC;oBACpC,IAAI,CAAC;wBACH,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;wBAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;4BACd,OAAO,KAAK,CAAC;wBACf,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,IAAI,QAAQ,EAAE,CAAC;4BACb,OAAO,KAAK,CAAC;wBACf,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CACL,EACD,EAAE,OAAO,EAAE,EAAE,EAAE,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACzD,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CACzD,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;gBAC3C,IAAI,cAAc,GAAG,CAAC,CAAC;gBAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,IAAI,CAAC;wBACH,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;wBACjE,cAAc,EAAE,CAAC;oBACnB,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,MAAM,UAAU,GAAG,EAAE;qBAClB,OAAO,CAAC,sCAAsC,CAAC;qBAC/C,GAAG,EAAuB,CAAC;gBAC9B,OAAO,UAAU,CAAC,KAAK,KAAK,cAAc,CAAC;YAC7C,CAAC,CAAC,CACH,EACD,EAAE,OAAO,EAAE,EAAE,EAAE,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAC9E,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;gBAC3C,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;wBACjE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC7B,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,MAAM,YAAY,GAAG,EAAE;yBACpB,OAAO,CAAC,+DAA+D,CAAC;yBACxE,GAAG,CAAC,MAAM,CAAsB,CAAC;oBACpC,IAAI,YAAY,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;wBAC7B,OAAO,KAAK,CAAC;oBACf,CAAC;gBACH,CAAC;gBAED,MAAM,eAAe,GAAG,EAAE;qBACvB,OAAO,CAAC,6CAA6C,CAAC;qBACtD,GAAG,EAAuB,CAAC;gBAC9B,OAAO,eAAe,CAAC,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC;YAClD,CAAC,CAAC,CACH,EACD,EAAE,OAAO,EAAE,EAAE,EAAE,CAChB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}