@marinoscar/platform-web 0.1.0-next.18 → 0.1.0-next.20
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.
- package/CHANGELOG.md +32 -0
- package/README.md +5 -3
- package/dist/ai/headless/errors.d.ts +7 -0
- package/dist/ai/headless/errors.d.ts.map +1 -1
- package/dist/ai/headless/errors.js +2 -0
- package/dist/ai/headless/errors.js.map +1 -1
- package/dist/ai/headless/types.d.ts +30 -5
- package/dist/ai/headless/types.d.ts.map +1 -1
- package/dist/ai/headless/types.js +22 -10
- package/dist/ai/headless/types.js.map +1 -1
- package/dist/ai/headless/use-ai-usage.d.ts +5 -2
- package/dist/ai/headless/use-ai-usage.d.ts.map +1 -1
- package/dist/ai/headless/use-ai-usage.js +15 -5
- package/dist/ai/headless/use-ai-usage.js.map +1 -1
- package/dist/ai/ui/AiUsagePage.d.ts.map +1 -1
- package/dist/ai/ui/AiUsagePage.js +7 -5
- package/dist/ai/ui/AiUsagePage.js.map +1 -1
- package/dist/ai/ui/shared/AiErrorAlert.d.ts.map +1 -1
- package/dist/ai/ui/shared/AiErrorAlert.js +5 -1
- package/dist/ai/ui/shared/AiErrorAlert.js.map +1 -1
- package/dist/ai/ui/usage/aiUsageFormat.d.ts +9 -6
- package/dist/ai/ui/usage/aiUsageFormat.d.ts.map +1 -1
- package/dist/ai/ui/usage/aiUsageFormat.js +28 -12
- package/dist/ai/ui/usage/aiUsageFormat.js.map +1 -1
- package/dist/ai/ui/user/MyAiUsageSection.d.ts.map +1 -1
- package/dist/ai/ui/user/MyAiUsageSection.js +5 -2
- package/dist/ai/ui/user/MyAiUsageSection.js.map +1 -1
- package/dist/ai/ui/user/aiErrorText.d.ts +4 -1
- package/dist/ai/ui/user/aiErrorText.d.ts.map +1 -1
- package/dist/ai/ui/user/aiErrorText.js +10 -2
- package/dist/ai/ui/user/aiErrorText.js.map +1 -1
- package/dist/alerts/headless/client.d.ts +134 -0
- package/dist/alerts/headless/client.d.ts.map +1 -0
- package/dist/alerts/headless/client.js +105 -0
- package/dist/alerts/headless/client.js.map +1 -0
- package/dist/alerts/headless/format.d.ts +95 -0
- package/dist/alerts/headless/format.d.ts.map +1 -0
- package/dist/alerts/headless/format.js +164 -0
- package/dist/alerts/headless/format.js.map +1 -0
- package/dist/alerts/headless/hooks.d.ts +245 -0
- package/dist/alerts/headless/hooks.d.ts.map +1 -0
- package/dist/alerts/headless/hooks.js +315 -0
- package/dist/alerts/headless/hooks.js.map +1 -0
- package/dist/alerts/headless/index.d.ts +9 -0
- package/dist/alerts/headless/index.d.ts.map +1 -0
- package/dist/alerts/headless/index.js +9 -0
- package/dist/alerts/headless/index.js.map +1 -0
- package/dist/alerts/headless/rule-draft.d.ts +175 -0
- package/dist/alerts/headless/rule-draft.d.ts.map +1 -0
- package/dist/alerts/headless/rule-draft.js +261 -0
- package/dist/alerts/headless/rule-draft.js.map +1 -0
- package/dist/alerts/ui/AlertIncidentDrawer.d.ts +30 -0
- package/dist/alerts/ui/AlertIncidentDrawer.d.ts.map +1 -0
- package/dist/alerts/ui/AlertIncidentDrawer.js +33 -0
- package/dist/alerts/ui/AlertIncidentDrawer.js.map +1 -0
- package/dist/alerts/ui/AlertRuleDialog.d.ts +47 -0
- package/dist/alerts/ui/AlertRuleDialog.d.ts.map +1 -0
- package/dist/alerts/ui/AlertRuleDialog.js +124 -0
- package/dist/alerts/ui/AlertRuleDialog.js.map +1 -0
- package/dist/alerts/ui/AlertRuleTestResult.d.ts +23 -0
- package/dist/alerts/ui/AlertRuleTestResult.d.ts.map +1 -0
- package/dist/alerts/ui/AlertRuleTestResult.js +30 -0
- package/dist/alerts/ui/AlertRuleTestResult.js.map +1 -0
- package/dist/alerts/ui/AlertsPage.d.ts +41 -0
- package/dist/alerts/ui/AlertsPage.d.ts.map +1 -0
- package/dist/alerts/ui/AlertsPage.js +238 -0
- package/dist/alerts/ui/AlertsPage.js.map +1 -0
- package/dist/alerts/ui/FiringAlertsBanner.d.ts +28 -0
- package/dist/alerts/ui/FiringAlertsBanner.d.ts.map +1 -0
- package/dist/alerts/ui/FiringAlertsBanner.js +45 -0
- package/dist/alerts/ui/FiringAlertsBanner.js.map +1 -0
- package/dist/alerts/ui/copy.d.ts +15 -0
- package/dist/alerts/ui/copy.d.ts.map +1 -0
- package/dist/alerts/ui/copy.js +14 -0
- package/dist/alerts/ui/copy.js.map +1 -0
- package/dist/alerts/ui/index.d.ts +14 -0
- package/dist/alerts/ui/index.d.ts.map +1 -0
- package/dist/alerts/ui/index.js +12 -0
- package/dist/alerts/ui/index.js.map +1 -0
- package/dist/alerts/ui/parts.d.ts +26 -0
- package/dist/alerts/ui/parts.d.ts.map +1 -0
- package/dist/alerts/ui/parts.js +27 -0
- package/dist/alerts/ui/parts.js.map +1 -0
- package/dist/alerts/ui/settings.d.ts +27 -0
- package/dist/alerts/ui/settings.d.ts.map +1 -0
- package/dist/alerts/ui/settings.js +37 -0
- package/dist/alerts/ui/settings.js.map +1 -0
- package/dist/core/http/client.d.ts.map +1 -1
- package/dist/core/http/client.js +7 -0
- package/dist/core/http/client.js.map +1 -1
- package/dist/core/http/sse.d.ts.map +1 -1
- package/dist/core/http/sse.js +3 -1
- package/dist/core/http/sse.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/time-zone/format.d.ts +6 -2
- package/dist/core/time-zone/format.d.ts.map +1 -1
- package/dist/core/time-zone/format.js +27 -25
- package/dist/core/time-zone/format.js.map +1 -1
- package/dist/core/time-zone/request.d.ts +17 -0
- package/dist/core/time-zone/request.d.ts.map +1 -0
- package/dist/core/time-zone/request.js +26 -0
- package/dist/core/time-zone/request.js.map +1 -0
- package/dist/datatable/headless/export/exportModel.d.ts +7 -1
- package/dist/datatable/headless/export/exportModel.d.ts.map +1 -1
- package/dist/datatable/headless/export/exportModel.js +10 -2
- package/dist/datatable/headless/export/exportModel.js.map +1 -1
- package/dist/datatable/headless/filter/dateRange.d.ts +40 -0
- package/dist/datatable/headless/filter/dateRange.d.ts.map +1 -0
- package/dist/datatable/headless/filter/dateRange.js +53 -0
- package/dist/datatable/headless/filter/dateRange.js.map +1 -0
- package/dist/datatable/headless/filter/filterTypes.d.ts.map +1 -1
- package/dist/datatable/headless/filter/filterTypes.js +24 -4
- package/dist/datatable/headless/filter/filterTypes.js.map +1 -1
- package/dist/datatable/headless/index.d.ts +2 -0
- package/dist/datatable/headless/index.d.ts.map +1 -1
- package/dist/datatable/headless/index.js +1 -0
- package/dist/datatable/headless/index.js.map +1 -1
- package/dist/db-backup/internal/time-zones.d.ts +3 -0
- package/dist/db-backup/internal/time-zones.d.ts.map +1 -0
- package/dist/db-backup/internal/time-zones.js +24 -0
- package/dist/db-backup/internal/time-zones.js.map +1 -0
- package/dist/db-backup/ui/DbBackupConfigPanel.d.ts +11 -6
- package/dist/db-backup/ui/DbBackupConfigPanel.d.ts.map +1 -1
- package/dist/db-backup/ui/DbBackupConfigPanel.js +18 -11
- package/dist/db-backup/ui/DbBackupConfigPanel.js.map +1 -1
- package/dist/identity/ui/tokens/CreatePatDialog.d.ts +17 -0
- package/dist/identity/ui/tokens/CreatePatDialog.d.ts.map +1 -1
- package/dist/identity/ui/tokens/CreatePatDialog.js +34 -11
- package/dist/identity/ui/tokens/CreatePatDialog.js.map +1 -1
- package/dist/nodes/headless/api.d.ts +3 -1
- package/dist/nodes/headless/api.d.ts.map +1 -1
- package/dist/nodes/headless/api.js +22 -0
- package/dist/nodes/headless/api.js.map +1 -1
- package/dist/nodes/headless/index.d.ts +7 -2
- package/dist/nodes/headless/index.d.ts.map +1 -1
- package/dist/nodes/headless/index.js +4 -1
- package/dist/nodes/headless/index.js.map +1 -1
- package/dist/nodes/headless/node-events.d.ts +43 -0
- package/dist/nodes/headless/node-events.d.ts.map +1 -0
- package/dist/nodes/headless/node-events.js +150 -0
- package/dist/nodes/headless/node-events.js.map +1 -0
- package/dist/nodes/headless/power.d.ts +43 -0
- package/dist/nodes/headless/power.d.ts.map +1 -0
- package/dist/nodes/headless/power.js +74 -0
- package/dist/nodes/headless/power.js.map +1 -0
- package/dist/nodes/headless/types.d.ts +40 -3
- package/dist/nodes/headless/types.d.ts.map +1 -1
- package/dist/nodes/headless/types.js +1 -1
- package/dist/nodes/headless/types.js.map +1 -1
- package/dist/nodes/headless/use-node-events.d.ts +59 -0
- package/dist/nodes/headless/use-node-events.d.ts.map +1 -0
- package/dist/nodes/headless/use-node-events.js +159 -0
- package/dist/nodes/headless/use-node-events.js.map +1 -0
- package/dist/nodes/ui/NodeEventsTimeline.d.ts +39 -0
- package/dist/nodes/ui/NodeEventsTimeline.d.ts.map +1 -0
- package/dist/nodes/ui/NodeEventsTimeline.js +63 -0
- package/dist/nodes/ui/NodeEventsTimeline.js.map +1 -0
- package/dist/nodes/ui/NodePowerBadge.d.ts +27 -0
- package/dist/nodes/ui/NodePowerBadge.d.ts.map +1 -0
- package/dist/nodes/ui/NodePowerBadge.js +48 -0
- package/dist/nodes/ui/NodePowerBadge.js.map +1 -0
- package/dist/nodes/ui/NodeVitalsDialog.d.ts +11 -1
- package/dist/nodes/ui/NodeVitalsDialog.d.ts.map +1 -1
- package/dist/nodes/ui/NodeVitalsDialog.js +14 -5
- package/dist/nodes/ui/NodeVitalsDialog.js.map +1 -1
- package/dist/nodes/ui/WorkersPage.d.ts.map +1 -1
- package/dist/nodes/ui/WorkersPage.js +2 -1
- package/dist/nodes/ui/WorkersPage.js.map +1 -1
- package/dist/nodes/ui/workerVitals.d.ts +17 -1
- package/dist/nodes/ui/workerVitals.d.ts.map +1 -1
- package/dist/nodes/ui/workerVitals.js +43 -0
- package/dist/nodes/ui/workerVitals.js.map +1 -1
- package/dist/nodes/ui/workersTable.d.ts.map +1 -1
- package/dist/nodes/ui/workersTable.js +2 -1
- package/dist/nodes/ui/workersTable.js.map +1 -1
- package/dist/settings/ui/ProfileSettings.d.ts +1 -1
- package/dist/settings/ui/ProfileSettings.d.ts.map +1 -1
- package/dist/settings/ui/UserSettingsSection.d.ts +1 -1
- package/dist/settings/ui/UserSettingsSection.d.ts.map +1 -1
- package/dist/sharing/internal/format.d.ts +10 -1
- package/dist/sharing/internal/format.d.ts.map +1 -1
- package/dist/sharing/internal/format.js +10 -1
- package/dist/sharing/internal/format.js.map +1 -1
- package/dist/telemetry/headless/hooks/useTelemetryDashboard.d.ts +1 -1
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.d.ts +11 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.js +17 -2
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSections.js.map +1 -1
- package/dist/webhooks/headless/client.d.ts +101 -0
- package/dist/webhooks/headless/client.d.ts.map +1 -0
- package/dist/webhooks/headless/client.js +105 -0
- package/dist/webhooks/headless/client.js.map +1 -0
- package/dist/webhooks/headless/event-selection.d.ts +119 -0
- package/dist/webhooks/headless/event-selection.d.ts.map +1 -0
- package/dist/webhooks/headless/event-selection.js +225 -0
- package/dist/webhooks/headless/event-selection.js.map +1 -0
- package/dist/webhooks/headless/format.d.ts +84 -0
- package/dist/webhooks/headless/format.d.ts.map +1 -0
- package/dist/webhooks/headless/format.js +142 -0
- package/dist/webhooks/headless/format.js.map +1 -0
- package/dist/webhooks/headless/hooks.d.ts +199 -0
- package/dist/webhooks/headless/hooks.d.ts.map +1 -0
- package/dist/webhooks/headless/hooks.js +249 -0
- package/dist/webhooks/headless/hooks.js.map +1 -0
- package/dist/webhooks/headless/index.d.ts +9 -0
- package/dist/webhooks/headless/index.d.ts.map +1 -0
- package/dist/webhooks/headless/index.js +9 -0
- package/dist/webhooks/headless/index.js.map +1 -0
- package/dist/webhooks/ui/WebhookDeliveryDrawer.d.ts +32 -0
- package/dist/webhooks/ui/WebhookDeliveryDrawer.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhookDeliveryDrawer.js +64 -0
- package/dist/webhooks/ui/WebhookDeliveryDrawer.js.map +1 -0
- package/dist/webhooks/ui/WebhookEndpointDetail.d.ts +21 -0
- package/dist/webhooks/ui/WebhookEndpointDetail.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhookEndpointDetail.js +96 -0
- package/dist/webhooks/ui/WebhookEndpointDetail.js.map +1 -0
- package/dist/webhooks/ui/WebhookEndpointDialog.d.ts +39 -0
- package/dist/webhooks/ui/WebhookEndpointDialog.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhookEndpointDialog.js +79 -0
- package/dist/webhooks/ui/WebhookEndpointDialog.js.map +1 -0
- package/dist/webhooks/ui/WebhookEventPicker.d.ts +30 -0
- package/dist/webhooks/ui/WebhookEventPicker.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhookEventPicker.js +33 -0
- package/dist/webhooks/ui/WebhookEventPicker.js.map +1 -0
- package/dist/webhooks/ui/WebhookSecretDialog.d.ts +27 -0
- package/dist/webhooks/ui/WebhookSecretDialog.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhookSecretDialog.js +52 -0
- package/dist/webhooks/ui/WebhookSecretDialog.js.map +1 -0
- package/dist/webhooks/ui/WebhookSignatureHelp.d.ts +18 -0
- package/dist/webhooks/ui/WebhookSignatureHelp.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhookSignatureHelp.js +40 -0
- package/dist/webhooks/ui/WebhookSignatureHelp.js.map +1 -0
- package/dist/webhooks/ui/WebhooksPage.d.ts +47 -0
- package/dist/webhooks/ui/WebhooksPage.d.ts.map +1 -0
- package/dist/webhooks/ui/WebhooksPage.js +172 -0
- package/dist/webhooks/ui/WebhooksPage.js.map +1 -0
- package/dist/webhooks/ui/copy.d.ts +24 -0
- package/dist/webhooks/ui/copy.d.ts.map +1 -0
- package/dist/webhooks/ui/copy.js +34 -0
- package/dist/webhooks/ui/copy.js.map +1 -0
- package/dist/webhooks/ui/index.d.ts +15 -0
- package/dist/webhooks/ui/index.d.ts.map +1 -0
- package/dist/webhooks/ui/index.js +12 -0
- package/dist/webhooks/ui/index.js.map +1 -0
- package/dist/webhooks/ui/parts.d.ts +25 -0
- package/dist/webhooks/ui/parts.d.ts.map +1 -0
- package/dist/webhooks/ui/parts.js +28 -0
- package/dist/webhooks/ui/parts.js.map +1 -0
- package/dist/webhooks/ui/settings.d.ts +58 -0
- package/dist/webhooks/ui/settings.d.ts.map +1 -0
- package/dist/webhooks/ui/settings.js +79 -0
- package/dist/webhooks/ui/settings.js.map +1 -0
- package/package.json +18 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PlatformApiClient } from '../../core/index.js';
|
|
2
|
-
import type { CreateNodeCredentialInput, NodeCredential, NodeCredentialCreated, WorkerNode } from './types.js';
|
|
2
|
+
import type { CreateNodeCredentialInput, NodeCredential, NodeCredentialCreated, NodeEventsQuery, WorkerNode, WorkerNodeEventList } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Every call the worker-node page and hooks make. `createNodesApi` builds one
|
|
5
5
|
* over the app's transport; a test or an app with its own client implements it.
|
|
@@ -20,6 +20,8 @@ export interface NodesApi {
|
|
|
20
20
|
createNodeCredential(input: CreateNodeCredentialInput): Promise<NodeCredentialCreated>;
|
|
21
21
|
/** `DELETE /admin/nodes/credentials/:id`: effective on the node's next request; one-way. */
|
|
22
22
|
revokeNodeCredential(id: string): Promise<void>;
|
|
23
|
+
/** `GET /admin/nodes/:id/events`: a page of the node's events, newest first (`nodes:read`). */
|
|
24
|
+
listNodeEvents(nodeId: string, query?: NodeEventsQuery): Promise<WorkerNodeEventList>;
|
|
23
25
|
}
|
|
24
26
|
/**
|
|
25
27
|
* The worker-node client over the app's transport.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/api.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,8EAA8E;IAC9E,cAAc,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACxC,6DAA6D;IAC7D,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,yGAAyG;IACzG,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,6FAA6F;IAC7F,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAChD,kFAAkF;IAClF,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvF,4FAA4F;IAC5F,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,+FAA+F;IAC/F,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACvF;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,QAAQ,CAmBlE"}
|
|
@@ -16,7 +16,28 @@
|
|
|
16
16
|
//
|
|
17
17
|
// `GET /admin/nodes` returns the whole fleet as a bare array, not a page: a
|
|
18
18
|
// fleet is tens of machines, and the page tallies its health verdicts.
|
|
19
|
+
//
|
|
20
|
+
// A node's events (#1045) ARE paged (`GET /admin/nodes/:id/events`): a laptop node
|
|
21
|
+
// on battery reports a change every few minutes, and a timeline only ever
|
|
22
|
+
// needs the newest screenful.
|
|
19
23
|
// =============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* `GET /admin/nodes/:id/events`'s query string: only the members that are set, in a
|
|
26
|
+
* fixed order (page, pageSize, type, severity), so a request is byte-stable.
|
|
27
|
+
*/
|
|
28
|
+
function nodeEventsQueryString(query) {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
if (query.page !== undefined)
|
|
31
|
+
params.set('page', String(query.page));
|
|
32
|
+
if (query.pageSize !== undefined)
|
|
33
|
+
params.set('pageSize', String(query.pageSize));
|
|
34
|
+
if (query.type)
|
|
35
|
+
params.set('type', query.type);
|
|
36
|
+
if (query.severity)
|
|
37
|
+
params.set('severity', query.severity);
|
|
38
|
+
const text = params.toString();
|
|
39
|
+
return text ? `?${text}` : '';
|
|
40
|
+
}
|
|
20
41
|
/**
|
|
21
42
|
* The worker-node client over the app's transport.
|
|
22
43
|
*
|
|
@@ -48,6 +69,7 @@ export function createNodesApi(client) {
|
|
|
48
69
|
revokeNodeCredential: async (id) => {
|
|
49
70
|
await client.delete(`/admin/nodes/credentials/${id}`);
|
|
50
71
|
},
|
|
72
|
+
listNodeEvents: (nodeId, query = {}) => client.get(`/admin/nodes/${encodeURIComponent(nodeId)}/events${nodeEventsQueryString(query)}`),
|
|
51
73
|
};
|
|
52
74
|
}
|
|
53
75
|
//# sourceMappingURL=api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/nodes/headless/api.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4CAA4C;AAC5C,gFAAgF;AAChF,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,8EAA8E;AAC9E,wDAAwD;AACxD,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,4EAA4E;AAC5E,iEAAiE;AACjE,6EAA6E;AAC7E,SAAS;AACT,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,gFAAgF;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/nodes/headless/api.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4CAA4C;AAC5C,gFAAgF;AAChF,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,8EAA8E;AAC9E,wDAAwD;AACxD,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,4EAA4E;AAC5E,iEAAiE;AACjE,6EAA6E;AAC7E,SAAS;AACT,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,EAAE;AACF,mFAAmF;AACnF,0EAA0E;AAC1E,8BAA8B;AAC9B,gFAAgF;AAoChF;;;GAGG;AACH,SAAS,qBAAqB,CAAC,KAAsB;IACnD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrE,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjF,IAAI,KAAK,CAAC,IAAI;QAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,QAAQ;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC/B,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB;IACtD,OAAO;QACL,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAe,cAAc,CAAC;QAC9D,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAa,gBAAgB,EAAE,EAAE,CAAC;QACnE,gBAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YAC7B,MAAM,MAAM,CAAC,MAAM,CAAO,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,kBAAkB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAmB,0BAA0B,CAAC;QAClF,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC9B,MAAM,IAAI,GAA8B,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7D,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS;gBAAE,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;YAChF,OAAO,MAAM,CAAC,IAAI,CAAwB,mBAAmB,EAAE,IAAI,CAAC,CAAC;QACvE,CAAC;QACD,oBAAoB,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACjC,MAAM,MAAM,CAAC,MAAM,CAAO,4BAA4B,EAAE,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,cAAc,EAAE,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CACrC,MAAM,CAAC,GAAG,CAAsB,gBAAgB,kBAAkB,CAAC,MAAM,CAAC,UAAU,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;KACtH,CAAC;AACJ,CAAC"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export { createNodesApi } from './api.js';
|
|
2
2
|
export type { NodesApi } from './api.js';
|
|
3
|
-
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_HEALTHS, NODE_STATUSES, nodeCredentialStatus, } from './types.js';
|
|
4
|
-
export type { CreateNodeCredentialInput, NodeCredential, NodeCredentialCreated, NodeCredentialStatus, NodeHealth, NodeJobCounts, NodeOwner, NodeStatus, NodeVitals, NodeVitalsCounters, WorkerNode, } from './types.js';
|
|
3
|
+
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_EVENT_TYPES, NODE_HEALTHS, NODE_STATUSES, nodeCredentialStatus, } from './types.js';
|
|
4
|
+
export type { CreateNodeCredentialInput, NodeCredential, NodeCredentialCreated, NodeCredentialStatus, NodeEventSeverity, NodeEventsQuery, NodeHealth, NodeHostVitals, NodeJobCounts, NodeOwner, NodePower, NodeStatus, NodeVitals, NodeVitalsCounters, WorkerNode, WorkerNodeEvent, WorkerNodeEventList, } from './types.js';
|
|
5
|
+
export { MAX_NODE_EVENT_SUMMARY_ATTRS, humanizeNodeEventType, nodeEventLabel, nodeEventSummary } from './node-events.js';
|
|
6
|
+
export { NODE_BATTERY_CRITICAL_PERCENT, NODE_BATTERY_WARNING_PERCENT, describeNodePower } from './power.js';
|
|
7
|
+
export type { NodePowerDescription } from './power.js';
|
|
8
|
+
export { useNodeEvents } from './use-node-events.js';
|
|
9
|
+
export type { UseNodeEventsResult } from './use-node-events.js';
|
|
5
10
|
export { formatDateTime, formatDuration, shortId } from './format.js';
|
|
6
11
|
export { formatNodeVital, nodeVitalFor, nodeVitalRows, registerNodeVital, registeredNodeVitals } from './node-vitals.js';
|
|
7
12
|
export type { NodeVitalDef, NodeVitalRow, NodeVitalUnit } from './node-vitals.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,YAAY,EACZ,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzH,OAAO,EAAE,6BAA6B,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC5G,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACzH,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7G,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC3F,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,6BAA6B,EAC7B,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC"}
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
// the data hooks, the visible-tab poll, the adapters and the formatting
|
|
5
5
|
// helpers. Documented in ../README.md. Explicit named exports only.
|
|
6
6
|
export { createNodesApi } from './api.js';
|
|
7
|
-
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_HEALTHS, NODE_STATUSES, nodeCredentialStatus, } from './types.js';
|
|
7
|
+
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_EVENT_TYPES, NODE_HEALTHS, NODE_STATUSES, nodeCredentialStatus, } from './types.js';
|
|
8
|
+
export { MAX_NODE_EVENT_SUMMARY_ATTRS, humanizeNodeEventType, nodeEventLabel, nodeEventSummary } from './node-events.js';
|
|
9
|
+
export { NODE_BATTERY_CRITICAL_PERCENT, NODE_BATTERY_WARNING_PERCENT, describeNodePower } from './power.js';
|
|
10
|
+
export { useNodeEvents } from './use-node-events.js';
|
|
8
11
|
export { formatDateTime, formatDuration, shortId } from './format.js';
|
|
9
12
|
export { formatNodeVital, nodeVitalFor, nodeVitalRows, registerNodeVital, registeredNodeVitals } from './node-vitals.js';
|
|
10
13
|
export { MAX_CAPABILITY_TEXT_LENGTH, MAX_LISTED_CAPABILITIES, nodeCapabilityItems } from './capabilities.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nodes/headless/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,4EAA4E;AAC5E,wFAAwF;AACxF,wEAAwE;AACxE,oEAAoE;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,YAAY,EACZ,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nodes/headless/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,4EAA4E;AAC5E,wFAAwF;AACxF,wEAAwE;AACxE,oEAAoE;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAoBpB,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzH,OAAO,EAAE,6BAA6B,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5G,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEzH,OAAO,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7G,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAc3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EACL,6BAA6B,EAC7B,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { WorkerNodeEvent } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Most attributes a summary of an unknown event prints.
|
|
4
|
+
*
|
|
5
|
+
* @stability experimental
|
|
6
|
+
*/
|
|
7
|
+
export declare const MAX_NODE_EVENT_SUMMARY_ATTRS = 4;
|
|
8
|
+
/**
|
|
9
|
+
* A dotted event type as words: the last segment is the event, the ones before
|
|
10
|
+
* it its area (`transcode.queue_full` to "Transcode: queue full").
|
|
11
|
+
*
|
|
12
|
+
* @param type - the event's dotted type.
|
|
13
|
+
* @returns the humanized text; the input itself when it has no segments.
|
|
14
|
+
*
|
|
15
|
+
* @stability experimental
|
|
16
|
+
*/
|
|
17
|
+
export declare function humanizeNodeEventType(type: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* How an event type reads: the platform's label for a `NODE_EVENT_TYPES` name,
|
|
20
|
+
* else {@link humanizeNodeEventType}.
|
|
21
|
+
*
|
|
22
|
+
* @param type - the event's dotted type.
|
|
23
|
+
* @returns the label.
|
|
24
|
+
*
|
|
25
|
+
* @stability experimental
|
|
26
|
+
*/
|
|
27
|
+
export declare function nodeEventLabel(type: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* One line that says what an event's attributes mean, or `null` when it has
|
|
30
|
+
* none worth printing.
|
|
31
|
+
*
|
|
32
|
+
* Known types read as a sentence fragment ("AC → Battery (64%)", "12% (threshold
|
|
33
|
+
* 20%)", "Asleep for 2h 03m", "4.5% free (1.2 GB)"); an unknown type, or a known
|
|
34
|
+
* one missing the attributes its fragment needs, reads as `key: value` pairs, at
|
|
35
|
+
* most {@link MAX_NODE_EVENT_SUMMARY_ATTRS} of them, sorted by key.
|
|
36
|
+
*
|
|
37
|
+
* @param event - the event (its `type` and `attrs`).
|
|
38
|
+
* @returns the summary, or `null`.
|
|
39
|
+
*
|
|
40
|
+
* @stability experimental
|
|
41
|
+
*/
|
|
42
|
+
export declare function nodeEventSummary(event: Pick<WorkerNodeEvent, 'type' | 'attrs'>): string | null;
|
|
43
|
+
//# sourceMappingURL=node-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-events.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/node-events.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAYlD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAU9C;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAyBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CA4C9F"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Node events: how the Worker Nodes page words one (issue #1045)
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// A node reports what it observed about itself on its heartbeat (a power
|
|
6
|
+
// change, a low battery, a wake from sleep, a low disk); the API stores each one
|
|
7
|
+
// and serves them at `GET /api/admin/nodes/:id/events`. These helpers turn one into
|
|
8
|
+
// text: a label for its type and a one-line summary of its attributes.
|
|
9
|
+
//
|
|
10
|
+
// The type is an OPEN dotted string: an app's node may report its own. A known
|
|
11
|
+
// type (`NODE_EVENT_TYPES`) reads by its label; an unknown one is still shown,
|
|
12
|
+
// humanized from its dotted name (`transcode.queue_full` -> "Transcode: queue
|
|
13
|
+
// full"), never hidden. Attributes are self-reported scalars; they are printed
|
|
14
|
+
// as plain text, bounded, and never turned into a verdict.
|
|
15
|
+
//
|
|
16
|
+
// Pure functions, no markup, so they live in the headless entry.
|
|
17
|
+
// =============================================================================
|
|
18
|
+
import { NODE_EVENT_TYPES } from '@marinoscar/platform-contract/nodes';
|
|
19
|
+
import { formatBytes } from '../internal/format-bytes.js';
|
|
20
|
+
import { formatDuration } from './format.js';
|
|
21
|
+
/** The platform's own event types, as an operator reads them. */
|
|
22
|
+
const NODE_EVENT_LABELS = Object.freeze({
|
|
23
|
+
[NODE_EVENT_TYPES.POWER_SOURCE_CHANGED]: 'Power source changed',
|
|
24
|
+
[NODE_EVENT_TYPES.BATTERY_LOW]: 'Battery low',
|
|
25
|
+
[NODE_EVENT_TYPES.BATTERY_CRITICAL]: 'Battery critical',
|
|
26
|
+
[NODE_EVENT_TYPES.BATTERY_RECOVERED]: 'Battery recovered',
|
|
27
|
+
[NODE_EVENT_TYPES.SLEEP_RESUMED]: 'Resumed from sleep',
|
|
28
|
+
[NODE_EVENT_TYPES.DISK_LOW]: 'Disk space low',
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Most attributes a summary of an unknown event prints.
|
|
32
|
+
*
|
|
33
|
+
* @stability experimental
|
|
34
|
+
*/
|
|
35
|
+
export const MAX_NODE_EVENT_SUMMARY_ATTRS = 4;
|
|
36
|
+
/** Longest attribute value a summary prints before an ellipsis. */
|
|
37
|
+
const MAX_ATTR_TEXT = 64;
|
|
38
|
+
function sentenceCase(text) {
|
|
39
|
+
const spaced = text.replace(/_/g, ' ').trim();
|
|
40
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A dotted event type as words: the last segment is the event, the ones before
|
|
44
|
+
* it its area (`transcode.queue_full` to "Transcode: queue full").
|
|
45
|
+
*
|
|
46
|
+
* @param type - the event's dotted type.
|
|
47
|
+
* @returns the humanized text; the input itself when it has no segments.
|
|
48
|
+
*
|
|
49
|
+
* @stability experimental
|
|
50
|
+
*/
|
|
51
|
+
export function humanizeNodeEventType(type) {
|
|
52
|
+
const segments = type.split('.').filter((segment) => segment !== '');
|
|
53
|
+
if (segments.length === 0)
|
|
54
|
+
return type;
|
|
55
|
+
if (segments.length === 1)
|
|
56
|
+
return sentenceCase(segments[0]);
|
|
57
|
+
const last = segments[segments.length - 1];
|
|
58
|
+
const area = segments.slice(0, -1).map(sentenceCase).join(' ');
|
|
59
|
+
return `${area}: ${last.replace(/_/g, ' ')}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* How an event type reads: the platform's label for a `NODE_EVENT_TYPES` name,
|
|
63
|
+
* else {@link humanizeNodeEventType}.
|
|
64
|
+
*
|
|
65
|
+
* @param type - the event's dotted type.
|
|
66
|
+
* @returns the label.
|
|
67
|
+
*
|
|
68
|
+
* @stability experimental
|
|
69
|
+
*/
|
|
70
|
+
export function nodeEventLabel(type) {
|
|
71
|
+
return NODE_EVENT_LABELS[type] ?? humanizeNodeEventType(type);
|
|
72
|
+
}
|
|
73
|
+
function attrNumber(attrs, key) {
|
|
74
|
+
const value = attrs[key];
|
|
75
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
76
|
+
}
|
|
77
|
+
function percent(value) {
|
|
78
|
+
return `${Math.round(value * 10) / 10}%`;
|
|
79
|
+
}
|
|
80
|
+
const POWER_SOURCE_WORDS = Object.freeze({ ac: 'AC', battery: 'Battery', unknown: 'Unknown' });
|
|
81
|
+
function powerSourceWord(value) {
|
|
82
|
+
if (typeof value !== 'string' || value === '')
|
|
83
|
+
return '?';
|
|
84
|
+
return POWER_SOURCE_WORDS[value] ?? value;
|
|
85
|
+
}
|
|
86
|
+
function plainAttr(value) {
|
|
87
|
+
const text = typeof value === 'number' ? value.toLocaleString(undefined, { maximumFractionDigits: 2 }) : String(value);
|
|
88
|
+
return text.length > MAX_ATTR_TEXT ? `${text.slice(0, MAX_ATTR_TEXT - 1)}…` : text;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* One line that says what an event's attributes mean, or `null` when it has
|
|
92
|
+
* none worth printing.
|
|
93
|
+
*
|
|
94
|
+
* Known types read as a sentence fragment ("AC → Battery (64%)", "12% (threshold
|
|
95
|
+
* 20%)", "Asleep for 2h 03m", "4.5% free (1.2 GB)"); an unknown type, or a known
|
|
96
|
+
* one missing the attributes its fragment needs, reads as `key: value` pairs, at
|
|
97
|
+
* most {@link MAX_NODE_EVENT_SUMMARY_ATTRS} of them, sorted by key.
|
|
98
|
+
*
|
|
99
|
+
* @param event - the event (its `type` and `attrs`).
|
|
100
|
+
* @returns the summary, or `null`.
|
|
101
|
+
*
|
|
102
|
+
* @stability experimental
|
|
103
|
+
*/
|
|
104
|
+
export function nodeEventSummary(event) {
|
|
105
|
+
const attrs = event.attrs && typeof event.attrs === 'object' ? event.attrs : {};
|
|
106
|
+
const battery = attrNumber(attrs, 'batteryPercent');
|
|
107
|
+
const threshold = attrNumber(attrs, 'threshold');
|
|
108
|
+
switch (event.type) {
|
|
109
|
+
case NODE_EVENT_TYPES.POWER_SOURCE_CHANGED:
|
|
110
|
+
if (attrs.from !== undefined || attrs.to !== undefined) {
|
|
111
|
+
const change = `${powerSourceWord(attrs.from)} → ${powerSourceWord(attrs.to)}`;
|
|
112
|
+
return battery !== undefined ? `${change} (${percent(battery)})` : change;
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
case NODE_EVENT_TYPES.BATTERY_LOW:
|
|
116
|
+
case NODE_EVENT_TYPES.BATTERY_CRITICAL:
|
|
117
|
+
case NODE_EVENT_TYPES.BATTERY_RECOVERED:
|
|
118
|
+
if (battery !== undefined) {
|
|
119
|
+
return threshold !== undefined ? `${percent(battery)} (threshold ${percent(threshold)})` : percent(battery);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
case NODE_EVENT_TYPES.SLEEP_RESUMED: {
|
|
123
|
+
const gap = attrNumber(attrs, 'gapSeconds');
|
|
124
|
+
if (gap !== undefined)
|
|
125
|
+
return `Asleep for ${formatDuration(gap * 1000)}`;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case NODE_EVENT_TYPES.DISK_LOW: {
|
|
129
|
+
const freePercent = attrNumber(attrs, 'freePercent');
|
|
130
|
+
const freeBytes = attrNumber(attrs, 'freeBytes');
|
|
131
|
+
if (freePercent !== undefined) {
|
|
132
|
+
return freeBytes !== undefined ? `${percent(freePercent)} free (${formatBytes(freeBytes)})` : `${percent(freePercent)} free`;
|
|
133
|
+
}
|
|
134
|
+
if (freeBytes !== undefined)
|
|
135
|
+
return `${formatBytes(freeBytes)} free`;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
default:
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
const entries = Object.entries(attrs)
|
|
142
|
+
.filter(([, value]) => typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value)))
|
|
143
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
144
|
+
if (entries.length === 0)
|
|
145
|
+
return null;
|
|
146
|
+
const shown = entries.slice(0, MAX_NODE_EVENT_SUMMARY_ATTRS).map(([key, value]) => `${key}: ${plainAttr(value)}`);
|
|
147
|
+
const rest = entries.length - shown.length;
|
|
148
|
+
return rest > 0 ? `${shown.join(', ')} (+${rest} more)` : shown.join(', ');
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=node-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-events.js","sourceRoot":"","sources":["../../../src/nodes/headless/node-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { NodePower } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* At or under this battery charge the badge reads in the warning colour.
|
|
4
|
+
*
|
|
5
|
+
* @stability experimental
|
|
6
|
+
*/
|
|
7
|
+
export declare const NODE_BATTERY_WARNING_PERCENT = 20;
|
|
8
|
+
/**
|
|
9
|
+
* At or under this battery charge the badge reads in the error colour.
|
|
10
|
+
*
|
|
11
|
+
* @stability experimental
|
|
12
|
+
*/
|
|
13
|
+
export declare const NODE_BATTERY_CRITICAL_PERCENT = 10;
|
|
14
|
+
/**
|
|
15
|
+
* A node's power state, ready to draw.
|
|
16
|
+
*
|
|
17
|
+
* @stability experimental
|
|
18
|
+
*/
|
|
19
|
+
export interface NodePowerDescription {
|
|
20
|
+
/** Where power comes from (`unknown` is never described). */
|
|
21
|
+
source: 'ac' | 'battery';
|
|
22
|
+
/** Battery charge, rounded to a whole percent, or `null` when not reported. */
|
|
23
|
+
percent: number | null;
|
|
24
|
+
/** Whether the battery is charging, or `null` when not reported. */
|
|
25
|
+
charging: boolean | null;
|
|
26
|
+
/** `warning` at or under 20%, `error` at or under 10%, on battery only. */
|
|
27
|
+
level: 'normal' | 'warning' | 'error';
|
|
28
|
+
/** The short visible text: `42%`, `AC`. */
|
|
29
|
+
text: string;
|
|
30
|
+
/** The full sentence, the accessible label: "On battery, 42%, discharging". */
|
|
31
|
+
label: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The badge's words and level for a node's reported power, or `null` when
|
|
35
|
+
* there is nothing to draw (no report, or source `unknown`).
|
|
36
|
+
*
|
|
37
|
+
* @param power - `lastVitals.power`, if any.
|
|
38
|
+
* @returns the description, or `null`.
|
|
39
|
+
*
|
|
40
|
+
* @stability experimental
|
|
41
|
+
*/
|
|
42
|
+
export declare function describeNodePower(power: NodePower | null | undefined): NodePowerDescription | null;
|
|
43
|
+
//# sourceMappingURL=power.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"power.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/power.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,MAAM,EAAE,IAAI,GAAG,SAAS,CAAC;IACzB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,oEAAoE;IACpE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,2EAA2E;IAC3E,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;IACtC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,oBAAoB,GAAG,IAAI,CAkClG"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// A node's power state, as the Worker Nodes page words it (issue #1045)
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// A node on a laptop reports `vitals.power` (source, battery charge, charging);
|
|
6
|
+
// the fleet table shows a badge for it. This module is the badge's words and
|
|
7
|
+
// level, without markup: the UI draws the icon and the colour from the level,
|
|
8
|
+
// and the SAME sentence is its accessible label, so nothing rests on colour.
|
|
9
|
+
//
|
|
10
|
+
// Display only: a node on battery is not "unhealthy", and nothing here turns
|
|
11
|
+
// the reading into a health verdict (health is the API's, from the heartbeat).
|
|
12
|
+
// An `unknown` or absent source draws nothing: a desktop that cannot tell is not
|
|
13
|
+
// worth a badge on every row.
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* At or under this battery charge the badge reads in the warning colour.
|
|
17
|
+
*
|
|
18
|
+
* @stability experimental
|
|
19
|
+
*/
|
|
20
|
+
export const NODE_BATTERY_WARNING_PERCENT = 20;
|
|
21
|
+
/**
|
|
22
|
+
* At or under this battery charge the badge reads in the error colour.
|
|
23
|
+
*
|
|
24
|
+
* @stability experimental
|
|
25
|
+
*/
|
|
26
|
+
export const NODE_BATTERY_CRITICAL_PERCENT = 10;
|
|
27
|
+
/**
|
|
28
|
+
* The badge's words and level for a node's reported power, or `null` when
|
|
29
|
+
* there is nothing to draw (no report, or source `unknown`).
|
|
30
|
+
*
|
|
31
|
+
* @param power - `lastVitals.power`, if any.
|
|
32
|
+
* @returns the description, or `null`.
|
|
33
|
+
*
|
|
34
|
+
* @stability experimental
|
|
35
|
+
*/
|
|
36
|
+
export function describeNodePower(power) {
|
|
37
|
+
if (!power || typeof power !== 'object')
|
|
38
|
+
return null;
|
|
39
|
+
const percent = typeof power.batteryPercent === 'number' && Number.isFinite(power.batteryPercent)
|
|
40
|
+
? Math.round(Math.min(100, Math.max(0, power.batteryPercent)))
|
|
41
|
+
: null;
|
|
42
|
+
const charging = typeof power.charging === 'boolean' ? power.charging : null;
|
|
43
|
+
if (power.source === 'ac') {
|
|
44
|
+
const parts = ['On AC power'];
|
|
45
|
+
if (percent !== null)
|
|
46
|
+
parts.push(`battery ${percent}%`);
|
|
47
|
+
if (charging === true)
|
|
48
|
+
parts.push('charging');
|
|
49
|
+
return { source: 'ac', percent, charging, level: 'normal', text: 'AC', label: parts.join(', ') };
|
|
50
|
+
}
|
|
51
|
+
if (power.source !== 'battery')
|
|
52
|
+
return null;
|
|
53
|
+
const level = percent !== null && percent <= NODE_BATTERY_CRITICAL_PERCENT
|
|
54
|
+
? 'error'
|
|
55
|
+
: percent !== null && percent <= NODE_BATTERY_WARNING_PERCENT
|
|
56
|
+
? 'warning'
|
|
57
|
+
: 'normal';
|
|
58
|
+
const parts = ['On battery'];
|
|
59
|
+
if (percent !== null)
|
|
60
|
+
parts.push(`${percent}%`);
|
|
61
|
+
if (charging !== null)
|
|
62
|
+
parts.push(charging ? 'charging' : 'discharging');
|
|
63
|
+
if (power.lowPowerMode === true)
|
|
64
|
+
parts.push('low power mode');
|
|
65
|
+
return {
|
|
66
|
+
source: 'battery',
|
|
67
|
+
percent,
|
|
68
|
+
charging,
|
|
69
|
+
level,
|
|
70
|
+
text: percent !== null ? `${percent}%` : 'Battery',
|
|
71
|
+
label: parts.join(', '),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=power.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"power.js","sourceRoot":"","sources":["../../../src/nodes/headless/power.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wEAAwE;AACxE,gFAAgF;AAChF,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,iFAAiF;AACjF,8BAA8B;AAC9B,gFAAgF;AAIhF;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAsBhD;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAmC;IACnE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,OAAO,GACX,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC;QAC/E,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,QAAQ,GAAG,OAAO,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7E,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC;QAC9B,IAAI,OAAO,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,GAAG,CAAC,CAAC;QACxD,IAAI,QAAQ,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACnG,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,KAAK,GACT,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,6BAA6B;QAC1D,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,4BAA4B;YAC3D,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,QAAQ,CAAC;IACjB,MAAM,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC;IAC7B,IAAI,OAAO,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAChD,IAAI,QAAQ,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IACzE,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC9D,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,OAAO;QACP,QAAQ;QACR,KAAK;QACL,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS;QAClD,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;KACxB,CAAC;AACJ,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
-
import type { AdminNode, AdminNodeCredential, NodeCredentialCreated, NodeHealth, NodeJobCounts, NodeOwner, NodeStatus, NodeVitals, NodeVitalsCounters, createNodeCredentialSchema } from '@marinoscar/platform-contract/nodes';
|
|
3
|
-
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_HEALTHS, NODE_STATUSES, } from '@marinoscar/platform-contract/nodes';
|
|
4
|
-
export type { NodeCredentialCreated, NodeHealth, NodeJobCounts, NodeOwner, NodeStatus, NodeVitals, NodeVitalsCounters, };
|
|
2
|
+
import type { AdminNode, AdminNodeCredential, AdminNodeEvent, AdminNodeEventList, NodeCredentialCreated, NodeHealth, NodeHostVitals, NodeJobCounts, NodeOwner, NodePower, NodeStatus, NodeVitals, NodeVitalsCounters, createNodeCredentialSchema } from '@marinoscar/platform-contract/nodes';
|
|
3
|
+
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_EVENT_TYPES, NODE_HEALTHS, NODE_STATUSES, } from '@marinoscar/platform-contract/nodes';
|
|
4
|
+
export type { NodeCredentialCreated, NodeHealth, NodeHostVitals, NodeJobCounts, NodeOwner, NodePower, NodeStatus, NodeVitals, NodeVitalsCounters, };
|
|
5
5
|
/**
|
|
6
6
|
* One node as `GET /api/admin/nodes` returns it (`AdminNodeDto`,
|
|
7
7
|
* `adminNodeSchema`).
|
|
@@ -9,6 +9,43 @@ export type { NodeCredentialCreated, NodeHealth, NodeJobCounts, NodeOwner, NodeS
|
|
|
9
9
|
* @stability experimental
|
|
10
10
|
*/
|
|
11
11
|
export type WorkerNode = AdminNode;
|
|
12
|
+
/**
|
|
13
|
+
* One stored node event as `GET /api/admin/nodes/:id/events` returns it
|
|
14
|
+
* (`adminNodeEventSchema`, #1045): a power change, a low battery, a wake from
|
|
15
|
+
* sleep, a low disk. `type` is an OPEN dotted string (`NODE_EVENT_TYPES` names
|
|
16
|
+
* the platform's own); `occurredAt` is the node's clock, `receivedAt` the server's.
|
|
17
|
+
*
|
|
18
|
+
* @stability experimental
|
|
19
|
+
*/
|
|
20
|
+
export type WorkerNodeEvent = AdminNodeEvent;
|
|
21
|
+
/**
|
|
22
|
+
* A page of node events (`adminNodeEventListSchema`), newest first.
|
|
23
|
+
*
|
|
24
|
+
* @stability experimental
|
|
25
|
+
*/
|
|
26
|
+
export type WorkerNodeEventList = AdminNodeEventList;
|
|
27
|
+
/**
|
|
28
|
+
* How loud a node event is: `info`, `warning` or `critical`.
|
|
29
|
+
*
|
|
30
|
+
* @stability experimental
|
|
31
|
+
*/
|
|
32
|
+
export type NodeEventSeverity = AdminNodeEvent['severity'];
|
|
33
|
+
/**
|
|
34
|
+
* The query `GET /api/admin/nodes/:id/events` takes. Every member optional; an absent
|
|
35
|
+
* one is left out of the query string (the API's defaults apply).
|
|
36
|
+
*
|
|
37
|
+
* @stability experimental
|
|
38
|
+
*/
|
|
39
|
+
export interface NodeEventsQuery {
|
|
40
|
+
/** 1-based page. */
|
|
41
|
+
page?: number;
|
|
42
|
+
/** Events per page. */
|
|
43
|
+
pageSize?: number;
|
|
44
|
+
/** Only events of this exact type (`power.battery_low`). */
|
|
45
|
+
type?: string;
|
|
46
|
+
/** Only events of this severity. */
|
|
47
|
+
severity?: NodeEventSeverity;
|
|
48
|
+
}
|
|
12
49
|
/**
|
|
13
50
|
* One credential as `GET /api/admin/nodes/credentials` returns it
|
|
14
51
|
* (`AdminNodeCredentialDto`, `adminNodeCredentialSchema`). No `token`, no hash;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/types.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,YAAY,EACZ,aAAa,GACd,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,GACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEnF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,WAAW,CAAC,EAC3D,GAAG,GAAE,IAAiB,GACrB,oBAAoB,CAStB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/types.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,EACV,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,kBAAkB,GACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEnF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,WAAW,CAAC,EAC3D,GAAG,GAAE,IAAiB,GACrB,oBAAoB,CAStB"}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// heartbeat against the `nodes.staleHeartbeatSeconds` system setting, which
|
|
20
20
|
// the browser does not read), so nothing in this slice recomputes it.
|
|
21
21
|
// =============================================================================
|
|
22
|
-
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_HEALTHS, NODE_STATUSES, } from '@marinoscar/platform-contract/nodes';
|
|
22
|
+
export { MAX_NODE_CREDENTIAL_DAYS, MAX_NODE_CREDENTIAL_NAME_LENGTH, NODE_EVENT_TYPES, NODE_HEALTHS, NODE_STATUSES, } from '@marinoscar/platform-contract/nodes';
|
|
23
23
|
/**
|
|
24
24
|
* Whether a credential can still authenticate a node right now.
|
|
25
25
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/nodes/headless/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,sEAAsE;AACtE,gFAAgF;AAChF,EAAE;AACF,wFAAwF;AACxF,gFAAgF;AAChF,8EAA8E;AAC9E,+EAA+E;AAC/E,eAAe;AACf,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,mCAAmC;AACnC,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,sEAAsE;AACtE,gFAAgF;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/nodes/headless/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,sEAAsE;AACtE,gFAAgF;AAChF,EAAE;AACF,wFAAwF;AACxF,gFAAgF;AAChF,8EAA8E;AAC9E,+EAA+E;AAC/E,eAAe;AACf,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,mCAAmC;AACnC,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,sEAAsE;AACtE,gFAAgF;AAoBhF,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,qCAAqC,CAAC;AAsF7C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAA2D,EAC3D,MAAY,IAAI,IAAI,EAAE;IAEtB,IAAI,UAAU,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,0EAA0E;IAC1E,yEAAyE;IACzE,gDAAgD;IAChD,IAAI,UAAU,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QACtF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One node's recent events (issue #1045): `GET /api/admin/nodes/:id/events`, newest
|
|
3
|
+
* first, with "load more".
|
|
4
|
+
*
|
|
5
|
+
* The same contract as the fleet hooks (`use-worker-nodes.ts`): every function
|
|
6
|
+
* resolves rather than throws, and a failure is a STRING the caller renders.
|
|
7
|
+
*
|
|
8
|
+
* The first page is asked for when the node or the filters change; `loadMore`
|
|
9
|
+
* appends the next page; `refresh` re-reads from the first page WITHOUT raising
|
|
10
|
+
* the loading flag (the list stays on screen). An event that arrives between a
|
|
11
|
+
* first page and a "load more" shifts the pages by one, so an appended page is
|
|
12
|
+
* de-duplicated by id rather than trusted to start where the last one ended.
|
|
13
|
+
*
|
|
14
|
+
* The query is read member by member (`page`, `pageSize`, `type`, `severity`),
|
|
15
|
+
* so an inline object literal does not re-fetch on every render.
|
|
16
|
+
*/
|
|
17
|
+
import type { NodesApi } from './api.js';
|
|
18
|
+
import type { NodeEventsQuery, WorkerNodeEvent } from './types.js';
|
|
19
|
+
/**
|
|
20
|
+
* What {@link useNodeEvents} returns.
|
|
21
|
+
*
|
|
22
|
+
* @stability experimental
|
|
23
|
+
*/
|
|
24
|
+
export interface UseNodeEventsResult {
|
|
25
|
+
/** The events read so far, newest first; emptied on an error or with no node. */
|
|
26
|
+
events: WorkerNodeEvent[];
|
|
27
|
+
/** How many events the node has in total (for the filters), `0` before an answer. */
|
|
28
|
+
total: number;
|
|
29
|
+
/** Whether a further page exists. */
|
|
30
|
+
hasMore: boolean;
|
|
31
|
+
/** The first page is in flight. */
|
|
32
|
+
isLoading: boolean;
|
|
33
|
+
/** A `loadMore` page is in flight. */
|
|
34
|
+
isLoadingMore: boolean;
|
|
35
|
+
/** The last failure as a sentence, or `null`. */
|
|
36
|
+
error: string | null;
|
|
37
|
+
/** Re-read from the first page without raising the loading flag. */
|
|
38
|
+
refresh: () => Promise<void>;
|
|
39
|
+
/** Append the next page. A no-op while one is in flight or when there is none. */
|
|
40
|
+
loadMore: () => Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* `GET /api/admin/nodes/:id/events`: a node's events, newest first, page by page.
|
|
44
|
+
*
|
|
45
|
+
* @param nodeId - the node id, or `null` to ask for nothing.
|
|
46
|
+
* @param query - the first page, its size and the filters (every member optional).
|
|
47
|
+
* @param api - a client to use instead of the adapters' or the host's.
|
|
48
|
+
* @returns the events and their state.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* const { events, hasMore, loadMore } = useNodeEvents(node.id, { pageSize: 20, severity: 'critical' });
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @extensionPoint hook
|
|
56
|
+
* @stability experimental
|
|
57
|
+
*/
|
|
58
|
+
export declare function useNodeEvents(nodeId: string | null, query?: NodeEventsQuery, api?: NodesApi): UseNodeEventsResult;
|
|
59
|
+
//# sourceMappingURL=use-node-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../../src/nodes/headless/use-node-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAC;AAExF;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,aAAa,EAAE,OAAO,CAAC;IACvB,iDAAiD;IACjD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oEAAoE;IACpE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AA2BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,GAAE,eAAoB,EAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAqGrH"}
|