@adonis-agora/durable-dashboard 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@
10
10
  rel="stylesheet"
11
11
  />
12
12
  <title>durable · control plane</title>
13
- <script type="module" crossorigin src="/__DURABLE_DASHBOARD__/assets/index-DdB9zxuX.js"></script>
13
+ <script type="module" crossorigin src="/__DURABLE_DASHBOARD__/assets/index-DupjrK7N.js"></script>
14
14
  <link rel="stylesheet" crossorigin href="/__DURABLE_DASHBOARD__/assets/index-6nmSTfT7.css">
15
15
  </head>
16
16
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/durable-dashboard",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Control-plane console (runs, step timeline, workflow graph, retry/cancel/fix-and-replay) for @adonis-agora/durable — a React SPA served by a thin AdonisJS provider. Part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -41,7 +41,7 @@
41
41
  "@base-ui/react": "1.9.0",
42
42
  "@tailwindcss/postcss": "4.3.3",
43
43
  "@tanstack/intent": "0.5.6",
44
- "@tanstack/react-query": "5.104.4",
44
+ "@tanstack/react-query": "5.104.5",
45
45
  "@tanstack/react-virtual": "3.14.21",
46
46
  "@testing-library/dom": "10.4.2",
47
47
  "@testing-library/react": "16.3.3",
@@ -52,9 +52,11 @@ export default defineConfig({
52
52
  })
53
53
  ```
54
54
 
55
- The default `authorize` is open outside production and requires a bearer token
56
- equal to `DURABLE_DASHBOARD_TOKEN` in production (**fails closed if unset**).
57
- The console mutates runs — always front it with a real guard in production.
55
+ The default `authorize` fails closed in **every** environment: it requires a
56
+ bearer token equal to `DURABLE_DASHBOARD_TOKEN`, denying everything when that
57
+ env var is unset. Open it up explicitly with `dashboardAuth`, your own
58
+ `authorize`, or (local dev only) `allowUnauthenticated: true`.
59
+ The console mutates runs — always front it with a real guard beyond local dev.
58
60
 
59
61
  ## Core patterns
60
62
 
@@ -156,6 +158,25 @@ export default defineConfig({
156
158
  })
157
159
  ```
158
160
 
161
+ Every bridge (`collectMetrics`, `attachDurableMetrics`, `attachDurableOtel`, the
162
+ diagnostics bridge Telescope reads) handles only the events its own instance
163
+ produced; another pod's events, re-delivered over the control plane, are skipped
164
+ (`isRemoteEvent(event)`), so a fleet counts and traces each event once.
165
+
166
+ The mounted dashboard also serves `GET <path>/api/metrics` (these counters plus
167
+ `durable_pending_runs` / `durable_running_runs` / `durable_dead_runs` and
168
+ per-group `durable_group_queue_depth` / `durable_group_live_workers` gauges),
169
+ `GET <path>/api/runs/:id/events/:key` (the latest `ctx.setEvent` value, through
170
+ `redact.checkpoint`) and `POST <path>/api/webhooks/:token` (resumes a run parked
171
+ on a `ctx.webhook()`; `wh:` tokens only, behind the console's guard like every
172
+ route — a callback landing before the run waits is buffered `202 { buffered: true }`
173
+ for a live run that has not consumed it yet, consumed by the later `wait()`;
174
+ unknown, terminal or duplicate tokens answer `404` and buffer nothing).
175
+
176
+ Inside a step, a helper that was never handed the logger records through
177
+ `currentStep()?.info(...)` (from `@adonis-agora/durable`; `undefined` outside a
178
+ step).
179
+
159
180
  Live-tail one run over SSE:
160
181
  `new EventSource('/durable/api/runs/${runId}/stream')`.
161
182
  Source: `docs/observability/events-and-interceptors.mdx`,
@@ -169,7 +190,7 @@ Register the extension once and workflows appear next to requests/queries/jobs:
169
190
  import { durableTelescopeExtension } from '@adonis-agora/durable/telescope'
170
191
 
171
192
  export default defineConfig({
172
- extensions: [durableTelescopeExtension({ runHref: '/durable/runs/{runId}' })],
193
+ extensions: [durableTelescopeExtension({ runHref: '/durable#/run/{runId}' })],
173
194
  })
174
195
  ```
175
196
 
@@ -177,18 +198,22 @@ Rollups (success rate, throughput, duration percentiles, top failures) come from
177
198
  captured entries bounded by Telescope's prune window; current-state gauges
178
199
  (dead/suspended/running/pending NOW) read live from the store via
179
200
  `engine.countRuns` (an exact `COUNT`, falling back to a capped `listRuns`
180
- listing on stores without it).
201
+ listing on stores without it). The **Worker health** table lists every group
202
+ (STARVED first); the **Workers** table has one row per live instance (mode,
203
+ limit, saturation, RAM/CPU, steps/min, p95, last adjustment; `n/a` = no status
204
+ reported, `—` = nothing measured yet). Copies of one event recorded by several
205
+ pods are collapsed by event + runId + emission instant (`dedupeRunEvents`).
181
206
  Per-run actions stay in the durable dashboard. Source:
182
207
  `docs/observability/telescope.mdx`.
183
208
 
184
209
  ## Common mistakes
185
210
 
186
- ### HIGH trusting an "empty" dashboard config in production
211
+ ### HIGH trusting an "empty" dashboard config to serve the console
187
212
 
188
213
  Wrong:
189
214
 
190
215
  ```ts
191
- export default defineConfig({}) // prod, DURABLE_DASHBOARD_TOKEN unset
216
+ export default defineConfig({}) // DURABLE_DASHBOARD_TOKEN unset — every route 403s
192
217
  ```
193
218
 
194
219
  Correct:
@@ -202,9 +227,11 @@ export default defineConfig({
202
227
  })
203
228
  ```
204
229
 
205
- Mechanism: the default authorize fails CLOSED in production when the token env
206
- var is unset, so every console route 403s and the console looks broken rather
207
- than leaking — either set the token deliberately or override authorize.
230
+ Mechanism: the default authorize fails CLOSED in every environment when the
231
+ token env var is unset, so every console route 403s and the console looks
232
+ broken rather than leaking — either set the token deliberately, configure
233
+ `dashboardAuth`, or override authorize (`allowUnauthenticated: true` is the
234
+ explicit local-dev-only opt-out).
208
235
  Source: `docs/observability/dashboard.mdx` ("Authorization").
209
236
 
210
237
  ### HIGH making interceptor outputs depend on time, randomness or external state
@@ -288,4 +315,5 @@ undercounts the fleet and zeroes on every deploy of that pod. Source:
288
315
  See also: `durable-reliability` — what the events mean operationally; bulk
289
316
  cancel + compensate semantics.
290
317
  See also: `durable-cluster` — which verbs proxy over the wire on store-less pods
291
- (`retry-with-input` / `continue` answer 404 there).
318
+ (`retry`, `retry-with-input`, `continue` and the value pickers do; signal /
319
+ update / tasks / events / webhooks / schedules answer 404 there).