@camunda8/orchestration-cluster-api 10.0.0-alpha.30 → 10.0.0-alpha.32

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.
@@ -6473,7 +6473,7 @@ var init_zod_gen = __esm({
6473
6473
  }));
6474
6474
  zSecretResolveRequest = z.object({
6475
6475
  references: z.array(z.string().max(256).register(z.globalRegistry, {
6476
- description: "A secret reference of the form `camunda.secrets.<name>`."
6476
+ description: "A secret reference of the form `camunda.secrets.<name>`, where `<name>` is a\nnon-empty token of letters, digits, `_` and `-`. A reference outside that form is\nreported in `errors` with `INVALID_REFERENCE` rather than failing the request.\n"
6477
6477
  })).max(20).register(z.globalRegistry, {
6478
6478
  description: "The secret references to resolve, each of the form `camunda.secrets.<name>`.\nDuplicate references are deduplicated by the server and resolved once.\nAt most 20 references may be requested in a single batch.\n"
6479
6479
  })
@@ -9219,19 +9219,30 @@ default, with local set to \`false\`, scope '1' will be { "foo": 5 } and scope '
9219
9219
  }
9220
9220
  });
9221
9221
 
9222
- // src/fp/index.ts
9223
- var fp_exports = {};
9224
- __export(fp_exports, {
9225
- classifyDomainError: () => classifyDomainError,
9226
- createCamundaFpClient: () => createCamundaFpClient,
9227
- eventuallyTE: () => eventuallyTE,
9228
- foldDomainError: () => foldDomainError,
9229
- isLeft: () => isLeft,
9230
- isRight: () => isRight,
9231
- retryTE: () => retryTE,
9232
- withTimeoutTE: () => withTimeoutTE
9222
+ // src/effect/index.ts
9223
+ var effect_exports = {};
9224
+ __export(effect_exports, {
9225
+ CamundaEffect: () => CamundaEffect,
9226
+ CamundaGenericError: () => CamundaGenericError,
9227
+ CamundaValidationError: () => CamundaValidationError2,
9228
+ EventualConsistencyTimeout: () => EventualConsistencyTimeout,
9229
+ HttpError: () => HttpError,
9230
+ RetryableJobError: () => RetryableJobError,
9231
+ TerminalJobError: () => TerminalJobError,
9232
+ activateJobsStream: () => activateJobsStream,
9233
+ createCamundaEffectClient: () => createCamundaEffectClient,
9234
+ createCamundaEffectWorker: () => createCamundaEffectWorker,
9235
+ eventually: () => eventually,
9236
+ layer: () => layer,
9237
+ retryWithBackoff: () => retryWithBackoff,
9238
+ runWorkerLoop: () => runWorkerLoop,
9239
+ withTimeout: () => withTimeout,
9240
+ workerLayer: () => workerLayer
9233
9241
  });
9234
- module.exports = __toCommonJS(fp_exports);
9242
+ module.exports = __toCommonJS(effect_exports);
9243
+
9244
+ // src/effect.ts
9245
+ var import_effect = require("effect");
9235
9246
 
9236
9247
  // src/gen/core/serverSentEvents.gen.ts
9237
9248
  var __STANDARD_REQUEST_INIT_KEYS = [
@@ -13783,7 +13794,7 @@ function createLogger(opts = {}) {
13783
13794
  }
13784
13795
 
13785
13796
  // src/runtime/version.ts
13786
- var packageVersion = "10.0.0-alpha.30";
13797
+ var packageVersion = "10.0.0-alpha.32";
13787
13798
 
13788
13799
  // src/runtime/supportLogger.ts
13789
13800
  var NoopSupportLogger = class {
@@ -14239,18 +14250,18 @@ function unwrapForInspection(s) {
14239
14250
  continue;
14240
14251
  }
14241
14252
  if (t === "ZodIntersection") {
14242
- const left2 = cur._def.left;
14243
- const right2 = cur._def.right;
14244
- if (left2?._def?.typeName === "ZodObject" && right2?._def?.typeName === "ZodObject") {
14253
+ const left = cur._def.left;
14254
+ const right = cur._def.right;
14255
+ if (left?._def?.typeName === "ZodObject" && right?._def?.typeName === "ZodObject") {
14245
14256
  try {
14246
- const leftShapeFn = left2._def.shape;
14247
- const rightShapeFn = right2._def.shape;
14257
+ const leftShapeFn = left._def.shape;
14258
+ const rightShapeFn = right._def.shape;
14248
14259
  const merged = { ...leftShapeFn(), ...rightShapeFn() };
14249
14260
  return import_zod.ZodObject.create(merged);
14250
14261
  } catch {
14251
14262
  }
14252
14263
  }
14253
- cur = left2;
14264
+ cur = left;
14254
14265
  continue;
14255
14266
  }
14256
14267
  break;
@@ -29957,54 +29968,73 @@ var CamundaClient = class {
29957
29968
  }
29958
29969
  };
29959
29970
 
29960
- // src/fp-ts.ts
29961
- var left = (e) => ({ _tag: "Left", left: e });
29962
- var right = (a) => ({ _tag: "Right", right: a });
29963
- var isLeft = (e) => e._tag === "Left";
29964
- var isRight = (e) => e._tag === "Right";
29971
+ // src/effect.ts
29972
+ var CamundaValidationError2 = class extends import_effect.Data.TaggedError("CamundaValidationError") {
29973
+ };
29974
+ var EventualConsistencyTimeout = class extends import_effect.Data.TaggedError("EventualConsistencyTimeout") {
29975
+ };
29976
+ var HttpError = class extends import_effect.Data.TaggedError("HttpError") {
29977
+ };
29978
+ var CamundaGenericError = class extends import_effect.Data.TaggedError("CamundaGenericError") {
29979
+ };
29965
29980
  function toDomainError(err) {
29966
- if (err instanceof CamundaValidationError) return err;
29967
- if (err instanceof EventualConsistencyTimeoutError) return err;
29968
- if (err instanceof Error) return err;
29969
- if (typeof err === "object") return err;
29970
- return { message: String(err) };
29971
- }
29972
- function classifyDomainError(err) {
29973
- if (err instanceof CamundaValidationError) return "validation";
29974
- if (err instanceof EventualConsistencyTimeoutError) return "timeout";
29975
- if (!(err instanceof Error) || err.status !== void 0) return "http";
29976
- return "generic";
29977
- }
29978
- function foldDomainError(handlers) {
29979
- return (err) => {
29980
- switch (classifyDomainError(err)) {
29981
- case "validation":
29982
- return handlers.validation(err);
29983
- case "timeout":
29984
- return handlers.timeout(err);
29985
- case "http":
29986
- return handlers.http(err);
29987
- case "generic":
29988
- return handlers.generic(err);
29989
- }
29990
- };
29981
+ if (err instanceof CamundaValidationError) {
29982
+ return new CamundaValidationError2({
29983
+ side: err.side,
29984
+ operationId: err.operationId,
29985
+ summary: err.summary,
29986
+ issues: err.issues,
29987
+ message: err.message,
29988
+ cause: err
29989
+ });
29990
+ }
29991
+ if (err instanceof EventualConsistencyTimeoutError) {
29992
+ return new EventualConsistencyTimeout({
29993
+ attempts: err.attempts,
29994
+ elapsedMs: err.elapsedMs,
29995
+ message: err.message,
29996
+ cause: err
29997
+ });
29998
+ }
29999
+ const anyErr = err;
30000
+ if (anyErr && typeof anyErr === "object" && typeof anyErr.status === "number") {
30001
+ return new HttpError({
30002
+ status: anyErr.status,
30003
+ body: anyErr.body,
30004
+ message: typeof anyErr.message === "string" ? anyErr.message : `HTTP ${anyErr.status}`,
30005
+ cause: err
30006
+ });
30007
+ }
30008
+ if (err instanceof Error) {
30009
+ return new CamundaGenericError({ message: err.message, cause: err });
30010
+ }
30011
+ return new CamundaGenericError({ message: String(err), cause: err });
29991
30012
  }
29992
30013
  function isPromiseLike(v) {
29993
- return v && typeof v.then === "function";
30014
+ return !!v && typeof v.then === "function";
29994
30015
  }
29995
- function createCamundaFpClient(options) {
30016
+ function createCamundaEffectClient(options) {
29996
30017
  const base = createCamundaClient(options);
29997
30018
  const cache = /* @__PURE__ */ new Map();
29998
30019
  function wrap(fn) {
29999
- return (...args) => async () => {
30020
+ return (...args) => import_effect.Effect.suspend(() => {
30021
+ let r;
30000
30022
  try {
30001
- const r = fn.apply(base, args);
30002
- const val = isPromiseLike(r) ? await r : r;
30003
- return right(val);
30023
+ r = fn.apply(base, args);
30004
30024
  } catch (e) {
30005
- return left(toDomainError(e));
30006
- }
30007
- };
30025
+ return import_effect.Effect.fail(toDomainError(e));
30026
+ }
30027
+ if (!isPromiseLike(r)) return import_effect.Effect.succeed(r);
30028
+ const promise = r;
30029
+ return import_effect.Effect.callback((resume) => {
30030
+ promise.then(
30031
+ (a) => resume(import_effect.Effect.succeed(a)),
30032
+ (e) => resume(import_effect.Effect.fail(toDomainError(e)))
30033
+ );
30034
+ const cancel = r.cancel;
30035
+ return typeof cancel === "function" ? import_effect.Effect.sync(() => cancel.call(r)) : void 0;
30036
+ });
30037
+ });
30008
30038
  }
30009
30039
  const handler = {
30010
30040
  get(_t, prop) {
@@ -30022,71 +30052,233 @@ function createCamundaFpClient(options) {
30022
30052
  };
30023
30053
  return new Proxy({}, handler);
30024
30054
  }
30025
- function retryTE(task, opts) {
30026
- const { max, baseDelayMs = 100, shouldRetry } = opts;
30027
- return async () => {
30028
- let attempt = 0;
30029
- let lastLeft;
30030
- while (attempt < max) {
30031
- const res = await task();
30032
- if (isRight(res)) return res;
30033
- lastLeft = res;
30034
- attempt++;
30035
- const retry = attempt < max && (shouldRetry ? await shouldRetry(res.left, attempt) : true);
30036
- if (!retry) return res;
30037
- const delay = Math.min(2e3, baseDelayMs * 2 ** (attempt - 1));
30038
- await new Promise((r) => setTimeout(r, delay));
30039
- }
30040
- return lastLeft;
30055
+ function formatDuration(d) {
30056
+ try {
30057
+ return import_effect.Duration.format(import_effect.Duration.fromInputUnsafe(d));
30058
+ } catch {
30059
+ return String(d);
30060
+ }
30061
+ }
30062
+ function retryWithBackoff(effect, opts) {
30063
+ const backoff = import_effect.Schedule.exponential(opts.baseDelay ?? "100 millis").pipe(import_effect.Schedule.jittered);
30064
+ return import_effect.Effect.retry(effect, {
30065
+ schedule: backoff,
30066
+ times: Math.max(0, opts.max - 1),
30067
+ while: opts.while
30068
+ });
30069
+ }
30070
+ function withTimeout(effect, duration, onTimeout) {
30071
+ return import_effect.Effect.timeoutOrElse(effect, {
30072
+ duration,
30073
+ orElse: () => import_effect.Effect.fail(
30074
+ onTimeout ? onTimeout() : new EventualConsistencyTimeout({
30075
+ message: `Timed out after ${formatDuration(duration)}`
30076
+ })
30077
+ )
30078
+ });
30079
+ }
30080
+ function eventually(effect, predicate, opts) {
30081
+ const interval = opts.interval ?? "500 millis";
30082
+ const poll = import_effect.Effect.suspend(
30083
+ () => effect.pipe(
30084
+ import_effect.Effect.flatMap(
30085
+ (a) => predicate(a) ? import_effect.Effect.succeed(a) : import_effect.Effect.sleep(interval).pipe(import_effect.Effect.andThen(poll))
30086
+ )
30087
+ )
30088
+ );
30089
+ return withTimeout(
30090
+ poll,
30091
+ opts.waitUpTo,
30092
+ () => new EventualConsistencyTimeout({
30093
+ message: `Eventual consistency timeout after ${formatDuration(opts.waitUpTo)}`
30094
+ })
30095
+ );
30096
+ }
30097
+ var CamundaEffect = class extends import_effect.Context.Service()(
30098
+ "CamundaEffect"
30099
+ ) {
30100
+ };
30101
+ function layer(options) {
30102
+ return import_effect.Layer.sync(CamundaEffect, () => createCamundaEffectClient(options));
30103
+ }
30104
+
30105
+ // src/effect-worker.ts
30106
+ var import_effect2 = require("effect");
30107
+ var RetryableJobError = class extends import_effect2.Data.TaggedError("RetryableJobError") {
30108
+ };
30109
+ var TerminalJobError = class extends import_effect2.Data.TaggedError("TerminalJobError") {
30110
+ };
30111
+ var DEFAULT_MAX_JOBS = 10;
30112
+ var DEFAULT_POLL_INTERVAL = "1 second";
30113
+ var DEFAULT_JOB_TIMEOUT = "60 seconds";
30114
+ var DEFAULT_LONGPOLL_TIMEOUT3 = 0;
30115
+ var _workerCounter3 = 0;
30116
+ function toMillis(d) {
30117
+ return import_effect2.Duration.toMillis(import_effect2.Duration.fromInputUnsafe(d));
30118
+ }
30119
+ function activateJobsStream(type, options = {}) {
30120
+ const worker = options.workerName ?? `effect-worker-${type}-${++_workerCounter3}`;
30121
+ const batch = options.maxJobsToActivate ?? DEFAULT_MAX_JOBS;
30122
+ const pollInterval = options.pollInterval ?? DEFAULT_POLL_INTERVAL;
30123
+ const jobTimeout = options.jobTimeout ?? DEFAULT_JOB_TIMEOUT;
30124
+ const requestTimeout = typeof options.requestTimeout === "number" ? options.requestTimeout : options.requestTimeout !== void 0 ? toMillis(options.requestTimeout) : DEFAULT_LONGPOLL_TIMEOUT3;
30125
+ const body = {
30126
+ type,
30127
+ worker,
30128
+ maxJobsToActivate: batch,
30129
+ requestTimeout,
30130
+ timeout: toMillis(jobTimeout),
30131
+ ...options.fetchVariables && options.fetchVariables.length > 0 ? { fetchVariable: [...options.fetchVariables] } : {}
30041
30132
  };
30133
+ const pollOnce = import_effect2.Effect.gen(function* () {
30134
+ const camunda = yield* CamundaEffect;
30135
+ const result = yield* camunda.activateJobs(body);
30136
+ const jobs = result?.jobs ?? [];
30137
+ if (jobs.length === 0) yield* import_effect2.Effect.sleep(pollInterval);
30138
+ return jobs;
30139
+ });
30140
+ const activation = options.activationRetrySchedule ? import_effect2.Effect.retry(pollOnce, { schedule: options.activationRetrySchedule }) : pollOnce;
30141
+ return import_effect2.Stream.fromIterableEffectRepeat(activation);
30042
30142
  }
30043
- function withTimeoutTE(task, ms, onTimeout) {
30044
- return async () => {
30045
- let settled = false;
30046
- const t = task().then((r) => {
30047
- settled = true;
30048
- return r;
30143
+ function completeJob2(job, vars) {
30144
+ return import_effect2.Effect.gen(function* () {
30145
+ const camunda = yield* CamundaEffect;
30146
+ yield* camunda.completeJob({
30147
+ jobKey: job.jobKey,
30148
+ variables: vars ?? {},
30149
+ ...job.leaseToken != null ? { leaseToken: job.leaseToken } : {}
30150
+ });
30151
+ });
30152
+ }
30153
+ function failJobRetryable(job, error) {
30154
+ return import_effect2.Effect.gen(function* () {
30155
+ const camunda = yield* CamundaEffect;
30156
+ yield* camunda.failJob({
30157
+ jobKey: job.jobKey,
30158
+ errorMessage: error.message,
30159
+ retries: Math.max(0, (job.retries ?? 1) - 1),
30160
+ ...error.retryBackoff !== void 0 ? { retryBackOff: toMillis(error.retryBackoff) } : {},
30161
+ ...error.variables ? { variables: { ...error.variables } } : {},
30162
+ ...job.leaseToken != null ? { leaseToken: job.leaseToken } : {}
30049
30163
  });
30050
- const timeout = new Promise(
30051
- (res) => setTimeout(() => {
30052
- if (!settled)
30053
- res(left(onTimeout ? onTimeout() : new Error(`Timeout after ${ms}ms`)));
30054
- }, ms)
30164
+ });
30165
+ }
30166
+ function raiseIncident(job, error) {
30167
+ return import_effect2.Effect.gen(function* () {
30168
+ const camunda = yield* CamundaEffect;
30169
+ yield* camunda.throwJobError({
30170
+ jobKey: job.jobKey,
30171
+ errorCode: error.code,
30172
+ errorMessage: error.message,
30173
+ ...error.variables ? { variables: { ...error.variables } } : {},
30174
+ ...job.leaseToken != null ? { leaseToken: job.leaseToken } : {}
30175
+ });
30176
+ });
30177
+ }
30178
+ function releaseLease(job) {
30179
+ return import_effect2.Effect.gen(function* () {
30180
+ const camunda = yield* CamundaEffect;
30181
+ yield* camunda.failJob({
30182
+ jobKey: job.jobKey,
30183
+ errorMessage: "worker interrupted; releasing lease for re-activation",
30184
+ retries: job.retries ?? 1,
30185
+ ...job.leaseToken != null ? { leaseToken: job.leaseToken } : {}
30186
+ });
30187
+ }).pipe(import_effect2.Effect.ignore);
30188
+ }
30189
+ function failJobOnDefect(job, defect) {
30190
+ return import_effect2.Effect.gen(function* () {
30191
+ const camunda = yield* CamundaEffect;
30192
+ yield* import_effect2.Effect.logError(
30193
+ `effect-worker: handler for job ${job.jobKey} threw an unexpected defect; failing job with retries - 1`,
30194
+ defect
30055
30195
  );
30056
- return Promise.race([t, timeout]);
30057
- };
30196
+ yield* camunda.failJob({
30197
+ jobKey: job.jobKey,
30198
+ errorMessage: defect instanceof Error ? defect.message : "Handler error",
30199
+ retries: Math.max(0, (job.retries ?? 1) - 1),
30200
+ ...job.leaseToken != null ? { leaseToken: job.leaseToken } : {}
30201
+ });
30202
+ });
30058
30203
  }
30059
- function eventuallyTE(thunk, predicate, opts) {
30060
- const { intervalMs = 500, waitUpToMs } = opts;
30061
- return async () => {
30062
- const start = Date.now();
30063
- let attempt = 0;
30064
- while (true) {
30065
- attempt++;
30066
- try {
30067
- const val = await thunk();
30068
- if (await predicate(val)) return right(val);
30069
- } catch (e) {
30070
- return left(e);
30071
- }
30072
- const elapsed = Date.now() - start;
30073
- if (elapsed >= waitUpToMs)
30074
- return left(
30075
- new EventualConsistencyTimeoutError({ attempts: attempt, elapsedMs: elapsed })
30076
- );
30077
- await new Promise((r) => setTimeout(r, intervalMs));
30078
- }
30079
- };
30204
+ function processJob(config, job) {
30205
+ const handled = config.handlerRetrySchedule ? import_effect2.Effect.retry(config.handler(job), {
30206
+ schedule: config.handlerRetrySchedule,
30207
+ while: (e) => e._tag === "RetryableJobError"
30208
+ }) : config.handler(job);
30209
+ return handled.pipe(
30210
+ import_effect2.Effect.flatMap((vars) => completeJob2(job, vars)),
30211
+ import_effect2.Effect.catchTag("RetryableJobError", (e) => failJobRetryable(job, e)),
30212
+ import_effect2.Effect.catchTag("TerminalJobError", (e) => raiseIncident(job, e)),
30213
+ // Interruption is re-raised (not a defect) by `onInterrupt` below; only genuine
30214
+ // handler defects reach here and are converted to a best-effort failJob.
30215
+ import_effect2.Effect.catchDefect((defect) => failJobOnDefect(job, defect)),
30216
+ import_effect2.Effect.onInterrupt(() => releaseLease(job))
30217
+ );
30218
+ }
30219
+ function runWorkerLoop(config) {
30220
+ const concurrency = config.concurrency ?? config.maxJobsToActivate ?? DEFAULT_MAX_JOBS;
30221
+ const maxJobsToActivate = typeof concurrency === "number" ? Math.min(config.maxJobsToActivate ?? DEFAULT_MAX_JOBS, concurrency) : config.maxJobsToActivate;
30222
+ return activateJobsStream(config.type, { ...config, maxJobsToActivate }).pipe(
30223
+ import_effect2.Stream.mapEffect(
30224
+ (job) => (
30225
+ // A per-job acknowledgement failure (completeJob/failJob/throwJobError raising a
30226
+ // `DomainError`) must not tear down the worker: a transient ack outage on one job
30227
+ // would otherwise fail `Stream.runDrain` and stop all processing. Log it and keep
30228
+ // going so `join` ends only on a fatal activation error (its documented contract),
30229
+ // matching the Promise worker which swallows per-job ack failures. Two causes are
30230
+ // re-raised instead of swallowed: a pure interruption (scope close / `interrupt`),
30231
+ // so shutdown and the best-effort lease release in `processJob` still propagate;
30232
+ // and a genuine defect (`die`), so an unexpected bug surfaces rather than hiding —
30233
+ // note handler defects are already converted to a best-effort failJob inside
30234
+ // `processJob`, so only truly unexpected defects reach here.
30235
+ // NOTE: `Effect.catchAll` is avoided deliberately — under the effect 4.0.0-rc it
30236
+ // suppresses `Stream.mapEffect` emission even on the success path; `catchCause`
30237
+ // does not.
30238
+ processJob(config, job).pipe(
30239
+ import_effect2.Effect.catchCause(
30240
+ (cause) => import_effect2.Cause.hasInterruptsOnly(cause) || import_effect2.Cause.hasDies(cause) ? import_effect2.Effect.failCause(cause) : import_effect2.Effect.logError(
30241
+ `effect-worker[${config.type}]: acknowledging job ${job.jobKey} failed; continuing`,
30242
+ cause
30243
+ )
30244
+ )
30245
+ )
30246
+ ),
30247
+ { concurrency }
30248
+ ),
30249
+ import_effect2.Stream.runDrain
30250
+ );
30251
+ }
30252
+ function createCamundaEffectWorker(config) {
30253
+ return import_effect2.Effect.gen(function* () {
30254
+ const fiber = yield* import_effect2.Effect.forkScoped(runWorkerLoop(config));
30255
+ return {
30256
+ type: config.type,
30257
+ join: import_effect2.Fiber.join(fiber),
30258
+ interrupt: import_effect2.Fiber.interrupt(fiber).pipe(import_effect2.Effect.asVoid)
30259
+ };
30260
+ });
30261
+ }
30262
+ function workerLayer(config) {
30263
+ return import_effect2.Layer.effectDiscard(createCamundaEffectWorker(config));
30080
30264
  }
30081
30265
  // Annotate the CommonJS export names for ESM import in node:
30082
30266
  0 && (module.exports = {
30083
- classifyDomainError,
30084
- createCamundaFpClient,
30085
- eventuallyTE,
30086
- foldDomainError,
30087
- isLeft,
30088
- isRight,
30089
- retryTE,
30090
- withTimeoutTE
30267
+ CamundaEffect,
30268
+ CamundaGenericError,
30269
+ CamundaValidationError,
30270
+ EventualConsistencyTimeout,
30271
+ HttpError,
30272
+ RetryableJobError,
30273
+ TerminalJobError,
30274
+ activateJobsStream,
30275
+ createCamundaEffectClient,
30276
+ createCamundaEffectWorker,
30277
+ eventually,
30278
+ layer,
30279
+ retryWithBackoff,
30280
+ runWorkerLoop,
30281
+ withTimeout,
30282
+ workerLayer
30091
30283
  });
30092
30284
  //# sourceMappingURL=index.cjs.map