envio 3.2.1 → 3.3.0-alpha.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.
Files changed (106) hide show
  1. package/package.json +6 -7
  2. package/src/Batch.res +12 -15
  3. package/src/Batch.res.mjs +4 -5
  4. package/src/BatchProcessing.res +199 -0
  5. package/src/BatchProcessing.res.mjs +125 -0
  6. package/src/ChainFetching.res +373 -0
  7. package/src/ChainFetching.res.mjs +206 -0
  8. package/src/ChainMetadata.res +27 -0
  9. package/src/ChainMetadata.res.mjs +27 -0
  10. package/src/ChainState.res +643 -0
  11. package/src/ChainState.res.mjs +476 -0
  12. package/src/ChainState.resi +87 -0
  13. package/src/Config.res +13 -4
  14. package/src/Config.res.mjs +8 -3
  15. package/src/ContractRegisterContext.res +106 -0
  16. package/src/ContractRegisterContext.res.mjs +76 -0
  17. package/src/Core.res +3 -0
  18. package/src/CrossChainState.res +294 -0
  19. package/src/CrossChainState.res.mjs +221 -0
  20. package/src/CrossChainState.resi +39 -0
  21. package/src/Ecosystem.res +58 -0
  22. package/src/Ecosystem.res.mjs +43 -1
  23. package/src/Env.res +0 -2
  24. package/src/Env.res.mjs +0 -3
  25. package/src/EventConfigBuilder.res +2 -2
  26. package/src/EventProcessing.res +60 -46
  27. package/src/EventProcessing.res.mjs +33 -32
  28. package/src/EventUtils.res +0 -4
  29. package/src/EventUtils.res.mjs +0 -4
  30. package/src/ExitOnCaughtUp.res +10 -0
  31. package/src/ExitOnCaughtUp.res.mjs +22 -0
  32. package/src/FetchState.res +205 -73
  33. package/src/FetchState.res.mjs +242 -103
  34. package/src/InMemoryStore.res +36 -451
  35. package/src/InMemoryStore.res.mjs +20 -369
  36. package/src/IndexerLoop.res +43 -0
  37. package/src/IndexerLoop.res.mjs +46 -0
  38. package/src/IndexerState.res +536 -0
  39. package/src/IndexerState.res.mjs +543 -0
  40. package/src/IndexerState.resi +128 -0
  41. package/src/Internal.res +29 -8
  42. package/src/LoadLayer.res +20 -18
  43. package/src/LoadLayer.res.mjs +14 -12
  44. package/src/LoadLayer.resi +6 -3
  45. package/src/Logging.res +11 -44
  46. package/src/Logging.res.mjs +10 -42
  47. package/src/Main.res +54 -79
  48. package/src/Main.res.mjs +44 -56
  49. package/src/PgStorage.res +8 -71
  50. package/src/PgStorage.res.mjs +3 -47
  51. package/src/Prometheus.res +1 -13
  52. package/src/Prometheus.res.mjs +84 -96
  53. package/src/PruneStaleHistory.res +45 -0
  54. package/src/PruneStaleHistory.res.mjs +46 -0
  55. package/src/RawEvent.res +73 -0
  56. package/src/RawEvent.res.mjs +51 -0
  57. package/src/Rollback.res +204 -0
  58. package/src/Rollback.res.mjs +118 -0
  59. package/src/SimulateItems.res +12 -10
  60. package/src/SimulateItems.res.mjs +1 -1
  61. package/src/UserContext.res +26 -114
  62. package/src/UserContext.res.mjs +15 -78
  63. package/src/Writing.res +242 -0
  64. package/src/Writing.res.mjs +215 -0
  65. package/src/db/InternalTable.res +14 -27
  66. package/src/sources/Evm.res +40 -1
  67. package/src/sources/Evm.res.mjs +94 -84
  68. package/src/sources/Fuel.res +40 -1
  69. package/src/sources/Fuel.res.mjs +36 -26
  70. package/src/sources/HyperFuel.res +41 -120
  71. package/src/sources/HyperFuel.res.mjs +42 -80
  72. package/src/sources/HyperFuel.resi +1 -24
  73. package/src/sources/HyperFuelClient.res +16 -297
  74. package/src/sources/HyperFuelClient.res.mjs +5 -4
  75. package/src/sources/HyperFuelSource.res +33 -8
  76. package/src/sources/HyperFuelSource.res.mjs +56 -10
  77. package/src/sources/HyperSyncSource.res +5 -3
  78. package/src/sources/HyperSyncSource.res.mjs +1 -1
  79. package/src/sources/RpcSource.res +2 -2
  80. package/src/sources/RpcSource.res.mjs +1 -1
  81. package/src/sources/SourceManager.res +14 -23
  82. package/src/sources/SourceManager.res.mjs +27 -29
  83. package/src/sources/SourceManager.resi +4 -2
  84. package/src/sources/Svm.res +18 -1
  85. package/src/sources/Svm.res.mjs +30 -22
  86. package/src/sources/SvmHyperSyncSource.res +1 -1
  87. package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
  88. package/src/tui/Tui.res +38 -36
  89. package/src/tui/Tui.res.mjs +51 -51
  90. package/src/ChainFetcher.res +0 -519
  91. package/src/ChainFetcher.res.mjs +0 -314
  92. package/src/ChainManager.res +0 -358
  93. package/src/ChainManager.res.mjs +0 -291
  94. package/src/Ctx.res +0 -6
  95. package/src/Ctx.res.mjs +0 -2
  96. package/src/GlobalState.res +0 -1056
  97. package/src/GlobalState.res.mjs +0 -1086
  98. package/src/GlobalStateManager.res +0 -57
  99. package/src/GlobalStateManager.res.mjs +0 -68
  100. package/src/GlobalStateManager.resi +0 -7
  101. package/src/Ports.res +0 -5
  102. package/src/Ports.res.mjs +0 -9
  103. package/src/adapters/MarkBatchProcessedAdapter.res +0 -5
  104. package/src/adapters/MarkBatchProcessedAdapter.res.mjs +0 -14
  105. package/src/sources/EnvioApiClient.res +0 -15
  106. package/src/sources/EnvioApiClient.res.mjs +0 -24
package/src/tui/Tui.res CHANGED
@@ -134,11 +134,11 @@ module App = {
134
134
  @react.component
135
135
  let make = (~getState) => {
136
136
  let stdoutColumns = Hooks.useStdoutColumns()
137
- // GlobalState is mutated in place — passing the same ref to useState
137
+ // IndexerState is mutated in place — passing the same ref to useState
138
138
  // would bail out via Object.is and skip the re-render. Tick a counter
139
139
  // instead and read state freshly from getState() on every render.
140
140
  let (tick, setTick) = React.useState(() => 0)
141
- let state: GlobalState.t = getState()
141
+ let state: IndexerState.t = getState()
142
142
 
143
143
  React.useEffect(() => {
144
144
  let intervalId = setInterval(() => {
@@ -153,18 +153,22 @@ module App = {
153
153
  }, [getState])
154
154
 
155
155
  let chains =
156
- state.chainManager.chainFetchers
157
- ->ChainMap.values
158
- ->Array.map(cf => {
159
- let {numEventsProcessed, fetchState} = cf
156
+ state
157
+ ->IndexerState.chainStates
158
+ ->Dict.valuesToArray
159
+ ->Array.map(cs => {
160
+ let numEventsProcessed = cs->ChainState.numEventsProcessed
161
+ let fetchState = cs->ChainState.fetchState
162
+ let committedProgressBlockNumber = cs->ChainState.committedProgressBlockNumber
163
+ let timestampCaughtUpToHeadOrEndblock = cs->ChainState.timestampCaughtUpToHeadOrEndblock
164
+ let sourceManager = cs->ChainState.sourceManager
160
165
  let latestFetchedBlockNumber = Pervasives.max(fetchState->FetchState.bufferBlockNumber, 0)
161
- let hasProcessedToEndblock = cf->ChainFetcher.hasProcessedToEndblock
162
- let knownHeight =
163
- cf->ChainFetcher.hasProcessedToEndblock
164
- ? cf.fetchState.endBlock->Option.getOr(cf.fetchState.knownHeight)
165
- : cf.fetchState.knownHeight
166
+ let hasProcessedToEndblock = cs->ChainState.hasProcessedToEndblock
167
+ let knownHeight = hasProcessedToEndblock
168
+ ? fetchState.endBlock->Option.getOr(fetchState.knownHeight)
169
+ : fetchState.knownHeight
166
170
 
167
- let firstEventBlock = cf.fetchState.firstEventBlock
171
+ let firstEventBlock = fetchState.firstEventBlock
168
172
  let progress: TuiData.progress = if hasProcessedToEndblock {
169
173
  // If the endblock has been reached then set the progress to synced.
170
174
  // if there's chains that have no events in the block range start->end,
@@ -172,25 +176,25 @@ module App = {
172
176
  // This ensures TUI still displays synced in this case
173
177
  Synced({
174
178
  firstEventBlockNumber: firstEventBlock->Option.getOr(0),
175
- latestProcessedBlock: cf.committedProgressBlockNumber,
176
- timestampCaughtUpToHeadOrEndblock: cf.timestampCaughtUpToHeadOrEndblock->Option.getOr(
179
+ latestProcessedBlock: committedProgressBlockNumber,
180
+ timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock->Option.getOr(
177
181
  Date.now()->Date.fromTime,
178
182
  ),
179
183
  numEventsProcessed,
180
184
  })
181
185
  } else {
182
- switch (firstEventBlock, cf.timestampCaughtUpToHeadOrEndblock) {
186
+ switch (firstEventBlock, timestampCaughtUpToHeadOrEndblock) {
183
187
  | (Some(firstEventBlockNumber), Some(timestampCaughtUpToHeadOrEndblock)) =>
184
188
  Synced({
185
189
  firstEventBlockNumber,
186
- latestProcessedBlock: cf.committedProgressBlockNumber,
190
+ latestProcessedBlock: committedProgressBlockNumber,
187
191
  timestampCaughtUpToHeadOrEndblock,
188
192
  numEventsProcessed,
189
193
  })
190
194
  | (Some(firstEventBlockNumber), None) =>
191
195
  Syncing({
192
196
  firstEventBlockNumber,
193
- latestProcessedBlock: cf.committedProgressBlockNumber,
197
+ latestProcessedBlock: committedProgressBlockNumber,
194
198
  numEventsProcessed,
195
199
  })
196
200
  | (None, _) => SearchingForEvents
@@ -203,25 +207,23 @@ module App = {
203
207
  knownHeight,
204
208
  latestFetchedBlockNumber,
205
209
  eventsProcessed: numEventsProcessed,
206
- chainId: cf.chainConfig.id->Int.toString,
207
- progressBlock: cf.committedProgressBlockNumber < cf.fetchState.startBlock
208
- ? Some(cf.fetchState.startBlock)
209
- : Some(cf.committedProgressBlockNumber),
210
+ chainId: (cs->ChainState.chainConfig).id->Int.toString,
211
+ progressBlock: committedProgressBlockNumber < fetchState.startBlock
212
+ ? Some(fetchState.startBlock)
213
+ : Some(committedProgressBlockNumber),
210
214
  bufferBlock: Some(latestFetchedBlockNumber),
211
- sourceBlock: Some(cf.fetchState.knownHeight),
212
- firstEventBlockNumber: cf.fetchState.firstEventBlock,
213
- startBlock: cf.fetchState.startBlock,
214
- endBlock: cf.fetchState.endBlock,
215
- poweredByHyperSync: (
216
- cf.sourceManager->SourceManager.getActiveSource
217
- ).poweredByHyperSync,
218
- blockUnit: switch state.ctx.config.ecosystem.name {
215
+ sourceBlock: Some(fetchState.knownHeight),
216
+ firstEventBlockNumber: fetchState.firstEventBlock,
217
+ startBlock: fetchState.startBlock,
218
+ endBlock: fetchState.endBlock,
219
+ poweredByHyperSync: (sourceManager->SourceManager.getActiveSource).poweredByHyperSync,
220
+ blockUnit: switch (state->IndexerState.config).ecosystem.name {
219
221
  | Svm => "Slot"
220
222
  | Evm | Fuel => "Block"
221
223
  },
222
- rateLimitTimeMs: cf.sourceManager->SourceManager.getRateLimitTimeMs,
223
- isRateLimited: cf.sourceManager->SourceManager.isRateLimited,
224
- rateLimitResetInMs: cf.sourceManager->SourceManager.getRateLimitResetInMs,
224
+ rateLimitTimeMs: sourceManager->SourceManager.getRateLimitTimeMs,
225
+ isRateLimited: sourceManager->SourceManager.isRateLimited,
226
+ rateLimitResetInMs: sourceManager->SourceManager.getRateLimitResetInMs,
225
227
  }: TuiData.chain
226
228
  )
227
229
  })
@@ -269,7 +271,7 @@ module App = {
269
271
  totalEventsProcessed
270
272
  eventsPerSecond={SyncETA.isIndexerFullySynced(chains) ? None : eventsPerSecond}
271
273
  />
272
- <SyncETA chains indexerStartTime=state.indexerStartTime />
274
+ <SyncETA chains indexerStartTime={state->IndexerState.indexerStartTime} />
273
275
  {
274
276
  let maxRateLimitTimeMs =
275
277
  chains->Array.reduce(0., (acc, chain) => Pervasives.max(acc, chain.rateLimitTimeMs))
@@ -315,7 +317,7 @@ module App = {
315
317
  }
316
318
  }
317
319
  </Box>
318
- {if state.ctx.config.isDev {
320
+ {if (state->IndexerState.config).isDev {
319
321
  <Box flexDirection={Row}>
320
322
  <Text> {"Dev Console: "->React.string} </Text>
321
323
  <Text color={Info} underline=true> {`${Env.envioAppUrl}/console`->React.string} </Text>
@@ -323,7 +325,7 @@ module App = {
323
325
  } else {
324
326
  React.null
325
327
  }}
326
- {switch (state.ctx.config.storage.clickhouse, Env.ClickHouse.host()) {
328
+ {switch ((state->IndexerState.config).storage.clickhouse, Env.ClickHouse.host()) {
327
329
  | (true, Some(host)) =>
328
330
  <Box flexDirection={Row}>
329
331
  <Text> {"ClickHouse: "->React.string} </Text>
@@ -331,7 +333,7 @@ module App = {
331
333
  </Box>
332
334
  | _ => React.null
333
335
  }}
334
- <Messages config=state.ctx.config />
336
+ <Messages config={state->IndexerState.config} />
335
337
  </Box>
336
338
  }
337
339
  }
@@ -6,10 +6,10 @@ import * as Ink$1 from "ink";
6
6
  import * as React from "react";
7
7
  import * as SyncETA from "./components/SyncETA.res.mjs";
8
8
  import * as TuiData from "./components/TuiData.res.mjs";
9
- import * as ChainMap from "../ChainMap.res.mjs";
10
9
  import * as Messages from "./components/Messages.res.mjs";
10
+ import * as ChainState from "../ChainState.res.mjs";
11
11
  import * as FetchState from "../FetchState.res.mjs";
12
- import * as ChainFetcher from "../ChainFetcher.res.mjs";
12
+ import * as IndexerState from "../IndexerState.res.mjs";
13
13
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
14
14
  import InkBigText from "ink-big-text";
15
15
  import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
@@ -207,47 +207,47 @@ function Tui$App(props) {
207
207
  clearInterval(intervalId);
208
208
  };
209
209
  }, [getState]);
210
- let chains = ChainMap.values(state.chainManager.chainFetchers).map(cf => {
211
- let numEventsProcessed = cf.numEventsProcessed;
212
- let latestFetchedBlockNumber = Primitive_int.max(FetchState.bufferBlockNumber(cf.fetchState), 0);
213
- let hasProcessedToEndblock = ChainFetcher.hasProcessedToEndblock(cf);
214
- let knownHeight = ChainFetcher.hasProcessedToEndblock(cf) ? Stdlib_Option.getOr(cf.fetchState.endBlock, cf.fetchState.knownHeight) : cf.fetchState.knownHeight;
215
- let firstEventBlock = cf.fetchState.firstEventBlock;
216
- let progress;
217
- if (hasProcessedToEndblock) {
218
- progress = {
210
+ let chains = Object.values(IndexerState.chainStates(state)).map(cs => {
211
+ let numEventsProcessed = ChainState.numEventsProcessed(cs);
212
+ let fetchState = ChainState.fetchState(cs);
213
+ let committedProgressBlockNumber = ChainState.committedProgressBlockNumber(cs);
214
+ let timestampCaughtUpToHeadOrEndblock = ChainState.timestampCaughtUpToHeadOrEndblock(cs);
215
+ let sourceManager = ChainState.sourceManager(cs);
216
+ let latestFetchedBlockNumber = Primitive_int.max(FetchState.bufferBlockNumber(fetchState), 0);
217
+ let hasProcessedToEndblock = ChainState.hasProcessedToEndblock(cs);
218
+ let knownHeight = hasProcessedToEndblock ? Stdlib_Option.getOr(fetchState.endBlock, fetchState.knownHeight) : fetchState.knownHeight;
219
+ let firstEventBlock = fetchState.firstEventBlock;
220
+ let progress = hasProcessedToEndblock ? ({
219
221
  TAG: "Synced",
220
222
  _0: {
221
223
  firstEventBlockNumber: Stdlib_Option.getOr(firstEventBlock, 0),
222
- latestProcessedBlock: cf.committedProgressBlockNumber,
224
+ latestProcessedBlock: committedProgressBlockNumber,
223
225
  numEventsProcessed: numEventsProcessed,
224
- timestampCaughtUpToHeadOrEndblock: Stdlib_Option.getOr(cf.timestampCaughtUpToHeadOrEndblock, new Date(Date.now()))
226
+ timestampCaughtUpToHeadOrEndblock: Stdlib_Option.getOr(timestampCaughtUpToHeadOrEndblock, new Date(Date.now()))
225
227
  }
226
- };
227
- } else {
228
- let match = cf.timestampCaughtUpToHeadOrEndblock;
229
- progress = firstEventBlock !== undefined ? (
230
- match !== undefined ? ({
231
- TAG: "Synced",
232
- _0: {
233
- firstEventBlockNumber: firstEventBlock,
234
- latestProcessedBlock: cf.committedProgressBlockNumber,
235
- numEventsProcessed: numEventsProcessed,
236
- timestampCaughtUpToHeadOrEndblock: match
237
- }
238
- }) : ({
239
- TAG: "Syncing",
240
- _0: {
241
- firstEventBlockNumber: firstEventBlock,
242
- latestProcessedBlock: cf.committedProgressBlockNumber,
243
- numEventsProcessed: numEventsProcessed
244
- }
245
- })
246
- ) : "SearchingForEvents";
247
- }
248
- let match$1 = state.ctx.config.ecosystem.name;
228
+ }) : (
229
+ firstEventBlock !== undefined ? (
230
+ timestampCaughtUpToHeadOrEndblock !== undefined ? ({
231
+ TAG: "Synced",
232
+ _0: {
233
+ firstEventBlockNumber: firstEventBlock,
234
+ latestProcessedBlock: committedProgressBlockNumber,
235
+ numEventsProcessed: numEventsProcessed,
236
+ timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock
237
+ }
238
+ }) : ({
239
+ TAG: "Syncing",
240
+ _0: {
241
+ firstEventBlockNumber: firstEventBlock,
242
+ latestProcessedBlock: committedProgressBlockNumber,
243
+ numEventsProcessed: numEventsProcessed
244
+ }
245
+ })
246
+ ) : "SearchingForEvents"
247
+ );
248
+ let match = IndexerState.config(state).ecosystem.name;
249
249
  let tmp;
250
- switch (match$1) {
250
+ switch (match) {
251
251
  case "evm" :
252
252
  case "fuel" :
253
253
  tmp = "Block";
@@ -257,22 +257,22 @@ function Tui$App(props) {
257
257
  break;
258
258
  }
259
259
  return {
260
- chainId: cf.chainConfig.id.toString(),
260
+ chainId: ChainState.chainConfig(cs).id.toString(),
261
261
  eventsProcessed: numEventsProcessed,
262
- progressBlock: cf.committedProgressBlockNumber < cf.fetchState.startBlock ? cf.fetchState.startBlock : cf.committedProgressBlockNumber,
262
+ progressBlock: committedProgressBlockNumber < fetchState.startBlock ? fetchState.startBlock : committedProgressBlockNumber,
263
263
  bufferBlock: latestFetchedBlockNumber,
264
- sourceBlock: cf.fetchState.knownHeight,
265
- startBlock: cf.fetchState.startBlock,
266
- endBlock: cf.fetchState.endBlock,
267
- firstEventBlockNumber: cf.fetchState.firstEventBlock,
268
- poweredByHyperSync: SourceManager.getActiveSource(cf.sourceManager).poweredByHyperSync,
264
+ sourceBlock: fetchState.knownHeight,
265
+ startBlock: fetchState.startBlock,
266
+ endBlock: fetchState.endBlock,
267
+ firstEventBlockNumber: fetchState.firstEventBlock,
268
+ poweredByHyperSync: SourceManager.getActiveSource(sourceManager).poweredByHyperSync,
269
269
  progress: progress,
270
270
  latestFetchedBlockNumber: latestFetchedBlockNumber,
271
271
  knownHeight: knownHeight,
272
272
  blockUnit: tmp,
273
- rateLimitTimeMs: SourceManager.getRateLimitTimeMs(cf.sourceManager),
274
- isRateLimited: SourceManager.isRateLimited(cf.sourceManager),
275
- rateLimitResetInMs: SourceManager.getRateLimitResetInMs(cf.sourceManager)
273
+ rateLimitTimeMs: SourceManager.getRateLimitTimeMs(sourceManager),
274
+ isRateLimited: SourceManager.isRateLimited(sourceManager),
275
+ rateLimitResetInMs: SourceManager.getRateLimitResetInMs(sourceManager)
276
276
  };
277
277
  });
278
278
  let totalEventsProcessed = Stdlib_Array.reduce(chains, 0, (acc, chain) => acc + chain.eventsProcessed);
@@ -329,7 +329,7 @@ function Tui$App(props) {
329
329
  tmp = null;
330
330
  }
331
331
  let defaultPassword = "testing";
332
- let match$1 = state.ctx.config.storage.clickhouse;
332
+ let match$1 = IndexerState.config(state).storage.clickhouse;
333
333
  let match$2 = Env.ClickHouse.host();
334
334
  return JsxRuntime.jsxs(Ink$1.Box, {
335
335
  children: [
@@ -362,7 +362,7 @@ function Tui$App(props) {
362
362
  }),
363
363
  JsxRuntime.jsx(SyncETA.make, {
364
364
  chains: chains,
365
- indexerStartTime: state.indexerStartTime
365
+ indexerStartTime: IndexerState.indexerStartTime(state)
366
366
  }),
367
367
  tmp,
368
368
  JsxRuntime.jsx(Ink.Newline.make, {}),
@@ -383,7 +383,7 @@ function Tui$App(props) {
383
383
  ],
384
384
  flexDirection: "row"
385
385
  }),
386
- state.ctx.config.isDev ? JsxRuntime.jsxs(Ink$1.Box, {
386
+ IndexerState.config(state).isDev ? JsxRuntime.jsxs(Ink$1.Box, {
387
387
  children: [
388
388
  JsxRuntime.jsx(Ink$1.Text, {
389
389
  children: "Dev Console: "
@@ -410,7 +410,7 @@ function Tui$App(props) {
410
410
  flexDirection: "row"
411
411
  }) : null,
412
412
  JsxRuntime.jsx(Messages.make, {
413
- config: state.ctx.config
413
+ config: IndexerState.config(state)
414
414
  })
415
415
  ],
416
416
  flexDirection: "column"