envio 3.11.0 → 3.12.1
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/index.d.ts +3 -0
- package/package.json +6 -6
- package/src/Batch.res +111 -78
- package/src/Batch.res.mjs +53 -46
- package/src/BatchProcessing.res +1 -11
- package/src/BatchProcessing.res.mjs +1 -4
- package/src/ChainFetching.res +7 -3
- package/src/ChainFetching.res.mjs +1 -1
- package/src/ChainState.res +82 -20
- package/src/ChainState.res.mjs +51 -13
- package/src/ChainState.resi +6 -1
- package/src/Config.res +58 -37
- package/src/Config.res.mjs +63 -53
- package/src/CrossChainState.res +50 -53
- package/src/CrossChainState.res.mjs +25 -23
- package/src/CrossChainState.resi +6 -13
- package/src/EffectState.res +13 -4
- package/src/EffectState.resi +7 -1
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +6 -6
- package/src/FetchState.res +65 -46
- package/src/FetchState.res.mjs +68 -36
- package/src/FinalizeBackfill.res +16 -12
- package/src/FinalizeBackfill.res.mjs +3 -3
- package/src/HistoryPolicy.res +46 -0
- package/src/HistoryPolicy.res.mjs +50 -0
- package/src/InMemoryStore.res +30 -32
- package/src/InMemoryStore.res.mjs +33 -28
- package/src/InMemoryTable.res +155 -67
- package/src/InMemoryTable.res.mjs +151 -60
- package/src/IndexerState.res +66 -45
- package/src/IndexerState.res.mjs +57 -29
- package/src/IndexerState.resi +8 -13
- package/src/Internal.res +4 -2
- package/src/LoadLayer.res +68 -38
- package/src/LoadLayer.res.mjs +50 -64
- package/src/LoadLayer.resi +1 -1
- package/src/Main.res +25 -24
- package/src/Main.res.mjs +24 -25
- package/src/Metrics.res +49 -1
- package/src/Metrics.res.mjs +26 -3
- package/src/Persistence.res +55 -16
- package/src/Persistence.res.mjs +18 -3
- package/src/PgStorage.res +286 -180
- package/src/PgStorage.res.mjs +209 -122
- package/src/PruneStaleHistory.res +9 -15
- package/src/PruneStaleHistory.res.mjs +11 -20
- package/src/Rollback.res +9 -14
- package/src/Rollback.res.mjs +5 -3
- package/src/Sink.res +7 -5
- package/src/Sink.res.mjs +4 -4
- package/src/Staging.res +298 -0
- package/src/Staging.res.mjs +257 -0
- package/src/TestIndexer.res +14 -30
- package/src/TestIndexer.res.mjs +11 -9
- package/src/UserContext.res +20 -36
- package/src/UserContext.res.mjs +6 -9
- package/src/Utils.res +10 -4
- package/src/Utils.res.mjs +16 -16
- package/src/Writing.res +34 -20
- package/src/Writing.res.mjs +15 -20
- package/src/bindings/ClickHouse.res +41 -34
- package/src/bindings/ClickHouse.res.mjs +36 -30
- package/src/bindings/ClickHouseSink.res +45 -186
- package/src/bindings/ClickHouseSink.res.mjs +21 -174
- package/src/db/CheckpointSequence.res +109 -0
- package/src/db/CheckpointSequence.res.mjs +99 -0
- package/src/db/EntityFilter.res +487 -275
- package/src/db/EntityFilter.res.mjs +557 -309
- package/src/db/EntityHistory.res +6 -5
- package/src/db/EntityHistory.res.mjs +5 -5
- package/src/db/Frontier.res +86 -0
- package/src/db/Frontier.res.mjs +126 -0
- package/src/db/InternalTable.res +145 -27
- package/src/db/InternalTable.res.mjs +115 -29
- package/src/db/RollbackFloors.res +34 -41
- package/src/db/RollbackFloors.res.mjs +27 -71
- package/src/db/Table.res +21 -6
- package/src/db/Table.res.mjs +13 -4
- package/src/sources/BlockStore.res +8 -0
- package/src/sources/EvmHyperSyncSource.res +5 -1
- package/src/sources/EvmHyperSyncSource.res.mjs +4 -3
- package/src/sources/FuelHyperSyncSource.res +1 -0
- package/src/sources/FuelHyperSyncSource.res.mjs +1 -1
- package/src/sources/HyperSync.res +6 -0
- package/src/sources/HyperSync.res.mjs +5 -2
- package/src/sources/HyperSync.resi +2 -0
- package/src/sources/HyperSyncClient.res +6 -0
- package/src/sources/HyperSyncSSE.res +1 -1
- package/src/sources/HyperSyncSSE.res.mjs +4 -10
- package/src/sources/RequestStat.res +8 -1
- package/src/sources/RpcSource.res +1 -0
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SimulateSource.res +1 -0
- package/src/sources/SimulateSource.res.mjs +1 -1
- package/src/sources/Source.res +11 -3
- package/src/sources/SourceManager.res +34 -13
- package/src/sources/SourceManager.res.mjs +26 -9
- package/src/sources/SourceManager.resi +2 -0
- package/src/sources/SvmHyperSyncClient.res +5 -0
- package/src/sources/SvmHyperSyncSource.res +3 -0
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
- package/src/tui/Tui.res +56 -143
- package/src/tui/Tui.res.mjs +70 -166
- package/src/tui/components/TuiData.res +61 -16
- package/src/tui/components/TuiData.res.mjs +53 -15
- package/svm.schema.json +0 -7
- package/src/db/CheckpointBounds.res +0 -53
- package/src/db/CheckpointBounds.res.mjs +0 -44
package/src/tui/Tui.res
CHANGED
|
@@ -6,9 +6,9 @@ module ChainLine = {
|
|
|
6
6
|
~chainId,
|
|
7
7
|
~maxChainIdLength,
|
|
8
8
|
~stdoutColumns: int,
|
|
9
|
-
~progressBlock,
|
|
10
|
-
~bufferBlock,
|
|
11
|
-
~
|
|
9
|
+
~progressBlock: int,
|
|
10
|
+
~bufferBlock: int,
|
|
11
|
+
~toBlock: int,
|
|
12
12
|
~startBlock,
|
|
13
13
|
~endBlock,
|
|
14
14
|
~poweredByHyperSync,
|
|
@@ -18,65 +18,45 @@ module ChainLine = {
|
|
|
18
18
|
let chainsWidth = Pervasives.min(stdoutColumns - 2, 60)
|
|
19
19
|
let headerWidth = maxChainIdLength + 10 // 10 for additional text
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
| Some(endBlock) => Pervasives.min(sourceBlock, endBlock)
|
|
25
|
-
| None => sourceBlock
|
|
26
|
-
}
|
|
27
|
-
let progressBlockStr = progressBlock->TuiData.formatLocaleString
|
|
28
|
-
let toBlockStr = toBlock->TuiData.formatLocaleString
|
|
29
|
-
let eventsStr = eventsProcessed->TuiData.formatFloatLocaleString
|
|
21
|
+
let progressBlockStr = progressBlock->TuiData.formatLocaleString
|
|
22
|
+
let toBlockStr = toBlock->TuiData.formatLocaleString
|
|
23
|
+
let eventsStr = eventsProcessed->TuiData.formatFloatLocaleString
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
let endLabel = ` (End ${blockUnit})`
|
|
26
|
+
let blocksText =
|
|
27
|
+
`${blockUnit}s: ${progressBlockStr} / ${toBlockStr}` ++
|
|
28
|
+
(endBlock->Option.isSome ? endLabel : "") ++ ` `
|
|
29
|
+
let eventsText = `Events: ${eventsStr}`
|
|
36
30
|
|
|
37
|
-
|
|
31
|
+
let fitsSameLine = blocksText->String.length + eventsText->String.length <= chainsWidth
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
</Box>
|
|
47
|
-
<BufferedProgressBar
|
|
48
|
-
barWidth={chainsWidth - headerWidth}
|
|
49
|
-
loaded={progressBlock - startBlock}
|
|
50
|
-
buffered={bufferBlock - startBlock}
|
|
51
|
-
outOf={toBlock - startBlock}
|
|
52
|
-
loadingColor={Secondary}
|
|
53
|
-
/>
|
|
54
|
-
</Box>
|
|
55
|
-
<Box flexDirection={Row}>
|
|
56
|
-
<Text color={Gray}> {blocksText->React.string} </Text>
|
|
57
|
-
{fitsSameLine ? <Text color={Gray}> {eventsText->React.string} </Text> : React.null}
|
|
33
|
+
<Box flexDirection={Column}>
|
|
34
|
+
<Box flexDirection=Row width=Num(chainsWidth)>
|
|
35
|
+
<Box width={Num(headerWidth)}>
|
|
36
|
+
<Text> {"Chain: "->React.string} </Text>
|
|
37
|
+
<Text bold=true> {chainId->React.string} </Text>
|
|
38
|
+
<Text> {" "->React.string} </Text>
|
|
39
|
+
{poweredByHyperSync ? <Text color=Secondary> {"⚡"->React.string} </Text> : React.null}
|
|
58
40
|
</Box>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
41
|
+
<BufferedProgressBar
|
|
42
|
+
barWidth={chainsWidth - headerWidth}
|
|
43
|
+
loaded={progressBlock - startBlock}
|
|
44
|
+
buffered={bufferBlock - startBlock}
|
|
45
|
+
outOf={toBlock - startBlock}
|
|
46
|
+
loadingColor={Secondary}
|
|
47
|
+
/>
|
|
65
48
|
</Box>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</Box>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<Newline />
|
|
78
|
-
</>
|
|
79
|
-
}
|
|
49
|
+
<Box flexDirection={Row}>
|
|
50
|
+
<Text color={Gray}> {blocksText->React.string} </Text>
|
|
51
|
+
{fitsSameLine ? <Text color={Gray}> {eventsText->React.string} </Text> : React.null}
|
|
52
|
+
</Box>
|
|
53
|
+
{fitsSameLine
|
|
54
|
+
? React.null
|
|
55
|
+
: <Box flexDirection={Row}>
|
|
56
|
+
<Text color={Gray}> {eventsText->String.trim->React.string} </Text>
|
|
57
|
+
</Box>}
|
|
58
|
+
<Newline />
|
|
59
|
+
</Box>
|
|
80
60
|
}
|
|
81
61
|
}
|
|
82
62
|
|
|
@@ -132,13 +112,13 @@ module TotalEventsProcessed = {
|
|
|
132
112
|
|
|
133
113
|
module App = {
|
|
134
114
|
@react.component
|
|
135
|
-
let make = (~
|
|
115
|
+
let make = (~config: Config.t, ~getMetrics) => {
|
|
136
116
|
let stdoutColumns = Hooks.useStdoutColumns()
|
|
137
|
-
//
|
|
138
|
-
// would bail out via Object.is and skip the re-render. Tick a
|
|
139
|
-
// instead and read
|
|
117
|
+
// Metrics are rebuilt from state mutated in place — passing the same value
|
|
118
|
+
// to useState would bail out via Object.is and skip the re-render. Tick a
|
|
119
|
+
// counter instead and read metrics freshly on every render.
|
|
140
120
|
let (tick, setTick) = React.useState(() => 0)
|
|
141
|
-
let
|
|
121
|
+
let metrics: Metrics.t = getMetrics()
|
|
142
122
|
|
|
143
123
|
React.useEffect(() => {
|
|
144
124
|
let intervalId = setInterval(() => {
|
|
@@ -150,80 +130,13 @@ module App = {
|
|
|
150
130
|
clearInterval(intervalId)
|
|
151
131
|
},
|
|
152
132
|
)
|
|
153
|
-
}, [
|
|
154
|
-
|
|
155
|
-
let chains =
|
|
156
|
-
state
|
|
157
|
-
->IndexerState.chainStates
|
|
158
|
-
->Dict.valuesToArray
|
|
159
|
-
->Array.map(cs => {
|
|
160
|
-
let data = cs->ChainState.toMetrics
|
|
161
|
-
let numEventsProcessed = data.numEventsProcessed
|
|
162
|
-
let committedProgressBlockNumber = cs->ChainState.committedProgressBlockNumber
|
|
163
|
-
let timestampCaughtUpToHeadOrEndblock = data.timestampCaughtUpToHeadOrEndblock
|
|
164
|
-
let sourceManager = cs->ChainState.sourceManager
|
|
165
|
-
let latestFetchedBlockNumber = data.latestFetchedBlockNumber
|
|
166
|
-
let hasProcessedToEndblock = cs->ChainState.hasProcessedToEndblock
|
|
167
|
-
|
|
168
|
-
let firstEventBlock = data.firstEventBlockNumber
|
|
169
|
-
let progress: TuiData.progress = if hasProcessedToEndblock {
|
|
170
|
-
// If the endblock has been reached then set the progress to synced.
|
|
171
|
-
// if there's chains that have no events in the block range start->end,
|
|
172
|
-
// it's possible there are no events in that block range (ie firstEventBlock = None)
|
|
173
|
-
// This ensures TUI still displays synced in this case
|
|
174
|
-
Synced({
|
|
175
|
-
firstEventBlockNumber: firstEventBlock->Option.getOr(0),
|
|
176
|
-
latestProcessedBlock: committedProgressBlockNumber,
|
|
177
|
-
timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock->Option.getOr(
|
|
178
|
-
Date.now()->Date.fromTime,
|
|
179
|
-
),
|
|
180
|
-
numEventsProcessed,
|
|
181
|
-
})
|
|
182
|
-
} else {
|
|
183
|
-
switch (firstEventBlock, timestampCaughtUpToHeadOrEndblock) {
|
|
184
|
-
| (Some(firstEventBlockNumber), Some(timestampCaughtUpToHeadOrEndblock)) =>
|
|
185
|
-
Synced({
|
|
186
|
-
firstEventBlockNumber,
|
|
187
|
-
latestProcessedBlock: committedProgressBlockNumber,
|
|
188
|
-
timestampCaughtUpToHeadOrEndblock,
|
|
189
|
-
numEventsProcessed,
|
|
190
|
-
})
|
|
191
|
-
| (Some(firstEventBlockNumber), None) =>
|
|
192
|
-
Syncing({
|
|
193
|
-
firstEventBlockNumber,
|
|
194
|
-
latestProcessedBlock: committedProgressBlockNumber,
|
|
195
|
-
numEventsProcessed,
|
|
196
|
-
})
|
|
197
|
-
| (None, _) => SearchingForEvents
|
|
198
|
-
}
|
|
199
|
-
}
|
|
133
|
+
}, [getMetrics])
|
|
200
134
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
eventsProcessed: numEventsProcessed,
|
|
207
|
-
chainId: (cs->ChainState.chainConfig).id->ChainId.toString,
|
|
208
|
-
progressBlock: committedProgressBlockNumber < data.startBlock
|
|
209
|
-
? Some(data.startBlock)
|
|
210
|
-
: Some(committedProgressBlockNumber),
|
|
211
|
-
bufferBlock: Some(latestFetchedBlockNumber),
|
|
212
|
-
sourceBlock: Some(cs->ChainState.knownHeight),
|
|
213
|
-
firstEventBlockNumber: firstEventBlock,
|
|
214
|
-
startBlock: data.startBlock,
|
|
215
|
-
endBlock: data.endBlock,
|
|
216
|
-
poweredByHyperSync: data.poweredByHyperSync,
|
|
217
|
-
blockUnit: switch (state->IndexerState.config).ecosystem.name {
|
|
218
|
-
| Svm => "Slot"
|
|
219
|
-
| Evm | Fuel => "Block"
|
|
220
|
-
},
|
|
221
|
-
rateLimitTimeMs: sourceManager->SourceManager.getRateLimitTimeMs,
|
|
222
|
-
isRateLimited: sourceManager->SourceManager.isRateLimited,
|
|
223
|
-
rateLimitResetInMs: sourceManager->SourceManager.getRateLimitResetInMs,
|
|
224
|
-
}: TuiData.chain
|
|
225
|
-
)
|
|
226
|
-
})
|
|
135
|
+
let blockUnit = switch config.ecosystem.name {
|
|
136
|
+
| Svm => "Slot"
|
|
137
|
+
| Evm | Fuel => "Block"
|
|
138
|
+
}
|
|
139
|
+
let chains = metrics.chains->Array.map(m => m->TuiData.fromChainMetrics(~blockUnit))
|
|
227
140
|
|
|
228
141
|
let totalEventsProcessed = chains->Array.reduce(0., (acc, chain) => {
|
|
229
142
|
acc +. chain.eventsProcessed
|
|
@@ -254,7 +167,7 @@ module App = {
|
|
|
254
167
|
maxChainIdLength={maxChainIdLength}
|
|
255
168
|
progressBlock={chainData.progressBlock}
|
|
256
169
|
bufferBlock={chainData.bufferBlock}
|
|
257
|
-
|
|
170
|
+
toBlock={chainData.toBlock}
|
|
258
171
|
startBlock={chainData.startBlock}
|
|
259
172
|
endBlock={chainData.endBlock}
|
|
260
173
|
stdoutColumns={stdoutColumns}
|
|
@@ -268,7 +181,7 @@ module App = {
|
|
|
268
181
|
totalEventsProcessed
|
|
269
182
|
eventsPerSecond={SyncETA.isIndexerFullySynced(chains) ? None : eventsPerSecond}
|
|
270
183
|
/>
|
|
271
|
-
<SyncETA chains indexerStartTime={
|
|
184
|
+
<SyncETA chains indexerStartTime={metrics.startTime} />
|
|
272
185
|
{
|
|
273
186
|
let maxRateLimitTimeMs =
|
|
274
187
|
chains->Array.reduce(0., (acc, chain) => Pervasives.max(acc, chain.rateLimitTimeMs))
|
|
@@ -314,7 +227,7 @@ module App = {
|
|
|
314
227
|
}
|
|
315
228
|
}
|
|
316
229
|
</Box>
|
|
317
|
-
{if
|
|
230
|
+
{if config.isDev {
|
|
318
231
|
<Box flexDirection={Row}>
|
|
319
232
|
<Text> {"Dev Console: "->React.string} </Text>
|
|
320
233
|
<Text color={Info} underline=true> {`${Env.envioAppUrl}/console`->React.string} </Text>
|
|
@@ -322,7 +235,7 @@ module App = {
|
|
|
322
235
|
} else {
|
|
323
236
|
React.null
|
|
324
237
|
}}
|
|
325
|
-
{switch (
|
|
238
|
+
{switch (config.storage.clickhouse, Env.ClickHouse.host()) {
|
|
326
239
|
| (true, Some(host)) =>
|
|
327
240
|
<Box flexDirection={Row}>
|
|
328
241
|
<Text> {"ClickHouse: "->React.string} </Text>
|
|
@@ -330,14 +243,14 @@ module App = {
|
|
|
330
243
|
</Box>
|
|
331
244
|
| _ => React.null
|
|
332
245
|
}}
|
|
333
|
-
<Messages config
|
|
246
|
+
<Messages config />
|
|
334
247
|
</Box>
|
|
335
248
|
}
|
|
336
249
|
}
|
|
337
250
|
|
|
338
|
-
let start = (~
|
|
339
|
-
let {rerender} = render(<App
|
|
251
|
+
let start = (~config, ~getMetrics) => {
|
|
252
|
+
let {rerender} = render(<App config getMetrics />)
|
|
340
253
|
() => {
|
|
341
|
-
rerender(<App
|
|
254
|
+
rerender(<App config getMetrics />)
|
|
342
255
|
}
|
|
343
256
|
}
|
package/src/tui/Tui.res.mjs
CHANGED
|
@@ -4,16 +4,12 @@ import * as Env from "../Env.res.mjs";
|
|
|
4
4
|
import * as Ink from "./bindings/Ink.res.mjs";
|
|
5
5
|
import * as Ink$1 from "ink";
|
|
6
6
|
import * as React from "react";
|
|
7
|
-
import * as ChainId from "../ChainId.res.mjs";
|
|
8
7
|
import * as SyncETA from "./components/SyncETA.res.mjs";
|
|
9
8
|
import * as TuiData from "./components/TuiData.res.mjs";
|
|
10
9
|
import * as Messages from "./components/Messages.res.mjs";
|
|
11
|
-
import * as ChainState from "../ChainState.res.mjs";
|
|
12
|
-
import * as IndexerState from "../IndexerState.res.mjs";
|
|
13
10
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
14
11
|
import InkBigText from "ink-big-text";
|
|
15
12
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
16
|
-
import * as SourceManager from "../sources/SourceManager.res.mjs";
|
|
17
13
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
18
14
|
import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
|
|
19
15
|
import * as JsxRuntime from "react/jsx-runtime";
|
|
@@ -21,86 +17,21 @@ import * as BufferedProgressBar from "./components/BufferedProgressBar.res.mjs";
|
|
|
21
17
|
|
|
22
18
|
function Tui$ChainLine(props) {
|
|
23
19
|
let blockUnit = props.blockUnit;
|
|
24
|
-
let poweredByHyperSync = props.poweredByHyperSync;
|
|
25
|
-
let endBlock = props.endBlock;
|
|
26
20
|
let startBlock = props.startBlock;
|
|
27
|
-
let
|
|
28
|
-
let bufferBlock = props.bufferBlock;
|
|
21
|
+
let toBlock = props.toBlock;
|
|
29
22
|
let progressBlock = props.progressBlock;
|
|
30
|
-
let chainId = props.chainId;
|
|
31
23
|
let chainsWidth = Primitive_int.min(props.stdoutColumns - 2 | 0, 60);
|
|
32
24
|
let headerWidth = props.maxChainIdLength + 10 | 0;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let fitsSameLine = (blocksText.length + eventsText.length | 0) <= chainsWidth;
|
|
44
|
-
return JsxRuntime.jsxs(Ink$1.Box, {
|
|
45
|
-
children: [
|
|
46
|
-
JsxRuntime.jsxs(Ink$1.Box, {
|
|
47
|
-
children: [
|
|
48
|
-
JsxRuntime.jsxs(Ink$1.Box, {
|
|
49
|
-
children: [
|
|
50
|
-
JsxRuntime.jsx(Ink$1.Text, {
|
|
51
|
-
children: "Chain: "
|
|
52
|
-
}),
|
|
53
|
-
JsxRuntime.jsx(Ink$1.Text, {
|
|
54
|
-
children: chainId,
|
|
55
|
-
bold: true
|
|
56
|
-
}),
|
|
57
|
-
JsxRuntime.jsx(Ink$1.Text, {
|
|
58
|
-
children: " "
|
|
59
|
-
}),
|
|
60
|
-
poweredByHyperSync ? JsxRuntime.jsx(Ink$1.Text, {
|
|
61
|
-
children: "⚡",
|
|
62
|
-
color: "#FFBB2F"
|
|
63
|
-
}) : null
|
|
64
|
-
],
|
|
65
|
-
width: headerWidth
|
|
66
|
-
}),
|
|
67
|
-
JsxRuntime.jsx(BufferedProgressBar.make, {
|
|
68
|
-
loaded: progressBlock - startBlock | 0,
|
|
69
|
-
buffered: bufferBlock - startBlock | 0,
|
|
70
|
-
outOf: toBlock - startBlock | 0,
|
|
71
|
-
barWidth: chainsWidth - headerWidth | 0,
|
|
72
|
-
loadingColor: "#FFBB2F"
|
|
73
|
-
})
|
|
74
|
-
],
|
|
75
|
-
width: chainsWidth,
|
|
76
|
-
flexDirection: "row"
|
|
77
|
-
}),
|
|
78
|
-
JsxRuntime.jsxs(Ink$1.Box, {
|
|
79
|
-
children: [
|
|
80
|
-
JsxRuntime.jsx(Ink$1.Text, {
|
|
81
|
-
children: blocksText,
|
|
82
|
-
color: "gray"
|
|
83
|
-
}),
|
|
84
|
-
fitsSameLine ? JsxRuntime.jsx(Ink$1.Text, {
|
|
85
|
-
children: eventsText,
|
|
86
|
-
color: "gray"
|
|
87
|
-
}) : null
|
|
88
|
-
],
|
|
89
|
-
flexDirection: "row"
|
|
90
|
-
}),
|
|
91
|
-
fitsSameLine ? null : JsxRuntime.jsx(Ink$1.Box, {
|
|
92
|
-
children: JsxRuntime.jsx(Ink$1.Text, {
|
|
93
|
-
children: eventsText.trim(),
|
|
94
|
-
color: "gray"
|
|
95
|
-
}),
|
|
96
|
-
flexDirection: "row"
|
|
97
|
-
}),
|
|
98
|
-
JsxRuntime.jsx(Ink.Newline.make, {})
|
|
99
|
-
],
|
|
100
|
-
flexDirection: "column"
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
return JsxRuntime.jsxs(JsxRuntime.Fragment, {
|
|
25
|
+
let progressBlockStr = TuiData.formatLocaleString(progressBlock);
|
|
26
|
+
let toBlockStr = TuiData.formatLocaleString(toBlock);
|
|
27
|
+
let eventsStr = TuiData.formatFloatLocaleString(props.eventsProcessed);
|
|
28
|
+
let endLabel = ` (End ` + blockUnit + `)`;
|
|
29
|
+
let blocksText = blockUnit + `s: ` + progressBlockStr + ` / ` + toBlockStr + (
|
|
30
|
+
Stdlib_Option.isSome(props.endBlock) ? endLabel : ""
|
|
31
|
+
) + ` `;
|
|
32
|
+
let eventsText = `Events: ` + eventsStr;
|
|
33
|
+
let fitsSameLine = (blocksText.length + eventsText.length | 0) <= chainsWidth;
|
|
34
|
+
return JsxRuntime.jsxs(Ink$1.Box, {
|
|
104
35
|
children: [
|
|
105
36
|
JsxRuntime.jsxs(Ink$1.Box, {
|
|
106
37
|
children: [
|
|
@@ -110,28 +41,53 @@ function Tui$ChainLine(props) {
|
|
|
110
41
|
children: "Chain: "
|
|
111
42
|
}),
|
|
112
43
|
JsxRuntime.jsx(Ink$1.Text, {
|
|
113
|
-
children: chainId,
|
|
44
|
+
children: props.chainId,
|
|
114
45
|
bold: true
|
|
115
46
|
}),
|
|
116
47
|
JsxRuntime.jsx(Ink$1.Text, {
|
|
117
48
|
children: " "
|
|
118
49
|
}),
|
|
119
|
-
poweredByHyperSync ? JsxRuntime.jsx(Ink$1.Text, {
|
|
50
|
+
props.poweredByHyperSync ? JsxRuntime.jsx(Ink$1.Text, {
|
|
120
51
|
children: "⚡",
|
|
121
52
|
color: "#FFBB2F"
|
|
122
53
|
}) : null
|
|
123
54
|
],
|
|
124
55
|
width: headerWidth
|
|
125
56
|
}),
|
|
126
|
-
JsxRuntime.jsx(
|
|
127
|
-
|
|
57
|
+
JsxRuntime.jsx(BufferedProgressBar.make, {
|
|
58
|
+
loaded: progressBlock - startBlock | 0,
|
|
59
|
+
buffered: props.bufferBlock - startBlock | 0,
|
|
60
|
+
outOf: toBlock - startBlock | 0,
|
|
61
|
+
barWidth: chainsWidth - headerWidth | 0,
|
|
62
|
+
loadingColor: "#FFBB2F"
|
|
128
63
|
})
|
|
129
64
|
],
|
|
130
65
|
width: chainsWidth,
|
|
131
66
|
flexDirection: "row"
|
|
132
67
|
}),
|
|
68
|
+
JsxRuntime.jsxs(Ink$1.Box, {
|
|
69
|
+
children: [
|
|
70
|
+
JsxRuntime.jsx(Ink$1.Text, {
|
|
71
|
+
children: blocksText,
|
|
72
|
+
color: "gray"
|
|
73
|
+
}),
|
|
74
|
+
fitsSameLine ? JsxRuntime.jsx(Ink$1.Text, {
|
|
75
|
+
children: eventsText,
|
|
76
|
+
color: "gray"
|
|
77
|
+
}) : null
|
|
78
|
+
],
|
|
79
|
+
flexDirection: "row"
|
|
80
|
+
}),
|
|
81
|
+
fitsSameLine ? null : JsxRuntime.jsx(Ink$1.Box, {
|
|
82
|
+
children: JsxRuntime.jsx(Ink$1.Text, {
|
|
83
|
+
children: eventsText.trim(),
|
|
84
|
+
color: "gray"
|
|
85
|
+
}),
|
|
86
|
+
flexDirection: "row"
|
|
87
|
+
}),
|
|
133
88
|
JsxRuntime.jsx(Ink.Newline.make, {})
|
|
134
|
-
]
|
|
89
|
+
],
|
|
90
|
+
flexDirection: "column"
|
|
135
91
|
});
|
|
136
92
|
}
|
|
137
93
|
|
|
@@ -196,84 +152,30 @@ let TotalEventsProcessed = {
|
|
|
196
152
|
};
|
|
197
153
|
|
|
198
154
|
function Tui$App(props) {
|
|
199
|
-
let
|
|
155
|
+
let getMetrics = props.getMetrics;
|
|
156
|
+
let config = props.config;
|
|
200
157
|
let stdoutColumns = Ink.Hooks.useStdoutColumns();
|
|
201
158
|
let match = React.useState(() => 0);
|
|
202
159
|
let setTick = match[1];
|
|
203
|
-
let
|
|
160
|
+
let metrics = getMetrics();
|
|
204
161
|
React.useEffect(() => {
|
|
205
162
|
let intervalId = setInterval(() => setTick(t => t + 1 | 0), 500);
|
|
206
163
|
return () => {
|
|
207
164
|
clearInterval(intervalId);
|
|
208
165
|
};
|
|
209
|
-
}, [
|
|
210
|
-
let
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
firstEventBlockNumber: Stdlib_Option.getOr(firstEventBlock, 0),
|
|
223
|
-
latestProcessedBlock: committedProgressBlockNumber,
|
|
224
|
-
numEventsProcessed: numEventsProcessed,
|
|
225
|
-
timestampCaughtUpToHeadOrEndblock: Stdlib_Option.getOr(timestampCaughtUpToHeadOrEndblock, new Date(Date.now()))
|
|
226
|
-
}
|
|
227
|
-
}) : (
|
|
228
|
-
firstEventBlock !== undefined ? (
|
|
229
|
-
timestampCaughtUpToHeadOrEndblock !== undefined ? ({
|
|
230
|
-
TAG: "Synced",
|
|
231
|
-
_0: {
|
|
232
|
-
firstEventBlockNumber: firstEventBlock,
|
|
233
|
-
latestProcessedBlock: committedProgressBlockNumber,
|
|
234
|
-
numEventsProcessed: numEventsProcessed,
|
|
235
|
-
timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock
|
|
236
|
-
}
|
|
237
|
-
}) : ({
|
|
238
|
-
TAG: "Syncing",
|
|
239
|
-
_0: {
|
|
240
|
-
firstEventBlockNumber: firstEventBlock,
|
|
241
|
-
latestProcessedBlock: committedProgressBlockNumber,
|
|
242
|
-
numEventsProcessed: numEventsProcessed
|
|
243
|
-
}
|
|
244
|
-
})
|
|
245
|
-
) : "SearchingForEvents"
|
|
246
|
-
);
|
|
247
|
-
let match = IndexerState.config(state).ecosystem.name;
|
|
248
|
-
let tmp;
|
|
249
|
-
switch (match) {
|
|
250
|
-
case "evm" :
|
|
251
|
-
case "fuel" :
|
|
252
|
-
tmp = "Block";
|
|
253
|
-
break;
|
|
254
|
-
case "svm" :
|
|
255
|
-
tmp = "Slot";
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
return {
|
|
259
|
-
chainId: ChainId.toString(ChainState.chainConfig(cs).id),
|
|
260
|
-
eventsProcessed: numEventsProcessed,
|
|
261
|
-
progressBlock: committedProgressBlockNumber < data.startBlock ? data.startBlock : committedProgressBlockNumber,
|
|
262
|
-
bufferBlock: latestFetchedBlockNumber,
|
|
263
|
-
sourceBlock: ChainState.knownHeight(cs),
|
|
264
|
-
startBlock: data.startBlock,
|
|
265
|
-
endBlock: data.endBlock,
|
|
266
|
-
firstEventBlockNumber: firstEventBlock,
|
|
267
|
-
poweredByHyperSync: data.poweredByHyperSync,
|
|
268
|
-
progress: progress,
|
|
269
|
-
latestFetchedBlockNumber: latestFetchedBlockNumber,
|
|
270
|
-
knownHeight: data.knownHeight,
|
|
271
|
-
blockUnit: tmp,
|
|
272
|
-
rateLimitTimeMs: SourceManager.getRateLimitTimeMs(sourceManager),
|
|
273
|
-
isRateLimited: SourceManager.isRateLimited(sourceManager),
|
|
274
|
-
rateLimitResetInMs: SourceManager.getRateLimitResetInMs(sourceManager)
|
|
275
|
-
};
|
|
276
|
-
});
|
|
166
|
+
}, [getMetrics]);
|
|
167
|
+
let match$1 = config.ecosystem.name;
|
|
168
|
+
let blockUnit;
|
|
169
|
+
switch (match$1) {
|
|
170
|
+
case "evm" :
|
|
171
|
+
case "fuel" :
|
|
172
|
+
blockUnit = "Block";
|
|
173
|
+
break;
|
|
174
|
+
case "svm" :
|
|
175
|
+
blockUnit = "Slot";
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
let chains = metrics.chains.map(m => TuiData.fromChainMetrics(m, blockUnit));
|
|
277
179
|
let totalEventsProcessed = Stdlib_Array.reduce(chains, 0, (acc, chain) => acc + chain.eventsProcessed);
|
|
278
180
|
let maxChainIdLength = Stdlib_Array.reduce(chains, 0, (acc, chain) => {
|
|
279
181
|
let chainIdLength = chain.chainId.length;
|
|
@@ -328,8 +230,8 @@ function Tui$App(props) {
|
|
|
328
230
|
tmp = null;
|
|
329
231
|
}
|
|
330
232
|
let defaultPassword = "testing";
|
|
331
|
-
let match$
|
|
332
|
-
let match$
|
|
233
|
+
let match$2 = config.storage.clickhouse;
|
|
234
|
+
let match$3 = Env.ClickHouse.host();
|
|
333
235
|
return JsxRuntime.jsxs(Ink$1.Box, {
|
|
334
236
|
children: [
|
|
335
237
|
JsxRuntime.jsx(InkBigText, {
|
|
@@ -348,7 +250,7 @@ function Tui$App(props) {
|
|
|
348
250
|
stdoutColumns: stdoutColumns,
|
|
349
251
|
progressBlock: chainData.progressBlock,
|
|
350
252
|
bufferBlock: chainData.bufferBlock,
|
|
351
|
-
|
|
253
|
+
toBlock: chainData.toBlock,
|
|
352
254
|
startBlock: chainData.startBlock,
|
|
353
255
|
endBlock: chainData.endBlock,
|
|
354
256
|
poweredByHyperSync: chainData.poweredByHyperSync,
|
|
@@ -361,7 +263,7 @@ function Tui$App(props) {
|
|
|
361
263
|
}),
|
|
362
264
|
JsxRuntime.jsx(SyncETA.make, {
|
|
363
265
|
chains: chains,
|
|
364
|
-
indexerStartTime:
|
|
266
|
+
indexerStartTime: metrics.startTime
|
|
365
267
|
}),
|
|
366
268
|
tmp,
|
|
367
269
|
JsxRuntime.jsx(Ink.Newline.make, {}),
|
|
@@ -382,7 +284,7 @@ function Tui$App(props) {
|
|
|
382
284
|
],
|
|
383
285
|
flexDirection: "row"
|
|
384
286
|
}),
|
|
385
|
-
|
|
287
|
+
config.isDev ? JsxRuntime.jsxs(Ink$1.Box, {
|
|
386
288
|
children: [
|
|
387
289
|
JsxRuntime.jsx(Ink$1.Text, {
|
|
388
290
|
children: "Dev Console: "
|
|
@@ -395,13 +297,13 @@ function Tui$App(props) {
|
|
|
395
297
|
],
|
|
396
298
|
flexDirection: "row"
|
|
397
299
|
}) : null,
|
|
398
|
-
match$
|
|
300
|
+
match$2 && match$3 !== undefined ? JsxRuntime.jsxs(Ink$1.Box, {
|
|
399
301
|
children: [
|
|
400
302
|
JsxRuntime.jsx(Ink$1.Text, {
|
|
401
303
|
children: "ClickHouse: "
|
|
402
304
|
}),
|
|
403
305
|
JsxRuntime.jsx(Ink$1.Text, {
|
|
404
|
-
children: match$
|
|
306
|
+
children: match$3 + `/play`,
|
|
405
307
|
color: "#6CBFEE",
|
|
406
308
|
underline: true
|
|
407
309
|
})
|
|
@@ -409,7 +311,7 @@ function Tui$App(props) {
|
|
|
409
311
|
flexDirection: "row"
|
|
410
312
|
}) : null,
|
|
411
313
|
JsxRuntime.jsx(Messages.make, {
|
|
412
|
-
config:
|
|
314
|
+
config: config
|
|
413
315
|
})
|
|
414
316
|
],
|
|
415
317
|
flexDirection: "column"
|
|
@@ -420,13 +322,15 @@ let App = {
|
|
|
420
322
|
make: Tui$App
|
|
421
323
|
};
|
|
422
324
|
|
|
423
|
-
function start(
|
|
325
|
+
function start(config, getMetrics) {
|
|
424
326
|
let match = Ink.render(undefined, JsxRuntime.jsx(Tui$App, {
|
|
425
|
-
|
|
327
|
+
config: config,
|
|
328
|
+
getMetrics: getMetrics
|
|
426
329
|
}));
|
|
427
330
|
let rerender = match.rerender;
|
|
428
331
|
return () => rerender(JsxRuntime.jsx(Tui$App, {
|
|
429
|
-
|
|
332
|
+
config: config,
|
|
333
|
+
getMetrics: getMetrics
|
|
430
334
|
}));
|
|
431
335
|
}
|
|
432
336
|
|