envio 2.22.0 → 2.22.2

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 (48) hide show
  1. package/package.json +7 -6
  2. package/src/Address.res.js +30 -0
  3. package/src/ChainMap.res.js +77 -0
  4. package/src/Envio.res.js +16 -0
  5. package/src/ErrorHandling.res.js +56 -0
  6. package/src/EventUtils.res.js +75 -0
  7. package/src/EvmTypes.res.js +16 -0
  8. package/src/FetchState.res.js +969 -0
  9. package/src/Hasura.res.js +245 -0
  10. package/src/Internal.res.js +50 -0
  11. package/src/LazyLoader.res.js +117 -0
  12. package/src/LoadManager.res.js +124 -0
  13. package/src/LogSelection.res.js +203 -0
  14. package/src/Logging.res.js +247 -0
  15. package/src/Persistence.res.js +90 -0
  16. package/src/PgStorage.res +18 -4
  17. package/src/PgStorage.res.js +125 -0
  18. package/src/Prometheus.res.js +750 -0
  19. package/src/ReorgDetection.res.js +223 -0
  20. package/src/Throttler.res.js +60 -0
  21. package/src/Time.res.js +41 -0
  22. package/src/TopicFilter.res.js +86 -0
  23. package/src/Utils.res.js +527 -0
  24. package/src/bindings/BigDecimal.res.js +41 -0
  25. package/src/bindings/BigInt.res.js +138 -0
  26. package/src/bindings/Ethers.res.js +109 -0
  27. package/src/bindings/Express.res.js +2 -0
  28. package/src/bindings/Hrtime.res.js +66 -0
  29. package/src/bindings/NodeJs.res.js +29 -0
  30. package/src/bindings/Pino.res.js +95 -0
  31. package/src/bindings/Postgres.res.js +16 -0
  32. package/src/bindings/PromClient.res.js +17 -0
  33. package/src/bindings/Promise.res.js +25 -0
  34. package/src/bindings/SDSL.res.js +8 -0
  35. package/src/bindings/Viem.res.js +45 -0
  36. package/src/db/EntityHistory.res.js +307 -0
  37. package/src/db/Schema.res.js +54 -0
  38. package/src/db/Table.res.js +365 -0
  39. package/src/sources/Fuel.res.js +28 -0
  40. package/src/sources/HyperFuel.res.js +193 -0
  41. package/src/sources/HyperFuelClient.res.js +19 -0
  42. package/src/sources/HyperSync.res.js +301 -0
  43. package/src/sources/HyperSyncClient.res.js +99 -0
  44. package/src/sources/HyperSyncJsonApi.res.js +259 -0
  45. package/src/sources/Rpc.res.js +198 -0
  46. package/src/sources/Source.res.js +9 -0
  47. package/src/sources/SourceManager.res.js +366 -0
  48. package/src/vendored/Rest.res.js +574 -0
@@ -0,0 +1,969 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ var Caml = require("rescript/lib/js/caml.js");
5
+ var Utils = require("./Utils.res.js");
6
+ var Js_exn = require("rescript/lib/js/js_exn.js");
7
+ var Js_dict = require("rescript/lib/js/js_dict.js");
8
+ var Logging = require("./Logging.res.js");
9
+ var Belt_Int = require("rescript/lib/js/belt_Int.js");
10
+ var Caml_obj = require("rescript/lib/js/caml_obj.js");
11
+ var Belt_Array = require("rescript/lib/js/belt_Array.js");
12
+ var Prometheus = require("./Prometheus.res.js");
13
+ var Belt_Option = require("rescript/lib/js/belt_Option.js");
14
+ var Belt_Result = require("rescript/lib/js/belt_Result.js");
15
+ var Caml_option = require("rescript/lib/js/caml_option.js");
16
+ var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
17
+
18
+ function copy(fetchState) {
19
+ return {
20
+ partitions: fetchState.partitions,
21
+ nextPartitionIndex: fetchState.nextPartitionIndex,
22
+ isFetchingAtHead: fetchState.isFetchingAtHead,
23
+ endBlock: fetchState.endBlock,
24
+ maxAddrInPartition: fetchState.maxAddrInPartition,
25
+ firstEventBlockNumber: fetchState.firstEventBlockNumber,
26
+ normalSelection: fetchState.normalSelection,
27
+ indexingContracts: fetchState.indexingContracts,
28
+ contractConfigs: fetchState.contractConfigs,
29
+ dcsToStore: fetchState.dcsToStore,
30
+ chainId: fetchState.chainId,
31
+ latestFullyFetchedBlock: fetchState.latestFullyFetchedBlock,
32
+ blockLag: fetchState.blockLag,
33
+ queue: fetchState.queue.slice(0)
34
+ };
35
+ }
36
+
37
+ function eventItemGt(a, b) {
38
+ if (a.blockNumber > b.blockNumber) {
39
+ return true;
40
+ } else if (a.blockNumber === b.blockNumber) {
41
+ return a.logIndex > b.logIndex;
42
+ } else {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ function mergeSortedEventList(a, b) {
48
+ return Utils.$$Array.mergeSorted(eventItemGt, a, b);
49
+ }
50
+
51
+ function mergeIntoPartition(p, target, maxAddrInPartition) {
52
+ if (!p.selection.dependsOnAddresses) {
53
+ return [
54
+ p,
55
+ target
56
+ ];
57
+ }
58
+ if (!target.selection.dependsOnAddresses) {
59
+ return [
60
+ p,
61
+ target
62
+ ];
63
+ }
64
+ var latestFetchedBlock = target.latestFetchedBlock;
65
+ var mergedAddresses = {};
66
+ var allowedAddressesNumber = {
67
+ contents: maxAddrInPartition
68
+ };
69
+ Utils.Dict.forEachWithKey(target.addressesByContractName, (function (contractName, addresses) {
70
+ allowedAddressesNumber.contents = allowedAddressesNumber.contents - addresses.length | 0;
71
+ mergedAddresses[contractName] = addresses;
72
+ }));
73
+ Utils.Dict.forEachWithKey(p.addressesByContractName, (function (contractName, addresses) {
74
+ allowedAddressesNumber.contents = allowedAddressesNumber.contents - addresses.length | 0;
75
+ var targetAddresses = mergedAddresses[contractName];
76
+ if (targetAddresses !== undefined) {
77
+ mergedAddresses[contractName] = Belt_Array.concat(targetAddresses, addresses);
78
+ } else {
79
+ mergedAddresses[contractName] = addresses;
80
+ }
81
+ }));
82
+ var rest;
83
+ if (allowedAddressesNumber.contents < 0) {
84
+ var restAddresses = {};
85
+ Utils.Dict.forEachWithKey(mergedAddresses, (function (contractName, addresses) {
86
+ if (allowedAddressesNumber.contents === 0) {
87
+ return ;
88
+ }
89
+ if (addresses.length <= (-allowedAddressesNumber.contents | 0)) {
90
+ allowedAddressesNumber.contents = allowedAddressesNumber.contents + addresses.length | 0;
91
+ Utils.Dict.deleteInPlace(mergedAddresses, contractName);
92
+ restAddresses[contractName] = addresses;
93
+ return ;
94
+ }
95
+ var restFrom = addresses.length + allowedAddressesNumber.contents | 0;
96
+ mergedAddresses[contractName] = addresses.slice(0, restFrom);
97
+ restAddresses[contractName] = addresses.slice(restFrom);
98
+ allowedAddressesNumber.contents = 0;
99
+ }));
100
+ rest = {
101
+ id: p.id,
102
+ status: {
103
+ fetchingStateId: undefined
104
+ },
105
+ latestFetchedBlock: latestFetchedBlock,
106
+ selection: target.selection,
107
+ addressesByContractName: restAddresses
108
+ };
109
+ } else {
110
+ rest = undefined;
111
+ }
112
+ return [
113
+ {
114
+ id: target.id,
115
+ status: {
116
+ fetchingStateId: undefined
117
+ },
118
+ latestFetchedBlock: latestFetchedBlock,
119
+ selection: target.selection,
120
+ addressesByContractName: mergedAddresses
121
+ },
122
+ rest
123
+ ];
124
+ }
125
+
126
+ function checkIsWithinSyncRange(latestFetchedBlock, currentBlockHeight) {
127
+ return (currentBlockHeight - latestFetchedBlock.blockNumber) / currentBlockHeight <= 0.001;
128
+ }
129
+
130
+ function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexingContractsOpt, dcsToStoreOpt, currentBlockHeight, queueOpt) {
131
+ var partitions = partitionsOpt !== undefined ? partitionsOpt : fetchState.partitions;
132
+ var nextPartitionIndex = nextPartitionIndexOpt !== undefined ? nextPartitionIndexOpt : fetchState.nextPartitionIndex;
133
+ var indexingContracts = indexingContractsOpt !== undefined ? indexingContractsOpt : fetchState.indexingContracts;
134
+ var dcsToStore = dcsToStoreOpt !== undefined ? Caml_option.valFromOption(dcsToStoreOpt) : fetchState.dcsToStore;
135
+ var queue = queueOpt !== undefined ? queueOpt : fetchState.queue;
136
+ var firstPartition = partitions[0];
137
+ var latestFullyFetchedBlock = firstPartition.latestFetchedBlock;
138
+ for(var idx = 0 ,idx_finish = partitions.length; idx < idx_finish; ++idx){
139
+ var p = partitions[idx];
140
+ if (latestFullyFetchedBlock.blockNumber > p.latestFetchedBlock.blockNumber) {
141
+ latestFullyFetchedBlock = p.latestFetchedBlock;
142
+ }
143
+
144
+ }
145
+ var latestFullyFetchedBlock$1 = latestFullyFetchedBlock;
146
+ var isFetchingAtHead = currentBlockHeight !== undefined ? (
147
+ latestFullyFetchedBlock$1.blockNumber >= currentBlockHeight ? true : fetchState.isFetchingAtHead && checkIsWithinSyncRange(latestFullyFetchedBlock$1, currentBlockHeight)
148
+ ) : fetchState.isFetchingAtHead;
149
+ var queueSize = queue.length;
150
+ Prometheus.IndexingPartitions.set(partitions.length, fetchState.chainId);
151
+ Prometheus.IndexingBufferSize.set(queueSize, fetchState.chainId);
152
+ Prometheus.IndexingBufferBlockNumber.set(latestFullyFetchedBlock$1.blockNumber, fetchState.chainId);
153
+ var item = Utils.$$Array.last(queue);
154
+ return {
155
+ partitions: partitions,
156
+ nextPartitionIndex: nextPartitionIndex,
157
+ isFetchingAtHead: isFetchingAtHead,
158
+ endBlock: fetchState.endBlock,
159
+ maxAddrInPartition: fetchState.maxAddrInPartition,
160
+ firstEventBlockNumber: item !== undefined ? Utils.$$Math.minOptInt(fetchState.firstEventBlockNumber, item.blockNumber) : fetchState.firstEventBlockNumber,
161
+ normalSelection: fetchState.normalSelection,
162
+ indexingContracts: indexingContracts,
163
+ contractConfigs: fetchState.contractConfigs,
164
+ dcsToStore: dcsToStore,
165
+ chainId: fetchState.chainId,
166
+ latestFullyFetchedBlock: latestFullyFetchedBlock$1,
167
+ blockLag: fetchState.blockLag,
168
+ queue: queue
169
+ };
170
+ }
171
+
172
+ function numAddresses(fetchState) {
173
+ return Object.keys(fetchState.indexingContracts).length;
174
+ }
175
+
176
+ function warnDifferentContractType(fetchState, existingContract, dc) {
177
+ var logger = Logging.createChild({
178
+ chainId: fetchState.chainId,
179
+ contractAddress: dc.address,
180
+ existingContractType: existingContract.contractName,
181
+ newContractType: dc.contractName
182
+ });
183
+ Logging.childWarn(logger, "Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.");
184
+ }
185
+
186
+ function registerDynamicContracts(fetchState, dynamicContracts, currentBlockHeight) {
187
+ if (Utils.$$Array.isEmpty(fetchState.normalSelection.eventConfigs)) {
188
+ Js_exn.raiseError("Invalid configuration. No events to fetch for the dynamic contract registration.");
189
+ }
190
+ var indexingContracts = fetchState.indexingContracts;
191
+ var registeringContracts = {};
192
+ var addressesByContractName = {};
193
+ var earliestRegisteringEventBlockNumber = Infinity;
194
+ var hasDCWithFilterByAddresses = false;
195
+ for(var idx = 0 ,idx_finish = dynamicContracts.length; idx < idx_finish; ++idx){
196
+ var dc = dynamicContracts[idx];
197
+ var match = fetchState.contractConfigs[dc.contractName];
198
+ if (match !== undefined) {
199
+ var existingContract = indexingContracts[dc.address];
200
+ if (existingContract !== undefined) {
201
+ if (existingContract.contractName !== dc.contractName) {
202
+ warnDifferentContractType(fetchState, existingContract, dc);
203
+ } else if (existingContract.startBlock > dc.startBlock) {
204
+ var logger = Logging.createChild({
205
+ chainId: fetchState.chainId,
206
+ contractAddress: dc.address,
207
+ existingBlockNumber: existingContract.startBlock,
208
+ newBlockNumber: dc.startBlock
209
+ });
210
+ Logging.childWarn(logger, "Skipping contract registration: Contract address is already registered at a later block number. Currently registration of the same contract address is not supported by Envio. Reach out to us if it's a problem for you.");
211
+ }
212
+
213
+ } else {
214
+ var registeringContract = registeringContracts[dc.address];
215
+ var shouldUpdate;
216
+ if (registeringContract !== undefined) {
217
+ if (registeringContract.contractName !== dc.contractName) {
218
+ warnDifferentContractType(fetchState, registeringContract, dc);
219
+ shouldUpdate = false;
220
+ } else {
221
+ var match$1 = registeringContract.register;
222
+ var match$2 = dc.register;
223
+ shouldUpdate = typeof match$1 !== "object" || typeof match$2 !== "object" ? Js_exn.raiseError("Unexpected case: Config registration should be handled in a different function") : registeringContract.startBlock > dc.startBlock || registeringContract.startBlock === dc.startBlock && match$1.registeringEventLogIndex > match$2.registeringEventLogIndex;
224
+ }
225
+ } else {
226
+ hasDCWithFilterByAddresses = hasDCWithFilterByAddresses || match.filterByAddresses;
227
+ Utils.Dict.push(addressesByContractName, dc.contractName, dc.address);
228
+ shouldUpdate = true;
229
+ }
230
+ if (shouldUpdate) {
231
+ earliestRegisteringEventBlockNumber = earliestRegisteringEventBlockNumber < dc.startBlock ? earliestRegisteringEventBlockNumber : dc.startBlock;
232
+ registeringContracts[dc.address] = dc;
233
+ }
234
+
235
+ }
236
+ } else {
237
+ var logger$1 = Logging.createChild({
238
+ chainId: fetchState.chainId,
239
+ contractAddress: dc.address,
240
+ contractName: dc.contractName
241
+ });
242
+ Logging.childWarn(logger$1, "Skipping contract registration: Contract doesn't have any events to fetch.");
243
+ }
244
+ }
245
+ var dcsToStore = Js_dict.values(registeringContracts);
246
+ if (dcsToStore.length === 0) {
247
+ return fetchState;
248
+ }
249
+ var newPartitions;
250
+ if (dcsToStore.length <= fetchState.maxAddrInPartition && !hasDCWithFilterByAddresses) {
251
+ newPartitions = [{
252
+ id: String(fetchState.nextPartitionIndex),
253
+ status: {
254
+ fetchingStateId: undefined
255
+ },
256
+ latestFetchedBlock: {
257
+ blockNumber: earliestRegisteringEventBlockNumber - 1 | 0,
258
+ blockTimestamp: 0
259
+ },
260
+ selection: fetchState.normalSelection,
261
+ addressesByContractName: addressesByContractName
262
+ }];
263
+ } else {
264
+ var partitions = [];
265
+ var earliestRegisteringEventBlockNumber$1 = {
266
+ contents: Infinity
267
+ };
268
+ var pendingAddressesByContractName = {
269
+ contents: {}
270
+ };
271
+ var pendingCount = 0;
272
+ var addPartition = function () {
273
+ partitions.push({
274
+ id: String(fetchState.nextPartitionIndex + partitions.length | 0),
275
+ status: {
276
+ fetchingStateId: undefined
277
+ },
278
+ latestFetchedBlock: {
279
+ blockNumber: earliestRegisteringEventBlockNumber$1.contents - 1 | 0,
280
+ blockTimestamp: 0
281
+ },
282
+ selection: fetchState.normalSelection,
283
+ addressesByContractName: pendingAddressesByContractName.contents
284
+ });
285
+ };
286
+ for(var idx$1 = 0 ,idx_finish$1 = Object.keys(addressesByContractName).length; idx$1 < idx_finish$1; ++idx$1){
287
+ var contractName = Object.keys(addressesByContractName)[idx$1];
288
+ var addresses = addressesByContractName[contractName];
289
+ var contractConfig = fetchState.contractConfigs[contractName];
290
+ if (contractConfig.filterByAddresses) {
291
+ var byStartBlock = {};
292
+ for(var jdx = 0 ,jdx_finish = addresses.length; jdx < jdx_finish; ++jdx){
293
+ var address = addresses[jdx];
294
+ var indexingContract = registeringContracts[address];
295
+ Utils.Dict.push(byStartBlock, String(indexingContract.startBlock), address);
296
+ }
297
+ Object.keys(byStartBlock).forEach((function(contractName,byStartBlock){
298
+ return function (startBlockKey) {
299
+ var addresses = byStartBlock[startBlockKey];
300
+ var addressesByContractName = {};
301
+ addressesByContractName[contractName] = addresses;
302
+ partitions.push({
303
+ id: String(fetchState.nextPartitionIndex + partitions.length | 0),
304
+ status: {
305
+ fetchingStateId: undefined
306
+ },
307
+ latestFetchedBlock: {
308
+ blockNumber: Caml.int_max(Belt_Option.getExn(Belt_Int.fromString(startBlockKey)) - 1 | 0, 0),
309
+ blockTimestamp: 0
310
+ },
311
+ selection: fetchState.normalSelection,
312
+ addressesByContractName: addressesByContractName
313
+ });
314
+ }
315
+ }(contractName,byStartBlock)));
316
+ } else {
317
+ for(var jdx$1 = 0 ,jdx_finish$1 = addresses.length; jdx$1 < jdx_finish$1; ++jdx$1){
318
+ var address$1 = addresses[jdx$1];
319
+ if (pendingCount === fetchState.maxAddrInPartition) {
320
+ addPartition();
321
+ pendingAddressesByContractName.contents = {};
322
+ pendingCount = 0;
323
+ earliestRegisteringEventBlockNumber$1.contents = Infinity;
324
+ }
325
+ var indexingContract$1 = registeringContracts[address$1];
326
+ pendingCount = pendingCount + 1 | 0;
327
+ Utils.Dict.push(pendingAddressesByContractName.contents, contractName, address$1);
328
+ earliestRegisteringEventBlockNumber$1.contents = earliestRegisteringEventBlockNumber$1.contents < indexingContract$1.startBlock ? earliestRegisteringEventBlockNumber$1.contents : indexingContract$1.startBlock;
329
+ }
330
+ }
331
+ }
332
+ if (pendingCount > 0) {
333
+ addPartition();
334
+ }
335
+ newPartitions = partitions;
336
+ }
337
+ Prometheus.IndexingAddresses.set(Object.keys(fetchState.indexingContracts).length + dcsToStore.length | 0, fetchState.chainId);
338
+ var existingDcs = fetchState.dcsToStore;
339
+ return updateInternal(fetchState, fetchState.partitions.concat(newPartitions), fetchState.nextPartitionIndex + newPartitions.length | 0, Object.assign(registeringContracts, indexingContracts), Caml_option.some(existingDcs !== undefined ? Belt_Array.concat(existingDcs, dcsToStore) : dcsToStore), currentBlockHeight, undefined);
340
+ }
341
+
342
+ var UnexpectedPartitionNotFound = /* @__PURE__ */Caml_exceptions.create("FetchState.UnexpectedPartitionNotFound");
343
+
344
+ var UnexpectedMergeQueryResponse = /* @__PURE__ */Caml_exceptions.create("FetchState.UnexpectedMergeQueryResponse");
345
+
346
+ function handleQueryResult(fetchState, query, latestFetchedBlock, reversedNewItems, currentBlockHeight) {
347
+ var partitions = fetchState.partitions;
348
+ var partitionId = query.partitionId;
349
+ var pIndex = Belt_Array.getIndexBy(partitions, (function (p) {
350
+ return p.id === partitionId;
351
+ }));
352
+ var tmp;
353
+ if (pIndex !== undefined) {
354
+ var p = partitions[pIndex];
355
+ var updatedPartition_id = p.id;
356
+ var updatedPartition_status = {
357
+ fetchingStateId: undefined
358
+ };
359
+ var updatedPartition_selection = p.selection;
360
+ var updatedPartition_addressesByContractName = p.addressesByContractName;
361
+ var updatedPartition = {
362
+ id: updatedPartition_id,
363
+ status: updatedPartition_status,
364
+ latestFetchedBlock: latestFetchedBlock,
365
+ selection: updatedPartition_selection,
366
+ addressesByContractName: updatedPartition_addressesByContractName
367
+ };
368
+ var match = query.target;
369
+ var exit = 0;
370
+ if (typeof match !== "object" || match.TAG === "EndBlock") {
371
+ exit = 1;
372
+ } else {
373
+ var intoPartitionId = match.intoPartitionId;
374
+ var targetIndex = Belt_Array.getIndexBy(partitions, (function (p) {
375
+ return p.id === intoPartitionId;
376
+ }));
377
+ var exit$1 = 0;
378
+ if (targetIndex !== undefined && partitions[targetIndex].latestFetchedBlock.blockNumber === latestFetchedBlock.blockNumber) {
379
+ var target = partitions[targetIndex];
380
+ var match$1 = mergeIntoPartition(updatedPartition, target, fetchState.maxAddrInPartition);
381
+ var rest = match$1[1];
382
+ var updatedPartitions = Utils.$$Array.setIndexImmutable(partitions, targetIndex, match$1[0]);
383
+ var updatedPartitions$1 = rest !== undefined ? (updatedPartitions[pIndex] = rest, updatedPartitions) : Utils.$$Array.removeAtIndex(updatedPartitions, pIndex);
384
+ tmp = {
385
+ TAG: "Ok",
386
+ _0: updatedPartitions$1
387
+ };
388
+ } else {
389
+ exit$1 = 2;
390
+ }
391
+ if (exit$1 === 2) {
392
+ tmp = {
393
+ TAG: "Ok",
394
+ _0: Utils.$$Array.setIndexImmutable(partitions, pIndex, updatedPartition)
395
+ };
396
+ }
397
+
398
+ }
399
+ if (exit === 1) {
400
+ tmp = {
401
+ TAG: "Ok",
402
+ _0: Utils.$$Array.setIndexImmutable(partitions, pIndex, updatedPartition)
403
+ };
404
+ }
405
+
406
+ } else {
407
+ tmp = {
408
+ TAG: "Error",
409
+ _0: {
410
+ RE_EXN_ID: UnexpectedPartitionNotFound,
411
+ partitionId: partitionId
412
+ }
413
+ };
414
+ }
415
+ return Belt_Result.map(tmp, (function (partitions) {
416
+ return updateInternal(fetchState, partitions, undefined, undefined, undefined, currentBlockHeight, mergeSortedEventList(reversedNewItems, fetchState.queue));
417
+ }));
418
+ }
419
+
420
+ function makePartitionQuery(p, indexingContracts, endBlock, mergeTarget) {
421
+ var latestFetchedBlockNumber = p.latestFetchedBlock.blockNumber;
422
+ var fromBlock = latestFetchedBlockNumber !== 0 ? latestFetchedBlockNumber + 1 | 0 : 0;
423
+ var tmp;
424
+ var exit = 0;
425
+ if (endBlock !== undefined) {
426
+ if (fromBlock > endBlock) {
427
+ tmp = undefined;
428
+ } else if (mergeTarget !== undefined) {
429
+ exit = 1;
430
+ } else {
431
+ tmp = {
432
+ TAG: "EndBlock",
433
+ toBlock: endBlock
434
+ };
435
+ }
436
+ } else if (mergeTarget !== undefined) {
437
+ exit = 1;
438
+ } else {
439
+ tmp = "Head";
440
+ }
441
+ if (exit === 1) {
442
+ tmp = {
443
+ TAG: "Merge",
444
+ intoPartitionId: mergeTarget.id,
445
+ toBlock: mergeTarget.latestFetchedBlock.blockNumber
446
+ };
447
+ }
448
+ return Belt_Option.map(tmp, (function (target) {
449
+ return {
450
+ partitionId: p.id,
451
+ fromBlock: fromBlock,
452
+ selection: p.selection,
453
+ addressesByContractName: p.addressesByContractName,
454
+ target: target,
455
+ indexingContracts: indexingContracts
456
+ };
457
+ }));
458
+ }
459
+
460
+ function startFetchingQueries(param, queries, stateId) {
461
+ var partitions = param.partitions;
462
+ Belt_Array.forEach(queries, (function (q) {
463
+ var p = partitions.find(function (p) {
464
+ return p.id === q.partitionId;
465
+ });
466
+ if (p !== undefined) {
467
+ p.status.fetchingStateId = stateId;
468
+ return ;
469
+ } else {
470
+ return Js_exn.raiseError("Unexpected case: Couldn't find partition for the fetching query");
471
+ }
472
+ }));
473
+ }
474
+
475
+ function addressesByContractNameCount(addressesByContractName) {
476
+ var numAddresses = 0;
477
+ var contractNames = Object.keys(addressesByContractName);
478
+ for(var idx = 0 ,idx_finish = contractNames.length; idx < idx_finish; ++idx){
479
+ var contractName = contractNames[idx];
480
+ numAddresses = numAddresses + addressesByContractName[contractName].length | 0;
481
+ }
482
+ return numAddresses;
483
+ }
484
+
485
+ function addressesByContractNameGetAll(addressesByContractName) {
486
+ var all = [];
487
+ var contractNames = Object.keys(addressesByContractName);
488
+ for(var idx = 0 ,idx_finish = contractNames.length; idx < idx_finish; ++idx){
489
+ var contractName = contractNames[idx];
490
+ all = Belt_Array.concat(all, addressesByContractName[contractName]);
491
+ }
492
+ return all;
493
+ }
494
+
495
+ function isFullPartition(p, maxAddrInPartition) {
496
+ if (p.selection.dependsOnAddresses) {
497
+ return addressesByContractNameCount(p.addressesByContractName) >= maxAddrInPartition;
498
+ } else {
499
+ return true;
500
+ }
501
+ }
502
+
503
+ function getNextQuery(param, concurrencyLimit, targetBufferSize, currentBlockHeight, stateId) {
504
+ if (currentBlockHeight === 0) {
505
+ return "WaitingForNewBlock";
506
+ }
507
+ if (concurrencyLimit === 0) {
508
+ return "ReachedMaxConcurrency";
509
+ }
510
+ var queue = param.queue;
511
+ var blockLag = param.blockLag;
512
+ var indexingContracts = param.indexingContracts;
513
+ var maxAddrInPartition = param.maxAddrInPartition;
514
+ var endBlock = param.endBlock;
515
+ var partitions = param.partitions;
516
+ var headBlock = currentBlockHeight - Belt_Option.getWithDefault(blockLag, 0) | 0;
517
+ var fullPartitions = [];
518
+ var mergingPartitions = [];
519
+ var areMergingPartitionsFetching = false;
520
+ var mostBehindMergingPartition;
521
+ var mergingPartitionTarget;
522
+ var shouldWaitForNewBlock = endBlock !== undefined ? headBlock < endBlock : true;
523
+ var checkIsFetchingPartition = function (p) {
524
+ var fetchingStateId = p.status.fetchingStateId;
525
+ if (fetchingStateId !== undefined) {
526
+ return stateId <= fetchingStateId;
527
+ } else {
528
+ return false;
529
+ }
530
+ };
531
+ for(var idx = 0 ,idx_finish = partitions.length; idx < idx_finish; ++idx){
532
+ var p = partitions[idx];
533
+ var isFetching = checkIsFetchingPartition(p);
534
+ var hasReachedTheHead = p.latestFetchedBlock.blockNumber >= headBlock;
535
+ if (isFetching || !hasReachedTheHead) {
536
+ shouldWaitForNewBlock = false;
537
+ }
538
+ if (p.selection.dependsOnAddresses ? addressesByContractNameCount(p.addressesByContractName) >= maxAddrInPartition : true) {
539
+ fullPartitions.push(p);
540
+ } else {
541
+ mergingPartitions.push(p);
542
+ var mostBehindMergingPartition$1 = mostBehindMergingPartition;
543
+ var tmp;
544
+ if (mostBehindMergingPartition$1 !== undefined) {
545
+ if (mostBehindMergingPartition$1.latestFetchedBlock.blockNumber === p.latestFetchedBlock.blockNumber) {
546
+ tmp = mostBehindMergingPartition$1;
547
+ } else if (mostBehindMergingPartition$1.latestFetchedBlock.blockNumber < p.latestFetchedBlock.blockNumber) {
548
+ var mergingPartitionTarget$1 = mergingPartitionTarget;
549
+ mergingPartitionTarget = mergingPartitionTarget$1 !== undefined && mergingPartitionTarget$1.latestFetchedBlock.blockNumber < p.latestFetchedBlock.blockNumber ? mergingPartitionTarget$1 : p;
550
+ tmp = mostBehindMergingPartition$1;
551
+ } else {
552
+ mergingPartitionTarget = mostBehindMergingPartition$1;
553
+ tmp = p;
554
+ }
555
+ } else {
556
+ tmp = p;
557
+ }
558
+ mostBehindMergingPartition = tmp;
559
+ if (isFetching) {
560
+ areMergingPartitionsFetching = true;
561
+ }
562
+
563
+ }
564
+ }
565
+ var targetBlockIdx = queue.length - targetBufferSize | 0;
566
+ var maxQueryBlockNumber;
567
+ if (targetBlockIdx < 0) {
568
+ maxQueryBlockNumber = currentBlockHeight;
569
+ } else {
570
+ var item = Belt_Array.get(queue, targetBlockIdx);
571
+ maxQueryBlockNumber = item !== undefined && item.blockNumber < currentBlockHeight ? item.blockNumber : currentBlockHeight;
572
+ }
573
+ var queries = [];
574
+ var registerPartitionQuery = function (p, mergeTarget) {
575
+ if (!(!checkIsFetchingPartition(p) && p.latestFetchedBlock.blockNumber < maxQueryBlockNumber)) {
576
+ return ;
577
+ }
578
+ var q = makePartitionQuery(p, indexingContracts, blockLag !== undefined ? (
579
+ endBlock !== undefined ? (
580
+ headBlock < endBlock ? headBlock : endBlock
581
+ ) : headBlock
582
+ ) : endBlock, mergeTarget);
583
+ if (q !== undefined) {
584
+ queries.push(q);
585
+ return ;
586
+ }
587
+
588
+ };
589
+ Belt_Array.forEach(fullPartitions, (function (p) {
590
+ registerPartitionQuery(p, undefined);
591
+ }));
592
+ if (!areMergingPartitionsFetching) {
593
+ var len = mergingPartitions.length;
594
+ if (len !== 1) {
595
+ if (len !== 0) {
596
+ var match = mostBehindMergingPartition;
597
+ var match$1 = mergingPartitionTarget;
598
+ if (match !== undefined) {
599
+ if (match$1 !== undefined) {
600
+ registerPartitionQuery(match, match$1);
601
+ } else {
602
+ registerPartitionQuery(match, undefined);
603
+ }
604
+ } else {
605
+ Js_exn.raiseError("Unexpected case, should always have a most behind partition.");
606
+ }
607
+ }
608
+
609
+ } else {
610
+ var p$1 = mergingPartitions[0];
611
+ registerPartitionQuery(p$1, undefined);
612
+ }
613
+ }
614
+ if (Utils.$$Array.isEmpty(queries)) {
615
+ if (shouldWaitForNewBlock) {
616
+ return "WaitingForNewBlock";
617
+ } else {
618
+ return "NothingToQuery";
619
+ }
620
+ } else {
621
+ return {
622
+ TAG: "Ready",
623
+ _0: queries.length > concurrencyLimit ? queries.sort(function (a, b) {
624
+ return a.fromBlock - b.fromBlock | 0;
625
+ }).slice(0, concurrencyLimit) : queries
626
+ };
627
+ }
628
+ }
629
+
630
+ function queueItemBlockNumber(queueItem) {
631
+ if (queueItem.TAG === "Item") {
632
+ return queueItem._0.item.blockNumber;
633
+ }
634
+ var blockNumber = queueItem.latestFetchedBlock.blockNumber;
635
+ if (blockNumber === 0) {
636
+ return 0;
637
+ } else {
638
+ return blockNumber + 1 | 0;
639
+ }
640
+ }
641
+
642
+ function queueItemIsInReorgThreshold(queueItem, currentBlockHeight, highestBlockBelowThreshold) {
643
+ if (currentBlockHeight === 0) {
644
+ return false;
645
+ } else {
646
+ return queueItemBlockNumber(queueItem) > highestBlockBelowThreshold;
647
+ }
648
+ }
649
+
650
+ function makeNoItem(param) {
651
+ return {
652
+ TAG: "NoItem",
653
+ latestFetchedBlock: param.latestFetchedBlock
654
+ };
655
+ }
656
+
657
+ function qItemLt(a, b) {
658
+ var aBlockNumber = queueItemBlockNumber(a);
659
+ var bBlockNumber = queueItemBlockNumber(b);
660
+ if (aBlockNumber < bBlockNumber) {
661
+ return true;
662
+ } else if (aBlockNumber === bBlockNumber) {
663
+ if (a.TAG === "Item") {
664
+ if (b.TAG === "Item") {
665
+ return a._0.item.logIndex < b._0.item.logIndex;
666
+ } else {
667
+ return false;
668
+ }
669
+ } else if (b.TAG === "Item") {
670
+ return true;
671
+ } else {
672
+ return false;
673
+ }
674
+ } else {
675
+ return false;
676
+ }
677
+ }
678
+
679
+ function getEarliestEvent(param) {
680
+ var queue = param.queue;
681
+ var latestFullyFetchedBlock = param.latestFullyFetchedBlock;
682
+ var item = Utils.$$Array.last(queue);
683
+ if (item !== undefined && item.blockNumber <= latestFullyFetchedBlock.blockNumber) {
684
+ return {
685
+ TAG: "Item",
686
+ _0: {
687
+ item: item,
688
+ popItemOffQueue: (function () {
689
+ queue.pop();
690
+ })
691
+ }
692
+ };
693
+ } else {
694
+ return {
695
+ TAG: "NoItem",
696
+ latestFetchedBlock: latestFullyFetchedBlock
697
+ };
698
+ }
699
+ }
700
+
701
+ function make(startBlock, endBlock, eventConfigs, staticContracts, dynamicContracts, maxAddrInPartition, chainId, blockLag) {
702
+ var latestFetchedBlock_blockNumber = startBlock - 1 | 0;
703
+ var latestFetchedBlock = {
704
+ blockNumber: latestFetchedBlock_blockNumber,
705
+ blockTimestamp: 0
706
+ };
707
+ var notDependingOnAddresses = [];
708
+ var normalEventConfigs = [];
709
+ var contractNamesWithNormalEvents = new Set();
710
+ var indexingContracts = {};
711
+ var contractConfigs = {};
712
+ Belt_Array.forEach(eventConfigs, (function (ec) {
713
+ var match = contractConfigs[ec.contractName];
714
+ if (match !== undefined) {
715
+ contractConfigs[ec.contractName] = {
716
+ filterByAddresses: match.filterByAddresses || ec.filterByAddresses
717
+ };
718
+ } else {
719
+ contractConfigs[ec.contractName] = {
720
+ filterByAddresses: ec.filterByAddresses
721
+ };
722
+ }
723
+ if (ec.dependsOnAddresses) {
724
+ normalEventConfigs.push(ec);
725
+ contractNamesWithNormalEvents.add(ec.contractName);
726
+ } else {
727
+ notDependingOnAddresses.push(ec);
728
+ }
729
+ }));
730
+ var partitions = [];
731
+ if (notDependingOnAddresses.length !== 0) {
732
+ partitions.push({
733
+ id: String(partitions.length),
734
+ status: {
735
+ fetchingStateId: undefined
736
+ },
737
+ latestFetchedBlock: latestFetchedBlock,
738
+ selection: {
739
+ eventConfigs: notDependingOnAddresses,
740
+ dependsOnAddresses: false
741
+ },
742
+ addressesByContractName: {}
743
+ });
744
+ }
745
+ var normalSelection = {
746
+ eventConfigs: normalEventConfigs,
747
+ dependsOnAddresses: true
748
+ };
749
+ if (normalEventConfigs.length !== 0) {
750
+ var makePendingNormalPartition = function () {
751
+ return {
752
+ id: String(partitions.length),
753
+ status: {
754
+ fetchingStateId: undefined
755
+ },
756
+ latestFetchedBlock: latestFetchedBlock,
757
+ selection: normalSelection,
758
+ addressesByContractName: {}
759
+ };
760
+ };
761
+ var pendingNormalPartition = {
762
+ contents: makePendingNormalPartition()
763
+ };
764
+ var registerAddress = function (contractName, address, dc) {
765
+ var pendingPartition = pendingNormalPartition.contents;
766
+ var addresses = pendingPartition.addressesByContractName[contractName];
767
+ if (addresses !== undefined) {
768
+ addresses.push(address);
769
+ } else {
770
+ pendingPartition.addressesByContractName[contractName] = [address];
771
+ }
772
+ indexingContracts[address] = dc !== undefined ? dc : ({
773
+ address: address,
774
+ contractName: contractName,
775
+ startBlock: startBlock,
776
+ register: "Config"
777
+ });
778
+ if (addressesByContractNameCount(pendingPartition.addressesByContractName) === maxAddrInPartition) {
779
+ partitions.push(pendingPartition);
780
+ pendingNormalPartition.contents = makePendingNormalPartition();
781
+ return ;
782
+ }
783
+
784
+ };
785
+ Belt_Array.forEach(Js_dict.entries(staticContracts), (function (param) {
786
+ var contractName = param[0];
787
+ if (contractNamesWithNormalEvents.has(contractName)) {
788
+ return Belt_Array.forEach(param[1], (function (a) {
789
+ registerAddress(contractName, a, undefined);
790
+ }));
791
+ }
792
+
793
+ }));
794
+ Belt_Array.forEach(dynamicContracts, (function (dc) {
795
+ var contractName = dc.contractName;
796
+ if (contractNamesWithNormalEvents.has(contractName)) {
797
+ return registerAddress(contractName, dc.address, dc);
798
+ }
799
+
800
+ }));
801
+ if (addressesByContractNameCount(pendingNormalPartition.contents.addressesByContractName) > 0) {
802
+ partitions.push(pendingNormalPartition.contents);
803
+ }
804
+
805
+ }
806
+ if (partitions.length === 0) {
807
+ Js_exn.raiseError("Invalid configuration: Nothing to fetch. Make sure that you provided at least one contract address to index, or have events with Wildcard mode enabled.");
808
+ }
809
+ var numAddresses = Object.keys(indexingContracts).length;
810
+ Prometheus.IndexingAddresses.set(numAddresses, chainId);
811
+ Prometheus.IndexingPartitions.set(partitions.length, chainId);
812
+ Prometheus.IndexingBufferSize.set(0, chainId);
813
+ Prometheus.IndexingBufferBlockNumber.set(latestFetchedBlock_blockNumber, chainId);
814
+ if (endBlock !== undefined) {
815
+ Prometheus.IndexingEndBlock.set(endBlock, chainId);
816
+ }
817
+ return {
818
+ partitions: partitions,
819
+ nextPartitionIndex: partitions.length,
820
+ isFetchingAtHead: false,
821
+ endBlock: endBlock,
822
+ maxAddrInPartition: maxAddrInPartition,
823
+ firstEventBlockNumber: undefined,
824
+ normalSelection: normalSelection,
825
+ indexingContracts: indexingContracts,
826
+ contractConfigs: contractConfigs,
827
+ dcsToStore: undefined,
828
+ chainId: chainId,
829
+ latestFullyFetchedBlock: latestFetchedBlock,
830
+ blockLag: blockLag,
831
+ queue: []
832
+ };
833
+ }
834
+
835
+ function queueSize(param) {
836
+ return param.queue.length;
837
+ }
838
+
839
+ function getLatestFullyFetchedBlock(param) {
840
+ return param.latestFullyFetchedBlock;
841
+ }
842
+
843
+ function pruneQueueFromFirstChangeEvent(queue, firstChangeEvent) {
844
+ return Belt_Array.keep(queue, (function (item) {
845
+ return Caml_obj.lessthan([
846
+ item.blockNumber,
847
+ item.logIndex
848
+ ], [
849
+ firstChangeEvent.blockNumber,
850
+ firstChangeEvent.logIndex
851
+ ]);
852
+ }));
853
+ }
854
+
855
+ function rollbackPartition(p, firstChangeEvent, addressesToRemove) {
856
+ if (!p.selection.dependsOnAddresses) {
857
+ return {
858
+ id: p.id,
859
+ status: {
860
+ fetchingStateId: undefined
861
+ },
862
+ latestFetchedBlock: p.latestFetchedBlock,
863
+ selection: p.selection,
864
+ addressesByContractName: p.addressesByContractName
865
+ };
866
+ }
867
+ var rollbackedAddressesByContractName = {};
868
+ Utils.Dict.forEachWithKey(p.addressesByContractName, (function (contractName, addresses) {
869
+ var keptAddresses = Belt_Array.keep(addresses, (function (address) {
870
+ return !addressesToRemove.has(address);
871
+ }));
872
+ if (keptAddresses.length !== 0) {
873
+ rollbackedAddressesByContractName[contractName] = keptAddresses;
874
+ return ;
875
+ }
876
+
877
+ }));
878
+ if (Object.keys(rollbackedAddressesByContractName).length === 0) {
879
+ return ;
880
+ }
881
+ var shouldRollbackFetched = p.latestFetchedBlock.blockNumber >= firstChangeEvent.blockNumber;
882
+ return {
883
+ id: p.id,
884
+ status: {
885
+ fetchingStateId: undefined
886
+ },
887
+ latestFetchedBlock: shouldRollbackFetched ? ({
888
+ blockNumber: firstChangeEvent.blockNumber - 1 | 0,
889
+ blockTimestamp: 0
890
+ }) : p.latestFetchedBlock,
891
+ selection: p.selection,
892
+ addressesByContractName: rollbackedAddressesByContractName
893
+ };
894
+ }
895
+
896
+ function rollback(fetchState, firstChangeEvent) {
897
+ var addressesToRemove = new Set();
898
+ var indexingContracts = {};
899
+ Belt_Array.forEach(Object.keys(fetchState.indexingContracts), (function (address) {
900
+ var indexingContract = fetchState.indexingContracts[address];
901
+ var dc = indexingContract.register;
902
+ var tmp;
903
+ tmp = typeof dc !== "object" ? true : indexingContract.startBlock < firstChangeEvent.blockNumber || indexingContract.startBlock === firstChangeEvent.blockNumber && dc.registeringEventLogIndex < firstChangeEvent.logIndex;
904
+ if (tmp) {
905
+ indexingContracts[address] = indexingContract;
906
+ } else {
907
+ addressesToRemove.add(address);
908
+ }
909
+ }));
910
+ var partitions = Belt_Array.keepMap(fetchState.partitions, (function (p) {
911
+ return rollbackPartition(p, firstChangeEvent, addressesToRemove);
912
+ }));
913
+ var dcsToStore = fetchState.dcsToStore;
914
+ var tmp;
915
+ if (dcsToStore !== undefined) {
916
+ var filtered = dcsToStore.filter(function (dc) {
917
+ return !addressesToRemove.has(dc.address);
918
+ });
919
+ tmp = filtered.length !== 0 ? filtered : undefined;
920
+ } else {
921
+ tmp = undefined;
922
+ }
923
+ return updateInternal(fetchState, partitions, undefined, indexingContracts, Caml_option.some(tmp), undefined, pruneQueueFromFirstChangeEvent(fetchState.queue, firstChangeEvent));
924
+ }
925
+
926
+ function isActivelyIndexing(fetchState) {
927
+ var endBlock = fetchState.endBlock;
928
+ if (endBlock === undefined) {
929
+ return true;
930
+ }
931
+ var isPastEndblock = fetchState.latestFullyFetchedBlock.blockNumber >= endBlock;
932
+ if (isPastEndblock) {
933
+ return queueSize(fetchState) > 0;
934
+ } else {
935
+ return true;
936
+ }
937
+ }
938
+
939
+ exports.copy = copy;
940
+ exports.eventItemGt = eventItemGt;
941
+ exports.mergeSortedEventList = mergeSortedEventList;
942
+ exports.mergeIntoPartition = mergeIntoPartition;
943
+ exports.checkIsWithinSyncRange = checkIsWithinSyncRange;
944
+ exports.updateInternal = updateInternal;
945
+ exports.numAddresses = numAddresses;
946
+ exports.warnDifferentContractType = warnDifferentContractType;
947
+ exports.registerDynamicContracts = registerDynamicContracts;
948
+ exports.UnexpectedPartitionNotFound = UnexpectedPartitionNotFound;
949
+ exports.UnexpectedMergeQueryResponse = UnexpectedMergeQueryResponse;
950
+ exports.handleQueryResult = handleQueryResult;
951
+ exports.makePartitionQuery = makePartitionQuery;
952
+ exports.startFetchingQueries = startFetchingQueries;
953
+ exports.addressesByContractNameCount = addressesByContractNameCount;
954
+ exports.addressesByContractNameGetAll = addressesByContractNameGetAll;
955
+ exports.isFullPartition = isFullPartition;
956
+ exports.getNextQuery = getNextQuery;
957
+ exports.queueItemBlockNumber = queueItemBlockNumber;
958
+ exports.queueItemIsInReorgThreshold = queueItemIsInReorgThreshold;
959
+ exports.makeNoItem = makeNoItem;
960
+ exports.qItemLt = qItemLt;
961
+ exports.getEarliestEvent = getEarliestEvent;
962
+ exports.make = make;
963
+ exports.queueSize = queueSize;
964
+ exports.getLatestFullyFetchedBlock = getLatestFullyFetchedBlock;
965
+ exports.pruneQueueFromFirstChangeEvent = pruneQueueFromFirstChangeEvent;
966
+ exports.rollbackPartition = rollbackPartition;
967
+ exports.rollback = rollback;
968
+ exports.isActivelyIndexing = isActivelyIndexing;
969
+ /* Utils Not a pure module */