envio 3.0.0-alpha.3 → 3.0.0-alpha.5

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.
Files changed (79) hide show
  1. package/README.md +2 -2
  2. package/evm.schema.json +0 -1
  3. package/index.d.ts +333 -2
  4. package/index.js +4 -0
  5. package/package.json +13 -6
  6. package/rescript.json +4 -1
  7. package/src/ChainFetcher.res +25 -1
  8. package/src/ChainFetcher.res.mjs +19 -1
  9. package/src/Config.res +212 -19
  10. package/src/Config.res.mjs +228 -29
  11. package/src/{Indexer.res → Ctx.res} +1 -1
  12. package/src/Ecosystem.res +2 -2
  13. package/src/Ecosystem.res.mjs +1 -1
  14. package/src/Envio.gen.ts +1 -1
  15. package/src/Envio.res +1 -1
  16. package/src/EventProcessing.res +18 -18
  17. package/src/EventProcessing.res.mjs +14 -14
  18. package/src/GlobalState.res +29 -35
  19. package/src/GlobalState.res.mjs +47 -47
  20. package/src/GlobalStateManager.res +68 -0
  21. package/src/GlobalStateManager.res.mjs +75 -0
  22. package/src/GlobalStateManager.resi +7 -0
  23. package/src/Internal.res +41 -1
  24. package/src/LogSelection.res +33 -27
  25. package/src/LogSelection.res.mjs +6 -0
  26. package/src/Main.res +342 -0
  27. package/src/Main.res.mjs +289 -0
  28. package/src/PgStorage.gen.ts +10 -0
  29. package/src/PgStorage.res +24 -2
  30. package/src/PgStorage.res.d.mts +5 -0
  31. package/src/PgStorage.res.mjs +22 -1
  32. package/src/Types.ts +1 -1
  33. package/src/UserContext.res +0 -1
  34. package/src/UserContext.res.mjs +0 -2
  35. package/src/Utils.res +28 -0
  36. package/src/Utils.res.mjs +18 -0
  37. package/src/bindings/ClickHouse.res +31 -1
  38. package/src/bindings/ClickHouse.res.mjs +27 -1
  39. package/src/bindings/Ethers.res +27 -67
  40. package/src/bindings/Ethers.res.mjs +18 -70
  41. package/src/bindings/Postgres.gen.ts +8 -0
  42. package/src/bindings/Postgres.res +3 -0
  43. package/src/bindings/Postgres.res.d.mts +5 -0
  44. package/src/bindings/RescriptMocha.res +123 -0
  45. package/src/bindings/RescriptMocha.res.mjs +18 -0
  46. package/src/bindings/Yargs.res +8 -0
  47. package/src/bindings/Yargs.res.mjs +2 -0
  48. package/src/sources/FuelSDK.res +4 -3
  49. package/src/sources/HyperSyncHeightStream.res +28 -110
  50. package/src/sources/HyperSyncHeightStream.res.mjs +30 -63
  51. package/src/sources/HyperSyncSource.res +11 -13
  52. package/src/sources/HyperSyncSource.res.mjs +20 -20
  53. package/src/sources/Rpc.res +43 -0
  54. package/src/sources/Rpc.res.mjs +31 -0
  55. package/src/sources/RpcSource.res +9 -4
  56. package/src/sources/RpcSource.res.mjs +9 -4
  57. package/src/sources/Source.res +1 -0
  58. package/src/sources/SourceManager.res +164 -81
  59. package/src/sources/SourceManager.res.mjs +146 -83
  60. package/src/sources/{Solana.res → Svm.res} +4 -4
  61. package/src/sources/{Solana.res.mjs → Svm.res.mjs} +4 -4
  62. package/src/tui/Tui.res +266 -0
  63. package/src/tui/Tui.res.mjs +342 -0
  64. package/src/tui/bindings/Ink.res +376 -0
  65. package/src/tui/bindings/Ink.res.mjs +75 -0
  66. package/src/tui/bindings/Style.res +123 -0
  67. package/src/tui/bindings/Style.res.mjs +2 -0
  68. package/src/tui/components/BufferedProgressBar.res +40 -0
  69. package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
  70. package/src/tui/components/CustomHooks.res +114 -0
  71. package/src/tui/components/CustomHooks.res.mjs +162 -0
  72. package/src/tui/components/Messages.res +41 -0
  73. package/src/tui/components/Messages.res.mjs +75 -0
  74. package/src/tui/components/SyncETA.res +193 -0
  75. package/src/tui/components/SyncETA.res.mjs +269 -0
  76. package/src/tui/components/TuiData.res +46 -0
  77. package/src/tui/components/TuiData.res.mjs +29 -0
  78. package/src/bindings/Ethers.gen.ts +0 -14
  79. /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
@@ -0,0 +1,266 @@
1
+ open Ink
2
+ open Belt
3
+
4
+ module ChainLine = {
5
+ @react.component
6
+ let make = (
7
+ ~chainId,
8
+ ~maxChainIdLength,
9
+ ~stdoutColumns: int,
10
+ ~progressBlock,
11
+ ~bufferBlock,
12
+ ~sourceBlock,
13
+ ~firstEventBlock,
14
+ ~startBlock,
15
+ ~endBlock,
16
+ ~poweredByHyperSync,
17
+ ~eventsProcessed,
18
+ ) => {
19
+ let chainsWidth = Pervasives.min(stdoutColumns - 2, 60)
20
+ let headerWidth = maxChainIdLength + 10 // 10 for additional text
21
+
22
+ switch (progressBlock, bufferBlock, sourceBlock) {
23
+ | (Some(progressBlock), Some(bufferBlock), Some(sourceBlock)) =>
24
+ let toBlock = switch endBlock {
25
+ | Some(endBlock) => Pervasives.min(sourceBlock, endBlock)
26
+ | None => sourceBlock
27
+ }
28
+ let firstEventBlock = firstEventBlock->Option.getWithDefault(startBlock)
29
+
30
+ let progressBlockStr = progressBlock->TuiData.formatLocaleString
31
+ let toBlockStr = toBlock->TuiData.formatLocaleString
32
+ let eventsStr = eventsProcessed->TuiData.formatLocaleString
33
+
34
+ let blocksText =
35
+ `Blocks: ${progressBlockStr} / ${toBlockStr}` ++
36
+ (endBlock->Option.isSome ? " (End Block)" : "") ++ ` `
37
+ let eventsText = `Events: ${eventsStr}`
38
+
39
+ let fitsSameLine = blocksText->String.length + eventsText->String.length <= chainsWidth
40
+
41
+ <Box flexDirection={Column}>
42
+ <Box flexDirection=Row width=Num(chainsWidth)>
43
+ <Box width={Num(headerWidth)}>
44
+ <Text> {"Chain: "->React.string} </Text>
45
+ <Text bold=true> {chainId->React.string} </Text>
46
+ <Text> {" "->React.string} </Text>
47
+ {poweredByHyperSync ? <Text color=Secondary> {"⚡"->React.string} </Text> : React.null}
48
+ </Box>
49
+ <BufferedProgressBar
50
+ barWidth={chainsWidth - headerWidth}
51
+ loaded={progressBlock - firstEventBlock}
52
+ buffered={bufferBlock - firstEventBlock}
53
+ outOf={toBlock - firstEventBlock}
54
+ loadingColor={Secondary}
55
+ />
56
+ </Box>
57
+ <Box flexDirection={Row}>
58
+ <Text color={Gray}> {blocksText->React.string} </Text>
59
+ {fitsSameLine ? <Text color={Gray}> {eventsText->React.string} </Text> : React.null}
60
+ </Box>
61
+ {fitsSameLine
62
+ ? React.null
63
+ : <Box flexDirection={Row}>
64
+ <Text color={Gray}> {eventsText->String.trim->React.string} </Text>
65
+ </Box>}
66
+ <Newline />
67
+ </Box>
68
+ | (_, _, _) =>
69
+ <>
70
+ <Box flexDirection=Row width=Num(chainsWidth)>
71
+ <Box width={Num(headerWidth)}>
72
+ <Text> {"Chain: "->React.string} </Text>
73
+ <Text bold=true> {chainId->React.string} </Text>
74
+ <Text> {" "->React.string} </Text>
75
+ {poweredByHyperSync ? <Text color=Secondary> {"⚡"->React.string} </Text> : React.null}
76
+ </Box>
77
+ <Text> {"Loading progress..."->React.string} </Text>
78
+ </Box>
79
+ <Newline />
80
+ </>
81
+ }
82
+ }
83
+ }
84
+
85
+ module TotalEventsProcessed = {
86
+ @react.component
87
+ let make = (~totalEventsProcessed) => {
88
+ let label = "Total Events: "
89
+ <Text>
90
+ <Text bold=true> {label->React.string} </Text>
91
+ <Text color={Secondary}>
92
+ {`${totalEventsProcessed->TuiData.formatLocaleString}`->React.string}
93
+ </Text>
94
+ </Text>
95
+ }
96
+ }
97
+
98
+ module App = {
99
+ @react.component
100
+ let make = (~getState) => {
101
+ let stdoutColumns = Hooks.useStdoutColumns()
102
+ let (state: GlobalState.t, setState) = React.useState(() => getState())
103
+
104
+ // useEffect to refresh state every 500ms
105
+ React.useEffect(() => {
106
+ let intervalId = Js.Global.setInterval(() => {
107
+ setState(_ => getState())
108
+ }, 500)
109
+
110
+ Some(
111
+ () => {
112
+ Js.Global.clearInterval(intervalId)
113
+ },
114
+ )
115
+ }, [getState])
116
+
117
+ let chains =
118
+ state.chainManager.chainFetchers
119
+ ->ChainMap.values
120
+ ->Array.map(cf => {
121
+ let {numEventsProcessed, fetchState, numBatchesFetched} = cf
122
+ let latestFetchedBlockNumber = Pervasives.max(fetchState->FetchState.bufferBlockNumber, 0)
123
+ let hasProcessedToEndblock = cf->ChainFetcher.hasProcessedToEndblock
124
+ let knownHeight =
125
+ cf->ChainFetcher.hasProcessedToEndblock
126
+ ? cf.fetchState.endBlock->Option.getWithDefault(cf.fetchState.knownHeight)
127
+ : cf.fetchState.knownHeight
128
+
129
+ let progress: TuiData.progress = if hasProcessedToEndblock {
130
+ // If the endblock has been reached then set the progress to synced.
131
+ // if there's chains that have no events in the block range start->end,
132
+ // it's possible there are no events in that block range (ie firstEventBlockNumber = None)
133
+ // This ensures TUI still displays synced in this case
134
+ let {
135
+ committedProgressBlockNumber,
136
+ timestampCaughtUpToHeadOrEndblock,
137
+ numEventsProcessed,
138
+ firstEventBlockNumber,
139
+ } = cf
140
+
141
+ Synced({
142
+ firstEventBlockNumber: firstEventBlockNumber->Option.getWithDefault(0),
143
+ latestProcessedBlock: committedProgressBlockNumber,
144
+ timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock->Option.getWithDefault(
145
+ Js.Date.now()->Js.Date.fromFloat,
146
+ ),
147
+ numEventsProcessed,
148
+ })
149
+ } else {
150
+ switch cf {
151
+ | {
152
+ committedProgressBlockNumber,
153
+ timestampCaughtUpToHeadOrEndblock: Some(timestampCaughtUpToHeadOrEndblock),
154
+ firstEventBlockNumber: Some(firstEventBlockNumber),
155
+ } =>
156
+ Synced({
157
+ firstEventBlockNumber,
158
+ latestProcessedBlock: committedProgressBlockNumber,
159
+ timestampCaughtUpToHeadOrEndblock,
160
+ numEventsProcessed,
161
+ })
162
+ | {
163
+ committedProgressBlockNumber,
164
+ timestampCaughtUpToHeadOrEndblock: None,
165
+ firstEventBlockNumber: Some(firstEventBlockNumber),
166
+ } =>
167
+ Syncing({
168
+ firstEventBlockNumber,
169
+ latestProcessedBlock: committedProgressBlockNumber,
170
+ numEventsProcessed,
171
+ })
172
+ | {firstEventBlockNumber: None} => SearchingForEvents
173
+ }
174
+ }
175
+
176
+ (
177
+ {
178
+ progress,
179
+ knownHeight,
180
+ latestFetchedBlockNumber,
181
+ numBatchesFetched,
182
+ eventsProcessed: numEventsProcessed,
183
+ chainId: cf.chainConfig.id->Int.toString,
184
+ progressBlock: cf.committedProgressBlockNumber === -1
185
+ ? None
186
+ : Some(cf.committedProgressBlockNumber),
187
+ bufferBlock: Some(latestFetchedBlockNumber),
188
+ sourceBlock: Some(cf.fetchState.knownHeight),
189
+ firstEventBlockNumber: cf.firstEventBlockNumber,
190
+ startBlock: cf.fetchState.startBlock,
191
+ endBlock: cf.fetchState.endBlock,
192
+ poweredByHyperSync: (
193
+ cf.sourceManager->SourceManager.getActiveSource
194
+ ).poweredByHyperSync,
195
+ }: TuiData.chain
196
+ )
197
+ })
198
+
199
+ let totalEventsProcessed = chains->Array.reduce(0, (acc, chain) => {
200
+ acc + chain.eventsProcessed
201
+ })
202
+ let maxChainIdLength = chains->Array.reduce(0, (acc, chain) => {
203
+ let chainIdLength = chain.chainId->String.length
204
+ if chainIdLength > acc {
205
+ chainIdLength
206
+ } else {
207
+ acc
208
+ }
209
+ })
210
+
211
+ <Box flexDirection={Column}>
212
+ <BigText
213
+ text="envio"
214
+ colors=[Secondary, Primary]
215
+ font={chains->Array.length > 5 ? Tiny : Block}
216
+ space=false
217
+ />
218
+ <Newline />
219
+ {chains
220
+ ->Array.mapWithIndex((i, chainData) => {
221
+ <ChainLine
222
+ key={i->Int.toString}
223
+ chainId={chainData.chainId}
224
+ maxChainIdLength={maxChainIdLength}
225
+ progressBlock={chainData.progressBlock}
226
+ bufferBlock={chainData.bufferBlock}
227
+ sourceBlock={chainData.sourceBlock}
228
+ startBlock={chainData.startBlock}
229
+ endBlock={chainData.endBlock}
230
+ stdoutColumns={stdoutColumns}
231
+ firstEventBlock={chainData.firstEventBlockNumber}
232
+ poweredByHyperSync={chainData.poweredByHyperSync}
233
+ eventsProcessed={chainData.eventsProcessed}
234
+ />
235
+ })
236
+ ->React.array}
237
+ <TotalEventsProcessed totalEventsProcessed />
238
+ <SyncETA chains indexerStartTime=state.indexerStartTime />
239
+ <Newline />
240
+ <Box flexDirection={Row}>
241
+ <Text> {"GraphQL: "->React.string} </Text>
242
+ <Text color={Info} underline=true> {Env.Hasura.url->React.string} </Text>
243
+ {
244
+ let defaultPassword = "testing"
245
+ if Env.Hasura.secret == defaultPassword {
246
+ <Text color={Gray}> {` (password: ${defaultPassword})`->React.string} </Text>
247
+ } else {
248
+ React.null
249
+ }
250
+ }
251
+ </Box>
252
+ <Box flexDirection={Row}>
253
+ <Text> {"Dev Console: "->React.string} </Text>
254
+ <Text color={Info} underline=true> {`${Env.envioAppUrl}/console`->React.string} </Text>
255
+ </Box>
256
+ <Messages config=state.ctx.config />
257
+ </Box>
258
+ }
259
+ }
260
+
261
+ let start = (~getState) => {
262
+ let {rerender} = render(<App getState />)
263
+ () => {
264
+ rerender(<App getState />)
265
+ }
266
+ }
@@ -0,0 +1,342 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Env from "../Env.res.mjs";
4
+ import * as $$Ink from "./bindings/Ink.res.mjs";
5
+ import * as $$Ink$1 from "ink";
6
+ import * as Caml from "rescript/lib/es6/caml.js";
7
+ import * as React from "react";
8
+ import * as $$String from "rescript/lib/es6/string.js";
9
+ import * as SyncETA from "./components/SyncETA.res.mjs";
10
+ import * as TuiData from "./components/TuiData.res.mjs";
11
+ import * as ChainMap from "../ChainMap.res.mjs";
12
+ import * as Messages from "./components/Messages.res.mjs";
13
+ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
14
+ import * as FetchState from "../FetchState.res.mjs";
15
+ import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
16
+ import * as Caml_option from "rescript/lib/es6/caml_option.js";
17
+ import * as ChainFetcher from "../ChainFetcher.res.mjs";
18
+ import InkBigText from "ink-big-text";
19
+ import * as SourceManager from "../sources/SourceManager.res.mjs";
20
+ import * as JsxRuntime from "react/jsx-runtime";
21
+ import * as BufferedProgressBar from "./components/BufferedProgressBar.res.mjs";
22
+
23
+ function Tui$ChainLine(props) {
24
+ var poweredByHyperSync = props.poweredByHyperSync;
25
+ var endBlock = props.endBlock;
26
+ var sourceBlock = props.sourceBlock;
27
+ var bufferBlock = props.bufferBlock;
28
+ var progressBlock = props.progressBlock;
29
+ var chainId = props.chainId;
30
+ var chainsWidth = Caml.int_min(props.stdoutColumns - 2 | 0, 60);
31
+ var headerWidth = props.maxChainIdLength + 10 | 0;
32
+ if (progressBlock !== undefined && bufferBlock !== undefined && sourceBlock !== undefined) {
33
+ var toBlock = endBlock !== undefined && sourceBlock >= endBlock ? endBlock : sourceBlock;
34
+ var firstEventBlock = Belt_Option.getWithDefault(props.firstEventBlock, props.startBlock);
35
+ var progressBlockStr = TuiData.formatLocaleString(progressBlock);
36
+ var toBlockStr = TuiData.formatLocaleString(toBlock);
37
+ var eventsStr = TuiData.formatLocaleString(props.eventsProcessed);
38
+ var blocksText = "Blocks: " + progressBlockStr + " / " + toBlockStr + (
39
+ Belt_Option.isSome(endBlock) ? " (End Block)" : ""
40
+ ) + " ";
41
+ var eventsText = "Events: " + eventsStr;
42
+ var fitsSameLine = (blocksText.length + eventsText.length | 0) <= chainsWidth;
43
+ return JsxRuntime.jsxs($$Ink$1.Box, {
44
+ children: [
45
+ JsxRuntime.jsxs($$Ink$1.Box, {
46
+ children: [
47
+ JsxRuntime.jsxs($$Ink$1.Box, {
48
+ children: [
49
+ JsxRuntime.jsx($$Ink$1.Text, {
50
+ children: "Chain: "
51
+ }),
52
+ JsxRuntime.jsx($$Ink$1.Text, {
53
+ children: chainId,
54
+ bold: true
55
+ }),
56
+ JsxRuntime.jsx($$Ink$1.Text, {
57
+ children: " "
58
+ }),
59
+ poweredByHyperSync ? JsxRuntime.jsx($$Ink$1.Text, {
60
+ children: "⚡",
61
+ color: "#FFBB2F"
62
+ }) : null
63
+ ],
64
+ width: headerWidth
65
+ }),
66
+ JsxRuntime.jsx(BufferedProgressBar.make, {
67
+ loaded: progressBlock - firstEventBlock | 0,
68
+ buffered: bufferBlock - firstEventBlock | 0,
69
+ outOf: toBlock - firstEventBlock | 0,
70
+ barWidth: chainsWidth - headerWidth | 0,
71
+ loadingColor: "#FFBB2F"
72
+ })
73
+ ],
74
+ width: chainsWidth,
75
+ flexDirection: "row"
76
+ }),
77
+ JsxRuntime.jsxs($$Ink$1.Box, {
78
+ children: [
79
+ JsxRuntime.jsx($$Ink$1.Text, {
80
+ children: blocksText,
81
+ color: "gray"
82
+ }),
83
+ fitsSameLine ? JsxRuntime.jsx($$Ink$1.Text, {
84
+ children: eventsText,
85
+ color: "gray"
86
+ }) : null
87
+ ],
88
+ flexDirection: "row"
89
+ }),
90
+ fitsSameLine ? null : JsxRuntime.jsx($$Ink$1.Box, {
91
+ children: Caml_option.some(JsxRuntime.jsx($$Ink$1.Text, {
92
+ children: $$String.trim(eventsText),
93
+ color: "gray"
94
+ })),
95
+ flexDirection: "row"
96
+ }),
97
+ JsxRuntime.jsx($$Ink.Newline.make, {})
98
+ ],
99
+ flexDirection: "column"
100
+ });
101
+ }
102
+ return JsxRuntime.jsxs(JsxRuntime.Fragment, {
103
+ children: [
104
+ JsxRuntime.jsxs($$Ink$1.Box, {
105
+ children: [
106
+ JsxRuntime.jsxs($$Ink$1.Box, {
107
+ children: [
108
+ JsxRuntime.jsx($$Ink$1.Text, {
109
+ children: "Chain: "
110
+ }),
111
+ JsxRuntime.jsx($$Ink$1.Text, {
112
+ children: chainId,
113
+ bold: true
114
+ }),
115
+ JsxRuntime.jsx($$Ink$1.Text, {
116
+ children: " "
117
+ }),
118
+ poweredByHyperSync ? JsxRuntime.jsx($$Ink$1.Text, {
119
+ children: "⚡",
120
+ color: "#FFBB2F"
121
+ }) : null
122
+ ],
123
+ width: headerWidth
124
+ }),
125
+ JsxRuntime.jsx($$Ink$1.Text, {
126
+ children: "Loading progress..."
127
+ })
128
+ ],
129
+ width: chainsWidth,
130
+ flexDirection: "row"
131
+ }),
132
+ JsxRuntime.jsx($$Ink.Newline.make, {})
133
+ ]
134
+ });
135
+ }
136
+
137
+ var ChainLine = {
138
+ make: Tui$ChainLine
139
+ };
140
+
141
+ function Tui$TotalEventsProcessed(props) {
142
+ return JsxRuntime.jsxs($$Ink$1.Text, {
143
+ children: [
144
+ JsxRuntime.jsx($$Ink$1.Text, {
145
+ children: "Total Events: ",
146
+ bold: true
147
+ }),
148
+ JsxRuntime.jsx($$Ink$1.Text, {
149
+ children: TuiData.formatLocaleString(props.totalEventsProcessed),
150
+ color: "#FFBB2F"
151
+ })
152
+ ]
153
+ });
154
+ }
155
+
156
+ var TotalEventsProcessed = {
157
+ make: Tui$TotalEventsProcessed
158
+ };
159
+
160
+ function Tui$App(props) {
161
+ var getState = props.getState;
162
+ var stdoutColumns = $$Ink.Hooks.useStdoutColumns();
163
+ var match = React.useState(function () {
164
+ return getState();
165
+ });
166
+ var setState = match[1];
167
+ var state = match[0];
168
+ React.useEffect((function () {
169
+ var intervalId = setInterval((function () {
170
+ setState(function (param) {
171
+ return getState();
172
+ });
173
+ }), 500);
174
+ return (function () {
175
+ clearInterval(intervalId);
176
+ });
177
+ }), [getState]);
178
+ var chains = Belt_Array.map(ChainMap.values(state.chainManager.chainFetchers), (function (cf) {
179
+ var numEventsProcessed = cf.numEventsProcessed;
180
+ var latestFetchedBlockNumber = Caml.int_max(FetchState.bufferBlockNumber(cf.fetchState), 0);
181
+ var hasProcessedToEndblock = ChainFetcher.hasProcessedToEndblock(cf);
182
+ var knownHeight = ChainFetcher.hasProcessedToEndblock(cf) ? Belt_Option.getWithDefault(cf.fetchState.endBlock, cf.fetchState.knownHeight) : cf.fetchState.knownHeight;
183
+ var progress;
184
+ if (hasProcessedToEndblock) {
185
+ progress = {
186
+ TAG: "Synced",
187
+ _0: {
188
+ firstEventBlockNumber: Belt_Option.getWithDefault(cf.firstEventBlockNumber, 0),
189
+ latestProcessedBlock: cf.committedProgressBlockNumber,
190
+ numEventsProcessed: cf.numEventsProcessed,
191
+ timestampCaughtUpToHeadOrEndblock: Belt_Option.getWithDefault(cf.timestampCaughtUpToHeadOrEndblock, new Date(Date.now()))
192
+ }
193
+ };
194
+ } else {
195
+ var timestampCaughtUpToHeadOrEndblock = cf.timestampCaughtUpToHeadOrEndblock;
196
+ if (timestampCaughtUpToHeadOrEndblock !== undefined) {
197
+ var firstEventBlockNumber = cf.firstEventBlockNumber;
198
+ progress = firstEventBlockNumber !== undefined ? ({
199
+ TAG: "Synced",
200
+ _0: {
201
+ firstEventBlockNumber: firstEventBlockNumber,
202
+ latestProcessedBlock: cf.committedProgressBlockNumber,
203
+ numEventsProcessed: numEventsProcessed,
204
+ timestampCaughtUpToHeadOrEndblock: Caml_option.valFromOption(timestampCaughtUpToHeadOrEndblock)
205
+ }
206
+ }) : "SearchingForEvents";
207
+ } else {
208
+ var firstEventBlockNumber$1 = cf.firstEventBlockNumber;
209
+ progress = firstEventBlockNumber$1 !== undefined ? ({
210
+ TAG: "Syncing",
211
+ _0: {
212
+ firstEventBlockNumber: firstEventBlockNumber$1,
213
+ latestProcessedBlock: cf.committedProgressBlockNumber,
214
+ numEventsProcessed: numEventsProcessed
215
+ }
216
+ }) : "SearchingForEvents";
217
+ }
218
+ }
219
+ return {
220
+ chainId: String(cf.chainConfig.id),
221
+ eventsProcessed: numEventsProcessed,
222
+ progressBlock: cf.committedProgressBlockNumber === -1 ? undefined : cf.committedProgressBlockNumber,
223
+ bufferBlock: latestFetchedBlockNumber,
224
+ sourceBlock: cf.fetchState.knownHeight,
225
+ startBlock: cf.fetchState.startBlock,
226
+ endBlock: cf.fetchState.endBlock,
227
+ firstEventBlockNumber: cf.firstEventBlockNumber,
228
+ poweredByHyperSync: SourceManager.getActiveSource(cf.sourceManager).poweredByHyperSync,
229
+ progress: progress,
230
+ latestFetchedBlockNumber: latestFetchedBlockNumber,
231
+ knownHeight: knownHeight,
232
+ numBatchesFetched: cf.numBatchesFetched
233
+ };
234
+ }));
235
+ var totalEventsProcessed = Belt_Array.reduce(chains, 0, (function (acc, chain) {
236
+ return acc + chain.eventsProcessed | 0;
237
+ }));
238
+ var maxChainIdLength = Belt_Array.reduce(chains, 0, (function (acc, chain) {
239
+ var chainIdLength = chain.chainId.length;
240
+ if (chainIdLength > acc) {
241
+ return chainIdLength;
242
+ } else {
243
+ return acc;
244
+ }
245
+ }));
246
+ var defaultPassword = "testing";
247
+ return JsxRuntime.jsxs($$Ink$1.Box, {
248
+ children: [
249
+ JsxRuntime.jsx(InkBigText, {
250
+ text: "envio",
251
+ font: chains.length > 5 ? "tiny" : "block",
252
+ colors: [
253
+ "#FFBB2F",
254
+ "#9860E5"
255
+ ],
256
+ space: false
257
+ }),
258
+ JsxRuntime.jsx($$Ink.Newline.make, {}),
259
+ Belt_Array.mapWithIndex(chains, (function (i, chainData) {
260
+ return JsxRuntime.jsx(Tui$ChainLine, {
261
+ chainId: chainData.chainId,
262
+ maxChainIdLength: maxChainIdLength,
263
+ stdoutColumns: stdoutColumns,
264
+ progressBlock: chainData.progressBlock,
265
+ bufferBlock: chainData.bufferBlock,
266
+ sourceBlock: chainData.sourceBlock,
267
+ firstEventBlock: chainData.firstEventBlockNumber,
268
+ startBlock: chainData.startBlock,
269
+ endBlock: chainData.endBlock,
270
+ poweredByHyperSync: chainData.poweredByHyperSync,
271
+ eventsProcessed: chainData.eventsProcessed
272
+ }, String(i));
273
+ })),
274
+ JsxRuntime.jsx(Tui$TotalEventsProcessed, {
275
+ totalEventsProcessed: totalEventsProcessed
276
+ }),
277
+ JsxRuntime.jsx(SyncETA.make, {
278
+ chains: chains,
279
+ indexerStartTime: state.indexerStartTime
280
+ }),
281
+ JsxRuntime.jsx($$Ink.Newline.make, {}),
282
+ JsxRuntime.jsxs($$Ink$1.Box, {
283
+ children: [
284
+ JsxRuntime.jsx($$Ink$1.Text, {
285
+ children: "GraphQL: "
286
+ }),
287
+ JsxRuntime.jsx($$Ink$1.Text, {
288
+ children: Env.Hasura.url,
289
+ color: "#6CBFEE",
290
+ underline: true
291
+ }),
292
+ Env.Hasura.secret === defaultPassword ? JsxRuntime.jsx($$Ink$1.Text, {
293
+ children: " (password: " + defaultPassword + ")",
294
+ color: "gray"
295
+ }) : null
296
+ ],
297
+ flexDirection: "row"
298
+ }),
299
+ JsxRuntime.jsxs($$Ink$1.Box, {
300
+ children: [
301
+ JsxRuntime.jsx($$Ink$1.Text, {
302
+ children: "Dev Console: "
303
+ }),
304
+ JsxRuntime.jsx($$Ink$1.Text, {
305
+ children: Env.envioAppUrl + "/console",
306
+ color: "#6CBFEE",
307
+ underline: true
308
+ })
309
+ ],
310
+ flexDirection: "row"
311
+ }),
312
+ JsxRuntime.jsx(Messages.make, {
313
+ config: state.ctx.config
314
+ })
315
+ ],
316
+ flexDirection: "column"
317
+ });
318
+ }
319
+
320
+ var App = {
321
+ make: Tui$App
322
+ };
323
+
324
+ function start(getState) {
325
+ var match = $$Ink.render(undefined, JsxRuntime.jsx(Tui$App, {
326
+ getState: getState
327
+ }));
328
+ var rerender = match.rerender;
329
+ return function () {
330
+ rerender(JsxRuntime.jsx(Tui$App, {
331
+ getState: getState
332
+ }));
333
+ };
334
+ }
335
+
336
+ export {
337
+ ChainLine ,
338
+ TotalEventsProcessed ,
339
+ App ,
340
+ start ,
341
+ }
342
+ /* Env Not a pure module */