@camunda8/orchestration-cluster-api 10.0.0-alpha.4 → 10.0.0-alpha.40
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/CHANGELOG.md +303 -0
- package/README.md +400 -68
- package/dist/{index-CtFmBFXM.d.ts → CamundaClient-BsoVLG5C.d.ts} +20566 -11221
- package/dist/{index-CvA10E3U.d.cts → CamundaClient-DsXh8p3U.d.cts} +20566 -11221
- package/dist/{chunk-YMG6EGPW.js → chunk-3HNGJ4FZ.js} +12167 -7410
- package/dist/chunk-3HNGJ4FZ.js.map +1 -0
- package/dist/{fp → effect}/index.cjs +18656 -12464
- package/dist/effect/index.cjs.map +1 -0
- package/dist/effect/index.d.cts +302 -0
- package/dist/effect/index.d.ts +302 -0
- package/dist/effect/index.js +367 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/index.cjs +18690 -12454
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -6
- package/dist/index.d.ts +76 -6
- package/dist/index.js +316 -15
- package/dist/index.js.map +1 -1
- package/dist/threadWorkerEntry.cjs +9 -3
- package/dist/threadWorkerEntry.cjs.map +1 -1
- package/dist/threadWorkerEntry.js +9 -3
- package/dist/threadWorkerEntry.js.map +1 -1
- package/dist/zod.gen-2PU225MP.js +9475 -0
- package/dist/zod.gen-2PU225MP.js.map +1 -0
- package/package.json +44 -26
- package/dist/chunk-YMG6EGPW.js.map +0 -1
- package/dist/fp/index.cjs.map +0 -1
- package/dist/fp/index.d.cts +0 -4
- package/dist/fp/index.d.ts +0 -4
- package/dist/fp/index.js +0 -23
- package/dist/fp/index.js.map +0 -1
- package/dist/zod.gen-WZT74U4Q.js +0 -8387
- package/dist/zod.gen-WZT74U4Q.js.map +0 -1
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import * as effect_Cause from 'effect/Cause';
|
|
2
|
+
import * as effect_Types from 'effect/Types';
|
|
3
|
+
import { Context, Effect, Stream, Duration, Layer, Schedule, Cause, Scope } from 'effect';
|
|
4
|
+
import { S as SearchPaginateOptions, P as Paginator, a as PaginationMode, C as ConsistencyOptions, b as SearchResponse, c as CamundaClient, d as CamundaOptions, A as ActivatedJobResult } from '../CamundaClient-DsXh8p3U.cjs';
|
|
5
|
+
import 'zod';
|
|
6
|
+
import '../logger-D-p21VHo.cjs';
|
|
7
|
+
|
|
8
|
+
declare const CamundaValidationError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
9
|
+
readonly _tag: "CamundaValidationError";
|
|
10
|
+
} & Readonly<A>;
|
|
11
|
+
/** A request/response validation failure surfaced by the SDK. */
|
|
12
|
+
declare class CamundaValidationError extends CamundaValidationError_base<{
|
|
13
|
+
readonly side: 'request' | 'response';
|
|
14
|
+
readonly operationId?: string;
|
|
15
|
+
readonly summary: string;
|
|
16
|
+
readonly issues: string[];
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly cause?: unknown;
|
|
19
|
+
}> {
|
|
20
|
+
}
|
|
21
|
+
declare const EventualConsistencyTimeout_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
22
|
+
readonly _tag: "EventualConsistencyTimeout";
|
|
23
|
+
} & Readonly<A>;
|
|
24
|
+
/** An eventual-consistency poll that did not converge within its budget. */
|
|
25
|
+
declare class EventualConsistencyTimeout extends EventualConsistencyTimeout_base<{
|
|
26
|
+
readonly attempts?: number;
|
|
27
|
+
readonly elapsedMs?: number;
|
|
28
|
+
readonly message: string;
|
|
29
|
+
readonly cause?: unknown;
|
|
30
|
+
}> {
|
|
31
|
+
}
|
|
32
|
+
declare const HttpError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
33
|
+
readonly _tag: "HttpError";
|
|
34
|
+
} & Readonly<A>;
|
|
35
|
+
/** An HTTP-level failure (non-2xx / transport carrying a status). */
|
|
36
|
+
declare class HttpError extends HttpError_base<{
|
|
37
|
+
readonly status?: number;
|
|
38
|
+
readonly body?: unknown;
|
|
39
|
+
readonly message: string;
|
|
40
|
+
readonly cause?: unknown;
|
|
41
|
+
}> {
|
|
42
|
+
}
|
|
43
|
+
declare const CamundaGenericError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
44
|
+
readonly _tag: "CamundaGenericError";
|
|
45
|
+
} & Readonly<A>;
|
|
46
|
+
/** Any other thrown value that does not map to a more specific tag. */
|
|
47
|
+
declare class CamundaGenericError extends CamundaGenericError_base<{
|
|
48
|
+
readonly message: string;
|
|
49
|
+
readonly cause?: unknown;
|
|
50
|
+
}> {
|
|
51
|
+
}
|
|
52
|
+
/** The typed error channel for every Effect the client produces. */
|
|
53
|
+
type DomainError = CamundaValidationError | EventualConsistencyTimeout | HttpError | CamundaGenericError;
|
|
54
|
+
/** The tag literals of the {@link DomainError} union. */
|
|
55
|
+
type DomainErrorTag = DomainError['_tag'];
|
|
56
|
+
/** Options for the Effect client's `.paginate`. */
|
|
57
|
+
interface EffectPaginateOptions<TData = unknown> {
|
|
58
|
+
/**
|
|
59
|
+
* Safety cap on pages fetched (default: unbounded). A non-positive value fetches
|
|
60
|
+
* no pages at all — the cap is enforced *before* the first request.
|
|
61
|
+
*/
|
|
62
|
+
readonly maxPages?: number;
|
|
63
|
+
/** How to advance. `auto` prefers a cursor, falls back to offset. */
|
|
64
|
+
readonly mode?: PaginationMode;
|
|
65
|
+
/**
|
|
66
|
+
* Eventual-consistency controls forwarded to the underlying search call. Defaults
|
|
67
|
+
* to `{ waitUpToMs: 0 }`. Only the **first** page honours this window: once paging
|
|
68
|
+
* is under way an empty page is end-of-results, not a not-yet-consistent read.
|
|
69
|
+
*/
|
|
70
|
+
readonly consistency?: ConsistencyOptions<TData>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The Effect-flavoured counterpart of a {@link Paginator}: the same three views
|
|
74
|
+
* (`pages` / `items` / `toArray`) over a multi-page search, as `Stream`s and an
|
|
75
|
+
* `Effect` rather than async iterables and a `Promise`.
|
|
76
|
+
*
|
|
77
|
+
* Every view is lazy — a page is fetched only when pulled — and interruptible:
|
|
78
|
+
* interrupting the fiber cancels the in-flight page request rather than leaving it
|
|
79
|
+
* to settle unobserved.
|
|
80
|
+
*/
|
|
81
|
+
interface EffectPaginator<TItem> {
|
|
82
|
+
/** A `Stream` of whole pages, each fetched lazily as it is pulled. */
|
|
83
|
+
pages(): Stream.Stream<SearchResponse<TItem>, DomainError>;
|
|
84
|
+
/** A `Stream` of individual items, flattened across all pages. */
|
|
85
|
+
items(): Stream.Stream<TItem, DomainError>;
|
|
86
|
+
/** Eagerly drains every item into an array. Bounded result sets only. */
|
|
87
|
+
toArray(): Effect.Effect<TItem[], DomainError>;
|
|
88
|
+
}
|
|
89
|
+
/** Keys of `C` whose values are callable. */
|
|
90
|
+
type FnKeys<C> = {
|
|
91
|
+
[K in keyof C]: C[K] extends (...a: any) => any ? K : never;
|
|
92
|
+
}[keyof C];
|
|
93
|
+
/**
|
|
94
|
+
* Helpers attached to a client *method* (not to the client), re-expressed in Effect
|
|
95
|
+
* terms. Resolves to `unknown` — the identity of `&` — for a method that carries none.
|
|
96
|
+
*/
|
|
97
|
+
type EffectifyMethodHelpers<F> = F extends {
|
|
98
|
+
paginate(body: infer B, opts?: SearchPaginateOptions<infer D>): Paginator<infer I>;
|
|
99
|
+
} ? {
|
|
100
|
+
paginate(body: B, opts?: EffectPaginateOptions<D>): EffectPaginator<I>;
|
|
101
|
+
} : unknown;
|
|
102
|
+
/** Maps a single method to its Effect-returning form, keeping its attached helpers. */
|
|
103
|
+
type EffectifyMethod<F> = F extends (...a: infer A) => infer R ? ((...a: A) => Effect.Effect<Awaited<R>, DomainError, never>) & EffectifyMethodHelpers<F> : never;
|
|
104
|
+
/** Maps every method of `C` to an Effect-returning method, preserving non-fn members. */
|
|
105
|
+
type Effectify<C> = {
|
|
106
|
+
[K in FnKeys<C>]: EffectifyMethod<C[K]>;
|
|
107
|
+
} & {
|
|
108
|
+
inner: C;
|
|
109
|
+
} & {
|
|
110
|
+
[K in Exclude<keyof C, FnKeys<C>>]: C[K];
|
|
111
|
+
};
|
|
112
|
+
/** The Effect-flavoured Camunda client. Every operation returns an `Effect`. */
|
|
113
|
+
type CamundaEffectClient = Effectify<CamundaClient>;
|
|
114
|
+
/**
|
|
115
|
+
* Create an Effect-flavoured Camunda client.
|
|
116
|
+
*
|
|
117
|
+
* Every `CamundaClient` method becomes `(...args) => Effect.Effect<Awaited<R>,
|
|
118
|
+
* DomainError, never>`. Failures are narrowed into the tagged {@link DomainError}
|
|
119
|
+
* union so callers use `Effect.catchTag`/`catchTags`. The underlying throwing
|
|
120
|
+
* client is reachable via the `.inner` escape hatch.
|
|
121
|
+
*
|
|
122
|
+
* @description Camunda Effect Client. See the README and [this test](https://github.com/camunda/orchestration-cluster-api-js/blob/main/tests-integration/effect.test.ts) for example usage.
|
|
123
|
+
*/
|
|
124
|
+
declare function createCamundaEffectClient(options?: CamundaOptions): CamundaEffectClient;
|
|
125
|
+
/**
|
|
126
|
+
* Retry an effect with exponential backoff (+ jitter), capped attempts, and an
|
|
127
|
+
* optional predicate over the error.
|
|
128
|
+
*/
|
|
129
|
+
declare function retryWithBackoff<A, E, R>(effect: Effect.Effect<A, E, R>, opts: {
|
|
130
|
+
max: number;
|
|
131
|
+
baseDelay?: Duration.Input;
|
|
132
|
+
while?: (e: E) => boolean;
|
|
133
|
+
}): Effect.Effect<A, E, R>;
|
|
134
|
+
/**
|
|
135
|
+
* Fail an effect with a real interruption if it does not settle within `duration`
|
|
136
|
+
* (true interruption, not a best-effort `Promise.race`).
|
|
137
|
+
*/
|
|
138
|
+
declare function withTimeout<A, E, R>(effect: Effect.Effect<A, E, R>, duration: Duration.Input, onTimeout?: () => E | EventualConsistencyTimeout): Effect.Effect<A, E | EventualConsistencyTimeout, R>;
|
|
139
|
+
/**
|
|
140
|
+
* Poll `effect` on the Effect `Clock` until `predicate` holds, timing out to
|
|
141
|
+
* {@link EventualConsistencyTimeout} once `waitUpTo` elapses. Because it uses the
|
|
142
|
+
* Effect `Clock` (not `Date.now`/`setTimeout`), `TestClock.adjust` advances it
|
|
143
|
+
* deterministically in tests — no real-clock burn.
|
|
144
|
+
*/
|
|
145
|
+
declare function eventually<A, E, R>(effect: Effect.Effect<A, E, R>, predicate: (a: A) => boolean, opts: {
|
|
146
|
+
waitUpTo: Duration.Input;
|
|
147
|
+
interval?: Duration.Input;
|
|
148
|
+
}): Effect.Effect<A, E | EventualConsistencyTimeout, R>;
|
|
149
|
+
declare const CamundaEffect_base: Context.ServiceClass<CamundaEffect, "CamundaEffect", CamundaEffectClient>;
|
|
150
|
+
/**
|
|
151
|
+
* `Context` service key for the Effect Camunda client. Compose worker/orchestration
|
|
152
|
+
* code against this tag and provide {@link layer} (or a test double) via `Layer`.
|
|
153
|
+
*/
|
|
154
|
+
declare class CamundaEffect extends CamundaEffect_base {
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* A `Layer` that constructs a {@link CamundaEffectClient} and provides it as the
|
|
158
|
+
* {@link CamundaEffect} service. Swap in a test double by providing a different
|
|
159
|
+
* `Layer` for the same tag.
|
|
160
|
+
*/
|
|
161
|
+
declare function layer(options?: CamundaOptions): Layer.Layer<CamundaEffect>;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* A single activated job handed to an Effect handler. This is the raw activation
|
|
165
|
+
* payload (variables + custom headers + lifecycle keys); acknowledgement is driven
|
|
166
|
+
* by the value/error the handler's `Effect` produces, not by imperative methods.
|
|
167
|
+
*/
|
|
168
|
+
type Job = ActivatedJobResult;
|
|
169
|
+
/** Variables to complete a job with. `void`/`undefined` completes with no variables. */
|
|
170
|
+
type CompleteVars = {
|
|
171
|
+
readonly [key: string]: unknown;
|
|
172
|
+
} | void | undefined;
|
|
173
|
+
declare const RetryableJobError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
174
|
+
readonly _tag: "RetryableJobError";
|
|
175
|
+
} & Readonly<A>;
|
|
176
|
+
/**
|
|
177
|
+
* A retryable job failure: the handler could not complete the job now, but a later
|
|
178
|
+
* activation might succeed. Mapped to `failJob` with `retries - 1` and an optional
|
|
179
|
+
* server-side re-activation backoff.
|
|
180
|
+
*/
|
|
181
|
+
declare class RetryableJobError extends RetryableJobError_base<{
|
|
182
|
+
readonly message: string;
|
|
183
|
+
/** Server-side delay before the job becomes re-activatable (`failJob` `retryBackOff`). */
|
|
184
|
+
readonly retryBackoff?: Duration.Input;
|
|
185
|
+
/** Optional variables to attach to the job on failure. */
|
|
186
|
+
readonly variables?: {
|
|
187
|
+
readonly [key: string]: unknown;
|
|
188
|
+
};
|
|
189
|
+
readonly cause?: unknown;
|
|
190
|
+
}> {
|
|
191
|
+
}
|
|
192
|
+
declare const TerminalJobError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
193
|
+
readonly _tag: "TerminalJobError";
|
|
194
|
+
} & Readonly<A>;
|
|
195
|
+
/**
|
|
196
|
+
* A terminal job failure: retrying will not help. Mapped to `throwJobError`, which
|
|
197
|
+
* is caught by a matching BPMN error boundary event or — if uncaught — raises an
|
|
198
|
+
* incident.
|
|
199
|
+
*/
|
|
200
|
+
declare class TerminalJobError extends TerminalJobError_base<{
|
|
201
|
+
/** The BPMN error code matched against an error catch event. */
|
|
202
|
+
readonly code: string;
|
|
203
|
+
readonly message: string;
|
|
204
|
+
/** Optional variables to instantiate at the error catch event's scope. */
|
|
205
|
+
readonly variables?: {
|
|
206
|
+
readonly [key: string]: unknown;
|
|
207
|
+
};
|
|
208
|
+
readonly cause?: unknown;
|
|
209
|
+
}> {
|
|
210
|
+
}
|
|
211
|
+
/** The typed error channel a job handler may fail with. */
|
|
212
|
+
type JobError = RetryableJobError | TerminalJobError;
|
|
213
|
+
/** A job handler: consumes a {@link Job}, produces completion variables or a {@link JobError}. */
|
|
214
|
+
type JobHandler<A extends CompleteVars, R> = (job: Job) => Effect.Effect<A, JobError, R>;
|
|
215
|
+
interface ActivateJobsStreamOptions<R = never> {
|
|
216
|
+
/** Worker name recorded on the activation request. Defaults to `effect-worker-<type>-<n>`, where `<n>` is an incrementing per-process counter. */
|
|
217
|
+
readonly workerName?: string;
|
|
218
|
+
/** Max jobs to activate per poll (the activation batch size). Default `10`. */
|
|
219
|
+
readonly maxJobsToActivate?: number;
|
|
220
|
+
/**
|
|
221
|
+
* Delay between polls that returned **no** jobs, on the Effect `Clock` (so it is
|
|
222
|
+
* virtual under `TestClock`). A poll that returns jobs schedules the next poll
|
|
223
|
+
* immediately. Default `1 second`.
|
|
224
|
+
*/
|
|
225
|
+
readonly pollInterval?: Duration.Input;
|
|
226
|
+
/** Per-job activation lock timeout (server-side). Default `60 seconds`. */
|
|
227
|
+
readonly jobTimeout?: Duration.Input;
|
|
228
|
+
/**
|
|
229
|
+
* Long-poll request timeout. `0` (the default) lets the broker hold the request
|
|
230
|
+
* for its configured default; a negative value returns immediately when idle.
|
|
231
|
+
*/
|
|
232
|
+
readonly requestTimeout?: Duration.Input | number;
|
|
233
|
+
/** Restrict activation to these variable names. */
|
|
234
|
+
readonly fetchVariables?: readonly string[];
|
|
235
|
+
/**
|
|
236
|
+
* `Schedule` used to back off and retry a **failed activation request** (transport
|
|
237
|
+
* outage, broker restart, transient server error). Runs on the Effect `Clock`.
|
|
238
|
+
* When omitted, an activation failure fails the stream.
|
|
239
|
+
*/
|
|
240
|
+
readonly activationRetrySchedule?: Schedule.Schedule<unknown, DomainError, never, R>;
|
|
241
|
+
}
|
|
242
|
+
interface EffectWorkerConfig<A extends CompleteVars, R = never> extends ActivateJobsStreamOptions<R> {
|
|
243
|
+
/** The job type to activate. */
|
|
244
|
+
readonly type: string;
|
|
245
|
+
/** The Effect job handler. */
|
|
246
|
+
readonly handler: JobHandler<A, R>;
|
|
247
|
+
/**
|
|
248
|
+
* Max jobs processed concurrently (handler parallelism / backpressure). The
|
|
249
|
+
* activation loop will not pull faster than handlers drain, and the activation
|
|
250
|
+
* batch is capped to this value (when it is a finite number) so the worker never
|
|
251
|
+
* leases more jobs than it can process at once. Default: the value of
|
|
252
|
+
* {@link ActivateJobsStreamOptions.maxJobsToActivate} (or `10`).
|
|
253
|
+
*/
|
|
254
|
+
readonly concurrency?: number | 'unbounded';
|
|
255
|
+
/**
|
|
256
|
+
* `Schedule` used to retry the **handler** in-process on a {@link RetryableJobError}
|
|
257
|
+
* before the job is failed back to the broker. Runs on the Effect `Clock`
|
|
258
|
+
* (virtual under `TestClock`). A {@link TerminalJobError} is never retried.
|
|
259
|
+
*/
|
|
260
|
+
readonly handlerRetrySchedule?: Schedule.Schedule<unknown, JobError, never, R>;
|
|
261
|
+
}
|
|
262
|
+
/** A handle to a running Effect worker. */
|
|
263
|
+
interface CamundaEffectWorkerHandle {
|
|
264
|
+
/** The job type this worker activates. */
|
|
265
|
+
readonly type: string;
|
|
266
|
+
/** Completes when the worker loop ends (only on a fatal, non-retryable activation error). */
|
|
267
|
+
readonly join: Effect.Effect<void, DomainError>;
|
|
268
|
+
/** Interrupt the worker (also happens automatically when the owning scope closes). */
|
|
269
|
+
readonly interrupt: Effect.Effect<void>;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* A `Stream` of activated jobs of `type`. Repeatedly calls `activateJobs` (through the
|
|
273
|
+
* `/effect` client `Layer`, i.e. the same backpressure-aware runtime the Promise worker
|
|
274
|
+
* uses) and emits each activated job. The between-empty-polls delay and the optional
|
|
275
|
+
* activation-retry `Schedule` both run on the Effect `Clock`, so `TestClock.adjust`
|
|
276
|
+
* advances them deterministically in tests.
|
|
277
|
+
*/
|
|
278
|
+
declare function activateJobsStream<R = never>(type: string, options?: ActivateJobsStreamOptions<R>): Stream.Stream<Job, DomainError, CamundaEffect | R>;
|
|
279
|
+
/**
|
|
280
|
+
* The worker loop: drains {@link activateJobsStream}, running the handler for each job
|
|
281
|
+
* with bounded `concurrency` (the backpressure knob), and acknowledging via
|
|
282
|
+
* `completeJob`/`failJob`/`throwJobError` per the handler's typed outcome.
|
|
283
|
+
*/
|
|
284
|
+
declare function runWorkerLoop<A extends CompleteVars, R = never>(config: EffectWorkerConfig<A, R>): Effect.Effect<void, DomainError, CamundaEffect | R>;
|
|
285
|
+
/**
|
|
286
|
+
* Create and start an Effect job worker, forked into the current `Scope`. The worker
|
|
287
|
+
* runs until its scope closes (or {@link CamundaEffectWorkerHandle.interrupt} is run),
|
|
288
|
+
* at which point it is interrupted and any in-flight job's lease is released.
|
|
289
|
+
*
|
|
290
|
+
* Depends on the {@link CamundaEffect} service — provide the `/effect` client `layer`.
|
|
291
|
+
*
|
|
292
|
+
* @description Camunda Effect Worker. See the README and [this test](https://github.com/camunda/orchestration-cluster-api-js/blob/main/tests-integration/effect-worker.test.ts) for example usage.
|
|
293
|
+
*/
|
|
294
|
+
declare function createCamundaEffectWorker<A extends CompleteVars, R = never>(config: EffectWorkerConfig<A, R>): Effect.Effect<CamundaEffectWorkerHandle, never, Scope.Scope | CamundaEffect | R>;
|
|
295
|
+
/**
|
|
296
|
+
* A `Layer` that runs a Camunda Effect worker for the layer's lifetime. Compose it
|
|
297
|
+
* with the `/effect` client `layer` (which provides its {@link CamundaEffect}
|
|
298
|
+
* dependency) plus a `Layer` for the handler's own requirements `R`.
|
|
299
|
+
*/
|
|
300
|
+
declare function workerLayer<A extends CompleteVars, R = never>(config: EffectWorkerConfig<A, R>): Layer.Layer<never, never, CamundaEffect | R>;
|
|
301
|
+
|
|
302
|
+
export { type ActivateJobsStreamOptions, CamundaEffect, type CamundaEffectClient, type CamundaEffectWorkerHandle, CamundaGenericError, CamundaValidationError, type CompleteVars, type DomainError, type DomainErrorTag, type EffectPaginateOptions, type EffectPaginator, type EffectWorkerConfig, type Effectify, EventualConsistencyTimeout, type FnKeys, HttpError, type Job, type JobError, type JobHandler, RetryableJobError, TerminalJobError, activateJobsStream, createCamundaEffectClient, createCamundaEffectWorker, eventually, layer, retryWithBackoff, runWorkerLoop, withTimeout, workerLayer };
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import * as effect_Cause from 'effect/Cause';
|
|
2
|
+
import * as effect_Types from 'effect/Types';
|
|
3
|
+
import { Context, Effect, Stream, Duration, Layer, Schedule, Cause, Scope } from 'effect';
|
|
4
|
+
import { S as SearchPaginateOptions, P as Paginator, a as PaginationMode, C as ConsistencyOptions, b as SearchResponse, c as CamundaClient, d as CamundaOptions, A as ActivatedJobResult } from '../CamundaClient-BsoVLG5C.js';
|
|
5
|
+
import 'zod';
|
|
6
|
+
import '../logger-D-p21VHo.js';
|
|
7
|
+
|
|
8
|
+
declare const CamundaValidationError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
9
|
+
readonly _tag: "CamundaValidationError";
|
|
10
|
+
} & Readonly<A>;
|
|
11
|
+
/** A request/response validation failure surfaced by the SDK. */
|
|
12
|
+
declare class CamundaValidationError extends CamundaValidationError_base<{
|
|
13
|
+
readonly side: 'request' | 'response';
|
|
14
|
+
readonly operationId?: string;
|
|
15
|
+
readonly summary: string;
|
|
16
|
+
readonly issues: string[];
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly cause?: unknown;
|
|
19
|
+
}> {
|
|
20
|
+
}
|
|
21
|
+
declare const EventualConsistencyTimeout_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
22
|
+
readonly _tag: "EventualConsistencyTimeout";
|
|
23
|
+
} & Readonly<A>;
|
|
24
|
+
/** An eventual-consistency poll that did not converge within its budget. */
|
|
25
|
+
declare class EventualConsistencyTimeout extends EventualConsistencyTimeout_base<{
|
|
26
|
+
readonly attempts?: number;
|
|
27
|
+
readonly elapsedMs?: number;
|
|
28
|
+
readonly message: string;
|
|
29
|
+
readonly cause?: unknown;
|
|
30
|
+
}> {
|
|
31
|
+
}
|
|
32
|
+
declare const HttpError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
33
|
+
readonly _tag: "HttpError";
|
|
34
|
+
} & Readonly<A>;
|
|
35
|
+
/** An HTTP-level failure (non-2xx / transport carrying a status). */
|
|
36
|
+
declare class HttpError extends HttpError_base<{
|
|
37
|
+
readonly status?: number;
|
|
38
|
+
readonly body?: unknown;
|
|
39
|
+
readonly message: string;
|
|
40
|
+
readonly cause?: unknown;
|
|
41
|
+
}> {
|
|
42
|
+
}
|
|
43
|
+
declare const CamundaGenericError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => effect_Cause.YieldableError & {
|
|
44
|
+
readonly _tag: "CamundaGenericError";
|
|
45
|
+
} & Readonly<A>;
|
|
46
|
+
/** Any other thrown value that does not map to a more specific tag. */
|
|
47
|
+
declare class CamundaGenericError extends CamundaGenericError_base<{
|
|
48
|
+
readonly message: string;
|
|
49
|
+
readonly cause?: unknown;
|
|
50
|
+
}> {
|
|
51
|
+
}
|
|
52
|
+
/** The typed error channel for every Effect the client produces. */
|
|
53
|
+
type DomainError = CamundaValidationError | EventualConsistencyTimeout | HttpError | CamundaGenericError;
|
|
54
|
+
/** The tag literals of the {@link DomainError} union. */
|
|
55
|
+
type DomainErrorTag = DomainError['_tag'];
|
|
56
|
+
/** Options for the Effect client's `.paginate`. */
|
|
57
|
+
interface EffectPaginateOptions<TData = unknown> {
|
|
58
|
+
/**
|
|
59
|
+
* Safety cap on pages fetched (default: unbounded). A non-positive value fetches
|
|
60
|
+
* no pages at all — the cap is enforced *before* the first request.
|
|
61
|
+
*/
|
|
62
|
+
readonly maxPages?: number;
|
|
63
|
+
/** How to advance. `auto` prefers a cursor, falls back to offset. */
|
|
64
|
+
readonly mode?: PaginationMode;
|
|
65
|
+
/**
|
|
66
|
+
* Eventual-consistency controls forwarded to the underlying search call. Defaults
|
|
67
|
+
* to `{ waitUpToMs: 0 }`. Only the **first** page honours this window: once paging
|
|
68
|
+
* is under way an empty page is end-of-results, not a not-yet-consistent read.
|
|
69
|
+
*/
|
|
70
|
+
readonly consistency?: ConsistencyOptions<TData>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The Effect-flavoured counterpart of a {@link Paginator}: the same three views
|
|
74
|
+
* (`pages` / `items` / `toArray`) over a multi-page search, as `Stream`s and an
|
|
75
|
+
* `Effect` rather than async iterables and a `Promise`.
|
|
76
|
+
*
|
|
77
|
+
* Every view is lazy — a page is fetched only when pulled — and interruptible:
|
|
78
|
+
* interrupting the fiber cancels the in-flight page request rather than leaving it
|
|
79
|
+
* to settle unobserved.
|
|
80
|
+
*/
|
|
81
|
+
interface EffectPaginator<TItem> {
|
|
82
|
+
/** A `Stream` of whole pages, each fetched lazily as it is pulled. */
|
|
83
|
+
pages(): Stream.Stream<SearchResponse<TItem>, DomainError>;
|
|
84
|
+
/** A `Stream` of individual items, flattened across all pages. */
|
|
85
|
+
items(): Stream.Stream<TItem, DomainError>;
|
|
86
|
+
/** Eagerly drains every item into an array. Bounded result sets only. */
|
|
87
|
+
toArray(): Effect.Effect<TItem[], DomainError>;
|
|
88
|
+
}
|
|
89
|
+
/** Keys of `C` whose values are callable. */
|
|
90
|
+
type FnKeys<C> = {
|
|
91
|
+
[K in keyof C]: C[K] extends (...a: any) => any ? K : never;
|
|
92
|
+
}[keyof C];
|
|
93
|
+
/**
|
|
94
|
+
* Helpers attached to a client *method* (not to the client), re-expressed in Effect
|
|
95
|
+
* terms. Resolves to `unknown` — the identity of `&` — for a method that carries none.
|
|
96
|
+
*/
|
|
97
|
+
type EffectifyMethodHelpers<F> = F extends {
|
|
98
|
+
paginate(body: infer B, opts?: SearchPaginateOptions<infer D>): Paginator<infer I>;
|
|
99
|
+
} ? {
|
|
100
|
+
paginate(body: B, opts?: EffectPaginateOptions<D>): EffectPaginator<I>;
|
|
101
|
+
} : unknown;
|
|
102
|
+
/** Maps a single method to its Effect-returning form, keeping its attached helpers. */
|
|
103
|
+
type EffectifyMethod<F> = F extends (...a: infer A) => infer R ? ((...a: A) => Effect.Effect<Awaited<R>, DomainError, never>) & EffectifyMethodHelpers<F> : never;
|
|
104
|
+
/** Maps every method of `C` to an Effect-returning method, preserving non-fn members. */
|
|
105
|
+
type Effectify<C> = {
|
|
106
|
+
[K in FnKeys<C>]: EffectifyMethod<C[K]>;
|
|
107
|
+
} & {
|
|
108
|
+
inner: C;
|
|
109
|
+
} & {
|
|
110
|
+
[K in Exclude<keyof C, FnKeys<C>>]: C[K];
|
|
111
|
+
};
|
|
112
|
+
/** The Effect-flavoured Camunda client. Every operation returns an `Effect`. */
|
|
113
|
+
type CamundaEffectClient = Effectify<CamundaClient>;
|
|
114
|
+
/**
|
|
115
|
+
* Create an Effect-flavoured Camunda client.
|
|
116
|
+
*
|
|
117
|
+
* Every `CamundaClient` method becomes `(...args) => Effect.Effect<Awaited<R>,
|
|
118
|
+
* DomainError, never>`. Failures are narrowed into the tagged {@link DomainError}
|
|
119
|
+
* union so callers use `Effect.catchTag`/`catchTags`. The underlying throwing
|
|
120
|
+
* client is reachable via the `.inner` escape hatch.
|
|
121
|
+
*
|
|
122
|
+
* @description Camunda Effect Client. See the README and [this test](https://github.com/camunda/orchestration-cluster-api-js/blob/main/tests-integration/effect.test.ts) for example usage.
|
|
123
|
+
*/
|
|
124
|
+
declare function createCamundaEffectClient(options?: CamundaOptions): CamundaEffectClient;
|
|
125
|
+
/**
|
|
126
|
+
* Retry an effect with exponential backoff (+ jitter), capped attempts, and an
|
|
127
|
+
* optional predicate over the error.
|
|
128
|
+
*/
|
|
129
|
+
declare function retryWithBackoff<A, E, R>(effect: Effect.Effect<A, E, R>, opts: {
|
|
130
|
+
max: number;
|
|
131
|
+
baseDelay?: Duration.Input;
|
|
132
|
+
while?: (e: E) => boolean;
|
|
133
|
+
}): Effect.Effect<A, E, R>;
|
|
134
|
+
/**
|
|
135
|
+
* Fail an effect with a real interruption if it does not settle within `duration`
|
|
136
|
+
* (true interruption, not a best-effort `Promise.race`).
|
|
137
|
+
*/
|
|
138
|
+
declare function withTimeout<A, E, R>(effect: Effect.Effect<A, E, R>, duration: Duration.Input, onTimeout?: () => E | EventualConsistencyTimeout): Effect.Effect<A, E | EventualConsistencyTimeout, R>;
|
|
139
|
+
/**
|
|
140
|
+
* Poll `effect` on the Effect `Clock` until `predicate` holds, timing out to
|
|
141
|
+
* {@link EventualConsistencyTimeout} once `waitUpTo` elapses. Because it uses the
|
|
142
|
+
* Effect `Clock` (not `Date.now`/`setTimeout`), `TestClock.adjust` advances it
|
|
143
|
+
* deterministically in tests — no real-clock burn.
|
|
144
|
+
*/
|
|
145
|
+
declare function eventually<A, E, R>(effect: Effect.Effect<A, E, R>, predicate: (a: A) => boolean, opts: {
|
|
146
|
+
waitUpTo: Duration.Input;
|
|
147
|
+
interval?: Duration.Input;
|
|
148
|
+
}): Effect.Effect<A, E | EventualConsistencyTimeout, R>;
|
|
149
|
+
declare const CamundaEffect_base: Context.ServiceClass<CamundaEffect, "CamundaEffect", CamundaEffectClient>;
|
|
150
|
+
/**
|
|
151
|
+
* `Context` service key for the Effect Camunda client. Compose worker/orchestration
|
|
152
|
+
* code against this tag and provide {@link layer} (or a test double) via `Layer`.
|
|
153
|
+
*/
|
|
154
|
+
declare class CamundaEffect extends CamundaEffect_base {
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* A `Layer` that constructs a {@link CamundaEffectClient} and provides it as the
|
|
158
|
+
* {@link CamundaEffect} service. Swap in a test double by providing a different
|
|
159
|
+
* `Layer` for the same tag.
|
|
160
|
+
*/
|
|
161
|
+
declare function layer(options?: CamundaOptions): Layer.Layer<CamundaEffect>;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* A single activated job handed to an Effect handler. This is the raw activation
|
|
165
|
+
* payload (variables + custom headers + lifecycle keys); acknowledgement is driven
|
|
166
|
+
* by the value/error the handler's `Effect` produces, not by imperative methods.
|
|
167
|
+
*/
|
|
168
|
+
type Job = ActivatedJobResult;
|
|
169
|
+
/** Variables to complete a job with. `void`/`undefined` completes with no variables. */
|
|
170
|
+
type CompleteVars = {
|
|
171
|
+
readonly [key: string]: unknown;
|
|
172
|
+
} | void | undefined;
|
|
173
|
+
declare const RetryableJobError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
174
|
+
readonly _tag: "RetryableJobError";
|
|
175
|
+
} & Readonly<A>;
|
|
176
|
+
/**
|
|
177
|
+
* A retryable job failure: the handler could not complete the job now, but a later
|
|
178
|
+
* activation might succeed. Mapped to `failJob` with `retries - 1` and an optional
|
|
179
|
+
* server-side re-activation backoff.
|
|
180
|
+
*/
|
|
181
|
+
declare class RetryableJobError extends RetryableJobError_base<{
|
|
182
|
+
readonly message: string;
|
|
183
|
+
/** Server-side delay before the job becomes re-activatable (`failJob` `retryBackOff`). */
|
|
184
|
+
readonly retryBackoff?: Duration.Input;
|
|
185
|
+
/** Optional variables to attach to the job on failure. */
|
|
186
|
+
readonly variables?: {
|
|
187
|
+
readonly [key: string]: unknown;
|
|
188
|
+
};
|
|
189
|
+
readonly cause?: unknown;
|
|
190
|
+
}> {
|
|
191
|
+
}
|
|
192
|
+
declare const TerminalJobError_base: new <A extends Record<string, any> = {}>(args: effect_Types.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
193
|
+
readonly _tag: "TerminalJobError";
|
|
194
|
+
} & Readonly<A>;
|
|
195
|
+
/**
|
|
196
|
+
* A terminal job failure: retrying will not help. Mapped to `throwJobError`, which
|
|
197
|
+
* is caught by a matching BPMN error boundary event or — if uncaught — raises an
|
|
198
|
+
* incident.
|
|
199
|
+
*/
|
|
200
|
+
declare class TerminalJobError extends TerminalJobError_base<{
|
|
201
|
+
/** The BPMN error code matched against an error catch event. */
|
|
202
|
+
readonly code: string;
|
|
203
|
+
readonly message: string;
|
|
204
|
+
/** Optional variables to instantiate at the error catch event's scope. */
|
|
205
|
+
readonly variables?: {
|
|
206
|
+
readonly [key: string]: unknown;
|
|
207
|
+
};
|
|
208
|
+
readonly cause?: unknown;
|
|
209
|
+
}> {
|
|
210
|
+
}
|
|
211
|
+
/** The typed error channel a job handler may fail with. */
|
|
212
|
+
type JobError = RetryableJobError | TerminalJobError;
|
|
213
|
+
/** A job handler: consumes a {@link Job}, produces completion variables or a {@link JobError}. */
|
|
214
|
+
type JobHandler<A extends CompleteVars, R> = (job: Job) => Effect.Effect<A, JobError, R>;
|
|
215
|
+
interface ActivateJobsStreamOptions<R = never> {
|
|
216
|
+
/** Worker name recorded on the activation request. Defaults to `effect-worker-<type>-<n>`, where `<n>` is an incrementing per-process counter. */
|
|
217
|
+
readonly workerName?: string;
|
|
218
|
+
/** Max jobs to activate per poll (the activation batch size). Default `10`. */
|
|
219
|
+
readonly maxJobsToActivate?: number;
|
|
220
|
+
/**
|
|
221
|
+
* Delay between polls that returned **no** jobs, on the Effect `Clock` (so it is
|
|
222
|
+
* virtual under `TestClock`). A poll that returns jobs schedules the next poll
|
|
223
|
+
* immediately. Default `1 second`.
|
|
224
|
+
*/
|
|
225
|
+
readonly pollInterval?: Duration.Input;
|
|
226
|
+
/** Per-job activation lock timeout (server-side). Default `60 seconds`. */
|
|
227
|
+
readonly jobTimeout?: Duration.Input;
|
|
228
|
+
/**
|
|
229
|
+
* Long-poll request timeout. `0` (the default) lets the broker hold the request
|
|
230
|
+
* for its configured default; a negative value returns immediately when idle.
|
|
231
|
+
*/
|
|
232
|
+
readonly requestTimeout?: Duration.Input | number;
|
|
233
|
+
/** Restrict activation to these variable names. */
|
|
234
|
+
readonly fetchVariables?: readonly string[];
|
|
235
|
+
/**
|
|
236
|
+
* `Schedule` used to back off and retry a **failed activation request** (transport
|
|
237
|
+
* outage, broker restart, transient server error). Runs on the Effect `Clock`.
|
|
238
|
+
* When omitted, an activation failure fails the stream.
|
|
239
|
+
*/
|
|
240
|
+
readonly activationRetrySchedule?: Schedule.Schedule<unknown, DomainError, never, R>;
|
|
241
|
+
}
|
|
242
|
+
interface EffectWorkerConfig<A extends CompleteVars, R = never> extends ActivateJobsStreamOptions<R> {
|
|
243
|
+
/** The job type to activate. */
|
|
244
|
+
readonly type: string;
|
|
245
|
+
/** The Effect job handler. */
|
|
246
|
+
readonly handler: JobHandler<A, R>;
|
|
247
|
+
/**
|
|
248
|
+
* Max jobs processed concurrently (handler parallelism / backpressure). The
|
|
249
|
+
* activation loop will not pull faster than handlers drain, and the activation
|
|
250
|
+
* batch is capped to this value (when it is a finite number) so the worker never
|
|
251
|
+
* leases more jobs than it can process at once. Default: the value of
|
|
252
|
+
* {@link ActivateJobsStreamOptions.maxJobsToActivate} (or `10`).
|
|
253
|
+
*/
|
|
254
|
+
readonly concurrency?: number | 'unbounded';
|
|
255
|
+
/**
|
|
256
|
+
* `Schedule` used to retry the **handler** in-process on a {@link RetryableJobError}
|
|
257
|
+
* before the job is failed back to the broker. Runs on the Effect `Clock`
|
|
258
|
+
* (virtual under `TestClock`). A {@link TerminalJobError} is never retried.
|
|
259
|
+
*/
|
|
260
|
+
readonly handlerRetrySchedule?: Schedule.Schedule<unknown, JobError, never, R>;
|
|
261
|
+
}
|
|
262
|
+
/** A handle to a running Effect worker. */
|
|
263
|
+
interface CamundaEffectWorkerHandle {
|
|
264
|
+
/** The job type this worker activates. */
|
|
265
|
+
readonly type: string;
|
|
266
|
+
/** Completes when the worker loop ends (only on a fatal, non-retryable activation error). */
|
|
267
|
+
readonly join: Effect.Effect<void, DomainError>;
|
|
268
|
+
/** Interrupt the worker (also happens automatically when the owning scope closes). */
|
|
269
|
+
readonly interrupt: Effect.Effect<void>;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* A `Stream` of activated jobs of `type`. Repeatedly calls `activateJobs` (through the
|
|
273
|
+
* `/effect` client `Layer`, i.e. the same backpressure-aware runtime the Promise worker
|
|
274
|
+
* uses) and emits each activated job. The between-empty-polls delay and the optional
|
|
275
|
+
* activation-retry `Schedule` both run on the Effect `Clock`, so `TestClock.adjust`
|
|
276
|
+
* advances them deterministically in tests.
|
|
277
|
+
*/
|
|
278
|
+
declare function activateJobsStream<R = never>(type: string, options?: ActivateJobsStreamOptions<R>): Stream.Stream<Job, DomainError, CamundaEffect | R>;
|
|
279
|
+
/**
|
|
280
|
+
* The worker loop: drains {@link activateJobsStream}, running the handler for each job
|
|
281
|
+
* with bounded `concurrency` (the backpressure knob), and acknowledging via
|
|
282
|
+
* `completeJob`/`failJob`/`throwJobError` per the handler's typed outcome.
|
|
283
|
+
*/
|
|
284
|
+
declare function runWorkerLoop<A extends CompleteVars, R = never>(config: EffectWorkerConfig<A, R>): Effect.Effect<void, DomainError, CamundaEffect | R>;
|
|
285
|
+
/**
|
|
286
|
+
* Create and start an Effect job worker, forked into the current `Scope`. The worker
|
|
287
|
+
* runs until its scope closes (or {@link CamundaEffectWorkerHandle.interrupt} is run),
|
|
288
|
+
* at which point it is interrupted and any in-flight job's lease is released.
|
|
289
|
+
*
|
|
290
|
+
* Depends on the {@link CamundaEffect} service — provide the `/effect` client `layer`.
|
|
291
|
+
*
|
|
292
|
+
* @description Camunda Effect Worker. See the README and [this test](https://github.com/camunda/orchestration-cluster-api-js/blob/main/tests-integration/effect-worker.test.ts) for example usage.
|
|
293
|
+
*/
|
|
294
|
+
declare function createCamundaEffectWorker<A extends CompleteVars, R = never>(config: EffectWorkerConfig<A, R>): Effect.Effect<CamundaEffectWorkerHandle, never, Scope.Scope | CamundaEffect | R>;
|
|
295
|
+
/**
|
|
296
|
+
* A `Layer` that runs a Camunda Effect worker for the layer's lifetime. Compose it
|
|
297
|
+
* with the `/effect` client `layer` (which provides its {@link CamundaEffect}
|
|
298
|
+
* dependency) plus a `Layer` for the handler's own requirements `R`.
|
|
299
|
+
*/
|
|
300
|
+
declare function workerLayer<A extends CompleteVars, R = never>(config: EffectWorkerConfig<A, R>): Layer.Layer<never, never, CamundaEffect | R>;
|
|
301
|
+
|
|
302
|
+
export { type ActivateJobsStreamOptions, CamundaEffect, type CamundaEffectClient, type CamundaEffectWorkerHandle, CamundaGenericError, CamundaValidationError, type CompleteVars, type DomainError, type DomainErrorTag, type EffectPaginateOptions, type EffectPaginator, type EffectWorkerConfig, type Effectify, EventualConsistencyTimeout, type FnKeys, HttpError, type Job, type JobError, type JobHandler, RetryableJobError, TerminalJobError, activateJobsStream, createCamundaEffectClient, createCamundaEffectWorker, eventually, layer, retryWithBackoff, runWorkerLoop, withTimeout, workerLayer };
|