Files
Mitul Shah 8a766884cf change timing markers to be precise on the timeline (#2775)
* doen

* Fix: Old test file `test/format-duration-precise.test.ts` still asserts two-decimal output ("45.20s", "1m 0.00s") that no longer matches the trimmed-zero output of `formatDurationPrecise`, so `pnpm test`/CI fails.

This commit fixes the issue reported at packages/web-shared/test/format-duration-precise.test.ts:15

## Bug

The PR changed `formatDurationPrecise` (in `packages/web-shared/src/lib/utils.ts`) to trim trailing zeros by wrapping the fractional value in `Number(x.toFixed(fractionDigits))`:

```ts
if (normalizedMs < MS_IN_MINUTE) {
  return `${Number((normalizedMs / MS_IN_SECOND).toFixed(fractionDigits))}s`;
}
...
parts.push(`${Number(seconds.toFixed(fractionDigits))}s`);
```

`Number("45.20")` → `45.2`, `Number("0.00")` → `0`, so whole/half seconds now render without padding.

A new test file `packages/web-shared/src/lib/utils.test.ts` reflects this behavior, but the pre-existing `packages/web-shared/test/format-duration-precise.test.ts` was left untouched and still asserts the **old** padded output.

## Concrete trigger

Reproduced the actual function output (integer decomposition + trimmed zeros):

| Input | Old assertion | New actual output |
|-------|---------------|-------------------|
| `45200` | `45.20s` | `45.2s` |
| `999.6` | `1.00s` | `1s` |
| `999.5` | `1.00s` | `1s` |
| `59999` | `1m 0.00s` | `1m 0s` |
| `59995` | `1m 0.00s` | `1m 0s` |
| `119999` | `2m 0.00s` | `2m 0s` |
| `3659999` | `1h 1m 0.00s` | `1h 1m 0s` |
| `86459999` | `1d 1m 0.00s` | `1d 1m 0s` |

The root `vitest.config.ts` uses default include globs, so `test/*.test.ts` runs and these assertions fail, breaking CI. (I couldn't run vitest directly in the sandbox because dev deps weren't installed / `vitest/config` unresolved, so I reproduced the exact function logic in a standalone Node script to confirm the outputs.)

## Fix

Updated the stale assertions in `test/format-duration-precise.test.ts` to the trimmed-zero outputs, and adjusted the file-level doc comment (which referenced `"1m 0.00s"` / `"60.00s"`) to describe the current behavior.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: mitul-s <mitulxshah@gmail.com>

---------

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-07-06 18:27:10 -04:00
..
2026-07-06 13:32:59 -07:00
2026-07-06 13:32:59 -07:00

@workflow/web-shared

Workflow Observability UI primitives. See Workflow SDK for more information.

Usage

This package contains:

  • pre-styled, prop-driven UI components (no data fetching)

If you want a full observability experience with server actions already wired, take a look at @workflow/web instead.

It comes with pre-styled UI components that accept data + callbacks:

import { WorkflowTraceViewer } from '@workflow/web-shared';

export default function MyRunDetailView({ run, events, fetchSpanDetail }) {
  return (
    <WorkflowTraceViewer
      run={run}
      events={events}
      fetchSpanDetail={fetchSpanDetail}
    />
  );
}

Server actions and data fetching are intentionally not part of web-shared. Implement those in your app and pass data + callbacks into these components. If you need world run helpers, use @workflow/core/runtime.

Security notice: If you implement server-side data fetching using @workflow/world-vercel or similar backends, ensure that user-supplied IDs (runId, stepId, etc.) are validated before passing them to world functions. The server actions in @workflow/web do not include authentication — see that package's README for details on securing self-hosted deployments.

Styling

In order for tailwind classes to be picked up correctly, you might need to configure your NextJS app to use the correct CSS processor. E.g. if you're using PostCSS with TailwindCSS, you can do the following:

// postcss.config.mjs in your NextJS app
const config = {
  plugins: ['@tailwindcss/postcss'],
};

export default config;