envio 3.11.0 → 3.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/index.d.ts +3 -0
  2. package/package.json +6 -6
  3. package/src/Batch.res +111 -78
  4. package/src/Batch.res.mjs +53 -46
  5. package/src/BatchProcessing.res +1 -11
  6. package/src/BatchProcessing.res.mjs +1 -4
  7. package/src/ChainFetching.res +7 -3
  8. package/src/ChainFetching.res.mjs +1 -1
  9. package/src/ChainState.res +82 -20
  10. package/src/ChainState.res.mjs +51 -13
  11. package/src/ChainState.resi +6 -1
  12. package/src/Config.res +58 -37
  13. package/src/Config.res.mjs +63 -53
  14. package/src/CrossChainState.res +50 -53
  15. package/src/CrossChainState.res.mjs +25 -23
  16. package/src/CrossChainState.resi +6 -13
  17. package/src/EffectState.res +13 -4
  18. package/src/EffectState.resi +7 -1
  19. package/src/EventProcessing.res +6 -6
  20. package/src/EventProcessing.res.mjs +6 -6
  21. package/src/FetchState.res +65 -46
  22. package/src/FetchState.res.mjs +68 -36
  23. package/src/FinalizeBackfill.res +16 -12
  24. package/src/FinalizeBackfill.res.mjs +3 -3
  25. package/src/HistoryPolicy.res +46 -0
  26. package/src/HistoryPolicy.res.mjs +50 -0
  27. package/src/InMemoryStore.res +30 -32
  28. package/src/InMemoryStore.res.mjs +33 -28
  29. package/src/InMemoryTable.res +155 -67
  30. package/src/InMemoryTable.res.mjs +151 -60
  31. package/src/IndexerState.res +66 -45
  32. package/src/IndexerState.res.mjs +57 -29
  33. package/src/IndexerState.resi +8 -13
  34. package/src/Internal.res +4 -2
  35. package/src/LoadLayer.res +68 -38
  36. package/src/LoadLayer.res.mjs +50 -64
  37. package/src/LoadLayer.resi +1 -1
  38. package/src/Main.res +25 -24
  39. package/src/Main.res.mjs +24 -25
  40. package/src/Metrics.res +49 -1
  41. package/src/Metrics.res.mjs +26 -3
  42. package/src/Persistence.res +55 -16
  43. package/src/Persistence.res.mjs +18 -3
  44. package/src/PgStorage.res +286 -180
  45. package/src/PgStorage.res.mjs +209 -122
  46. package/src/PruneStaleHistory.res +9 -15
  47. package/src/PruneStaleHistory.res.mjs +11 -20
  48. package/src/Rollback.res +9 -14
  49. package/src/Rollback.res.mjs +5 -3
  50. package/src/Sink.res +7 -5
  51. package/src/Sink.res.mjs +4 -4
  52. package/src/Staging.res +298 -0
  53. package/src/Staging.res.mjs +257 -0
  54. package/src/TestIndexer.res +14 -30
  55. package/src/TestIndexer.res.mjs +11 -9
  56. package/src/UserContext.res +20 -36
  57. package/src/UserContext.res.mjs +6 -9
  58. package/src/Utils.res +10 -4
  59. package/src/Utils.res.mjs +16 -16
  60. package/src/Writing.res +34 -20
  61. package/src/Writing.res.mjs +15 -20
  62. package/src/bindings/ClickHouse.res +41 -34
  63. package/src/bindings/ClickHouse.res.mjs +36 -30
  64. package/src/bindings/ClickHouseSink.res +45 -186
  65. package/src/bindings/ClickHouseSink.res.mjs +21 -174
  66. package/src/db/CheckpointSequence.res +109 -0
  67. package/src/db/CheckpointSequence.res.mjs +99 -0
  68. package/src/db/EntityFilter.res +487 -275
  69. package/src/db/EntityFilter.res.mjs +557 -309
  70. package/src/db/EntityHistory.res +6 -5
  71. package/src/db/EntityHistory.res.mjs +5 -5
  72. package/src/db/Frontier.res +86 -0
  73. package/src/db/Frontier.res.mjs +126 -0
  74. package/src/db/InternalTable.res +145 -27
  75. package/src/db/InternalTable.res.mjs +115 -29
  76. package/src/db/RollbackFloors.res +34 -41
  77. package/src/db/RollbackFloors.res.mjs +27 -71
  78. package/src/db/Table.res +21 -6
  79. package/src/db/Table.res.mjs +13 -4
  80. package/src/sources/BlockStore.res +8 -0
  81. package/src/sources/EvmHyperSyncSource.res +5 -1
  82. package/src/sources/EvmHyperSyncSource.res.mjs +4 -3
  83. package/src/sources/FuelHyperSyncSource.res +1 -0
  84. package/src/sources/FuelHyperSyncSource.res.mjs +1 -1
  85. package/src/sources/HyperSync.res +6 -0
  86. package/src/sources/HyperSync.res.mjs +5 -2
  87. package/src/sources/HyperSync.resi +2 -0
  88. package/src/sources/HyperSyncClient.res +6 -0
  89. package/src/sources/HyperSyncSSE.res +1 -1
  90. package/src/sources/HyperSyncSSE.res.mjs +4 -10
  91. package/src/sources/RequestStat.res +8 -1
  92. package/src/sources/RpcSource.res +1 -0
  93. package/src/sources/RpcSource.res.mjs +1 -1
  94. package/src/sources/SimulateSource.res +1 -0
  95. package/src/sources/SimulateSource.res.mjs +1 -1
  96. package/src/sources/Source.res +11 -3
  97. package/src/sources/SourceManager.res +34 -13
  98. package/src/sources/SourceManager.res.mjs +26 -9
  99. package/src/sources/SourceManager.resi +2 -0
  100. package/src/sources/SvmHyperSyncClient.res +5 -0
  101. package/src/sources/SvmHyperSyncSource.res +3 -0
  102. package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
  103. package/src/tui/Tui.res +56 -143
  104. package/src/tui/Tui.res.mjs +70 -166
  105. package/src/tui/components/TuiData.res +61 -16
  106. package/src/tui/components/TuiData.res.mjs +53 -15
  107. package/svm.schema.json +0 -7
  108. package/src/db/CheckpointBounds.res +0 -53
  109. package/src/db/CheckpointBounds.res.mjs +0 -44
@@ -12,16 +12,19 @@ import * as Schema from "./db/Schema.res.mjs";
12
12
  import * as ChainId from "./ChainId.res.mjs";
13
13
  import * as Logging from "./Logging.res.mjs";
14
14
  import * as EntityId from "./EntityId.res.mjs";
15
+ import * as Frontier from "./db/Frontier.res.mjs";
15
16
  import * as Internal from "./Internal.res.mjs";
16
17
  import Postgres from "postgres";
17
18
  import * as ChainState from "./ChainState.res.mjs";
18
19
  import * as AddressRows from "./AddressRows.res.mjs";
19
20
  import * as Performance from "./bindings/Performance.res.mjs";
20
21
  import * as Persistence from "./Persistence.res.mjs";
22
+ import * as EntityFilter from "./db/EntityFilter.res.mjs";
21
23
  import * as IndexCatalog from "./db/IndexCatalog.res.mjs";
22
24
  import * as IndexManager from "./db/IndexManager.res.mjs";
23
25
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
24
26
  import * as EntityHistory from "./db/EntityHistory.res.mjs";
27
+ import * as HistoryPolicy from "./HistoryPolicy.res.mjs";
25
28
  import * as InternalTable from "./db/InternalTable.res.mjs";
26
29
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
27
30
  import * as Child_process from "child_process";
@@ -29,10 +32,10 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
29
32
  import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
30
33
  import * as ContractMapping from "./ContractMapping.res.mjs";
31
34
  import * as IndexDefinition from "./db/IndexDefinition.res.mjs";
32
- import * as CheckpointBounds from "./db/CheckpointBounds.res.mjs";
33
35
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
34
36
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
35
37
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
38
+ import * as CheckpointSequence from "./db/CheckpointSequence.res.mjs";
36
39
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
37
40
 
38
41
  function makeClient() {
@@ -57,7 +60,25 @@ function formatSeconds(timeRef) {
57
60
 
58
61
  let slowOnLargeDatabaseNotice = "This can take a long time on a large database.";
59
62
 
60
- function getSchemaIndexes(entities) {
63
+ function partitionTableName(entityConfig, chainId) {
64
+ let chainIdStr = ChainId.toString(chainId);
65
+ return Table.fitPgTableName(entityConfig.table.tableName + `$` + chainIdStr, `$` + entityConfig.index.toString() + `$` + chainIdStr);
66
+ }
67
+
68
+ function indexTableNames(entityConfig, partitionChainIds) {
69
+ let match = Table.getChainIdField(entityConfig.table);
70
+ if (match !== undefined) {
71
+ if (partitionChainIds !== undefined) {
72
+ return partitionChainIds.map(chainId => partitionTableName(entityConfig, chainId));
73
+ } else {
74
+ return [entityConfig.table.tableName];
75
+ }
76
+ } else {
77
+ return [entityConfig.table.tableName];
78
+ }
79
+ }
80
+
81
+ function getSchemaIndexes(entities, partitionChainIds) {
61
82
  let derivedSchema = Schema.make(entities.map(e => e.table));
62
83
  let all = [];
63
84
  entities.forEach(param => {
@@ -76,6 +97,10 @@ function getSchemaIndexes(entities) {
76
97
  });
77
98
  });
78
99
  let seen = new Set();
100
+ let entityByTableName = {};
101
+ entities.forEach(entityConfig => {
102
+ entityByTableName[entityConfig.table.tableName] = entityConfig;
103
+ });
79
104
  return all.filter(definition => {
80
105
  let key = IndexDefinition.key(definition);
81
106
  if (seen.has(key)) {
@@ -84,7 +109,11 @@ function getSchemaIndexes(entities) {
84
109
  seen.add(key);
85
110
  return true;
86
111
  }
87
- });
112
+ }).flatMap(definition => indexTableNames(Stdlib_Option.getOrThrow(entityByTableName[definition.tableName], undefined), partitionChainIds).map(tableName => ({
113
+ tableName: tableName,
114
+ columns: definition.columns,
115
+ method: definition.method
116
+ })));
88
117
  }
89
118
 
90
119
  function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdModeOpt, partitionByColumn) {
@@ -108,11 +137,6 @@ function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdMode
108
137
  ) + `;`;
109
138
  }
110
139
 
111
- function partitionTableName(entityConfig, chainId) {
112
- let chainIdStr = ChainId.toString(chainId);
113
- return Table.fitPgTableName(entityConfig.table.tableName + `$` + chainIdStr, `$` + entityConfig.index.toString() + `$` + chainIdStr);
114
- }
115
-
116
140
  let rowSchemaCache = new WeakMap();
117
141
 
118
142
  function getRowSchema(entityConfig) {
@@ -228,7 +252,7 @@ function makeCreateEntityTableQueries(entityConfig, pgSchema, isNumericArrayAsTe
228
252
  ).concat([createTable(getEntityHistory(entityConfig).table, undefined)]);
229
253
  }
230
254
 
231
- function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfigsOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt, deferSchemaIndexesOpt, chainIdModeOpt) {
255
+ function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, checkpointSequence, chainConfigsOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt, deferSchemaIndexesOpt, chainIdModeOpt) {
232
256
  let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
233
257
  let entities = entitiesOpt !== undefined ? entitiesOpt : [];
234
258
  let enums = enumsOpt !== undefined ? enumsOpt : [];
@@ -240,12 +264,12 @@ function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfi
240
264
  InternalTable.EnvioInfo.table,
241
265
  InternalTable.EnvioContracts.table,
242
266
  InternalTable.EnvioAddresses.table,
243
- InternalTable.Checkpoints.table,
267
+ InternalTable.Checkpoints.tableFor(checkpointSequence),
244
268
  InternalTable.RawEvents.table
245
269
  ];
246
270
  let chainIds = chainConfigs.map(chainConfig => chainConfig.id);
247
271
  let tableQueries = generalTables.map(table => makeCreateTableQuery(table, pgSchema, isHasuraEnabled, chainIdMode, undefined)).concat(entities.flatMap(entityConfig => makeCreateEntityTableQueries(entityConfig, pgSchema, isHasuraEnabled, chainIdMode, chainIds)));
248
- let schemaIndexes = getSchemaIndexes(entities);
272
+ let schemaIndexes = getSchemaIndexes(entities, undefined);
249
273
  let query = {
250
274
  contents: (
251
275
  isEmptyPgSchema && pgSchema === "public" ? `CREATE SCHEMA IF NOT EXISTS "` + pgSchema + `";\n` : `DROP SCHEMA IF EXISTS "` + pgSchema + `" CASCADE;
@@ -278,7 +302,7 @@ function makeLoadQuery(pgSchema, tableName, condition) {
278
302
  return `SELECT * FROM "` + pgSchema + `"."` + tableName + `" WHERE ` + condition + `;`;
279
303
  }
280
304
 
281
- function makeFilterCondition(filter, table, params) {
305
+ function makeFilterCondition(filter, table, pgSchema, params) {
282
306
  let getQueryFieldOrThrow = fieldName => {
283
307
  let queryField = Table.queryFields(table)[fieldName];
284
308
  if (queryField !== undefined) {
@@ -310,39 +334,76 @@ function makeFilterCondition(filter, table, params) {
310
334
  params.push(param);
311
335
  return `$` + params.length.toString();
312
336
  };
313
- let scalarCondition = (fieldName, fieldValue, op) => {
314
- let queryField = getQueryFieldOrThrow(fieldName);
315
- return `"` + queryField.pgDbFieldName + `" ` + op + ` ` + serializeParamOrThrow(queryField, fieldName, fieldValue, false);
337
+ let condition = {
338
+ contents: ""
316
339
  };
317
- switch (filter.operator) {
318
- case "=" :
319
- let fieldValue = filter.fieldValue;
320
- let fieldName = filter.fieldName;
321
- if (getQueryFieldOrThrow(fieldName).isChainId) {
322
- return `"` + getQueryFieldOrThrow(fieldName).pgDbFieldName + `" = ` + ChainId.toString(ChainId.normalizeOrThrow(fieldValue));
323
- } else {
324
- return scalarCondition(fieldName, fieldValue, "=");
340
+ Utils.Dict.forEachWithKey(EntityFilter.entries(filter), (operators, fieldName) => {
341
+ let queryField = getQueryFieldOrThrow(fieldName);
342
+ Utils.Dict.forEachWithKey(operators, (fieldValue, operator) => {
343
+ let column = `"` + queryField.pgDbFieldName + `"`;
344
+ let part;
345
+ let exit = 0;
346
+ switch (operator) {
347
+ case "_eq" :
348
+ if (queryField.isChainId) {
349
+ part = column + ` = ` + ChainId.toString(ChainId.normalizeOrThrow(fieldValue));
350
+ } else {
351
+ exit = 1;
352
+ }
353
+ break;
354
+ case "_in" :
355
+ if (queryField.isArray || queryField.fieldType === "Boolean") {
356
+ let candidates = EntityFilter.asArray(fieldValue);
357
+ part = candidates.length !== 0 ? `(` + candidates.map(candidate => column + ` = ` + serializeParamOrThrow(queryField, fieldName, candidate, false)).join(" OR ") + `)` : "FALSE";
358
+ } else {
359
+ let param = serializeParamOrThrow(queryField, fieldName, fieldValue, true);
360
+ let match = queryField.fieldType;
361
+ let exit$1 = 0;
362
+ if (typeof match !== "object" || match.type !== "Enum") {
363
+ exit$1 = 2;
364
+ } else {
365
+ part = column + ` = ANY(` + param + `::TEXT[]::"` + pgSchema + `".` + match.config.name + `[])`;
366
+ }
367
+ if (exit$1 === 2) {
368
+ part = column + ` = ANY(` + param + `)`;
369
+ }
370
+ }
371
+ break;
372
+ default:
373
+ exit = 1;
325
374
  }
326
- case ">" :
327
- return scalarCondition(filter.fieldName, filter.fieldValue, ">");
328
- case "<" :
329
- return scalarCondition(filter.fieldName, filter.fieldValue, "<");
330
- case "in" :
331
- let fieldName$1 = filter.fieldName;
332
- let queryField = getQueryFieldOrThrow(fieldName$1);
333
- return `"` + queryField.pgDbFieldName + `" = ANY(` + serializeParamOrThrow(queryField, fieldName$1, filter.fieldValue, true) + `)`;
334
- case "and" :
335
- let filters = filter.filters;
336
- if (filters.length !== 0) {
337
- return `(` + filters.map(filter => makeFilterCondition(filter, table, params)).join(" AND ") + `)`;
375
+ if (exit === 1) {
376
+ let sqlOperator;
377
+ switch (operator) {
378
+ case "_eq" :
379
+ sqlOperator = "=";
380
+ break;
381
+ case "_gt" :
382
+ sqlOperator = ">";
383
+ break;
384
+ case "_gte" :
385
+ sqlOperator = ">=";
386
+ break;
387
+ case "_lt" :
388
+ sqlOperator = "<";
389
+ break;
390
+ case "_lte" :
391
+ sqlOperator = "<=";
392
+ break;
393
+ default:
394
+ throw {
395
+ RE_EXN_ID: Persistence.StorageError,
396
+ message: `Failed loading "` + table.tableName + `" from storage. Unknown filter operator "` + operator + `".`,
397
+ reason: new Error(`Unknown filter operator "` + operator + `"`),
398
+ Error: new Error()
399
+ };
400
+ }
401
+ part = column + ` ` + sqlOperator + ` ` + serializeParamOrThrow(queryField, fieldName, fieldValue, false);
338
402
  }
339
- throw {
340
- RE_EXN_ID: Persistence.StorageError,
341
- message: `Failed loading "` + table.tableName + `" from storage. The "and" filter must contain at least one nested filter.`,
342
- reason: new Error(`Empty "and" filter`),
343
- Error: new Error()
344
- };
345
- }
403
+ condition.contents = condition.contents === "" ? part : condition.contents + " AND " + part;
404
+ });
405
+ });
406
+ return condition.contents;
346
407
  }
347
408
 
348
409
  function makeChainIdCondition(table, chainId) {
@@ -687,10 +748,29 @@ function executeSet(sql, items, dbFunction) {
687
748
  }
688
749
  }
689
750
 
690
- async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, escapeTables) {
751
+ function pickCheckpoints(column, picked) {
752
+ if (typeof picked !== "object") {
753
+ return column;
754
+ } else {
755
+ return picked._0.map(index => column[index]);
756
+ }
757
+ }
758
+
759
+ async function writeBatch(sql, batch, pgSchema, rollback, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, escapeTables) {
691
760
  try {
692
761
  let chainIdMode = config.chainIdMode;
693
- let shouldSaveHistory = Config.shouldSaveHistory(config, isInReorgThreshold, undefined);
762
+ let indexes = Stdlib_Array.filterMapWithIndex(batch.checkpointChainIds, (chainId, index) => {
763
+ if (HistoryPolicy.forChain(batch.history, chainId)) {
764
+ return index;
765
+ }
766
+ });
767
+ let pickedCheckpoints = Utils.$$Array.isEmpty(indexes) ? undefined : (
768
+ indexes.length === batch.checkpointIds.length ? "AllCheckpoints" : ({
769
+ TAG: "CheckpointIndexes",
770
+ _0: indexes
771
+ })
772
+ );
773
+ let writtenFrontier = Persistence.writtenFrontier(batch, rollback);
694
774
  let specificError = {
695
775
  contents: undefined
696
776
  };
@@ -725,6 +805,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
725
805
  }
726
806
  };
727
807
  let setEntities = updatedEntities.map(param => {
808
+ let shouldSaveHistory = param.shouldSaveHistory;
728
809
  let changes = param.changes;
729
810
  let scope = param.scope;
730
811
  let entityConfig = param.entityConfig;
@@ -732,7 +813,6 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
732
813
  let idsToDelete = [];
733
814
  let scopeChainId;
734
815
  scopeChainId = scope === "crossChain" ? undefined : Primitive_option.some(scope);
735
- let shouldSaveHistory = Config.shouldSaveHistory(config, isInReorgThreshold, scopeChainId);
736
816
  let match = Table.getChainIdField(entityConfig.table);
737
817
  let changes$1;
738
818
  if (match !== undefined && scopeChainId !== undefined) {
@@ -756,7 +836,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
756
836
  let chainIdParams = match$1 !== undefined ? (
757
837
  scopeChainId !== undefined ? [Primitive_option.valFromOption(scopeChainId)] : []
758
838
  ) : [];
759
- let diffCheckpointId = Stdlib_Option.map(rollback, r => r.diffCheckpointId);
839
+ let diffCheckpointId = Stdlib_Option.flatMap(rollback, r => CheckpointSequence.findForScope(config.checkpointSequence, r.diffFrontier, scope));
760
840
  let batchSetUpdates = [];
761
841
  let batchDeleteEntityIds = [];
762
842
  let batchDeleteCheckpointIds = [];
@@ -872,6 +952,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
872
952
  sql => InternalTable.Chains.setProgressedChains(sql, pgSchema, Utils.Dict.mapValuesToArray(batch.progressedChainsById, chainAfterBatch => ({
873
953
  chainId: chainAfterBatch.fetchState.chainId,
874
954
  progressBlockNumber: chainAfterBatch.progressBlockNumber,
955
+ progressBlockTime: chainAfterBatch.progressBlockTime,
875
956
  sourceBlockNumber: chainAfterBatch.sourceBlockNumber,
876
957
  totalEventsProcessed: chainAfterBatch.totalEventsProcessed
877
958
  }))),
@@ -883,8 +964,11 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
883
964
  if (Utils.$$Array.notEmpty(registeredAddresses)) {
884
965
  setOperations.push(sql => InternalTable.EnvioAddresses.insert(sql, pgSchema, registeredAddresses.map(staged => staged.row), chainIdMode));
885
966
  }
886
- if (shouldSaveHistory) {
887
- setOperations.push(sql => InternalTable.Checkpoints.insert(sql, pgSchema, batch.checkpointIds, batch.checkpointChainIds, batch.checkpointBlockNumbers, batch.checkpointBlockHashes, batch.checkpointEventsProcessed, chainIdMode));
967
+ if (!Utils.Dict.isEmpty(writtenFrontier)) {
968
+ setOperations.push(sql => InternalTable.Chains.setCheckpointFrontier(sql, pgSchema, writtenFrontier, chainIdMode));
969
+ }
970
+ if (pickedCheckpoints !== undefined) {
971
+ setOperations.push(sql => InternalTable.Checkpoints.insert(sql, pgSchema, pickCheckpoints(batch.checkpointIds, pickedCheckpoints), pickCheckpoints(batch.checkpointChainIds, pickedCheckpoints), pickCheckpoints(batch.checkpointBlockNumbers, pickedCheckpoints), pickCheckpoints(batch.checkpointBlockHashes, pickedCheckpoints), pickCheckpoints(batch.checkpointEventsProcessed, pickedCheckpoints), chainIdMode));
888
972
  }
889
973
  await Promise.all(setOperations.map(dbFunc => dbFunc(sql)));
890
974
  if (sinkPromise === undefined) {
@@ -913,7 +997,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
913
997
  if (exn$1.RE_EXN_ID === PgEncodingError) {
914
998
  let escapeTables$1 = escapeTables !== undefined ? Primitive_option.valFromOption(escapeTables) : new Set();
915
999
  escapeTables$1.add(exn$1.table);
916
- return await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, Primitive_option.some(escapeTables$1));
1000
+ return await writeBatch(sql, batch, pgSchema, rollback, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, Primitive_option.some(escapeTables$1));
917
1001
  }
918
1002
  throw exn$1;
919
1003
  }
@@ -943,7 +1027,7 @@ function makeGetRollbackPreTargetRowsQuery(entityConfig, pgSchema, floors) {
943
1027
  let keyColumns = rollbackKeyColumns(entityConfig);
944
1028
  let keyColumnsCommaSeparated = keyColumns.map(c => tableRef + `."` + c + `"`).join(", ");
945
1029
  let keyMatch = keyColumns.map(c => `h."` + c + `" = ` + tableRef + `."` + c + `"`).join(" AND ");
946
- let bounds = CheckpointBounds.sql(floors.floors, Table.getPgChainIdColumn(entityConfig.table), tableRef);
1030
+ let bounds = CheckpointSequence.sql(floors.checkpointBounds, Table.getPgChainIdColumn(entityConfig.table), tableRef);
947
1031
  return `SELECT DISTINCT ON (` + keyColumnsCommaSeparated + `) ` + dataFieldsCommaSeparated + `, ` + tableRef + `."` + EntityHistory.changeFieldName + `"
948
1032
  FROM "` + pgSchema + `"."` + historyTableName + `"` + bounds.join + `
949
1033
  WHERE ` + tableRef + `."` + EntityHistory.checkpointIdFieldName + `" <= ` + bounds.checkpointId + `
@@ -961,7 +1045,7 @@ function makeGetRollbackRemovedIdsQuery(entityConfig, pgSchema, floors) {
961
1045
  let tableRef = `"` + historyTableName + `"`;
962
1046
  let keyColumns = rollbackKeyColumns(entityConfig);
963
1047
  let keyMatch = keyColumns.map(c => `h."` + c + `" = ` + tableRef + `."` + c + `"`).join(" AND ");
964
- let bounds = CheckpointBounds.sql(floors.floors, Table.getPgChainIdColumn(entityConfig.table), tableRef);
1048
+ let bounds = CheckpointSequence.sql(floors.checkpointBounds, Table.getPgChainIdColumn(entityConfig.table), tableRef);
965
1049
  return `SELECT DISTINCT ` + keyColumns.map(c => tableRef + `."` + c + `"`).join(", ") + `
966
1050
  FROM "` + pgSchema + `"."` + historyTableName + `"` + bounds.join + `
967
1051
  WHERE ` + tableRef + `."` + EntityHistory.checkpointIdFieldName + `" > ` + bounds.checkpointId + `
@@ -982,19 +1066,14 @@ let rollbackChainIdSchema = Utils.$$WeakMap.memoize(table => Stdlib_Option.map(T
982
1066
 
983
1067
  let rollbackRemovedIdSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => s.f(Table.idFieldName, Table.getIdSchema(table))));
984
1068
 
985
- function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isHasuraEnabled, chainIdModeOpt, ecosystem, sink, onInitialize, onNewTables) {
1069
+ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isHasuraEnabled, chainIdModeOpt, ecosystem, sink, isolatedOpt, onInitialize) {
986
1070
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
1071
+ let isolated = isolatedOpt !== undefined ? isolatedOpt : false;
987
1072
  let containerName = "envio-postgres";
988
- let psqlExecOptions_env = Object.fromEntries([
989
- [
990
- "PGPASSWORD",
991
- pgPassword
992
- ],
993
- [
994
- "PATH",
995
- process.env.PATH
996
- ]
997
- ]);
1073
+ let psqlExecOptions_env = {
1074
+ PGPASSWORD: pgPassword,
1075
+ PATH: process.env.PATH
1076
+ };
998
1077
  let psqlExecOptions = {
999
1078
  env: psqlExecOptions_env
1000
1079
  };
@@ -1107,9 +1186,6 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1107
1186
  }
1108
1187
  }
1109
1188
  let cacheTableInfo = await queryCacheTableInfo();
1110
- if (withUpload && Utils.$$Array.notEmpty(cacheTableInfo) && onNewTables !== undefined) {
1111
- await onNewTables(cacheTableInfo.map(info => info.table_name));
1112
- }
1113
1189
  let cache = {};
1114
1190
  cacheTableInfo.forEach(param => {
1115
1191
  let tableName = param.table_name;
@@ -1138,7 +1214,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1138
1214
  if (sink !== undefined) {
1139
1215
  await sink.initialize(entities);
1140
1216
  }
1141
- let queries = makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfigs, pgEntities, enums, Utils.$$Array.isEmpty(schemaTableNames), true, chainIdMode);
1217
+ let queries = makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, CheckpointSequence.fromEntities(entities), chainConfigs, pgEntities, enums, Utils.$$Array.isEmpty(schemaTableNames), true, chainIdMode);
1142
1218
  let rowsByChain = chainConfigs.map(chainConfig => ChainState.configStorageRows(chainConfig, ecosystem, contractMapping));
1143
1219
  let configAddressRows = rowsByChain.flat();
1144
1220
  await sql.begin(async sql => {
@@ -1165,19 +1241,20 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1165
1241
  endBlock: chainConfig.endBlock,
1166
1242
  maxReorgDepth: chainConfig.maxReorgDepth,
1167
1243
  progressBlockNumber: -1,
1244
+ progressBlockTime: undefined,
1168
1245
  numEventsProcessed: 0,
1169
1246
  firstEventBlockNumber: undefined,
1170
1247
  timestampCaughtUpToHeadOrEndblock: undefined,
1171
1248
  addressRows: AddressRows.seedRowsOf(rowsByChain[idx]),
1172
1249
  sourceBlockNumber: 0
1173
1250
  })),
1174
- checkpointId: InternalTable.Checkpoints.initialCheckpointId,
1251
+ checkpointFrontier: Frontier.empty(),
1175
1252
  reorgCheckpoints: []
1176
1253
  };
1177
1254
  };
1178
1255
  let loadOrThrow = async (filter, table) => {
1179
1256
  let params = [];
1180
- let condition = makeFilterCondition(filter, table, params);
1257
+ let condition = makeFilterCondition(filter, table, pgSchema, params);
1181
1258
  let rows;
1182
1259
  try {
1183
1260
  rows = await sql.unsafe(makeLoadQuery(pgSchema, table.tableName, condition), params, {prepare: true});
@@ -1206,12 +1283,8 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1206
1283
  let queryFields = Table.queryFields(table);
1207
1284
  let columns = [];
1208
1285
  let seen = new Set();
1209
- let collect = filter => {
1210
- if (filter.operator === "and") {
1211
- filter.filters.forEach(collect);
1212
- return;
1213
- }
1214
- let match = queryFields[filter.fieldName];
1286
+ filters.forEach(filter => Utils.Dict.forEachWithKey(EntityFilter.entries(filter), (param, fieldName) => {
1287
+ let match = queryFields[fieldName];
1215
1288
  if (match === undefined) {
1216
1289
  return;
1217
1290
  }
@@ -1221,8 +1294,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1221
1294
  columns.push(pgDbFieldName);
1222
1295
  return;
1223
1296
  }
1224
- };
1225
- filters.forEach(collect);
1297
+ }));
1226
1298
  return columns;
1227
1299
  };
1228
1300
  let runAndVerify = async (sql, prepared) => {
@@ -1246,10 +1318,23 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1246
1318
  }
1247
1319
  return IndexManager.resync(indexManager, name, rows);
1248
1320
  };
1249
- let ensureQueryIndexes = async (table, filters) => {
1250
- let columns = filterColumns(table, filters);
1321
+ let partitionChainIds = chainIds => {
1322
+ if (isolated) {
1323
+ return Primitive_option.some(chainIds);
1324
+ }
1325
+ };
1326
+ let queryTableName = (entityConfig, scope) => {
1327
+ if (scope === "crossChain") {
1328
+ return entityConfig.table.tableName;
1329
+ } else {
1330
+ return indexTableNames(entityConfig, partitionChainIds([scope]))[0];
1331
+ }
1332
+ };
1333
+ let ensureQueryIndexes = async (entityConfig, scope, filters) => {
1334
+ let tableName = queryTableName(entityConfig, scope);
1335
+ let columns = filterColumns(entityConfig.table, filters);
1251
1336
  await Promise.all(columns.map(column => {
1252
- let definition = IndexDefinition.single(table.tableName, column);
1337
+ let definition = IndexDefinition.single(tableName, column);
1253
1338
  return Stdlib_Promise.$$catch(IndexManager.ensure(indexManager, definition, "LeadingColumns", async () => {
1254
1339
  let prepared = IndexManager.prepare(indexManager, definition, "LeadingColumns", pgSchema);
1255
1340
  if (prepared === undefined) {
@@ -1258,7 +1343,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1258
1343
  let verb = prepared.isRebuild ? "Rebuilding unusable index" : "Creating index";
1259
1344
  Logging.info({
1260
1345
  storage: storageName,
1261
- msg: verb + ` "` + prepared.name + `" to serve a getWhere query on "` + table.tableName + `". Writes to the table are paused until it completes. ` + slowOnLargeDatabaseNotice
1346
+ msg: verb + ` "` + prepared.name + `" to serve a getWhere query on "` + tableName + `". Writes to the table are paused until it completes. ` + slowOnLargeDatabaseNotice
1262
1347
  });
1263
1348
  let timeRef = Performance.now();
1264
1349
  let entry = await runAndVerify(sql, prepared);
@@ -1270,15 +1355,15 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1270
1355
  }), async exn => {
1271
1356
  Logging.warn({
1272
1357
  storage: storageName,
1273
- msg: `Failed to create an index on "` + table.tableName + `"("` + column + `") for a getWhere query. The query runs without it.`,
1358
+ msg: `Failed to create an index on "` + tableName + `"("` + column + `") for a getWhere query. The query runs without it.`,
1274
1359
  err: Utils.prettifyExn(exn)
1275
1360
  });
1276
1361
  return await resyncIndex(IndexDefinition.name(definition));
1277
1362
  });
1278
1363
  }));
1279
1364
  };
1280
- let ensureSchemaIndexes = async entities => {
1281
- let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres));
1365
+ let ensureSchemaIndexes = async (entities, chainIds) => {
1366
+ let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres), partitionChainIds(chainIds));
1282
1367
  await Promise.all(schemaIndexes.map(definition => Stdlib_Promise.$$catch(IndexManager.ensure(indexManager, definition, "Exact", async () => {
1283
1368
  let prepared = IndexManager.prepare(indexManager, definition, "Exact", pgSchema);
1284
1369
  if (prepared === undefined) {
@@ -1306,7 +1391,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1306
1391
  })));
1307
1392
  };
1308
1393
  let finalizeBackfill = async (entities, chainIds, readyAt) => {
1309
- let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres));
1394
+ let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres), partitionChainIds(chainIds));
1310
1395
  let missing = Stdlib_Array.filterMap(schemaIndexes, definition => IndexManager.prepare(indexManager, definition, "Exact", pgSchema));
1311
1396
  let rebuilt = missing.filter(prepared => prepared.isRebuild);
1312
1397
  if (rebuilt.length !== 0) {
@@ -1362,9 +1447,6 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1362
1447
  let setEffectCacheOrThrow = async (table, itemSchema, items, initialize) => {
1363
1448
  if (initialize) {
1364
1449
  await sql.unsafe(makeCreateTableQuery(table, pgSchema, false, undefined, undefined));
1365
- if (onNewTables !== undefined) {
1366
- await onNewTables([table.tableName]);
1367
- }
1368
1450
  }
1369
1451
  return await setOrThrow$1(items, table, itemSchema);
1370
1452
  };
@@ -1415,22 +1497,31 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1415
1497
  return Logging.errorWithExn(Utils.prettifyExn(exn$1), `Failed to dump cache.`);
1416
1498
  }
1417
1499
  };
1418
- let resumeInitialState = async (entities, throwIfIncompatible) => {
1500
+ let resumeInitialState = async (entities, chainIds, throwIfIncompatible) => {
1419
1501
  let match = await Promise.all([
1420
1502
  restoreEffectCache(false),
1421
- InternalTable.Chains.getInitialState(sql, pgSchema).then(rawInitialStates => rawInitialStates.map(rawInitialState => ({
1422
- id: rawInitialState.id,
1423
- startBlock: rawInitialState.startBlock,
1424
- endBlock: Primitive_option.fromNull(rawInitialState.endBlock),
1425
- maxReorgDepth: rawInitialState.maxReorgDepth,
1426
- progressBlockNumber: rawInitialState.progressBlockNumber,
1427
- numEventsProcessed: rawInitialState.numEventsProcessed,
1428
- firstEventBlockNumber: Primitive_option.fromNull(rawInitialState.firstEventBlockNumber),
1429
- timestampCaughtUpToHeadOrEndblock: Primitive_option.fromNull(rawInitialState.timestampCaughtUpToHeadOrEndblock),
1430
- addressRows: rawInitialState.addressRows,
1431
- sourceBlockNumber: rawInitialState.sourceBlockNumber
1432
- }))),
1433
- sql.unsafe(InternalTable.Checkpoints.makeCommitedCheckpointIdQuery(pgSchema)),
1503
+ InternalTable.Chains.getInitialState(sql, pgSchema).then(rawInitialStates => {
1504
+ let rawInitialStates$1 = rawInitialStates.filter(rawInitialState => chainIds.includes(rawInitialState.id));
1505
+ return [
1506
+ rawInitialStates$1.map(rawInitialState => ({
1507
+ id: rawInitialState.id,
1508
+ startBlock: rawInitialState.startBlock,
1509
+ endBlock: Primitive_option.fromNull(rawInitialState.endBlock),
1510
+ maxReorgDepth: rawInitialState.maxReorgDepth,
1511
+ progressBlockNumber: rawInitialState.progressBlockNumber,
1512
+ progressBlockTime: InternalTable.Chains.blockTimeFromDb(rawInitialState.progressBlockTime),
1513
+ numEventsProcessed: rawInitialState.numEventsProcessed,
1514
+ firstEventBlockNumber: Primitive_option.fromNull(rawInitialState.firstEventBlockNumber),
1515
+ timestampCaughtUpToHeadOrEndblock: Primitive_option.fromNull(rawInitialState.timestampCaughtUpToHeadOrEndblock),
1516
+ addressRows: rawInitialState.addressRows,
1517
+ sourceBlockNumber: rawInitialState.sourceBlockNumber
1518
+ })),
1519
+ Frontier.fromEntries(rawInitialStates$1.map(rawInitialState => [
1520
+ rawInitialState.id,
1521
+ BigInt(rawInitialState.checkpointId)
1522
+ ]))
1523
+ ];
1524
+ }),
1434
1525
  sql.unsafe(InternalTable.Checkpoints.makeGetReorgCheckpointsQuery(pgSchema)),
1435
1526
  Promise.all([
1436
1527
  InternalTable.EnvioInfo.read(sql, pgSchema),
@@ -1451,21 +1542,22 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1451
1542
  }
1452
1543
  })
1453
1544
  ]);
1454
- let match$1 = match[4];
1545
+ let match$1 = match[3];
1455
1546
  let storedContractMapping = match$1[1];
1456
1547
  let storedEnvioInfo = match$1[0];
1457
- let chains = match[1];
1548
+ let match$2 = match[1];
1549
+ let checkpointFrontier = match$2[1];
1550
+ let chains = match$2[0];
1458
1551
  throwIfIncompatible(storedEnvioInfo, storedContractMapping);
1459
1552
  await reloadIndexCatalog();
1460
- let checkpointId = BigInt(match[2][0].id);
1461
- let reorgCheckpoints = match[3].map(raw => ({
1553
+ let reorgCheckpoints = match[2].map(raw => ({
1462
1554
  id: BigInt(raw.id),
1463
1555
  chain_id: ChainId.normalizeOrThrow(raw.chain_id),
1464
1556
  block_number: raw.block_number,
1465
1557
  block_hash: raw.block_hash
1466
1558
  }));
1467
1559
  if (sink !== undefined) {
1468
- await sink.resume(checkpointId, chains, entities);
1560
+ await sink.resume(checkpointFrontier, chains, entities);
1469
1561
  }
1470
1562
  return {
1471
1563
  cleanRun: false,
@@ -1473,7 +1565,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1473
1565
  envioInfo: storedEnvioInfo,
1474
1566
  cache: match[0],
1475
1567
  chains: chains,
1476
- checkpointId: checkpointId,
1568
+ checkpointFrontier: checkpointFrontier,
1477
1569
  reorgCheckpoints: reorgCheckpoints
1478
1570
  };
1479
1571
  };
@@ -1487,7 +1579,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1487
1579
  let getRollbackTargetCheckpoint = (reorgChainId, lastKnownValidBlockNumber) => InternalTable.Checkpoints.getRollbackTargetCheckpoint(sql, pgSchema, reorgChainId, lastKnownValidBlockNumber);
1488
1580
  let getRollbackProgressDiff = floors => InternalTable.Checkpoints.getRollbackProgressDiff(sql, pgSchema, floors);
1489
1581
  let getRollbackData = async (entityConfig, floors) => {
1490
- let params = CheckpointBounds.params(floors.floors);
1582
+ let params = CheckpointSequence.params(floors.checkpointBounds);
1491
1583
  let match = await Promise.all([
1492
1584
  sql.unsafe(makeGetRollbackRemovedIdsQuery(entityConfig, pgSchema, floors), params, {prepare: true}),
1493
1585
  sql.unsafe(makeGetRollbackPreTargetRowsQuery(entityConfig, pgSchema, floors), params, {prepare: true})
@@ -1521,7 +1613,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1521
1613
  S$RescriptSchema.parseOrThrow(restoredEntitiesResult, Table.pgRowsSchema(entityConfig.table))
1522
1614
  ];
1523
1615
  };
1524
- let writeBatchMethod = async (batch, rollback, isInReorgThreshold, config, allEntities, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, onWrite) => {
1616
+ let writeBatchMethod = async (batch, rollback, config, allEntities, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, onWrite) => {
1525
1617
  let pgUpdates = [];
1526
1618
  let chUpdates = [];
1527
1619
  for (let i = 0, i_finish = updatedEntities.length; i < i_finish; ++i) {
@@ -1537,14 +1629,14 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1537
1629
  let sinkPromise;
1538
1630
  if (sink !== undefined) {
1539
1631
  let timerRef = Performance.now();
1540
- sinkPromise = sink.writeBatch(batch, chUpdates).then(() => {
1632
+ sinkPromise = sink.writeBatch(batch, rollback !== undefined ? rollback.diffCheckpoints : [], chUpdates).then(() => {
1541
1633
  onWrite(sink.name, Performance.secondsSince(timerRef));
1542
1634
  }).catch(exn => exn);
1543
1635
  } else {
1544
1636
  sinkPromise = undefined;
1545
1637
  }
1546
1638
  let primaryTimerRef = Performance.now();
1547
- await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, pgUpdates, registeredAddresses, sinkPromise, chainMetaData, undefined);
1639
+ await writeBatch(sql, batch, pgSchema, rollback, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, pgUpdates, registeredAddresses, sinkPromise, chainMetaData, undefined);
1548
1640
  return onWrite(storageName, Performance.secondsSince(primaryTimerRef));
1549
1641
  };
1550
1642
  let close = () => sql.end();
@@ -1596,21 +1688,14 @@ function makeStorageFromEnv(config, sqlOpt, pgSchemaOpt, isHasuraEnabledOpt) {
1596
1688
  if (missing.length !== 0) {
1597
1689
  Stdlib_JsError.throwWithMessage(`ClickHouse storage is enabled but required env vars are not set: ` + missing.join(", ") + `. Please set them, disable clickhouse in the \`storage\` config, or run \`envio dev\` for a pre-configured local ClickHouse.`);
1598
1690
  }
1599
- tmp = Sink.makeClickHouse(host, database, username, password, config.chainIdMode);
1691
+ tmp = Sink.makeClickHouse(host, database, username, password, config.checkpointSequence, config.chainIdMode);
1600
1692
  } else {
1601
1693
  tmp = undefined;
1602
1694
  }
1603
- return make(sql, Env.Db.host, pgSchema, Env.Db.port, Env.Db.user, Env.Db.database, Env.Db.password, isHasuraEnabled, config.chainIdMode, config.ecosystem.name, tmp, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(Env.Hasura.graphqlEndpoint, {
1695
+ return make(sql, Env.Db.host, pgSchema, Env.Db.port, Env.Db.user, Env.Db.database, Env.Db.password, isHasuraEnabled, config.chainIdMode, config.ecosystem.name, tmp, config.isolated, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(Env.Hasura.graphqlEndpoint, {
1604
1696
  role: Env.Hasura.role,
1605
1697
  secret: Env.Hasura.secret
1606
- }, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.userEntities.map(e => e.table))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking tables`))) : undefined, isHasuraEnabled ? tableNames => Stdlib_Promise.$$catch(Hasura.trackTables(Env.Hasura.graphqlEndpoint, {
1607
- role: Env.Hasura.role,
1608
- secret: Env.Hasura.secret
1609
- }, pgSchema, tableNames.map(tableName => ({
1610
- tableName: tableName,
1611
- description: undefined,
1612
- columnConfigs: {}
1613
- }))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking new tables`))) : undefined);
1698
+ }, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.userEntities.map(e => e.table))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking tables`))) : undefined);
1614
1699
  }
1615
1700
 
1616
1701
  function makePersistenceFromConfig(config, storageOpt) {
@@ -1624,9 +1709,10 @@ export {
1624
1709
  makeClient,
1625
1710
  formatSeconds,
1626
1711
  slowOnLargeDatabaseNotice,
1712
+ partitionTableName,
1713
+ indexTableNames,
1627
1714
  getSchemaIndexes,
1628
1715
  makeCreateTableQuery,
1629
- partitionTableName,
1630
1716
  rowSchemaCache,
1631
1717
  getRowSchema,
1632
1718
  entityHistoryCache,
@@ -1658,6 +1744,7 @@ export {
1658
1744
  deleteByIdsOrThrow,
1659
1745
  makeInsertDeleteUpdatesQuery,
1660
1746
  executeSet,
1747
+ pickCheckpoints,
1661
1748
  writeBatch,
1662
1749
  rollbackKeyColumns,
1663
1750
  makeGetRollbackPreTargetRowsQuery,