Overview
What This Package Is For
Section titled “What This Package Is For”@lastshotlabs/slingshot-orchestration-temporal is the Temporal provider package for Slingshot
orchestration. It keeps the task/workflow authoring surface portable while delegating durable
execution, timers, retries, schedules, visibility, and worker coordination to Temporal.
When To Use It
Section titled “When To Use It”- Use it when orchestration runs must survive process restarts and execute across multiple machines.
- Use it when a workflow needs Temporal-native scheduling, signals, or queryable history.
- Prefer memory or SQLite for local-only development where you do not need external infrastructure.
- Prefer BullMQ when Redis is already your queue backbone and you do not need Temporal semantics.
Minimum Setup
Section titled “Minimum Setup”- A Temporal service or Temporal Cloud namespace
@temporalio/clienton the server side@temporalio/workeron the worker side@lastshotlabs/slingshot-orchestration-enginefor the portable task/workflow definitions
import { Client, Connection } from '@temporalio/client';import { z } from 'zod';import { defineTask, defineWorkflow, step, stepResult,} from '@lastshotlabs/slingshot-orchestration-engine';import { createTemporalOrchestrationAdapter, createTemporalOrchestrationWorker,} from '@lastshotlabs/slingshot-orchestration-temporal';
const sendWelcomeEmail = defineTask({ name: 'send-welcome-email', input: z.object({ email: z.string().email() }), output: z.object({ ok: z.boolean(), email: z.string().email() }), async handler(input) { return { ok: true, email: input.email }; },});
const onboardUser = defineWorkflow({ name: 'onboard-user', input: z.object({ email: z.string().email() }), output: z.object({ ok: z.boolean(), email: z.string().email() }), outputMapper(results) { return stepResult(results, 'send-email', sendWelcomeEmail)!; }, steps: [step('send-email', sendWelcomeEmail)],});
const connection = await Connection.connect({ address: 'localhost:7233' });const client = new Client({ connection, namespace: 'default' });
const adapter = createTemporalOrchestrationAdapter({ client, connection, namespace: 'default', workflowTaskQueue: 'slingshot-workflows', defaultActivityTaskQueue: 'email-activities', ownsConnection: false,});
const worker = await createTemporalOrchestrationWorker({ connection, namespace: 'default', workflowTaskQueue: 'slingshot-workflows', defaultActivityTaskQueue: 'email-activities', buildId: 'dev-build-1', definitionsModulePath: new URL('./definitions.ts', import.meta.url).pathname,});
void worker.run();What You Get
Section titled “What You Get”createTemporalOrchestrationAdapter()for server-side orchestration controlcreateTemporalOrchestrationWorker()for Node worker bootstrap- generated workflow-module support for handlers-directory and manifest worker bootstraps
- deterministic run ID derivation and Temporal search-attribute helpers
- adapter and worker validation schemas for plugin config
Enterprise fit
Section titled “Enterprise fit”- Choose Temporal when workflow state is a system of record, not just a job queue.
- Choose Temporal when long-running quoting, underwriting, ordering, approval, or fulfillment flows need durable timers, signals, and queryable execution history.
- Keep domain services outside the adapter. Temporal still runs the same portable task and workflow definitions from
@lastshotlabs/slingshot-orchestration-engine; your worker loads those definitions and task handlers call your real service layer.
Common Customization
Section titled “Common Customization”- Choose separate
workflowTaskQueueanddefaultActivityTaskQueuevalues when workflow execution and activity execution should scale independently. - Use
namespaceper environment or deployment boundary. - Use
taskNamesandworkflowNameson the worker when a process should poll only part of the orchestration surface. - Set
generatedWorkflowsDirwhen you want generated workflow bundles in a predictable location. - Attach an
eventSinkif workflow/task lifecycle events should be mirrored back into Slingshot.
Gotchas
Section titled “Gotchas”- Temporal workers must run on real Node.js. Bun is not supported for worker startup.
- The adapter does not start workers for you. Server and worker lifecycle are intentionally separate.
- If the adapter owns the Temporal connection, make sure shutdown responsibility is clear.
- Manifest mode still needs task/workflow code in handler modules or definitions modules.
- Search attributes and visibility depend on the Temporal cluster being configured correctly.
Key Files
Section titled “Key Files”packages/slingshot-orchestration-temporal/src/index.tspackages/slingshot-orchestration-temporal/src/adapter.tspackages/slingshot-orchestration-temporal/src/worker.tspackages/slingshot-orchestration-temporal/src/workflowModuleGenerator.ts