mirror of
https://github.com/hansjone/netxops.git
synced 2026-10-11 22:00:45 +08:00
Fix KB settings badge stuck on unconfigured after bind (0.1.38).
Reload Host kbRoot after browse/save so the status badge tracks the live package instead of a stale snapshot. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0f31a6648a
commit
1b4c402723
9 changed files with 261 additions and 50 deletions
|
|
@ -10,6 +10,7 @@ import type { AlarmPushRpcCall } from './alarm-push-status-view.ts'
|
|||
export const NETXOPS_RPC_CHANNEL = '/netxops'
|
||||
|
||||
export const KB_STATUS_ENDPOINT = 'kb.status'
|
||||
export const KB_RELOAD_ENDPOINT = 'kb.reload'
|
||||
export const KB_RESOLVE_ENDPOINT = 'kb.resolve'
|
||||
|
||||
export type { KbSnapshot, KbStatus }
|
||||
|
|
@ -50,6 +51,10 @@ export function asKbSnapshot(value: unknown): KbSnapshot {
|
|||
}
|
||||
}
|
||||
|
||||
function asRpcOk(result: unknown): result is { ok: true; value?: unknown } {
|
||||
return result !== null && typeof result === 'object' && (result as { ok?: boolean }).ok === true
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the published KB snapshot from the Host.
|
||||
*/
|
||||
|
|
@ -58,10 +63,37 @@ export async function fetchKbStatus(
|
|||
signal?: AbortSignal,
|
||||
): Promise<KbSnapshot> {
|
||||
const result = await call(NETXOPS_RPC_CHANNEL, KB_STATUS_ENDPOINT, {}, signal)
|
||||
if (result !== null && typeof result === 'object' && (result as { ok?: boolean }).ok === true) {
|
||||
return asKbSnapshot((result as { value?: unknown }).value)
|
||||
if (asRpcOk(result)) {
|
||||
return asKbSnapshot(result.value)
|
||||
}
|
||||
return unconfiguredKbSnapshot()
|
||||
// Do not pretend "unconfigured" on transport/shape miss — keep empty identity
|
||||
// but mark error so the badge is not stuck on the soft "pure netx" copy.
|
||||
if (result !== null && typeof result === 'object' && (result as { ok?: boolean }).ok === false) {
|
||||
const message = String(
|
||||
(result as { error?: { message?: string } }).error?.message ?? 'kb.status rpc failed',
|
||||
)
|
||||
return { ...unconfiguredKbSnapshot(), status: 'error', errorMessage: message }
|
||||
}
|
||||
return {
|
||||
...unconfiguredKbSnapshot(),
|
||||
status: 'error',
|
||||
errorMessage: 'kb.status unavailable',
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force Host to re-resolve `kbRoot` from live settings and republish.
|
||||
*/
|
||||
export async function reloadKbStatus(
|
||||
call: AlarmPushRpcCall,
|
||||
signal?: AbortSignal,
|
||||
): Promise<KbSnapshot> {
|
||||
const result = await call(NETXOPS_RPC_CHANNEL, KB_RELOAD_ENDPOINT, {}, signal)
|
||||
if (asRpcOk(result)) {
|
||||
return asKbSnapshot(result.value)
|
||||
}
|
||||
// Older hosts without kb.reload — fall back to status / resolve.
|
||||
return fetchKbStatus(call, signal)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,13 +106,17 @@ export async function resolveKbPath(
|
|||
): Promise<KbSnapshot> {
|
||||
// Prefer flat `{ path }` (netxops channel); also try `{ args: { path } }`.
|
||||
let result = await call(NETXOPS_RPC_CHANNEL, KB_RESOLVE_ENDPOINT, { path }, signal)
|
||||
if (!(result !== null && typeof result === 'object' && (result as { ok?: boolean }).ok === true)) {
|
||||
if (!asRpcOk(result)) {
|
||||
result = await call(NETXOPS_RPC_CHANNEL, KB_RESOLVE_ENDPOINT, { args: { path } }, signal)
|
||||
}
|
||||
if (result !== null && typeof result === 'object' && (result as { ok?: boolean }).ok === true) {
|
||||
return asKbSnapshot((result as { value?: unknown }).value)
|
||||
if (asRpcOk(result)) {
|
||||
return asKbSnapshot(result.value)
|
||||
}
|
||||
return {
|
||||
...unconfiguredKbSnapshot(),
|
||||
status: 'error',
|
||||
errorMessage: 'kb.resolve unavailable',
|
||||
}
|
||||
return unconfiguredKbSnapshot()
|
||||
}
|
||||
|
||||
/** Badge tone for the settings card. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue