envio 3.3.0-alpha.0 → 3.3.0-alpha.10

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 (140) hide show
  1. package/evm.schema.json +10 -0
  2. package/index.d.ts +45 -25
  3. package/package.json +7 -7
  4. package/src/Address.res +5 -2
  5. package/src/Address.res.mjs +3 -1
  6. package/src/Api.res +1 -1
  7. package/src/Api.res.mjs +1 -1
  8. package/src/Batch.res +0 -6
  9. package/src/Batch.res.mjs +1 -12
  10. package/src/BatchProcessing.res +7 -12
  11. package/src/BatchProcessing.res.mjs +8 -7
  12. package/src/Bin.res +3 -0
  13. package/src/Bin.res.mjs +4 -0
  14. package/src/ChainFetching.res +48 -16
  15. package/src/ChainFetching.res.mjs +36 -17
  16. package/src/ChainMetadata.res +1 -11
  17. package/src/ChainMetadata.res.mjs +1 -10
  18. package/src/ChainState.res +628 -149
  19. package/src/ChainState.res.mjs +440 -102
  20. package/src/ChainState.resi +74 -4
  21. package/src/Config.res +61 -33
  22. package/src/Config.res.mjs +50 -10
  23. package/src/ContractRegisterContext.res +2 -12
  24. package/src/ContractRegisterContext.res.mjs +3 -5
  25. package/src/Core.res +14 -3
  26. package/src/CrossChainState.res +142 -93
  27. package/src/CrossChainState.res.mjs +88 -60
  28. package/src/CrossChainState.resi +2 -10
  29. package/src/Ecosystem.res +5 -6
  30. package/src/Ecosystem.res.mjs +3 -3
  31. package/src/Env.res +0 -7
  32. package/src/Env.res.mjs +0 -6
  33. package/src/Envio.res +17 -11
  34. package/src/EnvioGlobal.res +53 -0
  35. package/src/EnvioGlobal.res.mjs +31 -0
  36. package/src/EventConfigBuilder.res +177 -88
  37. package/src/EventConfigBuilder.res.mjs +99 -42
  38. package/src/EventProcessing.res +74 -28
  39. package/src/EventProcessing.res.mjs +55 -29
  40. package/src/ExitOnCaughtUp.res +10 -2
  41. package/src/ExitOnCaughtUp.res.mjs +10 -1
  42. package/src/FetchState.res +558 -300
  43. package/src/FetchState.res.mjs +437 -423
  44. package/src/HandlerLoader.res +8 -104
  45. package/src/HandlerLoader.res.mjs +2 -81
  46. package/src/HandlerRegister.res +518 -144
  47. package/src/HandlerRegister.res.mjs +285 -133
  48. package/src/HandlerRegister.resi +24 -8
  49. package/src/IndexerLoop.res +2 -3
  50. package/src/IndexerLoop.res.mjs +1 -1
  51. package/src/IndexerState.res +10 -11
  52. package/src/IndexerState.res.mjs +14 -11
  53. package/src/IndexerState.resi +2 -5
  54. package/src/IndexingAddresses.res +108 -0
  55. package/src/IndexingAddresses.res.mjs +101 -0
  56. package/src/IndexingAddresses.resi +34 -0
  57. package/src/Internal.res +155 -46
  58. package/src/Internal.res.mjs +30 -2
  59. package/src/LoadLayer.res +5 -5
  60. package/src/LoadLayer.res.mjs +6 -6
  61. package/src/LogSelection.res +102 -165
  62. package/src/LogSelection.res.mjs +101 -116
  63. package/src/Main.res +71 -236
  64. package/src/Main.res.mjs +60 -145
  65. package/src/Metrics.res +74 -0
  66. package/src/Metrics.res.mjs +75 -0
  67. package/src/PgStorage.res +4 -4
  68. package/src/PgStorage.res.mjs +5 -5
  69. package/src/Prometheus.res +10 -74
  70. package/src/Prometheus.res.mjs +124 -186
  71. package/src/PruneStaleHistory.res +2 -2
  72. package/src/PruneStaleHistory.res.mjs +3 -3
  73. package/src/RawEvent.res +7 -2
  74. package/src/RawEvent.res.mjs +4 -4
  75. package/src/Rollback.res +3 -3
  76. package/src/Rollback.res.mjs +4 -4
  77. package/src/RollbackCommit.res +4 -1
  78. package/src/RollbackCommit.res.mjs +3 -2
  79. package/src/SimulateDeadInputTracker.res +85 -0
  80. package/src/SimulateDeadInputTracker.res.mjs +73 -0
  81. package/src/SimulateDeadInputTracker.resi +12 -0
  82. package/src/SimulateItems.res +91 -23
  83. package/src/SimulateItems.res.mjs +55 -32
  84. package/src/TestIndexer.res +54 -40
  85. package/src/TestIndexer.res.mjs +37 -30
  86. package/src/bindings/Performance.res +7 -0
  87. package/src/bindings/Performance.res.mjs +21 -0
  88. package/src/bindings/Performance.resi +7 -0
  89. package/src/bindings/Viem.res +0 -41
  90. package/src/bindings/Viem.res.mjs +1 -43
  91. package/src/sources/BlockStore.res +46 -0
  92. package/src/sources/BlockStore.res.mjs +24 -0
  93. package/src/sources/EventRouter.res +36 -33
  94. package/src/sources/EventRouter.res.mjs +13 -14
  95. package/src/sources/Evm.res +83 -72
  96. package/src/sources/Evm.res.mjs +53 -69
  97. package/src/sources/EvmChain.res +18 -20
  98. package/src/sources/EvmChain.res.mjs +15 -15
  99. package/src/sources/EvmRpcClient.res +74 -5
  100. package/src/sources/EvmRpcClient.res.mjs +13 -4
  101. package/src/sources/FieldMask.res +39 -0
  102. package/src/sources/FieldMask.res.mjs +42 -0
  103. package/src/sources/Fuel.res +9 -6
  104. package/src/sources/Fuel.res.mjs +5 -10
  105. package/src/sources/HyperFuelSource.res +46 -50
  106. package/src/sources/HyperFuelSource.res.mjs +64 -54
  107. package/src/sources/HyperSync.res +39 -7
  108. package/src/sources/HyperSync.res.mjs +57 -37
  109. package/src/sources/HyperSync.resi +12 -2
  110. package/src/sources/HyperSyncClient.res +22 -111
  111. package/src/sources/HyperSyncClient.res.mjs +2 -30
  112. package/src/sources/HyperSyncHeightStream.res +1 -8
  113. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  114. package/src/sources/HyperSyncSource.res +94 -107
  115. package/src/sources/HyperSyncSource.res.mjs +82 -86
  116. package/src/sources/Rpc.res +15 -47
  117. package/src/sources/Rpc.res.mjs +25 -56
  118. package/src/sources/RpcSource.res +320 -467
  119. package/src/sources/RpcSource.res.mjs +268 -385
  120. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  121. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  122. package/src/sources/SimulateSource.res +10 -4
  123. package/src/sources/SimulateSource.res.mjs +16 -6
  124. package/src/sources/Source.res +34 -6
  125. package/src/sources/SourceManager.res +86 -27
  126. package/src/sources/SourceManager.res.mjs +84 -47
  127. package/src/sources/SourceManager.resi +12 -3
  128. package/src/sources/Svm.res +31 -16
  129. package/src/sources/Svm.res.mjs +36 -13
  130. package/src/sources/SvmHyperSyncClient.res +5 -32
  131. package/src/sources/SvmHyperSyncSource.res +159 -134
  132. package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
  133. package/src/sources/TransactionStore.res +49 -0
  134. package/src/sources/TransactionStore.res.mjs +30 -0
  135. package/src/tui/Tui.res +13 -16
  136. package/src/tui/Tui.res.mjs +12 -14
  137. package/svm.schema.json +49 -37
  138. package/src/bindings/Hrtime.res +0 -58
  139. package/src/bindings/Hrtime.res.mjs +0 -90
  140. package/src/bindings/Hrtime.resi +0 -30
@@ -18,6 +18,7 @@ import * as CrossChainState from "./CrossChainState.res.mjs";
18
18
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
19
19
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
20
20
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
21
+ import * as SimulateDeadInputTracker from "./SimulateDeadInputTracker.res.mjs";
21
22
 
22
23
  function make() {
23
24
  let intervalMillis = Env.ThrottleWrites.pruneStaleDataIntervalMillis;
@@ -53,9 +54,7 @@ function get(self, entityName) {
53
54
  }
54
55
  }
55
56
 
56
- function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime, maxBackfillConcurrencyOpt, maxRealtimeConcurrencyOpt, targetBufferSizeOpt, committedCheckpointIdOpt, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, onError) {
57
- let maxBackfillConcurrency = maxBackfillConcurrencyOpt !== undefined ? maxBackfillConcurrencyOpt : Env.maxBackfillConcurrency;
58
- let maxRealtimeConcurrency = maxRealtimeConcurrencyOpt !== undefined ? maxRealtimeConcurrencyOpt : Env.maxRealtimeConcurrency;
57
+ function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime, targetBufferSizeOpt, committedCheckpointIdOpt, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, onError) {
59
58
  let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : CrossChainState.calculateTargetBufferSize();
60
59
  let committedCheckpointId = committedCheckpointIdOpt !== undefined ? committedCheckpointIdOpt : Internal.initialCheckpointId;
61
60
  let isDevelopmentMode = isDevelopmentModeOpt !== undefined ? isDevelopmentModeOpt : false;
@@ -84,7 +83,7 @@ function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime
84
83
  chainMetaDirty: false,
85
84
  chainMetaThrottler: chainMetaThrottler,
86
85
  isProcessing: false,
87
- crossChainState: CrossChainState.make(chainStates, isInReorgThreshold, isRealtime, maxBackfillConcurrency, maxRealtimeConcurrency, targetBufferSize),
86
+ crossChainState: CrossChainState.make(chainStates, isInReorgThreshold, isRealtime, targetBufferSize),
88
87
  rollbackState: "NoRollback",
89
88
  indexerStartTime: new Date(),
90
89
  writeThrottlers: make(),
@@ -93,16 +92,15 @@ function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime
93
92
  exitAfterFirstEventBlock: exitAfterFirstEventBlock,
94
93
  onError: onError,
95
94
  isStopped: false,
96
- epoch: 0
95
+ epoch: 0,
96
+ simulateDeadInputTracker: SimulateDeadInputTracker.makeFromConfig(config)
97
97
  };
98
98
  }
99
99
 
100
- function makeFromDbState(config, persistence, initialState, registrations, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, reducedPollingInterval, maxBackfillConcurrencyOpt, maxRealtimeConcurrencyOpt, targetBufferSizeOpt, onError) {
100
+ function makeFromDbState(config, persistence, initialState, registrationsByChainId, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, reducedPollingInterval, targetBufferSizeOpt, onError) {
101
101
  let isDevelopmentMode = isDevelopmentModeOpt !== undefined ? isDevelopmentModeOpt : false;
102
102
  let shouldUseTui = shouldUseTuiOpt !== undefined ? shouldUseTuiOpt : false;
103
103
  let exitAfterFirstEventBlock = exitAfterFirstEventBlockOpt !== undefined ? exitAfterFirstEventBlockOpt : false;
104
- let maxBackfillConcurrency = maxBackfillConcurrencyOpt !== undefined ? maxBackfillConcurrencyOpt : Env.maxBackfillConcurrency;
105
- let maxRealtimeConcurrency = maxRealtimeConcurrencyOpt !== undefined ? maxRealtimeConcurrencyOpt : Env.maxRealtimeConcurrency;
106
104
  let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : CrossChainState.calculateTargetBufferSize();
107
105
  let isInReorgThreshold = initialState.cleanRun ? false : initialState.chains.some(chain => {
108
106
  let progressBlockNumber = chain.progressBlockNumber;
@@ -125,7 +123,7 @@ function makeFromDbState(config, persistence, initialState, registrations, isDev
125
123
  initialState.chains.forEach(resumedChainState => {
126
124
  let chain = Config.getChain(config, resumedChainState.id);
127
125
  let chainConfig = ChainMap.get(config.chainMap, chain);
128
- chainStates[resumedChainState.id] = ChainState.makeFromDbState(chainConfig, resumedChainState, initialState.reorgCheckpoints, isInReorgThreshold, isRealtime, config, registrations, reducedPollingInterval);
126
+ chainStates[resumedChainState.id] = ChainState.makeFromDbState(chainConfig, resumedChainState, initialState.reorgCheckpoints, isInReorgThreshold, isRealtime, config, registrationsByChainId, reducedPollingInterval);
129
127
  });
130
128
  let allChainsReady = {
131
129
  contents: initialState.chains.length !== 0
@@ -144,7 +142,7 @@ function makeFromDbState(config, persistence, initialState, registrations, isDev
144
142
  if (allChainsReady.contents) {
145
143
  Prometheus.ProgressReady.setAllReady();
146
144
  }
147
- return make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime, maxBackfillConcurrency, maxRealtimeConcurrency, targetBufferSize, initialState.checkpointId, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, onError);
145
+ return make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime, targetBufferSize, initialState.checkpointId, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, onError);
148
146
  }
149
147
 
150
148
  function isStale(state, stateId) {
@@ -233,7 +231,7 @@ function invalidateInflight(state) {
233
231
  }
234
232
 
235
233
  function applyBatchProgress(state, batch) {
236
- CrossChainState.applyBatchProgress(state.crossChainState, batch);
234
+ CrossChainState.applyBatchProgress(state.crossChainState, batch, state.config.ecosystem.blockTimestampName);
237
235
  }
238
236
 
239
237
  function isProcessing(state) {
@@ -352,6 +350,10 @@ function pruneStaleEntityHistoryThrottler(state) {
352
350
  return state.writeThrottlers.pruneStaleEntityHistory;
353
351
  }
354
352
 
353
+ function simulateDeadInputTracker(state) {
354
+ return state.simulateDeadInputTracker;
355
+ }
356
+
355
357
  function queueProcessedBatch(state, batch) {
356
358
  state.processedBatches.push(batch);
357
359
  let checkpointId = Utils.$$Array.last(batch.checkpointIds);
@@ -531,6 +533,7 @@ export {
531
533
  isStopped,
532
534
  epoch,
533
535
  pruneStaleEntityHistoryThrottler,
536
+ simulateDeadInputTracker,
534
537
  queueProcessedBatch,
535
538
  drainBatchRun,
536
539
  takeRollback,
@@ -32,8 +32,6 @@ let make: (
32
32
  ~chainStates: dict<ChainState.t>,
33
33
  ~isInReorgThreshold: bool,
34
34
  ~isRealtime: bool,
35
- ~maxBackfillConcurrency: int=?,
36
- ~maxRealtimeConcurrency: int=?,
37
35
  ~targetBufferSize: int=?,
38
36
  ~committedCheckpointId: Internal.checkpointId=?,
39
37
  ~isDevelopmentMode: bool=?,
@@ -46,13 +44,11 @@ let makeFromDbState: (
46
44
  ~config: Config.t,
47
45
  ~persistence: Persistence.t,
48
46
  ~initialState: Persistence.initialState,
49
- ~registrations: HandlerRegister.registrations,
47
+ ~registrationsByChainId: HandlerRegister.registrationsByChainId,
50
48
  ~isDevelopmentMode: bool=?,
51
49
  ~shouldUseTui: bool=?,
52
50
  ~exitAfterFirstEventBlock: bool=?,
53
51
  ~reducedPollingInterval: int=?,
54
- ~maxBackfillConcurrency: int=?,
55
- ~maxRealtimeConcurrency: int=?,
56
52
  ~targetBufferSize: int=?,
57
53
  ~onError: ErrorHandling.t => unit,
58
54
  ) => t
@@ -111,6 +107,7 @@ let exitAfterFirstEventBlock: t => bool
111
107
  let isStopped: t => bool
112
108
  let epoch: t => int
113
109
  let pruneStaleEntityHistoryThrottler: t => Throttler.t
110
+ let simulateDeadInputTracker: t => option<SimulateDeadInputTracker.t>
114
111
 
115
112
  // Store domain operations.
116
113
  let queueProcessedBatch: (t, ~batch: Batch.t) => unit
@@ -0,0 +1,108 @@
1
+ type indexingAddress = Internal.indexingContract
2
+
3
+ type contractConfig = {startBlock: option<int>}
4
+
5
+ type t = dict<indexingAddress>
6
+
7
+ let deriveEffectiveStartBlock = (~registrationBlock: int, ~contractStartBlock: option<int>) => {
8
+ Pervasives.max(Pervasives.max(registrationBlock, 0), contractStartBlock->Option.getOr(0))
9
+ }
10
+
11
+ let makeContractConfigs = (~onEventRegistrations: array<Internal.onEventRegistration>): dict<
12
+ contractConfig,
13
+ > => {
14
+ let contractConfigs: dict<contractConfig> = Dict.make()
15
+ onEventRegistrations->Array.forEach(reg => {
16
+ let contractName = reg.eventConfig.contractName
17
+ switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(contractName) {
18
+ | Some({startBlock}) =>
19
+ contractConfigs->Dict.set(
20
+ contractName,
21
+ {
22
+ startBlock: switch (startBlock, reg.startBlock) {
23
+ | (Some(a), Some(b)) => Some(Pervasives.min(a, b))
24
+ | (Some(_) as s, None) | (None, Some(_) as s) => s
25
+ | (None, None) => None
26
+ },
27
+ },
28
+ )
29
+ | None =>
30
+ contractConfigs->Dict.set(
31
+ contractName,
32
+ {
33
+ startBlock: reg.startBlock,
34
+ },
35
+ )
36
+ }
37
+ })
38
+ contractConfigs
39
+ }
40
+
41
+ let makeIndexingAddress = (
42
+ ~contract: Internal.indexingAddress,
43
+ ~contractConfigs: dict<contractConfig>,
44
+ ): indexingAddress => {
45
+ let contractStartBlock = switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(
46
+ contract.contractName,
47
+ ) {
48
+ | Some({startBlock}) => startBlock
49
+ | None => None
50
+ }
51
+ {
52
+ address: contract.address,
53
+ contractName: contract.contractName,
54
+ registrationBlock: contract.registrationBlock,
55
+ effectiveStartBlock: deriveEffectiveStartBlock(
56
+ ~registrationBlock=contract.registrationBlock,
57
+ ~contractStartBlock,
58
+ ),
59
+ }
60
+ }
61
+
62
+ let make = (
63
+ ~contractConfigs: dict<contractConfig>,
64
+ ~addresses: array<Internal.indexingAddress>,
65
+ ): t => {
66
+ let indexingAddresses = Dict.make()
67
+ addresses->Array.forEach(contract => {
68
+ indexingAddresses->Dict.set(
69
+ contract.address->Address.toString,
70
+ makeIndexingAddress(~contract, ~contractConfigs),
71
+ )
72
+ })
73
+ indexingAddresses
74
+ }
75
+
76
+ let get = (indexingAddresses: t, address) =>
77
+ indexingAddresses->Utils.Dict.dangerouslyGetNonOption(address)
78
+
79
+ let size = (indexingAddresses: t) => indexingAddresses->Utils.Dict.size
80
+
81
+ let getContractAddresses = (indexingAddresses: t, ~contractName): array<Address.t> => {
82
+ let addresses = []
83
+ indexingAddresses->Utils.Dict.forEach(ia => {
84
+ if ia.contractName === contractName {
85
+ addresses->Array.push(ia.address)
86
+ }
87
+ })
88
+ addresses
89
+ }
90
+
91
+ // Underlying dict for the precompiled `clientAddressFilter` only — it does raw
92
+ // `indexingAddresses[srcAddress]` access in generated JS and can't take the opaque
93
+ // type. Don't reach for this elsewhere; use the domain accessors above.
94
+ let rawForFilter = (indexingAddresses: t): dict<indexingAddress> => indexingAddresses
95
+
96
+ let register = (indexingAddresses: t, additions: dict<indexingAddress>) => {
97
+ let _ = Utils.Dict.mergeInPlace(indexingAddresses, additions)
98
+ }
99
+
100
+ let rollbackInPlace = (indexingAddresses: t, ~targetBlockNumber: int): unit => {
101
+ // forEachWithKey is a `for..in`, so deleting the key currently being visited is
102
+ // safe — it doesn't affect enumeration of the remaining keys.
103
+ indexingAddresses->Utils.Dict.forEachWithKey((indexingContract, address) => {
104
+ if indexingContract.registrationBlock > targetBlockNumber {
105
+ indexingAddresses->Utils.Dict.deleteInPlace(address)
106
+ }
107
+ })
108
+ }
@@ -0,0 +1,101 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Utils from "./Utils.res.mjs";
4
+ import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
5
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
+
7
+ function deriveEffectiveStartBlock(registrationBlock, contractStartBlock) {
8
+ return Primitive_int.max(Primitive_int.max(registrationBlock, 0), Stdlib_Option.getOr(contractStartBlock, 0));
9
+ }
10
+
11
+ function makeContractConfigs(onEventRegistrations) {
12
+ let contractConfigs = {};
13
+ onEventRegistrations.forEach(reg => {
14
+ let contractName = reg.eventConfig.contractName;
15
+ let match = contractConfigs[contractName];
16
+ if (match !== undefined) {
17
+ let startBlock = match.startBlock;
18
+ let match$1 = reg.startBlock;
19
+ contractConfigs[contractName] = {
20
+ startBlock: startBlock !== undefined ? (
21
+ match$1 !== undefined ? Primitive_int.min(startBlock, match$1) : startBlock
22
+ ) : (
23
+ match$1 !== undefined ? match$1 : undefined
24
+ )
25
+ };
26
+ return;
27
+ }
28
+ contractConfigs[contractName] = {
29
+ startBlock: reg.startBlock
30
+ };
31
+ });
32
+ return contractConfigs;
33
+ }
34
+
35
+ function makeIndexingAddress(contract, contractConfigs) {
36
+ let match = contractConfigs[contract.contractName];
37
+ let contractStartBlock = match !== undefined ? match.startBlock : undefined;
38
+ return {
39
+ address: contract.address,
40
+ contractName: contract.contractName,
41
+ registrationBlock: contract.registrationBlock,
42
+ effectiveStartBlock: deriveEffectiveStartBlock(contract.registrationBlock, contractStartBlock)
43
+ };
44
+ }
45
+
46
+ function make(contractConfigs, addresses) {
47
+ let indexingAddresses = {};
48
+ addresses.forEach(contract => {
49
+ indexingAddresses[contract.address] = makeIndexingAddress(contract, contractConfigs);
50
+ });
51
+ return indexingAddresses;
52
+ }
53
+
54
+ function get(indexingAddresses, address) {
55
+ return indexingAddresses[address];
56
+ }
57
+
58
+ function size(indexingAddresses) {
59
+ return Utils.Dict.size(indexingAddresses);
60
+ }
61
+
62
+ function getContractAddresses(indexingAddresses, contractName) {
63
+ let addresses = [];
64
+ Utils.Dict.forEach(indexingAddresses, ia => {
65
+ if (ia.contractName === contractName) {
66
+ addresses.push(ia.address);
67
+ return;
68
+ }
69
+ });
70
+ return addresses;
71
+ }
72
+
73
+ function rawForFilter(indexingAddresses) {
74
+ return indexingAddresses;
75
+ }
76
+
77
+ function register(indexingAddresses, additions) {
78
+ Object.assign(indexingAddresses, additions);
79
+ }
80
+
81
+ function rollbackInPlace(indexingAddresses, targetBlockNumber) {
82
+ Utils.Dict.forEachWithKey(indexingAddresses, (indexingContract, address) => {
83
+ if (indexingContract.registrationBlock > targetBlockNumber) {
84
+ return Utils.Dict.deleteInPlace(indexingAddresses, address);
85
+ }
86
+ });
87
+ }
88
+
89
+ export {
90
+ deriveEffectiveStartBlock,
91
+ makeContractConfigs,
92
+ makeIndexingAddress,
93
+ make,
94
+ get,
95
+ size,
96
+ getContractAddresses,
97
+ rawForFilter,
98
+ register,
99
+ rollbackInPlace,
100
+ }
101
+ /* Utils Not a pure module */
@@ -0,0 +1,34 @@
1
+ type indexingAddress = Internal.indexingContract
2
+
3
+ type contractConfig = {startBlock: option<int>}
4
+
5
+ type t
6
+
7
+ let deriveEffectiveStartBlock: (~registrationBlock: int, ~contractStartBlock: option<int>) => int
8
+
9
+ let makeContractConfigs: (
10
+ ~onEventRegistrations: array<Internal.onEventRegistration>,
11
+ ) => dict<contractConfig>
12
+
13
+ let makeIndexingAddress: (
14
+ ~contract: Internal.indexingAddress,
15
+ ~contractConfigs: dict<contractConfig>,
16
+ ) => indexingAddress
17
+
18
+ let make: (~contractConfigs: dict<contractConfig>, ~addresses: array<Internal.indexingAddress>) => t
19
+
20
+ let get: (t, string) => option<indexingAddress>
21
+
22
+ let size: t => int
23
+
24
+ let getContractAddresses: (t, ~contractName: string) => array<Address.t>
25
+
26
+ // Underlying dict for the precompiled `clientAddressFilter` only, which does raw
27
+ // `indexingAddresses[srcAddress]` access in generated JS. Don't use elsewhere —
28
+ // prefer the domain accessors so the opaque type stays enforced.
29
+ let rawForFilter: t => dict<indexingAddress>
30
+
31
+ let register: (t, dict<indexingAddress>) => unit
32
+
33
+ // Deletes addresses registered after `targetBlockNumber` from the index in place.
34
+ let rollbackInPlace: (t, ~targetBlockNumber: int) => unit