@primero-ai/temporal-graph-tools 1.0.0
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/README.md +203 -0
- package/package.json +96 -0
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# @segundoai/temporal-graph-tools
|
|
2
|
+
|
|
3
|
+
TypeScript utilities for assembling Temporal workflows from plain activity
|
|
4
|
+
functions. Build a workflow plan, capture the generated source code, hydrate
|
|
5
|
+
activity implementations, and bundle everything for a worker without
|
|
6
|
+
hand-writing workflow files.
|
|
7
|
+
|
|
8
|
+
## Highlights
|
|
9
|
+
|
|
10
|
+
- Fluent builder for chaining sequential steps and running activity stages in
|
|
11
|
+
parallel with type-safe input/output propagation.
|
|
12
|
+
- Automatic activity key generation and optional per-activity configuration so
|
|
13
|
+
the generated workflow source stays deterministic.
|
|
14
|
+
- One-call bundler that validates multiple plans, hydrates activities, and
|
|
15
|
+
produces bundled workflow code ready for a worker.
|
|
16
|
+
- Emits Temporal workflow source that proxies activities and stitches staged
|
|
17
|
+
plans together.
|
|
18
|
+
- Low-level helpers remain available if you prefer to collect results, build
|
|
19
|
+
bundles, or hydrate activities manually.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @segundoai/temporal-graph-tools
|
|
25
|
+
# or
|
|
26
|
+
pnpm add @segundoai/temporal-graph-tools
|
|
27
|
+
# or
|
|
28
|
+
bun add @segundoai/temporal-graph-tools
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The package targets Node.js 18+ and ships ESM builds.
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import {
|
|
37
|
+
bundleWorkflows,
|
|
38
|
+
createActivity,
|
|
39
|
+
createWorkflowBuilder,
|
|
40
|
+
} from '@segundoai/temporal-graph-tools'
|
|
41
|
+
|
|
42
|
+
type FetchUserInput = { userId: string }
|
|
43
|
+
type FetchUserOutput = { profile: { id: string; name: string } }
|
|
44
|
+
|
|
45
|
+
const fetchUserProfile = createActivity(
|
|
46
|
+
async ({ userId }: FetchUserInput): Promise<FetchUserOutput> => {
|
|
47
|
+
return { profile: { id: userId, name: `User ${userId}` } }
|
|
48
|
+
},
|
|
49
|
+
{ id: 'fetchUserProfile' },
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
const sendWelcomeEmail = createActivity(
|
|
53
|
+
async ({ profile }: FetchUserOutput) => {
|
|
54
|
+
return { sent: true, name: profile.name }
|
|
55
|
+
},
|
|
56
|
+
{ id: 'sendWelcomeEmail' },
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
async function compile() {
|
|
60
|
+
const builder = createWorkflowBuilder<FetchUserInput>({
|
|
61
|
+
workflowName: 'customerOnboardingWorkflow',
|
|
62
|
+
proxyOptions: { startToCloseTimeout: '2 minutes' },
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const plan = builder.then(fetchUserProfile).then(sendWelcomeEmail).commit()
|
|
66
|
+
const { activities, workflowBundle } = await bundleWorkflows([plan])
|
|
67
|
+
|
|
68
|
+
// Use the emitted artifacts with a Temporal worker
|
|
69
|
+
return { workflowBundle, activities }
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
See the complete onboarding example in `examples/` for a richer flow that uses a
|
|
74
|
+
parallel stage and hooks a worker up to the generated artifacts.
|
|
75
|
+
|
|
76
|
+
### Example scripts
|
|
77
|
+
|
|
78
|
+
After installing dependencies you can explore the sample project:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
bun install
|
|
82
|
+
bun run worker # Starts a Temporal worker (needs a Temporal cluster)
|
|
83
|
+
bun run trigger-workflows # Launches the sample workflows through the client
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Set `TEMPORAL_ADDRESS`, `TEMPORAL_NAMESPACE`, and `TEMPORAL_TASK_QUEUE` in
|
|
87
|
+
`.env` to point the worker at your cluster. Use `bun run trigger-workflows` to
|
|
88
|
+
start the compiled workflows through the Temporal client once the worker is
|
|
89
|
+
running.
|
|
90
|
+
|
|
91
|
+
## Workflow builder API
|
|
92
|
+
|
|
93
|
+
### `createWorkflowBuilder<TInput>(options)`
|
|
94
|
+
|
|
95
|
+
Creates a `WorkflowBuilder` instance typed with the initial workflow input.
|
|
96
|
+
`options` must include:
|
|
97
|
+
|
|
98
|
+
- `workflowName`: Name of the exported workflow function. This value must be a
|
|
99
|
+
non-empty string and unique across the plans you later bundle.
|
|
100
|
+
|
|
101
|
+
Optional fields:
|
|
102
|
+
|
|
103
|
+
- `activitiesImportPath`: Module specifier used in the generated workflow import
|
|
104
|
+
(`'./activities'` by default).
|
|
105
|
+
- `proxyOptions`: Either a `@temporalio/workflow` `ActivityOptions` object or a
|
|
106
|
+
string literal dropped into the generated code. If omitted, a one-minute
|
|
107
|
+
`startToCloseTimeout` is emitted.
|
|
108
|
+
|
|
109
|
+
### `builder.then(activity, config?)`
|
|
110
|
+
|
|
111
|
+
Appends a sequential activity. The helper accepts either a bare activity
|
|
112
|
+
function or a value created with `createActivity`. When both inline and
|
|
113
|
+
preconfigured options are provided they are merged; `config.id` determines the
|
|
114
|
+
activity key.
|
|
115
|
+
|
|
116
|
+
### `builder.parallel([activityA, activityB, ...])`
|
|
117
|
+
|
|
118
|
+
Executes multiple activities against the current stage output and returns an
|
|
119
|
+
object keyed by each activity's `id`. A parallel stage can only be added after
|
|
120
|
+
at least one `then` call.
|
|
121
|
+
|
|
122
|
+
### `builder.commit(options?)`
|
|
123
|
+
|
|
124
|
+
Finalises the plan and returns:
|
|
125
|
+
|
|
126
|
+
- `workflowName`: The sanitized name of the exported workflow function.
|
|
127
|
+
- `workflowSource`: Generated TypeScript for the Temporal workflow function.
|
|
128
|
+
- `activities`: Map of activity keys to the original implementations and config
|
|
129
|
+
metadata. Implementations remain live references so any captured helpers stay
|
|
130
|
+
intact.
|
|
131
|
+
|
|
132
|
+
Additional `options` override the builder defaults for this invocation.
|
|
133
|
+
|
|
134
|
+
## Activity helpers
|
|
135
|
+
|
|
136
|
+
### `createActivity(activityFn, config?)`
|
|
137
|
+
|
|
138
|
+
Wraps an activity function so it can be reused with the builder. When a config
|
|
139
|
+
object is provided its `id` becomes the activity key; without options the
|
|
140
|
+
function name (or an auto-incremented fallback) is used. The helper is also
|
|
141
|
+
re-exported as `createActivity` for codebases that prefer plural naming.
|
|
142
|
+
|
|
143
|
+
## Workflow bundler utilities
|
|
144
|
+
|
|
145
|
+
### `bundleWorkflows(plans, options?)`
|
|
146
|
+
|
|
147
|
+
High-level helper that accepts one or more `WorkflowBuildResult` instances,
|
|
148
|
+
validates them, hydrates all activities, and bundles the generated workflow
|
|
149
|
+
sources. Returns:
|
|
150
|
+
|
|
151
|
+
- `activities`: Map of activity keys to runnable implementations.
|
|
152
|
+
- `workflowBundle`: Object containing the bundled JavaScript (in `code`) with an
|
|
153
|
+
inline source map.
|
|
154
|
+
|
|
155
|
+
Use this when you want a single call that prepares everything for a Temporal
|
|
156
|
+
worker. Under the hood it relies on the lower-level helpers documented below.
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
const plans = [onboardingPlan, greetingPlan]
|
|
160
|
+
const { activities, workflowBundle } = await bundleWorkflows(plans, {
|
|
161
|
+
filename: 'team-workflows.js',
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `collectWorkflowBuildResults(results)`
|
|
166
|
+
|
|
167
|
+
Merges the output of multiple `builder.commit()` calls into a single object.
|
|
168
|
+
Workflow names must be unique (duplicates are rejected), and activity IDs either
|
|
169
|
+
unique or guaranteed to have identical implementation/config pairs. The result
|
|
170
|
+
can feed directly into `instantiateActivities` or `buildWorkflowBundleCode`.
|
|
171
|
+
|
|
172
|
+
### `instantiateActivities(bundles)`
|
|
173
|
+
|
|
174
|
+
Accepts the `activities` map returned by `builder.commit()` (or
|
|
175
|
+
`collectWorkflowBuildResults`) and produces actual implementations. Each entry
|
|
176
|
+
is the original function reference supplied to the builder, so any captured
|
|
177
|
+
state remains intact.
|
|
178
|
+
|
|
179
|
+
### `buildWorkflowBundleCode(source, filename?)`
|
|
180
|
+
|
|
181
|
+
Runs Temporal's `bundleWorkflowCode` against the generated workflow source(s)
|
|
182
|
+
and returns bundled JavaScript with an inline source map. `source` can be:
|
|
183
|
+
|
|
184
|
+
- A raw workflow source string (preserved for backward compatibility).
|
|
185
|
+
- A single `WorkflowBuildResult` or `WorkflowSourceArtifact`.
|
|
186
|
+
- An array of `WorkflowSourceArtifact` values (for multiple workflows).
|
|
187
|
+
|
|
188
|
+
`filename` controls the `file` attribute recorded in the map. When omitted the
|
|
189
|
+
helper generates deterministic filenames per workflow and normalizes the map so
|
|
190
|
+
Temporal tooling can attribute stack traces correctly.
|
|
191
|
+
|
|
192
|
+
## Development
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
bun install
|
|
196
|
+
bun run type-check
|
|
197
|
+
bun run lint
|
|
198
|
+
bun run build
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@primero-ai/temporal-graph-tools",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Utilities for working with DAG workflows.",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"homepage": "https://github.com/primero-ai/temporal-graph-tools#readme",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/primero-ai/temporal-graph-tools/issues"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/primero-ai/temporal-graph-tools.git"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "sergio",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/src/index.d.ts",
|
|
20
|
+
"default": "./dist/src/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./bundler": {
|
|
23
|
+
"types": "./dist/src/bundler.d.ts",
|
|
24
|
+
"default": "./dist/src/bundler.js"
|
|
25
|
+
},
|
|
26
|
+
"./workflow-bundler": {
|
|
27
|
+
"types": "./dist/src/workflow-bundler.d.ts",
|
|
28
|
+
"default": "./dist/src/workflow-bundler.js"
|
|
29
|
+
},
|
|
30
|
+
"./workflow/*": {
|
|
31
|
+
"types": "./dist/src/workflow/*.d.ts",
|
|
32
|
+
"default": "./dist/src/workflow/*.js"
|
|
33
|
+
},
|
|
34
|
+
"./utils/*": {
|
|
35
|
+
"types": "./dist/src/utils/*.d.ts",
|
|
36
|
+
"default": "./dist/src/utils/*.js"
|
|
37
|
+
},
|
|
38
|
+
"./dist/src/*.js": {
|
|
39
|
+
"types": "./dist/src/*.d.ts",
|
|
40
|
+
"default": "./dist/src/*.js"
|
|
41
|
+
},
|
|
42
|
+
"./types": {
|
|
43
|
+
"types": "./dist/src/types.d.ts",
|
|
44
|
+
"default": "./dist/src/types.js"
|
|
45
|
+
},
|
|
46
|
+
"./package.json": "./package.json"
|
|
47
|
+
},
|
|
48
|
+
"main": "dist/src/index.js",
|
|
49
|
+
"types": "dist/src/index.d.ts",
|
|
50
|
+
"directories": {
|
|
51
|
+
"example": "examples"
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"dist"
|
|
55
|
+
],
|
|
56
|
+
"scripts": {
|
|
57
|
+
"with-env": "dotenv -e .env --",
|
|
58
|
+
"build": "tsc --project tsconfig.json",
|
|
59
|
+
"type-check": "tsc --noEmit --project tsconfig.json",
|
|
60
|
+
"lint": "eslint .",
|
|
61
|
+
"format": "prettier --write .",
|
|
62
|
+
"worker": "bun with-env tsx examples/worker.ts",
|
|
63
|
+
"trigger-workflows": "bun with-env bun examples/trigger-workflows.ts",
|
|
64
|
+
"clean": "rm -rf node_modules dist"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@temporalio/activity": "^1.13.1",
|
|
68
|
+
"@temporalio/client": "1.13.1",
|
|
69
|
+
"@temporalio/workflow": "1.13.1",
|
|
70
|
+
"@temporalio/worker": "1.13.1",
|
|
71
|
+
"lodash": "^4.17.21",
|
|
72
|
+
"zod": "4.1.12"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@types/lodash": "^4.14.202",
|
|
76
|
+
"tsx": "^4.19.2",
|
|
77
|
+
"@eslint/js": "^9.37.0",
|
|
78
|
+
"dotenv": "^17.2.1",
|
|
79
|
+
"dotenv-cli": "^10.0.0",
|
|
80
|
+
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
|
|
81
|
+
"@types/node": "^24.8.0",
|
|
82
|
+
"esbuild": "^0.24.0",
|
|
83
|
+
"eslint": "^9.37.0",
|
|
84
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
85
|
+
"eslint-plugin-import": "^2.32.0",
|
|
86
|
+
"prettier": "^3.6.2",
|
|
87
|
+
"prettier-plugin-tailwindcss": "^0.7.0",
|
|
88
|
+
"typescript": "^5.9.3",
|
|
89
|
+
"typescript-eslint": "^8.46.1"
|
|
90
|
+
},
|
|
91
|
+
"engines": {
|
|
92
|
+
"node": ">=18"
|
|
93
|
+
},
|
|
94
|
+
"module": "dist/src/index.js",
|
|
95
|
+
"packageManager": "bun@1.2.17"
|
|
96
|
+
}
|