Files
sim/apps
Theodore Li af8025c411 fix(table): dispatcher cold-start, live run counter, smooth typewriter (#4675)
* fix(table): cut dispatcher cold-start by lazy-loading heavy import chains

The trigger.dev table-run-dispatcher spent ~6s in module init before its
first batchTriggerAndWait — it imports lib/table/service for getTableById,
which eagerly imported lib/table/trigger → @/lib/webhooks/processor →
webhook-execution + executor, dragging the entire workflow-execution stack
into the dispatcher container even though it never fires a trigger.

- trigger.ts lazy-imports the webhook processor + polling utils inside
  fireTableTrigger (the only consumer), so importing service no longer pulls
  the executor.
- buildEnqueueItems only imports the cell job (for the inline `runner`) on the
  database backend; the trigger.dev backend triggers by task id and ignores
  runner.

* fix(table): run counter + gutter Stop update instantly on Run

The "X running" badge, per-row gutter Stop button, and runningByRowId map
stayed at zero after clicking Run until a manual refetch. useRunColumn
optimistically stamped cells pending in the rows cache but never bumped the
activeDispatches counter — so when the dispatcher's real pending SSE arrived,
applyCell saw the cell was already in-flight (wasInFlight === isInFlight) and
skipped the counter delta. The optimistic stamp ate the transition.

- onMutate now bumps runningCellCount / runningByRowId by the cells it stamps,
  snapshotting prior run-state for rollback on error.
- onSuccess seeds the dispatch into the overlay list from the response instead
  of invalidating activeDispatches (a refetch would reset the optimistic
  counter to the server's still-zero count before the dispatcher stamps).

* fix(table): drive cell typewriter with rAF so concurrent reveals stay smooth

The character-by-character reveal used a per-cell setInterval. When many cells
reveal at once (a Run-all completing in waves), the independent interval
callbacks fire at uncoordinated times and each forces its own render +
layout/paint — O(cells) reflows over an un-virtualized grid, so it degrades as
more cells fill. Switch to requestAnimationFrame: all cells' callbacks run
before one paint, so React batches them into a single render + paint per frame
regardless of cell count. Reveal length is derived from elapsed time, so a
dropped frame catches up instead of slowing the animation.

* fix(table): roll back optimistic run counter when no dispatch is created

useRunColumn.onSuccess returned early on a null dispatchId (no matching
groups / eligible rows) without undoing the onMutate counter bump — and no
SSE would arrive to correct it, leaving the counter permanently inflated.
Restore the pre-mutation run-state on that path, mirroring onError.

* chore(table): tighten inline comments on dispatcher cold-start fixes
2026-05-20 15:15:45 -04:00
..