Releases: egeominotti/bunqueue-dashboard
Releases · egeominotti/bunqueue-dashboard
Release list
v0.0.30
Fixed
- Cron preview accepted the wrong month for named months. The live schedule
preview rejectedjanas invalid and shifted every other month name one early
(febpreviewed January,decpreviewed November) — a 0-indexed month table
against cron's 1-based months. Names now resolve correctly (jan=1 … dec=12). - The Job Inspector could save an edited payload to the wrong job. Editing
the Data field, then looking up a different job with a byte-identical payload,
kept the unsaved edit and let Save write it to the new job. The editor is now
keyed per job id. - The Database inspector kept a stale filter across table switches. Choosing
a filter column/value on one table then switching to another left the old
inputs in place, causing a "no such column" error or a silent wrong-table
filter; the filter bar now resets per table. - Queue Control's config forms vanished silently when their load failed. A
failed stall/DLQ-config fetch removed the whole form with no message; it now
shows a retry card, matching Queue Detail. - A save then immediate re-edit of a queue's stall/DLQ config was clobbered
by the save's own echo on the next poll. The form now recognizes its own
just-saved value and preserves the re-edit. - CSV export from the Database inspector now quotes a bare carriage return
(which was splitting a row) and neutralizes spreadsheet formula injection on
text cells (a value starting with= + - @), while keeping real numbers numeric. - A queue with no processed jobs showed an error rate of "0.00%" instead of
"—" (0% from zero data is a claim, not a measurement). - Bulk job actions no longer overstate the confirm count. A mixed-state
selection now confirms and acts on only the eligible rows. - The backoff preview no longer implies a delay before a job's first run
(attempt 1 is the initial execution — backoff applies only to retries). - Duration and latency readouts no longer render "1000ms" where rounding
tipped a value to a full second; they show "1.0s" / "1.00s". - The DLQ retry/purge failure toast read "Retri failed" / "Purg failed"; it
now reads "Retry failed" / "Purge failed". - The live activity stream splits SSE frames on the earliest boundary, so a
mixed CRLF/LF stream can't merge two events into one. - Copilot: stopping a turn before its first token no longer leaves a
permanent "Thinking…" bubble, and a stopped turn's late teardown can no longer
cancel a newly-started turn's confirmations or release its busy lock. - Demo mode (
?demo/#demolocal preview) no longer loses its call-to-action
and the Flows default graph after the first navigation drops the query string.
Changed
- Shared
ConfigLoadErrorextracted to the config-forms module so Queue
Control and Queue Detail render one component. - The Database row-detail drawer fetches each truncated cell once instead of
re-fetching every truncated cell on every 6s poll. - Added regression tests (cron month names, duration/latency rounding, SSE frame
boundaries). The one remaining Biome warning (useActivityStreameffect deps)
is now a documented intentional-reconnect ignore, socheckis fully clean.
Full Changelog: v0.0.29...v0.0.30
v0.0.29
Changed
- Queue detail: "Recent jobs" now sits above "Jobs by priority." Recent
activity reads first, with the priority histogram directly beneath it.
Full Changelog: v0.0.28...v0.0.29
v0.0.28
Fixed
- Docs hero subtitle now centered. VitePress's prose paragraph styles reset
the alignment the hero inherits, so the intro paragraph rendered left-aligned
under the centered heading; pinnedtext-align: centeron it.
Added
- Per-priority histogram on a queue. Queue detail now charts how many waiting
jobs sit at each priority level, so you can see at a glance whether high-priority
work is starving the rest. The data already shipped in the queue payload and was
being dropped. - Memory tools in Diagnostics. A "Compact (GC)" button forces a garbage
collection + internal compaction and reports the freed RSS; a "Heap statistics"
panel loads thebun:jscbreakdown (object counts + top object types) on demand
for leak hunting; and a copyable Prometheus scrape URL for Grafana/Alertmanager. - Set job progress. The Job Inspector can now set an active job's progress
(0–100), which also refreshes its stall heartbeat and fires ajob.progress
webhook. AddedsetJobProgress/gc/heapStats/prometheusUrlto the client. - Advanced enqueue options. Add Job exposes tags, a group id, a dedup unique
key, job dependencies, and a backoff strategy (flat / fixed / exponential). - Advanced cron options. Create-schedule exposes a max-executions cap, run-
immediately, skip-missed-on-restart, and per-spawned-job options (max attempts,
backoff, timeout).
Full Changelog: v0.0.27...v0.0.28
v0.0.27
Added
- Social/OG cards on the live demo. The demo is the project's most-shared
link but shipped with only a<title>, so it unfurled as a bare, image-less
link on Twitter/Slack/Reddit/LinkedIn.index.htmlnow carries a meta
description, canonical, Open Graph and Twittersummary_large_imagetags, and
the OG image is served from the app root. - Demo-mode conversion CTA. In the hosted demo the sidebar now shows a small
prompt with a copy-to-clipboardbunx bunqueue-dashboard, a Star-on-GitHub
button, and a Docs link, so a wowed visitor has a path to install instead of a
dead end. Hidden outside demo mode.
Changed
- Sharper positioning. README and docs hero now lead with the one ownable
differentiator ("the only queue dashboard that also runs the server"), gloss
what bunqueue is (a fast, Redis-free, Bun-native job queue) for cold visitors,
and name who it's for. - Richer npm discoverability. Expanded
package.jsonkeywords with the
high-intent terms people actually search (bullmq-alternative,
queue-dashboard,job-queue-ui,dlq, …) and pointedhomepageat the
live demo instead of a README anchor.
Full Changelog: v0.0.26...v0.0.27
v0.0.26
Fixed
- DLQ Control entries table clipped its action column on mobile. The wrapper
usedoverflow-hidden(unlike every sibling table), so at ~390px the Retry and
Inspect buttons were cut off with no way to scroll to them. It now uses
overflow-x-autoand scrolls horizontally, matching the DLQ/Jobs tables. - iOS Safari zoomed the page when focusing a form field. The fluid rem type
scale put inputs/selects/textareas under 16px on phones, which triggers
Safari's zoom-on-focus. Controls are now pinned to 16px below thesm
breakpoint (this also makes the small JSON/data editors legible on mobile). - The Copilot launcher covered the bottom row on scrolled pages. The fixed
button overlapped pagination "Next" and last-row content; the main scroll area
now reserves bottom padding so nothing hides behind it.
Changed
- Mobile nav drawer is now accessible. Opening it moves focus into the
drawer and traps Tab within it, closing restores focus to the opener, page
content behind the overlay no longer scrolls, and the hamburger exposes
aria-expanded/aria-controlsto assistive tech. - Docs prose reads naturally. Replaced em-dash punctuation across the docs
site with commas and plain sentences (landing, pages, known-issues, agent,
quickstart, deploy guides).
Full Changelog: v0.0.25...v0.0.26
v0.0.25
Fixed
- "Open the live demo" did nothing on the docs site. The demo app lives on
the same origin as the docs (different path prefix), so VitePress's SPA
router intercepted the click and silently no-op'd. All demo links now open
in a new tab (target="_blank" rel="noreferrer"), which the router leaves
alone — and is the right behavior from docs to app anyway.
Changed
- UI/UX pass across every section (from a four-auditor review of all 24
pages; ~49 fixes). Highlights:- Overview: primary health row (Error Rate / Failed / DLQ) separated
from secondary throughput cards; Queue Health sorts worst-first; the
activity feed distinguishes connecting / idle / disconnected; the stale
banner shows "last updated Xs ago". - Queues: sortable columns; queue→DLQ links keep the queue context
(/dlq?queue=); Jobs and DLQ selections sync to the URL (shareable,
back-restorable); "queue not found" links back; config cards show a
Retry instead of vanishing on a failed fetch. - Logs: Follow/Pause with "N new" resume counter, failure reasons shown
on failed events, job IDs linked + copyable, absolute time on hover. - Alerts: per-metric threshold units (%, ms, jobs), channel routing
honestly marked "in-app only", queue disabled for global-only p99,
guidance when notifications are blocked. - Control: stop/restart confirms state the blast radius (live TCP/WS
counts); DLQ purge requires typing the queue name; Benchmark confirms the
target queue + server before enqueuing real load; Job Inspector shows the
error first on failed jobs, de-duplicates the Data card and puts actions
first on mobile; Enter submits the server config and inline job actions;
webhook URLs validated; optimistic webhook toggle. - Management/shell: honest S3 wording ("Check server storage", "Local
draft"); Settings tests the values as typed and each token has its own
show/hide; Database drawer is a real dialog with focus management and
exports also toast; Copilot declares its data egress, closes on Escape
and announces streamed replies; command palette reachable on mobile. - Charts gained y-scale labels and screen-reader summaries; inline action
results announce viarole="status"; table headers carryscope="col".
- Overview: primary health row (Error Rate / Failed / DLQ) separated
Full Changelog: v0.0.24...v0.0.25
v0.0.24
Fixed
- Landing page buttons/links dead on GitHub Pages. The new landing used
raw-HTMLhref="/…"anchors, which VitePress does not rewrite with the
site base (/bunqueue-dashboard/docs/) — every internal button/card/tile
pointed outside the site. All internal raw anchors are now relative, and
the tour video resolves throughwithBase()(rawsrcattributes aren't
base-rewritten either). Verified by building with the Pages base locally
and clicking through.
Full Changelog: v0.0.23...v0.0.24
v0.0.23
Fixed
- The live demo now has data on every page. A full click-through of demo
mode found and fixed the gaps: Workers was empty (three synthesized workers
with now-relative last-seen, active/stale mix); DLQ entries had reason
"unknown" and no error (now realistic timeout / max-attempts failures, and
the per-queue reason stats match); the webhook showed 0/0 deliveries (now
42/3 with a last-triggered time); Queue Control's Stall-detection and
DLQ-policy cards never rendered (/stall-configand/dlq-configare now
answered); Job Inspector logs were empty and mis-shaped ({data:{logs}}
with sample lines); and the Jobs Explorer read the wrong query param
(statevs the client'sstates), so status tabs did nothing and every
queue butemailswas empty — jobs are now filtered by the requested
states and retagged per queue, so all four queues are browseable.
Changed
- Docs landing page redesigned as a single-page product landing: keyword
hero with a clickable window-framed screenshot that opens the live demo, an
honest fact strip (MIT · zero-dep npm · 5-platform binaries · Docker),
a numbered 12-card feature inventory (each linking its guide page), the tour
video, an 8-tile "everything you can drive" grid, a 4-step get-running
process with real UI screenshots, install tabs (npm / binary / Docker /
source), and an 8-question FAQ with verifiable answers. Works in light and
dark, responsive, built on VitePress theme tokens.
Full Changelog: v0.0.22...v0.0.23
v0.0.22
Added
- Hook tests (23 new tests). The four data hooks are now covered by real
behavioral tests, rendered through a minimal in-repo hook harness
(test/domSetup.ts: happy-dom document +react-domroot underact()— no
testing-library dependency):usePolledData— initial load, self-scheduled re-polls, render stability
on unchanged payloads (same data reference), error set + clear on recovery,
the generation guard dropping a stale in-flight result after a deps change,
refetch(), and unmount stopping the loop.useActivityStream— driven end-to-end through the realsse.tsparser
via a mocked fetch stream: handshake → connected, newest-first ordering
through the 150 ms flush, status/counter mapping, the 250-event ring cap,
and the 2 s reconnect after a clean stream end.useThroughputSeries— immediate first sample (series +latest+ summed
depth), swallowed transient failures; plus puredepthTrendcases
(draining/accumulating/steady, dead band).useAlertEngine— breach + single toast, edge-triggered no-re-notify, the
skip-tick-when-overview-is-down policy (no false<-rule trips), per-source
null metrics on partial failure, queue-scoped andp99_latencyresolution,
and the idle no-rules path (zero polling).
happy-dom(dev-only) provides the DOM; the published package stays
zero-dependency.
Changed
- Coverage floors raised to lines ≥ 70% / functions ≥ 58% (from 62%/55%),
matching the new measured totals (72.7% / 60.3%).
Fixed
- Release publish race.
release.yml's asset globs overlapped
(bunqueue-dashboard-*.zipandbunqueue-dashboard-v*both matched the
zip), so the same asset was uploaded twice concurrently — the race broke the
first v0.0.22 publish (draft left without the zip) and duplicated the zip
line in every release'sSHA256SUMS. The globs are now disjoint
(bunqueue-dashboard-v*-*matches only the platform binaries).
Full Changelog: v0.0.21...v0.0.22
v0.0.21
Added
- Unit tests for the core API client (
lib/bq.ts). The transport layer's
contract is now pinned by tests: error mapping (HTTP errors, non-JSON bodies,
empty/204 responses, invalid JSON), the HTTP-200-{ok:false}throw convention
andhealth()'s opt-out, server-vs-agent auth-header scoping, the scoped
auth:requiredevent on 401, and URL/body construction for representative
endpoints (encoding,{limit}/{concurrency}shapes, optional bodies). - Aggregate test-coverage floor in CI.
bun run test:coverageruns the
suite with coverage andscripts/check-coverage.tsenforces a floor on the
lcov totals (lines ≥ 62%, functions ≥ 55%), so overall coverage can only go
up. (Bun's owncoverageThresholdis applied per file, which a single
legitimately low-coverage module would fail regardless of the aggregate.)
Changed
/cron-managernow redirects to/cron. The two routes served the same
CronManagerpage; the alias is kept as a redirect so old bookmarks keep
working.- Docs caught up with the shipped app.
CLAUDE.md's layout and
docs/pages.md's route/page tables now document every routed page —
Benchmark, Flows, MCP guide, QueuesOverview, QueueDetailPro, Bulk Add, the
demo-mode fetch shim, the Copilot assistant, the client-side alert engine —
and no longer claim Alerts is unrouted.
Full Changelog: v0.0.20...v0.0.21