envio 3.13.0 → 3.14.0

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 (69) hide show
  1. package/bin.mjs +10 -1
  2. package/index.d.ts +11 -0
  3. package/package.json +8 -20
  4. package/rescript.json +1 -4
  5. package/src/Config.res +69 -100
  6. package/src/Config.res.mjs +50 -63
  7. package/src/Core.res +46 -6
  8. package/src/Core.res.mjs +41 -4
  9. package/src/EventConfigBuilder.res +4 -10
  10. package/src/EventConfigBuilder.res.mjs +1 -3
  11. package/src/ExitOnCaughtUp.res +5 -1
  12. package/src/ExitOnCaughtUp.res.mjs +8 -3
  13. package/src/HandlerLoader.res +74 -32
  14. package/src/HandlerLoader.res.mjs +69 -23
  15. package/src/HandlerTypeCheck.mjs +14 -0
  16. package/src/HandlerTypeCheckWorker.mjs +68 -0
  17. package/src/Internal.res +1 -1
  18. package/src/Main.res +17 -12
  19. package/src/Main.res.mjs +9 -3
  20. package/src/NodeVersion.mjs +13 -0
  21. package/src/Persistence.res +79 -38
  22. package/src/Persistence.res.mjs +41 -10
  23. package/src/PgStorage.res +62 -34
  24. package/src/PgStorage.res.mjs +65 -31
  25. package/src/ResumePlan.res +172 -0
  26. package/src/ResumePlan.res.mjs +122 -0
  27. package/src/Supervisor.res +8 -8
  28. package/src/Supervisor.res.mjs +6 -1
  29. package/src/TestIndexer.res +14 -4
  30. package/src/TestIndexer.res.mjs +3 -2
  31. package/src/TsModuleHooks.mjs +121 -0
  32. package/src/Utils.res +0 -8
  33. package/src/Worker.res +8 -0
  34. package/src/Worker.res.mjs +11 -0
  35. package/src/bindings/NodeJs.res +8 -7
  36. package/src/bindings/NodeJs.res.mjs +0 -3
  37. package/src/bindings/Pino.res +2 -2
  38. package/src/db/InternalTable.res +52 -2
  39. package/src/db/InternalTable.res.mjs +32 -3
  40. package/src/sources/FuelHyperSync.res +2 -0
  41. package/src/sources/FuelHyperSync.res.mjs +1 -0
  42. package/src/sources/FuelHyperSync.resi +1 -0
  43. package/src/sources/FuelHyperSyncClient.res +25 -8
  44. package/src/sources/FuelHyperSyncClient.res.mjs +8 -2
  45. package/src/sources/FuelHyperSyncSource.res +24 -22
  46. package/src/sources/FuelHyperSyncSource.res.mjs +18 -13
  47. package/src/tui/InitApi.res +85 -0
  48. package/src/tui/{components/CustomHooks.res.mjs → InitApi.res.mjs} +11 -64
  49. package/src/tui/Tui.res +142 -249
  50. package/src/tui/Tui.res.mjs +123 -332
  51. package/src/Js.shim.ts +0 -11
  52. package/src/bindings/DateFns.res +0 -74
  53. package/src/bindings/DateFns.res.mjs +0 -22
  54. package/src/sources/FuelSDK.res +0 -38
  55. package/src/sources/FuelSDK.res.mjs +0 -27
  56. package/src/sources/vendored-fuel-abi-coder.js +0 -1792
  57. package/src/tui/bindings/Ink.res +0 -369
  58. package/src/tui/bindings/Ink.res.mjs +0 -66
  59. package/src/tui/bindings/Style.res +0 -123
  60. package/src/tui/bindings/Style.res.mjs +0 -2
  61. package/src/tui/components/BufferedProgressBar.res +0 -40
  62. package/src/tui/components/BufferedProgressBar.res.mjs +0 -57
  63. package/src/tui/components/CustomHooks.res +0 -122
  64. package/src/tui/components/Messages.res +0 -40
  65. package/src/tui/components/Messages.res.mjs +0 -71
  66. package/src/tui/components/SyncETA.res +0 -179
  67. package/src/tui/components/SyncETA.res.mjs +0 -249
  68. package/src/tui/components/TuiData.res +0 -98
  69. package/src/tui/components/TuiData.res.mjs +0 -73
@@ -1,122 +0,0 @@
1
- module InitApi = {
2
- type ecosystem = | @as("evm") Evm | @as("fuel") Fuel | @as("svm") Svm
3
- type body = {
4
- envioVersion: string,
5
- envioApiToken: option<string>,
6
- ecosystem: ecosystem,
7
- hyperSyncNetworks: array<ChainId.t>,
8
- rpcNetworks: array<ChainId.t>,
9
- }
10
-
11
- let bodySchema = S.object(s => {
12
- envioVersion: s.field("envioVersion", S.string),
13
- envioApiToken: s.field("envioApiToken", S.option(S.string)),
14
- ecosystem: s.field("ecosystem", S.enum([Evm, Fuel, Svm])),
15
- hyperSyncNetworks: s.field("hyperSyncNetworks", S.array(ChainId.schema)),
16
- rpcNetworks: s.field("rpcNetworks", S.array(ChainId.schema)),
17
- })
18
-
19
- let makeBody = (~envioVersion, ~envioApiToken, ~config: Config.t) => {
20
- let hyperSyncNetworks = []
21
- let rpcNetworks = []
22
- config.chainMap
23
- ->ChainMap.values
24
- ->Array.forEach(({sourceConfig, id}) => {
25
- // Check if chain uses HyperSync based on sourceConfig
26
- let usesHyperSync = switch sourceConfig {
27
- | Config.EvmSourceConfig({hypersync: Some(_)}) => true
28
- | Config.EvmSourceConfig({hypersync: None}) => false
29
- | Config.FuelSourceConfig(_) => true // Fuel always uses HyperFuel
30
- | Config.SvmSourceConfig(_) => false
31
- | Config.SimulateSourceConfig(_) => false
32
- | Config.CustomSources(sources) => sources->Array.some(s => s.poweredByHyperSync)
33
- }
34
- switch usesHyperSync {
35
- | true => hyperSyncNetworks
36
- | false => rpcNetworks
37
- }
38
- ->Array.push(id)
39
- ->ignore
40
- })
41
-
42
- {
43
- envioVersion,
44
- envioApiToken,
45
- ecosystem: (config.ecosystem.name :> ecosystem),
46
- hyperSyncNetworks,
47
- rpcNetworks,
48
- }
49
- }
50
-
51
- type messageColor =
52
- | @as("primary") Primary
53
- | @as("secondary") Secondary
54
- | @as("info") Info
55
- | @as("danger") Danger
56
- | @as("success") Success
57
- | @as("white") White
58
- | @as("gray") Gray
59
-
60
- let toTheme = (color: messageColor): Style.chalkTheme =>
61
- switch color {
62
- | Primary => Primary
63
- | Secondary => Secondary
64
- | Info => Info
65
- | Danger => Danger
66
- | Success => Success
67
- | White => White
68
- | Gray => Gray
69
- }
70
-
71
- type message = {
72
- color: messageColor,
73
- content: string,
74
- }
75
-
76
- let messageSchema = S.object(s => {
77
- color: s.field("color", S.enum([Primary, Secondary, Info, Danger, Success, White, Gray])),
78
- content: s.field("content", S.string),
79
- })
80
-
81
- let client = Rest.client(Env.envioAppUrl ++ "/api")
82
-
83
- let route = Rest.route(() => {
84
- method: Post,
85
- path: "/hyperindex/init",
86
- input: s => s.body(bodySchema),
87
- responses: [s => s.field("messages", S.array(messageSchema))],
88
- })
89
-
90
- let getMessages = async (~config) => {
91
- let envioVersion = Utils.EnvioPackage.value.version
92
- let body = makeBody(~envioVersion, ~envioApiToken=Env.envioApiToken, ~config)
93
-
94
- switch await route->Rest.fetch(body, ~client) {
95
- | exception exn => Error(exn->Obj.magic)
96
- | messages => Ok(messages)
97
- }
98
- }
99
- }
100
-
101
- type request<'ok, 'err> = Data('ok) | Loading | Err('err)
102
-
103
- let useMessages = (~config) => {
104
- let (request, setRequest) = React.useState(_ => Loading)
105
- React.useEffect0(() => {
106
- InitApi.getMessages(~config)
107
- ->Promise.thenResolve(res =>
108
- switch res {
109
- | Ok(data) => setRequest(_ => Data(data))
110
- | Error(e) =>
111
- Logging.error({
112
- "msg": "Failed to load messages from envio server",
113
- "err": e->Utils.prettifyExn,
114
- })
115
- setRequest(_ => Err(e))
116
- }
117
- )
118
- ->ignore
119
- None
120
- })
121
- request
122
- }
@@ -1,40 +0,0 @@
1
- open Ink
2
- module Message = {
3
- @react.component
4
- let make = (~message: CustomHooks.InitApi.message) => {
5
- <Text color={message.color->CustomHooks.InitApi.toTheme}>
6
- {message.content->React.string}
7
- </Text>
8
- }
9
- }
10
-
11
- module Notifications = {
12
- @react.component
13
- let make = (~children) => {
14
- <>
15
- <Newline />
16
- <Text bold=true> {"Notifications:"->React.string} </Text>
17
- {children}
18
- </>
19
- }
20
- }
21
-
22
- @react.component
23
- let make = (~config) => {
24
- let messages = CustomHooks.useMessages(~config)
25
- <>
26
- {switch messages {
27
- | Data([]) | Loading => React.null //Don't show anything while loading or no messages
28
- | Data(messages) =>
29
- <Notifications>
30
- {messages
31
- ->Array.mapWithIndex((message, i) => {<Message key={i->Int.toString} message />})
32
- ->React.array}
33
- </Notifications>
34
- | Err(_) =>
35
- <Notifications>
36
- <Message message={color: Danger, content: "Failed to load messages from envio server"} />
37
- </Notifications>
38
- }}
39
- </>
40
- }
@@ -1,71 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Ink from "../bindings/Ink.res.mjs";
4
- import * as Ink$1 from "ink";
5
- import * as CustomHooks from "./CustomHooks.res.mjs";
6
- import * as JsxRuntime from "react/jsx-runtime";
7
-
8
- function Messages$Message(props) {
9
- let message = props.message;
10
- return JsxRuntime.jsx(Ink$1.Text, {
11
- children: message.content,
12
- color: CustomHooks.InitApi.toTheme(message.color)
13
- });
14
- }
15
-
16
- let Message = {
17
- make: Messages$Message
18
- };
19
-
20
- function Messages$Notifications(props) {
21
- return JsxRuntime.jsxs(JsxRuntime.Fragment, {
22
- children: [
23
- JsxRuntime.jsx(Ink.Newline.make, {}),
24
- JsxRuntime.jsx(Ink$1.Text, {
25
- children: "Notifications:",
26
- bold: true
27
- }),
28
- props.children
29
- ]
30
- });
31
- }
32
-
33
- let Notifications = {
34
- make: Messages$Notifications
35
- };
36
-
37
- function Messages(props) {
38
- let messages = CustomHooks.useMessages(props.config);
39
- let tmp;
40
- if (typeof messages !== "object") {
41
- tmp = null;
42
- } else if (messages.TAG === "Data") {
43
- let messages$1 = messages._0;
44
- tmp = messages$1.length !== 0 ? JsxRuntime.jsx(Messages$Notifications, {
45
- children: messages$1.map((message, i) => JsxRuntime.jsx(Messages$Message, {
46
- message: message
47
- }, i.toString()))
48
- }) : null;
49
- } else {
50
- tmp = JsxRuntime.jsx(Messages$Notifications, {
51
- children: JsxRuntime.jsx(Messages$Message, {
52
- message: {
53
- color: "danger",
54
- content: "Failed to load messages from envio server"
55
- }
56
- })
57
- });
58
- }
59
- return JsxRuntime.jsx(JsxRuntime.Fragment, {
60
- children: tmp
61
- });
62
- }
63
-
64
- let make = Messages;
65
-
66
- export {
67
- Message,
68
- Notifications,
69
- make,
70
- }
71
- /* Ink Not a pure module */
@@ -1,179 +0,0 @@
1
- open Ink
2
-
3
- let isIndexerFullySynced = (chains: array<TuiData.chain>) => {
4
- switch chains {
5
- // A supervised run draws its first frame before any worker has reported, and
6
- // a run with nothing to report hasn't finished syncing.
7
- | [] => false
8
- | chains =>
9
- chains->Array.every(chain =>
10
- switch chain.progress {
11
- | Synced(_) => true
12
- | _ => false
13
- }
14
- )
15
- }
16
- }
17
-
18
- let getTotalRemainingBlocks = (chains: array<TuiData.chain>) => {
19
- chains->Array.reduce(0, (accum, {progress, knownHeight, latestFetchedBlockNumber, endBlock}) => {
20
- let finalBlock = switch endBlock {
21
- | Some(endBlock) => endBlock
22
- | None => knownHeight
23
- }
24
- switch progress {
25
- | Syncing({latestProcessedBlock})
26
- | Synced({latestProcessedBlock}) =>
27
- finalBlock - latestProcessedBlock + accum
28
- | SearchingForEvents => finalBlock - latestFetchedBlockNumber + accum
29
- }
30
- })
31
- }
32
-
33
- let getLatestTimeCaughtUpToHead = (chains: array<TuiData.chain>, indexerStartTime: Date.t) => {
34
- let latesttimestampCaughtUpToHeadOrEndblockFloat = chains->Array.reduce(0.0, (accum, current) => {
35
- switch current.progress {
36
- | Synced({timestampCaughtUpToHeadOrEndblock}) =>
37
- timestampCaughtUpToHeadOrEndblock->Date.getTime > accum
38
- ? timestampCaughtUpToHeadOrEndblock->Date.getTime
39
- : accum
40
- | Syncing(_)
41
- | SearchingForEvents => accum
42
- }
43
- })
44
-
45
- DateFns.formatDistanceWithOptions(
46
- indexerStartTime,
47
- latesttimestampCaughtUpToHeadOrEndblockFloat->Date.fromTime,
48
- {includeSeconds: true},
49
- )
50
- }
51
-
52
- let getTotalBlocksProcessed = (chains: array<TuiData.chain>) => {
53
- chains->Array.reduce(0, (accum, {progress, latestFetchedBlockNumber}) => {
54
- switch progress {
55
- | Syncing({latestProcessedBlock, firstEventBlockNumber})
56
- | Synced({latestProcessedBlock, firstEventBlockNumber}) =>
57
- latestProcessedBlock - firstEventBlockNumber + accum
58
- | SearchingForEvents => latestFetchedBlockNumber + accum
59
- }
60
- })
61
- }
62
-
63
- let useShouldDisplayEta = (~chains: array<TuiData.chain>) => {
64
- let (shouldDisplayEta, setShouldDisplayEta) = React.useState(_ => false)
65
- React.useEffect(() => {
66
- if !shouldDisplayEta {
67
- // Display ETA once all chains have a known height and some blocks have been fetched
68
- let allChainsStartedFetching = chains->Array.every(chain => {
69
- chain.knownHeight > 0 && chain.latestFetchedBlockNumber > 0
70
- })
71
-
72
- if allChainsStartedFetching {
73
- setShouldDisplayEta(_ => true)
74
- }
75
- }
76
-
77
- None
78
- }, [chains])
79
-
80
- shouldDisplayEta
81
- }
82
-
83
- let useEta = (~chains, ~indexerStartTime) => {
84
- let shouldDisplayEta = useShouldDisplayEta(~chains)
85
- let (secondsToSub, setSecondsToSub) = React.useState(_ => 0.)
86
- let (timeSinceStart, setTimeSinceStart) = React.useState(_ => 0.)
87
-
88
- React.useEffect2(() => {
89
- setTimeSinceStart(_ => Date.now() -. indexerStartTime->Date.getTime)
90
- setSecondsToSub(_ => 0.)
91
-
92
- let intervalId = setInterval(() => {
93
- setSecondsToSub(prev => prev +. 1.)
94
- }, 1000)
95
-
96
- Some(() => clearInterval(intervalId))
97
- }, (chains, indexerStartTime))
98
-
99
- //blocksProcessed/remainingBlocks = timeSoFar/eta
100
- //eta = (timeSoFar/blocksProcessed) * remainingBlocks
101
-
102
- let blocksProcessed = getTotalBlocksProcessed(chains)->Int.toFloat
103
- if shouldDisplayEta && blocksProcessed > 0. {
104
- let nowDate = Date.now()
105
- let remainingBlocks = getTotalRemainingBlocks(chains)->Int.toFloat
106
- let etaFloat = timeSinceStart /. blocksProcessed *. remainingBlocks
107
- let millisToSub = secondsToSub *. 1000.
108
- let etaFloat = Pervasives.max(etaFloat -. millisToSub, 0.0) //template this
109
- let eta = (etaFloat +. nowDate)->Date.fromTime
110
- let interval: DateFns.interval = {start: nowDate->Date.fromTime, end: eta}
111
- let duration = DateFns.intervalToDuration(interval)
112
- let formattedDuration = DateFns.formatDuration(
113
- duration,
114
- {format: ["hours", "minutes", "seconds"]},
115
- )
116
- let outputString = switch formattedDuration {
117
- | "" => "less than 1 second"
118
- | formattedDuration => formattedDuration
119
- }
120
- Some(outputString)
121
- } else {
122
- None
123
- }
124
- }
125
-
126
- module Syncing = {
127
- @react.component
128
- let make = (~etaStr) => {
129
- <Text bold=true>
130
- <Text> {"Sync Time ETA: "->React.string} </Text>
131
- <Text> {etaStr->React.string} </Text>
132
- <Text> {" ("->React.string} </Text>
133
- <Text color=Primary>
134
- <Spinner />
135
- </Text>
136
- <Text color=Secondary> {" in progress"->React.string} </Text>
137
- <Text> {")"->React.string} </Text>
138
- </Text>
139
- }
140
- }
141
-
142
- module Synced = {
143
- @react.component
144
- let make = (~latestTimeCaughtUpToHeadStr) => {
145
- <Text bold=true>
146
- <Text> {"Time Synced: "->React.string} </Text>
147
- <Text> {`${latestTimeCaughtUpToHeadStr}`->React.string} </Text>
148
- <Text> {" ("->React.string} </Text>
149
- <Text color=Success> {"synced"->React.string} </Text>
150
- <Text> {")"->React.string} </Text>
151
- </Text>
152
- }
153
- }
154
-
155
- module Calculating = {
156
- @react.component
157
- let make = () => {
158
- <Text>
159
- <Text color=Primary>
160
- <Spinner />
161
- </Text>
162
- <Text bold=true> {" Calculating ETA..."->React.string} </Text>
163
- </Text>
164
- }
165
- }
166
-
167
- @react.component
168
- let make = (~chains, ~indexerStartTime) => {
169
- let optEta = useEta(~chains, ~indexerStartTime)
170
- if isIndexerFullySynced(chains) {
171
- let latestTimeCaughtUpToHeadStr = getLatestTimeCaughtUpToHead(chains, indexerStartTime)
172
- <Synced latestTimeCaughtUpToHeadStr /> //TODO add real time
173
- } else {
174
- switch optEta {
175
- | Some(etaStr) => <Syncing etaStr />
176
- | None => <Calculating />
177
- }
178
- }
179
- }
@@ -1,249 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Ink from "ink";
4
- import * as React from "react";
5
- import * as DateFns from "date-fns";
6
- import InkSpinner from "ink-spinner";
7
- import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
8
- import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
9
- import * as JsxRuntime from "react/jsx-runtime";
10
-
11
- function isIndexerFullySynced(chains) {
12
- if (chains.length !== 0) {
13
- return chains.every(chain => {
14
- let match = chain.progress;
15
- if (typeof match !== "object") {
16
- return false;
17
- } else {
18
- return match.TAG !== "Syncing";
19
- }
20
- });
21
- } else {
22
- return false;
23
- }
24
- }
25
-
26
- function getTotalRemainingBlocks(chains) {
27
- return Stdlib_Array.reduce(chains, 0, (accum, param) => {
28
- let progress = param.progress;
29
- let endBlock = param.endBlock;
30
- let finalBlock = endBlock !== undefined ? endBlock : param.knownHeight;
31
- if (typeof progress !== "object") {
32
- return (finalBlock - param.latestFetchedBlockNumber | 0) + accum | 0;
33
- }
34
- progress.TAG === "Syncing";
35
- return (finalBlock - progress._0.latestProcessedBlock | 0) + accum | 0;
36
- });
37
- }
38
-
39
- function getLatestTimeCaughtUpToHead(chains, indexerStartTime) {
40
- let latesttimestampCaughtUpToHeadOrEndblockFloat = Stdlib_Array.reduce(chains, 0.0, (accum, current) => {
41
- let match = current.progress;
42
- if (typeof match !== "object") {
43
- return accum;
44
- }
45
- if (match.TAG === "Syncing") {
46
- return accum;
47
- }
48
- let timestampCaughtUpToHeadOrEndblock = match._0.timestampCaughtUpToHeadOrEndblock;
49
- if (timestampCaughtUpToHeadOrEndblock.getTime() > accum) {
50
- return timestampCaughtUpToHeadOrEndblock.getTime();
51
- } else {
52
- return accum;
53
- }
54
- });
55
- return DateFns.formatDistance(indexerStartTime, new Date(latesttimestampCaughtUpToHeadOrEndblockFloat), {
56
- includeSeconds: true
57
- });
58
- }
59
-
60
- function getTotalBlocksProcessed(chains) {
61
- return Stdlib_Array.reduce(chains, 0, (accum, param) => {
62
- let progress = param.progress;
63
- if (typeof progress !== "object") {
64
- return param.latestFetchedBlockNumber + accum | 0;
65
- }
66
- progress.TAG === "Syncing";
67
- let match = progress._0;
68
- return (match.latestProcessedBlock - match.firstEventBlockNumber | 0) + accum | 0;
69
- });
70
- }
71
-
72
- function useShouldDisplayEta(chains) {
73
- let match = React.useState(() => false);
74
- let setShouldDisplayEta = match[1];
75
- let shouldDisplayEta = match[0];
76
- React.useEffect(() => {
77
- if (!shouldDisplayEta) {
78
- let allChainsStartedFetching = chains.every(chain => {
79
- if (chain.knownHeight > 0) {
80
- return chain.latestFetchedBlockNumber > 0;
81
- } else {
82
- return false;
83
- }
84
- });
85
- if (allChainsStartedFetching) {
86
- setShouldDisplayEta(param => true);
87
- }
88
- }
89
- }, [chains]);
90
- return shouldDisplayEta;
91
- }
92
-
93
- function useEta(chains, indexerStartTime) {
94
- let shouldDisplayEta = useShouldDisplayEta(chains);
95
- let match = React.useState(() => 0);
96
- let setSecondsToSub = match[1];
97
- let match$1 = React.useState(() => 0);
98
- let setTimeSinceStart = match$1[1];
99
- React.useEffect(() => {
100
- setTimeSinceStart(param => Date.now() - indexerStartTime.getTime());
101
- setSecondsToSub(param => 0);
102
- let intervalId = setInterval(() => setSecondsToSub(prev => prev + 1), 1000);
103
- return () => {
104
- clearInterval(intervalId);
105
- };
106
- }, [
107
- chains,
108
- indexerStartTime
109
- ]);
110
- let blocksProcessed = getTotalBlocksProcessed(chains);
111
- if (!(shouldDisplayEta && blocksProcessed > 0)) {
112
- return;
113
- }
114
- let nowDate = Date.now();
115
- let remainingBlocks = getTotalRemainingBlocks(chains);
116
- let etaFloat = match$1[0] / blocksProcessed * remainingBlocks;
117
- let millisToSub = match[0] * 1000;
118
- let etaFloat$1 = Primitive_float.max(etaFloat - millisToSub, 0.0);
119
- let eta = new Date(etaFloat$1 + nowDate);
120
- let interval_start = new Date(nowDate);
121
- let interval = {
122
- start: interval_start,
123
- end: eta
124
- };
125
- let duration = DateFns.intervalToDuration(interval);
126
- let formattedDuration = DateFns.formatDuration(duration, {
127
- format: [
128
- "hours",
129
- "minutes",
130
- "seconds"
131
- ]
132
- });
133
- let tmp = formattedDuration === "" ? "less than 1 second" : formattedDuration;
134
- return tmp;
135
- }
136
-
137
- function SyncETA$Syncing(props) {
138
- return JsxRuntime.jsxs(Ink.Text, {
139
- children: [
140
- JsxRuntime.jsx(Ink.Text, {
141
- children: "Sync Time ETA: "
142
- }),
143
- JsxRuntime.jsx(Ink.Text, {
144
- children: props.etaStr
145
- }),
146
- JsxRuntime.jsx(Ink.Text, {
147
- children: " ("
148
- }),
149
- JsxRuntime.jsx(Ink.Text, {
150
- children: JsxRuntime.jsx(InkSpinner, {}),
151
- color: "#9860E5"
152
- }),
153
- JsxRuntime.jsx(Ink.Text, {
154
- children: " in progress",
155
- color: "#FFBB2F"
156
- }),
157
- JsxRuntime.jsx(Ink.Text, {
158
- children: ")"
159
- })
160
- ],
161
- bold: true
162
- });
163
- }
164
-
165
- let Syncing = {
166
- make: SyncETA$Syncing
167
- };
168
-
169
- function SyncETA$Synced(props) {
170
- return JsxRuntime.jsxs(Ink.Text, {
171
- children: [
172
- JsxRuntime.jsx(Ink.Text, {
173
- children: "Time Synced: "
174
- }),
175
- JsxRuntime.jsx(Ink.Text, {
176
- children: props.latestTimeCaughtUpToHeadStr
177
- }),
178
- JsxRuntime.jsx(Ink.Text, {
179
- children: " ("
180
- }),
181
- JsxRuntime.jsx(Ink.Text, {
182
- children: "synced",
183
- color: "#3B8C3D"
184
- }),
185
- JsxRuntime.jsx(Ink.Text, {
186
- children: ")"
187
- })
188
- ],
189
- bold: true
190
- });
191
- }
192
-
193
- let Synced = {
194
- make: SyncETA$Synced
195
- };
196
-
197
- function SyncETA$Calculating(props) {
198
- return JsxRuntime.jsxs(Ink.Text, {
199
- children: [
200
- JsxRuntime.jsx(Ink.Text, {
201
- children: JsxRuntime.jsx(InkSpinner, {}),
202
- color: "#9860E5"
203
- }),
204
- JsxRuntime.jsx(Ink.Text, {
205
- children: " Calculating ETA...",
206
- bold: true
207
- })
208
- ]
209
- });
210
- }
211
-
212
- let Calculating = {
213
- make: SyncETA$Calculating
214
- };
215
-
216
- function SyncETA(props) {
217
- let indexerStartTime = props.indexerStartTime;
218
- let chains = props.chains;
219
- let optEta = useEta(chains, indexerStartTime);
220
- if (!isIndexerFullySynced(chains)) {
221
- if (optEta !== undefined) {
222
- return JsxRuntime.jsx(SyncETA$Syncing, {
223
- etaStr: optEta
224
- });
225
- } else {
226
- return JsxRuntime.jsx(SyncETA$Calculating, {});
227
- }
228
- }
229
- let latestTimeCaughtUpToHeadStr = getLatestTimeCaughtUpToHead(chains, indexerStartTime);
230
- return JsxRuntime.jsx(SyncETA$Synced, {
231
- latestTimeCaughtUpToHeadStr: latestTimeCaughtUpToHeadStr
232
- });
233
- }
234
-
235
- let make = SyncETA;
236
-
237
- export {
238
- isIndexerFullySynced,
239
- getTotalRemainingBlocks,
240
- getLatestTimeCaughtUpToHead,
241
- getTotalBlocksProcessed,
242
- useShouldDisplayEta,
243
- useEta,
244
- Syncing,
245
- Synced,
246
- Calculating,
247
- make,
248
- }
249
- /* ink Not a pure module */