Install
Replace the checkout path below. Run the final install in your application directory. The worker build checks generated protocol files against the checkout’s protocol sources.
npm --prefix /path/to/aion/sdks/typescript/aion-client install
npm --prefix /path/to/aion/sdks/typescript/aion-client run build
npm --prefix /path/to/aion/sdks/typescript/aion-worker install
npm --prefix /path/to/aion/sdks/typescript/aion-worker run build
npm install /path/to/aion/sdks/typescript/aion-client /path/to/aion/sdks/typescript/aion-worker
Read workflows
This ESM example lists workflows through the local HTTP listener. Compile the TypeScript in your application’s build.
import { connect } from "@aion/client";
const client = await connect({
endpoint: "http://127.0.0.1:8080",
namespace: "default",
tls: { enabled: false },
});
const page = await client.list({
sort: { field: "started_at", direction: "desc" },
limit: 20,
});
console.log(page.items, page.count, page.next_cursor);
-
connect - HTTP endpoint; namespace, auth and TLS options. The built-in fetch transport handles operations; Node WebSocket handles subscriptions.
-
start / startRaw - API accepts ordinary JSON or explicit Payload input and an idempotencyKey. The built-in HTTP start path has the incompatibilities below; use direct HTTP or the Python caller for main.
-
signal / signalRaw - Named signal with ordinary JSON or explicit payload, scoped by workflowId and optional runId.
-
query / queryRaw - Named live query with optional timeoutMs. Current implementation sends the query name and identity only; use no-argument queries through this SDK.
-
cancel / describe - API methods supply an optional cancel reason or includeHistory and runId for describe. Workflow cancellation reaches active descendants. The default transport passes protocol ID wrappers; use direct HTTP when the server expects UUID strings.
-
list - ListOptions has flat namespace, filter, sort, limit and cursor fields. Sort and limit are required. Repeat the same filter and sort with the next_cursor.
-
WorkflowHandle - Retains workflowId, runId and namespace; exposes signal, query, cancel, describe and subscribe, including raw payload variants.
-
subscribe - handle.subscribe({maxReconnects}) yields an async event iterator. Reconnection resumes at the last delivered sequence plus one. The public handle method supplies no initial cursor.
The client maps failures to typed errors including InvalidArgumentError, AlreadyExistsError, QueryTimeoutError and ServerError.
Starting through HTTP
On main, the built-in transport’s start path has incompatible payload and response shapes. Ordinary JSON start sends application/json in an envelope where the HTTP handler expects Json. An explicit core payload can start the run, but the client then rejects the response because it expects wrapped UUIDs. Use the direct HTTP start request or the Python caller for this server.
-
Payload - sdks/typescript/aion-client/src/payload.ts:1–48 writes application/json for JSON payloads. crates/aion-server/src/api/http/payload.rs:19–28 recognizes the core Json tag.
-
Response - sdks/typescript/aion-client/src/client.ts:559–570 expects workflow_id.uuid and run_id.uuid. crates/aion-server/src/api/http/clean_dtos.rs:333–347 serializes core IDs as UUID strings.
-
Other operations - The built-in transport forwards protocol requests directly in sdks/typescript/aion-client/src/client.ts:755–785. Its ID and payload envelopes need to agree with the selected server. Use the direct HTTP reference when they differ.
Serve an activity
Deploy a workflow whose action name and schemas match this worker. The greeting tutorial uses pure workflow steps; this handler illustrates a separate external activity.
import { Worker, defineActivity } from "@aion/worker";
const greet = defineActivity<{ name: string }, { message: string }>(
"examples.greet",
async (input) => ({ message: `Hello, ${input.name}!` }),
{
contract: {
input: {
type: "object", required: ["name"],
properties: { name: { type: "string" } },
},
output: {
type: "object", required: ["message"],
properties: { message: { type: "string" } },
},
},
},
);
await new Worker({
endpoint: "127.0.0.1:50051",
namespaces: ["default"], subject: "worker",
taskQueue: "default", identity: "typescript-worker-1",
maxConcurrency: 4,
reconnect: { initialDelayMs: 100, maxDelayMs: 5000, maxAttempts: 10 },
}, [greet]).run();
-
defineActivity - Declare the name, async handler and contract. Supply the output JSON schema; an omitted input schema advertises acceptance of any JSON. Schemas describe the registration contract. Input JSON is parsed and cast to the handler type; add validation in the handler when needed.
-
Worker - new Worker(config, activities).run() connects the built-in gRPC transport and serves the declared handlers.
-
WorkerConfig - Set endpoint, namespaces, subject, taskQueue, identity, maxConcurrency and reconnect. Optional node defaults to hostname. Set the bearer/transport credentials for the deployment.
-
Reconnect - initialDelayMs, maxDelayMs and maxAttempts; optional connectTimeoutMs and registrationTimeoutMs must be positive finite milliseconds.
-
ActivityContext - Carries workflowId, runId, activityId, attempt and idempotencyKey. heartbeat() reports progress. isCancelled() reads the cancellation flag; cancelled() waits for it.
-
Failures - RetryableError and TerminalError classify handler failures. Declare contracts for every activity in a registration, or use an uncontracted queue; a partial contract list is refused.
The SDK echoes run identity and the opaque completion token when reporting a result. Use the context’s idempotency key to deduplicate external effects across repeat deliveries.
The public exports are in each package’s src/index.ts. The caller’s client.ts and handle.ts define operations; the worker’s activity.ts, context.ts and session.ts define registration and execution.