refactor(decode-payload): clean up decode-payload.ts API surface#3302
Conversation
…codeAllPotentialPayloadsWithCodec Replace all call sites with cloneAllPotentialPayloadsWithCodec directly, eliminating the duplicate recursive walker and its named-param wrapper.
decodePayload → decodeRawPayload decodePayloads → applyCodecToPayloads decodeReadablePayloads → decodePayloadsWithCodec decodeSingleReadablePayloadWithCodec → decodeUserMetadataPayload cloneAllPotentialPayloadsWithCodec → decodeEventAttributes isSinglePayload → isRawPayload
…ibutes The namespace argument was unused inside the function body. Removing it simplifies all call sites and makes the signature match actual behavior.
…ntAttributesForExport Remove the returnDataOnly parameter from the public decodeEventAttributes API. Extract a dedicated decodeEventAttributesForExport function for the two callers (export-history, workflow-service) that need to preserve the full payload structure with metadata.
Collapse the two separate branches in decodePayloadAttributes — one for indexedFields and one for flat searchAttributes — into a single branch that selects the correct target object via ternary. Fix stale test mocks in get-event-attributes and to-event-history that still referenced the removed convertPayloadToJsonWithCodec export.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| false, | ||
| )) as PotentiallyDecodable; | ||
|
|
||
| let summary = ''; |
There was a problem hiding this comment.
⚠️ 'workflow' is possibly 'undefined'.
| } | ||
| } | ||
|
|
||
| let details = ''; |
There was a problem hiding this comment.
⚠️ 'workflow' is possibly 'undefined'.
| return groups | ||
| .map((group) => { | ||
| const rawStatus = decodePayload( | ||
| const rawStatus = decodeRawPayload( |
There was a problem hiding this comment.
⚠️ Property 'groupValues' does not exist on type 'never'.
| const rawStatus = decodePayload( | ||
| const rawStatus = decodeRawPayload( | ||
| group?.groupValues[0], | ||
| ) as unknown as ActivityStatus; |
There was a problem hiding this comment.
⚠️ Property 'count' does not exist on type 'never'.
| return groups | ||
| .map((group) => { | ||
| const status = decodePayload( | ||
| const status = decodeRawPayload( |
There was a problem hiding this comment.
⚠️ Property 'groupValues' does not exist on type 'never'.
| const status = decodePayload( | ||
| const status = decodeRawPayload( | ||
| group?.groupValues[0], | ||
| ) as unknown as WorkflowStatus; |
There was a problem hiding this comment.
⚠️ Property 'count' does not exist on type 'never'.
| ): SummaryAttribute => { | ||
| if (typeof value === 'object') { | ||
| if (isSinglePayload(value)) { | ||
| if (isRawPayload(value)) { |
There was a problem hiding this comment.
⚠️ Type 'object | null' is not assignable to type 'string | Record<string, unknown> | IPayloads'.
| if (isSinglePayload(value)) { | ||
| if (isRawPayload(value)) { | ||
| return { key, value }; | ||
| } |
There was a problem hiding this comment.
⚠️ No overload matches this call.
|
…coder cascade data-encoder.ts now reads settings and namespace directly from page state instead of accepting them as parameters. This removes the need to thread settings through every call site in the chain: components → services → decode-payload → data-encoder. - codeServerRequest/decodePayloadsWithCodec/encodePayloadsWithCodec drop settings+namespace params - decodeEventAttributes/decodeEventAttributesForExport drop settings param - getEventAttributes takes HistoryEvent directly instead of EventWithMetadata - EventRequestMetadata.settings field removed - pending-activities model deleted (settings removal collapsed it to a no-op wrapper) - All tests updated to set codecEndpoint/passAccessToken/includeCredentials stores directly
| settings, | ||
| ); | ||
| const convertedAttributes = await decodeEventAttributes(_value); | ||
| const decodedAttributes = decodePayloadAttributes( |
There was a problem hiding this comment.
⚠️ Argument of type 'WorkflowEvent | EventAttribute | IMemo | PotentiallyDecodable' is not assignable to parameter of type 'Optional<WorkflowEvent | EventAttribute | PotentiallyDecodable>'.
| const convertedAttributes = await decodeEventAttributes(_value); | ||
| const decodedAttributes = decodePayloadAttributes( | ||
| convertedAttributes, | ||
| ) as object; |
There was a problem hiding this comment.
⚠️ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
| settings, | ||
| }); | ||
| const convertedAttributes = await convertWithCodec(attributes); | ||
|
|
There was a problem hiding this comment.
⚠️ Argument of type 'WorkflowEvent | EventAttribute | IMemo | PotentiallyDecodable' is not assignable to parameter of type 'Optional<WorkflowEvent | EventAttribute | PotentiallyDecodable>'.
| false, | ||
| )) as PotentiallyDecodable; | ||
|
|
||
| let summary = ''; |
There was a problem hiding this comment.
⚠️ 'workflow' is possibly 'undefined'.
| } | ||
| } | ||
|
|
||
| let details = ''; |
There was a problem hiding this comment.
⚠️ 'workflow' is possibly 'undefined'.
| decodeSetting, | ||
| returnDataOnly, | ||
| ); | ||
|
|
There was a problem hiding this comment.
⚠️ Argument of type 'WorkflowEvent | EventAttribute | IMemo | PotentiallyDecodable' is not assignable to parameter of type 'Optional<WorkflowEvent | EventAttribute | PotentiallyDecodable>'.
| ); | ||
| const decodedEvent = await decodePayloads(event, decodeSetting); | ||
| decodedEvents.push(decodedEvent); | ||
| } |
There was a problem hiding this comment.
⚠️ Argument of type 'Replace<Optional<WorkflowEvent | EventAttribute | PotentiallyDecodable>, Optional<WorkflowEvent | EventAttribute | PotentiallyDecodable>>[]' is not assignable to parameter of type 'HistoryEvent[]'.
| const decodedAttributes = parsePayloadAttributes( | ||
| convertedAttributes, | ||
| ) as object; | ||
| const keyExists = key && decodedAttributes?.[key]; |
There was a problem hiding this comment.
⚠️ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
| await decodeUserMetadata(workflow); | ||
| await decodeWorkflowUserMetadata(workflow); | ||
|
|
||
| const { taskQueue } = workflow; |
There was a problem hiding this comment.
⚠️ Type 'string | undefined' is not assignable to type 'string'.
| if (!payloads?.length) return undefined; | ||
|
|
||
| const decodedAttributes = decodePayloadAttributes( | ||
| const decodedAttributes = parsePayloadAttributes( |
There was a problem hiding this comment.
⚠️ Argument of type 'WorkflowEvent | EventAttribute | IMemo | PotentiallyDecodable' is not assignable to parameter of type 'Optional<WorkflowEvent | EventAttribute | PotentiallyDecodable>'.
| }, | ||
| page.data?.settings, | ||
| ); | ||
| getWorkflowStackTrace({ |
There was a problem hiding this comment.
⚠️ Type 'WorkflowExecution | null' is not assignable to type 'Eventual<{ id: string; runId: string; }>'.
There was a problem hiding this comment.
Would be nice to clear out this strict error but who knows probably it's fine.
| queryResult = getQuery({ | ||
| namespace, | ||
| workflow: params, | ||
| queryType, |
There was a problem hiding this comment.
⚠️ Type '{ payloads: IPayloads; } | null' is not assignable to type 'IPayloads | undefined'.
| @@ -76,7 +78,7 @@ export function decodePayload( | |||
| try { | |||
| const data = parseWithBigInt(atob(String(payload?.data ?? ''))); | |||
| if (returnDataOnly) return data; | |||
There was a problem hiding this comment.
⚠️ Argument of type '{ [k: string]: string; } | undefined' is not assignable to parameter of type 'Record<string, unknown>'.
| @@ -89,7 +91,7 @@ export function decodePayload( | |||
| const encoding = atob(String(payload?.metadata?.encoding ?? '')); | |||
| if (encoding === 'binary/null') { | |||
| if (returnDataOnly) return null; | |||
There was a problem hiding this comment.
⚠️ Argument of type '{ [k: string]: string; } | undefined' is not assignable to parameter of type 'Record<string, unknown>'.
| 'indexedFields', | ||
| ) | ||
| ? eventAttribute.searchAttributes.indexedFields | ||
| : eventAttribute.searchAttributes; |
There was a problem hiding this comment.
⚠️ No overload matches this call.
| ) | ||
| ? eventAttribute.searchAttributes.indexedFields | ||
| : eventAttribute.searchAttributes; | ||
| Object.entries(searchAttributes).forEach(([key, value]) => { |
There was a problem hiding this comment.
⚠️ 'searchAttributes' is of type 'unknown'.⚠️ Argument of type 'unknown' is not assignable to parameter of type 'Payload'.
| @@ -131,7 +135,7 @@ export const decodePayloadAttributes = < | |||
| const memo = eventAttribute.memo.fields; | |||
|
|
|||
There was a problem hiding this comment.
⚠️ No overload matches this call.
| @@ -150,132 +154,114 @@ export const decodePayloadAttributes = < | |||
| const queryResult = eventAttribute?.queryResult; | |||
|
|
|||
There was a problem hiding this comment.
⚠️ No overload matches this call.
| @@ -150,132 +154,114 @@ export const decodePayloadAttributes = < | |||
| const queryResult = eventAttribute?.queryResult; | |||
|
|
|||
| Object.entries(queryResult).forEach(([key, value]) => { | |||
There was a problem hiding this comment.
⚠️ 'queryResult' is of type 'unknown'.⚠️ Argument of type 'unknown' is not assignable to parameter of type 'Payload'.
| returnDataOnly: boolean = true, | ||
| ): Promise<unknown[]> => { | ||
| const awaitData = await callCodecEndpoint({ payloads: { payloads } }); | ||
| return (awaitData?.payloads ?? []).map((p) => |
There was a problem hiding this comment.
⚠️ Argument of type 'unknown' is not assignable to parameter of type 'Payload'.
| @@ -289,10 +275,8 @@ export const cloneAllPotentialPayloadsWithCodec = async ( | |||
| } else { | |||
There was a problem hiding this comment.
⚠️ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ id: string; attributes: EventAttribute; timestamp: string; classification: "Scheduled" | "Unspecified" | "Open" | "New" | "Started" | "Initiated" | "Running" | ... 7 more ... | "CancelRequested"; ... 70 more ...; eventId: string; } | ... 62 more ... | { ...; }'.
| @@ -289,10 +275,8 @@ export const cloneAllPotentialPayloadsWithCodec = async ( | |||
| } else { | |||
| const next = clone[key]; | |||
| if (isObject(next)) { | |||
There was a problem hiding this comment.
⚠️ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ id: string; attributes: EventAttribute; timestamp: string; classification: "Scheduled" | "Unspecified" | "Open" | "New" | "Started" | "Initiated" | "Running" | ... 7 more ... | "CancelRequested"; ... 70 more ...; eventId: string; } | ... 62 more ... | { ...; }'.
| includeCredentials, | ||
| }, | ||
| }; | ||
|
|
| signal?: AbortSignal, | ||
| ): Promise<ParsedQuery> { | ||
| return getQuery({ ...options, queryType: '__stack_trace' }, settings); | ||
| return getQuery({ ...options, queryType: '__stack_trace' }, signal); |
There was a problem hiding this comment.
👀 Signal lookin gooooood
| namespace, | ||
| codecSettings, | ||
| ); | ||
| const convertedAttributes = await decodeEventAttributes(event.attributes); |
| firstWorkflowTaskBackoff: '0s', | ||
| memo: null, | ||
| searchAttributes: { indexedFields: { CandidateEmail: 'whadup@lolcats.com' } }, | ||
| searchAttributes: { indexedFields: { CandidateEmail: 'test@test.com' } }, |
There was a problem hiding this comment.
0/10 the old email was much more better probably this will make the test suite less reliable
| * Sends `payloads` through the remote codec server, then Base64-decodes each | ||
| * result with {@link parseRawPayloadToJSON}. | ||
| */ | ||
| const decodePayloadsWithRemoteCodecAndParseRawPayloadToJSON = async ( |
Auto-generated version bump from 2.48.3 to 2.48.4 Specific version: 2.48.4 Changes included: - [`7cf1be53`](7cf1be5) Adjust breadcrumb spacing and min-height (#3304) - [`c9834815`](c983481) Add missing Nexus Operation events to event groups (#3309) - [`5c7aa86c`](5c7aa86) feat: add onItemsChange callback to PaginatedTable (#3300) - [`66d3cf68`](66d3cf6) Update pre-release badge to secondary in Workers (#3310) - [`393e84de`](393e84d) Keep Pending Activities/Operations at the top of Timeline and Compact view (#3307) - [`9f721347`](9f72134) Update error link in codec-server-error-banner (#3313) - [`e698bda3`](e698bda) Add class prop to BottomNav component (#3314) - [`55767fc9`](55767fc) Add overrides (#3317) - [`256cd274`](256cd27) refactor(decode-payload): clean up decode-payload.ts API surface (#3302) - [`04f8c251`](04f8c25) Make input height full so its easier to click into the input (#3318) - [`b2231056`](b223105) Workflows Table Row Density (#3285) - [`0b2ce4fd`](0b2ce4f) PR Review Notifications (#3322) - [`84618196`](8461819) feat: serverless worker deployment CRUD (#3236) Co-authored-by: rossnelson <[email protected]>
… components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup.
…load component (#3299) * refactor: replace PayloadDecoder and MetadataDecoder with unified Payload component Consolidates two divergent payload display components into a single `<Payload />` component at `src/lib/components/payload.svelte`. Previously, `payload-decoder.svelte` (Svelte 5 runes, required a `children` snippet, always decoded full attribute trees) and `metadata-decoder.svelte` (Svelte 4 options API with slot syntax, decoded single payloads to truncated summary strings) served different display purposes but used inconsistent APIs and decoding paths across 65+ call sites. The new component unifies both under a single `mode` prop: - `code-block` (default): renders a CodeBlock with the decoded value, replacing all PayloadDecoder + CodeBlock snippet patterns - `summary`: truncates to 120 chars and renders a Badge, replacing all MetadataDecoder usages - `inline-truncated`: renders the compact .payload pre block used in event detail rows - `children` snippet: escape hatch for callers that need custom rendering (schedule input, timeline SVG text elements) Both old components used a single decoding path internally (cloneAllPotentialPayloadsWithCodec -> decodePayloadAttributes -> stringifyWithBigInt). MetadataDecoder previously used a separate decodeSingleReadablePayloadWithCodec path; the new component uses the same unified path for consistency. The component is written in Svelte 5 runes throughout and imports from $app/state instead of $app/stores, matching the newer direction of the codebase. Migrated files: - src/lib/components/event/event-card.svelte - src/lib/components/event/event-details-row.svelte (+ moved .payload CSS) - src/lib/components/event/event-metadata-expanded.svelte - src/lib/components/event/event-summary-row.svelte - src/lib/components/lines-and-dots/svg/group-details-text.svelte - src/lib/components/lines-and-dots/svg/timeline-graph-row.svelte - src/lib/components/schedule/schedule-form/schedule-input-payload.svelte - src/lib/components/standalone-activities/activity-input-and-outcome.svelte - src/lib/components/workflow/client-actions/update-confirmation-modal.svelte - src/lib/components/workflow/input-and-results-payload.svelte - src/lib/components/workflow/metadata/metadata-events.svelte - src/lib/components/workflow/pending-activity/pending-activity-card.svelte - src/lib/components/workflow/workflow-json-navigator.svelte - src/lib/pages/standalone-activity-details.svelte - src/lib/pages/standalone-activity-search-attributes.svelte - src/lib/pages/workflow-memo.svelte - src/lib/pages/workflow-metadata.svelte - src/lib/pages/workflow-search-attributes.svelte All 1730 tests pass. * remove unused component, fix css * refactor: move Payload component into payload/ directory Moves payload.svelte into src/lib/components/payload/ and adds a USAGE.md report documenting all 31 call sites grouped by feature area. Updates all 17 import paths accordingly. * docs: add Payload component improvement suggestions * docs: add decode-payload usage report and refactoring recommendations * refactor(payload): split Payload component into focused mode-specific components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup. * fix(payload-summary): use decodeUserMetadata and add onDecode prop Replace decodeEventAttributes with decodeUserMetadata — the correct decode path for a single raw Payload (Phase 2 codec only, no attribute tree walking). Also add onDecode callback prop, called after a successful decode, consistent with PayloadCodeBlock. * refactor(payload): extract shared decode logic into decode-payload-value utility Remove 3-way duplication of getInitialValue/onMount decode logic from payload-code-block, payload-decoder, and payload-inline by extracting getInitialPayloadValue and decodePayloadValue into src/lib/utilities/decode-payload-value.ts. * fix(payload): replace onMount with \$effect for reactive value updates Components now re-decode when value or fieldName props change after mount, fixing the reactivity gap that caused stale decoded content when parent components updated their payload bindings. * add workflow with user metadata * remove unnecessary props from payload code block * fix summary display * add improvements * fix heading levels * add multi input workflow * get rid of fieldName prop and fix most of the call sites * fix remaining type errors * fix tests * rm inspect * rm console.log * fix CR feedback * remove bad key * fix export * remove unused type * cleanup unused stuff * fix possibly duplicate key * add language prop to PayloadCodeBlock * add copyIconTitle and copySuccessIconTitle to codeblock instance * refactor(payload): fix reactivity and race condition in payload-summary Replace $effect+$state async pattern with $derived promise + $effect cleanup to ensure all reactive deps (value, fallback, prefix, maxSummaryLength) are tracked synchronously. Use $effect cleanup function to cancel stale promise callbacks on re-run, preventing race conditions when value changes rapidly. Remove unused onDecode prop. * early return if no payloads in decode utils
* refactor: replace PayloadDecoder and MetadataDecoder with unified Payload component Consolidates two divergent payload display components into a single `<Payload />` component at `src/lib/components/payload.svelte`. Previously, `payload-decoder.svelte` (Svelte 5 runes, required a `children` snippet, always decoded full attribute trees) and `metadata-decoder.svelte` (Svelte 4 options API with slot syntax, decoded single payloads to truncated summary strings) served different display purposes but used inconsistent APIs and decoding paths across 65+ call sites. The new component unifies both under a single `mode` prop: - `code-block` (default): renders a CodeBlock with the decoded value, replacing all PayloadDecoder + CodeBlock snippet patterns - `summary`: truncates to 120 chars and renders a Badge, replacing all MetadataDecoder usages - `inline-truncated`: renders the compact .payload pre block used in event detail rows - `children` snippet: escape hatch for callers that need custom rendering (schedule input, timeline SVG text elements) Both old components used a single decoding path internally (cloneAllPotentialPayloadsWithCodec -> decodePayloadAttributes -> stringifyWithBigInt). MetadataDecoder previously used a separate decodeSingleReadablePayloadWithCodec path; the new component uses the same unified path for consistency. The component is written in Svelte 5 runes throughout and imports from $app/state instead of $app/stores, matching the newer direction of the codebase. Migrated files: - src/lib/components/event/event-card.svelte - src/lib/components/event/event-details-row.svelte (+ moved .payload CSS) - src/lib/components/event/event-metadata-expanded.svelte - src/lib/components/event/event-summary-row.svelte - src/lib/components/lines-and-dots/svg/group-details-text.svelte - src/lib/components/lines-and-dots/svg/timeline-graph-row.svelte - src/lib/components/schedule/schedule-form/schedule-input-payload.svelte - src/lib/components/standalone-activities/activity-input-and-outcome.svelte - src/lib/components/workflow/client-actions/update-confirmation-modal.svelte - src/lib/components/workflow/input-and-results-payload.svelte - src/lib/components/workflow/metadata/metadata-events.svelte - src/lib/components/workflow/pending-activity/pending-activity-card.svelte - src/lib/components/workflow/workflow-json-navigator.svelte - src/lib/pages/standalone-activity-details.svelte - src/lib/pages/standalone-activity-search-attributes.svelte - src/lib/pages/workflow-memo.svelte - src/lib/pages/workflow-metadata.svelte - src/lib/pages/workflow-search-attributes.svelte All 1730 tests pass. * remove unused component, fix css * refactor: move Payload component into payload/ directory Moves payload.svelte into src/lib/components/payload/ and adds a USAGE.md report documenting all 31 call sites grouped by feature area. Updates all 17 import paths accordingly. * docs: add Payload component improvement suggestions * docs: add decode-payload usage report and refactoring recommendations * refactor(payload): split Payload component into focused mode-specific components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup. * fix(payload-summary): use decodeUserMetadata and add onDecode prop Replace decodeEventAttributes with decodeUserMetadata — the correct decode path for a single raw Payload (Phase 2 codec only, no attribute tree walking). Also add onDecode callback prop, called after a successful decode, consistent with PayloadCodeBlock. * refactor(payload): extract shared decode logic into decode-payload-value utility Remove 3-way duplication of getInitialValue/onMount decode logic from payload-code-block, payload-decoder, and payload-inline by extracting getInitialPayloadValue and decodePayloadValue into src/lib/utilities/decode-payload-value.ts. * fix(payload): replace onMount with \$effect for reactive value updates Components now re-decode when value or fieldName props change after mount, fixing the reactivity gap that caused stale decoded content when parent components updated their payload bindings. * add workflow with user metadata * remove unnecessary props from payload code block * fix summary display * add improvements * fix heading levels * add multi input workflow * get rid of fieldName prop and fix most of the call sites * fix remaining type errors * fix tests * rm inspect * rm console.log * WIP - download external payloads * add support for downloading externally stored payloads * add some error handling to downloads * add support for filename * fix CR feedback * remove bad key * fix export * remove unused type * cleanup unused stuff * fix possibly duplicate key * add language prop to PayloadCodeBlock * add copyIconTitle and copySuccessIconTitle to codeblock instance * refactor(payload): fix reactivity and race condition in payload-summary Replace $effect+$state async pattern with $derived promise + $effect cleanup to ensure all reactive deps (value, fallback, prefix, maxSummaryLength) are tracked synchronously. Use $effect cleanup function to cancel stale promise callbacks on re-run, preventing race conditions when value changes rapidly. Remove unused onDecode prop. * early return if no payloads in decode utils * add type guards * support inline external payloads * fix download error and payload codeblock types * fix schedule input * rm console.log * fix tests and strict mode * fix spec * fix typo * add some optional chaining
…load component (#3299) * refactor: replace PayloadDecoder and MetadataDecoder with unified Payload component Consolidates two divergent payload display components into a single `<Payload />` component at `src/lib/components/payload.svelte`. Previously, `payload-decoder.svelte` (Svelte 5 runes, required a `children` snippet, always decoded full attribute trees) and `metadata-decoder.svelte` (Svelte 4 options API with slot syntax, decoded single payloads to truncated summary strings) served different display purposes but used inconsistent APIs and decoding paths across 65+ call sites. The new component unifies both under a single `mode` prop: - `code-block` (default): renders a CodeBlock with the decoded value, replacing all PayloadDecoder + CodeBlock snippet patterns - `summary`: truncates to 120 chars and renders a Badge, replacing all MetadataDecoder usages - `inline-truncated`: renders the compact .payload pre block used in event detail rows - `children` snippet: escape hatch for callers that need custom rendering (schedule input, timeline SVG text elements) Both old components used a single decoding path internally (cloneAllPotentialPayloadsWithCodec -> decodePayloadAttributes -> stringifyWithBigInt). MetadataDecoder previously used a separate decodeSingleReadablePayloadWithCodec path; the new component uses the same unified path for consistency. The component is written in Svelte 5 runes throughout and imports from $app/state instead of $app/stores, matching the newer direction of the codebase. Migrated files: - src/lib/components/event/event-card.svelte - src/lib/components/event/event-details-row.svelte (+ moved .payload CSS) - src/lib/components/event/event-metadata-expanded.svelte - src/lib/components/event/event-summary-row.svelte - src/lib/components/lines-and-dots/svg/group-details-text.svelte - src/lib/components/lines-and-dots/svg/timeline-graph-row.svelte - src/lib/components/schedule/schedule-form/schedule-input-payload.svelte - src/lib/components/standalone-activities/activity-input-and-outcome.svelte - src/lib/components/workflow/client-actions/update-confirmation-modal.svelte - src/lib/components/workflow/input-and-results-payload.svelte - src/lib/components/workflow/metadata/metadata-events.svelte - src/lib/components/workflow/pending-activity/pending-activity-card.svelte - src/lib/components/workflow/workflow-json-navigator.svelte - src/lib/pages/standalone-activity-details.svelte - src/lib/pages/standalone-activity-search-attributes.svelte - src/lib/pages/workflow-memo.svelte - src/lib/pages/workflow-metadata.svelte - src/lib/pages/workflow-search-attributes.svelte All 1730 tests pass. * remove unused component, fix css * refactor: move Payload component into payload/ directory Moves payload.svelte into src/lib/components/payload/ and adds a USAGE.md report documenting all 31 call sites grouped by feature area. Updates all 17 import paths accordingly. * docs: add Payload component improvement suggestions * docs: add decode-payload usage report and refactoring recommendations * refactor(payload): split Payload component into focused mode-specific components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup. * fix(payload-summary): use decodeUserMetadata and add onDecode prop Replace decodeEventAttributes with decodeUserMetadata — the correct decode path for a single raw Payload (Phase 2 codec only, no attribute tree walking). Also add onDecode callback prop, called after a successful decode, consistent with PayloadCodeBlock. * refactor(payload): extract shared decode logic into decode-payload-value utility Remove 3-way duplication of getInitialValue/onMount decode logic from payload-code-block, payload-decoder, and payload-inline by extracting getInitialPayloadValue and decodePayloadValue into src/lib/utilities/decode-payload-value.ts. * fix(payload): replace onMount with \$effect for reactive value updates Components now re-decode when value or fieldName props change after mount, fixing the reactivity gap that caused stale decoded content when parent components updated their payload bindings. * add workflow with user metadata * remove unnecessary props from payload code block * fix summary display * add improvements * fix heading levels * add multi input workflow * get rid of fieldName prop and fix most of the call sites * fix remaining type errors * fix tests * rm inspect * rm console.log * fix CR feedback * remove bad key * fix export * remove unused type * cleanup unused stuff * fix possibly duplicate key * add language prop to PayloadCodeBlock * add copyIconTitle and copySuccessIconTitle to codeblock instance * refactor(payload): fix reactivity and race condition in payload-summary Replace $effect+$state async pattern with $derived promise + $effect cleanup to ensure all reactive deps (value, fallback, prefix, maxSummaryLength) are tracked synchronously. Use $effect cleanup function to cancel stale promise callbacks on re-run, preventing race conditions when value changes rapidly. Remove unused onDecode prop. * early return if no payloads in decode utils
* refactor: replace PayloadDecoder and MetadataDecoder with unified Payload component Consolidates two divergent payload display components into a single `<Payload />` component at `src/lib/components/payload.svelte`. Previously, `payload-decoder.svelte` (Svelte 5 runes, required a `children` snippet, always decoded full attribute trees) and `metadata-decoder.svelte` (Svelte 4 options API with slot syntax, decoded single payloads to truncated summary strings) served different display purposes but used inconsistent APIs and decoding paths across 65+ call sites. The new component unifies both under a single `mode` prop: - `code-block` (default): renders a CodeBlock with the decoded value, replacing all PayloadDecoder + CodeBlock snippet patterns - `summary`: truncates to 120 chars and renders a Badge, replacing all MetadataDecoder usages - `inline-truncated`: renders the compact .payload pre block used in event detail rows - `children` snippet: escape hatch for callers that need custom rendering (schedule input, timeline SVG text elements) Both old components used a single decoding path internally (cloneAllPotentialPayloadsWithCodec -> decodePayloadAttributes -> stringifyWithBigInt). MetadataDecoder previously used a separate decodeSingleReadablePayloadWithCodec path; the new component uses the same unified path for consistency. The component is written in Svelte 5 runes throughout and imports from $app/state instead of $app/stores, matching the newer direction of the codebase. Migrated files: - src/lib/components/event/event-card.svelte - src/lib/components/event/event-details-row.svelte (+ moved .payload CSS) - src/lib/components/event/event-metadata-expanded.svelte - src/lib/components/event/event-summary-row.svelte - src/lib/components/lines-and-dots/svg/group-details-text.svelte - src/lib/components/lines-and-dots/svg/timeline-graph-row.svelte - src/lib/components/schedule/schedule-form/schedule-input-payload.svelte - src/lib/components/standalone-activities/activity-input-and-outcome.svelte - src/lib/components/workflow/client-actions/update-confirmation-modal.svelte - src/lib/components/workflow/input-and-results-payload.svelte - src/lib/components/workflow/metadata/metadata-events.svelte - src/lib/components/workflow/pending-activity/pending-activity-card.svelte - src/lib/components/workflow/workflow-json-navigator.svelte - src/lib/pages/standalone-activity-details.svelte - src/lib/pages/standalone-activity-search-attributes.svelte - src/lib/pages/workflow-memo.svelte - src/lib/pages/workflow-metadata.svelte - src/lib/pages/workflow-search-attributes.svelte All 1730 tests pass. * remove unused component, fix css * refactor: move Payload component into payload/ directory Moves payload.svelte into src/lib/components/payload/ and adds a USAGE.md report documenting all 31 call sites grouped by feature area. Updates all 17 import paths accordingly. * docs: add Payload component improvement suggestions * docs: add decode-payload usage report and refactoring recommendations * refactor(payload): split Payload component into focused mode-specific components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup. * fix(payload-summary): use decodeUserMetadata and add onDecode prop Replace decodeEventAttributes with decodeUserMetadata — the correct decode path for a single raw Payload (Phase 2 codec only, no attribute tree walking). Also add onDecode callback prop, called after a successful decode, consistent with PayloadCodeBlock. * refactor(payload): extract shared decode logic into decode-payload-value utility Remove 3-way duplication of getInitialValue/onMount decode logic from payload-code-block, payload-decoder, and payload-inline by extracting getInitialPayloadValue and decodePayloadValue into src/lib/utilities/decode-payload-value.ts. * fix(payload): replace onMount with \$effect for reactive value updates Components now re-decode when value or fieldName props change after mount, fixing the reactivity gap that caused stale decoded content when parent components updated their payload bindings. * add workflow with user metadata * remove unnecessary props from payload code block * fix summary display * add improvements * fix heading levels * add multi input workflow * get rid of fieldName prop and fix most of the call sites * fix remaining type errors * fix tests * rm inspect * rm console.log * WIP - download external payloads * add support for downloading externally stored payloads * add some error handling to downloads * add support for filename * fix CR feedback * remove bad key * fix export * remove unused type * cleanup unused stuff * fix possibly duplicate key * add language prop to PayloadCodeBlock * add copyIconTitle and copySuccessIconTitle to codeblock instance * refactor(payload): fix reactivity and race condition in payload-summary Replace $effect+$state async pattern with $derived promise + $effect cleanup to ensure all reactive deps (value, fallback, prefix, maxSummaryLength) are tracked synchronously. Use $effect cleanup function to cancel stale promise callbacks on re-run, preventing race conditions when value changes rapidly. Remove unused onDecode prop. * early return if no payloads in decode utils * add type guards * support inline external payloads * fix download error and payload codeblock types * fix schedule input * rm console.log * fix tests and strict mode * fix spec * fix typo * add some optional chaining
* refactor: replace PayloadDecoder and MetadataDecoder with unified Payload component Consolidates two divergent payload display components into a single `<Payload />` component at `src/lib/components/payload.svelte`. Previously, `payload-decoder.svelte` (Svelte 5 runes, required a `children` snippet, always decoded full attribute trees) and `metadata-decoder.svelte` (Svelte 4 options API with slot syntax, decoded single payloads to truncated summary strings) served different display purposes but used inconsistent APIs and decoding paths across 65+ call sites. The new component unifies both under a single `mode` prop: - `code-block` (default): renders a CodeBlock with the decoded value, replacing all PayloadDecoder + CodeBlock snippet patterns - `summary`: truncates to 120 chars and renders a Badge, replacing all MetadataDecoder usages - `inline-truncated`: renders the compact .payload pre block used in event detail rows - `children` snippet: escape hatch for callers that need custom rendering (schedule input, timeline SVG text elements) Both old components used a single decoding path internally (cloneAllPotentialPayloadsWithCodec -> decodePayloadAttributes -> stringifyWithBigInt). MetadataDecoder previously used a separate decodeSingleReadablePayloadWithCodec path; the new component uses the same unified path for consistency. The component is written in Svelte 5 runes throughout and imports from $app/state instead of $app/stores, matching the newer direction of the codebase. Migrated files: - src/lib/components/event/event-card.svelte - src/lib/components/event/event-details-row.svelte (+ moved .payload CSS) - src/lib/components/event/event-metadata-expanded.svelte - src/lib/components/event/event-summary-row.svelte - src/lib/components/lines-and-dots/svg/group-details-text.svelte - src/lib/components/lines-and-dots/svg/timeline-graph-row.svelte - src/lib/components/schedule/schedule-form/schedule-input-payload.svelte - src/lib/components/standalone-activities/activity-input-and-outcome.svelte - src/lib/components/workflow/client-actions/update-confirmation-modal.svelte - src/lib/components/workflow/input-and-results-payload.svelte - src/lib/components/workflow/metadata/metadata-events.svelte - src/lib/components/workflow/pending-activity/pending-activity-card.svelte - src/lib/components/workflow/workflow-json-navigator.svelte - src/lib/pages/standalone-activity-details.svelte - src/lib/pages/standalone-activity-search-attributes.svelte - src/lib/pages/workflow-memo.svelte - src/lib/pages/workflow-metadata.svelte - src/lib/pages/workflow-search-attributes.svelte All 1730 tests pass. * remove unused component, fix css * refactor: move Payload component into payload/ directory Moves payload.svelte into src/lib/components/payload/ and adds a USAGE.md report documenting all 31 call sites grouped by feature area. Updates all 17 import paths accordingly. * docs: add Payload component improvement suggestions * docs: add decode-payload usage report and refactoring recommendations * refactor(payload): split Payload component into focused mode-specific components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup. * fix(payload-summary): use decodeUserMetadata and add onDecode prop Replace decodeEventAttributes with decodeUserMetadata — the correct decode path for a single raw Payload (Phase 2 codec only, no attribute tree walking). Also add onDecode callback prop, called after a successful decode, consistent with PayloadCodeBlock. * refactor(payload): extract shared decode logic into decode-payload-value utility Remove 3-way duplication of getInitialValue/onMount decode logic from payload-code-block, payload-decoder, and payload-inline by extracting getInitialPayloadValue and decodePayloadValue into src/lib/utilities/decode-payload-value.ts. * fix(payload): replace onMount with \$effect for reactive value updates Components now re-decode when value or fieldName props change after mount, fixing the reactivity gap that caused stale decoded content when parent components updated their payload bindings. * add workflow with user metadata * remove unnecessary props from payload code block * fix summary display * add improvements * fix heading levels * add multi input workflow * get rid of fieldName prop and fix most of the call sites * fix remaining type errors * fix tests * rm inspect * rm console.log * WIP - download external payloads * add support for downloading externally stored payloads * add some error handling to downloads * add support for filename * fix CR feedback * remove bad key * fix export * remove unused type * cleanup unused stuff * fix possibly duplicate key * add language prop to PayloadCodeBlock * add copyIconTitle and copySuccessIconTitle to codeblock instance * refactor(payload): fix reactivity and race condition in payload-summary Replace $effect+$state async pattern with $derived promise + $effect cleanup to ensure all reactive deps (value, fallback, prefix, maxSummaryLength) are tracked synchronously. Use $effect cleanup function to cancel stale promise callbacks on re-run, preventing race conditions when value changes rapidly. Remove unused onDecode prop. * early return if no payloads in decode utils * add type guards * support inline external payloads * fix download error and payload codeblock types * fix schedule input * rm console.log * fix tests and strict mode * fix spec * fix typo * add some optional chaining
* refactor: replace PayloadDecoder and MetadataDecoder with unified Payload component Consolidates two divergent payload display components into a single `<Payload />` component at `src/lib/components/payload.svelte`. Previously, `payload-decoder.svelte` (Svelte 5 runes, required a `children` snippet, always decoded full attribute trees) and `metadata-decoder.svelte` (Svelte 4 options API with slot syntax, decoded single payloads to truncated summary strings) served different display purposes but used inconsistent APIs and decoding paths across 65+ call sites. The new component unifies both under a single `mode` prop: - `code-block` (default): renders a CodeBlock with the decoded value, replacing all PayloadDecoder + CodeBlock snippet patterns - `summary`: truncates to 120 chars and renders a Badge, replacing all MetadataDecoder usages - `inline-truncated`: renders the compact .payload pre block used in event detail rows - `children` snippet: escape hatch for callers that need custom rendering (schedule input, timeline SVG text elements) Both old components used a single decoding path internally (cloneAllPotentialPayloadsWithCodec -> decodePayloadAttributes -> stringifyWithBigInt). MetadataDecoder previously used a separate decodeSingleReadablePayloadWithCodec path; the new component uses the same unified path for consistency. The component is written in Svelte 5 runes throughout and imports from $app/state instead of $app/stores, matching the newer direction of the codebase. Migrated files: - src/lib/components/event/event-card.svelte - src/lib/components/event/event-details-row.svelte (+ moved .payload CSS) - src/lib/components/event/event-metadata-expanded.svelte - src/lib/components/event/event-summary-row.svelte - src/lib/components/lines-and-dots/svg/group-details-text.svelte - src/lib/components/lines-and-dots/svg/timeline-graph-row.svelte - src/lib/components/schedule/schedule-form/schedule-input-payload.svelte - src/lib/components/standalone-activities/activity-input-and-outcome.svelte - src/lib/components/workflow/client-actions/update-confirmation-modal.svelte - src/lib/components/workflow/input-and-results-payload.svelte - src/lib/components/workflow/metadata/metadata-events.svelte - src/lib/components/workflow/pending-activity/pending-activity-card.svelte - src/lib/components/workflow/workflow-json-navigator.svelte - src/lib/pages/standalone-activity-details.svelte - src/lib/pages/standalone-activity-search-attributes.svelte - src/lib/pages/workflow-memo.svelte - src/lib/pages/workflow-metadata.svelte - src/lib/pages/workflow-search-attributes.svelte All 1730 tests pass. * remove unused component, fix css * refactor: move Payload component into payload/ directory Moves payload.svelte into src/lib/components/payload/ and adds a USAGE.md report documenting all 31 call sites grouped by feature area. Updates all 17 import paths accordingly. * docs: add Payload component improvement suggestions * docs: add decode-payload usage report and refactoring recommendations * refactor(payload): split Payload component into focused mode-specific components Replace the 14-prop multi-mode payload.svelte with four single-purpose components: PayloadCodeBlock, PayloadSummary, PayloadDecoder, and PayloadInline. Each component carries only the props relevant to its render mode, eliminating dead props at call sites. Also updates the decode paths to use the renamed decode-payload.ts API (decodeEventAttributes, parsePayloadAttributes) following the #3302 cleanup. * fix(payload-summary): use decodeUserMetadata and add onDecode prop Replace decodeEventAttributes with decodeUserMetadata — the correct decode path for a single raw Payload (Phase 2 codec only, no attribute tree walking). Also add onDecode callback prop, called after a successful decode, consistent with PayloadCodeBlock. * refactor(payload): extract shared decode logic into decode-payload-value utility Remove 3-way duplication of getInitialValue/onMount decode logic from payload-code-block, payload-decoder, and payload-inline by extracting getInitialPayloadValue and decodePayloadValue into src/lib/utilities/decode-payload-value.ts. * fix(payload): replace onMount with \$effect for reactive value updates Components now re-decode when value or fieldName props change after mount, fixing the reactivity gap that caused stale decoded content when parent components updated their payload bindings. * add workflow with user metadata * remove unnecessary props from payload code block * fix summary display * add improvements * fix heading levels * add multi input workflow * get rid of fieldName prop and fix most of the call sites * fix remaining type errors * fix tests * rm inspect * rm console.log * WIP - download external payloads * add support for downloading externally stored payloads * add some error handling to downloads * add support for filename * fix CR feedback * remove bad key * fix export * remove unused type * cleanup unused stuff * fix possibly duplicate key * add language prop to PayloadCodeBlock * add copyIconTitle and copySuccessIconTitle to codeblock instance * refactor(payload): fix reactivity and race condition in payload-summary Replace $effect+$state async pattern with $derived promise + $effect cleanup to ensure all reactive deps (value, fallback, prefix, maxSummaryLength) are tracked synchronously. Use $effect cleanup function to cancel stale promise callbacks on re-run, preventing race conditions when value changes rapidly. Remove unused onDecode prop. * early return if no payloads in decode utils * add type guards * support inline external payloads * fix download error and payload codeblock types * fix schedule input * rm console.log * fix tests and strict mode * fix spec * fix typo * add some optional chaining
Description & motivation 💭
decode-payload.ts had grown several redundant abstractions over time: two nearly-identical recursive walk functions, a thin wrapper that added no
logic, an unused namespace parameter threaded through every call, and a returnDataOnly flag that only one caller ever set to false.
This PR removes the dead weight, renames functions to reflect what they actually do, and isolates the export-history code path that needed the
non-default behavior.
Changes
cloneAllPotentialPayloadsWithCodec), eliminating the duplicate recursive walker and its misleadingly-named wrapper
applyCodecToPayloads, decodeSingleReadablePayloadWithCodec → decodeUserMetadataPayload, cloneAllPotentialPayloadsWithCodec → decodeEventAttributes,
isSinglePayload → isRawPayload
chain
iterating
Screenshots (if applicable) 📸
Design Considerations 🎨
Testing 🧪
How was this tested 👻
Steps for others to test: 🚶🏽♂️🚶🏽♀️
Checklists
Draft Checklist
Merge Checklist
Issue(s) closed
Docs
Any docs updates needed?