@rahdar/plugin-sdk 0.0.0 → 2026.10.50

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 (154) hide show
  1. package/README.md +38 -0
  2. package/index.js +52 -0
  3. package/package.json +46 -1
  4. package/peers.json +8 -0
  5. package/shared.d.ts +3 -0
  6. package/shared.js +24 -0
  7. package/types/branding.d.ts +14 -0
  8. package/types/kernel/actions/ActionHost.d.ts +16 -0
  9. package/types/kernel/actions/hostContext.d.ts +4 -0
  10. package/types/kernel/actions/types.d.ts +130 -0
  11. package/types/kernel/api/paging.d.ts +39 -0
  12. package/types/kernel/api/polling.d.ts +37 -0
  13. package/types/kernel/api/request.d.ts +84 -0
  14. package/types/kernel/api/schema.d.ts +24077 -0
  15. package/types/kernel/approvals/ApprovalView.d.ts +6 -0
  16. package/types/kernel/approvals/ApprovalsView.d.ts +7 -0
  17. package/types/kernel/approvals/ApproverQuorumNotice.d.ts +8 -0
  18. package/types/kernel/approvals/BreakGlassBanner.d.ts +5 -0
  19. package/types/kernel/approvals/CancelRequest.d.ts +13 -0
  20. package/types/kernel/approvals/DecisionPanel.d.ts +11 -0
  21. package/types/kernel/approvals/ExpiresIn.d.ts +10 -0
  22. package/types/kernel/approvals/MyRequests.d.ts +5 -0
  23. package/types/kernel/approvals/Recap.d.ts +9 -0
  24. package/types/kernel/approvals/api.d.ts +130 -0
  25. package/types/kernel/approvals/columns.d.ts +22 -0
  26. package/types/kernel/approvals/words.d.ts +31 -0
  27. package/types/kernel/auth/Can.d.ts +9 -0
  28. package/types/kernel/auth/LoginView.d.ts +9 -0
  29. package/types/kernel/auth/SecondFactorForm.d.ts +25 -0
  30. package/types/kernel/auth/StepUp.d.ts +17 -0
  31. package/types/kernel/auth/api.d.ts +115 -0
  32. package/types/kernel/auth/freshSignIn.d.ts +2 -0
  33. package/types/kernel/auth/useCan.d.ts +49 -0
  34. package/types/kernel/auth/webauthn.d.ts +19 -0
  35. package/types/kernel/feature.d.ts +90 -0
  36. package/types/kernel/features.d.ts +5 -0
  37. package/types/kernel/inbox/InboxBell.d.ts +6 -0
  38. package/types/kernel/inbox/InboxView.d.ts +6 -0
  39. package/types/kernel/inbox/NoticeRow.d.ts +17 -0
  40. package/types/kernel/inbox/api.d.ts +53 -0
  41. package/types/kernel/keyboard/ShortcutsHelp.d.ts +6 -0
  42. package/types/kernel/keyboard/filterShortcut.d.ts +5 -0
  43. package/types/kernel/keyboard/keys.d.ts +14 -0
  44. package/types/kernel/keyboard/shortcuts.d.ts +5 -0
  45. package/types/kernel/keyboard/useKeySequences.d.ts +16 -0
  46. package/types/kernel/manifest.d.ts +21 -0
  47. package/types/kernel/metrics/ChartPanel.d.ts +28 -0
  48. package/types/kernel/metrics/MetricChart.d.ts +13 -0
  49. package/types/kernel/metrics/axis.d.ts +71 -0
  50. package/types/kernel/metrics/pluginSeries.d.ts +17 -0
  51. package/types/kernel/nav/currentView.d.ts +21 -0
  52. package/types/kernel/nav/groups.d.ts +22 -0
  53. package/types/kernel/plugins/PluginBoundary.d.ts +25 -0
  54. package/types/kernel/plugins/PluginUnavailable.d.ts +6 -0
  55. package/types/kernel/plugins/boot.d.ts +33 -0
  56. package/types/kernel/plugins/guarded.d.ts +3 -0
  57. package/types/kernel/plugins/usePluginsChanged.d.ts +6 -0
  58. package/types/kernel/plugins/validate.d.ts +19 -0
  59. package/types/kernel/registry.d.ts +12 -0
  60. package/types/kernel/routing/roots.d.ts +24 -0
  61. package/types/kernel/shell/AccountView.d.ts +11 -0
  62. package/types/kernel/shell/AdminView.d.ts +7 -0
  63. package/types/kernel/shell/Breadcrumb.d.ts +6 -0
  64. package/types/kernel/shell/ClusterLayout.d.ts +14 -0
  65. package/types/kernel/shell/ClusterViewNav.d.ts +13 -0
  66. package/types/kernel/shell/CommandPalette.d.ts +15 -0
  67. package/types/kernel/shell/FeatureDisabled.d.ts +13 -0
  68. package/types/kernel/shell/FeatureGate.d.ts +12 -0
  69. package/types/kernel/shell/FreshnessBar.d.ts +11 -0
  70. package/types/kernel/shell/GlobalContext.d.ts +7 -0
  71. package/types/kernel/shell/HomeView.d.ts +6 -0
  72. package/types/kernel/shell/NavGroup.d.ts +13 -0
  73. package/types/kernel/shell/NavItem.d.ts +33 -0
  74. package/types/kernel/shell/NavToggle.d.ts +13 -0
  75. package/types/kernel/shell/RootLayout.d.ts +15 -0
  76. package/types/kernel/shell/SectionNav.d.ts +41 -0
  77. package/types/kernel/shell/UserMenu.d.ts +10 -0
  78. package/types/kernel/shell/lastPlace.d.ts +17 -0
  79. package/types/kernel/shell/pageTitle.d.ts +13 -0
  80. package/types/kernel/shell/recents.d.ts +16 -0
  81. package/types/kernel/shell/useColorSchemeToggle.d.ts +10 -0
  82. package/types/kernel/shell/useFreshness.d.ts +25 -0
  83. package/types/kernel/shell/useNavCollapsed.d.ts +14 -0
  84. package/types/kernel/slots.d.ts +206 -0
  85. package/types/kernel/stream/sse.d.ts +22 -0
  86. package/types/kernel/stream/useClusterStream.d.ts +27 -0
  87. package/types/kernel/stream/useUserStream.d.ts +11 -0
  88. package/types/kernel/time/Ago.d.ts +9 -0
  89. package/types/kernel/time/ranges.d.ts +32 -0
  90. package/types/kernel/time/time.d.ts +89 -0
  91. package/types/kernel/time/timezone.d.ts +44 -0
  92. package/types/kernel/useDismissedNotice.d.ts +3 -0
  93. package/types/sdk/index.d.ts +92 -0
  94. package/types/ui/ActionMenuItem.d.ts +27 -0
  95. package/types/ui/AnchoredMenu.d.ts +20 -0
  96. package/types/ui/CapabilityGate.d.ts +23 -0
  97. package/types/ui/CapabilityReason.d.ts +11 -0
  98. package/types/ui/CodeEditor.d.ts +31 -0
  99. package/types/ui/ConfirmDialog.d.ts +51 -0
  100. package/types/ui/DescriptionList.d.ts +26 -0
  101. package/types/ui/DiagramView.d.ts +35 -0
  102. package/types/ui/DialogActions.d.ts +26 -0
  103. package/types/ui/EmptyState.d.ts +42 -0
  104. package/types/ui/ErrorState.d.ts +36 -0
  105. package/types/ui/FieldRow.d.ts +9 -0
  106. package/types/ui/HeldRequestLink.d.ts +4 -0
  107. package/types/ui/HoldToConfirm.d.ts +22 -0
  108. package/types/ui/LoadingState.d.ts +16 -0
  109. package/types/ui/NodeOutcomeSummary.d.ts +59 -0
  110. package/types/ui/Notice.d.ts +18 -0
  111. package/types/ui/Page.d.ts +13 -0
  112. package/types/ui/PageHeader.d.ts +18 -0
  113. package/types/ui/Pager.d.ts +21 -0
  114. package/types/ui/Section.d.ts +22 -0
  115. package/types/ui/Stat.d.ts +20 -0
  116. package/types/ui/StatusBadge.d.ts +11 -0
  117. package/types/ui/Toolbar.d.ts +19 -0
  118. package/types/ui/capabilityGate.d.ts +43 -0
  119. package/types/ui/codeDiagnostics.d.ts +11 -0
  120. package/types/ui/codeMirrorTheme.d.ts +11 -0
  121. package/types/ui/diagram.d.ts +49 -0
  122. package/types/ui/errorReading.d.ts +30 -0
  123. package/types/ui/formErrors.d.ts +10 -0
  124. package/types/ui/graph/ViewControls.d.ts +19 -0
  125. package/types/ui/graph/elk.d.ts +3 -0
  126. package/types/ui/held.d.ts +12 -0
  127. package/types/ui/inAppNavigation.d.ts +5 -0
  128. package/types/ui/nodeOutcome.d.ts +13 -0
  129. package/types/ui/notify.d.ts +77 -0
  130. package/types/ui/safeHref.d.ts +8 -0
  131. package/types/ui/table/ColumnsMenu.d.ts +26 -0
  132. package/types/ui/table/DataTable.d.ts +109 -0
  133. package/types/ui/table/GridFind.d.ts +16 -0
  134. package/types/ui/table/GridTable.d.ts +49 -0
  135. package/types/ui/table/HeaderCell.d.ts +25 -0
  136. package/types/ui/table/MiddleTruncate.d.ts +21 -0
  137. package/types/ui/table/StaticTable.d.ts +14 -0
  138. package/types/ui/table/TableStates.d.ts +35 -0
  139. package/types/ui/table/columns.d.ts +49 -0
  140. package/types/ui/table/density.d.ts +13 -0
  141. package/types/ui/table/gridFind.d.ts +7 -0
  142. package/types/ui/table/index.d.ts +5 -0
  143. package/types/ui/table/layout.d.ts +48 -0
  144. package/types/ui/table/measure.d.ts +16 -0
  145. package/types/ui/table/measurement.d.ts +92 -0
  146. package/types/ui/table/menuAnchor.d.ts +12 -0
  147. package/types/ui/table/rovingGrid.d.ts +37 -0
  148. package/types/ui/table/sort.d.ts +14 -0
  149. package/types/ui/table/tableState.d.ts +51 -0
  150. package/types/ui/table/useGridFind.d.ts +18 -0
  151. package/types/ui/trustedTypes.d.ts +16 -0
  152. package/types/ui/useTruncated.d.ts +8 -0
  153. package/vite.d.ts +14 -0
  154. package/vite.js +62 -0
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @rahdar/plugin-sdk
2
+
3
+ Build the UI of an [Rahdar](https://github.com/sudoitir/rahdar) plugin.
4
+
5
+ - **Typings** for everything a plugin's UI may use from Rahdar: routes under Rahdar's own roots, slots,
6
+ navigation, the API client, permission checks and shared components. At runtime Rahdar provides
7
+ the SDK itself, so a plugin's bundle never contains a copy.
8
+ - **A Vite preset** that builds the UI as a Module Federation remote taking React, Mantine and
9
+ TanStack from Rahdar.
10
+
11
+ ```ts
12
+ // vite.config.ts
13
+ import { defineConfig } from 'vite';
14
+ import react from '@vitejs/plugin-react';
15
+ import { rahdarPlugin } from '@rahdar/plugin-sdk/vite';
16
+
17
+ export default defineConfig({ plugins: [react(), rahdarPlugin({ id: 'acme-notes' })] });
18
+ ```
19
+
20
+ ```tsx
21
+ // src/feature.tsx
22
+ import { createRoute } from '@tanstack/react-router';
23
+ import { CONTRACT, clusterRoute, definePlugin, pluginPath, pluginView } from '@rahdar/plugin-sdk';
24
+
25
+ const notes = createRoute({
26
+ getParentRoute: () => clusterRoute,
27
+ path: pluginPath('acme-notes', 'notes'),
28
+ component: pluginView('acme-notes', NotesView),
29
+ });
30
+
31
+ export default definePlugin({ contract: CONTRACT, id: 'acme-notes', routes: { cluster: [notes] } });
32
+ ```
33
+
34
+ The SDK's version is the Rahdar version it was built from, and its peer dependencies are the exact
35
+ React, Mantine and TanStack versions that Rahdar ships. Build against the SDK of the oldest Rahdar
36
+ your plugin supports (`rahdar.since` in `plugin.json`).
37
+
38
+ The guide: <https://rahdar.dev/guide/plugins>.
package/index.js ADDED
@@ -0,0 +1,52 @@
1
+ // Generated by build.mjs. Rahdar provides this module at runtime; these names exist so a
2
+ // plugin's build knows what it imports. Running a plugin outside Rahdar fails here, loudly.
3
+ const outsideRahdar = (name) => () => {
4
+ throw new Error(`${name}: @rahdar/plugin-sdk is provided by Rahdar at runtime; load this plugin in Rahdar.`);
5
+ };
6
+ export const ACTION_SECTIONS = outsideRahdar('ACTION_SECTIONS');
7
+ export const ADMIN_GROUPS = outsideRahdar('ADMIN_GROUPS');
8
+ export const ActionMenuItem = outsideRahdar('ActionMenuItem');
9
+ export const ApiError = outsideRahdar('ApiError');
10
+ export const CONTRACT = outsideRahdar('CONTRACT');
11
+ export const CapabilityGate = outsideRahdar('CapabilityGate');
12
+ export const CodeEditor = outsideRahdar('CodeEditor');
13
+ export const ConfirmDialog = outsideRahdar('ConfirmDialog');
14
+ export const DataTable = outsideRahdar('DataTable');
15
+ export const DescriptionList = outsideRahdar('DescriptionList');
16
+ export const DiagramView = outsideRahdar('DiagramView');
17
+ export const EmptyState = outsideRahdar('EmptyState');
18
+ export const ErrorState = outsideRahdar('ErrorState');
19
+ export const FieldRow = outsideRahdar('FieldRow');
20
+ export const HoldToConfirm = outsideRahdar('HoldToConfirm');
21
+ export const LoadingState = outsideRahdar('LoadingState');
22
+ export const METRIC_RANGES = outsideRahdar('METRIC_RANGES');
23
+ export const MetricChart = outsideRahdar('MetricChart');
24
+ export const NAV_GROUPS = outsideRahdar('NAV_GROUPS');
25
+ export const NodeOutcomeSummary = outsideRahdar('NodeOutcomeSummary');
26
+ export const Notice = outsideRahdar('Notice');
27
+ export const OperationHeldError = outsideRahdar('OperationHeldError');
28
+ export const OutcomeSummary = outsideRahdar('OutcomeSummary');
29
+ export const Page = outsideRahdar('Page');
30
+ export const PageHeader = outsideRahdar('PageHeader');
31
+ export const Pager = outsideRahdar('Pager');
32
+ export const SETTINGS_GROUPS = outsideRahdar('SETTINGS_GROUPS');
33
+ export const Section = outsideRahdar('Section');
34
+ export const Stat = outsideRahdar('Stat');
35
+ export const StatusBadge = outsideRahdar('StatusBadge');
36
+ export const StepUpPrompt = outsideRahdar('StepUpPrompt');
37
+ export const Toolbar = outsideRahdar('Toolbar');
38
+ export const clusterKey = outsideRahdar('clusterKey');
39
+ export const clusterRoute = outsideRahdar('clusterRoute');
40
+ export const definePlugin = outsideRahdar('definePlugin');
41
+ export const gateFor = outsideRahdar('gateFor');
42
+ export const heldOperationsKey = outsideRahdar('heldOperationsKey');
43
+ export const notify = outsideRahdar('notify');
44
+ export const pluginApi = outsideRahdar('pluginApi');
45
+ export const pluginPath = outsideRahdar('pluginPath');
46
+ export const pluginView = outsideRahdar('pluginView');
47
+ export const request = outsideRahdar('request');
48
+ export const rootRoute = outsideRahdar('rootRoute');
49
+ export const useCan = outsideRahdar('useCan');
50
+ export const useMe = outsideRahdar('useMe');
51
+ export const usePluginSeries = outsideRahdar('usePluginSeries');
52
+ export const useUserStream = outsideRahdar('useUserStream');
package/package.json CHANGED
@@ -1 +1,46 @@
1
- {"name":"@rahdar/plugin-sdk","version":"0.0.0","description":"Placeholder reserving the name; real releases come from CI.","license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/sudoitir/rahdar.git"}}
1
+ {
2
+ "name": "@rahdar/plugin-sdk",
3
+ "version": "2026.10.50",
4
+ "description": "Build the UI of a Rahdar plugin: typings for the Rahdar APIs a plugin may use, and a Vite preset.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/sudoitir/rahdar.git",
9
+ "directory": "web/packages/plugin-sdk"
10
+ },
11
+ "homepage": "https://rahdar.dev/guide/plugins",
12
+ "type": "module",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./types/sdk/index.d.ts",
16
+ "default": "./index.js"
17
+ },
18
+ "./vite": {
19
+ "types": "./vite.d.ts",
20
+ "default": "./vite.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "index.js",
25
+ "shared.js",
26
+ "shared.d.ts",
27
+ "vite.js",
28
+ "vite.d.ts",
29
+ "peers.json",
30
+ "types",
31
+ "README.md"
32
+ ],
33
+ "sideEffects": false,
34
+ "peerDependencies": {
35
+ "react": "19.3.0",
36
+ "react-dom": "19.3.0",
37
+ "@mantine/core": "9.6.3",
38
+ "@mantine/hooks": "9.6.3",
39
+ "@tanstack/react-query": "5.104.1",
40
+ "@tanstack/react-router": "1.170.41",
41
+ "vite": ">=8"
42
+ },
43
+ "dependencies": {
44
+ "@module-federation/vite": "1.23.2"
45
+ }
46
+ }
package/peers.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "react": "19.3.0",
3
+ "react-dom": "19.3.0",
4
+ "@mantine/core": "9.6.3",
5
+ "@mantine/hooks": "9.6.3",
6
+ "@tanstack/react-query": "5.104.1",
7
+ "@tanstack/react-router": "1.170.41"
8
+ }
package/shared.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export const SHARED_LIBRARIES: string[];
2
+ export const SDK: string;
3
+ export function packageOf(specifier: string): string;
package/shared.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The libraries a plugin's UI takes from Rahdar instead of bundling (ADR-0100): the ones holding
3
+ * React context or module state, where a second copy breaks hooks, routing, theming or the query
4
+ * cache. Rahdar's own build (web/vite.config.ts) shares exactly these, so the list lives here, once.
5
+ */
6
+ export const SHARED_LIBRARIES = [
7
+ 'react',
8
+ 'react/jsx-runtime',
9
+ 'react-dom',
10
+ 'react-dom/client',
11
+ '@mantine/core',
12
+ '@mantine/hooks',
13
+ '@tanstack/react-query',
14
+ '@tanstack/react-router',
15
+ ];
16
+
17
+ /** The SDK itself: always the running Rahdar's copy. */
18
+ export const SDK = '@rahdar/plugin-sdk';
19
+
20
+ /** The package a shared specifier belongs to: `react-dom/client` → `react-dom`. */
21
+ export function packageOf(specifier) {
22
+ const parts = specifier.split('/');
23
+ return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];
24
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Single source of every user-visible product name on the web side.
3
+ * Mirror of `Branding.java`. See `docs/adr/0001-project-name-and-trademark-risk.md`.
4
+ *
5
+ * A rename is: this file, `Branding.java`, the Maven `artifactId`, the image
6
+ * coordinates, and `index.html` <title>. Nothing else.
7
+ */
8
+ export declare const branding: {
9
+ readonly productName: "Rahdar";
10
+ readonly productShortName: "Rahdar";
11
+ readonly tagline: "Cluster-wide management and observability for Apache ActiveMQ Artemis";
12
+ readonly trademarkNotice: string;
13
+ readonly projectUrl: "https://github.com/sudoitir/rahdar";
14
+ };
@@ -0,0 +1,16 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Hosts the dialogs row actions open (ADR-0107), outside any grid: a dialog mounted in a
4
+ * virtualized row is unmounted when the row scrolls away or when the refresh its own success
5
+ * triggers removes the row, and its outcome goes with it.
6
+ *
7
+ * <p>A dialog is mounted closed and opened on the next frame. Dialogs take their dry-run preview
8
+ * in `onEnterTransitionEnd`, which a modal mounted already open never fires. On close it is kept
9
+ * until its exit transition ends, then removed, and focus goes back to what opened it — unless the
10
+ * dialog navigated away, where moving focus would be a jump the operator did not ask for. The end
11
+ * is heard as the surface's `transitionend`, which React bubbles out of the dialog's portal; a
12
+ * timer as long as the slowest exit in the theme removes it if that event never comes.
13
+ */
14
+ export declare function ActionHostProvider({ children }: Readonly<{
15
+ children: ReactNode;
16
+ }>): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { ActionHost } from './types.ts';
2
+ export declare const HostContext: import("react").Context<ActionHost | null>;
3
+ /** The action host of the surrounding cluster layout (or test harness). */
4
+ export declare function useActionHost(): ActionHost;
@@ -0,0 +1,130 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import type { components } from '../api/schema.d.ts';
3
+ import type { GateVerdict } from '../../ui/capabilityGate.ts';
4
+ type Schemas = components['schemas'];
5
+ /**
6
+ * The sections of a row's action menu, in the order it shows them (ADR-0107). The list is closed,
7
+ * like the navigation groups: an action names one, and adding one is a kernel change.
8
+ */
9
+ export declare const ACTION_SECTIONS: readonly [{
10
+ readonly id: "open";
11
+ readonly label: "Open";
12
+ }, {
13
+ readonly id: "copy";
14
+ readonly label: "Copy";
15
+ }, {
16
+ readonly id: "operate";
17
+ readonly label: "Operate";
18
+ }, {
19
+ readonly id: "destroy";
20
+ readonly label: "Destroy";
21
+ }];
22
+ export type ActionSection = (typeof ACTION_SECTIONS)[number]['id'];
23
+ /**
24
+ * `act` offers everything; `navigate` only the Open and Copy sections, for a view that must never
25
+ * change the broker (Flow).
26
+ */
27
+ export type ActionMode = 'act' | 'navigate';
28
+ export interface QueueTarget {
29
+ queueName: string;
30
+ address?: string | null;
31
+ snapshot?: Schemas['QueueView'];
32
+ }
33
+ export interface AddressTarget {
34
+ address: string;
35
+ snapshot?: Schemas['AddressView'];
36
+ }
37
+ /** Connections, sessions, consumers and producers are per node; a close needs to know which. */
38
+ interface NodeScoped {
39
+ nodeId: string;
40
+ nodeName: string;
41
+ }
42
+ export interface ConnectionTarget extends NodeScoped {
43
+ connectionId: string;
44
+ snapshot?: Schemas['ConnectionView'];
45
+ }
46
+ export interface SessionTarget extends NodeScoped {
47
+ sessionId: string;
48
+ connectionId?: string | null;
49
+ snapshot?: Schemas['SessionView'];
50
+ }
51
+ export interface ConsumerTarget extends NodeScoped {
52
+ consumerId: string;
53
+ queueName?: string | null;
54
+ sessionId?: string | null;
55
+ snapshot?: Schemas['ConsumerView'];
56
+ }
57
+ export interface ProducerTarget extends NodeScoped {
58
+ producerId: string;
59
+ address?: string | null;
60
+ sessionId?: string | null;
61
+ snapshot?: Schemas['ProducerView'];
62
+ }
63
+ export interface MessageTarget {
64
+ queueName: string;
65
+ messageId: number;
66
+ /** The node the message was browsed on; absent for the live node. */
67
+ node?: string;
68
+ }
69
+ export interface DivertTarget {
70
+ name: string;
71
+ snapshot?: Schemas['DivertView'];
72
+ }
73
+ /** A client of the flow view: an identity that may stand for many connections. */
74
+ export interface ClientTarget {
75
+ label: string;
76
+ }
77
+ /** Each resource kind a row menu or a link can be about, with its target. */
78
+ export interface ActionTargets {
79
+ queue: QueueTarget;
80
+ address: AddressTarget;
81
+ connection: ConnectionTarget;
82
+ session: SessionTarget;
83
+ consumer: ConsumerTarget;
84
+ producer: ProducerTarget;
85
+ message: MessageTarget;
86
+ divert: DivertTarget;
87
+ client: ClientTarget;
88
+ }
89
+ export type ActionKind = keyof ActionTargets;
90
+ /** What the action host gives a dialog it hosts. */
91
+ export interface HostedDialogProps {
92
+ opened: boolean;
93
+ onClose: () => void;
94
+ }
95
+ type Blocked = Extract<GateVerdict, {
96
+ kind: 'blocked';
97
+ }>;
98
+ /**
99
+ * Where an action's dialog lives (ADR-0107): outside the grid, so it outlives the row that opened
100
+ * it, the menu that offered it, and the refresh that removes the row when the action succeeds.
101
+ */
102
+ export interface ActionHost {
103
+ /**
104
+ * Opens `Dialog` with `props`, plus `opened` and `onClose`. On close, focus goes back through
105
+ * `restoreFocus` — unless the dialog navigated away.
106
+ */
107
+ open<P extends HostedDialogProps>(Dialog: ComponentType<P>, props: NoInfer<Omit<P, keyof HostedDialogProps>>, options?: {
108
+ restoreFocus?: () => void;
109
+ }): void;
110
+ /** Explains why an action is unavailable, in full. */
111
+ explain(verdict: Blocked, what: string, options?: {
112
+ restoreFocus?: () => void;
113
+ }): void;
114
+ /** Copies `text` and says so; `what` names it ("queue name"). */
115
+ copy(text: string, what: string): void;
116
+ }
117
+ /** What a row-action contribution is given. */
118
+ export interface ActionProps<T> {
119
+ clusterId: string;
120
+ target: T;
121
+ host: ActionHost;
122
+ mode: ActionMode;
123
+ }
124
+ /** What a link contribution is given: it wraps `children` (the name) in a link to the resource. */
125
+ export interface LinkProps<T> {
126
+ clusterId: string;
127
+ target: T;
128
+ children: ReactNode;
129
+ }
130
+ export {};
@@ -0,0 +1,39 @@
1
+ import { type UseQueryResult } from '@tanstack/react-query';
2
+ import { type ApiError } from './request.ts';
3
+ /** Generic paged envelope (`PagedView<T>` on the backend). */
4
+ export interface PagedView<T> {
5
+ data: T[];
6
+ page: number;
7
+ pageSize: number;
8
+ /** The total across all pages; null where the server cannot know it. */
9
+ count: number | null;
10
+ hasNext: boolean;
11
+ }
12
+ /**
13
+ * A page of a history that can be very long (`HistoryPage<T>` on the backend): by page number for the first
14
+ * rows, then by the `next` cursor passed as `after`, which has no total.
15
+ */
16
+ export interface HistoryPage<T> extends PagedView<T> {
17
+ /** The cursor of the page after this one; null on the last page. */
18
+ next: string | null;
19
+ /** Read from a replica that may be a little behind the primary. */
20
+ mayLag: boolean;
21
+ }
22
+ /** The largest page the server allows (`ResourceQuery.MAX_SIZE`). */
23
+ export declare const MAX_PAGE_SIZE = 500;
24
+ /**
25
+ * Every row of a list the UI shows in full (roles, environments, channels, …): pages of the maximum size,
26
+ * followed while the server says another page exists. Stopping early would read as "no such row".
27
+ */
28
+ export declare function requestAll<T>(path: string): Promise<T[]>;
29
+ export interface ResourceParams {
30
+ q?: string;
31
+ sort?: string;
32
+ page?: number;
33
+ size?: number;
34
+ }
35
+ export declare function resourceSearch(params: ResourceParams): string;
36
+ /** One page of a cluster-wide listing (queues, addresses, consumers, …), refetched on the usual interval. */
37
+ export declare function useResource<T>(id: string, kind: string, params: ResourceParams): UseQueryResult<PagedView<T>, ApiError>;
38
+ /** Rows in the envelope every list endpoint answers with, for the fixtures that stand in for one. */
39
+ export declare function paged<T>(data: T[]): PagedView<T>;
@@ -0,0 +1,37 @@
1
+ import { type Query, type QueryClient } from '@tanstack/react-query';
2
+ /**
3
+ * Make TanStack's focus state mean "may refresh on its own": the tab is visible and
4
+ * refreshing is not paused. Called once, beside the `QueryClient`.
5
+ *
6
+ * A side effect: the retryer also waits for focus, so a request that fails while
7
+ * paused retries on resume rather than during the pause.
8
+ */
9
+ export declare function installPauseSeam(): void;
10
+ /**
11
+ * `refetchOnMount` for the QueryClient default, so pausing covers opening a view
12
+ * and not only the intervals.
13
+ *
14
+ * Pausing intervals but not mounts means an operator who pauses and then
15
+ * navigates has silently unpaused — every query the new screen observes is stale
16
+ * (the stream marks them so) and refetches on mount.
17
+ *
18
+ * A query that has never resolved is exempt: suspending its first fetch would hand
19
+ * the operator an empty screen. They paused a screen showing data to stop it
20
+ * moving, not to stop data existing.
21
+ */
22
+ export declare function mountRefetch(): (query: Query) => boolean;
23
+ export declare function isPollingPaused(): boolean;
24
+ export declare function setPollingPaused(next: boolean): void;
25
+ /** Record that the server said something changed while refreshing was paused. */
26
+ export declare function markPendingChange(): void;
27
+ export declare function usePollingPaused(): boolean;
28
+ export declare function usePendingChange(): boolean;
29
+ /**
30
+ * Refetch everything the current screen is observing: what resuming does, because the
31
+ * first thing an operator needs after unpausing is current data.
32
+ *
33
+ * `refetchType: 'active'` scopes it to what is on the display, the same scope the
34
+ * freshness indicator reports on. `cancelRefetch: false` lets a fetch already in
35
+ * flight finish rather than aborting it for an identical one.
36
+ */
37
+ export declare function refreshActiveQueries(qc: QueryClient): Promise<void>;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Transport to the Rahdar API: `request<T>()` and the RFC 9457 `ApiError`.
3
+ *
4
+ * DTO types come from `schema.d.ts`, generated by `openapi-typescript` from the
5
+ * backend's committed OpenAPI snapshot (`web/openapi.json`) — ADR-0019. Each
6
+ * feature's `api.ts` names the DTOs it uses and holds its own hooks and query
7
+ * keys, every cluster-scoped key under {@link clusterKey}.
8
+ */
9
+ export declare const BASE = "/api/v1";
10
+ /** A parsed `application/problem+json` body. */
11
+ export declare class ApiError extends Error {
12
+ readonly status: number;
13
+ readonly type: string;
14
+ readonly title: string;
15
+ readonly brokerErrorKind?: string;
16
+ readonly fieldErrors: {
17
+ field: string;
18
+ message: string;
19
+ }[];
20
+ /**
21
+ * The whole `problem+json` body. Handlers attach extra properties to a problem
22
+ * — the offending token on a syntax error, the estimate and ceiling on a
23
+ * refused query — and a message with the number left out is not something an
24
+ * operator can act on.
25
+ */
26
+ readonly problem: Record<string, unknown>;
27
+ constructor(status: number, body: Record<string, unknown>);
28
+ }
29
+ /** What the server says about an operation it held for approval instead of running. */
30
+ export interface HeldOperation {
31
+ id: string;
32
+ /** What the operation would do, in words, such as `Purge queue "orders" on prod`. */
33
+ summary: string;
34
+ /** When the request lapses unless someone decides it, as an ISO instant. */
35
+ expiresAt: string;
36
+ /** The held operation's API path. */
37
+ link: string;
38
+ }
39
+ /** The header a `202` carries when the operation was held for approval rather than run. */
40
+ export declare const HELD_HEADER = "X-Rahdar-Held-Operation";
41
+ /**
42
+ * The operation was not run but held for a second person to approve. It is thrown, not returned, so a
43
+ * mutation's success path (its toast, its invalidation, the dialog closing on "done") never treats a held
44
+ * operation as done; `notify.settle` and `ErrorState` show it as sent for approval, not as a failure.
45
+ */
46
+ export declare class OperationHeldError extends Error {
47
+ readonly heldOperation: HeldOperation;
48
+ constructor(heldOperation: HeldOperation);
49
+ }
50
+ /** The root every held-operation query key starts from, so a held outcome or a `held` signal refreshes all of them. */
51
+ export declare const heldOperationsKey: readonly ["held-operations"];
52
+ /**
53
+ * The header that tells the server a person, not a background refresh, made this request, so it
54
+ * counts towards the session's idle timeout (ADR-0145). Polling sends it only while the person is
55
+ * around; the event stream cannot send headers at all, so it never counts.
56
+ */
57
+ export declare const ACTIVITY_HEADER = "X-Rahdar-Activity";
58
+ /** How long after the last pointer or key press a request still counts as the person's. */
59
+ export declare const ACTIVITY_WINDOW_MS = 60000;
60
+ /** Whether the person used the pointer or keyboard within {@link ACTIVITY_WINDOW_MS}. */
61
+ export declare function personIsActive(): boolean;
62
+ /** The `reason` a 401 hands the sign-in screen when this page had been signed in, so it can say the session ended. */
63
+ export declare const SESSION_ENDED_REASON = "ended";
64
+ /** Reads the `XSRF-TOKEN` cookie Spring Security's `CookieCsrfTokenRepository` sets (identity-and-sessions spec). */
65
+ export declare function csrfToken(): string | undefined;
66
+ /** Whether this page is the sign-in page, which asks for nothing that needs a session. */
67
+ export declare function onLoginPage(): boolean;
68
+ export declare function request<T>(path: string, init?: RequestInit): Promise<T>;
69
+ /** The root every cluster-scoped query key starts from, so invalidating a cluster reaches all of it. */
70
+ export declare const clusterKey: (id: string, ...parts: unknown[]) => readonly ["clusters", string, ...unknown[]];
71
+ /** The path a cluster-wide command is issued under. */
72
+ export declare const lifecycleBase: (clusterId: string) => string;
73
+ /**
74
+ * A lifecycle command names the cluster, not a node, and comes back as a
75
+ * per-node outcome. `dryRun` previews without touching any broker; `override`
76
+ * clears the bulk cap on a destroy, which is the only kind the cap applies to.
77
+ * A defined `dryRun` is always sent, `false` included: a real run must never be
78
+ * left to the server's default.
79
+ */
80
+ export interface LifecycleVars {
81
+ dryRun?: boolean;
82
+ override?: boolean;
83
+ }
84
+ export declare function lifecycleQuery(dryRun?: boolean, override?: boolean): string;