-
Notifications
You must be signed in to change notification settings - Fork 297
Centralize workflow event semantics #2790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
394f4c2
2f39c3b
7ccc6bf
5f2455d
8683dc9
6802546
0d93ec3
0c40fb4
b670eda
0b57804
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| '@workflow/world': minor | ||
| '@workflow/core': patch | ||
| '@workflow/world-local': patch | ||
| '@workflow/world-postgres': patch | ||
| '@workflow/world-vercel': patch | ||
| '@workflow/web-shared': patch | ||
| '@workflow/web': patch | ||
| '@workflow/cli': patch | ||
| --- | ||
|
|
||
| Centralize workflow event type classifiers and event-data payload field helpers. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { importKey } from '@workflow/core/encryption'; | ||
| import { dehydrateStepError } from '@workflow/core/serialization'; | ||
| import { describe, expect, it } from 'vitest'; | ||
| import { hydrateResourceIO, isEncryptedRef } from './hydration.js'; | ||
|
|
||
| describe('hydrateResourceIO', () => { | ||
| it('displays and decrypts encrypted event errors', async () => { | ||
| const rawKey = new Uint8Array(32).fill(7); | ||
| const error = new Error('step failed'); | ||
| const encryptedError = await dehydrateStepError( | ||
| error, | ||
| 'run_1', | ||
| await importKey(rawKey), | ||
| [], | ||
| globalThis, | ||
| true | ||
| ); | ||
| const event = { | ||
| runId: 'run_1', | ||
| eventId: 'event_1', | ||
| eventType: 'step_failed', | ||
| eventData: { error: encryptedError }, | ||
| }; | ||
|
|
||
| const encrypted = await hydrateResourceIO(event); | ||
| expect(isEncryptedRef(encrypted.eventData.error)).toBe(true); | ||
|
|
||
| const decrypted = await hydrateResourceIO(event, async () => rawKey); | ||
| expect(decrypted.eventData.error).toBeInstanceOf(Error); | ||
| expect(decrypted.eventData.error).toHaveProperty('message', error.message); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,14 @@ import { | |
| } from '@workflow/core/serialization'; | ||
| import { VERCEL_403_ERROR_MESSAGE } from '@workflow/errors'; | ||
| import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name'; | ||
| import type { Event, Hook, Step, WorkflowRun, World } from '@workflow/world'; | ||
| import { | ||
| type Event, | ||
| type Hook, | ||
| isWaitEventType, | ||
| type Step, | ||
| type WorkflowRun, | ||
| type World, | ||
| } from '@workflow/world'; | ||
| import chalk from 'chalk'; | ||
|
|
||
| import { formatDistance } from 'date-fns'; | ||
|
|
@@ -619,7 +626,7 @@ export const listRuns = async (world: World, opts: InspectCLIOptions = {}) => { | |
|
|
||
| const useAnalytics = !opts.withData && Boolean(world.analytics); | ||
| const resolveData = opts.withData ? 'all' : 'none'; | ||
| const status = opts.status as WorkflowRun['status'] | undefined; | ||
| const status = opts.status; | ||
|
|
||
| // Resolve --since/--until into an explicit listing window. Only the | ||
| // analytics read path supports one; the runtime storage APIs have no time | ||
|
|
@@ -1371,7 +1378,7 @@ export const listSleeps = async ( | |
| // Group wait events by correlationId | ||
| const waitEventsByCorrelation = new Map<string, Event[]>(); | ||
| for (const event of events.data) { | ||
| if (event.correlationId?.startsWith('wait_')) { | ||
| if (isWaitEventType(event.eventType) && event.correlationId) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AI Review: Note Possible behavior change — sleep grouping switched from |
||
| const existing = waitEventsByCorrelation.get(event.correlationId) ?? []; | ||
| existing.push(event); | ||
| waitEventsByCorrelation.set(event.correlationId, existing); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eventType should never be encrypted, but
resultmight beThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, eventType isn't being decrypted
since
in order to access
result.eventTypewe need to have eventType on the generic T because resource: T in the function