envio 3.0.0-alpha.21 → 3.0.0-alpha.23

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 (220) hide show
  1. package/README.md +3 -3
  2. package/bin.mjs +2 -48
  3. package/evm.schema.json +67 -0
  4. package/fuel.schema.json +67 -0
  5. package/index.d.ts +822 -38
  6. package/index.js +5 -3
  7. package/package.json +10 -8
  8. package/rescript.json +5 -9
  9. package/src/Address.res +4 -5
  10. package/src/Address.res.mjs +9 -12
  11. package/src/Api.res +15 -0
  12. package/src/Api.res.mjs +20 -0
  13. package/src/Batch.res +32 -34
  14. package/src/Batch.res.mjs +172 -187
  15. package/src/Bin.res +89 -0
  16. package/src/Bin.res.mjs +97 -0
  17. package/src/ChainFetcher.res +33 -57
  18. package/src/ChainFetcher.res.mjs +197 -227
  19. package/src/ChainManager.res +6 -14
  20. package/src/ChainManager.res.mjs +74 -85
  21. package/src/ChainMap.res +14 -16
  22. package/src/ChainMap.res.mjs +38 -38
  23. package/src/Config.res +193 -135
  24. package/src/Config.res.mjs +566 -592
  25. package/src/Core.res +182 -0
  26. package/src/Core.res.mjs +207 -0
  27. package/src/Ecosystem.res +25 -4
  28. package/src/Ecosystem.res.mjs +12 -13
  29. package/src/Env.res +20 -13
  30. package/src/Env.res.mjs +124 -113
  31. package/src/EnvSafe.res +269 -0
  32. package/src/EnvSafe.res.mjs +296 -0
  33. package/src/EnvSafe.resi +18 -0
  34. package/src/Envio.res +37 -26
  35. package/src/Envio.res.mjs +59 -60
  36. package/src/ErrorHandling.res +2 -2
  37. package/src/ErrorHandling.res.mjs +15 -15
  38. package/src/EventConfigBuilder.res +219 -81
  39. package/src/EventConfigBuilder.res.mjs +259 -202
  40. package/src/EventProcessing.res +27 -38
  41. package/src/EventProcessing.res.mjs +165 -183
  42. package/src/EventUtils.res +11 -11
  43. package/src/EventUtils.res.mjs +21 -22
  44. package/src/EvmTypes.res +0 -1
  45. package/src/EvmTypes.res.mjs +5 -5
  46. package/src/FetchState.res +360 -256
  47. package/src/FetchState.res.mjs +958 -914
  48. package/src/GlobalState.res +365 -351
  49. package/src/GlobalState.res.mjs +958 -992
  50. package/src/GlobalStateManager.res +1 -2
  51. package/src/GlobalStateManager.res.mjs +36 -44
  52. package/src/HandlerLoader.res +107 -23
  53. package/src/HandlerLoader.res.mjs +128 -38
  54. package/src/HandlerRegister.res +127 -103
  55. package/src/HandlerRegister.res.mjs +164 -164
  56. package/src/HandlerRegister.resi +12 -4
  57. package/src/Hasura.res +35 -22
  58. package/src/Hasura.res.mjs +158 -167
  59. package/src/InMemoryStore.res +20 -27
  60. package/src/InMemoryStore.res.mjs +64 -80
  61. package/src/InMemoryTable.res +34 -39
  62. package/src/InMemoryTable.res.mjs +165 -170
  63. package/src/Internal.res +52 -33
  64. package/src/Internal.res.mjs +84 -81
  65. package/src/LazyLoader.res.mjs +55 -61
  66. package/src/LoadLayer.res +77 -78
  67. package/src/LoadLayer.res.mjs +160 -189
  68. package/src/LoadManager.res +16 -21
  69. package/src/LoadManager.res.mjs +79 -84
  70. package/src/LogSelection.res +236 -68
  71. package/src/LogSelection.res.mjs +211 -141
  72. package/src/Logging.res +13 -9
  73. package/src/Logging.res.mjs +130 -143
  74. package/src/Main.res +430 -51
  75. package/src/Main.res.mjs +530 -271
  76. package/src/Persistence.res +80 -84
  77. package/src/Persistence.res.mjs +131 -132
  78. package/src/PgStorage.res +294 -167
  79. package/src/PgStorage.res.mjs +799 -817
  80. package/src/Prometheus.res +50 -58
  81. package/src/Prometheus.res.mjs +345 -373
  82. package/src/ReorgDetection.res +22 -24
  83. package/src/ReorgDetection.res.mjs +100 -106
  84. package/src/SafeCheckpointTracking.res +7 -7
  85. package/src/SafeCheckpointTracking.res.mjs +40 -43
  86. package/src/SimulateItems.res +41 -49
  87. package/src/SimulateItems.res.mjs +257 -272
  88. package/src/Sink.res +2 -2
  89. package/src/Sink.res.mjs +22 -26
  90. package/src/TableIndices.res +1 -2
  91. package/src/TableIndices.res.mjs +42 -48
  92. package/src/TestIndexer.res +196 -189
  93. package/src/TestIndexer.res.mjs +536 -536
  94. package/src/TestIndexerProxyStorage.res +16 -16
  95. package/src/TestIndexerProxyStorage.res.mjs +99 -122
  96. package/src/TestIndexerWorker.res +4 -0
  97. package/src/TestIndexerWorker.res.mjs +7 -0
  98. package/src/Throttler.res +3 -3
  99. package/src/Throttler.res.mjs +23 -24
  100. package/src/Time.res +1 -1
  101. package/src/Time.res.mjs +18 -21
  102. package/src/TopicFilter.res +3 -3
  103. package/src/TopicFilter.res.mjs +29 -30
  104. package/src/UserContext.res +93 -54
  105. package/src/UserContext.res.mjs +197 -182
  106. package/src/Utils.res +141 -86
  107. package/src/Utils.res.mjs +334 -295
  108. package/src/bindings/BigDecimal.res +0 -2
  109. package/src/bindings/BigDecimal.res.mjs +19 -23
  110. package/src/bindings/ClickHouse.res +28 -27
  111. package/src/bindings/ClickHouse.res.mjs +243 -240
  112. package/src/bindings/DateFns.res +11 -11
  113. package/src/bindings/DateFns.res.mjs +7 -7
  114. package/src/bindings/EventSource.res.mjs +2 -2
  115. package/src/bindings/Express.res +2 -5
  116. package/src/bindings/Hrtime.res +2 -2
  117. package/src/bindings/Hrtime.res.mjs +30 -32
  118. package/src/bindings/Lodash.res.mjs +1 -1
  119. package/src/bindings/NodeJs.res +14 -9
  120. package/src/bindings/NodeJs.res.mjs +20 -20
  121. package/src/bindings/Pino.res +8 -10
  122. package/src/bindings/Pino.res.mjs +40 -43
  123. package/src/bindings/Postgres.res +7 -5
  124. package/src/bindings/Postgres.res.mjs +9 -9
  125. package/src/bindings/PromClient.res +17 -2
  126. package/src/bindings/PromClient.res.mjs +30 -7
  127. package/src/bindings/SDSL.res.mjs +2 -2
  128. package/src/bindings/Viem.res +4 -4
  129. package/src/bindings/Viem.res.mjs +20 -22
  130. package/src/bindings/Vitest.res +1 -1
  131. package/src/bindings/Vitest.res.mjs +2 -2
  132. package/src/bindings/WebSocket.res +1 -1
  133. package/src/db/EntityHistory.res +9 -3
  134. package/src/db/EntityHistory.res.mjs +84 -59
  135. package/src/db/InternalTable.res +62 -60
  136. package/src/db/InternalTable.res.mjs +271 -203
  137. package/src/db/Schema.res +1 -2
  138. package/src/db/Schema.res.mjs +28 -32
  139. package/src/db/Table.res +28 -27
  140. package/src/db/Table.res.mjs +276 -292
  141. package/src/sources/EventRouter.res +21 -16
  142. package/src/sources/EventRouter.res.mjs +55 -57
  143. package/src/sources/Evm.res +17 -1
  144. package/src/sources/Evm.res.mjs +16 -8
  145. package/src/sources/EvmChain.res +15 -17
  146. package/src/sources/EvmChain.res.mjs +40 -42
  147. package/src/sources/Fuel.res +14 -1
  148. package/src/sources/Fuel.res.mjs +16 -8
  149. package/src/sources/FuelSDK.res +1 -1
  150. package/src/sources/FuelSDK.res.mjs +6 -8
  151. package/src/sources/HyperFuel.res +8 -10
  152. package/src/sources/HyperFuel.res.mjs +113 -123
  153. package/src/sources/HyperFuelClient.res.mjs +6 -7
  154. package/src/sources/HyperFuelSource.res +19 -20
  155. package/src/sources/HyperFuelSource.res.mjs +339 -356
  156. package/src/sources/HyperSync.res +11 -13
  157. package/src/sources/HyperSync.res.mjs +206 -220
  158. package/src/sources/HyperSyncClient.res +5 -7
  159. package/src/sources/HyperSyncClient.res.mjs +70 -75
  160. package/src/sources/HyperSyncHeightStream.res +8 -9
  161. package/src/sources/HyperSyncHeightStream.res.mjs +78 -86
  162. package/src/sources/HyperSyncJsonApi.res +18 -15
  163. package/src/sources/HyperSyncJsonApi.res.mjs +201 -231
  164. package/src/sources/HyperSyncSource.res +17 -21
  165. package/src/sources/HyperSyncSource.res.mjs +268 -290
  166. package/src/sources/Rpc.res +5 -5
  167. package/src/sources/Rpc.res.mjs +168 -192
  168. package/src/sources/RpcSource.res +166 -167
  169. package/src/sources/RpcSource.res.mjs +972 -1046
  170. package/src/sources/RpcWebSocketHeightStream.res +10 -11
  171. package/src/sources/RpcWebSocketHeightStream.res.mjs +131 -145
  172. package/src/sources/SimulateSource.res +1 -1
  173. package/src/sources/SimulateSource.res.mjs +35 -38
  174. package/src/sources/Source.res +1 -1
  175. package/src/sources/Source.res.mjs +3 -3
  176. package/src/sources/SourceManager.res +39 -20
  177. package/src/sources/SourceManager.res.mjs +340 -371
  178. package/src/sources/SourceManager.resi +2 -1
  179. package/src/sources/Svm.res +12 -5
  180. package/src/sources/Svm.res.mjs +44 -41
  181. package/src/tui/Tui.res +23 -12
  182. package/src/tui/Tui.res.mjs +292 -290
  183. package/src/tui/bindings/Ink.res +2 -4
  184. package/src/tui/bindings/Ink.res.mjs +35 -41
  185. package/src/tui/components/BufferedProgressBar.res +7 -7
  186. package/src/tui/components/BufferedProgressBar.res.mjs +46 -46
  187. package/src/tui/components/CustomHooks.res +1 -2
  188. package/src/tui/components/CustomHooks.res.mjs +102 -122
  189. package/src/tui/components/Messages.res +1 -2
  190. package/src/tui/components/Messages.res.mjs +38 -42
  191. package/src/tui/components/SyncETA.res +10 -11
  192. package/src/tui/components/SyncETA.res.mjs +178 -196
  193. package/src/tui/components/TuiData.res +1 -1
  194. package/src/tui/components/TuiData.res.mjs +7 -6
  195. package/src/vendored/Rest.res +52 -66
  196. package/src/vendored/Rest.res.mjs +324 -364
  197. package/svm.schema.json +67 -0
  198. package/src/Address.gen.ts +0 -8
  199. package/src/Config.gen.ts +0 -19
  200. package/src/Envio.gen.ts +0 -55
  201. package/src/EvmTypes.gen.ts +0 -6
  202. package/src/InMemoryStore.gen.ts +0 -6
  203. package/src/Internal.gen.ts +0 -64
  204. package/src/PgStorage.gen.ts +0 -10
  205. package/src/PgStorage.res.d.mts +0 -5
  206. package/src/Types.ts +0 -56
  207. package/src/bindings/BigDecimal.gen.ts +0 -14
  208. package/src/bindings/BigDecimal.res.d.mts +0 -5
  209. package/src/bindings/BigInt.gen.ts +0 -10
  210. package/src/bindings/BigInt.res +0 -70
  211. package/src/bindings/BigInt.res.d.mts +0 -5
  212. package/src/bindings/BigInt.res.mjs +0 -154
  213. package/src/bindings/Ethers.res.d.mts +0 -5
  214. package/src/bindings/Pino.gen.ts +0 -17
  215. package/src/bindings/Postgres.gen.ts +0 -8
  216. package/src/bindings/Postgres.res.d.mts +0 -5
  217. package/src/bindings/Promise.res +0 -67
  218. package/src/bindings/Promise.res.mjs +0 -26
  219. package/src/db/InternalTable.gen.ts +0 -36
  220. package/src/sources/HyperSyncClient.gen.ts +0 -19
@@ -15,6 +15,7 @@ let make: (
15
15
  ~newBlockStallTimeout: int=?,
16
16
  ~newBlockStallTimeoutLive: int=?,
17
17
  ~stalledPollingInterval: int=?,
18
+ ~reducedPollingInterval: int=?,
18
19
  ~recoveryTimeout: float=?,
19
20
  ~getHeightRetryInterval: (~retry: int) => int=?,
20
21
  ) => t
@@ -30,7 +31,7 @@ let fetchNext: (
30
31
  ~stateId: int,
31
32
  ) => promise<unit>
32
33
 
33
- let waitForNewBlock: (t, ~knownHeight: int, ~isLive: bool) => promise<int>
34
+ let waitForNewBlock: (t, ~knownHeight: int, ~isLive: bool, ~reducedPolling: bool) => promise<int>
34
35
 
35
36
  let executeQuery: (
36
37
  t,
@@ -2,7 +2,7 @@
2
2
  @get external getTimestamp: Internal.eventBlock => int = "time"
3
3
  @get external getId: Internal.eventBlock => string = "hash"
4
4
 
5
- let cleanUpRawEventFieldsInPlace: Js.Json.t => unit = %raw(`fields => {
5
+ let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
6
6
  delete fields.hash
7
7
  delete fields.height
8
8
  delete fields.time
@@ -19,6 +19,13 @@ let ecosystem: Ecosystem.t = {
19
19
  getTimestamp,
20
20
  getId,
21
21
  cleanUpRawEventFieldsInPlace,
22
+ onBlockMethodName: "onSlot",
23
+ // SVM filter shape: `{slot: {_gte?, _lte?, _every?}}`.
24
+ // Inner range chunk parsed by `blockRangeSchema` in `Main.res`.
25
+ onBlockFilterSchema: S.object(s => s.field("slot", S.option(S.unknown))),
26
+ // SVM has no event handlers, so there is no `onEvent` `where` value to
27
+ // parse. The schema is a no-op object that always surfaces `None`.
28
+ onEventBlockFilterSchema: S.object(_ => None),
22
29
  }
23
30
 
24
31
  module GetFinalizedSlot = {
@@ -38,7 +45,7 @@ let makeRPCSource = (~chain, ~rpc: string): Source.t => {
38
45
 
39
46
  let urlHost = switch Utils.Url.getHostFromUrl(rpc) {
40
47
  | None =>
41
- Js.Exn.raiseError(
48
+ JsError.throwWithMessage(
42
49
  `The RPC url for chain ${chainId->Belt.Int.toString} is in incorrect format. The RPC url needs to start with either http:// or https://`,
43
50
  )
44
51
  | Some(host) => host
@@ -52,7 +59,7 @@ let makeRPCSource = (~chain, ~rpc: string): Source.t => {
52
59
  poweredByHyperSync: false,
53
60
  pollingInterval: 10_000,
54
61
  getBlockHashes: (~blockNumbers as _, ~logger as _) =>
55
- Js.Exn.raiseError("Svm does not support getting block hashes"),
62
+ JsError.throwWithMessage("Svm does not support getting block hashes"),
56
63
  getHeightOrThrow: async () => {
57
64
  let timerRef = Hrtime.makeTimer()
58
65
  let height = await GetFinalizedSlot.route->Rest.fetch((), ~client)
@@ -70,12 +77,12 @@ let makeRPCSource = (~chain, ~rpc: string): Source.t => {
70
77
  ~fromBlock as _,
71
78
  ~toBlock as _,
72
79
  ~addressesByContractName as _,
73
- ~indexingContracts as _,
80
+ ~indexingAddresses as _,
74
81
  ~knownHeight as _,
75
82
  ~partitionId as _,
76
83
  ~selection as _,
77
84
  ~retry as _,
78
85
  ~logger as _,
79
- ) => Js.Exn.raiseError("Svm does not support getting items"),
86
+ ) => JsError.throwWithMessage("Svm does not support getting items"),
80
87
  }
81
88
  }
@@ -4,19 +4,19 @@ import * as Rpc from "./Rpc.res.mjs";
4
4
  import * as Rest from "../vendored/Rest.res.mjs";
5
5
  import * as Utils from "../Utils.res.mjs";
6
6
  import * as Hrtime from "../bindings/Hrtime.res.mjs";
7
- import * as Js_exn from "rescript/lib/es6/js_exn.js";
8
7
  import * as Prometheus from "../Prometheus.res.mjs";
8
+ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
9
9
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
10
10
 
11
- var cleanUpRawEventFieldsInPlace = (fields => {
11
+ let cleanUpRawEventFieldsInPlace = (fields => {
12
12
  delete fields.hash
13
13
  delete fields.height
14
14
  delete fields.time
15
15
  });
16
16
 
17
- var ecosystem_blockFields = ["slot"];
17
+ let ecosystem_blockFields = ["slot"];
18
18
 
19
- var ecosystem_transactionFields = [];
19
+ let ecosystem_transactionFields = [];
20
20
 
21
21
  function ecosystem_getNumber(prim) {
22
22
  return prim.height;
@@ -30,7 +30,11 @@ function ecosystem_getId(prim) {
30
30
  return prim.hash;
31
31
  }
32
32
 
33
- var ecosystem = {
33
+ let ecosystem_onBlockFilterSchema = S$RescriptSchema.object(s => s.f("slot", S$RescriptSchema.option(S$RescriptSchema.unknown)));
34
+
35
+ let ecosystem_onEventBlockFilterSchema = S$RescriptSchema.object(param => {});
36
+
37
+ let ecosystem = {
34
38
  name: "svm",
35
39
  blockFields: ecosystem_blockFields,
36
40
  transactionFields: ecosystem_transactionFields,
@@ -40,51 +44,50 @@ var ecosystem = {
40
44
  getNumber: ecosystem_getNumber,
41
45
  getTimestamp: ecosystem_getTimestamp,
42
46
  getId: ecosystem_getId,
43
- cleanUpRawEventFieldsInPlace: cleanUpRawEventFieldsInPlace
47
+ cleanUpRawEventFieldsInPlace: cleanUpRawEventFieldsInPlace,
48
+ onBlockMethodName: "onSlot",
49
+ onBlockFilterSchema: ecosystem_onBlockFilterSchema,
50
+ onEventBlockFilterSchema: ecosystem_onEventBlockFilterSchema
44
51
  };
45
52
 
46
- var route = Rpc.makeRpcRoute("getSlot", S$RescriptSchema.tuple(function (s) {
47
- s.tag(0, {
48
- commitment: "finalized"
49
- });
50
- }), S$RescriptSchema.$$int);
53
+ let route = Rpc.makeRpcRoute("getSlot", S$RescriptSchema.tuple(s => {
54
+ s.tag(0, {
55
+ commitment: "finalized"
56
+ });
57
+ }), S$RescriptSchema.int);
51
58
 
52
- var GetFinalizedSlot = {
59
+ let GetFinalizedSlot = {
53
60
  route: route
54
61
  };
55
62
 
56
63
  function makeRPCSource(chain, rpc) {
57
- var client = Rest.client(rpc, undefined);
58
- var host = Utils.Url.getHostFromUrl(rpc);
59
- var urlHost = host !== undefined ? host : Js_exn.raiseError("The RPC url for chain " + String(chain) + " is in incorrect format. The RPC url needs to start with either http:// or https://");
60
- var name = "RPC (" + urlHost + ")";
64
+ let client = Rest.client(rpc, undefined);
65
+ let host = Utils.Url.getHostFromUrl(rpc);
66
+ let urlHost = host !== undefined ? host : Stdlib_JsError.throwWithMessage(`The RPC url for chain ` + String(chain) + ` is in incorrect format. The RPC url needs to start with either http:// or https://`);
67
+ let name = `RPC (` + urlHost + `)`;
61
68
  return {
62
- name: name,
63
- sourceFor: "Sync",
64
- chain: chain,
65
- poweredByHyperSync: false,
66
- pollingInterval: 10000,
67
- getBlockHashes: (function (param, param$1) {
68
- return Js_exn.raiseError("Svm does not support getting block hashes");
69
- }),
70
- getHeightOrThrow: (async function () {
71
- var timerRef = Hrtime.makeTimer();
72
- var height = await Rest.$$fetch(route, undefined, client);
73
- var seconds = Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef));
74
- Prometheus.SourceRequestCount.increment(name, chain, "getSlot");
75
- Prometheus.SourceRequestCount.addSeconds(name, chain, "getSlot", seconds);
76
- return height;
77
- }),
78
- getItemsOrThrow: (function (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) {
79
- return Js_exn.raiseError("Svm does not support getting items");
80
- })
81
- };
69
+ name: name,
70
+ sourceFor: "Sync",
71
+ chain: chain,
72
+ poweredByHyperSync: false,
73
+ pollingInterval: 10000,
74
+ getBlockHashes: (param, param$1) => Stdlib_JsError.throwWithMessage("Svm does not support getting block hashes"),
75
+ getHeightOrThrow: async () => {
76
+ let timerRef = Hrtime.makeTimer();
77
+ let height = await Rest.fetch(route, undefined, client);
78
+ let seconds = Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef));
79
+ Prometheus.SourceRequestCount.increment(name, chain, "getSlot");
80
+ Prometheus.SourceRequestCount.addSeconds(name, chain, "getSlot", seconds);
81
+ return height;
82
+ },
83
+ getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
84
+ };
82
85
  }
83
86
 
84
87
  export {
85
- cleanUpRawEventFieldsInPlace ,
86
- ecosystem ,
87
- GetFinalizedSlot ,
88
- makeRPCSource ,
88
+ cleanUpRawEventFieldsInPlace,
89
+ ecosystem,
90
+ GetFinalizedSlot,
91
+ makeRPCSource,
89
92
  }
90
- /* route Not a pure module */
93
+ /* ecosystem Not a pure module */
package/src/tui/Tui.res CHANGED
@@ -1,5 +1,4 @@
1
1
  open Ink
2
- open Belt
3
2
 
4
3
  module ChainLine = {
5
4
  @react.component
@@ -100,13 +99,13 @@ module App = {
100
99
 
101
100
  // useEffect to refresh state every 500ms
102
101
  React.useEffect(() => {
103
- let intervalId = Js.Global.setInterval(() => {
102
+ let intervalId = setInterval(() => {
104
103
  setState(_ => getState())
105
104
  }, 500)
106
105
 
107
106
  Some(
108
107
  () => {
109
- Js.Global.clearInterval(intervalId)
108
+ clearInterval(intervalId)
110
109
  },
111
110
  )
112
111
  }, [getState])
@@ -120,7 +119,7 @@ module App = {
120
119
  let hasProcessedToEndblock = cf->ChainFetcher.hasProcessedToEndblock
121
120
  let knownHeight =
122
121
  cf->ChainFetcher.hasProcessedToEndblock
123
- ? cf.fetchState.endBlock->Option.getWithDefault(cf.fetchState.knownHeight)
122
+ ? cf.fetchState.endBlock->Option.getOr(cf.fetchState.knownHeight)
124
123
  : cf.fetchState.knownHeight
125
124
 
126
125
  let firstEventBlock = cf.fetchState.firstEventBlock
@@ -130,10 +129,10 @@ module App = {
130
129
  // it's possible there are no events in that block range (ie firstEventBlock = None)
131
130
  // This ensures TUI still displays synced in this case
132
131
  Synced({
133
- firstEventBlockNumber: firstEventBlock->Option.getWithDefault(0),
132
+ firstEventBlockNumber: firstEventBlock->Option.getOr(0),
134
133
  latestProcessedBlock: cf.committedProgressBlockNumber,
135
- timestampCaughtUpToHeadOrEndblock: cf.timestampCaughtUpToHeadOrEndblock->Option.getWithDefault(
136
- Js.Date.now()->Js.Date.fromFloat,
134
+ timestampCaughtUpToHeadOrEndblock: cf.timestampCaughtUpToHeadOrEndblock->Option.getOr(
135
+ Date.now()->Date.fromTime,
137
136
  ),
138
137
  numEventsProcessed,
139
138
  })
@@ -199,7 +198,7 @@ module App = {
199
198
  />
200
199
  <Newline />
201
200
  {chains
202
- ->Array.mapWithIndex((i, chainData) => {
201
+ ->Array.mapWithIndex((chainData, i) => {
203
202
  <ChainLine
204
203
  key={i->Int.toString}
205
204
  chainId={chainData.chainId}
@@ -230,10 +229,22 @@ module App = {
230
229
  }
231
230
  }
232
231
  </Box>
233
- <Box flexDirection={Row}>
234
- <Text> {"Dev Console: "->React.string} </Text>
235
- <Text color={Info} underline=true> {`${Env.envioAppUrl}/console`->React.string} </Text>
236
- </Box>
232
+ {if Envio.isDevMode() {
233
+ <Box flexDirection={Row}>
234
+ <Text> {"Dev Console: "->React.string} </Text>
235
+ <Text color={Info} underline=true> {`${Env.envioAppUrl}/console`->React.string} </Text>
236
+ </Box>
237
+ } else {
238
+ React.null
239
+ }}
240
+ {switch (state.ctx.config.storage.clickhouse, Env.ClickHouse.host()) {
241
+ | (true, Some(host)) =>
242
+ <Box flexDirection={Row}>
243
+ <Text> {"ClickHouse: "->React.string} </Text>
244
+ <Text color={Info} underline=true> {`${host}/play`->React.string} </Text>
245
+ </Box>
246
+ | _ => React.null
247
+ }}
237
248
  <Messages config=state.ctx.config />
238
249
  </Box>
239
250
  }