@revealui/core 0.3.0 → 0.5.2

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 (155) hide show
  1. package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
  2. package/dist/client/admin/components/AdminDashboard.js +20 -3
  3. package/dist/client/richtext/index.d.ts.map +1 -1
  4. package/dist/client/richtext/plugins/FloatingToolbarPlugin.js +1 -3
  5. package/dist/collections/operations/create.d.ts +2 -1
  6. package/dist/collections/operations/create.d.ts.map +1 -1
  7. package/dist/collections/operations/create.js +28 -1
  8. package/dist/database/type-adapter.d.ts.map +1 -1
  9. package/dist/features.d.ts +13 -3
  10. package/dist/features.d.ts.map +1 -1
  11. package/dist/features.js +17 -0
  12. package/dist/globals/GlobalOperations.d.ts.map +1 -1
  13. package/dist/globals/GlobalOperations.js +12 -2
  14. package/dist/index.d.ts +11 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +11 -1
  17. package/dist/license.d.ts +6 -0
  18. package/dist/license.d.ts.map +1 -1
  19. package/dist/license.js +14 -1
  20. package/dist/monitoring/alerts.d.ts +4 -4
  21. package/dist/monitoring/alerts.d.ts.map +1 -1
  22. package/dist/plugins/nested-docs.d.ts.map +1 -1
  23. package/dist/plugins/nested-docs.js +0 -1
  24. package/dist/queries/queryBuilder.d.ts.map +1 -1
  25. package/dist/queries/queryBuilder.js +4 -3
  26. package/dist/richtext/index.d.ts.map +1 -1
  27. package/dist/storage/vercel-blob.d.ts.map +1 -1
  28. package/dist/storage/vercel-blob.js +3 -0
  29. package/dist/types/api.d.ts.map +1 -1
  30. package/dist/types/config.d.ts.map +1 -1
  31. package/dist/types/core.d.ts +1 -1
  32. package/dist/types/core.d.ts.map +1 -1
  33. package/dist/types/extensions.d.ts.map +1 -1
  34. package/dist/types/frontend.d.ts.map +1 -1
  35. package/dist/types/legacy.d.ts.map +1 -1
  36. package/dist/types/query.d.ts.map +1 -1
  37. package/dist/types/runtime.d.ts +1 -0
  38. package/dist/types/runtime.d.ts.map +1 -1
  39. package/dist/utils/error-responses.d.ts.map +1 -1
  40. package/dist/utils/error-responses.js +2 -3
  41. package/package.json +24 -24
  42. package/dist/caching/app-cache.d.ts +0 -242
  43. package/dist/caching/app-cache.d.ts.map +0 -1
  44. package/dist/caching/app-cache.js +0 -438
  45. package/dist/caching/cdn-config.d.ts +0 -155
  46. package/dist/caching/cdn-config.d.ts.map +0 -1
  47. package/dist/caching/cdn-config.js +0 -415
  48. package/dist/caching/edge-cache.d.ts +0 -177
  49. package/dist/caching/edge-cache.d.ts.map +0 -1
  50. package/dist/caching/edge-cache.js +0 -414
  51. package/dist/caching/service-worker.d.ts +0 -157
  52. package/dist/caching/service-worker.d.ts.map +0 -1
  53. package/dist/caching/service-worker.js +0 -438
  54. package/dist/client/admin/utils/auth.d.ts +0 -23
  55. package/dist/client/admin/utils/auth.d.ts.map +0 -1
  56. package/dist/client/admin/utils/auth.js +0 -52
  57. package/dist/client/http/client.d.ts +0 -15
  58. package/dist/client/http/client.d.ts.map +0 -1
  59. package/dist/client/http/client.js +0 -49
  60. package/dist/client/http/fetchBanner.d.ts +0 -18
  61. package/dist/client/http/fetchBanner.d.ts.map +0 -1
  62. package/dist/client/http/fetchBanner.js +0 -44
  63. package/dist/client/http/fetchCard.d.ts +0 -18
  64. package/dist/client/http/fetchCard.d.ts.map +0 -1
  65. package/dist/client/http/fetchCard.js +0 -46
  66. package/dist/client/http/fetchEvents.d.ts +0 -18
  67. package/dist/client/http/fetchEvents.d.ts.map +0 -1
  68. package/dist/client/http/fetchEvents.js +0 -44
  69. package/dist/client/http/fetchHero.d.ts +0 -17
  70. package/dist/client/http/fetchHero.d.ts.map +0 -1
  71. package/dist/client/http/fetchHero.js +0 -55
  72. package/dist/client/http/fetchMainInfos.d.ts +0 -17
  73. package/dist/client/http/fetchMainInfos.d.ts.map +0 -1
  74. package/dist/client/http/fetchMainInfos.js +0 -44
  75. package/dist/client/http/fetchVideos.d.ts +0 -13
  76. package/dist/client/http/fetchVideos.d.ts.map +0 -1
  77. package/dist/client/http/fetchVideos.js +0 -36
  78. package/dist/client/http/index.d.ts +0 -19
  79. package/dist/client/http/index.d.ts.map +0 -1
  80. package/dist/client/http/index.js +0 -11
  81. package/dist/error-handling/circuit-breaker.d.ts +0 -262
  82. package/dist/error-handling/circuit-breaker.d.ts.map +0 -1
  83. package/dist/error-handling/circuit-breaker.js +0 -550
  84. package/dist/error-handling/retry.d.ts +0 -194
  85. package/dist/error-handling/retry.d.ts.map +0 -1
  86. package/dist/error-handling/retry.js +0 -455
  87. package/dist/errors/index.d.ts +0 -23
  88. package/dist/errors/index.d.ts.map +0 -1
  89. package/dist/errors/index.js +0 -40
  90. package/dist/generated/agents/index.d.ts +0 -8
  91. package/dist/generated/agents/index.d.ts.map +0 -1
  92. package/dist/generated/agents/index.js +0 -7
  93. package/dist/generated/components/index.d.ts +0 -8
  94. package/dist/generated/components/index.d.ts.map +0 -1
  95. package/dist/generated/components/index.js +0 -7
  96. package/dist/generated/functions/index.d.ts +0 -8
  97. package/dist/generated/functions/index.d.ts.map +0 -1
  98. package/dist/generated/functions/index.js +0 -7
  99. package/dist/generated/hooks/index.d.ts +0 -8
  100. package/dist/generated/hooks/index.d.ts.map +0 -1
  101. package/dist/generated/hooks/index.js +0 -7
  102. package/dist/generated/plans/index.d.ts +0 -8
  103. package/dist/generated/plans/index.d.ts.map +0 -1
  104. package/dist/generated/plans/index.js +0 -7
  105. package/dist/generated/prompts/index.d.ts +0 -8
  106. package/dist/generated/prompts/index.d.ts.map +0 -1
  107. package/dist/generated/prompts/index.js +0 -7
  108. package/dist/generated/tools/index.d.ts +0 -8
  109. package/dist/generated/tools/index.d.ts.map +0 -1
  110. package/dist/generated/tools/index.js +0 -7
  111. package/dist/generated/types/supabase.d.ts +0 -193
  112. package/dist/generated/types/supabase.d.ts.map +0 -1
  113. package/dist/generated/types/supabase.js +0 -5
  114. package/dist/optimization/asset-optimizer.d.ts +0 -206
  115. package/dist/optimization/asset-optimizer.d.ts.map +0 -1
  116. package/dist/optimization/asset-optimizer.js +0 -336
  117. package/dist/optimization/build-optimizer.d.ts +0 -202
  118. package/dist/optimization/build-optimizer.d.ts.map +0 -1
  119. package/dist/optimization/build-optimizer.js +0 -271
  120. package/dist/optimization/bundle-analyzer.d.ts +0 -98
  121. package/dist/optimization/bundle-analyzer.d.ts.map +0 -1
  122. package/dist/optimization/bundle-analyzer.js +0 -346
  123. package/dist/optimization/code-splitting.d.ts +0 -121
  124. package/dist/optimization/code-splitting.d.ts.map +0 -1
  125. package/dist/optimization/code-splitting.js +0 -261
  126. package/dist/plugin/index.d.ts +0 -12
  127. package/dist/plugin/index.d.ts.map +0 -1
  128. package/dist/plugin/index.js +0 -4
  129. package/dist/security/audit.d.ts +0 -188
  130. package/dist/security/audit.d.ts.map +0 -1
  131. package/dist/security/audit.js +0 -433
  132. package/dist/security/auth.d.ts +0 -110
  133. package/dist/security/auth.d.ts.map +0 -1
  134. package/dist/security/auth.js +0 -257
  135. package/dist/security/authorization.d.ts +0 -211
  136. package/dist/security/authorization.d.ts.map +0 -1
  137. package/dist/security/authorization.js +0 -492
  138. package/dist/security/encryption.d.ts +0 -226
  139. package/dist/security/encryption.d.ts.map +0 -1
  140. package/dist/security/encryption.js +0 -534
  141. package/dist/security/gdpr-storage.d.ts +0 -102
  142. package/dist/security/gdpr-storage.d.ts.map +0 -1
  143. package/dist/security/gdpr-storage.js +0 -65
  144. package/dist/security/gdpr.d.ts +0 -320
  145. package/dist/security/gdpr.d.ts.map +0 -1
  146. package/dist/security/gdpr.js +0 -531
  147. package/dist/security/headers.d.ts +0 -184
  148. package/dist/security/headers.d.ts.map +0 -1
  149. package/dist/security/headers.js +0 -420
  150. package/dist/utils/jwt-validation.d.ts +0 -14
  151. package/dist/utils/jwt-validation.d.ts.map +0 -1
  152. package/dist/utils/jwt-validation.js +0 -36
  153. package/dist/utils/request-headers.d.ts +0 -15
  154. package/dist/utils/request-headers.d.ts.map +0 -1
  155. package/dist/utils/request-headers.js +0 -31
@@ -1,550 +0,0 @@
1
- /**
2
- * Circuit Breaker Pattern
3
- *
4
- * Prevents cascading failures by stopping requests to failing services
5
- */
6
- import { logger } from '../observability/logger.js';
7
- const DEFAULT_CONFIG = {
8
- failureThreshold: 5,
9
- successThreshold: 2,
10
- timeout: 60000,
11
- resetTimeout: 30000,
12
- volumeThreshold: 10,
13
- errorFilter: () => true,
14
- onStateChange: () => {
15
- // No-op default — consumers override via config
16
- },
17
- onTrip: () => {
18
- // No-op default — consumers override via config
19
- },
20
- onReset: () => {
21
- // No-op default — consumers override via config
22
- },
23
- };
24
- /**
25
- * Circuit Breaker implementation
26
- */
27
- export class CircuitBreaker {
28
- state = 'closed';
29
- failures = 0;
30
- successes = 0;
31
- consecutiveFailures = 0;
32
- consecutiveSuccesses = 0;
33
- totalCalls = 0;
34
- totalFailures = 0;
35
- totalSuccesses = 0;
36
- lastFailureTime;
37
- lastSuccessTime;
38
- stateChangedAt = Date.now();
39
- resetTimer;
40
- config;
41
- constructor(config = {}) {
42
- this.config = { ...DEFAULT_CONFIG, ...config };
43
- }
44
- /**
45
- * Execute function with circuit breaker
46
- */
47
- async execute(fn) {
48
- // Check if circuit is open
49
- if (this.state === 'open') {
50
- // Check if reset timeout has passed
51
- if (Date.now() - this.stateChangedAt >= this.config.resetTimeout) {
52
- this.transitionTo('half-open');
53
- }
54
- else {
55
- throw new CircuitBreakerOpenError('Circuit breaker is open');
56
- }
57
- }
58
- this.totalCalls++;
59
- try {
60
- const result = await fn();
61
- this.onSuccess();
62
- return result;
63
- }
64
- catch (error) {
65
- const err = error instanceof Error ? error : new Error(String(error));
66
- this.onFailure(err);
67
- throw error;
68
- }
69
- }
70
- /**
71
- * Handle successful execution
72
- */
73
- onSuccess() {
74
- this.successes++;
75
- this.consecutiveSuccesses++;
76
- this.totalSuccesses++;
77
- this.consecutiveFailures = 0;
78
- this.lastSuccessTime = Date.now();
79
- if (this.state === 'half-open') {
80
- // Check if we can close the circuit
81
- if (this.consecutiveSuccesses >= this.config.successThreshold) {
82
- this.transitionTo('closed');
83
- }
84
- }
85
- // Reset failure count in closed state
86
- if (this.state === 'closed') {
87
- this.failures = 0;
88
- }
89
- }
90
- /**
91
- * Handle failed execution
92
- */
93
- onFailure(error) {
94
- // Check if error should count
95
- if (!this.config.errorFilter(error)) {
96
- return;
97
- }
98
- this.failures++;
99
- this.consecutiveFailures++;
100
- this.totalFailures++;
101
- this.consecutiveSuccesses = 0;
102
- this.lastFailureTime = Date.now();
103
- if (this.state === 'half-open') {
104
- // Immediately open circuit on failure in half-open state
105
- this.transitionTo('open');
106
- }
107
- else if (this.state === 'closed') {
108
- // Check if we should open the circuit
109
- if (this.consecutiveFailures >= this.config.failureThreshold &&
110
- this.totalCalls >= this.config.volumeThreshold) {
111
- this.transitionTo('open');
112
- }
113
- }
114
- }
115
- /**
116
- * Transition to new state
117
- */
118
- transitionTo(newState) {
119
- if (this.state === newState)
120
- return;
121
- const oldState = this.state;
122
- this.state = newState;
123
- this.stateChangedAt = Date.now();
124
- // Reset counters
125
- if (newState === 'half-open' || newState === 'closed') {
126
- this.consecutiveFailures = 0;
127
- this.consecutiveSuccesses = 0;
128
- }
129
- // Clear reset timer
130
- if (this.resetTimer) {
131
- clearTimeout(this.resetTimer);
132
- this.resetTimer = undefined;
133
- }
134
- // Set reset timer for open state
135
- if (newState === 'open') {
136
- this.resetTimer = setTimeout(() => {
137
- this.transitionTo('half-open');
138
- }, this.config.resetTimeout);
139
- this.config.onTrip();
140
- }
141
- // Circuit reset
142
- if (newState === 'closed' && oldState === 'half-open') {
143
- this.failures = 0;
144
- this.config.onReset();
145
- }
146
- this.config.onStateChange(newState);
147
- logger.info(`Circuit breaker state changed: ${oldState} -> ${newState}`, this.getStats());
148
- }
149
- /**
150
- * Get current state
151
- */
152
- getState() {
153
- return this.state;
154
- }
155
- /**
156
- * Get statistics
157
- */
158
- getStats() {
159
- return {
160
- state: this.state,
161
- failures: this.failures,
162
- successes: this.successes,
163
- consecutiveFailures: this.consecutiveFailures,
164
- consecutiveSuccesses: this.consecutiveSuccesses,
165
- totalCalls: this.totalCalls,
166
- totalFailures: this.totalFailures,
167
- totalSuccesses: this.totalSuccesses,
168
- lastFailureTime: this.lastFailureTime,
169
- lastSuccessTime: this.lastSuccessTime,
170
- stateChangedAt: this.stateChangedAt,
171
- };
172
- }
173
- /**
174
- * Manually open circuit
175
- */
176
- trip() {
177
- this.transitionTo('open');
178
- }
179
- /**
180
- * Manually close circuit
181
- */
182
- reset() {
183
- this.failures = 0;
184
- this.successes = 0;
185
- this.consecutiveFailures = 0;
186
- this.consecutiveSuccesses = 0;
187
- this.transitionTo('closed');
188
- }
189
- /**
190
- * Force state to half-open
191
- */
192
- halfOpen() {
193
- this.transitionTo('half-open');
194
- }
195
- /**
196
- * Check if circuit is open
197
- */
198
- isOpen() {
199
- return this.state === 'open';
200
- }
201
- /**
202
- * Check if circuit is closed
203
- */
204
- isClosed() {
205
- return this.state === 'closed';
206
- }
207
- /**
208
- * Check if circuit is half-open
209
- */
210
- isHalfOpen() {
211
- return this.state === 'half-open';
212
- }
213
- /**
214
- * Get failure rate
215
- */
216
- getFailureRate() {
217
- if (this.totalCalls === 0)
218
- return 0;
219
- return this.totalFailures / this.totalCalls;
220
- }
221
- /**
222
- * Get success rate
223
- */
224
- getSuccessRate() {
225
- if (this.totalCalls === 0)
226
- return 0;
227
- return this.totalSuccesses / this.totalCalls;
228
- }
229
- /**
230
- * Cleanup
231
- */
232
- destroy() {
233
- if (this.resetTimer) {
234
- clearTimeout(this.resetTimer);
235
- }
236
- }
237
- }
238
- /**
239
- * Circuit breaker open error
240
- */
241
- export class CircuitBreakerOpenError extends Error {
242
- constructor(message = 'Circuit breaker is open') {
243
- super(message);
244
- this.name = 'CircuitBreakerOpenError';
245
- }
246
- }
247
- /**
248
- * Circuit breaker registry
249
- */
250
- export class CircuitBreakerRegistry {
251
- breakers = new Map();
252
- /**
253
- * Get or create circuit breaker
254
- */
255
- get(name, config) {
256
- let breaker = this.breakers.get(name);
257
- if (!breaker) {
258
- breaker = new CircuitBreaker(config);
259
- this.breakers.set(name, breaker);
260
- }
261
- return breaker;
262
- }
263
- /**
264
- * Check if breaker exists
265
- */
266
- has(name) {
267
- return this.breakers.has(name);
268
- }
269
- /**
270
- * Remove circuit breaker
271
- */
272
- remove(name) {
273
- const breaker = this.breakers.get(name);
274
- if (breaker) {
275
- breaker.destroy();
276
- return this.breakers.delete(name);
277
- }
278
- return false;
279
- }
280
- /**
281
- * Get all breakers
282
- */
283
- getAll() {
284
- return new Map(this.breakers);
285
- }
286
- /**
287
- * Get all statistics
288
- */
289
- getAllStats() {
290
- const stats = {};
291
- for (const [name, breaker] of this.breakers) {
292
- stats[name] = breaker.getStats();
293
- }
294
- return stats;
295
- }
296
- /**
297
- * Reset all breakers
298
- */
299
- resetAll() {
300
- for (const breaker of this.breakers.values()) {
301
- breaker.reset();
302
- }
303
- }
304
- /**
305
- * Clear all breakers
306
- */
307
- clear() {
308
- for (const breaker of this.breakers.values()) {
309
- breaker.destroy();
310
- }
311
- this.breakers.clear();
312
- }
313
- }
314
- /**
315
- * Global circuit breaker registry
316
- */
317
- export const circuitBreakerRegistry = new CircuitBreakerRegistry();
318
- /**
319
- * Create circuit breaker decorator
320
- */
321
- export function CircuitBreak(nameOrConfig = {}) {
322
- return (target, propertyKey, descriptor) => {
323
- const originalMethod = descriptor.value;
324
- const name = typeof nameOrConfig === 'string'
325
- ? nameOrConfig
326
- : `${target.constructor.name}.${propertyKey}`;
327
- const config = typeof nameOrConfig === 'object' ? nameOrConfig : undefined;
328
- descriptor.value = async function (...args) {
329
- const breaker = circuitBreakerRegistry.get(name, config);
330
- return breaker.execute(() => originalMethod.apply(this, args));
331
- };
332
- return descriptor;
333
- };
334
- }
335
- /**
336
- * Execute with circuit breaker
337
- */
338
- export async function withCircuitBreaker(name, fn, config) {
339
- const breaker = circuitBreakerRegistry.get(name, config);
340
- return breaker.execute(fn);
341
- }
342
- /**
343
- * Create circuit breaker middleware
344
- */
345
- export function createCircuitBreakerMiddleware(name, config) {
346
- const breaker = circuitBreakerRegistry.get(name, config);
347
- return async (_request, next) => {
348
- return breaker.execute(next);
349
- };
350
- }
351
- /**
352
- * Circuit breaker for fetch
353
- */
354
- export async function fetchWithCircuitBreaker(name, url, init, config) {
355
- const breaker = circuitBreakerRegistry.get(name, config);
356
- return breaker.execute(async () => {
357
- const response = await fetch(url, init);
358
- // Treat 5xx errors as failures
359
- if (response.status >= 500) {
360
- const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
361
- error.statusCode = response.status;
362
- throw error;
363
- }
364
- return response;
365
- });
366
- }
367
- /**
368
- * Adaptive circuit breaker with dynamic thresholds
369
- */
370
- export class AdaptiveCircuitBreaker extends CircuitBreaker {
371
- errorRateWindow = [];
372
- windowSize = 100;
373
- adaptiveThreshold;
374
- constructor(config = {}) {
375
- super(config);
376
- this.adaptiveThreshold = config.failureThreshold || 5;
377
- }
378
- /**
379
- * Execute with adaptive thresholds
380
- */
381
- async execute(fn) {
382
- try {
383
- const result = await super.execute(fn);
384
- this.recordSuccess();
385
- return result;
386
- }
387
- catch (error) {
388
- this.recordFailure();
389
- throw error;
390
- }
391
- }
392
- /**
393
- * Record success in window
394
- */
395
- recordSuccess() {
396
- this.errorRateWindow.push(0);
397
- this.trimWindow();
398
- this.adjustThreshold();
399
- }
400
- /**
401
- * Record failure in window
402
- */
403
- recordFailure() {
404
- this.errorRateWindow.push(1);
405
- this.trimWindow();
406
- this.adjustThreshold();
407
- }
408
- /**
409
- * Trim window to size
410
- */
411
- trimWindow() {
412
- if (this.errorRateWindow.length > this.windowSize) {
413
- this.errorRateWindow.shift();
414
- }
415
- }
416
- /**
417
- * Adjust threshold based on error rate
418
- */
419
- adjustThreshold() {
420
- const errorRate = this.getWindowErrorRate();
421
- // Increase threshold if error rate is low
422
- if (errorRate < 0.1) {
423
- this.adaptiveThreshold = Math.min(this.adaptiveThreshold + 1, 20);
424
- }
425
- // Decrease threshold if error rate is high
426
- else if (errorRate > 0.5) {
427
- this.adaptiveThreshold = Math.max(this.adaptiveThreshold - 1, 2);
428
- }
429
- // Sync adaptive threshold to parent config so it actually takes effect
430
- this.config.failureThreshold = this.adaptiveThreshold;
431
- }
432
- /**
433
- * Get error rate in window
434
- */
435
- getWindowErrorRate() {
436
- if (this.errorRateWindow.length === 0)
437
- return 0;
438
- const errors = this.errorRateWindow.reduce((sum, val) => sum + val, 0);
439
- return errors / this.errorRateWindow.length;
440
- }
441
- /**
442
- * Get adaptive threshold
443
- */
444
- getAdaptiveThreshold() {
445
- return this.adaptiveThreshold;
446
- }
447
- }
448
- /**
449
- * Bulkhead pattern - limit concurrent executions
450
- */
451
- export class Bulkhead {
452
- activeRequests = 0;
453
- queue = [];
454
- maxConcurrent;
455
- maxQueue;
456
- constructor(maxConcurrent = 10, maxQueue = 100) {
457
- this.maxConcurrent = maxConcurrent;
458
- this.maxQueue = maxQueue;
459
- }
460
- /**
461
- * Execute with bulkhead
462
- */
463
- async execute(fn) {
464
- // Check if at capacity
465
- if (this.activeRequests >= this.maxConcurrent) {
466
- // Check queue capacity
467
- if (this.queue.length >= this.maxQueue) {
468
- throw new Error('Bulkhead queue is full');
469
- }
470
- // Wait for slot
471
- await new Promise((resolve) => {
472
- this.queue.push(resolve);
473
- });
474
- }
475
- this.activeRequests++;
476
- try {
477
- return await fn();
478
- }
479
- finally {
480
- this.activeRequests--;
481
- // Process queue
482
- const next = this.queue.shift();
483
- if (next) {
484
- next();
485
- }
486
- }
487
- }
488
- /**
489
- * Get active requests
490
- */
491
- getActiveRequests() {
492
- return this.activeRequests;
493
- }
494
- /**
495
- * Get queue size
496
- */
497
- getQueueSize() {
498
- return this.queue.length;
499
- }
500
- /**
501
- * Get statistics
502
- */
503
- getStats() {
504
- return {
505
- activeRequests: this.activeRequests,
506
- queueSize: this.queue.length,
507
- maxConcurrent: this.maxConcurrent,
508
- maxQueue: this.maxQueue,
509
- };
510
- }
511
- }
512
- /**
513
- * Combined resilience wrapper
514
- */
515
- export class ResilientOperation {
516
- fn;
517
- circuitBreaker;
518
- bulkhead;
519
- constructor(fn, circuitBreaker, bulkhead) {
520
- this.fn = fn;
521
- this.circuitBreaker = circuitBreaker;
522
- this.bulkhead = bulkhead;
523
- }
524
- /**
525
- * Execute with all resilience patterns
526
- */
527
- async execute() {
528
- const executeFn = async () => {
529
- if (this.bulkhead) {
530
- return this.bulkhead.execute(this.fn);
531
- }
532
- return this.fn();
533
- };
534
- if (this.circuitBreaker) {
535
- return this.circuitBreaker.execute(executeFn);
536
- }
537
- return executeFn();
538
- }
539
- }
540
- /**
541
- * Create resilient function
542
- */
543
- export function createResilientFunction(fn, options = {}) {
544
- const breaker = options.circuitBreaker ? new CircuitBreaker(options.circuitBreaker) : undefined;
545
- const bulkhead = options.bulkhead
546
- ? new Bulkhead(options.bulkhead.maxConcurrent, options.bulkhead.maxQueue)
547
- : undefined;
548
- const operation = new ResilientOperation(fn, breaker, bulkhead);
549
- return () => operation.execute();
550
- }