@fabricorg/platform 1.7.0 → 1.8.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 (59) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +214 -3
  3. package/dist/actions/index.cjs +6 -6
  4. package/dist/actions/index.d.cts +9 -2
  5. package/dist/actions/index.d.ts +9 -2
  6. package/dist/actions/index.js +1 -1
  7. package/dist/adapters/index.cjs +33 -9
  8. package/dist/adapters/index.d.cts +388 -1
  9. package/dist/adapters/index.d.ts +388 -1
  10. package/dist/adapters/index.js +1 -1
  11. package/dist/chunk-5FOCPRTR.js +511 -0
  12. package/dist/chunk-5FOCPRTR.js.map +1 -0
  13. package/dist/{chunk-USDLP4E7.cjs → chunk-5IVFPWK6.cjs} +4 -4
  14. package/dist/{chunk-USDLP4E7.cjs.map → chunk-5IVFPWK6.cjs.map} +1 -1
  15. package/dist/chunk-6HY35TKB.cjs +491 -0
  16. package/dist/chunk-6HY35TKB.cjs.map +1 -0
  17. package/dist/chunk-6UGEIDLC.cjs +26 -0
  18. package/dist/chunk-6UGEIDLC.cjs.map +1 -0
  19. package/dist/chunk-BJGZE3GE.js +20 -0
  20. package/dist/chunk-BJGZE3GE.js.map +1 -0
  21. package/dist/{chunk-X3GHYMAJ.cjs → chunk-CRZXTZ36.cjs} +2 -22
  22. package/dist/chunk-CRZXTZ36.cjs.map +1 -0
  23. package/dist/{chunk-DCC3UIUJ.js → chunk-GFU7BGEJ.js} +3 -3
  24. package/dist/{chunk-DCC3UIUJ.js.map → chunk-GFU7BGEJ.js.map} +1 -1
  25. package/dist/chunk-HEYMMVDP.js +480 -0
  26. package/dist/chunk-HEYMMVDP.js.map +1 -0
  27. package/dist/chunk-IF6NJORI.cjs +526 -0
  28. package/dist/chunk-IF6NJORI.cjs.map +1 -0
  29. package/dist/{chunk-6QX4I45I.js → chunk-PIDZQAEL.js} +2 -2
  30. package/dist/{chunk-6QX4I45I.js.map → chunk-PIDZQAEL.js.map} +1 -1
  31. package/dist/{chunk-ATWWZTRC.js → chunk-TYNIFC7J.js} +3 -18
  32. package/dist/chunk-TYNIFC7J.js.map +1 -0
  33. package/dist/{chunk-XCAOO6KG.cjs → chunk-UGWGHTNC.cjs} +2 -2
  34. package/dist/{chunk-XCAOO6KG.cjs.map → chunk-UGWGHTNC.cjs.map} +1 -1
  35. package/dist/evidence/index.cjs +45 -1
  36. package/dist/evidence/index.d.cts +187 -1
  37. package/dist/evidence/index.d.ts +187 -1
  38. package/dist/evidence/index.js +3 -1
  39. package/dist/governance/index.d.cts +1 -0
  40. package/dist/governance/index.d.ts +1 -0
  41. package/dist/index.cjs +124 -59
  42. package/dist/index.d.cts +2 -2
  43. package/dist/index.d.ts +2 -2
  44. package/dist/index.js +7 -6
  45. package/dist/privacy/index.cjs +19 -18
  46. package/dist/privacy/index.js +2 -1
  47. package/dist/testing/index.cjs +5 -5
  48. package/dist/testing/index.js +2 -2
  49. package/package.json +1 -1
  50. package/dist/chunk-ATWWZTRC.js.map +0 -1
  51. package/dist/chunk-FAG2RTPM.js +0 -120
  52. package/dist/chunk-FAG2RTPM.js.map +0 -1
  53. package/dist/chunk-OZLZHISS.js +0 -3
  54. package/dist/chunk-OZLZHISS.js.map +0 -1
  55. package/dist/chunk-PG5LYTUX.cjs +0 -4
  56. package/dist/chunk-PG5LYTUX.cjs.map +0 -1
  57. package/dist/chunk-X3GHYMAJ.cjs.map +0 -1
  58. package/dist/chunk-XZQZQ5SW.cjs +0 -129
  59. package/dist/chunk-XZQZQ5SW.cjs.map +0 -1
@@ -1,3 +1,334 @@
1
+ /**
2
+ * State of an adapter circuit breaker.
3
+ *
4
+ * - `closed`: calls flow and outcomes are counted.
5
+ * - `open`: the dependency is presumed unhealthy. In `enforce` mode calls are
6
+ * rejected without being attempted until `cooldownMs` has elapsed.
7
+ * - `half_open`: the cooldown elapsed. One probe call is admitted; its outcome
8
+ * closes the breaker (success) or reopens it (failure).
9
+ */
10
+ type AdapterCircuitState = "closed" | "open" | "half_open";
11
+ /**
12
+ * How a single adapter outcome counts toward the breaker.
13
+ *
14
+ * - `success`: the dependency answered and the call succeeded.
15
+ * - `failure`: evidence the dependency is unhealthy.
16
+ * - `ignored`: the dependency answered but rejected the request on its merits
17
+ * (a validation or business rejection). It is neither a success nor a
18
+ * dependency failure and does not enter the rolling window.
19
+ */
20
+ type AdapterCircuitOutcome = "success" | "failure" | "ignored";
21
+ /**
22
+ * Map an {@link AdapterOutcomeKind} to how it counts toward a circuit breaker.
23
+ *
24
+ * | Outcome kind | Counts as |
25
+ * |---------------------|-----------|
26
+ * | `success` | `success` |
27
+ * | `transient_failure` | `failure` |
28
+ * | `timeout` | `failure` |
29
+ * | `ambiguous` | `failure` |
30
+ * | `permanent_failure` | `ignored` |
31
+ *
32
+ * `ambiguous` counts as a failure: the dependency did not give a definite
33
+ * answer, which is a health signal even though the Host routes the invocation
34
+ * to reconciliation. `permanent_failure` (validation or rejection) is the
35
+ * dependency working correctly and saying no, so it does not trip the breaker.
36
+ * `executeWithAdapterRetry` classifies a thrown error with the caller's
37
+ * `classifyThrownError` (default `transient_failure`) and maps that kind here,
38
+ * so an unclassified thrown error counts as a failure.
39
+ */
40
+ declare function classifyCircuitBreakerOutcome(kind: AdapterOutcomeKind): AdapterCircuitOutcome;
41
+ /** The answer a breaker gives before a call. */
42
+ interface AdapterCircuitAdmission {
43
+ /**
44
+ * Whether the call may proceed. Always `true` in `monitor` mode; `false`
45
+ * only in `enforce` mode while the breaker is open, forced open, or
46
+ * half-open with its probe already in flight.
47
+ */
48
+ allowed: boolean;
49
+ /** State at the time of the decision. */
50
+ state: AdapterCircuitState;
51
+ /** True when this admission is the half-open probe. Pass it back to `record`. */
52
+ probe: boolean;
53
+ /** Monitor mode only: true when `enforce` mode would have rejected this call. */
54
+ wouldReject?: boolean;
55
+ /**
56
+ * Milliseconds until the breaker will admit a probe, when known. Absent while
57
+ * a manual `force_open` override is set or a half-open probe is in flight.
58
+ */
59
+ retryAfterMs?: number;
60
+ /** Set when a manual override decided the admission. */
61
+ manualOverride?: AdapterCircuitBreakerManualOverride;
62
+ /**
63
+ * The breaker epoch the admission was granted in; opaque to callers.
64
+ * {@link InMemoryAdapterCircuitBreaker} lets an outcome change state only
65
+ * when this still matches its current epoch. An admission without it is
66
+ * treated as current.
67
+ */
68
+ generation?: number;
69
+ }
70
+ /**
71
+ * Contract between a circuit breaker and `executeWithAdapterRetry`.
72
+ * Implement it to plug in a shared or distributed breaker.
73
+ */
74
+ interface AdapterCircuitBreaker {
75
+ /** `adapterType:operation` this breaker guards. */
76
+ readonly key: string;
77
+ readonly mode: "monitor" | "enforce";
78
+ /** Current state, applying any elapsed cooldown or manual override. */
79
+ getState(): AdapterCircuitState;
80
+ /**
81
+ * Preview whether a call would be admitted now. Side-effect free: it does
82
+ * not commit an elapsed cooldown, take the half-open probe or emit
83
+ * telemetry.
84
+ */
85
+ check(): AdapterCircuitAdmission;
86
+ /**
87
+ * Decide whether a call may start now. Call it immediately before the
88
+ * external effect and pass the returned admission to {@link record}.
89
+ */
90
+ acquire(): AdapterCircuitAdmission;
91
+ /**
92
+ * Record the outcome of a call that was admitted by {@link acquire}. Pass
93
+ * that admission, not a {@link check} preview, so the breaker can tell a
94
+ * stale outcome from a current one.
95
+ */
96
+ record(outcome: AdapterCircuitOutcome, admission?: AdapterCircuitAdmission): void;
97
+ }
98
+ type AdapterCircuitBreakerEventReason = "failure_threshold" | "cooldown_elapsed" | "probe_succeeded" | "probe_failed" | "manual_override" | "manual_override_cleared";
99
+ interface AdapterCircuitBreakerEventBase {
100
+ key: string;
101
+ mode: "monitor" | "enforce";
102
+ /** Epoch milliseconds from the breaker's clock. */
103
+ at: number;
104
+ }
105
+ /** Telemetry reported by {@link InMemoryAdapterCircuitBreaker}. */
106
+ type AdapterCircuitBreakerEvent = (AdapterCircuitBreakerEventBase & {
107
+ type: "state_change";
108
+ from: AdapterCircuitState;
109
+ to: AdapterCircuitState;
110
+ reason: AdapterCircuitBreakerEventReason;
111
+ manualOverride?: AdapterCircuitBreakerManualOverride;
112
+ }) | (AdapterCircuitBreakerEventBase & {
113
+ /** Enforce mode refused a call; it was not attempted. */
114
+ type: "rejected";
115
+ state: AdapterCircuitState;
116
+ retryAfterMs?: number;
117
+ manualOverride?: AdapterCircuitBreakerManualOverride;
118
+ }) | (AdapterCircuitBreakerEventBase & {
119
+ /** Monitor mode let a call through that enforce mode would have refused. */
120
+ type: "would_reject";
121
+ state: AdapterCircuitState;
122
+ retryAfterMs?: number;
123
+ manualOverride?: AdapterCircuitBreakerManualOverride;
124
+ });
125
+ /**
126
+ * Telemetry callback. Errors it throws and promises it rejects are caught
127
+ * and discarded so telemetry cannot change an adapter call's outcome.
128
+ *
129
+ * {@link InMemoryAdapterCircuitBreaker} calls it only after the operation that
130
+ * produced the event has committed, never part-way through a decision or a
131
+ * record. A callback may call back into the breaker; it sees committed state,
132
+ * and events its own calls produce are delivered after it returns, in order.
133
+ */
134
+ type AdapterCircuitBreakerEventListener = (event: AdapterCircuitBreakerEvent) => void | Promise<void>;
135
+ interface InMemoryAdapterCircuitBreakerOptions {
136
+ /** Usually `adapterType:operation`. */
137
+ key: string;
138
+ config: AdapterCircuitBreakerConfig;
139
+ /** Epoch-millisecond clock. Defaults to `Date.now`. */
140
+ now?: () => number;
141
+ onEvent?: AdapterCircuitBreakerEventListener;
142
+ }
143
+ /**
144
+ * Validate a circuit-breaker config. Throws a `RangeError` naming the first
145
+ * invalid field: `mode` must be `monitor` or `enforce`; `failureThreshold` and
146
+ * `minimumSamples` positive integers; `windowMs` and `probeLeaseMs` positive
147
+ * finite numbers; `cooldownMs` a non-negative finite number; `manualOverride`
148
+ * `force_open` or `force_closed` when present.
149
+ */
150
+ declare function assertAdapterCircuitBreakerConfig(config: AdapterCircuitBreakerConfig): void;
151
+ /**
152
+ * Dependency-free, in-process circuit breaker for one adapter operation.
153
+ *
154
+ * State lives in this instance only: it is not shared between processes,
155
+ * hosts, or replicas, and it is lost on restart. Each replica trips on the
156
+ * failures it observes itself.
157
+ *
158
+ * Tripping rule (parity with the .NET `InMemoryAdapterCircuitBreaker`): after
159
+ * a failure is recorded while `closed`, let `N` be the outcomes recorded within
160
+ * the last `windowMs` and `M = minimumSamples ?? failureThreshold`. The breaker
161
+ * opens when `N >= M` and either
162
+ * 1. the most recent `failureThreshold` outcomes in the window are all
163
+ * failures, or
164
+ * 2. the failure ratio in the window is at least `failureThreshold / M`.
165
+ *
166
+ * With `minimumSamples` omitted this reads "`failureThreshold` consecutive
167
+ * failures". With `minimumSamples: 20, failureThreshold: 10` it also opens at
168
+ * a 50% failure rate over at least 20 calls.
169
+ *
170
+ * After `cooldownMs` the breaker turns `half_open` and admits one probe. A
171
+ * probe success closes it and clears the window; a probe failure reopens it
172
+ * and restarts the cooldown. At most one probe is outstanding at a time: it
173
+ * holds a lease of `probeLeaseMs` (default `max(cooldownMs, windowMs)`, never
174
+ * derived from the cooldown alone, so `cooldownMs: 0` still admits one probe).
175
+ * A probe that has not recorded when its lease expires is considered lost and
176
+ * the next call becomes the probe.
177
+ *
178
+ * Epochs: the breaker keeps a generation counter that advances on every state
179
+ * change (including one committed by an elapsed cooldown), every manual
180
+ * override change, and every probe grant. Each admission carries the
181
+ * generation it was granted in. `record` first commits any elapsed cooldown,
182
+ * then compares generations. An outcome from an earlier epoch is stale: it is
183
+ * dropped entirely. It changes no state, does not resolve or free the probe
184
+ * slot, and is not added to the rolling window, so it cannot contribute to a
185
+ * later trip either. Because a probe grant starts a new epoch, the outstanding
186
+ * probe is the only `probe: true` admission of the current epoch, which is how
187
+ * a replaced probe's late outcome is told apart. An outcome recorded without an
188
+ * admission, or with one that has no `generation`, is treated as current: it is
189
+ * sampled, can trip a closed breaker and resolves an outstanding probe.
190
+ *
191
+ * Telemetry is buffered and delivered after each operation commits. An
192
+ * elapsed cooldown is committed, and its `cooldown_elapsed` event delivered,
193
+ * as a step of its own before `acquire`, `record`, `getState` or
194
+ * `setManualOverride` continues, so a callback reacting to it (for example by
195
+ * forcing the breaker open) governs the call that observed it. Every other
196
+ * event is delivered once the method's decision or record is final, and a
197
+ * callback never revokes an admission that is already committed. Two cases
198
+ * follow from that: a breaker call made from inside a callback queues its own
199
+ * `cooldown_elapsed` behind the current delivery and decides first; and with
200
+ * `cooldownMs: 0`, a cooldown that falls due again during the decision (because
201
+ * a callback reopened the breaker) is committed and admitted before its event
202
+ * is delivered.
203
+ *
204
+ * `monitor` mode runs the same state machine and reports the same telemetry
205
+ * but admits every call; calls enforce mode would have refused are reported
206
+ * as `would_reject`.
207
+ *
208
+ * A manual override pins the reported state (`force_open` → `open`,
209
+ * `force_closed` → `closed`) and suspends automatic transitions while set;
210
+ * outcomes of calls admitted under the override are still recorded. Like an
211
+ * automatic open, `force_open` blocks only in `enforce` mode. Clearing the
212
+ * override returns the breaker to `closed` with its window intact.
213
+ */
214
+ declare class InMemoryAdapterCircuitBreaker implements AdapterCircuitBreaker {
215
+ readonly key: string;
216
+ readonly mode: "monitor" | "enforce";
217
+ private readonly config;
218
+ private readonly now;
219
+ private readonly onEvent;
220
+ private readonly probeLeaseMs;
221
+ private samples;
222
+ private state;
223
+ private openedAt;
224
+ private probeIssuedAt;
225
+ /** Advances on every state change, manual override change and probe grant. */
226
+ private generation;
227
+ private manualOverride;
228
+ /** Telemetry waiting for the current operation to commit. */
229
+ private readonly outbox;
230
+ private operationDepth;
231
+ private flushing;
232
+ constructor(options: InMemoryAdapterCircuitBreakerOptions);
233
+ getState(): AdapterCircuitState;
234
+ getManualOverride(): AdapterCircuitBreakerManualOverride | undefined;
235
+ /**
236
+ * Set (`force_open` / `force_closed`) or clear (`undefined`) the manual
237
+ * override. Clearing returns the breaker to `closed` with its window intact.
238
+ */
239
+ setManualOverride(override: AdapterCircuitBreakerManualOverride | undefined): void;
240
+ check(): AdapterCircuitAdmission;
241
+ acquire(): AdapterCircuitAdmission;
242
+ record(outcome: AdapterCircuitOutcome, admission?: AdapterCircuitAdmission): void;
243
+ private applyOutcome;
244
+ /**
245
+ * `take` is false for {@link check}: a pure preview that sees an elapsed
246
+ * cooldown without committing it, takes no probe and emits nothing.
247
+ */
248
+ private decide;
249
+ private refuse;
250
+ private releaseProbe;
251
+ /** Apply the time-based open → half_open transition. */
252
+ private advance;
253
+ private shouldTrip;
254
+ private prune;
255
+ private transition;
256
+ private reportedState;
257
+ /**
258
+ * Commit an elapsed cooldown as an operation of its own, delivering its
259
+ * event before the caller's operation reads state.
260
+ */
261
+ private settle;
262
+ /**
263
+ * Run `step` to completion, then deliver the telemetry it produced. The
264
+ * return value is fixed before any listener runs.
265
+ */
266
+ private operation;
267
+ private emit;
268
+ /**
269
+ * Deliver buffered events in order. A listener that calls back into the
270
+ * breaker queues its own events; this loop delivers them after it returns
271
+ * instead of recursing.
272
+ */
273
+ private flush;
274
+ private deliver;
275
+ }
276
+ /** Supplies the breaker, if any, that guards an adapter. */
277
+ interface AdapterCircuitBreakerProvider {
278
+ forAdapter(adapter: AdapterImplementation): AdapterCircuitBreaker | undefined;
279
+ }
280
+ interface AdapterCircuitBreakerRegistryOptions {
281
+ /** Epoch-millisecond clock handed to every breaker. Defaults to `Date.now`. */
282
+ now?: () => number;
283
+ onEvent?: AdapterCircuitBreakerEventListener;
284
+ }
285
+ /**
286
+ * Lazily creates one {@link InMemoryAdapterCircuitBreaker} per
287
+ * `adapterType:operation`, from that adapter's own `circuitBreaker` config.
288
+ * Adapters without a config get no breaker. The first config seen for a key
289
+ * wins; share a registry only between hosts that register the same adapters.
290
+ */
291
+ declare class AdapterCircuitBreakerRegistry implements AdapterCircuitBreakerProvider {
292
+ private readonly options;
293
+ private readonly breakers;
294
+ constructor(options?: AdapterCircuitBreakerRegistryOptions);
295
+ forAdapter(adapter: AdapterImplementation): InMemoryAdapterCircuitBreaker | undefined;
296
+ /** The breaker already created for `adapterType:operation`, if any. */
297
+ get(adapterType: string, operation: string): InMemoryAdapterCircuitBreaker | undefined;
298
+ }
299
+ /**
300
+ * Thrown by `executeWithAdapterRetry` when an `enforce`-mode breaker refuses
301
+ * an attempt. The refused attempt never reached `execute`, so no external
302
+ * effect happened for it.
303
+ */
304
+ declare class AdapterCircuitOpenError extends Error {
305
+ readonly name = "AdapterCircuitOpenError";
306
+ readonly code: "ADAPTER_CIRCUIT_OPEN";
307
+ readonly reason: "circuit_open";
308
+ readonly adapterKey: string;
309
+ readonly state: AdapterCircuitState;
310
+ /** The attempt number that was refused (1 = refused before any call). */
311
+ readonly attempt: number;
312
+ readonly retryAfterMs?: number;
313
+ readonly manualOverride?: AdapterCircuitBreakerManualOverride;
314
+ /** Error of the previous attempt, when the breaker opened mid-retry. */
315
+ readonly lastError?: string;
316
+ constructor(input: {
317
+ adapterKey: string;
318
+ state: AdapterCircuitState;
319
+ attempt: number;
320
+ retryAfterMs?: number;
321
+ manualOverride?: AdapterCircuitBreakerManualOverride;
322
+ lastError?: string;
323
+ });
324
+ }
325
+ /**
326
+ * Recognise an {@link AdapterCircuitOpenError}, including one constructed by a
327
+ * second copy of this package (for example an ESM and a CommonJS build loaded
328
+ * side by side), where `instanceof` fails.
329
+ */
330
+ declare function isAdapterCircuitOpenError(error: unknown): error is AdapterCircuitOpenError;
331
+
1
332
  interface AdapterExecutionContext {
2
333
  tenantId: string;
3
334
  spaceId: string;
@@ -89,12 +420,49 @@ interface ResolvedAdapterRetryPolicy {
89
420
  backoffMultiplier: number;
90
421
  maxDelayMs: number;
91
422
  }
423
+ /** Manual circuit-breaker override: pin the breaker open or closed. */
424
+ type AdapterCircuitBreakerManualOverride = "force_open" | "force_closed";
425
+ /**
426
+ * Per-adapter circuit-breaker configuration, read by
427
+ * {@link AdapterCircuitBreakerRegistry} (and so by Platform Host) to create one
428
+ * in-process {@link InMemoryAdapterCircuitBreaker} per `adapterType:operation`.
429
+ * Validated by {@link assertAdapterCircuitBreakerConfig}.
430
+ */
92
431
  interface AdapterCircuitBreakerConfig {
432
+ /**
433
+ * `monitor` records outcomes, runs the state machine and reports what it
434
+ * would have refused, but never blocks a call. `enforce` refuses calls
435
+ * while the breaker is open, without attempting them.
436
+ */
93
437
  mode: "monitor" | "enforce";
438
+ /**
439
+ * A failure count. Let `M = minimumSamples ?? failureThreshold`. Once at
440
+ * least `M` outcomes fall within `windowMs`, the breaker opens when the most
441
+ * recent `failureThreshold` of them are all failures, or when the failure
442
+ * ratio in the window reaches `failureThreshold / M`. Without
443
+ * `minimumSamples` this is "`failureThreshold` consecutive failures".
444
+ * Matches the .NET port's `InMemoryAdapterCircuitBreaker`. Positive integer.
445
+ */
94
446
  failureThreshold: number;
447
+ /** Rolling window, in milliseconds, of outcomes the thresholds consider. */
95
448
  windowMs: number;
449
+ /** Milliseconds an open breaker waits before admitting one half-open probe. */
96
450
  cooldownMs: number;
451
+ /** Outcomes required in the window before the breaker can open. Defaults to `failureThreshold`. */
97
452
  minimumSamples?: number;
453
+ /**
454
+ * How long, in milliseconds, the single half-open probe holds its slot
455
+ * before it is presumed lost and another call may probe. Defaults to
456
+ * `max(cooldownMs, windowMs)`; it is independent of `cooldownMs`, so a zero
457
+ * or short cooldown never admits concurrent probes. Positive.
458
+ */
459
+ probeLeaseMs?: number;
460
+ /**
461
+ * Optional initial manual override. `force_open` reports `open` (and blocks
462
+ * only in `enforce` mode); `force_closed` reports `closed` and never blocks.
463
+ * Change it at runtime with `InMemoryAdapterCircuitBreaker.setManualOverride`.
464
+ */
465
+ manualOverride?: AdapterCircuitBreakerManualOverride;
98
466
  }
99
467
  interface AdapterImplementation {
100
468
  adapterType: string;
@@ -136,6 +504,25 @@ interface ExecuteWithRetryOptions<T> {
136
504
  classifyThrownError?: (error: unknown) => AdapterOutcomeKind;
137
505
  sleep?: (delayMs: number) => Promise<void>;
138
506
  onAttempt?: (attempt: AdapterAttempt<T>) => Promise<void> | void;
507
+ /**
508
+ * Optional per-attempt preparation, awaited before the circuit breaker is
509
+ * consulted and before `execute` (for example, persisting the attempt
510
+ * number). Put every await a caller needs before the call here, so that
511
+ * nothing awaits between breaker admission and the external call. If it
512
+ * throws, no admission is taken and no breaker outcome is recorded; the
513
+ * error is classified with `classifyThrownError` and retried or rethrown
514
+ * exactly like an error thrown by `execute`.
515
+ */
516
+ prepareAttempt?: (attempt: number, maxAttempts: number) => Promise<void> | void;
517
+ /**
518
+ * Optional circuit breaker. When present, `acquire()` is called
519
+ * immediately before every `execute` call, with no await in between, and every attempt's outcome is
520
+ * recorded through {@link classifyCircuitBreakerOutcome}. In `enforce` mode
521
+ * a refused attempt is not executed and {@link AdapterCircuitOpenError} is
522
+ * thrown; if the breaker opens between attempts, retrying stops and the
523
+ * same error is thrown. When omitted, behaviour is unchanged.
524
+ */
525
+ circuitBreaker?: AdapterCircuitBreaker;
139
526
  }
140
527
  declare class MissingAdapterRegistrationError extends Error {
141
528
  constructor(adapterType: string, operation: string);
@@ -171,4 +558,4 @@ declare function shouldRetryAdapterOutcome(kind: AdapterOutcomeKind, idempotent:
171
558
  declare function assertAdapterOutcomeConsistency(result: AdapterExecutionResult): void;
172
559
  declare function executeWithAdapterRetry<T>(options: ExecuteWithRetryOptions<T>): Promise<T>;
173
560
 
174
- export { type AcceptedExternalOperation, type AdapterAttempt, type AdapterCircuitBreakerConfig, type AdapterExecutionContext, type AdapterExecutionResult, type AdapterExecutor, type AdapterImplementation, type AdapterOutcomeEvidence, type AdapterOutcomeKind, AdapterRegistry, type AdapterRetryPolicy, type ExecuteWithRetryOptions, MissingAdapterRegistrationError, type ResolvedAdapterRetryPolicy, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
561
+ export { type AcceptedExternalOperation, type AdapterAttempt, type AdapterCircuitAdmission, type AdapterCircuitBreaker, type AdapterCircuitBreakerConfig, type AdapterCircuitBreakerEvent, type AdapterCircuitBreakerEventListener, type AdapterCircuitBreakerEventReason, type AdapterCircuitBreakerManualOverride, type AdapterCircuitBreakerProvider, AdapterCircuitBreakerRegistry, type AdapterCircuitBreakerRegistryOptions, AdapterCircuitOpenError, type AdapterCircuitOutcome, type AdapterCircuitState, type AdapterExecutionContext, type AdapterExecutionResult, type AdapterExecutor, type AdapterImplementation, type AdapterOutcomeEvidence, type AdapterOutcomeKind, AdapterRegistry, type AdapterRetryPolicy, type ExecuteWithRetryOptions, InMemoryAdapterCircuitBreaker, type InMemoryAdapterCircuitBreakerOptions, MissingAdapterRegistrationError, type ResolvedAdapterRetryPolicy, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, classifyAdapterOutcome, classifyCircuitBreakerOutcome, executeWithAdapterRetry, getRetryDelayMs, isAdapterCircuitOpenError, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
@@ -1,3 +1,3 @@
1
- export { AdapterRegistry, MissingAdapterRegistrationError, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome } from '../chunk-FAG2RTPM.js';
1
+ export { AdapterCircuitBreakerRegistry, AdapterCircuitOpenError, AdapterRegistry, InMemoryAdapterCircuitBreaker, MissingAdapterRegistrationError, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, classifyAdapterOutcome, classifyCircuitBreakerOutcome, executeWithAdapterRetry, getRetryDelayMs, isAdapterCircuitOpenError, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome } from '../chunk-5FOCPRTR.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map