cmp-standards 2.9.1 → 3.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.
- package/dist/analytics/CrossProjectAnalytics.d.ts.map +1 -1
- package/dist/analytics/CrossProjectAnalytics.js +3 -0
- package/dist/analytics/CrossProjectAnalytics.js.map +1 -1
- package/dist/cli/index.js +411 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/db/turso-client.d.ts.map +1 -1
- package/dist/db/turso-client.js +3 -0
- package/dist/db/turso-client.js.map +1 -1
- package/dist/events/EventBus.d.ts +21 -0
- package/dist/events/EventBus.d.ts.map +1 -1
- package/dist/events/EventBus.js +81 -30
- package/dist/events/EventBus.js.map +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +1 -1
- package/dist/events/index.js.map +1 -1
- package/dist/schema/expert-types.d.ts +2 -2
- package/dist/services/MemoryRelationshipService.d.ts +187 -0
- package/dist/services/MemoryRelationshipService.d.ts.map +1 -0
- package/dist/services/MemoryRelationshipService.js +375 -0
- package/dist/services/MemoryRelationshipService.js.map +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/semantic-search.d.ts +8 -0
- package/dist/services/semantic-search.d.ts.map +1 -1
- package/dist/services/semantic-search.js +40 -4
- package/dist/services/semantic-search.js.map +1 -1
- package/dist/testing/index.d.ts +148 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +370 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/utils/resilience.d.ts +256 -0
- package/dist/utils/resilience.d.ts.map +1 -0
- package/dist/utils/resilience.js +499 -0
- package/dist/utils/resilience.js.map +1 -0
- package/package.json +9 -1
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMP-Standards Testing Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides helper functions for testing cmp-standards integrations:
|
|
5
|
+
* - Mock factories for common services
|
|
6
|
+
* - Test fixtures
|
|
7
|
+
* - Assertion helpers
|
|
8
|
+
*
|
|
9
|
+
* @version 3.0.0
|
|
10
|
+
*/
|
|
11
|
+
import { ulid } from 'ulid';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Mock Factories
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Create a mock DevItem for testing
|
|
17
|
+
*/
|
|
18
|
+
export function createMockDevItem(overrides) {
|
|
19
|
+
const now = new Date();
|
|
20
|
+
const id = overrides?.id ?? ulid();
|
|
21
|
+
const toDate = (value) => {
|
|
22
|
+
if (value === null)
|
|
23
|
+
return null;
|
|
24
|
+
if (value === undefined)
|
|
25
|
+
return now;
|
|
26
|
+
if (value instanceof Date)
|
|
27
|
+
return value;
|
|
28
|
+
return new Date(value);
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
id,
|
|
32
|
+
type: overrides?.type ?? 'memory',
|
|
33
|
+
status: overrides?.status ?? 'active',
|
|
34
|
+
system: overrides?.system ?? 'TEST',
|
|
35
|
+
content: {
|
|
36
|
+
title: 'Test Memory',
|
|
37
|
+
body: 'Test content body',
|
|
38
|
+
domain: 'testing',
|
|
39
|
+
source: 'system',
|
|
40
|
+
...overrides?.content,
|
|
41
|
+
},
|
|
42
|
+
priority: overrides?.priority ?? null,
|
|
43
|
+
tags: overrides?.tags ?? null,
|
|
44
|
+
createdAt: toDate(overrides?.createdAt),
|
|
45
|
+
updatedAt: toDate(overrides?.updatedAt),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a mock memory content
|
|
50
|
+
*/
|
|
51
|
+
export function createMockMemoryContent(overrides) {
|
|
52
|
+
return {
|
|
53
|
+
title: 'Test Memory',
|
|
54
|
+
body: 'This is a test memory body for testing purposes.',
|
|
55
|
+
domain: 'testing',
|
|
56
|
+
source: 'system',
|
|
57
|
+
...overrides,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create multiple mock items
|
|
62
|
+
*/
|
|
63
|
+
export function createMockItemBatch(count, overrides) {
|
|
64
|
+
return Array.from({ length: count }, (_, i) => createMockDevItem({
|
|
65
|
+
...overrides,
|
|
66
|
+
content: {
|
|
67
|
+
title: `Test Item ${i + 1}`,
|
|
68
|
+
body: `Body for test item ${i + 1}`,
|
|
69
|
+
...overrides?.content,
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a mock memory client for testing
|
|
75
|
+
*/
|
|
76
|
+
export function createMockMemoryClient(options = {}) {
|
|
77
|
+
const items = new Map();
|
|
78
|
+
// Initialize with provided items
|
|
79
|
+
for (const item of options.items ?? []) {
|
|
80
|
+
items.set(item.id, item);
|
|
81
|
+
}
|
|
82
|
+
const maybeDelay = async () => {
|
|
83
|
+
if (options.latency && options.latency > 0) {
|
|
84
|
+
await new Promise(resolve => setTimeout(resolve, options.latency));
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const maybeFail = () => {
|
|
88
|
+
if (options.shouldFail) {
|
|
89
|
+
throw new Error('Mock client configured to fail');
|
|
90
|
+
}
|
|
91
|
+
if (options.failureRate && Math.random() < options.failureRate) {
|
|
92
|
+
throw new Error('Random mock failure');
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
async get(id) {
|
|
97
|
+
await maybeDelay();
|
|
98
|
+
maybeFail();
|
|
99
|
+
return items.get(id) ?? null;
|
|
100
|
+
},
|
|
101
|
+
async create(item) {
|
|
102
|
+
await maybeDelay();
|
|
103
|
+
maybeFail();
|
|
104
|
+
const id = ulid();
|
|
105
|
+
const now = new Date();
|
|
106
|
+
const newItem = { ...item, id, createdAt: now, updatedAt: now };
|
|
107
|
+
items.set(id, newItem);
|
|
108
|
+
return { id };
|
|
109
|
+
},
|
|
110
|
+
async update(id, updates) {
|
|
111
|
+
await maybeDelay();
|
|
112
|
+
maybeFail();
|
|
113
|
+
const existing = items.get(id);
|
|
114
|
+
if (!existing)
|
|
115
|
+
throw new Error(`Item ${id} not found`);
|
|
116
|
+
items.set(id, { ...existing, ...updates, updatedAt: new Date() });
|
|
117
|
+
},
|
|
118
|
+
async delete(id) {
|
|
119
|
+
await maybeDelay();
|
|
120
|
+
maybeFail();
|
|
121
|
+
items.delete(id);
|
|
122
|
+
},
|
|
123
|
+
async list(query) {
|
|
124
|
+
await maybeDelay();
|
|
125
|
+
maybeFail();
|
|
126
|
+
let results = Array.from(items.values());
|
|
127
|
+
if (query?.type)
|
|
128
|
+
results = results.filter(i => i.type === query.type);
|
|
129
|
+
if (query?.status)
|
|
130
|
+
results = results.filter(i => i.status === query.status);
|
|
131
|
+
if (query?.limit)
|
|
132
|
+
results = results.slice(0, query.limit);
|
|
133
|
+
return results;
|
|
134
|
+
},
|
|
135
|
+
async search(query) {
|
|
136
|
+
await maybeDelay();
|
|
137
|
+
maybeFail();
|
|
138
|
+
const lowerQuery = query.toLowerCase();
|
|
139
|
+
return Array.from(items.values()).filter(item => {
|
|
140
|
+
if (!item.content)
|
|
141
|
+
return false;
|
|
142
|
+
const content = item.content;
|
|
143
|
+
return (content.title?.toLowerCase().includes(lowerQuery) ||
|
|
144
|
+
content.body?.toLowerCase().includes(lowerQuery));
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
// Test helpers
|
|
148
|
+
_getAll: () => Array.from(items.values()),
|
|
149
|
+
_clear: () => items.clear(),
|
|
150
|
+
_set: (item) => items.set(item.id, item),
|
|
151
|
+
_count: () => items.size,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create a mock EventBus for testing
|
|
156
|
+
*/
|
|
157
|
+
export function createMockEventBus() {
|
|
158
|
+
const handlers = new Map();
|
|
159
|
+
const history = [];
|
|
160
|
+
return {
|
|
161
|
+
subscribe(eventType, handler) {
|
|
162
|
+
if (!handlers.has(eventType)) {
|
|
163
|
+
handlers.set(eventType, []);
|
|
164
|
+
}
|
|
165
|
+
handlers.get(eventType).push(handler);
|
|
166
|
+
return () => {
|
|
167
|
+
const eventHandlers = handlers.get(eventType);
|
|
168
|
+
if (eventHandlers) {
|
|
169
|
+
const index = eventHandlers.indexOf(handler);
|
|
170
|
+
if (index > -1)
|
|
171
|
+
eventHandlers.splice(index, 1);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
async publish(event) {
|
|
176
|
+
history.push({ type: event.type, event, timestamp: new Date() });
|
|
177
|
+
const eventHandlers = handlers.get(event.type) ?? [];
|
|
178
|
+
for (const handler of eventHandlers) {
|
|
179
|
+
await Promise.resolve(handler(event));
|
|
180
|
+
}
|
|
181
|
+
return { success: true };
|
|
182
|
+
},
|
|
183
|
+
getHistory: () => [...history],
|
|
184
|
+
getHandlerCount: (type) => handlers.get(type)?.length ?? 0,
|
|
185
|
+
clear: () => {
|
|
186
|
+
handlers.clear();
|
|
187
|
+
history.length = 0;
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// =============================================================================
|
|
192
|
+
// Test Fixtures
|
|
193
|
+
// =============================================================================
|
|
194
|
+
/**
|
|
195
|
+
* Standard test fixtures for common scenarios
|
|
196
|
+
*/
|
|
197
|
+
export const fixtures = {
|
|
198
|
+
/**
|
|
199
|
+
* A basic memory for testing
|
|
200
|
+
*/
|
|
201
|
+
basicMemory: createMockDevItem({
|
|
202
|
+
type: 'memory',
|
|
203
|
+
content: {
|
|
204
|
+
title: 'Basic Test Memory',
|
|
205
|
+
body: 'This is a basic test memory used for unit tests.',
|
|
206
|
+
domain: 'testing',
|
|
207
|
+
source: 'system',
|
|
208
|
+
},
|
|
209
|
+
}),
|
|
210
|
+
/**
|
|
211
|
+
* A memory with tags
|
|
212
|
+
*/
|
|
213
|
+
taggedMemory: createMockDevItem({
|
|
214
|
+
type: 'memory',
|
|
215
|
+
content: {
|
|
216
|
+
title: 'Tagged Memory',
|
|
217
|
+
body: 'A memory with tags for testing filtering.',
|
|
218
|
+
domain: 'testing',
|
|
219
|
+
source: 'claude',
|
|
220
|
+
tags: ['important', 'testing', 'example'],
|
|
221
|
+
},
|
|
222
|
+
}),
|
|
223
|
+
/**
|
|
224
|
+
* A task item
|
|
225
|
+
*/
|
|
226
|
+
task: createMockDevItem({
|
|
227
|
+
type: 'task',
|
|
228
|
+
status: 'in_progress',
|
|
229
|
+
content: {
|
|
230
|
+
title: 'Test Task',
|
|
231
|
+
userRequest: 'Implement feature X',
|
|
232
|
+
plan: ['Step 1', 'Step 2', 'Step 3'],
|
|
233
|
+
currentStep: 1,
|
|
234
|
+
domain: 'development',
|
|
235
|
+
files: ['src/feature.ts'],
|
|
236
|
+
},
|
|
237
|
+
}),
|
|
238
|
+
/**
|
|
239
|
+
* An improvement suggestion
|
|
240
|
+
*/
|
|
241
|
+
improvement: createMockDevItem({
|
|
242
|
+
type: 'improvement',
|
|
243
|
+
status: 'pending',
|
|
244
|
+
content: {
|
|
245
|
+
area: 'testing',
|
|
246
|
+
title: 'Add more tests',
|
|
247
|
+
description: 'Increase test coverage for edge cases.',
|
|
248
|
+
priority: 'medium',
|
|
249
|
+
effort: 'small',
|
|
250
|
+
detectedBy: 'expert-panel',
|
|
251
|
+
detectedAt: new Date().toISOString(),
|
|
252
|
+
},
|
|
253
|
+
}),
|
|
254
|
+
/**
|
|
255
|
+
* A batch of memories for testing list/search
|
|
256
|
+
*/
|
|
257
|
+
memoryBatch: createMockItemBatch(10, { type: 'memory' }),
|
|
258
|
+
};
|
|
259
|
+
// =============================================================================
|
|
260
|
+
// Assertion Helpers
|
|
261
|
+
// =============================================================================
|
|
262
|
+
/**
|
|
263
|
+
* Assert that a DevItem has required fields
|
|
264
|
+
*/
|
|
265
|
+
export function assertValidDevItem(item) {
|
|
266
|
+
if (!item || typeof item !== 'object') {
|
|
267
|
+
throw new Error('Expected DevItem object');
|
|
268
|
+
}
|
|
269
|
+
const obj = item;
|
|
270
|
+
if (typeof obj.id !== 'string' || !obj.id) {
|
|
271
|
+
throw new Error('DevItem must have a non-empty string id');
|
|
272
|
+
}
|
|
273
|
+
if (typeof obj.type !== 'string' || !obj.type) {
|
|
274
|
+
throw new Error('DevItem must have a non-empty string type');
|
|
275
|
+
}
|
|
276
|
+
if (typeof obj.status !== 'string' || !obj.status) {
|
|
277
|
+
throw new Error('DevItem must have a non-empty string status');
|
|
278
|
+
}
|
|
279
|
+
if (typeof obj.content !== 'object' || obj.content === null) {
|
|
280
|
+
throw new Error('DevItem must have a content object');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Assert that a memory content has required fields
|
|
285
|
+
*/
|
|
286
|
+
export function assertValidMemoryContent(content) {
|
|
287
|
+
if (!content || typeof content !== 'object') {
|
|
288
|
+
throw new Error('Expected MemoryContent object');
|
|
289
|
+
}
|
|
290
|
+
const obj = content;
|
|
291
|
+
if (typeof obj.title !== 'string') {
|
|
292
|
+
throw new Error('MemoryContent must have a string title');
|
|
293
|
+
}
|
|
294
|
+
if (typeof obj.body !== 'string') {
|
|
295
|
+
throw new Error('MemoryContent must have a string body');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Assert that two items are equivalent (ignoring timestamps)
|
|
300
|
+
*/
|
|
301
|
+
export function assertItemsEquivalent(actual, expected) {
|
|
302
|
+
if (actual.id !== expected.id) {
|
|
303
|
+
throw new Error(`ID mismatch: ${actual.id} !== ${expected.id}`);
|
|
304
|
+
}
|
|
305
|
+
if (actual.type !== expected.type) {
|
|
306
|
+
throw new Error(`Type mismatch: ${actual.type} !== ${expected.type}`);
|
|
307
|
+
}
|
|
308
|
+
if (actual.status !== expected.status) {
|
|
309
|
+
throw new Error(`Status mismatch: ${actual.status} !== ${expected.status}`);
|
|
310
|
+
}
|
|
311
|
+
const actualContent = JSON.stringify(actual.content);
|
|
312
|
+
const expectedContent = JSON.stringify(expected.content);
|
|
313
|
+
if (actualContent !== expectedContent) {
|
|
314
|
+
throw new Error(`Content mismatch:\n${actualContent}\n!==\n${expectedContent}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// =============================================================================
|
|
318
|
+
// Test Utilities
|
|
319
|
+
// =============================================================================
|
|
320
|
+
/**
|
|
321
|
+
* Wait for a condition to be true (polling)
|
|
322
|
+
*/
|
|
323
|
+
export async function waitFor(condition, options) {
|
|
324
|
+
const timeout = options?.timeout ?? 5000;
|
|
325
|
+
const interval = options?.interval ?? 100;
|
|
326
|
+
const startTime = Date.now();
|
|
327
|
+
while (Date.now() - startTime < timeout) {
|
|
328
|
+
if (await condition())
|
|
329
|
+
return;
|
|
330
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
331
|
+
}
|
|
332
|
+
throw new Error(`waitFor timed out after ${timeout}ms`);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Create a deferred promise for async testing
|
|
336
|
+
*/
|
|
337
|
+
export function createDeferred() {
|
|
338
|
+
let resolve;
|
|
339
|
+
let reject;
|
|
340
|
+
const promise = new Promise((res, rej) => {
|
|
341
|
+
resolve = res;
|
|
342
|
+
reject = rej;
|
|
343
|
+
});
|
|
344
|
+
return { promise, resolve, reject };
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Run async operations in sequence with timing info
|
|
348
|
+
*/
|
|
349
|
+
export async function measureAsync(operation) {
|
|
350
|
+
const start = Date.now();
|
|
351
|
+
const result = await operation();
|
|
352
|
+
return { result, durationMs: Date.now() - start };
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Create a spy function that tracks calls
|
|
356
|
+
*/
|
|
357
|
+
export function createSpy(implementation) {
|
|
358
|
+
const calls = [];
|
|
359
|
+
const spy = ((...args) => {
|
|
360
|
+
const result = implementation?.(...args);
|
|
361
|
+
calls.push({ args, result, timestamp: new Date() });
|
|
362
|
+
return result;
|
|
363
|
+
});
|
|
364
|
+
Object.defineProperty(spy, 'calls', { get: () => calls });
|
|
365
|
+
Object.defineProperty(spy, 'callCount', { get: () => calls.length });
|
|
366
|
+
Object.defineProperty(spy, 'lastCall', { get: () => calls[calls.length - 1] ?? null });
|
|
367
|
+
spy.reset = () => { calls.length = 0; };
|
|
368
|
+
return spy;
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resilience Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides fault-tolerant patterns for network operations:
|
|
5
|
+
* - Retry with exponential backoff
|
|
6
|
+
* - Timeout protection
|
|
7
|
+
* - Circuit breaker pattern
|
|
8
|
+
* - Rate limiting helpers
|
|
9
|
+
*
|
|
10
|
+
* @version 2.9.1
|
|
11
|
+
*/
|
|
12
|
+
export interface RetryOptions {
|
|
13
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
14
|
+
maxRetries: number;
|
|
15
|
+
/** Base delay in milliseconds (default: 1000) */
|
|
16
|
+
baseDelay: number;
|
|
17
|
+
/** Maximum delay cap in milliseconds (default: 30000) */
|
|
18
|
+
maxDelay: number;
|
|
19
|
+
/** Multiplier for exponential backoff (default: 2) */
|
|
20
|
+
backoffMultiplier: number;
|
|
21
|
+
/** Jitter factor 0-1 to randomize delays (default: 0.1) */
|
|
22
|
+
jitter: number;
|
|
23
|
+
/** Function to determine if error is retryable (default: all errors) */
|
|
24
|
+
isRetryable?: (error: unknown) => boolean;
|
|
25
|
+
/** Callback on each retry attempt */
|
|
26
|
+
onRetry?: (attempt: number, error: unknown, nextDelay: number) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface TimeoutOptions<T> {
|
|
29
|
+
/** Timeout in milliseconds */
|
|
30
|
+
timeoutMs: number;
|
|
31
|
+
/** Fallback value if timeout occurs */
|
|
32
|
+
fallback?: T;
|
|
33
|
+
/** Error message for timeout */
|
|
34
|
+
message?: string;
|
|
35
|
+
/** Callback when timeout occurs */
|
|
36
|
+
onTimeout?: () => void;
|
|
37
|
+
}
|
|
38
|
+
export interface CircuitBreakerOptions {
|
|
39
|
+
/** Number of failures before opening circuit (default: 5) */
|
|
40
|
+
failureThreshold: number;
|
|
41
|
+
/** Time in ms to wait before half-open state (default: 30000) */
|
|
42
|
+
resetTimeout: number;
|
|
43
|
+
/** Number of successes needed in half-open to close (default: 2) */
|
|
44
|
+
successThreshold: number;
|
|
45
|
+
/** Callback when circuit state changes */
|
|
46
|
+
onStateChange?: (state: CircuitState) => void;
|
|
47
|
+
}
|
|
48
|
+
export type CircuitState = 'closed' | 'open' | 'half-open';
|
|
49
|
+
export declare class RetryableError extends Error {
|
|
50
|
+
readonly retryAfter?: number | undefined;
|
|
51
|
+
constructor(message: string, retryAfter?: number | undefined);
|
|
52
|
+
}
|
|
53
|
+
export declare class TimeoutError extends Error {
|
|
54
|
+
constructor(message?: string);
|
|
55
|
+
}
|
|
56
|
+
export declare class CircuitOpenError extends Error {
|
|
57
|
+
readonly resetAt?: number | undefined;
|
|
58
|
+
constructor(message?: string, resetAt?: number | undefined);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Execute operation with retry logic and exponential backoff
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const result = await withRetry(
|
|
66
|
+
* () => fetch('https://api.example.com/data'),
|
|
67
|
+
* { maxRetries: 3, baseDelay: 1000 }
|
|
68
|
+
* )
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function withRetry<T>(operation: () => Promise<T>, options?: Partial<RetryOptions>): Promise<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Check if an HTTP status code is retryable
|
|
74
|
+
*/
|
|
75
|
+
export declare function isRetryableHttpStatus(status: number): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Check if an error is a network/transient error
|
|
78
|
+
*/
|
|
79
|
+
export declare function isTransientError(error: unknown): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Execute operation with timeout protection
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const result = await withTimeout(
|
|
86
|
+
* fetch('https://api.example.com/data'),
|
|
87
|
+
* { timeoutMs: 5000, fallback: null }
|
|
88
|
+
* )
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function withTimeout<T>(promise: Promise<T>, options: TimeoutOptions<T>): Promise<T>;
|
|
92
|
+
/**
|
|
93
|
+
* Create an AbortController with automatic timeout
|
|
94
|
+
*/
|
|
95
|
+
export declare function createTimeoutController(timeoutMs: number): {
|
|
96
|
+
controller: AbortController;
|
|
97
|
+
cleanup: () => void;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Circuit Breaker for protecting against cascade failures
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const breaker = new CircuitBreaker({ failureThreshold: 5 })
|
|
105
|
+
*
|
|
106
|
+
* try {
|
|
107
|
+
* const result = await breaker.execute(() => riskyOperation())
|
|
108
|
+
* } catch (error) {
|
|
109
|
+
* if (error instanceof CircuitOpenError) {
|
|
110
|
+
* // Circuit is open, use fallback
|
|
111
|
+
* }
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare class CircuitBreaker {
|
|
116
|
+
private state;
|
|
117
|
+
private failures;
|
|
118
|
+
private successes;
|
|
119
|
+
private lastFailureTime;
|
|
120
|
+
private options;
|
|
121
|
+
constructor(options?: Partial<CircuitBreakerOptions>);
|
|
122
|
+
/**
|
|
123
|
+
* Get current circuit state
|
|
124
|
+
*/
|
|
125
|
+
getState(): CircuitState;
|
|
126
|
+
/**
|
|
127
|
+
* Get circuit statistics
|
|
128
|
+
*/
|
|
129
|
+
getStats(): {
|
|
130
|
+
state: CircuitState;
|
|
131
|
+
failures: number;
|
|
132
|
+
successes: number;
|
|
133
|
+
lastFailureTime: number;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Execute operation through circuit breaker
|
|
137
|
+
*/
|
|
138
|
+
execute<T>(operation: () => Promise<T>): Promise<T>;
|
|
139
|
+
/**
|
|
140
|
+
* Record successful operation
|
|
141
|
+
*/
|
|
142
|
+
private onSuccess;
|
|
143
|
+
/**
|
|
144
|
+
* Record failed operation
|
|
145
|
+
*/
|
|
146
|
+
private onFailure;
|
|
147
|
+
/**
|
|
148
|
+
* Transition to new state
|
|
149
|
+
*/
|
|
150
|
+
private transitionTo;
|
|
151
|
+
/**
|
|
152
|
+
* Manually reset the circuit breaker
|
|
153
|
+
*/
|
|
154
|
+
reset(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Manually trip the circuit breaker
|
|
157
|
+
*/
|
|
158
|
+
trip(): void;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Execute operation with retry, timeout, and circuit breaker
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const breaker = new CircuitBreaker()
|
|
166
|
+
*
|
|
167
|
+
* const result = await withResilience(
|
|
168
|
+
* () => fetch('https://api.example.com/data'),
|
|
169
|
+
* {
|
|
170
|
+
* retry: { maxRetries: 3 },
|
|
171
|
+
* timeout: { timeoutMs: 5000 },
|
|
172
|
+
* circuitBreaker: breaker
|
|
173
|
+
* }
|
|
174
|
+
* )
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export declare function withResilience<T>(operation: () => Promise<T>, options: {
|
|
178
|
+
retry?: Partial<RetryOptions>;
|
|
179
|
+
timeout?: TimeoutOptions<T>;
|
|
180
|
+
circuitBreaker?: CircuitBreaker;
|
|
181
|
+
}): Promise<T>;
|
|
182
|
+
/**
|
|
183
|
+
* Simple mutex for protecting async initialization
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* const initMutex = new AsyncMutex()
|
|
188
|
+
* let instance: Client | null = null
|
|
189
|
+
*
|
|
190
|
+
* async function getInstance() {
|
|
191
|
+
* if (instance) return instance
|
|
192
|
+
* return initMutex.runExclusive(async () => {
|
|
193
|
+
* if (instance) return instance // Double-check after acquiring lock
|
|
194
|
+
* instance = await createClient()
|
|
195
|
+
* return instance
|
|
196
|
+
* })
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export declare class AsyncMutex {
|
|
201
|
+
private locked;
|
|
202
|
+
private queue;
|
|
203
|
+
/**
|
|
204
|
+
* Check if mutex is currently locked
|
|
205
|
+
*/
|
|
206
|
+
isLocked(): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Acquire the mutex lock
|
|
209
|
+
*/
|
|
210
|
+
acquire(): Promise<void>;
|
|
211
|
+
/**
|
|
212
|
+
* Release the mutex lock
|
|
213
|
+
*/
|
|
214
|
+
release(): void;
|
|
215
|
+
/**
|
|
216
|
+
* Run operation exclusively (acquires and releases automatically)
|
|
217
|
+
*/
|
|
218
|
+
runExclusive<T>(operation: () => Promise<T>): Promise<T>;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Execute cache operation safely (returns null on error instead of throwing)
|
|
222
|
+
*/
|
|
223
|
+
export declare function safeCacheGet<T>(operation: () => Promise<T | null>, context?: string): Promise<T | null>;
|
|
224
|
+
/**
|
|
225
|
+
* Execute cache set operation safely (returns success boolean)
|
|
226
|
+
*/
|
|
227
|
+
export declare function safeCacheSet(operation: () => Promise<void>, context?: string): Promise<boolean>;
|
|
228
|
+
export interface BatchResult<T, E = unknown> {
|
|
229
|
+
succeeded: T[];
|
|
230
|
+
failed: Array<{
|
|
231
|
+
item: unknown;
|
|
232
|
+
error: E;
|
|
233
|
+
}>;
|
|
234
|
+
total: number;
|
|
235
|
+
successRate: number;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Process items in batches with individual error handling
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const result = await processBatch(
|
|
243
|
+
* items,
|
|
244
|
+
* async (item) => await processItem(item),
|
|
245
|
+
* { chunkSize: 10, concurrency: 5 }
|
|
246
|
+
* )
|
|
247
|
+
* console.log(`Processed ${result.succeeded.length}/${result.total}`)
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
export declare function processBatch<T, R>(items: T[], processor: (item: T, index: number) => Promise<R>, options?: {
|
|
251
|
+
chunkSize?: number;
|
|
252
|
+
concurrency?: number;
|
|
253
|
+
delayBetweenChunks?: number;
|
|
254
|
+
onProgress?: (processed: number, total: number) => void;
|
|
255
|
+
}): Promise<BatchResult<R>>;
|
|
256
|
+
//# sourceMappingURL=resilience.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilience.d.ts","sourceRoot":"","sources":["../../src/utils/resilience.ts"],"names":[],"mappings":"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"}
|