Skip to content

Comments

@workflow/web: Decompose workflow-api-client.ts into focused modules and add test infrastructure#1070

Open
alizenhom wants to merge 7 commits intovercel:mainfrom
alizenhom:ali/enhance-o11y
Open

@workflow/web: Decompose workflow-api-client.ts into focused modules and add test infrastructure#1070
alizenhom wants to merge 7 commits intovercel:mainfrom
alizenhom:ali/enhance-o11y

Conversation

@alizenhom
Copy link

@alizenhom alizenhom commented Feb 15, 2026

Summary

  • Refactors the monolithic workflow-api-client.ts (~1,330 lines) into 8 focused, single-responsibility modules while preserving a barrel re-export for backward compatibility
  • Sets up vitest + jsdom + @testing-library/react test infrastructure for packages/web and adds comprehensive unit tests across all extracted modules

Motivation

workflow-api-client.ts had grown to 1,329 lines with extensive duplication across 5 distinct patterns — paginated list hooks, exhaustive fetch helpers, merge-by-ID functions, poll functions, and server action wrappers — each repeated 2-3 times with only the fetch call or ID key varying. This made it difficult to test, navigate, and reason about individual concerns, and the package had no unit tests or test runner configured.

What Changed?

The monolith was split along natural boundaries into standalone modules:

  • workflow-errors.ts —> WorkflowWebAPIError class, getErrorMessage, unwrapServerActionResult, and unwrapOrThrow helpers for consistent error handling across the package
  • workflow-primitives.ts —> Pure utility functions (mergeById, fetchAllPaginated, pollResource) that provide the generic pagination and polling building blocks used by the hooks
  • workflow-actions.ts —> Thin wrappers around server actions (cancelRun, recreateRun, reenqueueRun, wakeUpRun, resumeHook) with uniform error unwrapping
  • workflow-streams.ts —> readStream and listStreams for fetching workflow stream data via the Fetch API
  • Four React hooks were extracted into hooks/:
    • use-paginated-list.ts —> Generic usePaginatedList hook with page caching and navigation, plus concrete useWorkflowRuns and useWorkflowHooks hooks built on top of it
    • use-resource-data.ts —> useWorkflowResourceData for fetching individual run/step/hook/sleep detail views with auto-refresh
    • use-trace-viewer.ts —> useWorkflowTraceViewerData for the trace viewer, combining run, steps, hooks, and events with live polling and exhaustive pagination
    • use-workflow-streams.ts —> useWorkflowStreams for polling the list of stream IDs on a run
      workflow-api-client.ts is now a ~39-line barrel that re-exports everything, so existing consumers are unaffected.

Test infrastructure

  • Added vitest, jsdom, and @testing-library/react as dev dependencies
  • Created vitest.config.ts with jsdom environment and ~ path alias
  • Added pnpm test script (pnpm test)

Test coverage

Added 8 test files organized to mirror the module structure:

Utilities & core logic

  • workflow-errors.test.ts —> error class construction, 403 message handling, unwrapOrThrow success/failure/rejection paths
  • workflow-primitives.test.ts —> mergeById deduplication and custom ID keys, fetchAllPaginated multi-page traversal and error bail-out, pollResource with both always and onHasMore cursor strategies
  • workflow-actions.test.ts —> success and failure cases for all 5 action wrappers
  • workflow-streams.test.ts —> readStream with startIndex/abort signal/non-ok responses/null body, listStreams success and structured error parsing

React hooks (using @testing-library/react + jsdom)

  • use-paginated-list.test.ts —> initial fetch, error propagation, parameter forwarding, cursor-based nextPage, previousPage cache hit, and reload (covers both useWorkflowRuns and useWorkflowHooks)
  • use-resource-data.test.ts —> run/step/hook/sleep resource types, enabled: false short-circuit, error states
  • use-trace-viewer.test.ts —> combined initial load of run + steps + hooks + events, paginated step population, error handling
  • use-workflow-streams.test.ts—> initial fetch and error handling

Notes

Apologies for the size of this PR, the extraction touched a lot of files but the actual logic is unchanged. Happy to break it up differently or address any feedback.

As a new contributor still getting familiar with the codebase, there may be rough edges I've missed. I'd appreciate any guidance on the following directions I'm interested in exploring next:

  • Convex world — implementing a new world for convex.
  • Observability improvements — continuing to expand test coverage, refactoring, and improving latency in the web package

Would love to know if either of these aligns with the project's priorities!

@changeset-bot
Copy link

changeset-bot bot commented Feb 15, 2026

🦋 Changeset detected

Latest commit: 7bbe71c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 15 packages
Name Type
@workflow/web Minor
@workflow/cli Patch
workflow Patch
@workflow/world-testing Patch
@workflow/core Patch
@workflow/builders Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/web-shared Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/nuxt Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Contributor

vercel bot commented Feb 15, 2026

@alizenhom is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant