@camunda8/orchestration-cluster-api 8.9.0-alpha.22 → 8.9.0-alpha.24

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 CHANGED
@@ -1,3 +1,29 @@
1
+ # [8.9.0-alpha.24](https://github.com/camunda/orchestration-cluster-api-js/compare/v8.9.0-alpha.23...v8.9.0-alpha.24) (2026-03-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * harden README code injection ([4745468](https://github.com/camunda/orchestration-cluster-api-js/commit/47454684f052027e1449367204e7097b2b26f271)), closes [#87](https://github.com/camunda/orchestration-cluster-api-js/issues/87)
7
+
8
+ # [8.9.0-alpha.23](https://github.com/camunda/orchestration-cluster-api-js/compare/v8.9.0-alpha.22...v8.9.0-alpha.23) (2026-03-30)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * address PR review comments ([fd357d5](https://github.com/camunda/orchestration-cluster-api-js/commit/fd357d5938dbb0e22d18711087b26560a802494c))
14
+ * address PR review comments on heritable worker defaults ([efec39c](https://github.com/camunda/orchestration-cluster-api-js/commit/efec39c54c788f625f27f7be70c830321ff43ef6))
15
+ * **config:** add signedInt schema type for CAMUNDA_WORKER_REQUEST_TIMEOUT ([9f9f794](https://github.com/camunda/orchestration-cluster-api-js/commit/9f9f7949e3b1cfcf90ab8abf723595276c41a18d))
16
+ * **tests:** convert threaded handler fixtures to .js for Node 20 compat ([1e5f7b1](https://github.com/camunda/orchestration-cluster-api-js/commit/1e5f7b17931043adade84c7630264a1ed543cf2a))
17
+ * **threadedJobWorker:** extract validated fields to fix TS strict null errors ([7097cbd](https://github.com/camunda/orchestration-cluster-api-js/commit/7097cbde12076b8ba0d35208cedf7ebe1c891493))
18
+ * **threadPool:** don't pass TS strip flags to workers on Node < 22 ([dbf18d3](https://github.com/camunda/orchestration-cluster-api-js/commit/dbf18d3ab92ed1fd5fdf54988c1f613eaf7b09e3))
19
+ * use number types for int config overrides in tests and examples ([f7bfa2f](https://github.com/camunda/orchestration-cluster-api-js/commit/f7bfa2f3d9be5152d4cf9a1ca6d0d4f8c117e14b))
20
+ * wire README worker-defaults examples into snippet injection ([7759561](https://github.com/camunda/orchestration-cluster-api-js/commit/775956168f588dd02bf6e969ed641f3abb67e288))
21
+
22
+
23
+ ### Features
24
+
25
+ * heritable worker defaults via CAMUNDA_WORKER_* env vars ([0311308](https://github.com/camunda/orchestration-cluster-api-js/commit/03113084fb15566bdf7d3bbb3d0d6e78ef582584))
26
+
1
27
  # [8.9.0-alpha.22](https://github.com/camunda/orchestration-cluster-api-js/compare/v8.9.0-alpha.21...v8.9.0-alpha.22) (2026-03-30)
2
28
 
3
29
 
package/README.md CHANGED
@@ -54,7 +54,7 @@ In the vast majority of use-cases, this will not be an issue; but you should be
54
54
 
55
55
  Keep configuration out of application code. Let the factory read `CAMUNDA_*` variables from the environment (12‑factor style). This makes rotation, secret management, and environment promotion safer & simpler.
56
56
 
57
- <!-- snippet:ReadmeDefaultImport+ReadmeQuickStart -->
57
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeDefaultImport+ReadmeQuickStart -->
58
58
 
59
59
  ```ts
60
60
  import createCamundaClient from '@camunda8/orchestration-cluster-api';
@@ -96,7 +96,7 @@ CAMUNDA_SDK_HTTP_RETRY_MAX_DELAY_MS=2000 # optional: cap (ms)
96
96
 
97
97
  Use only when you must supply or mutate configuration dynamically (e.g. multi‑tenant routing, tests, ephemeral preview environments) or in the browser. Keys mirror their `CAMUNDA_*` env names.
98
98
 
99
- <!-- snippet:ReadmeOverrides -->
99
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeOverrides -->
100
100
 
101
101
  ```ts
102
102
  const camunda = createCamundaClient({
@@ -113,7 +113,7 @@ const camunda = createCamundaClient({
113
113
 
114
114
  Inject a custom `fetch` to add tracing, mock responses, instrumentation, circuit breakers, etc.
115
115
 
116
- <!-- snippet:ReadmeCustomFetch -->
116
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeCustomFetch -->
117
117
 
118
118
  ```ts
119
119
  const camunda = createCamundaClient({
@@ -166,7 +166,7 @@ Every API method accepts an optional trailing `options` parameter that lets you
166
166
 
167
167
  ### Disable Retry for a Single Call
168
168
 
169
- <!-- snippet:ReadmeDisableRetry -->
169
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeDisableRetry -->
170
170
 
171
171
  ```ts
172
172
  // This call will not retry on transient errors
@@ -177,7 +177,7 @@ await camunda.completeJob({ jobKey }, { retry: false });
177
177
 
178
178
  Pass a partial `HttpRetryPolicy` to override individual fields. Unspecified fields inherit from the global configuration.
179
179
 
180
- <!-- snippet:ReadmeRetryOverride -->
180
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeRetryOverride -->
181
181
 
182
182
  ```ts
183
183
  // More aggressive retry for this operation only
@@ -224,6 +224,7 @@ Set `CAMUNDA_SDK_HTTP_RETRY_MAX_ATTEMPTS=1` so the SDK does only the initial att
224
224
 
225
225
  ### Minimal Example (Single Operation)
226
226
 
227
+ <!-- snippet-exempt: uses external cockatiel library -->
227
228
  ```ts
228
229
  import { createCamundaClient } from '@camunda8/orchestration-cluster-api';
229
230
  import { retry, ExponentialBackoff, handleAll } from 'cockatiel';
@@ -252,6 +253,7 @@ console.log(topo.brokers?.length);
252
253
 
253
254
  ### Bulk Wrapping All Operations
254
255
 
256
+ <!-- snippet-exempt: uses external cockatiel library -->
255
257
  ```ts
256
258
  import { createCamundaClient } from '@camunda8/orchestration-cluster-api';
257
259
  import { retry, ExponentialBackoff, handleAll } from 'cockatiel';
@@ -330,6 +332,7 @@ Refer to `./docs/CONFIG_REFERENCE.md` for the full list of related environment v
330
332
 
331
333
  Retry only network errors + 429/503, plus optionally 500 on safe GET endpoints you mark:
332
334
 
335
+ <!-- snippet-exempt: uses external cockatiel library -->
333
336
  ```ts
334
337
  import { retry, ExponentialBackoff, handleWhen } from 'cockatiel';
335
338
 
@@ -474,7 +477,7 @@ The SDK provides a lightweight polling job worker for service task job types usi
474
477
 
475
478
  ### Minimal Example
476
479
 
477
- <!-- snippet:ReadmeJobWorkerImport+ReadmeJobWorkerMinimal -->
480
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeJobWorkerImport+ReadmeJobWorkerMinimal -->
478
481
 
479
482
  ```ts
480
483
  import createCamundaClient from '@camunda8/orchestration-cluster-api';
@@ -521,7 +524,7 @@ TypeScript inference:
521
524
 
522
525
  - When you provide `inputSchema`, the type of `fetchVariables` is constrained to the keys of the inferred `variables` type from that schema. Example:
523
526
 
524
- <!-- snippet:ReadmeJobWorkerInference -->
527
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeJobWorkerInference -->
525
528
 
526
529
  ```ts
527
530
  const Input = z.object({ orderId: z.string(), amount: z.number() });
@@ -567,26 +570,25 @@ Recommended usage:
567
570
 
568
571
  Example patterns:
569
572
 
573
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeJobCompletionPatterns -->
570
574
  ```ts
571
575
  // GOOD: explicit completion
572
- return job.complete({ processed: true }); // sentinel stored for ultimate return
576
+ return job.complete({ variables: { processed: true } });
577
+
578
+ // GOOD: No-arg completion example, sentinel stored for ultimate return
573
579
  const ack = await job.complete();
574
580
  // ...
575
581
  return ack;
576
582
 
577
583
  // GOOD: explicit ignore
578
- const ack = await job.ignore();
579
- ```
580
-
581
- ```ts
582
- // No-arg completion example
584
+ const ack2 = await job.ignore();
583
585
  ```
584
586
 
585
587
  ### Job Corrections (User Task Listeners)
586
588
 
587
589
  When a job worker handles a [user task listener](https://docs.camunda.io/docs/components/concepts/user-task-listeners/), it can correct task properties (assignee, due date, candidate groups, etc.) by passing a `result` to `job.complete()`:
588
590
 
589
- <!-- snippet:ReadmeJobCorrectionsImport+ReadmeJobCorrections -->
591
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeJobCorrectionsImport+ReadmeJobCorrections -->
590
592
 
591
593
  ```ts
592
594
  import type { JobResult } from '@camunda8/orchestration-cluster-api';
@@ -610,14 +612,17 @@ const worker = client.createJobWorker({
610
612
 
611
613
  To deny a task completion (reject the work):
612
614
 
613
- <!-- snippet:ReadmeJobCorrectionsDenial -->
615
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeJobCorrectionsDenial -->
614
616
 
615
617
  ```ts
616
- return job.complete({}, {
617
- type: 'userTask',
618
- denied: true,
619
- deniedReason: 'Insufficient documentation',
620
- });
618
+ return job.complete(
619
+ {},
620
+ {
621
+ type: 'userTask',
622
+ denied: true,
623
+ deniedReason: 'Insufficient documentation',
624
+ }
625
+ );
621
626
  ```
622
627
 
623
628
  | Correctable attribute | Type | Clear value |
@@ -647,7 +652,7 @@ If `validateSchemas` is true:
647
652
 
648
653
  Use `await worker.stopGracefully({ waitUpToMs?, checkIntervalMs? })` to drain without force‑cancelling the current activation request.
649
654
 
650
- <!-- snippet:ReadmeJobWorkerGraceful -->
655
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeJobWorkerGraceful -->
651
656
 
652
657
  ```ts
653
658
  // Attempt graceful drain for up to 8 seconds
@@ -676,7 +681,7 @@ You can register multiple workers on a single client instance—one per job type
676
681
 
677
682
  When deploying multiple application instances simultaneously (e.g. a rolling restart or scale-up), all workers start polling at the same time and can saturate the server with activation requests. Set `startupJitterMaxSeconds` to spread out the initial poll across a random window:
678
683
 
679
- <!-- snippet:ReadmeJobWorkerJitter -->
684
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeJobWorkerJitter -->
680
685
 
681
686
  ```ts
682
687
  client.createJobWorker({
@@ -690,11 +695,66 @@ client.createJobWorker({
690
695
 
691
696
  A value of `0` (the default) means no delay.
692
697
 
698
+ ### Heritable Worker Defaults
699
+
700
+ When running many workers with the same base configuration, you can set global defaults via environment variables (or equivalent keys in `CamundaOptions.config`). These apply to every worker created by the client (both `createJobWorker` and `createThreadedJobWorker`) unless the individual worker config explicitly overrides them.
701
+
702
+ | Environment Variable | Worker Config Field | Type |
703
+ | ------------------------------------------ | -------------------------- | ------ |
704
+ | `CAMUNDA_WORKER_TIMEOUT` | `jobTimeoutMs` | number |
705
+ | `CAMUNDA_WORKER_MAX_CONCURRENT_JOBS` | `maxParallelJobs` | number |
706
+ | `CAMUNDA_WORKER_REQUEST_TIMEOUT` | `pollTimeoutMs` | number |
707
+ | `CAMUNDA_WORKER_NAME` | `workerName` | string |
708
+ | `CAMUNDA_WORKER_STARTUP_JITTER_MAX_SECONDS`| `startupJitterMaxSeconds` | number |
709
+
710
+ **Precedence:** explicit worker config value > `CAMUNDA_WORKER_*` (from environment variables or `CamundaOptions.config` overrides) > hardcoded default (where applicable).
711
+
712
+ Example — set defaults via environment:
713
+
714
+ ```bash
715
+ export CAMUNDA_WORKER_TIMEOUT=30000
716
+ export CAMUNDA_WORKER_MAX_CONCURRENT_JOBS=8
717
+ export CAMUNDA_WORKER_NAME=order-service
718
+ ```
719
+
720
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeWorkerDefaultsEnv -->
721
+ ```ts
722
+ // Workers inherit timeout, concurrency, and name from environment
723
+ const w1 = client.createJobWorker({
724
+ jobType: 'validate-order',
725
+ jobHandler: async (job) => job.complete(),
726
+ });
727
+
728
+ const w2 = client.createJobWorker({
729
+ jobType: 'ship-order',
730
+ jobHandler: async (job) => job.complete(),
731
+ });
732
+
733
+ // Per-worker override: this worker uses 32 concurrent jobs instead of the global 8
734
+ const w3 = client.createJobWorker({
735
+ jobType: 'bulk-import',
736
+ maxParallelJobs: 32,
737
+ jobHandler: async (job) => job.complete(),
738
+ });
739
+ ```
740
+
741
+ You can also pass defaults programmatically via the client constructor:
742
+
743
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeWorkerDefaultsClient -->
744
+ ```ts
745
+ const client = createCamundaClient({
746
+ config: {
747
+ CAMUNDA_WORKER_TIMEOUT: 30000,
748
+ CAMUNDA_WORKER_MAX_CONCURRENT_JOBS: 8,
749
+ },
750
+ });
751
+ ```
752
+
693
753
  ### Receipt Type (Unique Symbol)
694
754
 
695
755
  Action methods return a unique symbol (not a string) to avoid accidental misuse and allow internal metrics. If you store the receipt, annotate its type as `JobActionReceipt` to preserve uniqueness:
696
756
 
697
- <!-- snippet:ReadmeReceiptImport+ReadmeReceipt -->
757
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeReceiptImport+ReadmeReceipt -->
698
758
 
699
759
  ```ts
700
760
  import type { JobActionReceipt } from '@camunda8/orchestration-cluster-api';
@@ -732,14 +792,14 @@ This reverts to only per‑request retry for transient errors (no global gating)
732
792
 
733
793
  Call `client.getBackpressureState()` to obtain:
734
794
 
795
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeBackpressureState -->
735
796
  ```ts
736
- {
737
- severity: 'healthy' | 'soft' | 'severe';
738
- consecutive: number; // consecutive backpressure signals observed
739
- permitsMax: number | null; // current concurrency cap (null => unlimited/not engaged)
740
- permitsCurrent: number; // currently acquired permits
741
- waiters: number; // queued operations waiting for a permit
742
- }
797
+ const state = client.getBackpressureState();
798
+ // state.severity: 'healthy' | 'soft' | 'severe'
799
+ // state.consecutive: number consecutive backpressure signals observed
800
+ // state.permitsMax: number | null current concurrency cap (null => unlimited/not engaged)
801
+ // state.permitsCurrent: number currently acquired permits
802
+ // state.waiters: number queued operations waiting for a permit
743
803
  ```
744
804
 
745
805
  ### Threaded Job Workers (Node.js Only)
@@ -758,6 +818,7 @@ If your handler is mostly I/O-bound (HTTP calls, database queries), the standard
758
818
 
759
819
  The handler must be a **separate file** (not an inline function) that exports a default async function:
760
820
 
821
+ <!-- snippet-exempt: pseudo-code referencing heavyComputation which cannot be type-checked -->
761
822
  ```ts
762
823
  // my-handler.ts (or my-handler.js)
763
824
  import type { ThreadedJobHandler } from '@camunda8/orchestration-cluster-api';
@@ -780,7 +841,7 @@ The handler receives two arguments:
780
841
 
781
842
  #### Minimal example
782
843
 
783
- <!-- snippet:ReadmeThreadedWorkerImport+ReadmeThreadedWorker -->
844
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeThreadedWorkerImport+ReadmeThreadedWorker -->
784
845
 
785
846
  ```ts
786
847
  import createCamundaClient from '@camunda8/orchestration-cluster-api';
@@ -812,19 +873,24 @@ Other familiar options: `jobType`, `maxParallelJobs`, `jobTimeoutMs`, `pollInter
812
873
 
813
874
  Threaded workers integrate with the same lifecycle as regular workers:
814
875
 
876
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeThreadedLifecycle -->
815
877
  ```ts
816
878
  // Returned by getWorkers()
817
879
  const allWorkers = client.getWorkers();
818
880
 
819
881
  // Stopped by stopAllWorkers()
820
882
  client.stopAllWorkers();
883
+ ```
821
884
 
885
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeThreadedGraceful -->
886
+ ```ts
822
887
  // Graceful shutdown (waits for in-flight jobs to finish)
823
888
  const { timedOut, remainingJobs } = await worker.stopGracefully({ waitUpToMs: 10_000 });
824
889
  ```
825
890
 
826
891
  #### Pool stats
827
892
 
893
+ <!-- snippet-source: examples/readme.ts | regions: ReadmePoolStats -->
828
894
  ```ts
829
895
  worker.poolSize; // number of threads
830
896
  worker.busyThreads; // threads currently processing a job
@@ -932,7 +998,7 @@ If both cert & key are available an https.Agent is attached to all outbound call
932
998
 
933
999
  Import branded key helpers directly:
934
1000
 
935
- <!-- snippet:ReadmeBrandedKeysImport+ReadmeBrandedKeys -->
1001
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeBrandedKeysImport+ReadmeBrandedKeys -->
936
1002
 
937
1003
  ```ts
938
1004
  import { ProcessDefinitionKey, ProcessInstanceKey } from '@camunda8/orchestration-cluster-api';
@@ -948,7 +1014,7 @@ They are zero‑cost runtime strings with compile‑time separation.
948
1014
 
949
1015
  All methods return a `CancelablePromise<T>`:
950
1016
 
951
- <!-- snippet:ReadmeCancelable -->
1017
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeCancelable -->
952
1018
 
953
1019
  ```ts
954
1020
  const p = camunda.searchProcessInstances(
@@ -985,6 +1051,7 @@ Notes:
985
1051
 
986
1052
  The main entry stays minimal. To opt in to a TaskEither-style facade & helper combinators import from the dedicated subpath:
987
1053
 
1054
+ <!-- snippet-exempt: uses SDK /fp subpath not available in examples project -->
988
1055
  ```ts
989
1056
  import {
990
1057
  createCamundaFpClient,
@@ -992,7 +1059,7 @@ import {
992
1059
  withTimeoutTE,
993
1060
  eventuallyTE,
994
1061
  isLeft,
995
- } from '@camunda8/orchestration-cluster/fp';
1062
+ } from '@camunda8/orchestration-cluster-api/fp';
996
1063
 
997
1064
  const fp = createCamundaFpClient();
998
1065
  const deployTE = fp.deployResourcesFromFiles(['./bpmn/process.bpmn']);
@@ -1060,7 +1127,7 @@ Use this to understand convergence speed and data shape evolution during tests o
1060
1127
 
1061
1128
  ### Example
1062
1129
 
1063
- <!-- snippet:ReadmeEventualConsistency -->
1130
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeEventualConsistency -->
1064
1131
 
1065
1132
  ```ts
1066
1133
  const jobs = await camunda.searchJobs(
@@ -1084,7 +1151,7 @@ On timeout an `EventualConsistencyTimeoutError` includes diagnostic fields: `{ a
1084
1151
 
1085
1152
  Per‑client logger; no global singleton. The level defaults from `CAMUNDA_SDK_LOG_LEVEL` (default `error`).
1086
1153
 
1087
- <!-- snippet:ReadmeLogging -->
1154
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeLogging -->
1088
1155
 
1089
1156
  ```ts
1090
1157
  const client = createCamundaClient({
@@ -1137,9 +1204,10 @@ Provide a `transport` function to forward structured `LogEvent` objects into any
1137
1204
 
1138
1205
  #### Pino
1139
1206
 
1207
+ <!-- snippet-exempt: uses external pino dependency -->
1140
1208
  ```ts
1141
1209
  import pino from 'pino';
1142
- import createCamundaClient from '@camunda8/orchestration-cluster';
1210
+ import createCamundaClient from '@camunda8/orchestration-cluster-api';
1143
1211
 
1144
1212
  const p = pino();
1145
1213
  const client = createCamundaClient({
@@ -1155,9 +1223,10 @@ const client = createCamundaClient({
1155
1223
 
1156
1224
  #### Winston
1157
1225
 
1226
+ <!-- snippet-exempt: uses external winston dependency -->
1158
1227
  ```ts
1159
1228
  import winston from 'winston';
1160
- import createCamundaClient from '@camunda8/orchestration-cluster';
1229
+ import createCamundaClient from '@camunda8/orchestration-cluster-api';
1161
1230
 
1162
1231
  const w = winston.createLogger({ transports: [new winston.transports.Console()] });
1163
1232
  const client = createCamundaClient({
@@ -1180,9 +1249,10 @@ const client = createCamundaClient({
1180
1249
 
1181
1250
  #### loglevel
1182
1251
 
1252
+ <!-- snippet-exempt: uses external loglevel dependency -->
1183
1253
  ```ts
1184
1254
  import log from 'loglevel';
1185
- import createCamundaClient from '@camunda8/orchestration-cluster';
1255
+ import createCamundaClient from '@camunda8/orchestration-cluster-api';
1186
1256
 
1187
1257
  log.setLevel('info'); // host app level
1188
1258
  const client = createCamundaClient({
@@ -1223,7 +1293,7 @@ May throw:
1223
1293
 
1224
1294
  All SDK-thrown operational errors normalize to a discriminated union (`SdkError`) when they originate from HTTP, network, auth, or validation layers. Use the guard `isSdkError` to narrow inside a catch:
1225
1295
 
1226
- <!-- snippet:ReadmeErrorHandlingImport+ReadmeErrorHandling -->
1296
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeErrorHandlingImport+ReadmeErrorHandling -->
1227
1297
 
1228
1298
  ```ts
1229
1299
  import { createCamundaClient, isSdkError } from '@camunda8/orchestration-cluster-api';
@@ -1273,7 +1343,7 @@ _Note that this feature is experimental and subject to change._
1273
1343
 
1274
1344
  If you prefer FP‑style explicit error handling instead of exceptions, use the result client wrapper:
1275
1345
 
1276
- <!-- snippet:ReadmeResultClientImport+ReadmeResultClient -->
1346
+ <!-- snippet-source: examples/readme-imports.txt,examples/readme.ts | regions: ReadmeResultClientImport+ReadmeResultClient -->
1277
1347
 
1278
1348
  ```ts
1279
1349
  import { createCamundaResultClient, isOk } from '@camunda8/orchestration-cluster-api';
@@ -1295,8 +1365,9 @@ API surface differences:
1295
1365
 
1296
1366
  Helpers:
1297
1367
 
1368
+ <!-- snippet-exempt: one-liner import example -->
1298
1369
  ```ts
1299
- import { isOk, isErr } from '@camunda8/orchestration-cluster';
1370
+ import { isOk, isErr } from '@camunda8/orchestration-cluster-api';
1300
1371
  ```
1301
1372
 
1302
1373
  When to use:
@@ -1311,8 +1382,9 @@ _Note that this feature is experimental and subject to change._
1311
1382
 
1312
1383
  For projects using `fp-ts`, wrap the throwing client in a lazy `TaskEither` facade:
1313
1384
 
1385
+ <!-- snippet-exempt: requires external fp-ts dependency -->
1314
1386
  ```ts
1315
- import { createCamundaFpClient } from '@camunda8/orchestration-cluster';
1387
+ import { createCamundaFpClient } from '@camunda8/orchestration-cluster-api/fp';
1316
1388
  import { pipe } from 'fp-ts/function';
1317
1389
  import * as TE from 'fp-ts/TaskEither';
1318
1390
 
@@ -1360,7 +1432,7 @@ The deployment endpoint requires each resource to have a filename (extension use
1360
1432
 
1361
1433
  ### Browser
1362
1434
 
1363
- <!-- snippet:ReadmeDeployBrowser -->
1435
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeDeployBrowser -->
1364
1436
 
1365
1437
  ```ts
1366
1438
  const bpmnXml = `<definitions id="process" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">...</definitions>`;
@@ -1371,6 +1443,7 @@ console.log(result.deployments.length);
1371
1443
 
1372
1444
  From an existing Blob:
1373
1445
 
1446
+ <!-- snippet-exempt: uses hypothetical getBlob() function -->
1374
1447
  ```ts
1375
1448
  const blob: Blob = getBlob();
1376
1449
  const file = new File([blob], 'model.bpmn');
@@ -1381,7 +1454,7 @@ await camunda.createDeployment({ resources: [file] });
1381
1454
 
1382
1455
  Use the built-in helper `deployResourcesFromFiles(...)` to read local files and create `File` objects automatically. It returns the enriched `ExtendedDeploymentResult` (adds typed arrays: `processes`, `decisions`, `decisionRequirements`, `forms`, `resources`).
1383
1456
 
1384
- <!-- snippet:ReadmeDeployNode -->
1457
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeDeployNode -->
1385
1458
 
1386
1459
  ```ts
1387
1460
  const result = await camunda.deployResourcesFromFiles([
@@ -1396,12 +1469,14 @@ console.log(result.decisions.length);
1396
1469
 
1397
1470
  With explicit tenant (overriding tenant from configuration):
1398
1471
 
1472
+ <!-- snippet-exempt: small variant of injected deploy example above -->
1399
1473
  ```ts
1400
1474
  await camunda.deployResourcesFromFiles(['./bpmn/order-process.bpmn'], { tenantId: 'tenant-a' });
1401
1475
  ```
1402
1476
 
1403
1477
  Error handling:
1404
1478
 
1479
+ <!-- snippet-exempt: small variant of injected deploy example above -->
1405
1480
  ```ts
1406
1481
  try {
1407
1482
  await camunda.deployResourcesFromFiles([]); // throws (empty array)
@@ -1412,6 +1487,7 @@ try {
1412
1487
 
1413
1488
  Manual construction alternative (if you need custom logic):
1414
1489
 
1490
+ <!-- snippet-exempt: alternative construction pattern using node:buffer -->
1415
1491
  ```ts
1416
1492
  import { File } from 'node:buffer';
1417
1493
  const bpmnXml =
@@ -1433,7 +1509,7 @@ Empty arrays are rejected. Always use correct extensions so the server can class
1433
1509
 
1434
1510
  Create isolated clients per test file:
1435
1511
 
1436
- <!-- snippet:ReadmeTestingClient -->
1512
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeTestingClient -->
1437
1513
 
1438
1514
  ```ts
1439
1515
  const client = createCamundaClient({
@@ -1443,7 +1519,7 @@ const client = createCamundaClient({
1443
1519
 
1444
1520
  Inject a mock fetch:
1445
1521
 
1446
- <!-- snippet:ReadmeTestingMock -->
1522
+ <!-- snippet-source: examples/readme.ts | regions: ReadmeTestingMock -->
1447
1523
 
1448
1524
  ```ts
1449
1525
  const client = createCamundaClient({