@workflow/core 4.0.1-beta.4 → 4.0.1-beta.41

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.
Files changed (147) hide show
  1. package/LICENSE.md +201 -21
  2. package/dist/builtins.js +1 -1
  3. package/dist/class-serialization.d.ts +26 -0
  4. package/dist/class-serialization.d.ts.map +1 -0
  5. package/dist/class-serialization.js +66 -0
  6. package/dist/create-hook.js +1 -1
  7. package/dist/define-hook.d.ts +40 -25
  8. package/dist/define-hook.d.ts.map +1 -1
  9. package/dist/define-hook.js +22 -27
  10. package/dist/events-consumer.js +1 -1
  11. package/dist/flushable-stream.d.ts +82 -0
  12. package/dist/flushable-stream.d.ts.map +1 -0
  13. package/dist/flushable-stream.js +214 -0
  14. package/dist/global.d.ts +12 -2
  15. package/dist/global.d.ts.map +1 -1
  16. package/dist/global.js +32 -8
  17. package/dist/index.d.ts +3 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +3 -2
  20. package/dist/logger.js +1 -1
  21. package/dist/observability.d.ts +60 -0
  22. package/dist/observability.d.ts.map +1 -1
  23. package/dist/observability.js +175 -19
  24. package/dist/parse-name.d.ts +12 -0
  25. package/dist/parse-name.d.ts.map +1 -1
  26. package/dist/parse-name.js +28 -3
  27. package/dist/private.d.ts +10 -1
  28. package/dist/private.d.ts.map +1 -1
  29. package/dist/private.js +6 -1
  30. package/dist/runtime/helpers.d.ts +52 -0
  31. package/dist/runtime/helpers.d.ts.map +1 -0
  32. package/dist/runtime/helpers.js +264 -0
  33. package/dist/runtime/resume-hook.d.ts +16 -11
  34. package/dist/runtime/resume-hook.d.ts.map +1 -1
  35. package/dist/runtime/resume-hook.js +76 -64
  36. package/dist/runtime/start.d.ts +10 -0
  37. package/dist/runtime/start.d.ts.map +1 -1
  38. package/dist/runtime/start.js +56 -45
  39. package/dist/runtime/step-handler.d.ts +7 -0
  40. package/dist/runtime/step-handler.d.ts.map +1 -0
  41. package/dist/runtime/step-handler.js +353 -0
  42. package/dist/runtime/suspension-handler.d.ts +20 -0
  43. package/dist/runtime/suspension-handler.d.ts.map +1 -0
  44. package/dist/runtime/suspension-handler.js +179 -0
  45. package/dist/runtime/world.d.ts.map +1 -1
  46. package/dist/runtime/world.js +22 -21
  47. package/dist/runtime.d.ts +3 -7
  48. package/dist/runtime.d.ts.map +1 -1
  49. package/dist/runtime.js +76 -334
  50. package/dist/schemas.d.ts +1 -15
  51. package/dist/schemas.d.ts.map +1 -1
  52. package/dist/schemas.js +2 -15
  53. package/dist/serialization.d.ts +74 -10
  54. package/dist/serialization.d.ts.map +1 -1
  55. package/dist/serialization.js +295 -56
  56. package/dist/sleep.d.ts +33 -0
  57. package/dist/sleep.d.ts.map +1 -0
  58. package/dist/sleep.js +10 -0
  59. package/dist/source-map.d.ts +10 -0
  60. package/dist/source-map.d.ts.map +1 -0
  61. package/dist/source-map.js +56 -0
  62. package/dist/step/context-storage.d.ts +2 -0
  63. package/dist/step/context-storage.d.ts.map +1 -1
  64. package/dist/step/context-storage.js +1 -1
  65. package/dist/step/get-closure-vars.d.ts +9 -0
  66. package/dist/step/get-closure-vars.d.ts.map +1 -0
  67. package/dist/step/get-closure-vars.js +16 -0
  68. package/dist/step/get-step-metadata.js +1 -1
  69. package/dist/step/get-workflow-metadata.js +1 -1
  70. package/dist/step/writable-stream.d.ts +14 -0
  71. package/dist/step/writable-stream.d.ts.map +1 -0
  72. package/dist/step/writable-stream.js +30 -0
  73. package/dist/step.d.ts +1 -1
  74. package/dist/step.d.ts.map +1 -1
  75. package/dist/step.js +51 -11
  76. package/dist/symbols.d.ts +7 -0
  77. package/dist/symbols.d.ts.map +1 -1
  78. package/dist/symbols.js +8 -1
  79. package/dist/telemetry/semantic-conventions.d.ts +66 -38
  80. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  81. package/dist/telemetry/semantic-conventions.js +16 -3
  82. package/dist/telemetry.d.ts +8 -4
  83. package/dist/telemetry.d.ts.map +1 -1
  84. package/dist/telemetry.js +39 -6
  85. package/dist/types.d.ts +0 -7
  86. package/dist/types.d.ts.map +1 -1
  87. package/dist/types.js +1 -26
  88. package/dist/util.d.ts +9 -27
  89. package/dist/util.d.ts.map +1 -1
  90. package/dist/util.js +37 -44
  91. package/dist/vm/index.js +2 -2
  92. package/dist/vm/uuid.js +1 -1
  93. package/dist/workflow/create-hook.js +1 -1
  94. package/dist/workflow/define-hook.d.ts +3 -3
  95. package/dist/workflow/define-hook.d.ts.map +1 -1
  96. package/dist/workflow/define-hook.js +1 -1
  97. package/dist/workflow/get-workflow-metadata.js +1 -1
  98. package/dist/workflow/hook.d.ts.map +1 -1
  99. package/dist/workflow/hook.js +6 -9
  100. package/dist/workflow/index.d.ts +1 -0
  101. package/dist/workflow/index.d.ts.map +1 -1
  102. package/dist/workflow/index.js +2 -1
  103. package/dist/workflow/sleep.d.ts +4 -0
  104. package/dist/workflow/sleep.d.ts.map +1 -0
  105. package/dist/workflow/sleep.js +54 -0
  106. package/dist/workflow/writable-stream.js +1 -1
  107. package/dist/workflow.d.ts.map +1 -1
  108. package/dist/workflow.js +60 -9
  109. package/dist/writable-stream.d.ts +5 -4
  110. package/dist/writable-stream.d.ts.map +1 -1
  111. package/dist/writable-stream.js +7 -6
  112. package/package.json +23 -18
  113. package/dist/builtins.js.map +0 -1
  114. package/dist/create-hook.js.map +0 -1
  115. package/dist/define-hook.js.map +0 -1
  116. package/dist/events-consumer.js.map +0 -1
  117. package/dist/global.js.map +0 -1
  118. package/dist/index.js.map +0 -1
  119. package/dist/logger.js.map +0 -1
  120. package/dist/observability.js.map +0 -1
  121. package/dist/parse-name.js.map +0 -1
  122. package/dist/private.js.map +0 -1
  123. package/dist/runtime/resume-hook.js.map +0 -1
  124. package/dist/runtime/start.js.map +0 -1
  125. package/dist/runtime/world.js.map +0 -1
  126. package/dist/runtime.js.map +0 -1
  127. package/dist/schemas.js.map +0 -1
  128. package/dist/serialization.js.map +0 -1
  129. package/dist/step/context-storage.js.map +0 -1
  130. package/dist/step/get-step-metadata.js.map +0 -1
  131. package/dist/step/get-workflow-metadata.js.map +0 -1
  132. package/dist/step.js.map +0 -1
  133. package/dist/symbols.js.map +0 -1
  134. package/dist/telemetry/semantic-conventions.js.map +0 -1
  135. package/dist/telemetry.js.map +0 -1
  136. package/dist/types.js.map +0 -1
  137. package/dist/util.js.map +0 -1
  138. package/dist/vm/index.js.map +0 -1
  139. package/dist/vm/uuid.js.map +0 -1
  140. package/dist/workflow/create-hook.js.map +0 -1
  141. package/dist/workflow/define-hook.js.map +0 -1
  142. package/dist/workflow/get-workflow-metadata.js.map +0 -1
  143. package/dist/workflow/hook.js.map +0 -1
  144. package/dist/workflow/index.js.map +0 -1
  145. package/dist/workflow/writable-stream.js.map +0 -1
  146. package/dist/workflow.js.map +0 -1
  147. package/dist/writable-stream.js.map +0 -1
@@ -0,0 +1,264 @@
1
+ import { HealthCheckPayloadSchema } from '@workflow/world';
2
+ import { monotonicFactory } from 'ulid';
3
+ import * as Attribute from '../telemetry/semantic-conventions.js';
4
+ import { getSpanKind, trace } from '../telemetry.js';
5
+ import { getWorld } from './world.js';
6
+ /** Default timeout for health checks in milliseconds */
7
+ const DEFAULT_HEALTH_CHECK_TIMEOUT = 30_000;
8
+ const generateId = monotonicFactory();
9
+ /**
10
+ * Returns the stream name for a health check with the given correlation ID.
11
+ */
12
+ function getHealthCheckStreamName(correlationId) {
13
+ return `__health_check__${correlationId}`;
14
+ }
15
+ /**
16
+ * Checks if the given message is a health check payload.
17
+ * If so, returns the parsed payload. Otherwise returns undefined.
18
+ */
19
+ export function parseHealthCheckPayload(message) {
20
+ const result = HealthCheckPayloadSchema.safeParse(message);
21
+ if (result.success) {
22
+ return result.data;
23
+ }
24
+ return undefined;
25
+ }
26
+ /**
27
+ * Generates a fake runId for health check streams.
28
+ * This runId passes server validation but is not associated with a real run.
29
+ * The server skips run validation for streams starting with `__health_check__`.
30
+ */
31
+ function generateHealthCheckRunId() {
32
+ return `wrun_${generateId()}`;
33
+ }
34
+ /**
35
+ * Handles a health check message by writing the result to the world's stream.
36
+ * The caller can listen to this stream to get the health check response.
37
+ *
38
+ * @param healthCheck - The parsed health check payload
39
+ * @param endpoint - Which endpoint is responding ('workflow' or 'step')
40
+ */
41
+ export async function handleHealthCheckMessage(healthCheck, endpoint) {
42
+ const world = getWorld();
43
+ const streamName = getHealthCheckStreamName(healthCheck.correlationId);
44
+ const response = JSON.stringify({
45
+ healthy: true,
46
+ endpoint,
47
+ correlationId: healthCheck.correlationId,
48
+ timestamp: Date.now(),
49
+ });
50
+ // Use a fake runId that passes validation.
51
+ // The stream name includes the correlationId for identification.
52
+ // The server skips run validation for health check streams.
53
+ const fakeRunId = generateHealthCheckRunId();
54
+ await world.writeToStream(streamName, fakeRunId, response);
55
+ await world.closeStream(streamName, fakeRunId);
56
+ }
57
+ /**
58
+ * Performs a health check by sending a message through the queue pipeline
59
+ * and verifying it is processed by the specified endpoint.
60
+ *
61
+ * This function bypasses Deployment Protection on Vercel because it goes
62
+ * through the queue infrastructure rather than direct HTTP.
63
+ *
64
+ * @param world - The World instance to use for the health check
65
+ * @param endpoint - Which endpoint to health check: 'workflow' or 'step'
66
+ * @param options - Optional configuration for the health check
67
+ * @returns Promise resolving to health check result
68
+ */
69
+ // Poll interval for health check retries (ms)
70
+ const HEALTH_CHECK_POLL_INTERVAL = 100;
71
+ // Per-read timeout to prevent blocking forever on local world's EventEmitter
72
+ // (which doesn't work across processes)
73
+ const HEALTH_CHECK_READ_TIMEOUT = 500;
74
+ /**
75
+ * Read chunks from a stream with a timeout per read operation.
76
+ * Returns { chunks, timedOut } where timedOut indicates if a read timed out.
77
+ */
78
+ async function readStreamWithTimeout(reader, readTimeout) {
79
+ const chunks = [];
80
+ let done = false;
81
+ let timedOut = false;
82
+ while (!done && !timedOut) {
83
+ const readPromise = reader.read();
84
+ const timeoutPromise = new Promise((resolve) => setTimeout(() => {
85
+ timedOut = true;
86
+ resolve({ done: true, value: undefined });
87
+ }, readTimeout));
88
+ const result = await Promise.race([readPromise, timeoutPromise]);
89
+ done = result.done;
90
+ if (result.value)
91
+ chunks.push(result.value);
92
+ }
93
+ return { chunks, timedOut };
94
+ }
95
+ /**
96
+ * Parse and validate a health check response from stream chunks.
97
+ * Returns the parsed response or null if invalid.
98
+ */
99
+ function parseHealthCheckResponse(chunks) {
100
+ if (chunks.length === 0)
101
+ return null;
102
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
103
+ const combined = new Uint8Array(totalLength);
104
+ let offset = 0;
105
+ for (const chunk of chunks) {
106
+ combined.set(chunk, offset);
107
+ offset += chunk.length;
108
+ }
109
+ const responseText = new TextDecoder().decode(combined);
110
+ let response;
111
+ try {
112
+ response = JSON.parse(responseText);
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ if (typeof response !== 'object' ||
118
+ response === null ||
119
+ !('healthy' in response) ||
120
+ typeof response.healthy !== 'boolean') {
121
+ return null;
122
+ }
123
+ return { healthy: response.healthy };
124
+ }
125
+ export async function healthCheck(world, endpoint, options) {
126
+ const timeout = options?.timeout ?? DEFAULT_HEALTH_CHECK_TIMEOUT;
127
+ const correlationId = `hc_${generateId()}`;
128
+ const streamName = getHealthCheckStreamName(correlationId);
129
+ const queueName = endpoint === 'workflow'
130
+ ? '__wkf_workflow_health_check'
131
+ : '__wkf_step_health_check';
132
+ const startTime = Date.now();
133
+ try {
134
+ await world.queue(queueName, {
135
+ __healthCheck: true,
136
+ correlationId,
137
+ });
138
+ while (Date.now() - startTime < timeout) {
139
+ try {
140
+ const stream = await world.readFromStream(streamName);
141
+ const reader = stream.getReader();
142
+ const { chunks, timedOut } = await readStreamWithTimeout(reader, HEALTH_CHECK_READ_TIMEOUT);
143
+ if (timedOut) {
144
+ try {
145
+ reader.cancel();
146
+ }
147
+ catch {
148
+ // Ignore cancel errors
149
+ }
150
+ await new Promise((resolve) => setTimeout(resolve, HEALTH_CHECK_POLL_INTERVAL));
151
+ continue;
152
+ }
153
+ const response = parseHealthCheckResponse(chunks);
154
+ if (response) {
155
+ return response;
156
+ }
157
+ await new Promise((resolve) => setTimeout(resolve, HEALTH_CHECK_POLL_INTERVAL));
158
+ }
159
+ catch {
160
+ await new Promise((resolve) => setTimeout(resolve, HEALTH_CHECK_POLL_INTERVAL));
161
+ }
162
+ }
163
+ return {
164
+ healthy: false,
165
+ error: `Health check timed out after ${timeout}ms`,
166
+ };
167
+ }
168
+ catch (error) {
169
+ return {
170
+ healthy: false,
171
+ error: error instanceof Error ? error.message : String(error),
172
+ };
173
+ }
174
+ }
175
+ /**
176
+ * Loads all workflow run events by iterating through all pages of paginated results.
177
+ * This ensures that *all* events are loaded into memory before running the workflow.
178
+ * Events must be in chronological order (ascending) for proper workflow replay.
179
+ */
180
+ export async function getAllWorkflowRunEvents(runId) {
181
+ const allEvents = [];
182
+ let cursor = null;
183
+ let hasMore = true;
184
+ const world = getWorld();
185
+ while (hasMore) {
186
+ // TODO: we're currently loading all the data with resolveRef behaviour. We need to update this
187
+ // to lazyload the data from the world instead so that we can optimize and make the event log loading
188
+ // much faster and memory efficient
189
+ const response = await world.events.list({
190
+ runId,
191
+ pagination: {
192
+ sortOrder: 'asc', // Required: events must be in chronological order for replay
193
+ cursor: cursor ?? undefined,
194
+ },
195
+ });
196
+ allEvents.push(...response.data);
197
+ hasMore = response.hasMore;
198
+ cursor = response.cursor;
199
+ }
200
+ return allEvents;
201
+ }
202
+ /**
203
+ * CORS headers for health check responses.
204
+ * Allows the observability UI to check endpoint health from a different origin.
205
+ */
206
+ const HEALTH_CHECK_CORS_HEADERS = {
207
+ 'Access-Control-Allow-Origin': '*',
208
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS, GET, HEAD',
209
+ 'Access-Control-Allow-Headers': 'Content-Type',
210
+ };
211
+ /**
212
+ * Wraps a request/response handler and adds a health check "mode"
213
+ * based on the presence of a `__health` query parameter.
214
+ */
215
+ export function withHealthCheck(handler) {
216
+ return async (req) => {
217
+ const url = new URL(req.url);
218
+ const isHealthCheck = url.searchParams.has('__health');
219
+ if (isHealthCheck) {
220
+ // Handle CORS preflight for health check
221
+ if (req.method === 'OPTIONS') {
222
+ return new Response(null, {
223
+ status: 204,
224
+ headers: HEALTH_CHECK_CORS_HEADERS,
225
+ });
226
+ }
227
+ return new Response(`Workflow DevKit "${url.pathname}" endpoint is healthy`, {
228
+ status: 200,
229
+ headers: {
230
+ 'Content-Type': 'text/plain',
231
+ ...HEALTH_CHECK_CORS_HEADERS,
232
+ },
233
+ });
234
+ }
235
+ return await handler(req);
236
+ };
237
+ }
238
+ /**
239
+ * Queues a message to the specified queue with tracing.
240
+ */
241
+ export async function queueMessage(world, ...args) {
242
+ const queueName = args[0];
243
+ await trace('queueMessage', {
244
+ attributes: Attribute.QueueName(queueName),
245
+ kind: await getSpanKind('PRODUCER'),
246
+ }, async (span) => {
247
+ const { messageId } = await world.queue(...args);
248
+ span?.setAttributes(Attribute.QueueMessageId(messageId));
249
+ });
250
+ }
251
+ /**
252
+ * Calculates the queue overhead time in milliseconds for a given message.
253
+ */
254
+ export function getQueueOverhead(message) {
255
+ if (!message.requestedAt)
256
+ return;
257
+ try {
258
+ return Attribute.QueueOverheadMs(Date.now() - message.requestedAt.getTime());
259
+ }
260
+ catch {
261
+ return;
262
+ }
263
+ }
264
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2hlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxTQUFTLE1BQU0sc0NBQXNDLENBQUM7QUFDbEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXRDLHdEQUF3RDtBQUN4RCxNQUFNLDRCQUE0QixHQUFHLE1BQU0sQ0FBQztBQUU1QyxNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO0FBRXRDOztHQUVHO0FBQ0gsU0FBUyx3QkFBd0IsQ0FBQyxhQUFxQjtJQUNyRCxPQUFPLG1CQUFtQixhQUFhLEVBQUUsQ0FBQztBQUM1QyxDQUFDO0FBV0Q7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxPQUFnQjtJQUVoQixNQUFNLE1BQU0sR0FBRyx3QkFBd0IsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0QsSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkIsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsd0JBQXdCO0lBQy9CLE9BQU8sUUFBUSxVQUFVLEVBQUUsRUFBRSxDQUFDO0FBQ2hDLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLHdCQUF3QixDQUM1QyxXQUErQixFQUMvQixRQUE2QjtJQUU3QixNQUFNLEtBQUssR0FBRyxRQUFRLEVBQUUsQ0FBQztJQUN6QixNQUFNLFVBQVUsR0FBRyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDdkUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM5QixPQUFPLEVBQUUsSUFBSTtRQUNiLFFBQVE7UUFDUixhQUFhLEVBQUUsV0FBVyxDQUFDLGFBQWE7UUFDeEMsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7S0FDdEIsQ0FBQyxDQUFDO0lBQ0gsMkNBQTJDO0lBQzNDLGlFQUFpRTtJQUNqRSw0REFBNEQ7SUFDNUQsTUFBTSxTQUFTLEdBQUcsd0JBQXdCLEVBQUUsQ0FBQztJQUM3QyxNQUFNLEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMzRCxNQUFNLEtBQUssQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2pELENBQUM7QUFTRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILDhDQUE4QztBQUM5QyxNQUFNLDBCQUEwQixHQUFHLEdBQUcsQ0FBQztBQUN2Qyw2RUFBNkU7QUFDN0Usd0NBQXdDO0FBQ3hDLE1BQU0seUJBQXlCLEdBQUcsR0FBRyxDQUFDO0FBRXRDOzs7R0FHRztBQUNILEtBQUssVUFBVSxxQkFBcUIsQ0FDbEMsTUFBK0MsRUFDL0MsV0FBbUI7SUFFbkIsTUFBTSxNQUFNLEdBQWlCLEVBQUUsQ0FBQztJQUNoQyxJQUFJLElBQUksR0FBRyxLQUFLLENBQUM7SUFDakIsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRXJCLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMxQixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbEMsTUFBTSxjQUFjLEdBQUcsSUFBSSxPQUFPLENBQ2hDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDVixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNoQixPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FDbEIsQ0FBQztRQUVGLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ25CLElBQUksTUFBTSxDQUFDLEtBQUs7WUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUM5QixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyx3QkFBd0IsQ0FDL0IsTUFBb0I7SUFFcEIsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUVyQyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekUsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDN0MsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUMzQixRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUN6QixDQUFDO0lBQ0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFeEQsSUFBSSxRQUFpQixDQUFDO0lBQ3RCLElBQUksQ0FBQztRQUNILFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUNFLE9BQU8sUUFBUSxLQUFLLFFBQVE7UUFDNUIsUUFBUSxLQUFLLElBQUk7UUFDakIsQ0FBQyxDQUFDLFNBQVMsSUFBSSxRQUFRLENBQUM7UUFDeEIsT0FBUSxRQUFpQyxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQy9ELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLEVBQUUsT0FBTyxFQUFHLFFBQWlDLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDakUsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsV0FBVyxDQUMvQixLQUFZLEVBQ1osUUFBNkIsRUFDN0IsT0FBNEI7SUFFNUIsTUFBTSxPQUFPLEdBQUcsT0FBTyxFQUFFLE9BQU8sSUFBSSw0QkFBNEIsQ0FBQztJQUNqRSxNQUFNLGFBQWEsR0FBRyxNQUFNLFVBQVUsRUFBRSxFQUFFLENBQUM7SUFDM0MsTUFBTSxVQUFVLEdBQUcsd0JBQXdCLENBQUMsYUFBYSxDQUFDLENBQUM7SUFFM0QsTUFBTSxTQUFTLEdBQ2IsUUFBUSxLQUFLLFVBQVU7UUFDckIsQ0FBQyxDQUFDLDZCQUE2QjtRQUMvQixDQUFDLENBQUMseUJBQXlCLENBQUM7SUFFaEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBRTdCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7WUFDM0IsYUFBYSxFQUFFLElBQUk7WUFDbkIsYUFBYTtTQUNkLENBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxPQUFPLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxxQkFBcUIsQ0FDdEQsTUFBTSxFQUNOLHlCQUF5QixDQUMxQixDQUFDO2dCQUVGLElBQUksUUFBUSxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDO3dCQUNILE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDbEIsQ0FBQztvQkFBQyxNQUFNLENBQUM7d0JBQ1AsdUJBQXVCO29CQUN6QixDQUFDO29CQUNELE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUM1QixVQUFVLENBQUMsT0FBTyxFQUFFLDBCQUEwQixDQUFDLENBQ2hELENBQUM7b0JBQ0YsU0FBUztnQkFDWCxDQUFDO2dCQUVELE1BQU0sUUFBUSxHQUFHLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLFFBQVEsRUFBRSxDQUFDO29CQUNiLE9BQU8sUUFBUSxDQUFDO2dCQUNsQixDQUFDO2dCQUVELE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUM1QixVQUFVLENBQUMsT0FBTyxFQUFFLDBCQUEwQixDQUFDLENBQ2hELENBQUM7WUFDSixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUM1QixVQUFVLENBQUMsT0FBTyxFQUFFLDBCQUEwQixDQUFDLENBQ2hELENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU87WUFDTCxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxnQ0FBZ0MsT0FBTyxJQUFJO1NBQ25ELENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE9BQU87WUFDTCxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1NBQzlELENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLHVCQUF1QixDQUFDLEtBQWE7SUFDekQsTUFBTSxTQUFTLEdBQVksRUFBRSxDQUFDO0lBQzlCLElBQUksTUFBTSxHQUFrQixJQUFJLENBQUM7SUFDakMsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBRW5CLE1BQU0sS0FBSyxHQUFHLFFBQVEsRUFBRSxDQUFDO0lBQ3pCLE9BQU8sT0FBTyxFQUFFLENBQUM7UUFDZiwrRkFBK0Y7UUFDL0YscUdBQXFHO1FBQ3JHLG1DQUFtQztRQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ3ZDLEtBQUs7WUFDTCxVQUFVLEVBQUU7Z0JBQ1YsU0FBUyxFQUFFLEtBQUssRUFBRSw2REFBNkQ7Z0JBQy9FLE1BQU0sRUFBRSxNQUFNLElBQUksU0FBUzthQUM1QjtTQUNGLENBQUMsQ0FBQztRQUVILFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFDM0IsTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLHlCQUF5QixHQUFHO0lBQ2hDLDZCQUE2QixFQUFFLEdBQUc7SUFDbEMsOEJBQThCLEVBQUUsMEJBQTBCO0lBQzFELDhCQUE4QixFQUFFLGNBQWM7Q0FDL0MsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQzdCLE9BQTRDO0lBRTVDLE9BQU8sS0FBSyxFQUFFLEdBQVksRUFBRSxFQUFFO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QixNQUFNLGFBQWEsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN2RCxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ2xCLHlDQUF5QztZQUN6QyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzdCLE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFO29CQUN4QixNQUFNLEVBQUUsR0FBRztvQkFDWCxPQUFPLEVBQUUseUJBQXlCO2lCQUNuQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQ0QsT0FBTyxJQUFJLFFBQVEsQ0FDakIsb0JBQW9CLEdBQUcsQ0FBQyxRQUFRLHVCQUF1QixFQUN2RDtnQkFDRSxNQUFNLEVBQUUsR0FBRztnQkFDWCxPQUFPLEVBQUU7b0JBQ1AsY0FBYyxFQUFFLFlBQVk7b0JBQzVCLEdBQUcseUJBQXlCO2lCQUM3QjthQUNGLENBQ0YsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsWUFBWSxDQUNoQyxLQUFZLEVBQ1osR0FBRyxJQUFvQztJQUV2QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsTUFBTSxLQUFLLENBQ1QsY0FBYyxFQUNkO1FBQ0UsVUFBVSxFQUFFLFNBQVMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQzFDLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQyxVQUFVLENBQUM7S0FDcEMsRUFDRCxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDYixNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDakQsSUFBSSxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQyxDQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsT0FBK0I7SUFDOUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXO1FBQUUsT0FBTztJQUNqQyxJQUFJLENBQUM7UUFDSCxPQUFPLFNBQVMsQ0FBQyxlQUFlLENBQzlCLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUMzQyxDQUFDO0lBQ0osQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU87SUFDVCxDQUFDO0FBQ0gsQ0FBQyJ9
@@ -13,9 +13,10 @@ export declare function getHookByToken(token: string): Promise<Hook>;
13
13
  * This function is called externally (e.g., from an API route or server action)
14
14
  * to send data to a hook and resume the associated workflow run.
15
15
  *
16
- * @param token - The unique token identifying the hook
16
+ * @param tokenOrHook - The unique token identifying the hook, or the hook object itself
17
17
  * @param payload - The data payload to send to the hook
18
- * @returns Promise resolving to an object with the runId, or null if the hook doesn't exist
18
+ * @returns Promise resolving to the hook
19
+ * @throws Error if the hook is not found or if there's an error during the process
19
20
  *
20
21
  * @example
21
22
  *
@@ -25,17 +26,17 @@ export declare function getHookByToken(token: string): Promise<Hook>;
25
26
  *
26
27
  * export async function POST(request: Request) {
27
28
  * const { token, data } = await request.json();
28
- * const result = await resumeHook(token, data);
29
29
  *
30
- * if (!result) {
30
+ * try {
31
+ * const hook = await resumeHook(token, data);
32
+ * return Response.json({ runId: hook.runId });
33
+ * } catch (error) {
31
34
  * return new Response('Hook not found', { status: 404 });
32
35
  * }
33
- *
34
- * return Response.json({ runId: result.runId });
35
36
  * }
36
37
  * ```
37
38
  */
38
- export declare function resumeHook<T = any>(token: string, payload: T): Promise<Hook | null>;
39
+ export declare function resumeHook<T = any>(tokenOrHook: string | Hook, payload: T): Promise<Hook>;
39
40
  /**
40
41
  * Resumes a webhook by sending a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request | Request}
41
42
  * object to a hook identified by its token.
@@ -45,7 +46,8 @@ export declare function resumeHook<T = any>(token: string, payload: T): Promise<
45
46
  *
46
47
  * @param token - The unique token identifying the hook
47
48
  * @param request - The request to send to the hook
48
- * @returns Promise resolving to the response, or null if the hook doesn't exist
49
+ * @returns Promise resolving to the response
50
+ * @throws Error if the hook is not found or if there's an error during the process
49
51
  *
50
52
  * @example
51
53
  *
@@ -61,9 +63,12 @@ export declare function resumeHook<T = any>(token: string, payload: T): Promise<
61
63
  * return new Response('Missing token', { status: 400 });
62
64
  * }
63
65
  *
64
- * const response = await resumeWebhook(token, request);
65
- *
66
- * return response ?? new Response('Webhook not found', { status: 404 });
66
+ * try {
67
+ * const response = await resumeWebhook(token, request);
68
+ * return response;
69
+ * } catch (error) {
70
+ * return new Response('Webhook not found', { status: 404 });
71
+ * }
67
72
  * }
68
73
  * ```
69
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"resume-hook.d.ts","sourceRoot":"","sources":["../../src/runtime/resume-hook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAW5C;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,UAAU,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,GACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAuEtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC,CAkDnB"}
1
+ {"version":3,"file":"resume-hook.d.ts","sourceRoot":"","sources":["../../src/runtime/resume-hook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAyB,MAAM,iBAAiB,CAAC;AAWnE;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,UAAU,CAAC,CAAC,GAAG,GAAG,EACtC,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,OAAO,EAAE,CAAC,GACT,OAAO,CAAC,IAAI,CAAC,CAkFf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC,CAkDnB"}
@@ -4,6 +4,7 @@ import { dehydrateStepReturnValue, hydrateStepArguments, } from '../serializatio
4
4
  import { WEBHOOK_RESPONSE_WRITABLE } from '../symbols.js';
5
5
  import * as Attribute from '../telemetry/semantic-conventions.js';
6
6
  import { getSpanContextForTraceCarrier, trace } from '../telemetry.js';
7
+ import { waitedUntil } from '../util.js';
7
8
  import { getWorld } from './world.js';
8
9
  /**
9
10
  * Get the hook by token to find the associated workflow run,
@@ -16,7 +17,7 @@ export async function getHookByToken(token) {
16
17
  const world = getWorld();
17
18
  const hook = await world.hooks.getByToken(token);
18
19
  if (typeof hook.metadata !== 'undefined') {
19
- hook.metadata = hydrateStepArguments(hook.metadata, [], globalThis);
20
+ hook.metadata = hydrateStepArguments(hook.metadata, [], hook.runId);
20
21
  }
21
22
  return hook;
22
23
  }
@@ -26,9 +27,10 @@ export async function getHookByToken(token) {
26
27
  * This function is called externally (e.g., from an API route or server action)
27
28
  * to send data to a hook and resume the associated workflow run.
28
29
  *
29
- * @param token - The unique token identifying the hook
30
+ * @param tokenOrHook - The unique token identifying the hook, or the hook object itself
30
31
  * @param payload - The data payload to send to the hook
31
- * @returns Promise resolving to an object with the runId, or null if the hook doesn't exist
32
+ * @returns Promise resolving to the hook
33
+ * @throws Error if the hook is not found or if there's an error during the process
32
34
  *
33
35
  * @example
34
36
  *
@@ -38,69 +40,75 @@ export async function getHookByToken(token) {
38
40
  *
39
41
  * export async function POST(request: Request) {
40
42
  * const { token, data } = await request.json();
41
- * const result = await resumeHook(token, data);
42
43
  *
43
- * if (!result) {
44
+ * try {
45
+ * const hook = await resumeHook(token, data);
46
+ * return Response.json({ runId: hook.runId });
47
+ * } catch (error) {
44
48
  * return new Response('Hook not found', { status: 404 });
45
49
  * }
46
- *
47
- * return Response.json({ runId: result.runId });
48
50
  * }
49
51
  * ```
50
52
  */
51
- export async function resumeHook(token, payload) {
52
- return trace('HOOK.resume', async (span) => {
53
- const world = getWorld();
54
- try {
55
- const hook = await getHookByToken(token);
56
- span?.setAttributes({
57
- ...Attribute.HookToken(token),
58
- ...Attribute.HookId(hook.hookId),
59
- ...Attribute.WorkflowRunId(hook.runId),
60
- });
61
- // Dehydrate the payload for storage
62
- const ops = [];
63
- const dehydratedPayload = dehydrateStepReturnValue(payload, ops, globalThis);
64
- waitUntil(Promise.all(ops));
65
- // Create a hook_received event with the payload
66
- await world.events.create(hook.runId, {
67
- eventType: 'hook_received',
68
- correlationId: hook.hookId,
69
- eventData: {
70
- payload: dehydratedPayload,
71
- },
72
- });
73
- const workflowRun = await world.runs.get(hook.runId);
74
- span?.setAttributes({
75
- ...Attribute.WorkflowName(workflowRun.workflowName),
76
- });
77
- const traceCarrier = workflowRun.executionContext?.traceCarrier;
78
- if (traceCarrier) {
79
- const context = await getSpanContextForTraceCarrier(traceCarrier);
80
- if (context) {
81
- span?.addLink?.({ context });
53
+ export async function resumeHook(tokenOrHook, payload) {
54
+ return await waitedUntil(() => {
55
+ return trace('HOOK.resume', async (span) => {
56
+ const world = getWorld();
57
+ try {
58
+ const hook = typeof tokenOrHook === 'string'
59
+ ? await getHookByToken(tokenOrHook)
60
+ : tokenOrHook;
61
+ span?.setAttributes({
62
+ ...Attribute.HookToken(hook.token),
63
+ ...Attribute.HookId(hook.hookId),
64
+ ...Attribute.WorkflowRunId(hook.runId),
65
+ });
66
+ // Dehydrate the payload for storage
67
+ const ops = [];
68
+ const dehydratedPayload = dehydrateStepReturnValue(payload, ops, hook.runId);
69
+ // NOTE: Workaround instead of injecting catching undefined unhandled rejections in webhook bundle
70
+ waitUntil(Promise.all(ops).catch((err) => {
71
+ if (err !== undefined)
72
+ throw err;
73
+ }));
74
+ // Create a hook_received event with the payload
75
+ await world.events.create(hook.runId, {
76
+ eventType: 'hook_received',
77
+ correlationId: hook.hookId,
78
+ eventData: {
79
+ payload: dehydratedPayload,
80
+ },
81
+ });
82
+ const workflowRun = await world.runs.get(hook.runId);
83
+ span?.setAttributes({
84
+ ...Attribute.WorkflowName(workflowRun.workflowName),
85
+ });
86
+ const traceCarrier = workflowRun.executionContext?.traceCarrier;
87
+ if (traceCarrier) {
88
+ const context = await getSpanContextForTraceCarrier(traceCarrier);
89
+ if (context) {
90
+ span?.addLink?.({ context });
91
+ }
82
92
  }
93
+ // Re-trigger the workflow against the deployment ID associated
94
+ // with the workflow run that the hook belongs to
95
+ await world.queue(`__wkf_workflow_${workflowRun.workflowName}`, {
96
+ runId: hook.runId,
97
+ // attach the trace carrier from the workflow run
98
+ traceCarrier: workflowRun.executionContext?.traceCarrier ?? undefined,
99
+ }, {
100
+ deploymentId: workflowRun.deploymentId,
101
+ });
102
+ return hook;
83
103
  }
84
- // Re-trigger the workflow against the deployment ID associated
85
- // with the workflow run that the hook belongs to
86
- await world.queue(`__wkf_workflow_${workflowRun.workflowName}`, {
87
- runId: hook.runId,
88
- // attach the trace carrier from the workflow run
89
- traceCarrier: workflowRun.executionContext?.traceCarrier ?? undefined,
90
- }, {
91
- deploymentId: workflowRun.deploymentId,
92
- });
93
- return hook;
94
- }
95
- catch (_err) {
96
- // If hook not found, return null
97
- span?.setAttributes({
98
- ...Attribute.HookToken(token),
99
- ...Attribute.HookFound(false),
100
- });
101
- // TODO: Check for specific error types
102
- return null;
103
- }
104
+ catch (err) {
105
+ span?.setAttributes({
106
+ ...Attribute.HookToken(typeof tokenOrHook === 'string' ? tokenOrHook : tokenOrHook.token),
107
+ ...Attribute.HookFound(false),
108
+ });
109
+ throw err;
110
+ }
111
+ });
104
112
  });
105
113
  }
106
114
  /**
@@ -112,7 +120,8 @@ export async function resumeHook(token, payload) {
112
120
  *
113
121
  * @param token - The unique token identifying the hook
114
122
  * @param request - The request to send to the hook
115
- * @returns Promise resolving to the response, or null if the hook doesn't exist
123
+ * @returns Promise resolving to the response
124
+ * @throws Error if the hook is not found or if there's an error during the process
116
125
  *
117
126
  * @example
118
127
  *
@@ -128,9 +137,12 @@ export async function resumeHook(token, payload) {
128
137
  * return new Response('Missing token', { status: 400 });
129
138
  * }
130
139
  *
131
- * const response = await resumeWebhook(token, request);
132
- *
133
- * return response ?? new Response('Webhook not found', { status: 404 });
140
+ * try {
141
+ * const response = await resumeWebhook(token, request);
142
+ * return response;
143
+ * } catch (error) {
144
+ * return new Response('Webhook not found', { status: 404 });
145
+ * }
134
146
  * }
135
147
  * ```
136
148
  */
@@ -159,7 +171,7 @@ export async function resumeWebhook(token, request) {
159
171
  // No `respondWith` value implies the default behavior of returning a 202
160
172
  response = new Response(null, { status: 202 });
161
173
  }
162
- await resumeHook(hook.token, request);
174
+ await resumeHook(hook, request);
163
175
  if (responseReadable) {
164
176
  // Wait for the readable stream to emit one chunk,
165
177
  // which is the `Response` object
@@ -177,4 +189,4 @@ export async function resumeWebhook(token, request) {
177
189
  }
178
190
  return response;
179
191
  }
180
- //# sourceMappingURL=resume-hook.js.map
192
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdW1lLWhvb2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9yZXN1bWUtaG9vay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXJFLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsb0JBQW9CLEdBQ3JCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sS0FBSyxTQUFTLE1BQU0sc0NBQXNDLENBQUM7QUFDbEUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDekMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV0Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FBQyxLQUFhO0lBQ2hELE1BQU0sS0FBSyxHQUFHLFFBQVEsRUFBRSxDQUFDO0lBQ3pCLE1BQU0sSUFBSSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakQsSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLFFBQVEsR0FBRyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsUUFBZSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNEJHO0FBQ0gsTUFBTSxDQUFDLEtB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
@@ -1,9 +1,19 @@
1
+ import type { World } from '@workflow/world';
1
2
  import { Run } from '../runtime.js';
2
3
  export interface StartOptions {
3
4
  /**
4
5
  * The deployment ID to use for the workflow run.
6
+ *
7
+ * @deprecated This property should not be set in user code under normal circumstances.
8
+ * It is automatically inferred from environment variables when deploying to Vercel.
9
+ * Only set this if you are doing something advanced and know what you are doing.
5
10
  */
6
11
  deploymentId?: string;
12
+ /**
13
+ * The world to use for the workflow run creation,
14
+ * by default the world is inferred from the environment variables.
15
+ */
16
+ world?: World;
7
17
  }
8
18
  /**
9
19
  * Represents an imported workflow function.
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/runtime/start.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAOpC,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,IAAI,CAC/D,GAAG,IAAI,EAAE,KAAK,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EACpD,QAAQ,EAAE,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,gBAAgB,EAC7D,IAAI,EAAE,KAAK,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAEzB,wBAAgB,KAAK,CAAC,OAAO,EAC3B,QAAQ,EAAE,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,gBAAgB,EAC1D,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/runtime/start.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAyB,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAQpC,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,IAAI,CAC/D,GAAG,IAAI,EAAE,KAAK,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EACpD,QAAQ,EAAE,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,gBAAgB,EAC7D,IAAI,EAAE,KAAK,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAEzB,wBAAgB,KAAK,CAAC,OAAO,EAC3B,QAAQ,EAAE,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,gBAAgB,EAC1D,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC"}