@nanobpm/nano-sdk
v1.2.7
Published
Drop-in replacement for @camunda8/orchestration-cluster-api that upgrades to the Nano Falcon protocol when connected to a Nano server.
Readme
@nanobpm/nano-sdk
A drop-in replacement for @camunda8/orchestration-cluster-api that transparently upgrades to Nano's falcon protocol when connected to a Nano server. Against stock Camunda 8 it behaves exactly like the upstream SDK.
- import { createCamundaClient } from "@camunda8/orchestration-cluster-api";
+ import { createCamundaClient } from "@nanobpm/nano-sdk";Everything else is re-exported unchanged — same types, same client, same API.
What gets upgraded
When the client detects a Nano server, two hot paths move from REST onto a single persistent WebSocket (/falcon):
createProcessInstance→createInstanceframe, gated on the server's submission-credit window (withawaitCompletionresolved viainstanceCompleted).createJobWorker→subscribe+ pushedjobframes, acked withcompleteJob/failJob/throwErrorand credit-replenished.
This avoids the ~125 creates/s/conn ceiling of the REST long-poll path.
Detection & override
Detection is automatic: the SDK probes GET /v2/topology once and looks for the Nano falconPath advertisement. Control it via the CAMUNDA_TRANSPORT config (or env var):
| value | behaviour |
| ---------------- | ------------------------------------------- |
| auto (default) | falcon on Nano, REST elsewhere |
| falcon | force the stream (assume Nano) |
| rest | never upgrade — pure upstream behaviour |
const client = createCamundaClient({
config: { CAMUNDA_REST_ADDRESS: "http://localhost:8080", CAMUNDA_TRANSPORT: "auto" },
});Failing fast under backpressure (submitTimeoutMs)
On the Falcon protocol, admission backpressure is expressed by the server
withholding submission credits (no 503, no retry), so a createProcessInstance
otherwise waits indefinitely for the gateway to ack. To fail fast instead, set a
submit timeout — per call, or client-wide via config/env:
// Client-wide default (ms); per-call submitTimeoutMs wins when both are set.
const client = createCamundaClient({
config: { CAMUNDA_REST_ADDRESS: "http://localhost:8080", CAMUNDA_NANO_SUBMIT_TIMEOUT_MS: 2000 },
});
import { SubmissionTimeoutError } from "@nanobpm/nano-sdk";
try {
await client.createProcessInstance({ processDefinitionId: "order", submitTimeoutMs: 500 });
} catch (err) {
if (err instanceof SubmissionTimeoutError) {
// Server is applying admission backpressure — back off, do NOT tight-loop retry.
}
}submitTimeoutMs is a client-side guard: the SDK gates each create on the
server's submission-credit window (queuing client-side under backpressure rather
than flooding the gateway), and this bounds how long it waits for a credit before
rejecting with SubmissionTimeoutError. It is never sent on the wire. On timeout
the queued create is dropped so no credit slot leaks. Omit it (the default) to
wait indefinitely.
WebSocket-blocked infrastructure
The Falcon upgrade needs a WebSocket. Some infrastructure allows REST but not WebSockets — corporate forward proxies, HTTP-only ingress, and some L7 load balancers / WAFs. The SDK degrades to REST gracefully in every such case:
- Upgrade rejected (the common case — the proxy answers the
Upgradewith a normal HTTP response): the socket errors immediately, the client marks Falcon dead for its lifetime, logs a one-time warning, and routes everything through REST. - Upgrade blackholed (rarer — a transparent proxy completes the WebSocket
handshake but no
welcomeframe ever arrives): a handshake deadline (CAMUNDA_NANO_CONNECT_TIMEOUT_MS, default5000ms) rejects the connect withConnectTimeoutErrorso the client falls back to REST instead of hanging the first request. Set it to0to wait indefinitely (legacy behaviour). - Mid-session drop (a proxy severs an established socket): the in-flight
createProcessInstanceretries once over REST; job workers fall back to a REST worker.
To skip Falcon detection entirely (no topology probe, no socket), set the escape
hatch CAMUNDA_FORCE_REST=1 (or CAMUNDA_TRANSPORT=rest):
const client = createCamundaClient({
config: { CAMUNDA_REST_ADDRESS: "http://localhost:8080", CAMUNDA_FORCE_REST: 1 },
});Build & verify
npm install
npm run build
npm run verify # against a running Nano server on :8080upstream-ref/ holds the cloned upstream SDK source for reference; the published package is the thin wrapper in src/.
