@adonis-agora/durable 0.21.1 → 0.22.0

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/assets/spa/assets/index-BpH1yTMa.js +81 -0
  3. package/dist/assets/spa/assets/index-BpH1yTMa.js.map +1 -0
  4. package/dist/assets/spa/assets/index-CTsYsi6p.css +1 -0
  5. package/dist/assets/spa/index.html +19 -0
  6. package/dist/providers/dashboard_provider.d.ts +51 -52
  7. package/dist/providers/dashboard_provider.d.ts.map +1 -1
  8. package/dist/providers/dashboard_provider.js +234 -121
  9. package/dist/providers/dashboard_provider.js.map +1 -1
  10. package/dist/src/dashboard/attr-filter.d.ts +8 -0
  11. package/dist/src/dashboard/attr-filter.d.ts.map +1 -0
  12. package/dist/src/dashboard/attr-filter.js +35 -0
  13. package/dist/src/dashboard/attr-filter.js.map +1 -0
  14. package/dist/src/dashboard/auth.d.ts +55 -10
  15. package/dist/src/dashboard/auth.d.ts.map +1 -1
  16. package/dist/src/dashboard/auth.js +50 -11
  17. package/dist/src/dashboard/auth.js.map +1 -1
  18. package/dist/src/dashboard/gateway-adapter.d.ts +52 -5
  19. package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -1
  20. package/dist/src/dashboard/gateway-adapter.js +48 -6
  21. package/dist/src/dashboard/gateway-adapter.js.map +1 -1
  22. package/dist/src/dashboard/handlers.d.ts +56 -8
  23. package/dist/src/dashboard/handlers.d.ts.map +1 -1
  24. package/dist/src/dashboard/handlers.js +116 -14
  25. package/dist/src/dashboard/handlers.js.map +1 -1
  26. package/dist/src/dashboard/index.d.ts +4 -4
  27. package/dist/src/dashboard/index.d.ts.map +1 -1
  28. package/dist/src/dashboard/index.js +3 -3
  29. package/dist/src/dashboard/index.js.map +1 -1
  30. package/dist/src/dashboard/spa.d.ts +22 -0
  31. package/dist/src/dashboard/spa.d.ts.map +1 -0
  32. package/dist/src/dashboard/spa.js +43 -0
  33. package/dist/src/dashboard/spa.js.map +1 -0
  34. package/dist/src/index.d.ts +1 -1
  35. package/dist/src/index.js +1 -1
  36. package/dist/src/transports/queue-mock-adapter.d.ts +1 -0
  37. package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -1
  38. package/dist/src/transports/queue-mock-adapter.js +1 -0
  39. package/dist/src/transports/queue-mock-adapter.js.map +1 -1
  40. package/dist/stubs/config/durable_dashboard.stub +19 -0
  41. package/package.json +18 -17
@@ -11,15 +11,31 @@ import { type DashboardSession, type DashboardSessionUser } from './session_cook
11
11
  * When left unconfigured the dashboard behaves exactly as before (no login/logout routes, no
12
12
  * session guard).
13
13
  */
14
- /** Host hook validating submitted credentials from the built-in login page. */
14
+ /** Host hook validating submitted credentials from the built-in login page (Mode B — standalone). */
15
15
  export type LoginHook = (username: string, password: string) => Promise<DashboardSessionUser | null> | DashboardSessionUser | null;
16
+ /**
17
+ * Host hook validating the HOST APP's own auth off the raw request (Mode A — SSO / "open from your
18
+ * app"). Receives the underlying platform request object (an AdonisJS `Request['request']`, i.e. the
19
+ * raw Node `IncomingMessage`) rather than an AdonisJS type, so this module stays framework-light and
20
+ * unit-testable with no `HttpContext` — the provider passes it through untouched. Mirrors the NestJS
21
+ * sibling console's `SessionHook` byte-for-byte (same two-mode split).
22
+ */
23
+ export type SessionHook = (request: unknown) => Promise<DashboardSessionUser | null> | DashboardSessionUser | null;
16
24
  /**
17
25
  * Author-facing `dashboardAuth` option on `config/durable_dashboard.ts`. Gates the dashboard behind
18
- * a signed session cookie via the built-in server-rendered login page (`GET <path>/login`) — the
19
- * bundled dashboard SPA stays untouched.
26
+ * a signed session cookie, minted by whichever mode(s) are configured:
27
+ *
28
+ * - Mode B (`login`) — the built-in server-rendered login page (`GET <path>/login`), for a
29
+ * standalone console with its own credentials.
30
+ * - Mode A (`session`) — `POST <path>/session`, for a host app that's already authenticated the
31
+ * operator itself and wants a one-shot "open the console" button (see `client/console-session.ts`).
32
+ *
33
+ * Both may be configured together; at least one is required. The bundled dashboard SPA is unaware of
34
+ * which mode(s) are active — it only reacts to a 401's `{ auth: { modes } }` body (see
35
+ * `durable-client.ts`).
20
36
  *
21
- * Nest needed a `forRootAsync` to reach app services from the `login` hook; AdonisJS does not — the
22
- * config module is a plain file and `login` is just a function that may be `async` and close over
37
+ * Nest needed a `forRootAsync` to reach app services from these hooks; AdonisJS does not — the config
38
+ * module is a plain file and each hook is just a function that may be `async` and close over
23
39
  * `app.container`/services (import them at the top of `config/durable_dashboard.ts`), so there is
24
40
  * nothing extra to build for the async case.
25
41
  */
@@ -30,20 +46,30 @@ export interface DashboardAuthOptions {
30
46
  ttl?: string;
31
47
  /** Validates submitted username/password; return the session user, or `null` to deny. Thrown
32
48
  * errors are treated as a denial (logged once, never surfaced to the client). May be async. */
33
- login: LoginHook;
49
+ login?: LoginHook;
50
+ /** Validates the host app's own auth off the raw request; return the session user, or `null` to
51
+ * deny. Thrown errors are treated as a denial. May be async. */
52
+ session?: SessionHook;
34
53
  }
35
- /** Resolved, validated `dashboardAuth` config shared by the guard, the login handler, and the page. */
54
+ /** Which auth surface(s) are active — carried on an API 401's `{ auth: { modes } }` body so the SPA
55
+ * knows whether to offer the login page or just report "not authenticated". */
56
+ export type AuthMode = 'session' | 'login';
57
+ /** Resolved, validated `dashboardAuth` config shared by the guard, the login/session handlers, and
58
+ * the page. */
36
59
  export interface ResolvedDashboardAuth {
37
60
  secret: string;
38
61
  ttlMs: number;
39
- login: LoginHook;
62
+ modes: AuthMode[];
63
+ login?: LoginHook;
64
+ session?: SessionHook;
40
65
  }
41
66
  /** Cookie name carrying the signed dashboard session. */
42
67
  export declare const SESSION_COOKIE_NAME = "durable_dashboard_session";
43
68
  /**
44
69
  * Validate + resolve the `dashboardAuth` option. Returns `null` when unconfigured (today's
45
70
  * unauthenticated behavior, unchanged). Throws at boot (fail closed) when configured but missing a
46
- * secret or a `login` hook — the host learns immediately rather than shipping an un-mintable gate.
71
+ * secret, or neither `login` nor `session` is a function — the host learns immediately rather than
72
+ * shipping an un-mintable gate.
47
73
  */
48
74
  export declare function resolveDashboardAuth(options: DashboardAuthOptions | undefined): ResolvedDashboardAuth | null;
49
75
  /**
@@ -77,9 +103,28 @@ export type LoginOutcome = {
77
103
  * Decide a login attempt end-to-end (validate body → run hook → mint cookie) with no HTTP types.
78
104
  * On success returns the signed cookie value to set plus the sanitized `redirectTo`; the password
79
105
  * is forwarded to the hook AS-IS (empty string when blank), so the hook alone decides whether a
80
- * password is required.
106
+ * password is required. `404`-worthy (Mode B not configured) is the provider's call, not this
107
+ * function's — it only runs once the provider has confirmed `auth.login` exists.
81
108
  */
82
109
  export declare function performLogin(auth: ResolvedDashboardAuth, body: unknown, basePath: string, now?: number): Promise<LoginOutcome>;
110
+ /**
111
+ * The framework-light outcome of a Mode A session-mint attempt (`POST <path>/session`), mapped to
112
+ * HTTP by the provider: `ok` → set the cookie, reply `204`; `unauthorized` → uniform `401` (the
113
+ * `session` hook returned/threw a denial).
114
+ */
115
+ export type SessionOutcome = {
116
+ kind: 'ok';
117
+ cookieValue: string;
118
+ } | {
119
+ kind: 'unauthorized';
120
+ hookError?: unknown;
121
+ };
122
+ /**
123
+ * Decide a Mode A session-mint attempt end-to-end: run the host's `session` hook against the raw
124
+ * platform request, and mint the cookie on success. No body to validate — the hook reads whatever it
125
+ * needs directly off `request` (its own cookie/JWT/header).
126
+ */
127
+ export declare function performSession(auth: ResolvedDashboardAuth, request: unknown, now?: number): Promise<SessionOutcome>;
83
128
  /**
84
129
  * Read + verify a session cookie value, returning the session or `null` when absent, tampered, or
85
130
  * expired. Thin wrapper over {@link verifySessionCookie} so the provider never touches crypto.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/dashboard/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAG1B,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AAEH,+EAA+E;AAC/E,MAAM,MAAM,SAAS,GAAG,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAAC;AAExE;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;oGACgG;IAChG,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,uGAAuG;AACvG,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,8BAA8B,CAAC;AAoB/D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,oBAAoB,GAAG,SAAS,GACxC,qBAAqB,GAAG,IAAI,CAgB9B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM7E;AAaD;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAqBnE;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,qBAAqB,EAC3B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,CAAC,CAiBvB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,qBAAqB,EAC3B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,CAAC,EAAE,MAAM,GACX,gBAAgB,GAAG,IAAI,CAMzB;AAED,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/dashboard/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAG1B,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AAEH,qGAAqG;AACrG,MAAM,MAAM,SAAS,GAAG,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAAC;AAExE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,oBAAoB;IACnC,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;oGACgG;IAChG,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;qEACiE;IACjE,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED;gFACgF;AAChF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3C;gBACgB;AAChB,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,8BAA8B,CAAC;AAoB/D;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,oBAAoB,GAAG,SAAS,GACxC,qBAAqB,GAAG,IAAI,CA0B9B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM7E;AAaD;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAoBnE;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,qBAAqB,EAC3B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,CAAC,CAuBvB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAElD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,CAAC,CAezB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,qBAAqB,EAC3B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,CAAC,EAAE,MAAM,GACX,gBAAgB,GAAG,IAAI,CAMzB;AAED,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -22,7 +22,8 @@ function durationToMs(ttl) {
22
22
  /**
23
23
  * Validate + resolve the `dashboardAuth` option. Returns `null` when unconfigured (today's
24
24
  * unauthenticated behavior, unchanged). Throws at boot (fail closed) when configured but missing a
25
- * secret or a `login` hook — the host learns immediately rather than shipping an un-mintable gate.
25
+ * secret, or neither `login` nor `session` is a function — the host learns immediately rather than
26
+ * shipping an un-mintable gate.
26
27
  */
27
28
  export function resolveDashboardAuth(options) {
28
29
  if (options === undefined)
@@ -31,13 +32,23 @@ export function resolveDashboardAuth(options) {
31
32
  throw new Error('durable_dashboard: dashboardAuth.secret is required and must be a non-empty string ' +
32
33
  '(HMAC-SHA256 signing key, 32+ bytes recommended). Failing closed.');
33
34
  }
34
- if (typeof options.login !== 'function') {
35
- throw new Error('durable_dashboard: dashboardAuth.login is required (a login hook).');
35
+ const hasLogin = typeof options.login === 'function';
36
+ const hasSession = typeof options.session === 'function';
37
+ if (!hasLogin && !hasSession) {
38
+ throw new Error('durable_dashboard: dashboardAuth needs at least one of `login` or `session` (a login hook or ' +
39
+ 'a host-session hook).');
36
40
  }
41
+ const modes = [];
42
+ if (hasSession)
43
+ modes.push('session');
44
+ if (hasLogin)
45
+ modes.push('login');
37
46
  return {
38
47
  secret: options.secret,
39
48
  ttlMs: durationToMs(options.ttl ?? DEFAULT_TTL),
40
- login: options.login,
49
+ modes,
50
+ ...(hasLogin ? { login: options.login } : {}),
51
+ ...(hasSession ? { session: options.session } : {}),
41
52
  };
42
53
  }
43
54
  /**
@@ -62,13 +73,14 @@ function isString(value) {
62
73
  }
63
74
  const UNAUTHORIZED_MESSAGE = 'Invalid username or password.';
64
75
  /**
65
- * Run the host's `login` hook defensively: a throw is treated as a denial (uniform failure) so a
66
- * buggy hook never 500s the endpoint into a stack-trace leak. The thrown error is surfaced on the
67
- * outcome (`hookError`) so the provider can warn-log it once, but it never reaches the client.
76
+ * Run a host hook (`login` or `session`) defensively: a throw is treated as a denial (uniform
77
+ * failure) so a buggy hook never 500s the endpoint into a stack-trace leak. The thrown error is
78
+ * surfaced on the outcome (`hookError`) so the provider can warn-log it once, but it never reaches
79
+ * the client.
68
80
  */
69
- async function runLoginHook(auth, username, password) {
81
+ async function runHook(hook) {
70
82
  try {
71
- return { user: (await auth.login(username, password)) ?? null };
83
+ return { user: (await hook()) ?? null };
72
84
  }
73
85
  catch (error) {
74
86
  return { user: null, error };
@@ -78,14 +90,19 @@ async function runLoginHook(auth, username, password) {
78
90
  * Decide a login attempt end-to-end (validate body → run hook → mint cookie) with no HTTP types.
79
91
  * On success returns the signed cookie value to set plus the sanitized `redirectTo`; the password
80
92
  * is forwarded to the hook AS-IS (empty string when blank), so the hook alone decides whether a
81
- * password is required.
93
+ * password is required. `404`-worthy (Mode B not configured) is the provider's call, not this
94
+ * function's — it only runs once the provider has confirmed `auth.login` exists.
82
95
  */
83
96
  export async function performLogin(auth, body, basePath, now) {
84
97
  const parsed = (body ?? {});
85
98
  if (!isString(parsed.username) || !isString(parsed.password)) {
86
99
  return { kind: 'bad-request', message: 'Body must include string `username` and `password`.' };
87
100
  }
88
- const { user, error } = await runLoginHook(auth, parsed.username, parsed.password);
101
+ const login = auth.login;
102
+ if (!login) {
103
+ return { kind: 'unauthorized', message: UNAUTHORIZED_MESSAGE };
104
+ }
105
+ const { user, error } = await runHook(() => login(parsed.username, parsed.password));
89
106
  if (!user) {
90
107
  return error !== undefined
91
108
  ? { kind: 'unauthorized', message: UNAUTHORIZED_MESSAGE, hookError: error }
@@ -98,6 +115,28 @@ export async function performLogin(auth, body, basePath, now) {
98
115
  });
99
116
  return { kind: 'ok', cookieValue, redirectTo: sanitizeReturnTo(parsed.returnTo, basePath) };
100
117
  }
118
+ /**
119
+ * Decide a Mode A session-mint attempt end-to-end: run the host's `session` hook against the raw
120
+ * platform request, and mint the cookie on success. No body to validate — the hook reads whatever it
121
+ * needs directly off `request` (its own cookie/JWT/header).
122
+ */
123
+ export async function performSession(auth, request, now) {
124
+ const session = auth.session;
125
+ if (!session)
126
+ return { kind: 'unauthorized' };
127
+ const { user, error } = await runHook(() => session(request));
128
+ if (!user) {
129
+ return error !== undefined
130
+ ? { kind: 'unauthorized', hookError: error }
131
+ : { kind: 'unauthorized' };
132
+ }
133
+ const cookieValue = signSessionCookie(user, {
134
+ secret: auth.secret,
135
+ ttlMs: auth.ttlMs,
136
+ ...(now !== undefined ? { now } : {}),
137
+ });
138
+ return { kind: 'ok', cookieValue };
139
+ }
101
140
  /**
102
141
  * Read + verify a session cookie value, returning the session or `null` when absent, tampered, or
103
142
  * expired. Thin wrapper over {@link verifySessionCookie} so the provider never touches crypto.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/dashboard/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/dashboard/auth.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,65 @@
1
+ import type { EngineEvent, RunResult } from '../interfaces.js';
1
2
  import type { RunGateway } from '../run-gateway/interface.js';
2
3
  import type { DashboardEngine } from './handlers.js';
4
+ /**
5
+ * The slice of {@link import('../engine.js').WorkflowEngine} a store role's {@link
6
+ * storeDashboardEngine} delegates to. Declared structurally (not by importing the concrete class) so
7
+ * this module depends only on the verbs it forwards — mirrors `run-gateway/store-run-gateway.ts`'s
8
+ * `RunGatewayEngine` pattern. The real `WorkflowEngine` is structurally assignable to this (every
9
+ * method here — including `retryWithInput`, `continue`, and the global `subscribe` — already exists
10
+ * on it).
11
+ */
12
+ export interface StoreEngineLike {
13
+ getRun: DashboardEngine['getRun'];
14
+ listRuns: DashboardEngine['listRuns'];
15
+ listCheckpoints: DashboardEngine['listCheckpoints'];
16
+ getRunChildren: DashboardEngine['getRunChildren'];
17
+ requeue: DashboardEngine['requeue'];
18
+ redispatchPending?: DashboardEngine['redispatchPending'];
19
+ cancel: DashboardEngine['cancel'];
20
+ workerHealth: DashboardEngine['workerHealth'];
21
+ retryWithInput(runId: string, input: unknown, newRunId?: string): Promise<{
22
+ runId: string;
23
+ } | null>;
24
+ continue(runId: string): Promise<RunResult | null>;
25
+ /** The engine's GLOBAL listener (every run) — {@link storeDashboardEngine} filters it to one run,
26
+ * same as `StoreRunGateway.subscribe` does. */
27
+ subscribe(listener: (event: EngineEvent) => void): () => void;
28
+ }
29
+ /**
30
+ * Adapt a store-backed {@link import('../engine.js').WorkflowEngine} to the {@link DashboardEngine}
31
+ * port — an explicit wrapper (not a raw `as DashboardEngine` cast) because two verbs need shape
32
+ * bridging, not just a type assertion:
33
+ * - `subscribe(runId, onEvent)` — the engine's `subscribe` is a GLOBAL listener with no `runId`
34
+ * filter; this narrows it to one run's events, byte-for-byte the same filter `StoreRunGateway`
35
+ * already applies.
36
+ * - `redispatchPending` — degrades to `null` when the engine lacks it (kept optional for the same
37
+ * reason `RunGatewayEngine.redispatchPending` is: not every engine build has it yet).
38
+ * Every other verb (including `retryWithInput`/`continue`, which the AdonisJS engine already
39
+ * implements) forwards 1:1 — behavior unchanged from a plain cast for those.
40
+ */
41
+ export declare function storeDashboardEngine(engine: StoreEngineLike): DashboardEngine;
3
42
  /**
4
43
  * Adapt a {@link RunGateway} to the {@link DashboardEngine} port the JSON handlers drive, so a
5
44
  * **store-less `tenant` pod** serves the SAME dashboard over the wire (design §8) — every read/control
6
45
  * verb round-trips through the pod's `ProxyRunGateway` to the control plane, with NO local store or
7
46
  * engine. Store presence stays invisible above the handler line.
8
47
  *
9
- * The gateway is a near-superset of the port; two verbs need bridging:
48
+ * The gateway is a near-superset of the port; three verbs need bridging:
10
49
  * - `listCheckpoints` → the gateway's `getCheckpoints` (same shape, §8 naming);
11
50
  * - `requeue` → the gateway's `redispatchPending` (the operator recovery verb; the extra
12
- * `redispatched` count on the result is a harmless superset of `RunResult`).
51
+ * `redispatched` count on the result is a harmless superset of `RunResult`);
52
+ * - `subscribe(runId, onEvent)` → the gateway's own per-run `subscribe` (already scoped, no filtering
53
+ * needed here — unlike the store-role adapter above).
13
54
  *
14
- * `getRunChildren` (parent→child fan-out) now rides the P4 read surface too (a `getRunChildren`
55
+ * `getRunChildren` (parent→child fan-out) rides the P4 read surface too (a `getRunChildren`
15
56
  * `RunRequestKind` verb), so a store-less tenant pod's run detail view lists children round-tripped over
16
57
  * the wire — the responder enforces the tenant-ownership check before answering (anti-IDOR).
58
+ *
59
+ * `retryWithInput`/`continue` have NO gateway verb yet (design §8 didn't need fix-and-replay or
60
+ * breakpoint-continue over the wire) — they degrade to `null`, same convention as
61
+ * `RunGatewayEngine.redispatchPending`'s optional degrade. A tenant pod's dashboard therefore shows
62
+ * these actions as unavailable (the handlers 404) until the wire protocol grows the verbs.
17
63
  */
18
64
  export declare function gatewayDashboardEngine(gateway: RunGateway): DashboardEngine;
19
65
  /** The minimal container surface {@link dashboardEngineForRole} resolves bindings through. */
@@ -27,8 +73,9 @@ export interface DashboardContainer {
27
73
  * - **`tenant`** (store-less): resolve the {@link DURABLE_RUN_GATEWAY} token (a `ProxyRunGateway`) and
28
74
  * adapt it — the engine binding is deliberately ABSENT on a tenant pod (structural isolation), so we
29
75
  * MUST NOT reach for `WorkflowEngine` here;
30
- * - **store roles** (`standalone`/`control-plane`): resolve the concrete `WorkflowEngine` (structurally a
31
- * {@link DashboardEngine}) exactly as before — behavior byte-for-byte unchanged.
76
+ * - **store roles** (`standalone`/`control-plane`): resolve the concrete `WorkflowEngine` and adapt it
77
+ * via {@link storeDashboardEngine} — every verb still forwards 1:1, just through an explicit wrapper
78
+ * instead of a raw cast (see that function's doc for why).
32
79
  *
33
80
  * `engineToken` is injected (rather than imported) so the module doesn't hard-depend on the engine class
34
81
  * for the tenant path — the tenant branch never touches it.
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-adapter.d.ts","sourceRoot":"","sources":["../../../src/dashboard/gateway-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,UAAU,GAAG,eAAe,CAW3E;AAED,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,YAAY,GAAG,eAAe,GAAG,QAAQ,EAC/C,SAAS,EAAE,kBAAkB,EAC7B,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,eAAe,CAAC,CAM1B"}
1
+ {"version":3,"file":"gateway-adapter.d.ts","sourceRoot":"","sources":["../../../src/dashboard/gateway-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClC,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACtC,eAAe,EAAE,eAAe,CAAC,iBAAiB,CAAC,CAAC;IACpD,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAClD,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACpC,iBAAiB,CAAC,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC;IACzD,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClC,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC;IAC9C,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACnD;oDACgD;IAChD,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAiB7E;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,UAAU,GAAG,eAAe,CAc3E;AAED,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,YAAY,GAAG,eAAe,GAAG,QAAQ,EAC/C,SAAS,EAAE,kBAAkB,EAC7B,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,eAAe,CAAC,CAO1B"}
@@ -1,18 +1,55 @@
1
1
  import { DURABLE_RUN_GATEWAY } from '../role_bindings.js';
2
+ /**
3
+ * Adapt a store-backed {@link import('../engine.js').WorkflowEngine} to the {@link DashboardEngine}
4
+ * port — an explicit wrapper (not a raw `as DashboardEngine` cast) because two verbs need shape
5
+ * bridging, not just a type assertion:
6
+ * - `subscribe(runId, onEvent)` — the engine's `subscribe` is a GLOBAL listener with no `runId`
7
+ * filter; this narrows it to one run's events, byte-for-byte the same filter `StoreRunGateway`
8
+ * already applies.
9
+ * - `redispatchPending` — degrades to `null` when the engine lacks it (kept optional for the same
10
+ * reason `RunGatewayEngine.redispatchPending` is: not every engine build has it yet).
11
+ * Every other verb (including `retryWithInput`/`continue`, which the AdonisJS engine already
12
+ * implements) forwards 1:1 — behavior unchanged from a plain cast for those.
13
+ */
14
+ export function storeDashboardEngine(engine) {
15
+ return {
16
+ getRun: (runId) => engine.getRun(runId),
17
+ listRuns: (query) => engine.listRuns(query),
18
+ listCheckpoints: (runId) => engine.listCheckpoints(runId),
19
+ getRunChildren: (runId) => engine.getRunChildren(runId),
20
+ requeue: (runId) => engine.requeue(runId),
21
+ redispatchPending: (runId) => engine.redispatchPending?.(runId) ?? Promise.resolve(null),
22
+ cancel: (runId, opts) => engine.cancel(runId, opts),
23
+ workerHealth: (extra) => engine.workerHealth(extra),
24
+ retryWithInput: (runId, input) => engine.retryWithInput(runId, input),
25
+ continue: (runId) => engine.continue(runId),
26
+ subscribe: (runId, onEvent) => engine.subscribe((event) => {
27
+ if (event.runId === runId)
28
+ onEvent(event);
29
+ }),
30
+ };
31
+ }
2
32
  /**
3
33
  * Adapt a {@link RunGateway} to the {@link DashboardEngine} port the JSON handlers drive, so a
4
34
  * **store-less `tenant` pod** serves the SAME dashboard over the wire (design §8) — every read/control
5
35
  * verb round-trips through the pod's `ProxyRunGateway` to the control plane, with NO local store or
6
36
  * engine. Store presence stays invisible above the handler line.
7
37
  *
8
- * The gateway is a near-superset of the port; two verbs need bridging:
38
+ * The gateway is a near-superset of the port; three verbs need bridging:
9
39
  * - `listCheckpoints` → the gateway's `getCheckpoints` (same shape, §8 naming);
10
40
  * - `requeue` → the gateway's `redispatchPending` (the operator recovery verb; the extra
11
- * `redispatched` count on the result is a harmless superset of `RunResult`).
41
+ * `redispatched` count on the result is a harmless superset of `RunResult`);
42
+ * - `subscribe(runId, onEvent)` → the gateway's own per-run `subscribe` (already scoped, no filtering
43
+ * needed here — unlike the store-role adapter above).
12
44
  *
13
- * `getRunChildren` (parent→child fan-out) now rides the P4 read surface too (a `getRunChildren`
45
+ * `getRunChildren` (parent→child fan-out) rides the P4 read surface too (a `getRunChildren`
14
46
  * `RunRequestKind` verb), so a store-less tenant pod's run detail view lists children round-tripped over
15
47
  * the wire — the responder enforces the tenant-ownership check before answering (anti-IDOR).
48
+ *
49
+ * `retryWithInput`/`continue` have NO gateway verb yet (design §8 didn't need fix-and-replay or
50
+ * breakpoint-continue over the wire) — they degrade to `null`, same convention as
51
+ * `RunGatewayEngine.redispatchPending`'s optional degrade. A tenant pod's dashboard therefore shows
52
+ * these actions as unavailable (the handlers 404) until the wire protocol grows the verbs.
16
53
  */
17
54
  export function gatewayDashboardEngine(gateway) {
18
55
  return {
@@ -24,6 +61,9 @@ export function gatewayDashboardEngine(gateway) {
24
61
  redispatchPending: (runId) => gateway.redispatchPending(runId),
25
62
  cancel: (runId, opts) => gateway.cancel(runId, opts),
26
63
  workerHealth: () => gateway.workerHealth(),
64
+ retryWithInput: () => Promise.resolve(null),
65
+ continue: () => Promise.resolve(null),
66
+ subscribe: (runId, onEvent) => gateway.subscribe(runId, onEvent),
27
67
  };
28
68
  }
29
69
  /**
@@ -33,8 +73,9 @@ export function gatewayDashboardEngine(gateway) {
33
73
  * - **`tenant`** (store-less): resolve the {@link DURABLE_RUN_GATEWAY} token (a `ProxyRunGateway`) and
34
74
  * adapt it — the engine binding is deliberately ABSENT on a tenant pod (structural isolation), so we
35
75
  * MUST NOT reach for `WorkflowEngine` here;
36
- * - **store roles** (`standalone`/`control-plane`): resolve the concrete `WorkflowEngine` (structurally a
37
- * {@link DashboardEngine}) exactly as before — behavior byte-for-byte unchanged.
76
+ * - **store roles** (`standalone`/`control-plane`): resolve the concrete `WorkflowEngine` and adapt it
77
+ * via {@link storeDashboardEngine} — every verb still forwards 1:1, just through an explicit wrapper
78
+ * instead of a raw cast (see that function's doc for why).
38
79
  *
39
80
  * `engineToken` is injected (rather than imported) so the module doesn't hard-depend on the engine class
40
81
  * for the tenant path — the tenant branch never touches it.
@@ -44,6 +85,7 @@ export async function dashboardEngineForRole(role, container, engineToken) {
44
85
  const gateway = (await container.make(DURABLE_RUN_GATEWAY));
45
86
  return gatewayDashboardEngine(gateway);
46
87
  }
47
- return (await container.make(engineToken));
88
+ const engine = (await container.make(engineToken));
89
+ return storeDashboardEngine(engine);
48
90
  }
49
91
  //# sourceMappingURL=gateway-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/dashboard/gateway-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI1D;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAmB;IACxD,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;QACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC5C,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC;QACzD,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC;QACxD,OAAO,EAAE,CAAC,KAAK,EAA6B,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC;QAC/E,iBAAiB,EAAE,CAAC,KAAK,EAA6B,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC;QACzF,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC;QACpD,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE;KAC3C,CAAC;AACJ,CAAC;AAOD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAA+C,EAC/C,SAA6B,EAC7B,WAAoB;IAEpB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAe,CAAC;QAC1E,OAAO,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAoB,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"gateway-adapter.js","sourceRoot":"","sources":["../../../src/dashboard/gateway-adapter.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { GroupHealth, RunQuery, RunResult, StepCheckpoint, WorkflowRun } from '../index.js';
1
+ import type { EngineEvent, GroupHealth, RunQuery, RunResult, StepCheckpoint, WorkflowRun } from '../index.js';
2
2
  /**
3
3
  * Framework-light JSON handlers over a {@link DashboardEngine}.
4
4
  *
@@ -11,15 +11,24 @@ import type { GroupHealth, RunQuery, RunResult, StepCheckpoint, WorkflowRun } fr
11
11
  * leak in, so the handlers are unit-testable against a real in-memory engine
12
12
  * with no HTTP server. The provider adapts an AdonisJS `HttpContext` to these
13
13
  * shapes.
14
+ *
15
+ * `listRuns`/`getRun`/`retryRun`/`redispatchPendingRun`/`cancelRun`/`health` are the original
16
+ * handlers this file always had (kept response-shape compatible with the legacy static
17
+ * `assets/dashboard.html`, still served as a compat fallback — see `compat.ts`/`compat-view.ts`).
18
+ * `workers`, `topology`, `retryWithInputRun`, `continueRun`, and `bulkAction` are additions that give
19
+ * the new `@adonis-agora/durable-dashboard` React SPA parity with `@dudousxd/nestjs-durable-dashboard`'s
20
+ * `DurableApiController` (fix-and-replay, bulk retry/cancel, breakpoint continue, full worker
21
+ * heartbeats, topology badge). The SSE `runs/:id/stream` route is wired directly in
22
+ * `providers/dashboard_provider.ts` since streaming needs the raw HTTP response, not a JSON `ApiResponse`.
14
23
  */
15
24
  /**
16
25
  * The bounded read/control surface the JSON handlers drive — declared STRUCTURALLY (a port), not by
17
26
  * importing the concrete `WorkflowEngine` class, so the same handlers serve BOTH durable topologies
18
- * (design §8): a store role passes the real {@link import('../engine.js').WorkflowEngine} (structurally
19
- * assignable — it has every method here); a store-less `tenant` pod passes an adapter over its
20
- * {@link import('../run-gateway/interface.js').RunGateway} (see `gatewayDashboardEngine`). Store presence
21
- * is therefore invisible to the handlers. Mirrors the `RunGatewayEngine` port pattern already used by
22
- * `StoreRunGateway`.
27
+ * (design §8): a store role passes an adapter over the real {@link
28
+ * import('../engine.js').WorkflowEngine} (`storeDashboardEngine`); a store-less `tenant` pod passes an
29
+ * adapter over its {@link import('../run-gateway/interface.js').RunGateway} (`gatewayDashboardEngine`).
30
+ * Store presence is therefore invisible to the handlers. Mirrors the `RunGatewayEngine` port pattern
31
+ * already used by `StoreRunGateway`.
23
32
  */
24
33
  export interface DashboardEngine {
25
34
  getRun(runId: string): Promise<WorkflowRun | null>;
@@ -32,6 +41,17 @@ export interface DashboardEngine {
32
41
  compensate?: boolean;
33
42
  }): Promise<RunResult | null>;
34
43
  workerHealth(extra?: string[]): Promise<GroupHealth[]>;
44
+ /** Fix-and-replay: start a fresh linked run from `runId`'s workflow with a corrected `input`. Returns
45
+ * the new run's id, or `null` if `runId` is unknown. Degrades to `null` on a topology that can't
46
+ * perform it yet (a store-less `tenant` pod — see `gateway-adapter.ts`). */
47
+ retryWithInput(runId: string, input: unknown): Promise<{
48
+ runId: string;
49
+ } | null>;
50
+ /** Resume a run paused at a `ctx.breakpoint()`. Returns `null` if the run isn't paused at one, or on
51
+ * a topology that can't perform it yet (see `retryWithInput`). */
52
+ continue(runId: string): Promise<RunResult | null>;
53
+ /** Live lifecycle events for ONE run; returns an unsubscribe fn. */
54
+ subscribe(runId: string, onEvent: (event: EngineEvent) => void): () => void;
35
55
  }
36
56
  /** The read/control port the handlers operate over (a store engine or a tenant gateway adapter). */
37
57
  export interface Deps {
@@ -53,7 +73,7 @@ export interface ApiResponse {
53
73
  }
54
74
  /** A `200 OK` JSON response. Exported so sibling handlers (e.g. `compat`) share one convention. */
55
75
  export declare const ok: (body: unknown) => ApiResponse;
56
- /** `GET /runs` — list runs filtered by status/workflow/tag, paginated. */
76
+ /** `GET /runs` — list runs filtered by status/workflow/tag/namespace/search-attributes, paginated. */
57
77
  export declare function listRuns(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
58
78
  /** `GET /runs/:id` — a run's detail: the run, its step timeline, and child run ids. */
59
79
  export declare function getRun(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
@@ -72,6 +92,34 @@ export declare function retryRun(deps: Deps, req: ApiRequest): Promise<ApiRespon
72
92
  export declare function redispatchPendingRun(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
73
93
  /** `POST /runs/:id/cancel` — cancel a run. Pass `{ compensate: true }` to undo the saga first. */
74
94
  export declare function cancelRun(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
75
- /** `GET /health` — per-group worker health (queue backlog + live worker heartbeats). */
95
+ /**
96
+ * `POST /runs/:id/retry-with-input` — fix-and-replay: start a fresh linked run of `runId`'s workflow
97
+ * with a corrected `input`. Body: `{ input: unknown }`. Returns the new run's id; the ORIGINAL run is
98
+ * left untouched (mirrors `@dudousxd/nestjs-durable-dashboard`'s `retryWithInput`).
99
+ */
100
+ export declare function retryWithInputRun(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
101
+ /**
102
+ * `POST /runs/:id/continue` — resume a run paused at a {@link import('../interfaces.js').WorkflowCtx}
103
+ * breakpoint (the dashboard's "continue" button). `404` if the run isn't paused at one.
104
+ */
105
+ export declare function continueRun(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
106
+ /**
107
+ * `POST /bulk/:action` (`action` = `retry`|`cancel`) — apply an action to every run matching the same
108
+ * filter `listRuns` accepts (status/workflow/tag/namespace/attr), capped at 500 matches. Skips (does
109
+ * not abort on) a run that can't take the action (e.g. already terminal). Mirrors
110
+ * `@dudousxd/nestjs-durable-dashboard`'s `DashboardService.bulk`.
111
+ */
112
+ export declare function bulkAction(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
113
+ /** `GET /health` — per-group worker health (queue backlog + live worker heartbeats), reduced to a
114
+ * compact shape. Kept for the legacy static dashboard (`assets/dashboard.html`, compat fallback). */
76
115
  export declare function health(deps: Deps): Promise<ApiResponse>;
116
+ /** `GET /workers` — full per-group worker health (every live worker's heartbeat, not just a count),
117
+ * for the new SPA's Workers panel (`pivot-by-worker.ts`/`group-by-partition.ts` need per-instance
118
+ * `instanceId`/`lastBeatAt`). Raw `GroupHealth[]`, unwrapped — matches
119
+ * `@dudousxd/nestjs-durable-dashboard`'s `GET /workers` shape byte for byte (minus the `status`
120
+ * telemetry field, which the AdonisJS engine's heartbeat doesn't carry — see `durable-client.ts`). */
121
+ export declare function workers(deps: Deps): Promise<ApiResponse>;
122
+ /** `GET /topology` — this deployment's durable role, for the header badge. Pure/local (no engine
123
+ * round-trip): the role is already known by `dashboard_provider.ts` from `config/durable.ts`. */
124
+ export declare function topology(role: 'standalone' | 'control-plane' | 'tenant', tenant?: string): ApiResponse;
77
125
  //# sourceMappingURL=handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/dashboard/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,QAAQ,EACR,SAAS,EAET,cAAc,EACd,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;GAYG;AAEH;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC1D,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAClD,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAClF,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CACxD;AAED,oGAAoG;AACpG,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACrD,2CAA2C;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,mGAAmG;AACnG,eAAO,MAAM,EAAE,GAAI,MAAM,OAAO,KAAG,WAAsC,CAAC;AAqC1E,0EAA0E;AAC1E,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBhF;AAED,uFAAuF;AACvF,wBAAsB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAe9E;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAMhF;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAM5F;AAED,kGAAkG;AAClG,wBAAsB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAUjF;AAED,wFAAwF;AACxF,wBAAsB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAW7D"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/dashboard/handlers.ts"],"names":[],"mappings":"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"}