Improve signer status

This commit is contained in:
Jon Staab
2026-01-06 15:30:54 -08:00
parent e5d1b82a9d
commit 7f8744725c
2 changed files with 37 additions and 37 deletions
+18 -15
View File
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import {spec, prop, avg} from "@welshman/lib" import {spec, avg} from "@welshman/lib"
import {session, SessionMethod, signerLog, SignerLogEntryStatus} from "@welshman/app" import {session, SessionMethod, signerLog} from "@welshman/app"
import CloseCircle from "@assets/icons/close-circle.svg?dataurl" import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
import Danger from "@assets/icons/danger-triangle.svg?dataurl" import Danger from "@assets/icons/danger-triangle.svg?dataurl"
import ClockCircle from "@assets/icons/clock-circle.svg?dataurl" import ClockCircle from "@assets/icons/clock-circle.svg?dataurl"
@@ -10,17 +10,18 @@
import LogOut from "@app/components/LogOut.svelte" import LogOut from "@app/components/LogOut.svelte"
import {pushModal} from "@app/util/modal" import {pushModal} from "@app/util/modal"
const {Pending, Success, Failure} = SignerLogEntryStatus const finished = $derived($signerLog.filter(x => x.finished_at))
const pending = $derived($signerLog.filter(spec({status: Pending})).length) const pending = $derived($signerLog.filter(x => !x.finished_at))
const success = $derived($signerLog.filter(spec({status: Success})).length) const failure = $derived(finished.filter(spec({ok: false})))
const failure = $derived($signerLog.filter(spec({status: Failure})).length) const success = $derived(finished.filter(spec({ok: true})))
const recent = $derived($signerLog.slice(-10)) const recent = $derived($signerLog.slice(-10))
const recentAvg = $derived(avg(recent.map(prop("duration")))) const recentFinished = $derived(recent.filter(x => x.finished_at))
const recentPending = $derived(recent.filter(spec({status: Pending})).length) const recentPending = $derived(recent.filter(x => !x.finished_at))
const recentSuccess = $derived(recent.filter(spec({status: Success})).length) const recentAvg = $derived(avg(recentFinished.map(x => x.finished_at! - x.started_at)))
const recentFailure = $derived(recent.filter(spec({status: Failure})).length) const recentFailure = $derived(recentFinished.filter(x => !x.ok))
const recentSuccess = $derived(recentFinished.filter(x => x.ok))
const isDisconnected = $derived( const isDisconnected = $derived(
recent.length > 0 && recentFailure + recentPending === recent.length, recent.length > 0 && recentFailure.length + recentPending.length === recent.length,
) )
const logout = () => pushModal(LogOut) const logout = () => pushModal(LogOut)
@@ -34,11 +35,13 @@
<span class="flex items-center gap-2"> <span class="flex items-center gap-2">
{#if isDisconnected} {#if isDisconnected}
<Icon icon={CloseCircle} class="text-error" size={4} /> Disconnected <Icon icon={CloseCircle} class="text-error" size={4} /> Disconnected
{:else if recentFailure > 3} {:else if recentFailure.length > 3}
<Icon icon={Danger} class="text-warning" size={4} /> Partial Failure <Icon icon={Danger} class="text-warning" size={4} /> Partial Failure
{:else if recentAvg > 1000 || recentPending > 3} {:else if recentAvg > 1000 || recentPending.length > 3}
<Icon icon={ClockCircle} class="text-warning" size={4} /> Slow connection <Icon icon={ClockCircle} class="text-warning" size={4} /> Slow connection
{:else if recentSuccess === 0 && recentFailure > 0}{:else} {:else if recentSuccess.length === 0 && recentFailure.length > 0}
<Icon icon={Danger} class="text-warning" size={4} /> Partial Failure
{:else}
<Icon icon={CheckCircle} class="text-success" size={4} /> Ok <Icon icon={CheckCircle} class="text-success" size={4} /> Ok
{/if} {/if}
</span> </span>
@@ -59,7 +62,7 @@
{/if} {/if}
</p> </p>
<p> <p>
{success} requests succeeded, {failure} failed, {pending} pending {success.length} requests succeeded, {failure.length} failed, {pending.length} pending
</p> </p>
</div> </div>
</div> </div>
+19 -22
View File
@@ -1,17 +1,16 @@
<script lang="ts"> <script lang="ts">
import "@src/app.css" import "@src/app.css"
import "@capacitor-community/safe-area" import "@capacitor-community/safe-area"
import {throttle} from "throttle-debounce"
import * as nip19 from "nostr-tools/nip19" import * as nip19 from "nostr-tools/nip19"
import type {Unsubscriber} from "svelte/store" import type {Unsubscriber} from "svelte/store"
import {get} from "svelte/store" import {get} from "svelte/store"
import {App, type URLOpenListenerEvent} from "@capacitor/app" import {App, type URLOpenListenerEvent} from "@capacitor/app"
import {dev} from "$app/environment" import {dev} from "$app/environment"
import {goto} from "$app/navigation" import {goto} from "$app/navigation"
import {sync} from "@welshman/store" import {sync, throttled} from "@welshman/store"
import {call, spec} from "@welshman/lib" import {call} from "@welshman/lib"
import {defaultSocketPolicies} from "@welshman/net" import {defaultSocketPolicies} from "@welshman/net"
import {pubkey, sessions, signerLog, shouldUnwrap, SignerLogEntryStatus} from "@welshman/app" import {pubkey, sessions, signerLog, shouldUnwrap} from "@welshman/app"
import * as lib from "@welshman/lib" import * as lib from "@welshman/lib"
import * as util from "@welshman/util" import * as util from "@welshman/util"
import * as feeds from "@welshman/feeds" import * as feeds from "@welshman/feeds"
@@ -141,25 +140,23 @@
// Listen for signer errors, report to user via toast // Listen for signer errors, report to user via toast
unsubscribers.push( unsubscribers.push(
signerLog.subscribe( throttled(10_000, signerLog).subscribe($log => {
throttle(10_000, $log => { const cutoff = Date.now() - 3_000
const recent = $log.slice(-10) const recent = $log.filter(x => x.started_at < cutoff).slice(-10)
const success = recent.filter(spec({status: SignerLogEntryStatus.Success})) const ok = recent.filter(x => x.ok)
const failure = recent.filter(spec({status: SignerLogEntryStatus.Failure}))
if (!$toast && failure.length > 5 && success.length === 0) { if (!$toast && recent.length > 5 && ok.length === 0) {
pushToast({ pushToast({
theme: "error", theme: "error",
timeout: 60_000, timeout: 60_000,
message: "Your signer appears to be unresponsive.", message: "Your signer appears to be unresponsive.",
action: { action: {
message: "Details", message: "Details",
onclick: () => goto("/settings/profile"), onclick: () => goto("/settings/profile"),
}, },
}) })
} }
}), }),
),
) )
// Sync theme and font size // Sync theme and font size