+16
-11
src/App.svelte
+16
-11
src/App.svelte
···
15
15
const BUNDLE_OPS = 10_000
16
16
17
17
type StatusResponse = {
18
+
ok: boolean;
18
19
bundles: {
19
20
last_bundle: number;
20
21
root_hash: string;
···
46
47
hash: string | null;
47
48
mempool: number | null;
48
49
mempoolPercent: number;
50
+
mempoolBundle: number;
49
51
time?: string;
50
-
etaNext?: Date;
52
+
etaNext?: Date | null;
51
53
totalSize: number;
52
54
totalSizeUncompressed: number;
53
55
}
···
119
121
isUpdating = true
120
122
canRefresh = false
121
123
for (const i of instances) {
122
-
i.status = undefined
124
+
if (i.status) {
125
+
i.status.ok = false
126
+
}
123
127
}
124
128
125
-
lastKnownBundle.mempool = null
126
-
lastKnownBundle.mempoolPercent = 0
127
-
128
129
await Promise.all(instances.map(async (instance) => {
129
130
const status = await getStatus(instance)
130
131
instance.status = status
132
+
if (instance.status) {
133
+
instance.status.ok = true
134
+
}
131
135
132
136
if (status?.bundles?.last_bundle && status.bundles.last_bundle >= lastKnownBundle.number) {
133
137
lastKnownBundle.number = status.bundles.last_bundle
134
138
lastKnownBundle.hash = status.bundles.head_hash
135
139
lastKnownBundle.time = status.bundles.end_time
136
140
137
-
if (status?.mempool?.count && (!lastKnownBundle.mempool || status.mempool.count > lastKnownBundle.mempool)) {
141
+
if (status?.mempool?.count && (!lastKnownBundle.mempool || status.mempool.count > lastKnownBundle.mempool || status.bundles.last_bundle > lastKnownBundle.mempoolBundle)) {
142
+
lastKnownBundle.mempoolBundle = status.bundles.last_bundle
138
143
lastKnownBundle.mempool = status.mempool.count
139
144
lastKnownBundle.mempoolPercent = Math.round((lastKnownBundle.mempool/100)*100)/100
140
145
lastKnownBundle.etaNext = status.mempool.eta_next_bundle_seconds ? addSeconds(new Date(), status.mempool.eta_next_bundle_seconds) : null
···
227
232
</div>
228
233
<div class="flex gap-4">
229
234
<div class="mt-4">
230
-
<Progress value={lastKnownBundle.mempoolPercent} class="items-center">
235
+
<Progress value={lastKnownBundle.mempoolPercent} class="items-center {lastKnownBundle.mempoolPercent > 98 ? 'animate-pulse' : ''}">
231
236
<Progress.Circle style="--size: 64px; --thickness: 10px;">
232
237
<Progress.CircleTrack />
233
238
<Progress.CircleRange />
···
253
258
</div>
254
259
<div class="mt-2 grid grid-cols-1 gap-1">
255
260
<div><span class="opacity-50">Instances:</span> {instances.filter(i => i._head).length} latest / {instances.length} total</div>
256
-
<div><span class="opacity-50">PLC Operations:</span> {formatNumber((lastKnownBundle.number * BUNDLE_OPS) + lastKnownBundle.mempool)}</div>
261
+
<div><span class="opacity-50">PLC Operations:</span> {formatNumber((lastKnownBundle.number * BUNDLE_OPS) + (lastKnownBundle.mempool || 0))}</div>
257
262
<div><span class="opacity-50">Bundles Size:</span> {filesize(lastKnownBundle.totalSize)}</div>
258
263
<div><span class="opacity-50">Uncompressed:</span> {filesize(lastKnownBundle.totalSizeUncompressed)}</div>
259
264
</div>
···
281
286
{#each orderBy(instances, ...instanceOrderBy) as instance}
282
287
<tr>
283
288
<td><a href={instance.url} target="_blank" class="font-semibold">{instance.url.replace("https://", "")}</a></td>
284
-
<td>{#if instance._head}{#if isConflict}⚠️{:else}✅{/if}{:else if instance.status}🔄{:else}⌛{/if}</td>
289
+
<td>{#if instance._head && instance.status?.ok}{#if isConflict}⚠️{:else}✅{/if}{:else if instance.status}🔄{:else}⌛{/if}</td>
285
290
<td>{#if instance.status?.bundles?.last_bundle}{instance.status?.bundles?.last_bundle}{/if}</td>
286
291
<td>{#if instance.status?.mempool && instance._head}{formatNumber(instance.status?.mempool.count)}{:else if instance.status}<span class="opacity-25 text-xs">syncing</span>{/if}</td>
287
292
<td class="text-xs opacity-50">{#if instance.status?.mempool && instance._head}{instance.status?.mempool.last_op_age_seconds || 0}s{/if}</td>
288
293
<td><span class="font-mono text-xs {instance._head ? (isConflict ? 'text-error-600' : 'text-success-600') : 'opacity-50'}">{#if instance.status?.bundles?.head_hash}{instance.status?.bundles?.head_hash.slice(0, 7)}{/if}</span></td>
289
294
<td><span class="font-mono text-xs {instance.status ? (instance.status?.bundles?.root_hash === ROOT ? 'text-success-600' : 'text-error-600') : ''}">{#if instance.status?.bundles?.root_hash}{instance.status?.bundles?.root_hash.slice(0, 7)}{/if}</span></td>
290
-
<td class="text-xs">{#if instance.status?.server?.version}<a href="{instance.url}/status">{instance.status?.server?.version}</a>{/if}</td>
295
+
<td class="text-xs">{#if instance.status?.server?.version}{instance.status?.server?.version}{/if}</td>
291
296
<td class="text-xs">{#if instance.status?.server?.websocket_enabled}✔︎{:else if instance.status}<span class="opacity-25">-</span>{/if}</td>
292
297
<td class="text-xs">{#if instance.status?.server?.uptime_seconds}{formatUptime(instance.status?.server?.uptime_seconds)}{/if}</td>
293
-
<td class="text-xs opacity-50">{#if instance.status?.latency}{Math.round(instance.status?.latency)}ms{/if}</td>
298
+
<td class="text-xs opacity-50">{#if instance.status?.latency}<a href="{instance.url}/status">{Math.round(instance.status?.latency)}ms</a>{/if}</td>
294
299
</tr>
295
300
{/each}
296
301
</tbody>