@camstack/addon-admin-ui 1.2.106 → 1.2.108
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/dist/assets/{AddLocationWizard-DPvpYCGn.js → AddLocationWizard-C1QuDd5l.js} +1 -1
- package/dist/assets/{AddonCollectionPage-DLJXV_3S.js → AddonCollectionPage-CAMY7BSp.js} +1 -1
- package/dist/assets/Addons-bWB0ZmER.js +1 -0
- package/dist/assets/{AdminTabs-ugTfV6vR.js → AdminTabs-DIHki8py.js} +1 -1
- package/dist/assets/{AiProfiles-B3OoMGwy.js → AiProfiles-DiQNZe9S.js} +2 -2
- package/dist/assets/{BrokerForm-FW8CGvEw.js → BrokerForm-mfcucCqe.js} +1 -1
- package/dist/assets/{Build-CKSSyLHR.js → Build-Bd3bm4rZ.js} +4 -4
- package/dist/assets/Capabilities-CT-vp-yT.js +1 -0
- package/dist/assets/{CapabilityBadges-2_RTtE8F.js → CapabilityBadges-5yUqlEI8.js} +1 -1
- package/dist/assets/Cluster-BPFw3CEh.js +11 -0
- package/dist/assets/Data-DLHWqZce.js +1 -0
- package/dist/assets/DetectionIntelligence-B4PBUQWJ.js +1 -0
- package/dist/assets/{DeviceAggregateSection-B-LbbxBn.js → DeviceAggregateSection-CJc0z5bD.js} +1 -1
- package/dist/assets/DeviceDetail-bORj-EYN.js +2 -0
- package/dist/assets/{Devices-DyOwMmsB.js → Devices-D88uoW-K.js} +1 -1
- package/dist/assets/{EmbedPlayerPage-DLylekcq.js → EmbedPlayerPage-BQ5bsryo.js} +1 -1
- package/dist/assets/Events-D9XRueHk.js +1 -0
- package/dist/assets/{FormBuilder-DaTNPCtr.js → FormBuilder-DfwoGzWg.js} +1 -1
- package/dist/assets/Identity-43Eya081.js +1 -0
- package/dist/assets/IntegrationDetail-CwEQCSYB.js +1 -0
- package/dist/assets/Integrations-Bj0zg-09.js +1 -0
- package/dist/assets/Integrations-tWtIaZju.js +1 -0
- package/dist/assets/{Logs-B9aMiGDX.js → Logs-BI78-0VJ.js} +1 -1
- package/dist/assets/{MotionZonesSettings-BAld-2Lw.js → MotionZonesSettings-gEbDj9Pj.js} +1 -1
- package/dist/assets/MyAccess-Dq5YfsIV.js +2 -0
- package/dist/assets/Network-0uDqECDb.js +1 -0
- package/dist/assets/NodeAddonsSettingsPanel-CAyKEQpD.js +1 -0
- package/dist/assets/{NodeInferenceDevices-DruKQsKv.js → NodeInferenceDevices-CnDRCNxR.js} +1 -1
- package/dist/assets/Notifications-zU06XSrO.js +1 -0
- package/dist/assets/Pipeline-B5A-GVGG.js +1 -0
- package/dist/assets/Plates-LVOTLRQ_.js +1 -0
- package/dist/assets/{PrivacyMaskSettings-t81B_gek.js → PrivacyMaskSettings-ByMo4smL.js} +1 -1
- package/dist/assets/{ProviderIcon-1IBp_VK5.js → ProviderIcon-BuQT-C1f.js} +1 -1
- package/dist/assets/Recordings-TSgV5nm4.js +1 -0
- package/dist/assets/{ScanNetworkModal-DId274fd.js → ScanNetworkModal-DO_NYOIO.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-B57j4d9e.js → SceneMonitorEditor-COTXt9Av.js} +1 -1
- package/dist/assets/{Scenes-BJcEln5I.js → Scenes-DgDtCzMz.js} +1 -1
- package/dist/assets/Settings-UaBYAyll.js +1 -0
- package/dist/assets/{Showroom-CGYvWhTb.js → Showroom-BO0DQHWe.js} +1 -1
- package/dist/assets/{Terminal-Db32GfJu.js → Terminal-D6BI2-dB.js} +4 -4
- package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-x2EKNp38.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-6VfZqYHt.js} +1 -1
- package/dist/assets/{bell-ring-fa6SzUi_.js → bell-ring-COnGH5xz.js} +1 -1
- package/dist/assets/{boxes-CfnJWdJa.js → boxes-BqAi_ZYu.js} +1 -1
- package/dist/assets/circle-check-big-BQVyFP9A.js +1 -0
- package/dist/assets/{circle-x-B470_M0K.js → circle-x-CAQ2kQrS.js} +1 -1
- package/dist/assets/clock-DGWYKseh.js +1 -0
- package/dist/assets/{copy-Bz5_L_j0.js → copy-D25tAWbr.js} +1 -1
- package/dist/assets/{debounced-invalidate-BgLJ3Lz0.js → debounced-invalidate-Dd9oPYKq.js} +1 -1
- package/dist/assets/dist-B_SWpX_l.js +349 -0
- package/dist/assets/{dist-BiaTzHe6.js → dist-Cz-CwPmU.js} +1 -1
- package/dist/assets/{download-CPPi4lEs.js → download-DC6CvEwh.js} +1 -1
- package/dist/assets/{face-bbox-Bk5OxbZ9.js → face-bbox-HBoy_dVM.js} +1 -1
- package/dist/assets/{hostInit-CfHVCMU0.js → hostInit-BZyW6qkD.js} +1 -1
- package/dist/assets/index-2B_jjVhf.css +2 -0
- package/dist/assets/index-Cp84SBzW.js +4 -0
- package/dist/assets/{key-round-GUiZ3GBz.js → key-round-CkImMp76.js} +1 -1
- package/dist/assets/{layers-BHA4WXNG.js → layers-DR9qbaZc.js} +1 -1
- package/dist/assets/{mf-entry-bootstrap-0-72686030.js → mf-entry-bootstrap-0-ed3637b6.js} +2 -2
- package/dist/assets/{pencil-CywoEYDw.js → pencil-D-rxGNNf.js} +1 -1
- package/dist/assets/play-s0iikQHY.js +1 -0
- package/dist/assets/{player-overlays-C1Oe-16j.js → player-overlays-wniETo4u.js} +1 -1
- package/dist/assets/plus-BVcSfMMt.js +1 -0
- package/dist/assets/power-CcdufSlh.js +1 -0
- package/dist/assets/{radio-lEGHQd-3.js → radio-dB0UNm47.js} +1 -1
- package/dist/assets/{refresh-cw-BEHJsw3X.js → refresh-cw-srKCTv_-.js} +1 -1
- package/dist/assets/remoteEntry-B2zHiyBK.js +1 -0
- package/dist/assets/rotate-ccw-CY-1yf9N.js +1 -0
- package/dist/assets/rotate-cw-DKLLB8dt.js +1 -0
- package/dist/assets/{send-CdTPIK-7.js → send-DouvNKBS.js} +1 -1
- package/dist/assets/{server-CKXUNcfQ.js → server-BQtqKhWd.js} +1 -1
- package/dist/assets/{shield-DuQG63BO.js → shield-Df5MsuC2.js} +1 -1
- package/dist/assets/square-CFDIb2ZA.js +1 -0
- package/dist/assets/{square-check-big-xoQlO2z6.js → square-check-big-DRcEphPQ.js} +1 -1
- package/dist/assets/src-CsxD-27Y.js +349 -0
- package/dist/assets/src-IW6snE8b.js +67 -0
- package/dist/assets/{star-Dij84nD8.js → star-DSf9DLF0.js} +1 -1
- package/dist/assets/{undo-2-DtQ5QK61.js → undo-2-D8E8Za4o.js} +1 -1
- package/dist/assets/{use-scenes-feed-BAtj9fjN.js → use-scenes-feed-DZbJbkzy.js} +1 -1
- package/dist/assets/useEventInvalidation-CsNvM4qI.js +1 -0
- package/dist/assets/{video-_cSQX0pK.js → video-DMGYxQJX.js} +1 -1
- package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CCi4D5V9.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-ByOZvjdD.js} +2 -2
- package/dist/assets/{wifi-DFad8LAE.js → wifi-DPLmik5h.js} +1 -1
- package/dist/assets/{zap-BEaKr1nX.js → zap-D-TFU8vN.js} +1 -1
- package/dist/index.html +6 -6
- package/dist/server/addon.js +256 -26
- package/package.json +1 -1
- package/dist/assets/Addons-COnaHviu.js +0 -1
- package/dist/assets/Capabilities-Bvk135Hx.js +0 -1
- package/dist/assets/Cluster-BIIxDRXP.js +0 -1
- package/dist/assets/Data-DUfQYWdR.js +0 -1
- package/dist/assets/DetectionIntelligence-_SicEHJ7.js +0 -1
- package/dist/assets/DeviceDetail-QGu4Zppg.js +0 -2
- package/dist/assets/Events-Bd7_dT0H.js +0 -1
- package/dist/assets/Identity-qjHZBREK.js +0 -1
- package/dist/assets/IntegrationDetail-DaIdJdyp.js +0 -1
- package/dist/assets/Integrations-B3wdYU9G.js +0 -1
- package/dist/assets/Integrations-BXkqNtA2.js +0 -1
- package/dist/assets/MyAccess-DYc5Ia6R.js +0 -2
- package/dist/assets/Network-DtCqr7_n.js +0 -1
- package/dist/assets/NodeAddonsSettingsPanel-DCrm5WAe.js +0 -1
- package/dist/assets/Notifications-DN4WDeO2.js +0 -1
- package/dist/assets/Pipeline-BQaaY2RF.js +0 -1
- package/dist/assets/Plates-DzAZ1RGB.js +0 -1
- package/dist/assets/Recordings-C6gSAs30.js +0 -1
- package/dist/assets/Settings-DxbbgMBy.js +0 -1
- package/dist/assets/build-cluster-graph-BlQoSudm.js +0 -7
- package/dist/assets/circle-check-big-C_6LzyMr.js +0 -1
- package/dist/assets/clock-44ycL5OK.js +0 -1
- package/dist/assets/dist-CxVTxcO_.js +0 -349
- package/dist/assets/index-BlRpxCYM.css +0 -2
- package/dist/assets/index-DmGVQVip.js +0 -4
- package/dist/assets/play-Dfmddr6T.js +0 -1
- package/dist/assets/plus-BpSOCY8P.js +0 -1
- package/dist/assets/power-CNppeI6O.js +0 -1
- package/dist/assets/remoteEntry-CpjMZXjT.js +0 -1
- package/dist/assets/rotate-ccw-ZN_nOrZf.js +0 -1
- package/dist/assets/rotate-cw-CDaIhQNY.js +0 -1
- package/dist/assets/square-BpVTHFXt.js +0 -1
- package/dist/assets/src-DLoxi-uA.js +0 -349
- package/dist/assets/src-DjZVUvrt.js +0 -67
- package/dist/assets/upload-Bh__Gcoi.js +0 -1
- package/dist/assets/useEventInvalidation-Deon74Uu.js +0 -1
package/dist/server/addon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
//#region ../types/dist/event-category-
|
|
3
|
+
//#region ../types/dist/event-category-BZL-fdNj.mjs
|
|
4
4
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
5
5
|
EventCategory["SystemBoot"] = "system.boot";
|
|
6
6
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -437,7 +437,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
437
437
|
EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
|
|
438
438
|
/**
|
|
439
439
|
* Periodic per-node process-tree snapshot (camstack-related pids
|
|
440
|
-
* with
|
|
440
|
+
* with root / managed / system classification). Emitted ~0.2 Hz by
|
|
441
441
|
* the metrics-provider addon. Drives the Cluster → Processes tab
|
|
442
442
|
* without polling `metricsProvider.listNodeProcesses`.
|
|
443
443
|
*/
|
|
@@ -11129,6 +11129,19 @@ var SettingsRecordSchema = object({
|
|
|
11129
11129
|
data: record(string(), unknown())
|
|
11130
11130
|
});
|
|
11131
11131
|
/**
|
|
11132
|
+
* One record of a BULK insert — {@link SettingsRecordSchema} with the id made
|
|
11133
|
+
* optional.
|
|
11134
|
+
*
|
|
11135
|
+
* A separate schema rather than loosening the shared one: every other method
|
|
11136
|
+
* on this cap addresses a row BY its id, and making that field optional
|
|
11137
|
+
* everywhere would turn a forgotten key into a silently generated one on
|
|
11138
|
+
* `update` and `delete` as well.
|
|
11139
|
+
*/
|
|
11140
|
+
var BulkRecordSchema = object({
|
|
11141
|
+
id: string().optional(),
|
|
11142
|
+
data: record(string(), unknown())
|
|
11143
|
+
});
|
|
11144
|
+
/**
|
|
11132
11145
|
* Column declaration for a structured (SQL-backed) collection.
|
|
11133
11146
|
*
|
|
11134
11147
|
* Logical types — the backend translates each to the matching SQLite
|
|
@@ -11185,6 +11198,10 @@ method(object({
|
|
|
11185
11198
|
collection: string(),
|
|
11186
11199
|
record: SettingsRecordSchema
|
|
11187
11200
|
}), _void(), { kind: "mutation" }), method(object({
|
|
11201
|
+
namespace: string().optional(),
|
|
11202
|
+
collection: string(),
|
|
11203
|
+
records: array(BulkRecordSchema).readonly()
|
|
11204
|
+
}), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
|
|
11188
11205
|
namespace: string().optional(),
|
|
11189
11206
|
collection: string(),
|
|
11190
11207
|
id: string(),
|
|
@@ -11293,6 +11310,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
11293
11310
|
}), _void(), {
|
|
11294
11311
|
kind: "mutation",
|
|
11295
11312
|
auth: "admin"
|
|
11313
|
+
}), method(object({
|
|
11314
|
+
namespace: string().optional(),
|
|
11315
|
+
collection: string(),
|
|
11316
|
+
records: array(BulkRecordSchema).readonly()
|
|
11317
|
+
}), object({ inserted: number().int() }), {
|
|
11318
|
+
kind: "mutation",
|
|
11319
|
+
auth: "admin"
|
|
11296
11320
|
}), method(object({
|
|
11297
11321
|
namespace: string().optional(),
|
|
11298
11322
|
collection: string(),
|
|
@@ -13061,6 +13085,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
|
|
|
13061
13085
|
limit: number().optional(),
|
|
13062
13086
|
tags: record(string(), string()).optional()
|
|
13063
13087
|
}), array(LogEntrySchema).readonly());
|
|
13088
|
+
var LoadContributionSchema = object({
|
|
13089
|
+
role: _enum([
|
|
13090
|
+
"decode",
|
|
13091
|
+
"transcode",
|
|
13092
|
+
"recording",
|
|
13093
|
+
"streaming",
|
|
13094
|
+
"detection"
|
|
13095
|
+
]),
|
|
13096
|
+
/**
|
|
13097
|
+
* The NUMERIC device id — the same value every log line carries as
|
|
13098
|
+
* `tags.deviceId`. `null` means this cost genuinely belongs to no single
|
|
13099
|
+
* camera (a shared pool), NOT that the contributor forgot to look it up: a
|
|
13100
|
+
* contributor that cannot name its camera must not emit the entry at all,
|
|
13101
|
+
* because an unnamed per-camera entry is indistinguishable from a shared one
|
|
13102
|
+
* and would quietly turn one camera's cost into everybody's.
|
|
13103
|
+
*/
|
|
13104
|
+
deviceId: number().int().positive().nullable(),
|
|
13105
|
+
attribution: _enum([
|
|
13106
|
+
"measured",
|
|
13107
|
+
"accounted",
|
|
13108
|
+
"unattributable"
|
|
13109
|
+
]),
|
|
13110
|
+
/**
|
|
13111
|
+
* What ONE entry is, in the contributor's own words — `615/high`,
|
|
13112
|
+
* `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
|
|
13113
|
+
* family and inventing a common one would lose the only information that
|
|
13114
|
+
* makes two entries for the same camera distinguishable.
|
|
13115
|
+
*/
|
|
13116
|
+
unit: string(),
|
|
13117
|
+
/**
|
|
13118
|
+
* The OS process this cost lives in, when there is one. Present so a
|
|
13119
|
+
* consumer can (a) tell two generations of the same unit apart across a
|
|
13120
|
+
* restart, and (b) subtract claimed processes from the node's process
|
|
13121
|
+
* snapshot to see what NOBODY claimed. Absent for an entry that owns no
|
|
13122
|
+
* process of its own.
|
|
13123
|
+
*/
|
|
13124
|
+
pid: number().int().positive().optional(),
|
|
13125
|
+
/**
|
|
13126
|
+
* When this generation started. The pid's incarnation marker: a consumer
|
|
13127
|
+
* differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
|
|
13128
|
+
* window when this changes, because the counter restarted from zero in a new
|
|
13129
|
+
* process.
|
|
13130
|
+
*/
|
|
13131
|
+
startedAtMs: number().optional(),
|
|
13132
|
+
/**
|
|
13133
|
+
* CUMULATIVE CPU seconds this unit has consumed since it started — user +
|
|
13134
|
+
* system, read from the child's own `/proc/<pid>/stat` at the moment the
|
|
13135
|
+
* contribution is asked for.
|
|
13136
|
+
*
|
|
13137
|
+
* Cumulative and not a rate on purpose: a rate needs a window, a window
|
|
13138
|
+
* needs a sampler, and a new per-node sampler is the defect half of
|
|
13139
|
+
* `docs/architecture/load-ledger.md` documents. A counter can be differenced
|
|
13140
|
+
* by whoever already keeps a history; a rate cannot be un-averaged.
|
|
13141
|
+
*
|
|
13142
|
+
* Absent — never zero — on a node with no `/proc`, on a read failure, and on
|
|
13143
|
+
* an entry with no process.
|
|
13144
|
+
*/
|
|
13145
|
+
cpuSeconds: number().optional(),
|
|
13146
|
+
/** Resident bytes of this unit's process, same source and same rules. */
|
|
13147
|
+
rssBytes: number().optional()
|
|
13148
|
+
});
|
|
13149
|
+
method(_void(), array(LoadContributionSchema).readonly());
|
|
13064
13150
|
/**
|
|
13065
13151
|
* `login-method` — collection cap through which auth addons contribute
|
|
13066
13152
|
* their pre-auth login surfaces to the login page. This is the SINGLE,
|
|
@@ -13264,8 +13350,7 @@ var NodeProcessSchema = object({
|
|
|
13264
13350
|
classification: _enum([
|
|
13265
13351
|
"root",
|
|
13266
13352
|
"managed",
|
|
13267
|
-
"system"
|
|
13268
|
-
"ghost"
|
|
13353
|
+
"system"
|
|
13269
13354
|
]),
|
|
13270
13355
|
/** `$process` addon binding when `managed`, else null. */
|
|
13271
13356
|
addonId: string().nullable(),
|
|
@@ -13273,22 +13358,39 @@ var NodeProcessSchema = object({
|
|
|
13273
13358
|
nodeId: string().nullable(),
|
|
13274
13359
|
/** Truncated command line. */
|
|
13275
13360
|
command: string(),
|
|
13361
|
+
/**
|
|
13362
|
+
* `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
|
|
13363
|
+
* On a runner up for days it barely moves. Fine as a column, useless as a
|
|
13364
|
+
* series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
|
|
13365
|
+
*/
|
|
13276
13366
|
cpuPercent: number(),
|
|
13277
13367
|
memoryRssBytes: number(),
|
|
13368
|
+
/**
|
|
13369
|
+
* Instantaneous CPU% of the process's own threads over the last
|
|
13370
|
+
* process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
|
|
13371
|
+
*
|
|
13372
|
+
* `null` = UNKNOWN, never zero: no previous sample yet (first tick after
|
|
13373
|
+
* boot), the pid was recycled, or this node is not Linux.
|
|
13374
|
+
*/
|
|
13375
|
+
cpuMainPercent: number().nullable(),
|
|
13376
|
+
/**
|
|
13377
|
+
* Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
|
|
13378
|
+
*
|
|
13379
|
+
* This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
|
|
13380
|
+
* `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
|
|
13381
|
+
* does not separate it from `cpuMainPercent` shows "busy" where the truth is
|
|
13382
|
+
* "allocating too much".
|
|
13383
|
+
*
|
|
13384
|
+
* Concurrent GC is the dominant tenant of that pool but not the only one
|
|
13385
|
+
* (background compilation runs there too), so it is reported as
|
|
13386
|
+
* "GC / V8 helpers" rather than as pure collection time. `null` has the same
|
|
13387
|
+
* meaning as on `cpuMainPercent`.
|
|
13388
|
+
*/
|
|
13389
|
+
cpuGcPercent: number().nullable(),
|
|
13390
|
+
/** Threads seen in the tick scan. `null` under the same conditions. */
|
|
13391
|
+
threadCount: number().nullable(),
|
|
13278
13392
|
/** Wall-clock uptime (seconds). Parsed from `ps etime`. */
|
|
13279
|
-
uptimeSec: number()
|
|
13280
|
-
/** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
|
|
13281
|
-
orphaned: boolean()
|
|
13282
|
-
});
|
|
13283
|
-
var KillProcessInputSchema = object({
|
|
13284
|
-
pid: number(),
|
|
13285
|
-
/** Force = SIGKILL. Default is SIGTERM. */
|
|
13286
|
-
force: boolean().optional()
|
|
13287
|
-
});
|
|
13288
|
-
var KillProcessResultSchema = object({
|
|
13289
|
-
success: boolean(),
|
|
13290
|
-
reason: string().optional(),
|
|
13291
|
-
signal: _enum(["SIGTERM", "SIGKILL"]).optional()
|
|
13393
|
+
uptimeSec: number()
|
|
13292
13394
|
});
|
|
13293
13395
|
var DumpHeapSnapshotInputSchema = object({
|
|
13294
13396
|
/** The addon whose runner should dump a heap snapshot. */
|
|
@@ -13301,6 +13403,104 @@ var DumpHeapSnapshotResultSchema = object({
|
|
|
13301
13403
|
pid: number().optional(),
|
|
13302
13404
|
reason: string().optional()
|
|
13303
13405
|
});
|
|
13406
|
+
/**
|
|
13407
|
+
* One point of one function's series.
|
|
13408
|
+
*
|
|
13409
|
+
* The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
|
|
13410
|
+
* point of the whole surface. The two obvious reductions both lie: a mean per
|
|
13411
|
+
* bucket smears a spike away, and taking every Nth sample skips it outright.
|
|
13412
|
+
* Either would give us a tool built to find peaks that does not show peaks.
|
|
13413
|
+
* `...Min` carries the other end, `samples` says how many raw snapshots folded
|
|
13414
|
+
* into the bucket, and a mean stays derivable where it is wanted.
|
|
13415
|
+
*
|
|
13416
|
+
* An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
|
|
13417
|
+
* equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
|
|
13418
|
+
* caller cannot tell which it received — which is what "one reader" means.
|
|
13419
|
+
*/
|
|
13420
|
+
var LoadPointSchema = object({
|
|
13421
|
+
/** Bucket START, or the snapshot's own timestamp when unreduced. */
|
|
13422
|
+
atMs: number(),
|
|
13423
|
+
/** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
|
|
13424
|
+
samples: number().int(),
|
|
13425
|
+
/**
|
|
13426
|
+
* `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
|
|
13427
|
+
* of every snapshot in it reported a thread split. A partial sum is a
|
|
13428
|
+
* smaller number that looks exactly as real as a complete one.
|
|
13429
|
+
*/
|
|
13430
|
+
cpuMainPercent: number().nullable(),
|
|
13431
|
+
cpuMainPercentMin: number().nullable(),
|
|
13432
|
+
cpuGcPercent: number().nullable(),
|
|
13433
|
+
cpuGcPercentMin: number().nullable(),
|
|
13434
|
+
/** Lifetime-average CPU%, summed. Always known — and never a rate. */
|
|
13435
|
+
cpuLifetimePercent: number(),
|
|
13436
|
+
cpuLifetimePercentMin: number(),
|
|
13437
|
+
memoryRssBytes: number(),
|
|
13438
|
+
memoryRssBytesMin: number(),
|
|
13439
|
+
processCount: number().int(),
|
|
13440
|
+
processCountMin: number().int()
|
|
13441
|
+
});
|
|
13442
|
+
/** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
|
|
13443
|
+
var LoadFunctionSeriesSchema = object({
|
|
13444
|
+
key: string(),
|
|
13445
|
+
kind: _enum([
|
|
13446
|
+
"addon",
|
|
13447
|
+
"root",
|
|
13448
|
+
"unattributed"
|
|
13449
|
+
]),
|
|
13450
|
+
/** Oldest-first. A missing interval is MISSING — never zero-filled. */
|
|
13451
|
+
points: array(LoadPointSchema).readonly()
|
|
13452
|
+
});
|
|
13453
|
+
var NodeLoadSeriesSchema = object({
|
|
13454
|
+
nodeId: string(),
|
|
13455
|
+
/** One entry per function seen in the window, heaviest-first. */
|
|
13456
|
+
series: array(LoadFunctionSeriesSchema).readonly(),
|
|
13457
|
+
/**
|
|
13458
|
+
* Width of one returned bucket, in ms. Equals the sampling cadence when no
|
|
13459
|
+
* reduction was needed — so a caller can always say what one point covers
|
|
13460
|
+
* without having to know whether it was reduced.
|
|
13461
|
+
*/
|
|
13462
|
+
bucketMs: number(),
|
|
13463
|
+
/** Raw snapshots that went into this answer, across both tiers. */
|
|
13464
|
+
retainedSamples: number(),
|
|
13465
|
+
/** Oldest snapshot represented, or `null` when nothing is retained. */
|
|
13466
|
+
oldestAtMs: number().nullable(),
|
|
13467
|
+
/** The fixed sampling cadence in force on the cluster, in ms. */
|
|
13468
|
+
cadenceMs: number(),
|
|
13469
|
+
/**
|
|
13470
|
+
* Did the DURABLE tier contribute? `false` means the answer is the hot ring
|
|
13471
|
+
* alone — an agent (which holds no table), or a store that refused.
|
|
13472
|
+
* Reported because "the last hour" and "the last six hours" are different
|
|
13473
|
+
* questions and an operator must not have to guess which was answered.
|
|
13474
|
+
*/
|
|
13475
|
+
durable: boolean()
|
|
13476
|
+
});
|
|
13477
|
+
var GetLoadSeriesInputSchema = object({
|
|
13478
|
+
/**
|
|
13479
|
+
* The node whose series is wanted.
|
|
13480
|
+
*
|
|
13481
|
+
* NOT named `nodeId`: the generated cap router strips a top-level
|
|
13482
|
+
* `nodeId` from every method input and uses it to ROUTE the call to
|
|
13483
|
+
* that node's provider (`generated-cap-routers.ts`). A series target
|
|
13484
|
+
* called `nodeId` would silently become a routing pin and never reach
|
|
13485
|
+
* the provider. The hub holds every node it hears from, so the
|
|
13486
|
+
* ordinary call is unpinned — answered by the hub, for any node.
|
|
13487
|
+
*/
|
|
13488
|
+
forNodeId: string(),
|
|
13489
|
+
/**
|
|
13490
|
+
* EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
|
|
13491
|
+
* holds and receives only what it is missing, so seeding a live chart
|
|
13492
|
+
* from this method cannot double a point already drawn.
|
|
13493
|
+
*/
|
|
13494
|
+
sinceMs: number().optional(),
|
|
13495
|
+
/**
|
|
13496
|
+
* Most points the caller wants PER FUNCTION. The window is reduced to fit,
|
|
13497
|
+
* preserving min and max per bucket.
|
|
13498
|
+
*
|
|
13499
|
+
* Absent means NO reduction — legitimate for a short window and a trap for a
|
|
13500
|
+
* long one, which is why a chart passes its own pixel width.
|
|
13501
|
+
*/
|
|
13502
|
+
maxPoints: number().int().positive().optional()
|
|
13503
|
+
});
|
|
13304
13504
|
var SystemMetricsSchema = object({
|
|
13305
13505
|
cpuPercent: number(),
|
|
13306
13506
|
memoryPercent: number(),
|
|
@@ -13311,10 +13511,7 @@ var SystemMetricsSchema = object({
|
|
|
13311
13511
|
gpuPercent: number().optional(),
|
|
13312
13512
|
gpuMemoryPercent: number().optional()
|
|
13313
13513
|
});
|
|
13314
|
-
method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(
|
|
13315
|
-
kind: "mutation",
|
|
13316
|
-
auth: "admin"
|
|
13317
|
-
}), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
|
|
13514
|
+
method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(GetLoadSeriesInputSchema, NodeLoadSeriesSchema), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
|
|
13318
13515
|
kind: "mutation",
|
|
13319
13516
|
auth: "admin"
|
|
13320
13517
|
});
|
|
@@ -26617,6 +26814,15 @@ var LoggingSettingsPatchSchema = object({
|
|
|
26617
26814
|
* authority over the whole hierarchy and answers for every layer, so the
|
|
26618
26815
|
* layer selector needs a name the transport does not already own.
|
|
26619
26816
|
*/
|
|
26817
|
+
/**
|
|
26818
|
+
* One contribution, plus WHO reported it.
|
|
26819
|
+
*
|
|
26820
|
+
* The addon and node are added by the hub as it enumerates providers, never by
|
|
26821
|
+
* the contributor: an addon reporting its own identity could report somebody
|
|
26822
|
+
* else's, and the whole point of this surface is that no claim is made by
|
|
26823
|
+
* anyone but its owner.
|
|
26824
|
+
*/
|
|
26825
|
+
var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
|
|
26620
26826
|
var GetLoggingSettingsInputSchema = object({
|
|
26621
26827
|
scopeNodeId: string().optional(),
|
|
26622
26828
|
/**
|
|
@@ -26675,7 +26881,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
|
|
|
26675
26881
|
}), method(_void(), SiteLocationStatusSchema, {
|
|
26676
26882
|
kind: "mutation",
|
|
26677
26883
|
auth: "admin"
|
|
26678
|
-
}), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
|
|
26884
|
+
}), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
|
|
26679
26885
|
kind: "mutation",
|
|
26680
26886
|
auth: "admin"
|
|
26681
26887
|
});
|
|
@@ -28291,6 +28497,12 @@ Object.freeze({
|
|
|
28291
28497
|
addonId: null,
|
|
28292
28498
|
access: "create"
|
|
28293
28499
|
},
|
|
28500
|
+
"dataStoreProvider.insertMany": {
|
|
28501
|
+
capName: "data-store-provider",
|
|
28502
|
+
capScope: "system",
|
|
28503
|
+
addonId: null,
|
|
28504
|
+
access: "create"
|
|
28505
|
+
},
|
|
28294
28506
|
"dataStoreProvider.isEmpty": {
|
|
28295
28507
|
capName: "data-store-provider",
|
|
28296
28508
|
capScope: "system",
|
|
@@ -29605,6 +29817,12 @@ Object.freeze({
|
|
|
29605
29817
|
addonId: null,
|
|
29606
29818
|
access: "create"
|
|
29607
29819
|
},
|
|
29820
|
+
"loadContribution.list": {
|
|
29821
|
+
capName: "load-contribution",
|
|
29822
|
+
capScope: "system",
|
|
29823
|
+
addonId: null,
|
|
29824
|
+
access: "view"
|
|
29825
|
+
},
|
|
29608
29826
|
"localNetwork.downloadCa": {
|
|
29609
29827
|
capName: "local-network",
|
|
29610
29828
|
capScope: "system",
|
|
@@ -29905,17 +30123,17 @@ Object.freeze({
|
|
|
29905
30123
|
addonId: null,
|
|
29906
30124
|
access: "view"
|
|
29907
30125
|
},
|
|
29908
|
-
"metricsProvider.
|
|
30126
|
+
"metricsProvider.getLoadSeries": {
|
|
29909
30127
|
capName: "metrics-provider",
|
|
29910
30128
|
capScope: "system",
|
|
29911
30129
|
addonId: null,
|
|
29912
30130
|
access: "view"
|
|
29913
30131
|
},
|
|
29914
|
-
"metricsProvider.
|
|
30132
|
+
"metricsProvider.getProcessStats": {
|
|
29915
30133
|
capName: "metrics-provider",
|
|
29916
30134
|
capScope: "system",
|
|
29917
30135
|
addonId: null,
|
|
29918
|
-
access: "
|
|
30136
|
+
access: "view"
|
|
29919
30137
|
},
|
|
29920
30138
|
"metricsProvider.listAddonInstances": {
|
|
29921
30139
|
capName: "metrics-provider",
|
|
@@ -31927,6 +32145,12 @@ Object.freeze({
|
|
|
31927
32145
|
addonId: null,
|
|
31928
32146
|
access: "create"
|
|
31929
32147
|
},
|
|
32148
|
+
"settingsStore.insertMany": {
|
|
32149
|
+
capName: "settings-store",
|
|
32150
|
+
capScope: "system",
|
|
32151
|
+
addonId: null,
|
|
32152
|
+
access: "create"
|
|
32153
|
+
},
|
|
31930
32154
|
"settingsStore.isEmpty": {
|
|
31931
32155
|
capName: "settings-store",
|
|
31932
32156
|
capScope: "system",
|
|
@@ -32539,6 +32763,12 @@ Object.freeze({
|
|
|
32539
32763
|
addonId: null,
|
|
32540
32764
|
access: "create"
|
|
32541
32765
|
},
|
|
32766
|
+
"system.getLoadContributions": {
|
|
32767
|
+
capName: "system",
|
|
32768
|
+
capScope: "system",
|
|
32769
|
+
addonId: null,
|
|
32770
|
+
access: "view"
|
|
32771
|
+
},
|
|
32542
32772
|
"system.getLoggingSettings": {
|
|
32543
32773
|
capName: "system",
|
|
32544
32774
|
capScope: "system",
|
|
@@ -35438,7 +35668,7 @@ var AdminUIAddon = class extends BaseAddon {
|
|
|
35438
35668
|
capability: adminUiCapability,
|
|
35439
35669
|
provider: {
|
|
35440
35670
|
getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
|
|
35441
|
-
getVersion: async () => ({ version: "1.2.
|
|
35671
|
+
getVersion: async () => ({ version: "1.2.108" })
|
|
35442
35672
|
}
|
|
35443
35673
|
}];
|
|
35444
35674
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as e,K as t,Q as n,R as r,S as i,W as a,b as o,o as s,q as c,x as l,z as u}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DhP-Lgiq.js";import{Z as d}from"./player-overlays-C1Oe-16j.js";import{An as f,Bn as p,C as m,Cn as ee,Dn as h,En as g,Fn as _,In as v,Ln as y,Ls as b,Mn as x,Pn as S,Qi as C,Sn as w,Tn as T,Vn as te,Y as ne,bn as re,g as E,ia as ie,jn as D,kn as O,q as ae,un as oe,wn as se,xn as ce,zn as le}from"./src-DjZVUvrt.js";import{Rt as k}from"./src-DLoxi-uA.js";import{t as A}from"./clock-44ycL5OK.js";import{t as j}from"./download-CPPi4lEs.js";import{t as ue}from"./plus-BpSOCY8P.js";import{t as M}from"./refresh-cw-BEHJsw3X.js";import{t as N}from"./upload-Bh__Gcoi.js";import{B as P,F as de,Y as F,Z as fe,h as pe,i as I,m as L,p as R,q as z,s as B,v as me,w as V,z as H}from"./index-DmGVQVip.js";import{t as U}from"./AdminPage-CCD07UMs.js";import{t as he}from"./NodeAddonsSettingsPanel-DCrm5WAe.js";var ge=z(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),W=z(`octagon-alert`,[[`path`,{d:`M12 16h.01`,key:`1drbdi`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z`,key:`1fd625`}]]),_e=z(`package`,[[`path`,{d:`M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z`,key:`1a0edw`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}],[`polyline`,{points:`3.29 7 12 12 20.71 7`,key:`ousv84`}],[`path`,{d:`m7.5 4.27 9 5.15`,key:`1c824w`}]]),G=z(`skip-forward`,[[`polygon`,{points:`5 4 15 12 5 20 5 4`,key:`16p6eg`}],[`line`,{x1:`19`,x2:`19`,y1:`5`,y2:`19`,key:`futhcm`}]]);n();var K=new Set([`completed`,`failed`,`partially-failed`,`cancelled`]),q=new Set([`done`,`failed`,`skipped`]);function ve(e){return!q.has(e.phase)&&!K.has(e.jobState)}function J(e,t){let n=new Map,r=[...e].sort((e,t)=>e.createdAtMs-t.createdAtMs);for(let e of r){let r=K.has(e.state);for(let i of e.tasks)r&&i.finishedAtMs!==null&&t-i.finishedAtMs>6e4||n.set(i.packageName,{jobId:e.jobId,packageName:i.packageName,phase:i.phase,fromVersion:i.fromVersion,toVersion:i.toVersion,error:i.error,jobState:e.state,finishedAtMs:i.finishedAtMs})}return n}function ye(){let{data:e}=O({activeOnly:!0},{refetchOnWindowFocus:!1,refetchInterval:e=>(e.state.data?.length??0)>0?3e3:!1}),{map:t}=b(k.AddonsJobProgress,e=>e.job.jobId);return a(()=>{let n=new Map;for(let t of e??[])n.set(t.jobId,t);for(let[e,r]of t)n.set(e,r.job);return J([...n.values()],Date.now())},[e,t])}var be={queued:{icon:A,cls:`bg-muted text-foreground-subtle`,label:`queued`},fetching:{icon:V,cls:`bg-primary/10 text-primary`,label:`fetching`,spin:!0},staged:{icon:V,cls:`bg-primary/10 text-primary`,label:`staged`,spin:!0},validating:{icon:V,cls:`bg-primary/10 text-primary`,label:`validating`,spin:!0},applying:{icon:V,cls:`bg-primary/10 text-primary`,label:`applying`,spin:!0},restarting:{icon:V,cls:`bg-amber-500/10 text-amber-600 dark:text-amber-400`,label:`restarting`,spin:!0},applied:{icon:V,cls:`bg-primary/10 text-primary`,label:`finalizing`,spin:!0},done:{icon:P,cls:`bg-success/10 text-success`,label:`updated`},failed:{icon:W,cls:`bg-danger/10 text-danger`,label:`failed`},skipped:{icon:G,cls:`bg-muted text-foreground-subtle`,label:`skipped`}};function xe({progress:e}){let t=be[e.phase],n=t.icon,r=e.error??`${e.packageName}: ${e.fromVersion??`?`} → ${e.toVersion}`;return i(`span`,{"data-testid":`addon-job-progress`,className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded shrink-0 ${t.cls}`,title:r,children:[l(n,{className:`w-2.5 h-2.5 ${t.spin?`animate-spin`:``}`}),t.label,i(`span`,{className:`font-mono`,children:[`→ `,e.toVersion]})]})}function Se({packageName:e,currentVersion:t,installSource:n,onInstall:r,onClose:a,onSelect:s,selectedVersion:c}){let u=n===`upload`||n===`local`,{data:d,isLoading:f}=T({name:e});return i(`div`,{className:`fixed z-50 w-72 rounded-lg border border-border bg-surface shadow-xl overflow-hidden`,style:{top:`auto`,bottom:`auto`},ref:e=>{if(!e)return;let t=e.parentElement?.getBoundingClientRect();if(!t)return;let n=window.innerHeight-t.bottom,r=t.top;n<280&&r>n?(e.style.bottom=`${window.innerHeight-t.top+4}px`,e.style.top=`auto`):(e.style.top=`${t.bottom+4}px`,e.style.bottom=`auto`),e.style.right=`${window.innerWidth-t.right}px`},onClick:e=>e.stopPropagation(),children:[i(`div`,{className:`flex items-center justify-between px-3 py-2 border-b border-border`,children:[l(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle font-medium`,children:`Versions`}),l(`button`,{type:`button`,onClick:a,className:`text-foreground-subtle hover:text-foreground`,children:l(I,{className:`h-3 w-3`})})]}),u&&i(`div`,{className:`flex items-start gap-2 px-3 py-2 border-b border-border bg-cyan-500/10 text-[10px]`,children:[l(N,{className:`h-3 w-3 mt-0.5 text-cyan-500 shrink-0`}),i(`div`,{className:`text-cyan-700 dark:text-cyan-200`,children:[i(`span`,{className:`font-semibold`,children:[n===`upload`?`Uploaded copy`:`Local copy`,` in place.`]}),` `,`Re-install `,l(`span`,{className:`font-mono`,children:t}),` from npm to track upstream releases again.`]})]}),f&&i(`div`,{className:`flex items-center justify-center gap-2 py-6 text-[10px] text-foreground-subtle`,children:[l(V,{className:`h-3.5 w-3.5 animate-spin`}),`Loading versions...`]}),d&&l(`div`,{className:`max-h-64 overflow-auto divide-y divide-border`,children:d.map(e=>{let n=e.version===t,a=s!==void 0&&e.version===c,d=/-(alpha|beta|rc|dev|canary|next)/i.test(e.version),f=i(o,{children:[l(`span`,{className:`font-mono flex-1 text-left ${n?`text-primary font-semibold`:d?`text-amber-400`:`text-foreground`}`,children:e.version}),n&&l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium bg-primary/10 text-primary`,children:`current`}),e.distTags.map(e=>l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e===`latest`?`bg-emerald-500/15 text-emerald-400`:e===`beta`?`bg-amber-500/15 text-amber-400`:`bg-gray-500/15 text-gray-400`}`,children:e},e)),e.deprecated&&l(`span`,{className:`text-[9px] text-red-400 line-through`,children:`deprecated`}),l(`span`,{className:`text-[9px] text-foreground-subtle shrink-0`,children:new Date(e.publishedAt).toLocaleDateString()})]});return s?i(`button`,{type:`button`,"aria-label":`Select ${e.version}`,onClick:()=>s(e.version),className:`w-full flex items-center gap-2 px-3 py-2 text-[11px] ${a?`bg-primary/5`:`hover:bg-surface-hover`} transition-colors`,children:[f,a?l(P,{className:`h-3 w-3 text-primary shrink-0`}):l(`span`,{className:`w-3 shrink-0`})]},e.version):i(`div`,{className:`flex items-center gap-2 px-3 py-2 text-[11px] ${n?`bg-primary/5`:`hover:bg-surface-hover`} transition-colors`,children:[f,n&&!u?l(P,{className:`h-3 w-3 text-primary shrink-0`}):l(`button`,{type:`button`,onClick:()=>r(e.version),className:`shrink-0 rounded p-0.5 hover:bg-primary/20 text-foreground-subtle hover:text-primary transition-colors`,title:n?`Re-install ${e.version} from npm`:`Install ${e.version}`,children:l(j,{className:`h-3 w-3`})})]},e.version)})}),d&&d.length===0&&l(`div`,{className:`py-4 text-center text-[10px] text-foreground-subtle`,children:`No versions found`})]})}var Y={queued:{icon:A,bg:`bg-muted text-foreground-subtle`,label:`queued`},updating:{icon:V,bg:`bg-primary/10 text-primary`,label:`updating`,spin:!0},"done-pending-restart":{icon:M,bg:`bg-amber-500/10 text-amber-700`,label:`pending restart`},done:{icon:P,bg:`bg-success/10 text-success`,label:`done`},failed:{icon:W,bg:`bg-danger/10 text-danger`,label:`failed`}};function Ce({item:e}){let t=Y[e.status],n=t.icon;return i(`span`,{className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded ${t.bg}`,title:e.error,children:[l(n,{className:`w-2.5 h-2.5 ${t.spin?`animate-spin`:``}`}),t.label]})}n();var X=`device-export`;function Z(e){return e.capabilities.some(e=>(typeof e==`string`?e:e.name)===X)}function we({isBundle:e,installSource:t,addonId:n,iconPath:r,color:a}){let[o,s]=c(!1),u=a?{backgroundColor:`${a.startsWith(`#`)?a:`#${a}`}26`}:void 0,d=e?`bg-indigo-500/20 text-indigo-700 dark:text-indigo-300`:`bg-purple-500/20 text-purple-700 dark:text-purple-300`,f=n&&r?`/api/addon-assets/${n}/${r}`:null,p=!!f&&!o;return i(`div`,{className:`relative flex-shrink-0`,children:[l(`div`,{className:`h-9 w-9 rounded-lg flex items-center justify-center ${u?``:d}`,style:u,children:p?l(`img`,{src:f,alt:n,className:`h-5 w-5`,onError:()=>s(!0)}):l(e?_e:me,{className:`h-4 w-4`})}),t===`local`&&l(`span`,{className:`absolute -top-1.5 -left-1.5 text-[7px] font-bold leading-none bg-orange-500 text-white px-1 py-0.5 rounded -rotate-12 shadow-sm`,children:`DEV`}),t===`npm`&&l(`span`,{className:`absolute -top-1 -left-1 w-4 h-4 rounded bg-[#cb3837] flex items-center justify-center -rotate-12 shadow-sm`,children:l(`svg`,{viewBox:`0 0 780 250`,className:`w-[11px] h-[11px]`,children:l(`path`,{fill:`#fff`,d:`M240 250h100V50h100v200h340V0H0v250z`})})}),t===`upload`&&l(`span`,{className:`absolute -top-1.5 -left-1.5 flex items-center justify-center h-4 w-4 rounded bg-cyan-500 -rotate-12 shadow-sm`,children:l(N,{className:`h-2.5 w-2.5 text-white`})})]})}function Te({version:e,availableUpdate:t,selectedVersion:n,isUpdating:r,installSource:a,disabled:o,onUpdate:s,onOpenPicker:c,children:u}){if(r)return i(`span`,{className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-blue-500/30 bg-blue-500/10 text-blue-400 shrink-0`,children:[l(V,{className:`h-3 w-3 animate-spin`}),`Updating…`]});if(t){let r=n??t;return i(`div`,{className:`relative inline-flex items-center gap-1 shrink-0`,children:[s&&i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),s()},disabled:o,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-semibold border border-blue-500/30 bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,title:`Update to ${r}`,children:[l(j,{className:`h-3 w-3`}),`Update`]}),i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),c()},disabled:o,"aria-label":`Select version to install`,title:`Installed ${e} — update available. Selected ${r}; tap to choose another version.`,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-bold font-mono border border-amber-500/40 bg-amber-500/15 text-amber-500 hover:bg-amber-500/25 animate-pulse disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:[l(`span`,{className:`font-normal opacity-70`,children:e}),l(`span`,{className:`font-normal opacity-70`,children:`→`}),r,l(H,{className:`h-3 w-3`})]}),u]})}return i(`div`,{className:`relative inline-flex items-center gap-1 shrink-0`,children:[i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),c()},disabled:o,className:[`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-bold font-mono border transition-colors disabled:opacity-50 disabled:cursor-not-allowed`,a===`local`?`border-orange-500/30 bg-orange-500/10 text-orange-400 hover:bg-orange-500/20`:`border-emerald-500/30 bg-emerald-500/10 text-emerald-400 hover:bg-emerald-500/20`].join(` `),title:`Version ${e} — tap to view all versions`,children:[e,l(H,{className:`h-3 w-3 opacity-50`})]}),u]})}function Ee({addonId:e}){let t=s(),{data:n=`inherit`}=w({addonId:e}),r=v({onSuccess:()=>{t.invalidateQueries({queryKey:[[`addons`,`getAddonAutoUpdate`]]})}});return l(`div`,{className:`flex rounded-lg border border-border overflow-hidden text-[10px] font-medium`,children:[`inherit`,`off`,`latest`,`beta`].map(t=>l(`button`,{type:`button`,onClick:n=>{n.stopPropagation(),r.mutate({addonId:e,channel:t})},disabled:r.isPending,className:`px-2.5 py-1 transition-colors capitalize ${n===t?t===`inherit`?`bg-gray-700/50 text-gray-700 dark:text-gray-300`:t===`off`?`bg-gray-700 text-gray-700 dark:text-gray-300`:t===`latest`?`bg-blue-500/20 text-blue-400`:`bg-amber-500/20 text-amber-400`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`} ${t===`inherit`?``:`border-l border-border`}`,children:t},t))})}function De({addon:e,agents:t=[],clusterStatus:n,hideVersion:r,availableUpdate:a,onUpdate:f,isUpdating:ee,jobProgress:h,bundle:_,bulkItem:v,disabledByBulk:y,isSystem:b}){let[C,w]=c(!1),[T,te]=c(!1),[re,E]=c(!1),[ie,D]=c(null);u(()=>{D(null)},[a]);let O=ie??a,[se,ce]=c(!1),[le,k]=c(!1),[A,j]=c(`logs`),N=s(),P=d(),de=F(),fe=oe(),{manifest:L}=e,z=e.installedOn??[],me=!_&&!L.protected&&L.removable!==!1,V=!!_,U=_?.displayName??L.name,G=_?.packageName??L.packageName,K=_?.version??L.packageVersion??L.version,q=_?.installSource??e.installSource,ve=_?_.bundle?.description??_.addons[0]?.manifest.description:L.description,J=p({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]}),N.invalidateQueries({queryKey:[[`addonPages`]]}),N.invalidateQueries({queryKey:[[`capabilities`]]})}}),ye=x({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]})}}),be=g({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]}),N.invalidateQueries({queryKey:[[`addonPages`]]}),N.invalidateQueries({queryKey:[[`capabilities`]]}),N.invalidateQueries({queryKey:[[`integrations`]]})}}),Y=S({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]}),N.invalidateQueries({queryKey:[[`alerts`]]})}}),X=e.health,Q=X?.phase===`failed`&&!X.inGracePeriod,Oe=Q&&X?.nextRetryAt&&!X.retrying;return i(`div`,{className:`rounded-lg border bg-surface overflow-hidden ${Q?`border-red-500/50`:`border-border`}`,children:[Q&&X&&i(`div`,{className:`bg-danger/10 border-b border-danger/30 px-4 py-2.5 flex items-start gap-2.5`,children:[l(W,{className:`h-4 w-4 text-danger shrink-0 mt-0.5`}),i(`div`,{className:`flex-1 min-w-0`,children:[i(`div`,{className:`text-xs font-semibold text-danger`,children:[`Failed to load (attempt #`,X.retryCount,`)`]}),l(`div`,{className:`text-[11px] text-foreground mt-0.5 break-words font-mono`,children:X.lastError?.message??`Unknown error`}),Oe&&X.nextRetryAt&&i(`div`,{className:`text-[10px] text-foreground-subtle mt-1`,children:[`Auto-retry at `,new Date(X.nextRetryAt).toLocaleTimeString()]})]}),i(`button`,{type:`button`,disabled:Y.isPending||X.retrying,onClick:e=>{e.stopPropagation(),Y.mutate({packageName:G})},className:`inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-semibold border border-red-400/40 bg-red-400/10 text-red-700 dark:text-red-300 hover:bg-red-400/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0`,title:`Reset retry counter and force immediate reload`,children:[l(M,{className:`h-3 w-3 ${Y.isPending||X.retrying?`animate-spin`:``}`}),`Retry now`]})]}),i(`div`,{className:`flex items-start gap-3 px-4 py-3`,children:[l(we,{isBundle:V||!!L.components&&L.components.length>1,installSource:q,addonId:V?_.addons[0]?.manifest.id:L.id,iconPath:V?_.bundle?.icon??_.addons[0]?.manifest.icon:L.icon,color:V?_.addons[0]?.manifest.color:L.color}),i(`div`,{className:`flex-1 min-w-0`,children:[i(`div`,{className:`flex items-start justify-between gap-2`,children:[l(`span`,{className:`text-sm font-semibold text-foreground truncate min-w-0`,children:U}),!r&&l(Te,{version:K,availableUpdate:a,...O===void 0?{}:{selectedVersion:O},isUpdating:ee,installSource:q,disabled:y,...f&&O!==void 0?{onUpdate:()=>f(O)}:{},onOpenPicker:()=>E(e=>!e),children:re&&l(Se,{packageName:G,currentVersion:K,...q?{installSource:q}:{},...a!==void 0&&O!==void 0?{selectedVersion:O,onSelect:e=>{D(e),E(!1)}}:{},onInstall:e=>{E(!1),be.mutate({packageName:G,version:e})},onClose:()=>E(!1)})})]}),i(`div`,{className:`flex flex-wrap items-center gap-x-1.5 gap-y-1 mt-0.5`,children:[G!==U&&l(`span`,{className:`text-[10px] text-foreground-subtle font-mono truncate max-w-full`,children:G}),V&&i(`span`,{className:`text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1`,children:[l(_e,{className:`h-3 w-3`}),_.addons.length]}),b&&i(`span`,{className:`text-[10px] rounded-full bg-amber-500/15 text-amber-700 dark:text-amber-300 px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1`,title:`System package — updating restarts the hub`,children:[l(M,{className:`h-3 w-3`}),`System`]}),v!=null&&l(Ce,{item:v}),h!=null&&l(xe,{progress:h})]}),ve&&l(`p`,{className:`text-[10px] text-foreground-subtle mt-1 line-clamp-1`,children:ve}),!V&&e.process&&i(`div`,{className:`flex flex-wrap items-center gap-1.5 mt-1`,children:[l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.mode===`forked`?`bg-blue-500/15 text-blue-400`:`bg-gray-500/15 text-gray-400`}`,children:e.process.mode===`forked`?`forked`:`in-process`}),e.process.pid!=null&&i(`span`,{className:`text-[9px] font-mono text-foreground-subtle`,children:[`PID `,e.process.pid]}),l(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.state===`running`?`bg-emerald-500/15 text-emerald-400`:e.process.state===`crashed`||e.process.state===`failed`?`bg-red-500/15 text-red-400`:`bg-gray-500/15 text-gray-400`}`,children:e.process.state})]})]})]}),!V&&i(`div`,{className:`flex items-center gap-1 px-4 py-1.5 border-t border-border/50 bg-surface-hover/20`,children:[i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),ye.mutate({addonId:L.id})},disabled:ye.isPending||y,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-blue-400 hover:border-blue-500/30 hover:bg-blue-500/10 disabled:opacity-50 transition-colors`,children:[l(M,{className:`h-3 w-3 ${ye.isPending?`animate-spin`:``}`}),`Restart`]}),i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),ce(e=>!e)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${se?`border-primary/30 bg-primary/10 text-primary`:`border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10`}`,children:[l(pe,{className:`h-3 w-3`}),`Logs`]}),!V&&i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),k(!0)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${le?`border-primary/30 bg-primary/10 text-primary`:`border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10`}`,children:[l(R,{className:`h-3 w-3`}),`Settings`]}),l(`div`,{className:`flex-1`}),me&&i(`button`,{type:`button`,onClick:async e=>{e.stopPropagation(),await fe({title:`Uninstall ${L.name}?`,message:`This will remove the addon package and all its data. This action cannot be undone.`,confirmLabel:`Uninstall`,variant:`danger`})&&J.mutate({packageName:L.packageName})},disabled:J.isPending||y,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-red-400 hover:border-red-500/30 hover:bg-red-500/10 disabled:opacity-50 transition-colors`,children:[l(B,{className:`h-3 w-3`}),J.isPending?`Removing...`:`Uninstall`]})]}),n&&n.nodes.length>1&&!V&&i(`div`,{className:`border-t border-border px-4 py-2 bg-muted/10`,children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle mb-1.5`,children:`Cluster Deployment`}),l(`div`,{className:`space-y-1`,children:n.nodes.map(e=>i(`div`,{className:`flex items-center gap-2 text-[10px]`,children:[l(`div`,{className:`h-1.5 w-1.5 rounded-full shrink-0 ${e.status===`offline`?`bg-muted-foreground/30`:e.synced?`bg-success`:`bg-amber-500`}`}),l(`span`,{className:`font-medium text-foreground min-w-[60px]`,children:e.name}),l(`span`,{className:`font-mono text-foreground-subtle`,children:e.version}),!e.synced&&e.status!==`offline`&&l(`span`,{className:`text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-400 border border-amber-500/20`,children:`outdated`}),e.status===`offline`&&l(`span`,{className:`text-[9px] px-1 py-0.5 rounded bg-muted text-muted-foreground`,children:`offline`}),e.synced&&e.status!==`offline`&&l(`span`,{className:`text-[9px] text-success`,children:`synced`})]},e.nodeId))})]}),se&&!V&&i(`div`,{className:`border-t border-border`,children:[i(`div`,{className:`flex items-center px-4 py-1 bg-surface-hover/20 border-b border-border/50`,children:[i(`div`,{className:`flex rounded border border-border overflow-hidden text-[9px]`,children:[l(`button`,{type:`button`,onClick:()=>j(`logs`),className:`px-2 py-0.5 transition-colors ${A===`logs`?`bg-primary/10 text-primary`:`text-foreground-subtle hover:bg-surface-hover`}`,children:`Logs`}),l(`button`,{type:`button`,onClick:()=>j(`events`),className:`px-2 py-0.5 border-l border-border transition-colors ${A===`events`?`bg-primary/10 text-primary`:`text-foreground-subtle hover:bg-surface-hover`}`,children:`Events`})]}),l(`div`,{className:`flex-1`}),l(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),ce(!1)},className:`text-foreground-subtle hover:text-foreground`,children:l(I,{className:`h-3.5 w-3.5`})})]}),A===`logs`&&l(ne,{addonId:L.id,maxHeight:`max-h-64`,showFilters:!1}),A===`events`&&l(ae,{addonId:L.id,category:`addon.*`,maxHeight:`max-h-64`})]}),V&&i(o,{children:[l(`button`,{type:`button`,onClick:()=>w(e=>!e),className:`w-full flex items-center justify-center border-t border-border py-1 hover:bg-surface-hover/50 transition-colors`,children:l(C?ge:H,{className:`h-3.5 w-3.5 text-foreground-subtle`})}),C&&l(`div`,{className:`border-t border-border px-3 py-2 space-y-2`,children:_.addons.map(e=>l(De,{addon:e,agents:t,hideVersion:!0},e.manifest.id))})]}),le&&!V&&l(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4`,onClick:()=>k(!1),children:i(`div`,{className:`w-full max-w-lg max-h-[80vh] rounded-xl border border-border bg-surface shadow-2xl flex flex-col overflow-hidden`,onClick:e=>e.stopPropagation(),children:[i(`div`,{className:`flex items-center justify-between px-5 py-3 border-b border-border flex-shrink-0`,children:[i(`div`,{className:`flex items-center gap-2`,children:[l(R,{className:`h-4 w-4 text-primary`}),i(`h2`,{className:`text-sm font-semibold text-foreground`,children:[U,` Settings`]})]}),l(`button`,{onClick:()=>k(!1),className:`text-foreground-subtle hover:text-foreground transition-colors p-1 rounded`,children:l(I,{className:`h-4 w-4`})})]}),i(`div`,{className:`flex-1 overflow-y-auto px-5 py-4 space-y-4`,children:[l(he,{nodeId:`hub`,addonIds:[L.id],level:`global`}),Z(L)&&i(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:`Device export`}),l(m,{addonId:L.id,trpc:P.trpcClient,onOpenDevice:e=>de(`/devices/${e}`)})]}),q===`npm`&&i(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:`Auto-Update`}),l(Ee,{addonId:L.id})]}),L.components&&L.components.length>0&&i(`div`,{children:[i(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:[`Components (`,L.components.length,`)`]}),l(`div`,{className:`flex flex-wrap gap-1`,children:L.components.map(e=>l(`span`,{className:`text-[10px] rounded bg-background border border-border px-1.5 py-0.5 text-foreground-subtle font-mono`,children:e},e))})]}),t.length>=2&&i(`div`,{children:[l(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:`Installed on`}),i(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[z.length===0&&l(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Hub (local)`}),z.map(e=>l(`span`,{className:`rounded-full bg-surface-hover border border-border px-2 py-0.5 text-[10px] text-foreground-subtle`,children:e},e)),i(`div`,{className:`relative`,children:[i(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),te(e=>!e)},className:`inline-flex items-center gap-1 rounded-full border border-dashed border-border px-2 py-0.5 text-[10px] text-foreground-subtle hover:text-foreground hover:border-primary transition-colors`,title:`Install on more agents`,children:[l(ue,{className:`h-3 w-3`}),`Add agent`]}),T&&i(`div`,{className:`absolute left-0 top-full mt-1 z-10 min-w-[160px] rounded-md border border-border bg-surface shadow-lg overflow-hidden`,children:[t.filter(e=>!e.isHub&&!z.includes(e.name)).map(e=>l(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),te(!1)},className:`w-full text-left px-3 py-1.5 text-[10px] text-foreground hover:bg-surface-hover transition-colors`,children:e.name},e.id)),t.filter(e=>!e.isHub&&!z.includes(e.name)).length===0&&l(`div`,{className:`px-3 py-1.5 text-[10px] text-foreground-subtle`,children:`No available agents`})]})]})]})]})]}),l(`div`,{className:`flex items-center justify-end px-5 py-3 border-t border-border flex-shrink-0`,children:l(`button`,{type:`button`,onClick:()=>k(!1),className:`rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors`,children:`Close`})})]})})]})}n();var Q=`.tgz,.tar.gz,.zip`;function Oe({onUploadSuccess:n}){let[r,a]=c(!1),s=t(null),u=e(async e=>{a(!0);let t=new FormData;t.append(`file`,e);let r=localStorage.getItem(`camstack_admin_token`)??``;try{(await(await fetch(`/api/addons/upload`,{method:`POST`,headers:{Authorization:`Bearer ${r}`},body:t})).json()).success&&n()}finally{a(!1)}},[n]);return i(o,{children:[l(`input`,{ref:s,type:`file`,accept:Q,onChange:e(e=>{let t=e.target.files?.[0];t&&u(t),e.target.value=``},[u]),className:`hidden`}),i(`button`,{type:`button`,onClick:()=>s.current?.click(),disabled:r,className:`flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,children:[r?l(V,{className:`w-3.5 h-3.5 animate-spin`}):l(N,{className:`w-3.5 h-3.5`}),r?`Uploading...`:`Upload`]})]})}n();var ke=[{seconds:900,label:`15m`},{seconds:3600,label:`1h`},{seconds:21600,label:`6h`},{seconds:43200,label:`12h`},{seconds:86400,label:`24h`}],Ae=new Set([`@camstack/system`,`@camstack/types`,`@camstack/sdk`,`@camstack/shm-ring`,`@camstack/ui-library`]);function je(e){return e!==void 0&&Ae.has(e)}function Me(e,t){let n=e??`hub-only`;return n===`any-node`?!0:n===`hub-only`?t:!t}function Ne(e){let t=e;if(!t?.manifest)return null;let n={...t.manifest,name:t.manifest.name??t.manifest.id,version:t.manifest.version??`0.0.0`,capabilities:t.manifest.capabilities??[]},r=t.process,i=r?{pid:r.pid,mode:r.mode===`forked`?`forked`:`in-process`,state:r.state??`unknown`}:void 0,a=t.health,o=t.declaration?.execution,s=t.manifest.execution,c=o?.placement??s?.placement;return{manifest:n,enabled:!0,source:t.source,installSource:t.installSource,installedOn:[],...i?{process:i}:{},hasBackup:t.hasBackup,...a?{health:a}:{},...c?{placement:c}:{}}}function Pe(e){let t=new Map,n=[];for(let r of e){let e=r.manifest.packageName;if(!e){n.push(r);continue}let i=t.get(e);if(i)i.addons.push(r);else{let n=r.manifest.bundle,i={packageName:e,displayName:n?.displayName??r.manifest.packageDisplayName??r.manifest.name,version:r.manifest.packageVersion,addons:[r],...r.installSource===void 0?{}:{installSource:r.installSource},...n===void 0?{}:{bundle:n}};t.set(e,i)}}let r=[];for(let e of t.values())e.bundle!==void 0||e.addons.length>=2?r.push({bundle:e,representative:e.addons[0]}):r.push(e.addons[0]);return r.push(...n),r}function $(e){return`bundle`in e}function Fe({addons:n,clusterStatus:o,selectedNode:d,onRefresh:p,isRefreshing:m}){let h=s(),[v,b]=c(``),x=r(v),[S,C]=c(!1),w=t(null);u(()=>{if(!S)return;let e=e=>{w.current&&!w.current.contains(e.target)&&C(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[S]);let{data:T}=f({nodeId:d.id}),ne=a(()=>{let e=new Map;for(let t of T??[])e.set(t.name,t.latestVersion);return e},[T]),E=a(()=>(T??[]).filter(e=>!e.isSystem).length,[T]),[ie,D]=c(()=>new Set),[O,ae]=c(()=>new Map),ce=e(e=>{D(t=>new Set(t).add(e))},[]),k=e(e=>{D(t=>{if(!t.has(e))return t;let n=new Set(t);return n.delete(e),n})},[]),A=e((e,t)=>{ae(n=>new Map(n).set(e,t))},[]),ue=e(e=>{ae(t=>{if(!t.has(e))return t;let n=new Map(t);return n.delete(e),n})},[]),N=te({onMutate:e=>{ce(e.name),ue(e.name)},onSuccess:(e,t)=>{k(t.name);let n=e;if(n&&n.success===!1){A(t.name,n.error??`Update failed (no error message returned by server)`);return}h.invalidateQueries({queryKey:[[`addons`]]}),h.invalidateQueries({queryKey:[[`addons`,`listUpdates`]]})},onError:(e,t)=>{k(t.name),A(t.name,e instanceof Error?e.message:String(e))}}),F=ye(),pe=t(new Set);u(()=>{let e=new Set;for(let[t,n]of F)ve(n)&&e.add(t);let t=[...pe.current].some(t=>!e.has(t));pe.current=e,t&&(h.invalidateQueries({queryKey:[[`addons`]]}),h.invalidateQueries({queryKey:[[`addons`,`listUpdates`]]}))},[F,h]);let{data:I}=ee(void 0),R=re({onSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`,`getAutoUpdateSettings`]]})}}),z=y({onSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`,`getAutoUpdateSettings`]]})}}),{data:B,isFetching:me}=_({query:x||void 0},{enabled:S}),H=le(),{data:U}=se(void 0),he=U?.requestedAt,[ge,W]=c(null),[_e,G]=c(!1);u(()=>{if(U?.kind===`framework-bulk-update`&&U.requestedAt!==ge){W(U.requestedAt),G(!0);let e=window.setTimeout(()=>G(!1),6e3);return()=>window.clearTimeout(e)}},[he,ge,U]),oe();let K=e(async()=>{let e=(T??[]).filter(e=>!e.isSystem);if(e.length!==0){if(!d.isHub){for(let t of e)await N.mutateAsync({name:t.name,version:t.latestVersion,nodeId:d.id});return}await H.mutateAsync({kind:`update`,targets:e.map(e=>({name:e.name,version:e.latestVersion})),nodeIds:[d.id]})}},[T,d.id,d.isHub,H,N]),q=g({onSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`]]}),h.invalidateQueries({queryKey:[[`addonPages`]]}),h.invalidateQueries({queryKey:[[`capabilities`]]}),h.invalidateQueries({queryKey:[[`integrations`]]})}}),[J,be]=c(`type`),[xe,Se]=c(()=>typeof window>`u`?`grouped`:window.localStorage.getItem(`camstack.addons.viewMode`)===`flat`?`flat`:`grouped`),Y=e=>{Se(e),typeof window<`u`&&window.localStorage.setItem(`camstack.addons.viewMode`,e)},[Ce,X]=fe(),Z=Ce.get(`capability`),we=a(()=>{let e=n.filter(e=>!je(e.manifest.packageName));return d.isHub||(e=e.filter(e=>Me(e.placement,d.isHub))),Z&&(e=e.filter(e=>(e.manifest.capabilities??[]).some(e=>(typeof e==`string`?e:e.name)===Z))),e},[n,d.isHub,Z]),Te=()=>{let e=new URLSearchParams(Ce);e.delete(`capability`),X(e,{replace:!0})},Ee=xe===`flat`?we:Pe(we),Q=a(()=>{let e=[...Ee];switch(J){case`type`:e.sort((e,t)=>{let n=+!$(e),r=+!$(t);if(n!==r)return n-r;let i=$(e)?e.bundle.displayName:e.manifest.name,a=$(t)?t.bundle.displayName:t.manifest.name;return i.localeCompare(a)});break;case`name`:e.sort((e,t)=>{let n=$(e)?e.bundle.displayName:e.manifest.name,r=$(t)?t.bundle.displayName:t.manifest.name;return n.localeCompare(r)});break;case`source`:e.sort((e,t)=>{let n=$(e)?e.bundle.installSource??``:e.installSource??``,r=$(t)?t.bundle.installSource??``:t.installSource??``;return n.localeCompare(r)});break}return e},[Ee,J]);return i(`div`,{className:`space-y-4`,children:[[...O.entries()].map(([e,t])=>l(`div`,{className:`rounded-md border border-danger/30 bg-danger/5 px-3 py-2 text-[11px]`,children:i(`div`,{className:`flex items-start justify-between gap-3`,children:[i(`div`,{className:`space-y-0.5`,children:[i(`div`,{className:`font-medium text-danger`,children:[`Failed to update `,e]}),l(`div`,{className:`text-foreground-subtle font-mono`,children:t})]}),l(`button`,{type:`button`,onClick:()=>ue(e),className:`text-foreground-subtle hover:text-foreground text-[10px]`,children:`dismiss`})]})},e)),i(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[i(`div`,{className:`flex items-center gap-1.5`,children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Sort:`}),i(`select`,{value:J,onChange:e=>be(e.target.value),className:`rounded-md border border-border bg-surface px-2 py-1.5 text-[11px] text-foreground focus:outline-none focus:border-primary/50`,children:[l(`option`,{value:`type`,children:`Bundles first`}),l(`option`,{value:`name`,children:`Name`}),l(`option`,{value:`source`,children:`Install source`})]})]}),i(`div`,{className:`flex items-center gap-1.5`,children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:`View:`}),l(`div`,{className:`flex rounded-md border border-border overflow-hidden text-[10px] font-medium`,children:[`grouped`,`flat`].map(e=>l(`button`,{type:`button`,onClick:()=>Y(e),className:`px-2.5 py-1.5 transition-colors capitalize ${xe===e?`bg-primary/10 text-primary`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`}`,title:e===`grouped`?`Group multi-addon packages into a bundle card`:`Show every addon as its own card`,children:e},e))})]}),d.isHub&&i(`div`,{className:`flex items-center gap-1.5`,children:[l(M,{className:`h-3 w-3 text-foreground-subtle`}),l(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Auto-Update:`}),l(`div`,{className:`flex rounded-md border border-border overflow-hidden text-[10px] font-medium`,children:[`off`,`latest`,`beta`].map(e=>l(`button`,{type:`button`,onClick:()=>R.mutate({channel:e}),disabled:R.isPending,className:`px-2.5 py-1.5 transition-colors capitalize ${I?.channel===e?e===`off`?`bg-gray-700 text-gray-200`:e===`latest`?`bg-blue-500/20 text-blue-400`:`bg-amber-500/20 text-amber-400`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`} ${e===`off`?``:`border-l border-border`}`,children:e},e))})]}),d.isHub&&i(`div`,{className:`flex items-center gap-1.5`,children:[l(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Check every:`}),l(`select`,{className:`rounded-md border border-border bg-transparent px-1.5 py-1 text-[10px] font-medium text-foreground-subtle`,value:I?.updateCheckIntervalSeconds??21600,disabled:z.isPending||I===void 0,onChange:e=>{I!==void 0&&z.mutate({channel:I.channel,updateCheckIntervalSeconds:Number(e.target.value)})},children:ke.map(e=>l(`option`,{value:e.seconds,children:e.label},e.seconds))})]}),E>0&&i(`button`,{type:`button`,onClick:()=>void K(),disabled:H.isPending,className:`flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 border border-blue-500/30 disabled:opacity-50 transition-colors font-medium`,children:[H.isPending?l(V,{className:`w-3 h-3 animate-spin`}):l(j,{className:`w-3 h-3`}),H.isPending?`Updating…`:`Update All (${E})`]}),i(`button`,{type:`button`,onClick:p,disabled:m||H.isPending,className:`flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,children:[l(M,{className:`w-3 h-3 ${m?`animate-spin`:``}`}),`Refresh`]})]}),i(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3`,children:[i(`div`,{className:`relative flex-1 min-w-0 sm:min-w-[200px]`,ref:w,children:[l(L,{className:`absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-foreground-subtle`}),l(`input`,{type:`text`,value:v,onChange:e=>{b(e.target.value),C(!0)},onFocus:()=>C(!0),placeholder:`Search addons on npm...`,disabled:H.isPending,className:`w-full rounded-lg border border-border bg-background pl-9 pr-3 py-2 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed`}),me&&l(V,{className:`absolute right-2.5 top-1/2 -translate-y-1/2 h-3 w-3 text-foreground-subtle animate-spin`}),S&&B&&B.length>0&&i(`div`,{className:`absolute left-0 right-0 top-full mt-1 z-40 rounded-lg border border-border bg-surface shadow-xl overflow-hidden`,children:[B.length>0&&i(`div`,{className:`px-3 py-1.5 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border`,children:[`npm results (`,B.length,`)`]}),B&&B.length>0&&l(`div`,{className:`max-h-72 overflow-auto divide-y divide-border`,children:B.map(e=>i(`div`,{className:`flex items-center gap-3 px-3 py-2 hover:bg-surface-hover transition-colors`,children:[l(`div`,{className:`w-6 h-6 rounded-md bg-primary/10 flex items-center justify-center text-primary text-[9px] font-bold shrink-0`,children:e.name.replace(`@camstack/addon-`,``).charAt(0).toUpperCase()}),i(`div`,{className:`flex-1 min-w-0`,children:[i(`div`,{className:`flex items-baseline gap-2 min-w-0`,children:[l(`span`,{className:`text-[11px] font-semibold break-words`,children:e.name.replace(/^@camstack\/(addon-)?/,``)}),i(`span`,{className:`text-[10px] text-foreground-subtle shrink-0`,children:[`v`,e.version]})]}),l(`div`,{className:`font-mono text-[9px] text-foreground-subtle/80 truncate`,children:e.name}),e.description&&l(`div`,{className:`text-[10px] text-foreground-subtle truncate`,children:e.description})]}),e.installed?i(`span`,{className:`inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md border border-emerald-500/30 bg-emerald-500/10 text-emerald-400 shrink-0`,children:[l(P,{className:`h-3 w-3`}),e.installedVersion??`Installed`]}):i(`button`,{type:`button`,onClick:()=>q.mutate({packageName:e.name}),disabled:q.isPending,className:`inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors shrink-0`,children:[q.isPending?l(V,{className:`h-3 w-3 animate-spin`}):l(j,{className:`h-3 w-3`}),`Install`]})]},e.name))})]})]}),l(Oe,{onUploadSuccess:()=>{h.invalidateQueries({queryKey:[[`addons`]]}),p()}})]}),Z&&i(`div`,{className:`flex items-center gap-2 px-3 py-2 rounded-lg bg-primary/10 border border-primary/30 text-sm`,children:[l(`span`,{className:`text-foreground-subtle`,children:`Filtering by capability:`}),l(`span`,{className:`font-mono text-primary font-semibold`,children:Z}),l(`button`,{type:`button`,onClick:Te,className:`ml-auto text-xs text-foreground-subtle hover:text-foreground underline`,children:`Clear`})]}),_e&&i(`div`,{className:`fixed top-[calc(env(safe-area-inset-top)+1rem)] right-[calc(env(safe-area-inset-right)+1rem)] z-50 flex items-start gap-2 px-3 py-2.5 rounded-md border border-green-500/30 bg-green-500/10 shadow-lg backdrop-blur-sm max-w-sm pointer-events-auto`,children:[l(de,{className:`w-4 h-4 shrink-0 mt-0.5 text-green-400`}),i(`div`,{children:[l(`div`,{className:`text-[11px] font-semibold text-foreground`,children:`Bulk update completed`}),l(`div`,{className:`text-[10px] text-foreground-subtle mt-0.5`,children:`System packages updated — hub restarted successfully.`})]})]}),we.length===0&&l(`div`,{className:`text-xs text-foreground-subtle`,children:n.length===0?`No addons installed`:Z?`No installed addons declare the "${Z}" capability. Browse the npm catalog above to find a compatible addon.`:`No addons compatible with ${d.name} (placement filter active)`}),l(`div`,{className:`space-y-2`,children:Q.map(e=>{let t=$(e)?e.bundle.packageName:e.manifest.packageName,n=ne.get(t),r=$(e)?e.representative:e,i=n?e=>N.mutate({name:t,version:e,nodeId:d.id}):void 0,a=F.get(t)??null,s=a!==null&&ve(a);return l(De,{addon:r,clusterStatus:o?.[r.manifest.id],bundle:$(e)?e.bundle:void 0,availableUpdate:n,isUpdating:ie.has(t)||s,jobProgress:a,onUpdate:i,disabledByBulk:H.isPending},$(e)?t:e.manifest.id)})})]})}function Ie(){let e=s(),{data:n,isLoading:r,isError:o}=h(),{data:d}=C(void 0),{data:f}=ie(void 0,{refetchInterval:1e4}),p=a(()=>{let e=new Map;e.set(`hub`,{id:`hub`,name:`Hub`,isHub:!0});for(let t of f??[]){let n=String(t.id??``);n&&e.set(n,{id:n,name:String(t.name??n),isHub:!!t.isHub})}return[...e.values()]},[f]),[m,ee]=c(`hub`),g=p.find(e=>e.id===m)??p[0],_=ce(),v=D(),y=_.isPending||v.isPending,b=async()=>{await _.mutateAsync({nodeId:m}),await v.mutateAsync(),e.invalidateQueries({queryKey:[[`addons`]]})},x=t(_);x.current=_,u(()=>{x.current.mutate({nodeId:`hub`})},[]);let S=(n??[]).map(Ne).filter(e=>e!==null);return i(U,{children:[i(`div`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[l(E,{selectedNodeId:m,onSelect:ee}),i(`div`,{className:`flex items-center gap-3 flex-wrap`,children:[!r&&!o&&i(`span`,{className:`text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium`,children:[S.length,` installed`]}),i(`button`,{type:`button`,onClick:()=>void b(),disabled:y,className:`inline-flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,title:`Re-fetch addons + check npm for new versions`,children:[l(M,{className:`w-3 h-3 ${y?`animate-spin`:``}`}),`Check for updates`]})]})]}),!g.isHub&&i(`div`,{className:`rounded-md border border-warning/30 bg-warning/5 px-3 py-2 text-[11px] text-foreground-subtle`,children:[`Showing only addons compatible with`,` `,l(`span`,{className:`font-medium text-foreground`,children:g.name}),` — agents only run`,` `,l(`code`,{className:`font-mono`,children:`agent-only`}),` and`,` `,l(`code`,{className:`font-mono`,children:`any-node`}),` addons. Install / uninstall is hub-driven; agents auto-sync from the hub.`]}),r&&l(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:`Loading…`}),o&&l(`div`,{className:`text-xs text-danger`,children:`Failed to load addons`}),!r&&!o&&l(Fe,{addons:S,clusterStatus:d,selectedNode:g,onRefresh:()=>void b(),isRefreshing:y})]})}export{Ie as AddonsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as e,S as t,W as n,a as r,q as i,t as a,x as o}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DhP-Lgiq.js";import{Z as s}from"./player-overlays-C1Oe-16j.js";import{Xt as c}from"./src-DjZVUvrt.js";import{t as l}from"./circle-check-big-C_6LzyMr.js";import{I as u,d,w as f}from"./index-DmGVQVip.js";import{t as p}from"./AdminPage-CCD07UMs.js";e();var m={detection:`border-green-500`,detector:`border-green-500`,streaming:`border-blue-500`,decode:`border-blue-500`,decoder:`border-blue-500`,recording:`border-orange-500`,recorder:`border-orange-500`,transcoding:`border-purple-500`,transcoder:`border-purple-500`,restream:`border-cyan-500`,restreamer:`border-cyan-500`,storage:`border-yellow-500`,notification:`border-pink-500`,notifier:`border-pink-500`,faces:`border-indigo-500`},h={detection:`bg-green-500/5`,detector:`bg-green-500/5`,streaming:`bg-blue-500/5`,decode:`bg-blue-500/5`,decoder:`bg-blue-500/5`,recording:`bg-orange-500/5`,recorder:`bg-orange-500/5`,transcoding:`bg-purple-500/5`,transcoder:`bg-purple-500/5`,restream:`bg-cyan-500/5`,restreamer:`bg-cyan-500/5`,storage:`bg-yellow-500/5`,notification:`bg-pink-500/5`,notifier:`bg-pink-500/5`,faces:`bg-indigo-500/5`};function g({entry:e,actions:n}){let r=e.name.toLowerCase(),i=m[r]??`border-primary`,a=h[r]??`bg-primary/5`,s=e.providers.find(e=>e.active),c=n?.pendingCapability===e.name;return t(`div`,{className:`rounded-lg border-t-2 border border-border ${i} ${a} p-3 space-y-2`,children:[t(`div`,{className:`flex items-center justify-between gap-2`,children:[t(`span`,{className:`text-xs font-semibold text-foreground capitalize flex items-center gap-1.5`,children:[e.name,c&&o(f,{className:`h-3 w-3 animate-spin text-primary`})]}),o(`span`,{className:`rounded-full px-2 py-0.5 text-[10px] font-medium ${e.mode===`singleton`?`bg-primary/10 text-primary`:`bg-info/10 text-info`}`,children:e.mode})]}),e.mode===`singleton`?o(_,{entry:e,actions:n,activeProvider:s,isPending:c}):o(v,{entry:e,actions:n,isPending:c})]})}function _({entry:e,actions:n,activeProvider:r,isPending:i}){if(!n)return o(`div`,{children:r?t(`div`,{className:`flex items-center gap-1.5 text-[10px] text-foreground`,children:[o(l,{className:`h-3 w-3 text-green-400 shrink-0`}),o(`span`,{className:`font-medium`,children:r.addonName}),o(`span`,{className:`rounded-full bg-green-500/10 text-green-400 px-1.5 py-0.5 font-medium ml-auto`,children:`ACTIVE`})]}):o(`div`,{className:`text-[10px] text-foreground-subtle italic`,children:`No active provider`})});if(e.providers.length===0)return o(`div`,{className:`text-[10px] text-foreground-subtle italic`,children:`No providers`});let a=`__inherit__`;return t(`div`,{className:`space-y-2`,children:[o(`div`,{className:`space-y-1`,children:e.providers.map(r=>{let a=r.active;return t(`button`,{type:`button`,disabled:i||a,onClick:()=>n.onSelectSingleton(e.name,r.addonId),className:`flex w-full items-center gap-1.5 rounded px-1.5 py-1 text-[10px] text-left transition-colors ${a?`bg-green-500/10 text-foreground cursor-default`:`text-foreground-subtle hover:bg-surface-hover hover:text-foreground disabled:opacity-50`}`,children:[o(`span`,{className:`h-2.5 w-2.5 rounded-full border shrink-0 ${a?`border-green-400 bg-green-400`:`border-border`}`}),o(`span`,{className:`font-medium truncate`,children:r.addonName}),a&&o(`span`,{className:`rounded-full bg-green-500/10 text-green-400 px-1.5 py-0.5 font-medium ml-auto shrink-0`,children:`ACTIVE`})]},r.addonId)})}),e.perNode&&e.perNode.length>0&&o(`div`,{className:`space-y-2 pt-1 border-t border-border/40`,children:e.perNode.map(r=>{let s=r.hasOverride&&r.resolvedActive?r.resolvedActive:a,c=[{value:a,label:`Inherit global${r.resolvedActive?` (${r.resolvedActive})`:``}`},...r.providers.map(e=>({value:e,label:e}))],l=t=>{t===a?n.onClearNodeSingleton(e.name,r.nodeId):n.onSelectNodeSingleton(e.name,r.nodeId,t)},u=i;return t(`div`,{className:`space-y-0.5`,children:[t(`div`,{className:`text-[9px] font-semibold uppercase tracking-widest text-foreground-subtle/60 px-1.5`,children:[r.nodeId,r.hasOverride&&o(`span`,{className:`ml-1.5 rounded-full bg-primary/10 text-primary px-1 py-0.5 normal-case tracking-normal font-medium`,children:`override`})]}),c.map(e=>{let n=s===e.value;return t(`button`,{type:`button`,disabled:u||n,onClick:()=>l(e.value),className:`flex w-full items-center gap-1.5 rounded px-1.5 py-1 text-[10px] text-left transition-colors ${n?`bg-green-500/10 text-foreground cursor-default`:`text-foreground-subtle hover:bg-surface-hover hover:text-foreground disabled:opacity-50`}`,children:[o(`span`,{className:`h-2.5 w-2.5 rounded-full border shrink-0 ${n?`border-green-400 bg-green-400`:`border-border`}`}),o(`span`,{className:`font-medium truncate`,children:e.label}),n&&e.value!==a&&o(`span`,{className:`rounded-full bg-green-500/10 text-green-400 px-1.5 py-0.5 font-medium ml-auto shrink-0`,children:`ACTIVE`})]},e.value)})]},r.nodeId)})})]})}function v({entry:e,actions:n,isPending:r}){if(e.providers.length===0)return o(`div`,{className:`text-[10px] text-foreground-subtle italic`,children:`No providers`});if(!n)return o(`div`,{className:`space-y-1`,children:e.providers.map(e=>t(`div`,{className:`flex items-center justify-between gap-2 text-[10px]`,children:[o(`span`,{className:`text-foreground-subtle`,children:e.addonName}),e.active&&o(`span`,{className:`rounded-full bg-green-500/10 text-green-400 px-1.5 py-0.5 font-medium`,children:`ACTIVE`})]},e.addonId))});let i=e.providers.filter(e=>e.active).map(e=>e.addonId),a=(t,r)=>{let a=r?[...new Set([...i,t])]:i.filter(e=>e!==t);n.onToggleCollection(e.name,a)};return o(`div`,{className:`space-y-1`,children:e.providers.map(e=>t(`label`,{className:`flex items-center justify-between gap-2 text-[10px] rounded px-1.5 py-1 transition-colors ${r?`opacity-50`:`hover:bg-surface-hover cursor-pointer`}`,children:[t(`span`,{className:`flex items-center gap-1.5 min-w-0`,children:[o(`input`,{type:`checkbox`,checked:e.active,disabled:r,onChange:t=>a(e.addonId,t.target.checked),className:`h-3 w-3 accent-green-500 shrink-0`}),o(`span`,{className:`text-foreground truncate`,children:e.addonName})]}),e.active&&o(`span`,{className:`rounded-full bg-green-500/10 text-green-400 px-1.5 py-0.5 font-medium shrink-0`,children:`ACTIVE`})]},e.addonId))})}function y({capabilities:e,actions:t}){return e.length===0?o(`div`,{className:`text-xs text-foreground-subtle text-center py-8`,children:`No capabilities registered`}):o(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3`,children:e.map(e=>o(g,{entry:e,actions:t},e.name))})}var b=[`capabilities`,`listCapabilities`];function x(e){return e===`singleton`||e===`collection`}function S(e){let t=e.indexOf(`@`);return t===-1?`${e} (hub)`:`${e.slice(0,t)} (${e.slice(t+1)})`}function C(e,t){return{name:e.name,mode:t,providers:e.providers.map(n=>({addonId:n,addonName:S(n),active:t===`singleton`?e.activeProvider===n:!e.disabledProviders.includes(n)})),...t===`singleton`&&e.perNode?{perNode:e.perNode}:{}}}function w(){let e=s(),[f,m]=i(null),[h,g]=i(null),_=r({queryKey:b,queryFn:()=>e.trpcClient.capabilities.listCapabilities.query()}),v=n(()=>{let e=(_.data??[]).flatMap(e=>x(e.mode)?[C(e,e.mode)]:[]),t=e.filter(e=>e.mode===`singleton`).toSorted((e,t)=>e.name.localeCompare(t.name)),n=e.filter(e=>e.mode===`collection`).toSorted((e,t)=>e.name.localeCompare(t.name));return[...t,...n]},[_.data]),S=n(()=>v.filter(e=>e.mode===`singleton`),[v]),w=n(()=>v.filter(e=>e.mode===`collection`),[v]),T=a({mutationFn:t=>e.trpcClient.capabilities.setActiveSingleton.mutate({capability:t.capName,addonId:t.addonId}),onMutate:e=>{m(e.capName),g(null)},onSuccess:async(e,t)=>{g({kind:`success`,message:`${t.capName} → ${t.addonId} is now active.`}),await _.refetch()},onError:(e,t)=>{g({kind:`error`,message:`Failed to set ${t.capName}: ${e instanceof Error?e.message:`unknown error`}`})},onSettled:()=>m(null)}),E=a({mutationFn:t=>e.trpcClient.capabilities.setActiveSingleton.mutate({capability:t.capName,addonId:t.addonId,nodeId:t.nodeId}),onMutate:e=>{m(e.capName),g(null)},onSuccess:async(e,t)=>{g({kind:`success`,message:`${t.capName} @ ${t.nodeId} → ${t.addonId}.`}),await _.refetch()},onError:(e,t)=>{g({kind:`error`,message:`Failed to set ${t.capName} @ ${t.nodeId}: ${e instanceof Error?e.message:`unknown error`}`})},onSettled:()=>m(null)}),D=a({mutationFn:t=>e.trpcClient.capabilities.clearSingletonNodeOverride.mutate({capability:t.capName,nodeId:t.nodeId}),onMutate:e=>{m(e.capName),g(null)},onSuccess:async(e,t)=>{g({kind:`success`,message:`${t.capName} @ ${t.nodeId} now inherits the global default.`}),await _.refetch()},onError:(e,t)=>{g({kind:`error`,message:`Failed to clear ${t.capName} @ ${t.nodeId}: ${e instanceof Error?e.message:`unknown error`}`})},onSettled:()=>m(null)}),O=a({mutationFn:t=>e.trpcClient.capabilities.setCollectionEnabledProviders.mutate({capability:t.capName,enabledAddonIds:[...t.enabledAddonIds]}),onMutate:e=>{m(e.capName),g(null)},onSuccess:async(e,t)=>{g({kind:`success`,message:`${t.capName}: ${t.enabledAddonIds.length} provider(s) enabled.`}),await _.refetch()},onError:(e,t)=>{g({kind:`error`,message:`Failed to update ${t.capName}: ${e instanceof Error?e.message:`unknown error`}`})},onSettled:()=>m(null)}),k={onSelectSingleton:(e,t)=>T.mutate({capName:e,addonId:t}),onSelectNodeSingleton:(e,t,n)=>E.mutate({capName:e,nodeId:t,addonId:n}),onClearNodeSingleton:(e,t)=>D.mutate({capName:e,nodeId:t}),onToggleCollection:(e,t)=>O.mutate({capName:e,enabledAddonIds:t}),pendingCapability:f};return t(p,{icon:d,title:`Capabilities`,subtitle:`Choose which provider is active for each system capability. Singleton caps pick exactly one provider; collection caps enable a set.`,children:[h&&t(`div`,{className:`flex items-center gap-2 rounded-md border px-3 py-2 text-xs ${h.kind===`success`?`border-green-500/30 bg-green-500/10 text-green-700 dark:text-green-300`:`border-danger/40 bg-danger/10 text-danger`}`,children:[h.kind===`success`?o(l,{className:`h-3.5 w-3.5 shrink-0`}):o(u,{className:`h-3.5 w-3.5 shrink-0`}),o(`span`,{children:h.message})]}),_.isLoading&&o(`div`,{className:`flex items-center justify-center py-16`,children:o(`div`,{className:`animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full`})}),_.isError&&!_.isLoading&&o(c,{title:`Failed to load capabilities`,message:_.error instanceof Error?_.error.message:`Unknown error`,onRetry:()=>void _.refetch()}),!_.isLoading&&!_.isError&&v.length===0&&o(`div`,{className:`text-xs text-foreground-subtle text-center py-16`,children:`No capabilities registered.`}),!_.isLoading&&!_.isError&&v.length>0&&t(`div`,{className:`space-y-6`,children:[S.length>0&&t(`section`,{className:`space-y-2`,children:[o(`h2`,{className:`text-[11px] font-semibold uppercase tracking-widest text-foreground-subtle/70`,children:`Singleton — pick one provider`}),o(y,{capabilities:S,actions:k})]}),w.length>0&&t(`section`,{className:`space-y-2`,children:[o(`h2`,{className:`text-[11px] font-semibold uppercase tracking-widest text-foreground-subtle/70`,children:`Collection — enable a set`}),o(y,{capabilities:w,actions:k})]})]})]})}export{w as CapabilitiesPage,w as default};
|