envio 3.5.0-alpha.2 → 3.5.0-alpha.3

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.
@@ -200,16 +200,92 @@ function ascSortFn(a, b) {
200
200
  return Primitive_int.compare(a.latestFetchedBlock.blockNumber, b.latestFetchedBlock.blockNumber);
201
201
  }
202
202
 
203
+ function anchoredContracts(partitions) {
204
+ let set = new Set();
205
+ partitions.forEach(p => {
206
+ let match = p.mergeBlock;
207
+ let match$1 = p.selection.clientFilteredContracts;
208
+ if (match !== undefined || match$1 === undefined) {
209
+ return;
210
+ } else {
211
+ match$1.forEach(name => {
212
+ set.add(name);
213
+ });
214
+ return;
215
+ }
216
+ });
217
+ return set;
218
+ }
219
+
220
+ function getAnchorSafeBlock(p) {
221
+ let safeRef = {
222
+ contents: p.latestFetchedBlock.blockNumber
223
+ };
224
+ p.mutPendingQueries.forEach(pq => {
225
+ let match = safeRef.contents;
226
+ if (match === undefined) {
227
+ return;
228
+ }
229
+ let toBlock = pq.toBlock;
230
+ let match$1 = pq.fetchedBlock;
231
+ if (match$1 === undefined) {
232
+ if (toBlock !== undefined) {
233
+ if (toBlock > match) {
234
+ safeRef.contents = toBlock;
235
+ return;
236
+ } else {
237
+ return;
238
+ }
239
+ } else {
240
+ safeRef.contents = undefined;
241
+ return;
242
+ }
243
+ }
244
+ let blockNumber = match$1.blockNumber;
245
+ if (blockNumber > match) {
246
+ safeRef.contents = blockNumber;
247
+ return;
248
+ }
249
+ });
250
+ return safeRef.contents;
251
+ }
252
+
203
253
  function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContracts, clientFilteredContracts) {
204
254
  let newPartitions = [];
205
255
  let mergingPartitions = {};
206
256
  let nextPartitionIndexRef = {
207
257
  contents: nextPartitionIndex
208
258
  };
259
+ let anchorSafeBlocks = {};
260
+ let anchoredContractsSet = new Set();
261
+ if (clientFilteredContracts.size > 0) {
262
+ partitions.forEach(p => {
263
+ let match = p.mergeBlock;
264
+ let match$1 = p.selection.clientFilteredContracts;
265
+ if (match !== undefined) {
266
+ return;
267
+ }
268
+ if (match$1 === undefined) {
269
+ return;
270
+ }
271
+ let safeBlock = getAnchorSafeBlock(p);
272
+ match$1.forEach(name => {
273
+ anchoredContractsSet.add(name);
274
+ if (safeBlock !== undefined) {
275
+ anchorSafeBlocks[name] = safeBlock;
276
+ return;
277
+ }
278
+ });
279
+ });
280
+ }
209
281
  for (let idx = 0, idx_finish = partitions.length; idx < idx_finish; ++idx) {
210
282
  let p = partitions[idx];
211
- let exit = 0;
212
- if (p.dynamicContract !== undefined && p.mergeBlock === undefined && p.selection.dependsOnAddresses) {
283
+ let mergeBlock = p.mergeBlock;
284
+ if (mergeBlock !== undefined) {
285
+ if (p.latestFetchedBlock.blockNumber < mergeBlock) {
286
+ newPartitions.push(p);
287
+ }
288
+ } else if (p.dynamicContract !== undefined && p.selection.dependsOnAddresses) {
213
289
  let contractName = p.dynamicContract;
214
290
  let pAddressesCount = p.addresses.countFor(contractName);
215
291
  let match = Utils.$$Array.last(p.mutPendingQueries);
@@ -236,9 +312,6 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
236
312
  newPartitions.push(p);
237
313
  }
238
314
  } else {
239
- exit = 1;
240
- }
241
- if (exit === 1) {
242
315
  newPartitions.push(p);
243
316
  }
244
317
  }
@@ -276,12 +349,57 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
276
349
  };
277
350
  newPartitions.push(currentPRef);
278
351
  }
279
- newPartitions.sort(ascSortFn);
280
- let partitionsCount = newPartitions.length;
352
+ let finalPartitions;
353
+ if (anchoredContractsSet.size === 0) {
354
+ finalPartitions = newPartitions;
355
+ } else {
356
+ let anchored = [];
357
+ newPartitions.forEach(p => {
358
+ if (p.mergeBlock !== undefined) {
359
+ anchored.push(p);
360
+ return;
361
+ }
362
+ let contractName = p.dynamicContract;
363
+ if (contractName !== undefined) {
364
+ if (anchoredContractsSet.has(contractName)) {
365
+ let anchorSafeBlock = anchorSafeBlocks[contractName];
366
+ if (anchorSafeBlock !== undefined) {
367
+ if (p.latestFetchedBlock.blockNumber < anchorSafeBlock) {
368
+ anchored.push({
369
+ id: p.id,
370
+ latestFetchedBlock: p.latestFetchedBlock,
371
+ selection: p.selection,
372
+ addresses: p.addresses,
373
+ mergeBlock: anchorSafeBlock,
374
+ dynamicContract: p.dynamicContract,
375
+ mutPendingQueries: p.mutPendingQueries,
376
+ sourceRangeCapacity: p.sourceRangeCapacity,
377
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
378
+ eventDensity: p.eventDensity,
379
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
380
+ });
381
+ return;
382
+ } else {
383
+ return;
384
+ }
385
+ } else {
386
+ anchored.push(p);
387
+ return;
388
+ }
389
+ }
390
+ anchored.push(p);
391
+ return;
392
+ }
393
+ anchored.push(p);
394
+ });
395
+ finalPartitions = anchored;
396
+ }
397
+ finalPartitions.sort(ascSortFn);
398
+ let partitionsCount = finalPartitions.length;
281
399
  let idsInAscOrder = Array(partitionsCount);
282
400
  let entities = {};
283
401
  for (let idx$2 = 0; idx$2 < partitionsCount; ++idx$2) {
284
- let p$1 = newPartitions[idx$2];
402
+ let p$1 = finalPartitions[idx$2];
285
403
  idsInAscOrder[idx$2] = p$1.id;
286
404
  entities[p$1.id] = p$1;
287
405
  }
@@ -475,6 +593,8 @@ let OptimizedPartitions = {
475
593
  mergePartitionsAtBlock: mergePartitionsAtBlock,
476
594
  tooFarBlockRange: 20000,
477
595
  ascSortFn: ascSortFn,
596
+ anchoredContracts: anchoredContracts,
597
+ getAnchorSafeBlock: getAnchorSafeBlock,
478
598
  make: make,
479
599
  consumeFetchedQueries: consumeFetchedQueries,
480
600
  getPendingQueryOrThrow: getPendingQueryOrThrow,
@@ -683,14 +803,17 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSo
683
803
  };
684
804
  }
685
805
 
686
- function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold) {
806
+ function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold, shouldLogOpt) {
807
+ let shouldLog = shouldLogOpt !== undefined ? shouldLogOpt : true;
687
808
  clientFilteredContracts.add(contractName);
688
- Logging.childTrace(Logging.createChild({
689
- chainId: chainId,
690
- contractName: contractName,
691
- addressCount: addressCount,
692
- threshold: threshold
693
- }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
809
+ if (shouldLog) {
810
+ return Logging.childTrace(Logging.createChild({
811
+ chainId: chainId,
812
+ contractName: contractName,
813
+ addressCount: addressCount,
814
+ threshold: threshold
815
+ }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
816
+ }
694
817
  }
695
818
 
696
819
  function claimedFetchedBlock(p, knownHeight) {
@@ -700,7 +823,8 @@ function claimedFetchedBlock(p, knownHeight) {
700
823
  });
701
824
  }
702
825
 
703
- function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, knownHeight) {
826
+ function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, clientFilteredFrontiersOpt, knownHeight) {
827
+ let clientFilteredFrontiers = clientFilteredFrontiersOpt !== undefined ? clientFilteredFrontiersOpt : [];
704
828
  if (clientFilteredContracts.size === 0) {
705
829
  return partitions;
706
830
  }
@@ -711,6 +835,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
711
835
  let backfills = [];
712
836
  let absorbedPartitions = [];
713
837
  let strippedFrontiers = [];
838
+ let anchoredContracts$1 = anchoredContracts(partitions);
714
839
  partitions.forEach(p => {
715
840
  if (!p.selection.dependsOnAddresses) {
716
841
  if (p.mergeBlock !== undefined) {
@@ -726,6 +851,11 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
726
851
  let serverSideNames = contractNames.filter(c => !clientFilteredContracts.has(c));
727
852
  if (serverSideNames.length === contractNames.length) {
728
853
  kept.push(p);
854
+ return;
855
+ }
856
+ let contractName = p.dynamicContract;
857
+ if (contractName !== undefined ? anchoredContracts$1.has(contractName) : false) {
858
+ kept.push(p);
729
859
  } else if (Utils.$$Array.isEmpty(serverSideNames)) {
730
860
  absorbedPartitions.push(p);
731
861
  } else {
@@ -735,7 +865,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
735
865
  });
736
866
  let standing = standingRef.contents;
737
867
  let selectionChanged = standing !== undefined ? Stdlib_Option.mapOr(standing.selection.clientFilteredContracts, 0, prim => prim.length) !== clientFilteredContracts.size : true;
738
- if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && !selectionChanged) {
868
+ if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && Utils.$$Array.isEmpty(clientFilteredFrontiers) && !selectionChanged) {
739
869
  return partitions;
740
870
  }
741
871
  let minFrontierRef = {
@@ -753,6 +883,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
753
883
  absorbedPartitions.forEach(p => considerFrontier(p.latestFetchedBlock));
754
884
  backfills.forEach(p => considerFrontier(p.latestFetchedBlock));
755
885
  strippedFrontiers.forEach(considerFrontier);
886
+ clientFilteredFrontiers.forEach(considerFrontier);
756
887
  let regByIndex = {};
757
888
  let addRegs = regs => {
758
889
  regs.forEach(reg => {
@@ -849,59 +980,72 @@ function createPartitions(registeringSetsByContract, addressStore, dynamicContra
849
980
  };
850
981
  let dynamicPartitions = [];
851
982
  let nonDynamicPartitions = [];
983
+ let clientFilteredFrontiers = [];
984
+ let anchoredContracts$1 = anchoredContracts(existingPartitions);
852
985
  let contractNames = Object.keys(registeringSetsByContract);
853
986
  for (let cIdx = 0, cIdx_finish = contractNames.length; cIdx < cIdx_finish; ++cIdx) {
854
987
  let contractName = contractNames[cIdx];
855
988
  let contractSet = registeringSetsByContract[contractName];
856
- let isDynamic = dynamicContracts.has(contractName);
989
+ let isAnchored = anchoredContracts$1.has(contractName);
990
+ let isDynamic = dynamicContracts.has(contractName) || isAnchored;
857
991
  let partitions = isDynamic ? dynamicPartitions : nonDynamicPartitions;
858
992
  let groups = contractSet.startBlockGroups();
859
- let offsetRef = 0;
860
- let groupIdx = 0;
861
- while (groupIdx < groups.length) {
862
- let startBlock = groups[groupIdx].startBlock;
863
- let countRef = 0;
864
- let nextIdx = groupIdx;
865
- let joining = true;
866
- while (joining && nextIdx < groups.length) {
867
- let group = groups[nextIdx];
868
- if ((group.startBlock - startBlock | 0) < 20000) {
869
- countRef = countRef + group.count | 0;
870
- nextIdx = nextIdx + 1 | 0;
871
- } else {
872
- joining = false;
873
- }
874
- };
875
- let latestFetchedBlock_blockNumber = Primitive_int.max(startBlock - 1 | 0, progressBlockNumber);
876
- let latestFetchedBlock = {
877
- blockNumber: latestFetchedBlock_blockNumber,
878
- blockTimestamp: 0
879
- };
880
- let remainingRef = countRef;
881
- let chunkOffsetRef = offsetRef;
882
- while (remainingRef > 0) {
883
- let take = Primitive_int.min(remainingRef, maxAddrInPartition);
884
- let pAddresses = contractSet.slice(chunkOffsetRef, take);
885
- partitions.push({
886
- id: nextPartitionIndexRef.contents.toString(),
887
- latestFetchedBlock: latestFetchedBlock,
888
- selection: normalSelection,
889
- addresses: pAddresses,
890
- mergeBlock: undefined,
891
- dynamicContract: isDynamic ? contractName : undefined,
892
- mutPendingQueries: [],
893
- sourceRangeCapacity: 0,
894
- prevSourceRangeCapacity: 0,
895
- eventDensity: undefined,
896
- latestSourceRangeCapacityUpdateBlock: 0
993
+ if (clientFilteredContracts.has(contractName) && !isAnchored) {
994
+ let match = groups[0];
995
+ if (match !== undefined) {
996
+ clientFilteredFrontiers.push({
997
+ blockNumber: Primitive_int.max(match.startBlock - 1 | 0, progressBlockNumber),
998
+ blockTimestamp: 0
897
999
  });
898
- nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
899
- chunkOffsetRef = chunkOffsetRef + take | 0;
900
- remainingRef = remainingRef - take | 0;
1000
+ }
1001
+ } else {
1002
+ let offsetRef = 0;
1003
+ let groupIdx = 0;
1004
+ while (groupIdx < groups.length) {
1005
+ let startBlock = groups[groupIdx].startBlock;
1006
+ let countRef = 0;
1007
+ let nextIdx = groupIdx;
1008
+ let joining = true;
1009
+ while (joining && nextIdx < groups.length) {
1010
+ let group = groups[nextIdx];
1011
+ if ((group.startBlock - startBlock | 0) < 20000) {
1012
+ countRef = countRef + group.count | 0;
1013
+ nextIdx = nextIdx + 1 | 0;
1014
+ } else {
1015
+ joining = false;
1016
+ }
1017
+ };
1018
+ let latestFetchedBlock_blockNumber = Primitive_int.max(startBlock - 1 | 0, progressBlockNumber);
1019
+ let latestFetchedBlock = {
1020
+ blockNumber: latestFetchedBlock_blockNumber,
1021
+ blockTimestamp: 0
1022
+ };
1023
+ let remainingRef = countRef;
1024
+ let chunkOffsetRef = offsetRef;
1025
+ while (remainingRef > 0) {
1026
+ let take = Primitive_int.min(remainingRef, maxAddrInPartition);
1027
+ let pAddresses = contractSet.slice(chunkOffsetRef, take);
1028
+ partitions.push({
1029
+ id: nextPartitionIndexRef.contents.toString(),
1030
+ latestFetchedBlock: latestFetchedBlock,
1031
+ selection: normalSelection,
1032
+ addresses: pAddresses,
1033
+ mergeBlock: undefined,
1034
+ dynamicContract: isDynamic ? contractName : undefined,
1035
+ mutPendingQueries: [],
1036
+ sourceRangeCapacity: 0,
1037
+ prevSourceRangeCapacity: 0,
1038
+ eventDensity: undefined,
1039
+ latestSourceRangeCapacityUpdateBlock: 0
1040
+ });
1041
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
1042
+ chunkOffsetRef = chunkOffsetRef + take | 0;
1043
+ remainingRef = remainingRef - take | 0;
1044
+ };
1045
+ offsetRef = offsetRef + countRef | 0;
1046
+ groupIdx = nextIdx;
901
1047
  };
902
- offsetRef = offsetRef + countRef | 0;
903
- groupIdx = nextIdx;
904
- };
1048
+ }
905
1049
  }
906
1050
  let mergedNonDynamic = [];
907
1051
  if (nonDynamicPartitions.length !== 0) {
@@ -944,7 +1088,7 @@ function createPartitions(registeringSetsByContract, addressStore, dynamicContra
944
1088
  mergedNonDynamic.push(currentPRef);
945
1089
  }
946
1090
  let mergedPartitions = mergedNonDynamic.concat(dynamicPartitions);
947
- let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, knownHeight);
1091
+ let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, clientFilteredFrontiers, knownHeight);
948
1092
  return make(allPartitions, maxAddrInPartition, nextPartitionIndexRef.contents, dynamicContracts, clientFilteredContracts);
949
1093
  }
950
1094
 
@@ -1097,7 +1241,7 @@ function registerDynamicContracts(fetchState, addressStore, claimCeilingOpt, ite
1097
1241
  Array.from(dynamicContractsRef).forEach(contractName => {
1098
1242
  let addressCount = addressStore.contractCount(contractName);
1099
1243
  if (!clientFilteredContracts$1.has(contractName) && addressCount > threshold) {
1100
- return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold);
1244
+ return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold, undefined);
1101
1245
  }
1102
1246
  });
1103
1247
  clientFilteredContracts = clientFilteredContracts$1;
@@ -1482,12 +1626,13 @@ function getReadyItemsCount(fetchState, targetSize, fromItem) {
1482
1626
  return acc;
1483
1627
  }
1484
1628
 
1485
- function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt) {
1629
+ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt, isResumedOpt) {
1486
1630
  let progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
1487
1631
  let onBlockRegistrations = onBlockRegistrationsOpt !== undefined ? onBlockRegistrationsOpt : [];
1488
1632
  let blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
1489
1633
  let firstEventBlock = firstEventBlockOpt !== undefined ? Primitive_option.valFromOption(firstEventBlockOpt) : undefined;
1490
1634
  let clientFilterAddressThreshold = clientFilterAddressThresholdOpt !== undefined ? Primitive_option.valFromOption(clientFilterAddressThresholdOpt) : undefined;
1635
+ let isResumed = isResumedOpt !== undefined ? isResumedOpt : false;
1491
1636
  let latestFetchedBlock = {
1492
1637
  blockNumber: progressBlockNumber,
1493
1638
  blockTimestamp: 0
@@ -1552,7 +1697,7 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
1552
1697
  Utils.Dict.forEachWithKey(registeringSetsByContract, (set, contractName) => {
1553
1698
  let addressCount = set.size();
1554
1699
  if (addressCount > clientFilterAddressThreshold) {
1555
- return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold);
1700
+ return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold, !isResumed);
1556
1701
  }
1557
1702
  });
1558
1703
  }
@@ -1669,6 +1814,7 @@ function rollback(fetchState, addressStore, targetBlockNumber) {
1669
1814
  } else {
1670
1815
  let id$1 = nextKeptIdRef.toString();
1671
1816
  nextKeptIdRef = nextKeptIdRef + 1 | 0;
1817
+ let mergeBlock$2 = p.mergeBlock;
1672
1818
  keptPartitions.push({
1673
1819
  id: id$1,
1674
1820
  latestFetchedBlock: p.latestFetchedBlock.blockNumber > targetBlockNumber ? ({
@@ -1677,7 +1823,7 @@ function rollback(fetchState, addressStore, targetBlockNumber) {
1677
1823
  }) : p.latestFetchedBlock,
1678
1824
  selection: p.selection,
1679
1825
  addresses: p.addresses,
1680
- mergeBlock: p.mergeBlock,
1826
+ mergeBlock: mergeBlock$2 !== undefined && mergeBlock$2 > targetBlockNumber ? targetBlockNumber : mergeBlock$2,
1681
1827
  dynamicContract: p.dynamicContract,
1682
1828
  mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
1683
1829
  sourceRangeCapacity: p.sourceRangeCapacity,
@@ -0,0 +1,34 @@
1
+ // The FinalizingIndexes phase. Runs once, from the processing loop, when every
2
+ // chain has caught up: processing is already paused (the loop awaits this),
3
+ // pending writes are flushed, then storage creates every missing schema-defined
4
+ // index and stamps `ready_at` in one transaction. A failure rolls back both, so
5
+ // the next batch simply retries — the indexer never reports ready with an index
6
+ // the schema promised still missing.
7
+
8
+ let run = async (state: IndexerState.t) => {
9
+ Logging.info(
10
+ "All chains are caught up. Finalizing the indexer before switching to realtime: flushing pending writes, then creating the indexes the schema promises.",
11
+ )
12
+
13
+ await Writing.flush(state)
14
+
15
+ // A failed write already surfaced through onError; committing ready_at on top
16
+ // of an incomplete write would claim progress that isn't durable.
17
+ if !(state->IndexerState.hasFailedWrite) {
18
+ let persistence = state->IndexerState.persistence
19
+ let storage = persistence->Persistence.getInitializedStorageOrThrow
20
+ let readyAt = Date.make()
21
+
22
+ await storage.finalizeBackfill(
23
+ ~entities=persistence.allEntities,
24
+ ~chainIds=state
25
+ ->IndexerState.chainStates
26
+ ->Dict.valuesToArray
27
+ ->Array.map(cs => (cs->ChainState.chainConfig).id),
28
+ ~readyAt,
29
+ )
30
+
31
+ state->IndexerState.markReady(~readyAt)
32
+ Logging.info("The indexer is ready. Switching to realtime indexing.")
33
+ }
34
+ }
@@ -0,0 +1,26 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Logging from "./Logging.res.mjs";
4
+ import * as Writing from "./Writing.res.mjs";
5
+ import * as ChainState from "./ChainState.res.mjs";
6
+ import * as Persistence from "./Persistence.res.mjs";
7
+ import * as IndexerState from "./IndexerState.res.mjs";
8
+
9
+ async function run(state) {
10
+ Logging.info("All chains are caught up. Finalizing the indexer before switching to realtime: flushing pending writes, then creating the indexes the schema promises.");
11
+ await Writing.flush(state);
12
+ if (IndexerState.hasFailedWrite(state)) {
13
+ return;
14
+ }
15
+ let persistence = IndexerState.persistence(state);
16
+ let storage = Persistence.getInitializedStorageOrThrow(persistence);
17
+ let readyAt = new Date();
18
+ await storage.finalizeBackfill(persistence.allEntities, Object.values(IndexerState.chainStates(state)).map(cs => ChainState.chainConfig(cs).id), readyAt);
19
+ IndexerState.markReady(state, readyAt);
20
+ return Logging.info("The indexer is ready. Switching to realtime indexing.");
21
+ }
22
+
23
+ export {
24
+ run,
25
+ }
26
+ /* Logging Not a pure module */
@@ -2,7 +2,7 @@ module Entity = {
2
2
  type relatedEntityId = string
3
3
  type filterWithRelatedIds = (EntityFilter.t, Utils.Set.t<relatedEntityId>)
4
4
  // Keyed by EntityFilter.toString
5
- type filterIndices = dict<filterWithRelatedIds>
5
+ type filterIndexes = dict<filterWithRelatedIds>
6
6
 
7
7
  type entityFilters = Utils.Set.t<EntityFilter.t>
8
8
  type t = {
@@ -14,7 +14,7 @@ module Entity = {
14
14
  // previous changes persist in the background.
15
15
  mutable prevEntityChanges: array<Change.t<Internal.entity>>,
16
16
  mutable filtersByEntityId: dict<entityFilters>,
17
- mutable filterIndices: filterIndices,
17
+ mutable filterIndexes: filterIndexes,
18
18
  }
19
19
 
20
20
  // Helper to extract an entity's id as a dict key. The raw id may be a
@@ -44,7 +44,7 @@ module Entity = {
44
44
  changesCount: 0.,
45
45
  prevEntityChanges: [],
46
46
  filtersByEntityId: Dict.make(),
47
- filterIndices: Dict.make(),
47
+ filterIndexes: Dict.make(),
48
48
  }
49
49
 
50
50
  // Changes to persist for checkpoints in (committedCheckpointId, upToCheckpointId].
@@ -81,7 +81,7 @@ module Entity = {
81
81
  }
82
82
 
83
83
  // Frees committed changes: drops latest entries at or below committedCheckpointId
84
- // (re-readable from the db) and clears the per-batch indices (rebuilt on the next
84
+ // (re-readable from the db) and clears the per-batch indexes (rebuilt on the next
85
85
  // getWhere). Uncommitted changes are kept. With keepLoadedFromDb, entries seeded
86
86
  // from a db read are spared so the cheaper-to-re-derive writes are dropped first.
87
87
  let dropCommittedChanges = (self: t, ~committedCheckpointId, ~keepLoadedFromDb) => {
@@ -98,10 +98,10 @@ module Entity = {
98
98
  keysToDelete->Array.forEach(key => self.latestEntityChangeById->Utils.Dict.deleteInPlace(key))
99
99
  self.changesCount = self.changesCount -. keysToDelete->Array.length->Int.toFloat
100
100
  self.filtersByEntityId = Dict.make()
101
- self.filterIndices = Dict.make()
101
+ self.filterIndexes = Dict.make()
102
102
  }
103
103
 
104
- let updateIndices = (self: t, ~entity: Internal.entity) => {
104
+ let updateIndexes = (self: t, ~entity: Internal.entity) => {
105
105
  let entityId = entity->getEntityIdUnsafe
106
106
  let entityAsDict = entity->(Utils.magic: Internal.entity => dict<EntityFilter.FieldValue.t>)
107
107
 
@@ -116,7 +116,7 @@ module Entity = {
116
116
  })
117
117
  }
118
118
 
119
- self.filterIndices->Utils.Dict.forEach(((filter, relatedEntityIds)) => {
119
+ self.filterIndexes->Utils.Dict.forEach(((filter, relatedEntityIds)) => {
120
120
  if filter->EntityFilter.matches(~entity=entityAsDict) {
121
121
  //Add entity id to the filter index and the filter to entity filters
122
122
  relatedEntityIds->Utils.Set.add(entityId)->ignore
@@ -127,12 +127,12 @@ module Entity = {
127
127
  })
128
128
  }
129
129
 
130
- let deleteEntityFromIndices = (self: t, ~entityId: string) =>
130
+ let deleteEntityFromIndexes = (self: t, ~entityId: string) =>
131
131
  switch self.filtersByEntityId->Utils.Dict.dangerouslyGetNonOption(entityId) {
132
132
  | None => ()
133
133
  | Some(entityFilters) =>
134
134
  entityFilters->Utils.Set.forEach(filter => {
135
- switch self.filterIndices->Utils.Dict.dangerouslyGetNonOption(
135
+ switch self.filterIndexes->Utils.Dict.dangerouslyGetNonOption(
136
136
  filter->EntityFilter.toString,
137
137
  ) {
138
138
  | Some((_filter, relatedEntityIds)) =>
@@ -159,8 +159,8 @@ module Entity = {
159
159
  }
160
160
 
161
161
  switch change {
162
- | Set({entity}) => inMemTable->updateIndices(~entity)
163
- | Delete({entityId}) => inMemTable->deleteEntityFromIndices(~entityId=entityId->EntityId.toKey)
162
+ | Set({entity}) => inMemTable->updateIndexes(~entity)
163
+ | Delete({entityId}) => inMemTable->deleteEntityFromIndexes(~entityId=entityId->EntityId.toKey)
164
164
  }
165
165
  inMemTable.latestEntityChangeById->Dict.set(entityKey, change)
166
166
  }
@@ -200,12 +200,12 @@ module Entity = {
200
200
 
201
201
  let hasIndex = (inMemTable: t) =>
202
202
  (filterKey: string) =>
203
- inMemTable.filterIndices->Utils.Dict.dangerouslyGetNonOption(filterKey) !== None
203
+ inMemTable.filterIndexes->Utils.Dict.dangerouslyGetNonOption(filterKey) !== None
204
204
 
205
205
  let getUnsafeOnIndex = (inMemTable: t) => {
206
206
  let getEntity = inMemTable->getUnsafe
207
207
  (filterKey: string) => {
208
- switch inMemTable.filterIndices->Utils.Dict.dangerouslyGetNonOption(filterKey) {
208
+ switch inMemTable.filterIndexes->Utils.Dict.dangerouslyGetNonOption(filterKey) {
209
209
  | None =>
210
210
  JsError.throwWithMessage(`Unexpected error. Must have an index for the filter ${filterKey}`)
211
211
  | Some((_filter, relatedEntityIds)) =>
@@ -223,7 +223,7 @@ module Entity = {
223
223
 
224
224
  let addEmptyIndex = (inMemTable: t, ~filter: EntityFilter.t) => {
225
225
  let filterKey = filter->EntityFilter.toString
226
- switch inMemTable.filterIndices->Utils.Dict.dangerouslyGetNonOption(filterKey) {
226
+ switch inMemTable.filterIndexes->Utils.Dict.dangerouslyGetNonOption(filterKey) {
227
227
  | Some(_) => () //Should not happen, this means the index already exists
228
228
  | None =>
229
229
  let relatedEntityIds = Utils.Set.make()
@@ -240,7 +240,7 @@ module Entity = {
240
240
  | None => ()
241
241
  }
242
242
  })
243
- inMemTable.filterIndices->Dict.set(filterKey, (filter, relatedEntityIds))
243
+ inMemTable.filterIndexes->Dict.set(filterKey, (filter, relatedEntityIds))
244
244
  }
245
245
  }
246
246
  }