@danielsimonjr/memory-mcp 12.5.2 → 12.7.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 (159) hide show
  1. package/README.md +158 -14
  2. package/dist/core/EntityManager.d.ts +263 -0
  3. package/dist/core/EntityManager.d.ts.map +1 -0
  4. package/dist/core/EntityManager.js +478 -0
  5. package/dist/core/GraphStorage.d.ts +344 -0
  6. package/dist/core/GraphStorage.d.ts.map +1 -0
  7. package/dist/core/GraphStorage.js +708 -0
  8. package/dist/core/GraphTraversal.d.ts +136 -0
  9. package/dist/core/GraphTraversal.d.ts.map +1 -0
  10. package/dist/core/GraphTraversal.js +556 -0
  11. package/dist/core/HierarchyManager.d.ts +111 -0
  12. package/dist/core/HierarchyManager.d.ts.map +1 -0
  13. package/dist/core/HierarchyManager.js +224 -0
  14. package/dist/core/ManagerContext.d.ts +72 -0
  15. package/dist/core/ManagerContext.d.ts.map +1 -0
  16. package/dist/core/ManagerContext.js +118 -0
  17. package/dist/core/ObservationManager.d.ts +85 -0
  18. package/dist/core/ObservationManager.d.ts.map +1 -0
  19. package/dist/core/ObservationManager.js +123 -0
  20. package/dist/core/RelationManager.d.ts +131 -0
  21. package/dist/core/RelationManager.d.ts.map +1 -0
  22. package/dist/core/RelationManager.js +210 -0
  23. package/dist/core/SQLiteStorage.d.ts +354 -0
  24. package/dist/core/SQLiteStorage.d.ts.map +1 -0
  25. package/dist/core/SQLiteStorage.js +917 -0
  26. package/dist/core/StorageFactory.d.ts +45 -0
  27. package/dist/core/StorageFactory.d.ts.map +1 -0
  28. package/dist/core/StorageFactory.js +64 -0
  29. package/dist/core/TransactionManager.d.ts +259 -0
  30. package/dist/core/TransactionManager.d.ts.map +1 -0
  31. package/dist/core/TransactionManager.js +392 -0
  32. package/dist/core/index.d.ts +16 -0
  33. package/dist/core/index.d.ts.map +1 -0
  34. package/dist/core/index.js +17 -0
  35. package/dist/features/AnalyticsManager.d.ts +44 -0
  36. package/dist/features/AnalyticsManager.d.ts.map +1 -0
  37. package/dist/features/AnalyticsManager.js +223 -0
  38. package/dist/features/ArchiveManager.d.ts +121 -0
  39. package/dist/features/ArchiveManager.d.ts.map +1 -0
  40. package/dist/features/ArchiveManager.js +240 -0
  41. package/dist/features/CompressionManager.d.ts +109 -0
  42. package/dist/features/CompressionManager.d.ts.map +1 -0
  43. package/dist/features/CompressionManager.js +404 -0
  44. package/dist/features/IOManager.d.ts +221 -0
  45. package/dist/features/IOManager.d.ts.map +1 -0
  46. package/dist/features/IOManager.js +997 -0
  47. package/dist/features/StreamingExporter.d.ts +105 -0
  48. package/dist/features/StreamingExporter.d.ts.map +1 -0
  49. package/dist/features/StreamingExporter.js +150 -0
  50. package/dist/features/TagManager.d.ts +147 -0
  51. package/dist/features/TagManager.d.ts.map +1 -0
  52. package/dist/features/TagManager.js +210 -0
  53. package/dist/features/index.d.ts +12 -0
  54. package/dist/features/index.d.ts.map +1 -0
  55. package/dist/features/index.js +11 -0
  56. package/dist/index.js +8 -2
  57. package/dist/search/BasicSearch.d.ts +51 -0
  58. package/dist/search/BasicSearch.d.ts.map +1 -0
  59. package/dist/search/BasicSearch.js +137 -0
  60. package/dist/search/BooleanSearch.d.ts +98 -0
  61. package/dist/search/BooleanSearch.d.ts.map +1 -0
  62. package/dist/search/BooleanSearch.js +430 -0
  63. package/dist/search/EmbeddingService.d.ts +178 -0
  64. package/dist/search/EmbeddingService.d.ts.map +1 -0
  65. package/dist/search/EmbeddingService.js +358 -0
  66. package/dist/search/FuzzySearch.d.ts +118 -0
  67. package/dist/search/FuzzySearch.d.ts.map +1 -0
  68. package/dist/search/FuzzySearch.js +312 -0
  69. package/dist/search/RankedSearch.d.ts +71 -0
  70. package/dist/search/RankedSearch.d.ts.map +1 -0
  71. package/dist/search/RankedSearch.js +238 -0
  72. package/dist/search/SavedSearchManager.d.ts +79 -0
  73. package/dist/search/SavedSearchManager.d.ts.map +1 -0
  74. package/dist/search/SavedSearchManager.js +145 -0
  75. package/dist/search/SearchFilterChain.d.ts +120 -0
  76. package/dist/search/SearchFilterChain.d.ts.map +1 -0
  77. package/dist/search/SearchFilterChain.js +185 -0
  78. package/dist/search/SearchManager.d.ts +285 -0
  79. package/dist/search/SearchManager.d.ts.map +1 -0
  80. package/dist/search/SearchManager.js +338 -0
  81. package/dist/search/SearchSuggestions.d.ts +27 -0
  82. package/dist/search/SearchSuggestions.d.ts.map +1 -0
  83. package/dist/search/SearchSuggestions.js +57 -0
  84. package/dist/search/SemanticSearch.d.ts +146 -0
  85. package/dist/search/SemanticSearch.d.ts.map +1 -0
  86. package/dist/search/SemanticSearch.js +313 -0
  87. package/dist/search/TFIDFIndexManager.d.ts +63 -0
  88. package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
  89. package/dist/search/TFIDFIndexManager.js +215 -0
  90. package/dist/search/VectorStore.d.ts +235 -0
  91. package/dist/search/VectorStore.d.ts.map +1 -0
  92. package/dist/search/VectorStore.js +311 -0
  93. package/dist/search/index.d.ts +18 -0
  94. package/dist/search/index.d.ts.map +1 -0
  95. package/dist/search/index.js +21 -0
  96. package/dist/server/MCPServer.d.ts.map +1 -1
  97. package/dist/server/toolDefinitions.d.ts +1 -1
  98. package/dist/server/toolDefinitions.d.ts.map +1 -1
  99. package/dist/server/toolDefinitions.js +254 -2
  100. package/dist/server/toolHandlers.d.ts.map +1 -1
  101. package/dist/server/toolHandlers.js +241 -25
  102. package/dist/types/index.d.ts +13 -0
  103. package/dist/types/index.d.ts.map +1 -0
  104. package/dist/types/index.js +12 -0
  105. package/dist/types/types.d.ts +1234 -0
  106. package/dist/types/types.d.ts.map +1 -0
  107. package/dist/types/types.js +9 -0
  108. package/dist/utils/compressedCache.d.ts +192 -0
  109. package/dist/utils/compressedCache.d.ts.map +1 -0
  110. package/dist/utils/compressedCache.js +309 -0
  111. package/dist/utils/compressionUtil.d.ts +214 -0
  112. package/dist/utils/compressionUtil.d.ts.map +1 -0
  113. package/dist/utils/compressionUtil.js +247 -0
  114. package/dist/utils/constants.d.ts +245 -0
  115. package/dist/utils/constants.d.ts.map +1 -0
  116. package/dist/utils/constants.js +252 -0
  117. package/dist/utils/entityUtils.d.ts +321 -0
  118. package/dist/utils/entityUtils.d.ts.map +1 -0
  119. package/dist/utils/entityUtils.js +538 -0
  120. package/dist/utils/errors.d.ts +77 -0
  121. package/dist/utils/errors.d.ts.map +1 -0
  122. package/dist/utils/errors.js +121 -0
  123. package/dist/utils/formatters.d.ts +145 -0
  124. package/dist/utils/formatters.d.ts.map +1 -0
  125. package/dist/utils/formatters.js +132 -0
  126. package/dist/utils/index.d.ts +22 -0
  127. package/dist/utils/index.d.ts.map +1 -0
  128. package/dist/utils/index.js +75 -0
  129. package/dist/utils/indexes.d.ts +270 -0
  130. package/dist/utils/indexes.d.ts.map +1 -0
  131. package/dist/utils/indexes.js +526 -0
  132. package/dist/utils/logger.d.ts +24 -0
  133. package/dist/utils/logger.d.ts.map +1 -0
  134. package/dist/utils/logger.js +33 -0
  135. package/dist/utils/parallelUtils.d.ts +72 -0
  136. package/dist/utils/parallelUtils.d.ts.map +1 -0
  137. package/dist/utils/parallelUtils.js +169 -0
  138. package/dist/utils/schemas.d.ts +374 -0
  139. package/dist/utils/schemas.d.ts.map +1 -0
  140. package/dist/utils/schemas.js +484 -0
  141. package/dist/utils/searchAlgorithms.d.ts +99 -0
  142. package/dist/utils/searchAlgorithms.d.ts.map +1 -0
  143. package/dist/utils/searchAlgorithms.js +167 -0
  144. package/dist/utils/searchCache.d.ts +108 -0
  145. package/dist/utils/searchCache.d.ts.map +1 -0
  146. package/dist/utils/searchCache.js +209 -0
  147. package/dist/utils/taskScheduler.d.ts +290 -0
  148. package/dist/utils/taskScheduler.d.ts.map +1 -0
  149. package/dist/utils/taskScheduler.js +466 -0
  150. package/dist/workers/WorkerPool.d.ts +81 -0
  151. package/dist/workers/WorkerPool.d.ts.map +1 -0
  152. package/dist/workers/WorkerPool.js +121 -0
  153. package/dist/workers/index.d.ts +12 -0
  154. package/dist/workers/index.d.ts.map +1 -0
  155. package/dist/workers/index.js +9 -0
  156. package/dist/workers/levenshteinWorker.d.ts +60 -0
  157. package/dist/workers/levenshteinWorker.d.ts.map +1 -0
  158. package/dist/workers/levenshteinWorker.js +98 -0
  159. package/package.json +7 -7
@@ -0,0 +1,466 @@
1
+ /**
2
+ * Task Scheduler
3
+ *
4
+ * Advanced task scheduling utilities using workerpool.
5
+ * Phase 8 Sprint 4: Priority queues, concurrency control, progress tracking.
6
+ *
7
+ * @module utils/taskScheduler
8
+ */
9
+ import workerpool from '@danielsimonjr/workerpool/modern';
10
+ // ==================== Types ====================
11
+ /**
12
+ * Task priority levels.
13
+ * Higher priority tasks are executed first.
14
+ */
15
+ export var TaskPriority;
16
+ (function (TaskPriority) {
17
+ TaskPriority[TaskPriority["LOW"] = 0] = "LOW";
18
+ TaskPriority[TaskPriority["NORMAL"] = 1] = "NORMAL";
19
+ TaskPriority[TaskPriority["HIGH"] = 2] = "HIGH";
20
+ TaskPriority[TaskPriority["CRITICAL"] = 3] = "CRITICAL";
21
+ })(TaskPriority || (TaskPriority = {}));
22
+ /**
23
+ * Task status in the queue.
24
+ */
25
+ export var TaskStatus;
26
+ (function (TaskStatus) {
27
+ TaskStatus["PENDING"] = "pending";
28
+ TaskStatus["RUNNING"] = "running";
29
+ TaskStatus["COMPLETED"] = "completed";
30
+ TaskStatus["FAILED"] = "failed";
31
+ TaskStatus["CANCELLED"] = "cancelled";
32
+ })(TaskStatus || (TaskStatus = {}));
33
+ /**
34
+ * Priority Task Queue with advanced scheduling.
35
+ *
36
+ * Features:
37
+ * - Priority-based execution (CRITICAL > HIGH > NORMAL > LOW)
38
+ * - Configurable concurrency limits
39
+ * - Progress tracking
40
+ * - Graceful error handling
41
+ * - Task cancellation
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const queue = new TaskQueue({ concurrency: 4 });
46
+ *
47
+ * // Add tasks with different priorities
48
+ * queue.enqueue({
49
+ * id: 'task1',
50
+ * priority: TaskPriority.HIGH,
51
+ * fn: (x: number) => x * 2,
52
+ * input: 5,
53
+ * });
54
+ *
55
+ * // Process all tasks
56
+ * const results = await queue.processAll();
57
+ * ```
58
+ */
59
+ export class TaskQueue {
60
+ queue = [];
61
+ running = new Map();
62
+ completed = [];
63
+ pool = null;
64
+ concurrency;
65
+ defaultTimeout;
66
+ isProcessing = false;
67
+ totalExecutionTime = 0;
68
+ totalProcessed = 0;
69
+ useWorkerPool;
70
+ constructor(options = {}) {
71
+ this.concurrency = options.concurrency ?? Math.max(1, workerpool.cpus - 1);
72
+ this.defaultTimeout = options.timeout ?? 30000;
73
+ this.useWorkerPool = options.useWorkerPool ?? true;
74
+ }
75
+ /**
76
+ * Get or create the worker pool.
77
+ */
78
+ getPool() {
79
+ if (!this.pool) {
80
+ this.pool = workerpool.pool({
81
+ maxWorkers: this.concurrency,
82
+ workerType: 'thread',
83
+ });
84
+ }
85
+ return this.pool;
86
+ }
87
+ /**
88
+ * Add a task to the queue.
89
+ *
90
+ * @param task - Task to add
91
+ * @returns Promise that resolves when the task completes
92
+ */
93
+ enqueue(task) {
94
+ return new Promise((resolve, reject) => {
95
+ const queuedTask = {
96
+ ...task,
97
+ status: TaskStatus.PENDING,
98
+ addedAt: Date.now(),
99
+ resolve: resolve,
100
+ reject,
101
+ };
102
+ // Insert based on priority (higher priority first)
103
+ const insertIndex = this.queue.findIndex(t => t.priority < task.priority);
104
+ if (insertIndex === -1) {
105
+ this.queue.push(queuedTask);
106
+ }
107
+ else {
108
+ this.queue.splice(insertIndex, 0, queuedTask);
109
+ }
110
+ // Start processing if not already running
111
+ if (!this.isProcessing) {
112
+ this.processNext();
113
+ }
114
+ });
115
+ }
116
+ /**
117
+ * Process the next task in the queue.
118
+ */
119
+ async processNext() {
120
+ if (this.running.size >= this.concurrency || this.queue.length === 0) {
121
+ if (this.running.size === 0 && this.queue.length === 0) {
122
+ this.isProcessing = false;
123
+ }
124
+ return;
125
+ }
126
+ this.isProcessing = true;
127
+ const task = this.queue.shift();
128
+ if (!task)
129
+ return;
130
+ task.status = TaskStatus.RUNNING;
131
+ this.running.set(task.id, task);
132
+ const startTime = Date.now();
133
+ try {
134
+ // Execute task - try worker pool first, fall back to direct execution
135
+ let result;
136
+ if (this.useWorkerPool) {
137
+ try {
138
+ const pool = this.getPool();
139
+ const fnString = task.fn.toString();
140
+ const timeout = task.timeout ?? this.defaultTimeout;
141
+ result = await pool
142
+ .exec((input, fnStr) => {
143
+ // eslint-disable-next-line no-new-func
144
+ const fn = new Function('return ' + fnStr)();
145
+ return fn(input);
146
+ }, [task.input, fnString])
147
+ .timeout(timeout);
148
+ }
149
+ catch {
150
+ // Fall back to direct execution
151
+ result = await Promise.resolve(task.fn(task.input));
152
+ }
153
+ }
154
+ else {
155
+ // Direct execution without worker pool
156
+ result = await Promise.resolve(task.fn(task.input));
157
+ }
158
+ const endTime = Date.now();
159
+ const duration = endTime - startTime;
160
+ const taskResult = {
161
+ id: task.id,
162
+ status: TaskStatus.COMPLETED,
163
+ result,
164
+ duration,
165
+ startedAt: startTime,
166
+ completedAt: endTime,
167
+ };
168
+ this.totalExecutionTime += duration;
169
+ this.totalProcessed++;
170
+ this.completed.push(taskResult);
171
+ this.running.delete(task.id);
172
+ task.resolve(taskResult);
173
+ }
174
+ catch (error) {
175
+ const endTime = Date.now();
176
+ const duration = endTime - startTime;
177
+ const taskResult = {
178
+ id: task.id,
179
+ status: TaskStatus.FAILED,
180
+ error: error instanceof Error ? error : new Error(String(error)),
181
+ duration,
182
+ startedAt: startTime,
183
+ completedAt: endTime,
184
+ };
185
+ this.totalProcessed++;
186
+ this.completed.push(taskResult);
187
+ this.running.delete(task.id);
188
+ task.resolve(taskResult);
189
+ }
190
+ // Process next task
191
+ this.processNext();
192
+ }
193
+ /**
194
+ * Cancel a pending task.
195
+ *
196
+ * @param taskId - ID of the task to cancel
197
+ * @returns True if task was cancelled, false if not found or already running
198
+ */
199
+ cancel(taskId) {
200
+ const index = this.queue.findIndex(t => t.id === taskId);
201
+ if (index === -1)
202
+ return false;
203
+ const task = this.queue.splice(index, 1)[0];
204
+ task.status = TaskStatus.CANCELLED;
205
+ const result = {
206
+ id: task.id,
207
+ status: TaskStatus.CANCELLED,
208
+ duration: 0,
209
+ startedAt: Date.now(),
210
+ completedAt: Date.now(),
211
+ };
212
+ task.resolve(result);
213
+ return true;
214
+ }
215
+ /**
216
+ * Wait for all tasks to complete.
217
+ *
218
+ * @returns Array of all task results
219
+ */
220
+ async drain() {
221
+ // Wait for queue to empty and all running tasks to complete
222
+ while (this.queue.length > 0 || this.running.size > 0) {
223
+ await new Promise(resolve => setTimeout(resolve, 10));
224
+ }
225
+ return [...this.completed];
226
+ }
227
+ /**
228
+ * Get queue statistics.
229
+ */
230
+ getStats() {
231
+ return {
232
+ pending: this.queue.length,
233
+ running: this.running.size,
234
+ completed: this.completed.filter(r => r.status === TaskStatus.COMPLETED).length,
235
+ failed: this.completed.filter(r => r.status === TaskStatus.FAILED).length,
236
+ averageExecutionTime: this.totalProcessed > 0 ? this.totalExecutionTime / this.totalProcessed : 0,
237
+ totalProcessed: this.totalProcessed,
238
+ };
239
+ }
240
+ /**
241
+ * Clear all completed results.
242
+ */
243
+ clearCompleted() {
244
+ this.completed = [];
245
+ }
246
+ /**
247
+ * Shutdown the task queue and release resources.
248
+ */
249
+ async shutdown() {
250
+ // Cancel all pending tasks
251
+ for (const task of this.queue) {
252
+ task.status = TaskStatus.CANCELLED;
253
+ task.resolve({
254
+ id: task.id,
255
+ status: TaskStatus.CANCELLED,
256
+ duration: 0,
257
+ startedAt: Date.now(),
258
+ completedAt: Date.now(),
259
+ });
260
+ }
261
+ this.queue = [];
262
+ // Terminate worker pool
263
+ if (this.pool) {
264
+ await this.pool.terminate();
265
+ this.pool = null;
266
+ }
267
+ this.isProcessing = false;
268
+ }
269
+ }
270
+ // ==================== Batch Processing Utilities ====================
271
+ /**
272
+ * Process items in parallel batches with progress tracking.
273
+ *
274
+ * Unlike parallelMap, this provides:
275
+ * - Progress callbacks
276
+ * - Configurable concurrency
277
+ * - Error handling options
278
+ * - Task-level timeouts
279
+ *
280
+ * @template T - Input item type
281
+ * @template R - Output item type
282
+ * @param items - Array of items to process
283
+ * @param fn - Processing function (must be serializable)
284
+ * @param options - Batch processing options
285
+ * @returns Array of results (or errors if stopOnError is false)
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * const results = await batchProcess(
290
+ * urls,
291
+ * (url: string) => fetch(url).then(r => r.json()),
292
+ * {
293
+ * concurrency: 5,
294
+ * timeout: 10000,
295
+ * onProgress: ({ completed, total, percentage }) => {
296
+ * console.log(`Progress: ${percentage.toFixed(1)}%`);
297
+ * },
298
+ * }
299
+ * );
300
+ * ```
301
+ */
302
+ export async function batchProcess(items, fn, options = {}) {
303
+ const { concurrency = Math.max(1, workerpool.cpus - 1), timeout = 30000, onProgress, stopOnError = false, } = options;
304
+ const results = [];
305
+ let completed = 0;
306
+ const total = items.length;
307
+ // Process in batches respecting concurrency
308
+ for (let i = 0; i < items.length; i += concurrency) {
309
+ const batch = items.slice(i, i + concurrency);
310
+ const batchPromises = batch.map(async (item, batchIndex) => {
311
+ const itemIndex = i + batchIndex;
312
+ try {
313
+ // Execute with timeout
314
+ const result = await Promise.race([
315
+ Promise.resolve(fn(item)),
316
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Task timeout')), timeout)),
317
+ ]);
318
+ results[itemIndex] = { success: true, result };
319
+ }
320
+ catch (error) {
321
+ const err = error instanceof Error ? error : new Error(String(error));
322
+ results[itemIndex] = { success: false, error: err };
323
+ if (stopOnError) {
324
+ throw err;
325
+ }
326
+ }
327
+ finally {
328
+ completed++;
329
+ if (onProgress) {
330
+ onProgress({
331
+ completed,
332
+ total,
333
+ percentage: (completed / total) * 100,
334
+ currentTaskId: `item-${itemIndex}`,
335
+ });
336
+ }
337
+ }
338
+ });
339
+ await Promise.all(batchPromises);
340
+ }
341
+ return results;
342
+ }
343
+ /**
344
+ * Execute tasks with rate limiting.
345
+ *
346
+ * Ensures tasks don't exceed a specified rate (tasks per second).
347
+ *
348
+ * @template T - Input item type
349
+ * @template R - Output item type
350
+ * @param items - Items to process
351
+ * @param fn - Processing function
352
+ * @param rateLimit - Maximum tasks per second
353
+ * @returns Array of results
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * // Process max 10 items per second
358
+ * const results = await rateLimitedProcess(
359
+ * items,
360
+ * (item) => processItem(item),
361
+ * 10
362
+ * );
363
+ * ```
364
+ */
365
+ export async function rateLimitedProcess(items, fn, rateLimit) {
366
+ const results = [];
367
+ const minInterval = 1000 / rateLimit;
368
+ let lastExecutionTime = 0;
369
+ for (const item of items) {
370
+ // Calculate wait time
371
+ const now = Date.now();
372
+ const timeSinceLast = now - lastExecutionTime;
373
+ if (timeSinceLast < minInterval) {
374
+ await new Promise(resolve => setTimeout(resolve, minInterval - timeSinceLast));
375
+ }
376
+ lastExecutionTime = Date.now();
377
+ const result = await fn(item);
378
+ results.push(result);
379
+ }
380
+ return results;
381
+ }
382
+ /**
383
+ * Retry a function with exponential backoff.
384
+ *
385
+ * @template T - Return type
386
+ * @param fn - Function to retry
387
+ * @param options - Retry options
388
+ * @returns Result of the function
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * const result = await withRetry(
393
+ * () => fetchData(),
394
+ * { maxRetries: 3, baseDelay: 1000 }
395
+ * );
396
+ * ```
397
+ */
398
+ export async function withRetry(fn, options = {}) {
399
+ const { maxRetries = 3, baseDelay = 1000, maxDelay = 30000, onRetry } = options;
400
+ let lastError;
401
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
402
+ try {
403
+ return await fn();
404
+ }
405
+ catch (error) {
406
+ lastError = error instanceof Error ? error : new Error(String(error));
407
+ if (attempt < maxRetries) {
408
+ const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
409
+ if (onRetry) {
410
+ onRetry(lastError, attempt + 1);
411
+ }
412
+ await new Promise(resolve => setTimeout(resolve, delay));
413
+ }
414
+ }
415
+ }
416
+ throw lastError;
417
+ }
418
+ /**
419
+ * Create a debounced version of a function.
420
+ *
421
+ * @template T - Function arguments type
422
+ * @template R - Return type
423
+ * @param fn - Function to debounce
424
+ * @param delay - Delay in milliseconds
425
+ * @returns Debounced function
426
+ */
427
+ export function debounce(fn, delay) {
428
+ let timeoutId = null;
429
+ let pendingResolve = null;
430
+ return (...args) => {
431
+ return new Promise(resolve => {
432
+ if (timeoutId) {
433
+ clearTimeout(timeoutId);
434
+ }
435
+ pendingResolve = resolve;
436
+ timeoutId = setTimeout(() => {
437
+ const result = fn(...args);
438
+ if (pendingResolve) {
439
+ pendingResolve(result);
440
+ }
441
+ timeoutId = null;
442
+ pendingResolve = null;
443
+ }, delay);
444
+ });
445
+ };
446
+ }
447
+ /**
448
+ * Create a throttled version of a function.
449
+ *
450
+ * @template T - Function arguments type
451
+ * @template R - Return type
452
+ * @param fn - Function to throttle
453
+ * @param limit - Minimum time between calls in milliseconds
454
+ * @returns Throttled function
455
+ */
456
+ export function throttle(fn, limit) {
457
+ let lastCall = 0;
458
+ return (...args) => {
459
+ const now = Date.now();
460
+ if (now - lastCall >= limit) {
461
+ lastCall = now;
462
+ return fn(...args);
463
+ }
464
+ return undefined;
465
+ };
466
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * WorkerPool
3
+ *
4
+ * Manages a pool of worker threads for parallel task execution.
5
+ *
6
+ * @module workers/WorkerPool
7
+ */
8
+ /**
9
+ * Worker pool configuration options.
10
+ */
11
+ interface PoolOptions {
12
+ /** Maximum number of concurrent workers (default: CPU count - 1) */
13
+ maxWorkers?: number;
14
+ /** Absolute path to the worker script */
15
+ workerPath: string;
16
+ }
17
+ /**
18
+ * Statistics about the worker pool.
19
+ */
20
+ export interface PoolStats {
21
+ /** Number of currently active workers */
22
+ activeWorkers: number;
23
+ /** Number of tasks waiting in queue */
24
+ queueSize: number;
25
+ /** Maximum number of concurrent workers */
26
+ maxWorkers: number;
27
+ }
28
+ /**
29
+ * Worker pool for parallel task execution.
30
+ *
31
+ * Features:
32
+ * - Limits concurrent workers to maxWorkers
33
+ * - Queues tasks when all workers are busy
34
+ * - Automatically terminates workers after task completion
35
+ * - Supports batch execution with executeAll()
36
+ */
37
+ export declare class WorkerPool<TInput, TOutput> {
38
+ private taskQueue;
39
+ private activeWorkers;
40
+ private readonly maxWorkers;
41
+ private readonly workerPath;
42
+ constructor(options: PoolOptions);
43
+ /**
44
+ * Execute a single task in a worker thread.
45
+ *
46
+ * @param data - Input data for the worker
47
+ * @returns Promise that resolves with the worker's output
48
+ */
49
+ execute(data: TInput): Promise<TOutput>;
50
+ /**
51
+ * Execute multiple tasks in parallel.
52
+ *
53
+ * @param items - Array of input data for workers
54
+ * @returns Promise that resolves with array of outputs
55
+ */
56
+ executeAll(items: TInput[]): Promise<TOutput[]>;
57
+ /**
58
+ * Process the task queue, spawning workers as needed.
59
+ */
60
+ private processQueue;
61
+ /**
62
+ * Run a single task in a worker thread.
63
+ *
64
+ * @param task - Task to execute
65
+ */
66
+ private runTask;
67
+ /**
68
+ * Wait for all active workers to complete.
69
+ *
70
+ * @returns Promise that resolves when all workers are done
71
+ */
72
+ shutdown(): Promise<void>;
73
+ /**
74
+ * Get current statistics about the worker pool.
75
+ *
76
+ * @returns Pool statistics
77
+ */
78
+ getStats(): PoolStats;
79
+ }
80
+ export {};
81
+ //# sourceMappingURL=WorkerPool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkerPool.d.ts","sourceRoot":"","sources":["../../src/workers/WorkerPool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH;;GAEG;AACH,UAAU,WAAW;IACnB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,qBAAa,UAAU,CAAC,MAAM,EAAE,OAAO;IACrC,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,OAAO,EAAE,WAAW;IAKhC;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO7C;;;;;OAKG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAKrD;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAsCf;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B;;;;OAIG;IACH,QAAQ,IAAI,SAAS;CAOtB"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * WorkerPool
3
+ *
4
+ * Manages a pool of worker threads for parallel task execution.
5
+ *
6
+ * @module workers/WorkerPool
7
+ */
8
+ import { Worker } from 'worker_threads';
9
+ import { cpus } from 'os';
10
+ /**
11
+ * Worker pool for parallel task execution.
12
+ *
13
+ * Features:
14
+ * - Limits concurrent workers to maxWorkers
15
+ * - Queues tasks when all workers are busy
16
+ * - Automatically terminates workers after task completion
17
+ * - Supports batch execution with executeAll()
18
+ */
19
+ export class WorkerPool {
20
+ taskQueue = [];
21
+ activeWorkers = 0;
22
+ maxWorkers;
23
+ workerPath;
24
+ constructor(options) {
25
+ this.maxWorkers = options.maxWorkers ?? Math.max(1, cpus().length - 1);
26
+ this.workerPath = options.workerPath;
27
+ }
28
+ /**
29
+ * Execute a single task in a worker thread.
30
+ *
31
+ * @param data - Input data for the worker
32
+ * @returns Promise that resolves with the worker's output
33
+ */
34
+ async execute(data) {
35
+ return new Promise((resolve, reject) => {
36
+ this.taskQueue.push({ data, resolve, reject });
37
+ this.processQueue();
38
+ });
39
+ }
40
+ /**
41
+ * Execute multiple tasks in parallel.
42
+ *
43
+ * @param items - Array of input data for workers
44
+ * @returns Promise that resolves with array of outputs
45
+ */
46
+ async executeAll(items) {
47
+ const promises = items.map(item => this.execute(item));
48
+ return Promise.all(promises);
49
+ }
50
+ /**
51
+ * Process the task queue, spawning workers as needed.
52
+ */
53
+ processQueue() {
54
+ while (this.taskQueue.length > 0 && this.activeWorkers < this.maxWorkers) {
55
+ const task = this.taskQueue.shift();
56
+ if (task) {
57
+ this.runTask(task);
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Run a single task in a worker thread.
63
+ *
64
+ * @param task - Task to execute
65
+ */
66
+ runTask(task) {
67
+ this.activeWorkers++;
68
+ let taskCompleted = false;
69
+ const worker = new Worker(this.workerPath, {
70
+ workerData: task.data,
71
+ });
72
+ worker.on('message', (result) => {
73
+ if (!taskCompleted) {
74
+ taskCompleted = true;
75
+ task.resolve(result);
76
+ this.activeWorkers--;
77
+ worker.terminate();
78
+ this.processQueue();
79
+ }
80
+ });
81
+ worker.on('error', (error) => {
82
+ if (!taskCompleted) {
83
+ taskCompleted = true;
84
+ task.reject(error);
85
+ this.activeWorkers--;
86
+ worker.terminate();
87
+ this.processQueue();
88
+ }
89
+ });
90
+ worker.on('exit', (code) => {
91
+ if (!taskCompleted && code !== 0) {
92
+ taskCompleted = true;
93
+ task.reject(new Error(`Worker stopped with exit code ${code}`));
94
+ this.activeWorkers--;
95
+ this.processQueue();
96
+ }
97
+ });
98
+ }
99
+ /**
100
+ * Wait for all active workers to complete.
101
+ *
102
+ * @returns Promise that resolves when all workers are done
103
+ */
104
+ async shutdown() {
105
+ while (this.activeWorkers > 0) {
106
+ await new Promise(resolve => setTimeout(resolve, 10));
107
+ }
108
+ }
109
+ /**
110
+ * Get current statistics about the worker pool.
111
+ *
112
+ * @returns Pool statistics
113
+ */
114
+ getStats() {
115
+ return {
116
+ activeWorkers: this.activeWorkers,
117
+ queueSize: this.taskQueue.length,
118
+ maxWorkers: this.maxWorkers,
119
+ };
120
+ }
121
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Workers Module
3
+ *
4
+ * Worker thread utilities for parallel processing.
5
+ * Phase 8: Uses workerpool library for worker management.
6
+ *
7
+ * @module workers
8
+ */
9
+ export type { Pool, PoolStats } from '@danielsimonjr/workerpool/modern';
10
+ export type { WorkerInput, MatchResult } from './levenshteinWorker.js';
11
+ export { levenshteinDistance, similarity, searchEntities } from './levenshteinWorker.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAGxE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Workers Module
3
+ *
4
+ * Worker thread utilities for parallel processing.
5
+ * Phase 8: Uses workerpool library for worker management.
6
+ *
7
+ * @module workers
8
+ */
9
+ export { levenshteinDistance, similarity, searchEntities } from './levenshteinWorker.js';