envio 3.3.0-alpha.7 → 3.3.0-alpha.9

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 (95) hide show
  1. package/index.d.ts +23 -5
  2. package/package.json +6 -6
  3. package/src/Api.res +1 -1
  4. package/src/Api.res.mjs +1 -1
  5. package/src/ChainFetching.res +21 -10
  6. package/src/ChainFetching.res.mjs +11 -10
  7. package/src/ChainState.res +401 -171
  8. package/src/ChainState.res.mjs +270 -104
  9. package/src/ChainState.resi +19 -7
  10. package/src/Config.res +11 -27
  11. package/src/Config.res.mjs +8 -7
  12. package/src/Core.res +7 -0
  13. package/src/CrossChainState.res +82 -82
  14. package/src/CrossChainState.res.mjs +52 -59
  15. package/src/CrossChainState.resi +1 -1
  16. package/src/Ecosystem.res +3 -3
  17. package/src/Ecosystem.res.mjs +3 -3
  18. package/src/Envio.res +14 -9
  19. package/src/EnvioGlobal.res +53 -0
  20. package/src/EnvioGlobal.res.mjs +31 -0
  21. package/src/EventConfigBuilder.res +117 -69
  22. package/src/EventConfigBuilder.res.mjs +71 -34
  23. package/src/EventProcessing.res +19 -15
  24. package/src/EventProcessing.res.mjs +13 -12
  25. package/src/FetchState.res +410 -185
  26. package/src/FetchState.res.mjs +268 -253
  27. package/src/HandlerLoader.res +8 -113
  28. package/src/HandlerLoader.res.mjs +2 -88
  29. package/src/HandlerRegister.res +518 -144
  30. package/src/HandlerRegister.res.mjs +285 -133
  31. package/src/HandlerRegister.resi +24 -8
  32. package/src/IndexerState.res +6 -3
  33. package/src/IndexerState.res.mjs +3 -3
  34. package/src/IndexerState.resi +1 -1
  35. package/src/IndexingAddresses.res +10 -7
  36. package/src/IndexingAddresses.res.mjs +8 -7
  37. package/src/IndexingAddresses.resi +3 -1
  38. package/src/Internal.res +104 -39
  39. package/src/Internal.res.mjs +11 -1
  40. package/src/LogSelection.res +102 -165
  41. package/src/LogSelection.res.mjs +101 -116
  42. package/src/Main.res +49 -164
  43. package/src/Main.res.mjs +39 -104
  44. package/src/Metrics.res +43 -2
  45. package/src/Metrics.res.mjs +39 -3
  46. package/src/Prometheus.res +0 -35
  47. package/src/Prometheus.res.mjs +33 -68
  48. package/src/RawEvent.res +7 -2
  49. package/src/RawEvent.res.mjs +4 -4
  50. package/src/RollbackCommit.res +4 -1
  51. package/src/RollbackCommit.res.mjs +3 -2
  52. package/src/SimulateItems.res +20 -7
  53. package/src/SimulateItems.res.mjs +7 -11
  54. package/src/TestIndexer.res +1 -1
  55. package/src/TestIndexer.res.mjs +1 -1
  56. package/src/sources/BlockStore.res +46 -0
  57. package/src/sources/BlockStore.res.mjs +24 -0
  58. package/src/sources/EventRouter.res +19 -12
  59. package/src/sources/EventRouter.res.mjs +7 -5
  60. package/src/sources/Evm.res +58 -5
  61. package/src/sources/Evm.res.mjs +44 -5
  62. package/src/sources/EvmChain.res +14 -18
  63. package/src/sources/EvmChain.res.mjs +12 -13
  64. package/src/sources/FieldMask.res +39 -0
  65. package/src/sources/FieldMask.res.mjs +42 -0
  66. package/src/sources/Fuel.res +8 -3
  67. package/src/sources/Fuel.res.mjs +5 -4
  68. package/src/sources/HyperFuelSource.res +31 -40
  69. package/src/sources/HyperFuelSource.res.mjs +52 -44
  70. package/src/sources/HyperSync.res +31 -9
  71. package/src/sources/HyperSync.res.mjs +47 -31
  72. package/src/sources/HyperSync.resi +10 -3
  73. package/src/sources/HyperSyncClient.res +15 -4
  74. package/src/sources/HyperSyncHeightStream.res +1 -8
  75. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  76. package/src/sources/HyperSyncSource.res +58 -90
  77. package/src/sources/HyperSyncSource.res.mjs +57 -66
  78. package/src/sources/RpcSource.res +118 -120
  79. package/src/sources/RpcSource.res.mjs +92 -74
  80. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  81. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  82. package/src/sources/SimulateSource.res +5 -3
  83. package/src/sources/SimulateSource.res.mjs +12 -4
  84. package/src/sources/Source.res +19 -5
  85. package/src/sources/SourceManager.res +60 -10
  86. package/src/sources/SourceManager.res.mjs +54 -8
  87. package/src/sources/SourceManager.resi +10 -0
  88. package/src/sources/Svm.res +14 -10
  89. package/src/sources/Svm.res.mjs +23 -6
  90. package/src/sources/SvmHyperSyncClient.res +5 -6
  91. package/src/sources/SvmHyperSyncSource.res +82 -41
  92. package/src/sources/SvmHyperSyncSource.res.mjs +86 -41
  93. package/src/sources/TransactionStore.res +6 -107
  94. package/src/sources/TransactionStore.res.mjs +5 -86
  95. package/svm.schema.json +19 -0
@@ -35,8 +35,7 @@ let subscribe = (~hyperSyncUrl, ~apiToken, ~chainId, ~onHeight: int => unit): (u
35
35
  and scheduleReconnect = () => {
36
36
  // Clear any pending stale/reconnect timeout to avoid double reconnect
37
37
  timeoutIdRef.contents->clearTimeout
38
- let delay =
39
- baseDuration * Math.pow(2.0, ~exp=errorCount.contents->Int.toFloat)->Float.toInt
38
+ let delay = baseDuration * Math.pow(2.0, ~exp=errorCount.contents->Int.toFloat)->Float.toInt
40
39
  timeoutIdRef := setTimeout(() => refreshEventSource(), Pervasives.min(delay, 60_000))
41
40
  }
42
41
  and refreshEventSource = () => {
@@ -102,12 +101,6 @@ let subscribe = (~hyperSyncUrl, ~apiToken, ~chainId, ~onHeight: int => unit): (u
102
101
  es->EventSource.addEventListener("height", event => {
103
102
  switch event.data->Int.fromString {
104
103
  | Some(height) =>
105
- // Track the SSE height event
106
- Prometheus.SourceRequestCount.increment(
107
- ~sourceName="HyperSync",
108
- ~chainId,
109
- ~method="heightStream",
110
- )
111
104
  // On a successful height event, update the timeout
112
105
  updateTimeoutId()
113
106
  // Call the callback with the new height
@@ -2,7 +2,6 @@
2
2
 
3
3
  import * as Utils from "../Utils.res.mjs";
4
4
  import * as Logging from "../Logging.res.mjs";
5
- import * as Prometheus from "../Prometheus.res.mjs";
6
5
  import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
7
6
  import * as Eventsource from "eventsource";
8
7
  import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
@@ -83,7 +82,6 @@ function subscribe(hyperSyncUrl, apiToken, chainId, onHeight) {
83
82
  es$1.addEventListener("height", event => {
84
83
  let height = Stdlib_Int.fromString(event.data, undefined);
85
84
  if (height !== undefined) {
86
- Prometheus.SourceRequestCount.increment("HyperSync", chainId, "heightStream");
87
85
  updateTimeoutId();
88
86
  return onHeight(height);
89
87
  } else {
@@ -7,26 +7,23 @@ type selectionConfig = {
7
7
  fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
8
8
  }
9
9
 
10
- let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
10
+ let getSelectionConfig = (selection: FetchState.selection) => {
11
11
  let capitalizedBlockFields = Utils.Set.make()
12
12
  let capitalizedTransactionFields = Utils.Set.make()
13
13
 
14
- let staticTopicSelectionsByContract = Dict.make()
15
- let dynamicEventFiltersByContract = Dict.make()
16
- let dynamicWildcardEventFiltersByContract = Dict.make()
14
+ let topicSelectionsByContract = Dict.make()
15
+ let wildcardTopicSelectionsByContract = Dict.make()
17
16
  let noAddressesTopicSelections = []
18
17
  let contractNames = Utils.Set.make()
19
18
 
20
- selection.eventConfigs
21
- ->(Utils.magic: array<Internal.eventConfig> => array<Internal.evmEventConfig>)
22
- ->Array.forEach(({
23
- dependsOnAddresses,
24
- contractName,
25
- getEventFiltersOrThrow,
26
- selectedBlockFields,
27
- selectedTransactionFields,
28
- isWildcard,
29
- }) => {
19
+ selection.onEventRegistrations
20
+ ->(Utils.magic: array<Internal.onEventRegistration> => array<Internal.evmOnEventRegistration>)
21
+ ->Array.forEach(reg => {
22
+ let eventConfig =
23
+ reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
24
+ let contractName = eventConfig.contractName
25
+ let {selectedBlockFields, selectedTransactionFields} = eventConfig
26
+ let {dependsOnAddresses, resolvedWhere, isWildcard} = reg
30
27
  selectedBlockFields
31
28
  ->Utils.Set.toArray
32
29
  ->Array.forEach(name =>
@@ -46,24 +43,16 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
46
43
  }
47
44
  })
48
45
 
49
- let eventFilters = getEventFiltersOrThrow(chain)
50
46
  if dependsOnAddresses {
51
47
  let _ = contractNames->Utils.Set.add(contractName)
52
- switch eventFilters {
53
- | Static(topicSelections) =>
54
- staticTopicSelectionsByContract->Utils.Dict.pushMany(contractName, topicSelections)
55
- | Dynamic(fn) =>
56
- (
57
- isWildcard ? dynamicWildcardEventFiltersByContract : dynamicEventFiltersByContract
58
- )->Utils.Dict.push(contractName, fn)
59
- }
48
+
49
+ (
50
+ isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract
51
+ )->Utils.Dict.pushMany(contractName, resolvedWhere.topicSelections)
60
52
  } else {
61
53
  noAddressesTopicSelections
62
54
  ->Array.pushMany(
63
- switch eventFilters {
64
- | Static(s) => s
65
- | Dynamic(fn) => fn([])
66
- },
55
+ resolvedWhere.topicSelections->LogSelection.materializeTopicSelections(~addresses=[]),
67
56
  )
68
57
  ->ignore
69
58
  }
@@ -94,27 +83,26 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
94
83
  | None
95
84
  | Some([]) => ()
96
85
  | Some(addresses) =>
97
- switch staticTopicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
86
+ switch topicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
98
87
  | None => ()
99
88
  | Some(topicSelections) =>
100
- logSelections->Array.push(LogSelection.make(~addresses, ~topicSelections))
101
- }
102
- switch dynamicEventFiltersByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
103
- | None => ()
104
- | Some(fns) =>
105
89
  logSelections->Array.push(
106
- LogSelection.make(~addresses, ~topicSelections=fns->Array.flatMap(fn => fn(addresses))),
90
+ LogSelection.make(
91
+ ~addresses,
92
+ ~topicSelections=topicSelections->LogSelection.materializeTopicSelections(~addresses),
93
+ ),
107
94
  )
108
95
  }
109
- switch dynamicWildcardEventFiltersByContract->Utils.Dict.dangerouslyGetNonOption(
110
- contractName,
111
- ) {
96
+ // Wildcard events that filter an indexed param by registered addresses:
97
+ // the addresses fold into the topics, so the query itself stays
98
+ // address-unbound.
99
+ switch wildcardTopicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
112
100
  | None => ()
113
- | Some(fns) =>
101
+ | Some(topicSelections) =>
114
102
  logSelections->Array.push(
115
103
  LogSelection.make(
116
104
  ~addresses=[],
117
- ~topicSelections=fns->Array.flatMap(fn => fn(addresses)),
105
+ ~topicSelections=topicSelections->LogSelection.materializeTopicSelections(~addresses),
118
106
  ),
119
107
  )
120
108
  }
@@ -129,8 +117,7 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
129
117
  }
130
118
  }
131
119
 
132
- let memoGetSelectionConfig = (~chain) =>
133
- Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
120
+ let memoGetSelectionConfig = () => Utils.WeakMap.memoize(getSelectionConfig)
134
121
 
135
122
  // Surfaced by HyperSyncClient.getHeight (Rust) when HyperSync rejects the API
136
123
  // token. The corrupted-token test feeds the real server error through this
@@ -141,7 +128,7 @@ type options = {
141
128
  chain: ChainMap.Chain.t,
142
129
  endpointUrl: string,
143
130
  allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
144
- eventRouter: EventRouter.t<Internal.evmEventConfig>,
131
+ eventRouter: EventRouter.t<Internal.evmOnEventRegistration>,
145
132
  apiToken: option<string>,
146
133
  clientTimeoutMillis: int,
147
134
  lowercaseAddresses: bool,
@@ -166,7 +153,7 @@ let make = (
166
153
  ): t => {
167
154
  let name = "HyperSync"
168
155
 
169
- let getSelectionConfig = memoGetSelectionConfig(~chain)
156
+ let getSelectionConfig = memoGetSelectionConfig()
170
157
 
171
158
  let apiToken = switch apiToken {
172
159
  | Some(token) => token
@@ -197,27 +184,25 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
197
184
 
198
185
  let makeEventBatchQueueItem = (
199
186
  item: HyperSyncClient.EventItems.item,
200
- ~block: HyperSyncClient.ResponseTypes.block,
201
187
  ~params: Internal.eventParams,
202
- ~eventConfig: Internal.evmEventConfig,
188
+ ~onEventRegistration: Internal.evmOnEventRegistration,
203
189
  ): Internal.item => {
204
190
  let {transactionIndex, logIndex, srcAddress} = item
205
191
  let chainId = chain->ChainMap.Chain.toChainId
206
192
 
207
193
  Internal.Event({
208
- eventConfig: (eventConfig :> Internal.eventConfig),
209
- timestamp: block.timestamp->Option.getUnsafe,
194
+ onEventRegistration: (onEventRegistration :> Internal.onEventRegistration),
210
195
  chain,
211
196
  blockNumber: item.blockNumber,
212
- blockHash: block.hash->Option.getUnsafe,
213
197
  logIndex,
214
198
  transactionIndex,
199
+ // `block` and `transaction` are omitted; they're materialised from the
200
+ // per-chain stores onto the payload at batch prep.
215
201
  payload: {
216
- contractName: eventConfig.contractName,
217
- eventName: eventConfig.name,
202
+ contractName: onEventRegistration.eventConfig.contractName,
203
+ eventName: onEventRegistration.eventConfig.name,
218
204
  chainId,
219
205
  params,
220
- block: block->(Utils.magic: HyperSyncClient.ResponseTypes.block => Internal.eventBlock),
221
206
  srcAddress,
222
207
  logIndex,
223
208
  }->Evm.fromPayload,
@@ -248,11 +233,6 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
248
233
  let startFetchingBatchTimeRef = Performance.now()
249
234
 
250
235
  //fetch batch
251
- Prometheus.SourceRequestCount.increment(
252
- ~sourceName=name,
253
- ~chainId=chain->ChainMap.Chain.toChainId,
254
- ~method="getLogs",
255
- )
256
236
  let pageUnsafe = try await HyperSync.GetLogs.query(
257
237
  ~client,
258
238
  ~fromBlock,
@@ -307,6 +287,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
307
287
  }
308
288
 
309
289
  let pageFetchTime = startFetchingBatchTimeRef->Performance.secondsSince
290
+ let requestStats = [{Source.method: "getLogs", seconds: pageFetchTime}]
310
291
 
311
292
  //set height and next from block
312
293
  let knownHeight = pageUnsafe.archiveHeight
@@ -321,28 +302,25 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
321
302
  //Parse page items into queue items
322
303
  let parsedQueueItems = []
323
304
 
324
- // Blocks are returned once per number; items reference them by blockNumber.
305
+ // Block headers are returned once per number; items reference them by blockNumber.
325
306
  let blocksByNumber = Utils.Map.make()
326
307
  pageUnsafe.blocks->Array.forEach(block => {
327
- switch block.number {
328
- | Some(number) => blocksByNumber->Utils.Map.set(number, block)->ignore
329
- | None => ()
330
- }
308
+ blocksByNumber->Utils.Map.set(block.number, block)->ignore
331
309
  })
332
310
  let getBlock = blockNumber => blocksByNumber->Utils.Map.unsafeGet(blockNumber)
333
311
 
334
312
  let handleDecodeFailure = (
335
- ~eventConfig: Internal.evmEventConfig,
313
+ ~onEventRegistration: Internal.evmOnEventRegistration,
336
314
  ~logIndex,
337
315
  ~blockNumber,
338
316
  ~chainId,
339
317
  ~exn,
340
318
  ) => {
341
- if !eventConfig.isWildcard {
319
+ if !onEventRegistration.isWildcard {
342
320
  //Wildcard events can be parsed as undefined if the number of topics
343
321
  //don't match the event with the given topic0
344
322
  //Non wildcard events should be expected to be parsed
345
- let msg = `Event ${eventConfig.name} was unexpectedly parsed as undefined`
323
+ let msg = `Event ${onEventRegistration.eventConfig.name} was unexpectedly parsed as undefined`
346
324
  let logger = Logging.createChildFrom(
347
325
  ~logger,
348
326
  ~params={
@@ -370,19 +348,17 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
370
348
 
371
349
  switch maybeEventConfig {
372
350
  | None => () //ignore events that aren't registered
373
- | Some(eventConfig) =>
351
+ | Some(onEventRegistration) =>
374
352
  switch item.params
375
353
  ->Nullable.toOption
376
- ->Option.flatMap(Dict.get(_, eventConfig.contractName)) {
354
+ ->Option.flatMap(Dict.get(_, onEventRegistration.eventConfig.contractName)) {
377
355
  | Some(params) =>
378
356
  parsedQueueItems
379
- ->Array.push(
380
- makeEventBatchQueueItem(item, ~block=getBlock(item.blockNumber), ~params, ~eventConfig),
381
- )
357
+ ->Array.push(makeEventBatchQueueItem(item, ~params, ~onEventRegistration))
382
358
  ->ignore
383
359
  | None =>
384
360
  handleDecodeFailure(
385
- ~eventConfig,
361
+ ~onEventRegistration,
386
362
  ~logIndex=item.logIndex,
387
363
  ~blockNumber=item.blockNumber,
388
364
  ~chainId,
@@ -400,11 +376,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
400
376
  // detection notices same-block-number-different-hash collisions itself.
401
377
  let blockHashes = []
402
378
  pageUnsafe.blocks->Array.forEach(block => {
403
- switch (block.number, block.hash) {
404
- | (Some(blockNumber), Some(blockHash)) =>
405
- blockHashes->Array.push({ReorgDetection.blockNumber, blockHash})->ignore
406
- | _ => ()
407
- }
379
+ blockHashes
380
+ ->Array.push({ReorgDetection.blockNumber: block.number, blockHash: block.hash})
381
+ ->ignore
408
382
  })
409
383
  switch pageUnsafe.rollbackGuard {
410
384
  | None => ()
@@ -428,7 +402,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
428
402
  | None =>
429
403
  switch pageUnsafe.items->Array.get(pageUnsafe.items->Array.length - 1) {
430
404
  | Some(item) if item.blockNumber == heighestBlockQueried =>
431
- getBlock(item.blockNumber).timestamp->Option.getUnsafe
405
+ getBlock(item.blockNumber).timestamp
432
406
  | _ => 0
433
407
  }
434
408
  }
@@ -445,11 +419,13 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
445
419
  latestFetchedBlockTimestamp,
446
420
  parsedQueueItems,
447
421
  transactionStore: Some(pageUnsafe.transactionStore),
422
+ blockStore: Some(pageUnsafe.blockStore),
448
423
  latestFetchedBlockNumber: heighestBlockQueried,
449
424
  stats,
450
425
  knownHeight,
451
426
  blockHashes,
452
427
  fromBlockQueried: fromBlock,
428
+ requestStats,
453
429
  }
454
430
  }
455
431
 
@@ -460,7 +436,10 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
460
436
  ~sourceName=name,
461
437
  ~chainId=chain->ChainMap.Chain.toChainId,
462
438
  ~logger,
463
- )->Promise.thenResolve(HyperSync.mapExn)
439
+ )->Promise.thenResolve(((queryRes, requestStats)) => {
440
+ Source.result: queryRes->HyperSync.mapExn,
441
+ requestStats,
442
+ })
464
443
 
465
444
  {
466
445
  name,
@@ -471,7 +450,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
471
450
  getBlockHashes,
472
451
  getHeightOrThrow: async () => {
473
452
  let timerRef = Performance.now()
474
- let result = try {
453
+ let height = try {
475
454
  await client.getHeight()
476
455
  } catch {
477
456
  | JsExn(e) =>
@@ -485,18 +464,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
485
464
  }
486
465
  }
487
466
  let seconds = timerRef->Performance.secondsSince
488
- Prometheus.SourceRequestCount.increment(
489
- ~sourceName=name,
490
- ~chainId=chain->ChainMap.Chain.toChainId,
491
- ~method="getHeight",
492
- )
493
- Prometheus.SourceRequestCount.addSeconds(
494
- ~sourceName=name,
495
- ~chainId=chain->ChainMap.Chain.toChainId,
496
- ~method="getHeight",
497
- ~seconds,
498
- )
499
- result
467
+ {height, requestStats: [{method: "getHeight", seconds}]}
500
468
  },
501
469
  getItemsOrThrow,
502
470
  createHeightSubscription: (~onHeight) =>
@@ -4,7 +4,6 @@ import * as Utils from "../Utils.res.mjs";
4
4
  import * as Source from "./Source.res.mjs";
5
5
  import * as Logging from "../Logging.res.mjs";
6
6
  import * as HyperSync from "./HyperSync.res.mjs";
7
- import * as Prometheus from "../Prometheus.res.mjs";
8
7
  import * as EventRouter from "./EventRouter.res.mjs";
9
8
  import * as Performance from "../bindings/Performance.res.mjs";
10
9
  import * as LogSelection from "../LogSelection.res.mjs";
@@ -17,37 +16,33 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
17
16
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
18
17
  import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
19
18
 
20
- function getSelectionConfig(selection, chain) {
19
+ function getSelectionConfig(selection) {
21
20
  let capitalizedBlockFields = new Set();
22
21
  let capitalizedTransactionFields = new Set();
23
- let staticTopicSelectionsByContract = {};
24
- let dynamicEventFiltersByContract = {};
25
- let dynamicWildcardEventFiltersByContract = {};
22
+ let topicSelectionsByContract = {};
23
+ let wildcardTopicSelectionsByContract = {};
26
24
  let noAddressesTopicSelections = [];
27
25
  let contractNames = new Set();
28
- selection.eventConfigs.forEach(param => {
29
- let contractName = param.contractName;
30
- Array.from(param.selectedBlockFields).forEach(name => {
26
+ selection.onEventRegistrations.forEach(reg => {
27
+ let eventConfig = reg.eventConfig;
28
+ let contractName = eventConfig.contractName;
29
+ let resolvedWhere = reg.resolvedWhere;
30
+ Array.from(eventConfig.selectedBlockFields).forEach(name => {
31
31
  capitalizedBlockFields.add(Utils.$$String.capitalize(name));
32
32
  });
33
- Array.from(param.selectedTransactionFields).forEach(name => {
33
+ Array.from(eventConfig.selectedTransactionFields).forEach(name => {
34
34
  if (name !== "transactionIndex") {
35
35
  capitalizedTransactionFields.add(Utils.$$String.capitalize(name));
36
36
  return;
37
37
  }
38
38
  });
39
- let eventFilters = param.getEventFiltersOrThrow(chain);
40
- if (param.dependsOnAddresses) {
39
+ if (reg.dependsOnAddresses) {
41
40
  contractNames.add(contractName);
42
- if (eventFilters.TAG === "Static") {
43
- return Utils.Dict.pushMany(staticTopicSelectionsByContract, contractName, eventFilters._0);
44
- } else {
45
- return Utils.Dict.push(param.isWildcard ? dynamicWildcardEventFiltersByContract : dynamicEventFiltersByContract, contractName, eventFilters._0);
46
- }
41
+ return Utils.Dict.pushMany(reg.isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract, contractName, resolvedWhere.topicSelections);
42
+ } else {
43
+ noAddressesTopicSelections.push(...LogSelection.materializeTopicSelections(resolvedWhere.topicSelections, []));
44
+ return;
47
45
  }
48
- let tmp;
49
- tmp = eventFilters.TAG === "Static" ? eventFilters._0 : eventFilters._0([]);
50
- noAddressesTopicSelections.push(...tmp);
51
46
  });
52
47
  let fieldSelection_block = Array.from(capitalizedBlockFields);
53
48
  let fieldSelection_transaction = Array.from(capitalizedTransactionFields);
@@ -79,17 +74,13 @@ function getSelectionConfig(selection, chain) {
79
74
  if (addresses.length === 0) {
80
75
  return;
81
76
  }
82
- let topicSelections = staticTopicSelectionsByContract[contractName];
77
+ let topicSelections = topicSelectionsByContract[contractName];
83
78
  if (topicSelections !== undefined) {
84
- logSelections.push(LogSelection.make(addresses, topicSelections));
79
+ logSelections.push(LogSelection.make(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
85
80
  }
86
- let fns = dynamicEventFiltersByContract[contractName];
87
- if (fns !== undefined) {
88
- logSelections.push(LogSelection.make(addresses, fns.flatMap(fn => fn(addresses))));
89
- }
90
- let fns$1 = dynamicWildcardEventFiltersByContract[contractName];
91
- if (fns$1 !== undefined) {
92
- logSelections.push(LogSelection.make([], fns$1.flatMap(fn => fn(addresses))));
81
+ let topicSelections$1 = wildcardTopicSelectionsByContract[contractName];
82
+ if (topicSelections$1 !== undefined) {
83
+ logSelections.push(LogSelection.make([], LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
93
84
  return;
94
85
  }
95
86
  });
@@ -101,8 +92,8 @@ function getSelectionConfig(selection, chain) {
101
92
  };
102
93
  }
103
94
 
104
- function memoGetSelectionConfig(chain) {
105
- return Utils.$$WeakMap.memoize(selection => getSelectionConfig(selection, chain));
95
+ function memoGetSelectionConfig() {
96
+ return Utils.$$WeakMap.memoize(getSelectionConfig);
106
97
  }
107
98
 
108
99
  function isUnauthorizedError(message) {
@@ -115,7 +106,7 @@ function make(param) {
115
106
  let endpointUrl = param.endpointUrl;
116
107
  let chain = param.chain;
117
108
  let name = "HyperSync";
118
- let getSelectionConfig = memoGetSelectionConfig(chain);
109
+ let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
119
110
  let apiToken$1 = apiToken !== undefined ? apiToken : Stdlib_JsError.throwWithMessage(`An Envio API token is required for using HyperSync as a data-source.
120
111
  Set the ENVIO_API_TOKEN environment variable in your .env file.
121
112
  Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
@@ -127,31 +118,28 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
127
118
  client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the hypersync client, please double check your ABI", exn);
128
119
  }
129
120
  let UndefinedValue = /* @__PURE__ */Primitive_exceptions.create("UndefinedValue");
130
- let makeEventBatchQueueItem = (item, block, params, eventConfig) => {
121
+ let makeEventBatchQueueItem = (item, params, onEventRegistration) => {
131
122
  let logIndex = item.logIndex;
132
123
  return {
133
124
  kind: 0,
134
- eventConfig: eventConfig,
135
- timestamp: block.timestamp,
125
+ onEventRegistration: onEventRegistration,
136
126
  chain: chain,
137
127
  blockNumber: item.blockNumber,
138
- blockHash: block.hash,
139
128
  logIndex: logIndex,
140
129
  transactionIndex: item.transactionIndex,
141
130
  payload: {
142
- contractName: eventConfig.contractName,
143
- eventName: eventConfig.name,
131
+ contractName: onEventRegistration.eventConfig.contractName,
132
+ eventName: onEventRegistration.eventConfig.name,
144
133
  params: params,
145
134
  chainId: chain,
146
135
  srcAddress: item.srcAddress,
147
- logIndex: logIndex,
148
- block: block
136
+ logIndex: logIndex
149
137
  }
150
138
  };
151
139
  };
152
140
  let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, itemsTarget, retry, logger) => {
153
141
  let totalTimeRef = Performance.now();
154
- let selectionConfig = getSelectionConfig(selection);
142
+ let selectionConfig = getSelectionConfig$1(selection);
155
143
  let logSelections;
156
144
  try {
157
145
  logSelections = selectionConfig.getLogSelectionOrThrow(addressesByContractName);
@@ -160,7 +148,6 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
160
148
  logSelections = ErrorHandling.mkLogAndRaise(logger, "Failed getting log selection for the query", exn);
161
149
  }
162
150
  let startFetchingBatchTimeRef = Performance.now();
163
- Prometheus.SourceRequestCount.increment(name, chain, "getLogs");
164
151
  let pageUnsafe;
165
152
  try {
166
153
  pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection, itemsTarget);
@@ -212,26 +199,26 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
212
199
  };
213
200
  }
214
201
  let pageFetchTime = Performance.secondsSince(startFetchingBatchTimeRef);
202
+ let requestStats = [{
203
+ method: "getLogs",
204
+ seconds: pageFetchTime
205
+ }];
215
206
  let knownHeight$1 = pageUnsafe.archiveHeight;
216
207
  let heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
217
208
  let parsingTimeRef = Performance.now();
218
209
  let parsedQueueItems = [];
219
210
  let blocksByNumber = new Map();
220
211
  pageUnsafe.blocks.forEach(block => {
221
- let number = block.number;
222
- if (number !== undefined) {
223
- blocksByNumber.set(number, block);
224
- return;
225
- }
212
+ blocksByNumber.set(block.number, block);
226
213
  });
227
214
  pageUnsafe.items.forEach(item => {
228
215
  let maybeEventConfig = EventRouter.get(eventRouter, EventRouter.getEvmEventId(item.topic0, item.topicCount), item.srcAddress, contractNameByAddress);
229
216
  if (maybeEventConfig === undefined) {
230
217
  return;
231
218
  }
232
- let params = Stdlib_Option.flatMap(Primitive_option.fromNullable(item.params), __x => __x[maybeEventConfig.contractName]);
219
+ let params = Stdlib_Option.flatMap(Primitive_option.fromNullable(item.params), __x => __x[maybeEventConfig.eventConfig.contractName]);
233
220
  if (params !== undefined) {
234
- parsedQueueItems.push(makeEventBatchQueueItem(item, blocksByNumber.get(item.blockNumber), Primitive_option.valFromOption(params), maybeEventConfig));
221
+ parsedQueueItems.push(makeEventBatchQueueItem(item, Primitive_option.valFromOption(params), maybeEventConfig));
235
222
  return;
236
223
  } else {
237
224
  let logIndex = item.logIndex;
@@ -242,7 +229,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
242
229
  if (maybeEventConfig.isWildcard) {
243
230
  return;
244
231
  }
245
- let msg = `Event ` + maybeEventConfig.name + ` was unexpectedly parsed as undefined`;
232
+ let msg = `Event ` + maybeEventConfig.eventConfig.name + ` was unexpectedly parsed as undefined`;
246
233
  let logger$1 = Logging.createChildFrom(logger, {
247
234
  chainId: chain,
248
235
  blockNumber: blockNumber,
@@ -255,15 +242,10 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
255
242
  let parsingTimeElapsed = Performance.secondsSince(parsingTimeRef);
256
243
  let blockHashes = [];
257
244
  pageUnsafe.blocks.forEach(block => {
258
- let match = block.number;
259
- let match$1 = block.hash;
260
- if (match !== undefined && match$1 !== undefined) {
261
- blockHashes.push({
262
- blockHash: match$1,
263
- blockNumber: match
264
- });
265
- return;
266
- }
245
+ blockHashes.push({
246
+ blockHash: block.hash,
247
+ blockNumber: block.number
248
+ });
267
249
  });
268
250
  let match = pageUnsafe.rollbackGuard;
269
251
  if (match !== undefined) {
@@ -297,13 +279,18 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
297
279
  blockHashes: blockHashes,
298
280
  parsedQueueItems: parsedQueueItems,
299
281
  transactionStore: Primitive_option.some(pageUnsafe.transactionStore),
282
+ blockStore: Primitive_option.some(pageUnsafe.blockStore),
300
283
  fromBlockQueried: fromBlock,
301
284
  latestFetchedBlockNumber: heighestBlockQueried,
302
285
  latestFetchedBlockTimestamp: latestFetchedBlockTimestamp,
303
- stats: stats
286
+ stats: stats,
287
+ requestStats: requestStats
304
288
  };
305
289
  };
306
- let getBlockHashes = (blockNumbers, logger) => HyperSync.queryBlockDataMulti(client, blockNumbers, name, chain, logger).then(HyperSync.mapExn);
290
+ let getBlockHashes = (blockNumbers, logger) => HyperSync.queryBlockDataMulti(client, blockNumbers, name, chain, logger).then(param => ({
291
+ result: HyperSync.mapExn(param[0]),
292
+ requestStats: param[1]
293
+ }));
307
294
  return {
308
295
  name: name,
309
296
  sourceFor: "Sync",
@@ -313,9 +300,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
313
300
  getBlockHashes: getBlockHashes,
314
301
  getHeightOrThrow: async () => {
315
302
  let timerRef = Performance.now();
316
- let result;
303
+ let height;
317
304
  try {
318
- result = await client.getHeight();
305
+ height = await client.getHeight();
319
306
  } catch (raw_e) {
320
307
  let e = Primitive_exceptions.internalToException(raw_e);
321
308
  if (e.RE_EXN_ID === "JsExn") {
@@ -325,7 +312,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
325
312
  if (message.includes("401 Unauthorized")) {
326
313
  Logging.error(`Your ENVIO_API_TOKEN was rejected by HyperSync (401 Unauthorized). The indexer will not be able to fetch events. Update the token and try again using 'envio start' or 'envio dev'. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens`);
327
314
  await new Promise((param, param$1) => {});
328
- result = 0;
315
+ height = 0;
329
316
  } else {
330
317
  throw {
331
318
  RE_EXN_ID: "JsExn",
@@ -345,9 +332,13 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
345
332
  }
346
333
  }
347
334
  let seconds = Performance.secondsSince(timerRef);
348
- Prometheus.SourceRequestCount.increment(name, chain, "getHeight");
349
- Prometheus.SourceRequestCount.addSeconds(name, chain, "getHeight", seconds);
350
- return result;
335
+ return {
336
+ height: height,
337
+ requestStats: [{
338
+ method: "getHeight",
339
+ seconds: seconds
340
+ }]
341
+ };
351
342
  },
352
343
  getItemsOrThrow: getItemsOrThrow,
353
344
  createHeightSubscription: onHeight => HyperSyncHeightStream.subscribe(endpointUrl, apiToken$1, chain, onHeight)