envio 2.32.3 → 3.0.0-alpha.0

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 (115) hide show
  1. package/bin.js +5 -3
  2. package/evm.schema.json +23 -6
  3. package/fuel.schema.json +17 -5
  4. package/index.d.ts +1 -27
  5. package/index.js +9 -6
  6. package/package.json +12 -7
  7. package/rescript.json +4 -3
  8. package/src/{Address.res.js → Address.res.mjs} +7 -6
  9. package/src/Batch.res +4 -4
  10. package/src/{Batch.res.js → Batch.res.mjs} +19 -18
  11. package/src/{ChainMap.res.js → ChainMap.res.mjs} +20 -19
  12. package/src/Change.res +9 -0
  13. package/src/Config.res +5 -5
  14. package/src/{Config.res.js → Config.res.mjs} +13 -10
  15. package/src/Envio.gen.ts +4 -17
  16. package/src/Envio.res +13 -38
  17. package/src/{Envio.res.js → Envio.res.mjs} +5 -16
  18. package/src/{ErrorHandling.res.js → ErrorHandling.res.mjs} +10 -9
  19. package/src/EventRegister.res +10 -11
  20. package/src/{EventRegister.res.js → EventRegister.res.mjs} +33 -26
  21. package/src/EventRegister.resi +2 -1
  22. package/src/{EventUtils.res.js → EventUtils.res.mjs} +10 -9
  23. package/src/{EvmTypes.res.js → EvmTypes.res.mjs} +5 -4
  24. package/src/{FetchState.res.js → FetchState.res.mjs} +44 -43
  25. package/src/{Hasura.res.js → Hasura.res.mjs} +25 -24
  26. package/src/InMemoryStore.res +7 -15
  27. package/src/{InMemoryStore.res.js → InMemoryStore.res.mjs} +21 -22
  28. package/src/InMemoryTable.res +50 -35
  29. package/src/{InMemoryTable.res.js → InMemoryTable.res.mjs} +73 -104
  30. package/src/Internal.gen.ts +1 -5
  31. package/src/Internal.res +29 -40
  32. package/src/Internal.res.mjs +58 -0
  33. package/src/{LazyLoader.res.js → LazyLoader.res.mjs} +14 -13
  34. package/src/{LoadManager.res.js → LoadManager.res.mjs} +11 -10
  35. package/src/{LogSelection.res.js → LogSelection.res.mjs} +14 -13
  36. package/src/{Logging.res.js → Logging.res.mjs} +37 -36
  37. package/src/Persistence.res +190 -38
  38. package/src/Persistence.res.mjs +213 -0
  39. package/src/PgStorage.res +700 -14
  40. package/src/{PgStorage.res.js → PgStorage.res.mjs} +478 -65
  41. package/src/Platform.res +140 -0
  42. package/src/Platform.res.mjs +170 -0
  43. package/src/Prometheus.res +41 -0
  44. package/src/{Prometheus.res.js → Prometheus.res.mjs} +106 -60
  45. package/src/{ReorgDetection.res.js → ReorgDetection.res.mjs} +12 -11
  46. package/src/SafeCheckpointTracking.res +5 -4
  47. package/src/{SafeCheckpointTracking.res.js → SafeCheckpointTracking.res.mjs} +6 -5
  48. package/src/Sink.res +47 -0
  49. package/src/Sink.res.mjs +37 -0
  50. package/src/{TableIndices.res.js → TableIndices.res.mjs} +8 -7
  51. package/src/{Throttler.res.js → Throttler.res.mjs} +7 -6
  52. package/src/{Time.res.js → Time.res.mjs} +8 -7
  53. package/src/{TopicFilter.res.js → TopicFilter.res.mjs} +18 -17
  54. package/src/Utils.res +42 -0
  55. package/src/{Utils.res.js → Utils.res.mjs} +71 -34
  56. package/src/bindings/BigDecimal.gen.ts +2 -2
  57. package/src/bindings/BigDecimal.res +5 -5
  58. package/src/bindings/BigDecimal.res.d.mts +5 -0
  59. package/src/bindings/{BigDecimal.res.js → BigDecimal.res.mjs} +10 -9
  60. package/src/bindings/BigInt.gen.ts +2 -2
  61. package/src/bindings/BigInt.res.d.mts +5 -0
  62. package/src/bindings/{BigInt.res.js → BigInt.res.mjs} +25 -24
  63. package/src/bindings/ClickHouse.res +387 -0
  64. package/src/bindings/ClickHouse.res.mjs +275 -0
  65. package/src/bindings/Ethers.gen.ts +2 -2
  66. package/src/bindings/Ethers.res.d.mts +5 -0
  67. package/src/bindings/{Ethers.res.js → Ethers.res.mjs} +18 -17
  68. package/src/bindings/Express.res.mjs +2 -0
  69. package/src/bindings/{Hrtime.res.js → Hrtime.res.mjs} +13 -12
  70. package/src/bindings/{Lodash.res.js → Lodash.res.mjs} +4 -3
  71. package/src/bindings/NodeJs.res +13 -1
  72. package/src/bindings/NodeJs.res.mjs +48 -0
  73. package/src/bindings/Pino.res +4 -4
  74. package/src/bindings/{Pino.res.js → Pino.res.mjs} +16 -15
  75. package/src/bindings/Postgres.res +17 -2
  76. package/src/bindings/{Postgres.res.js → Postgres.res.mjs} +4 -3
  77. package/src/bindings/{PromClient.res.js → PromClient.res.mjs} +6 -5
  78. package/src/bindings/{Promise.res.js → Promise.res.mjs} +6 -5
  79. package/src/bindings/{SDSL.res.js → SDSL.res.mjs} +3 -2
  80. package/src/bindings/{Viem.res.js → Viem.res.mjs} +9 -8
  81. package/src/bindings/vendored-lodash-fns.js +3 -35
  82. package/src/db/EntityHistory.res +33 -156
  83. package/src/db/EntityHistory.res.mjs +121 -0
  84. package/src/db/InternalTable.gen.ts +2 -2
  85. package/src/db/InternalTable.res +55 -56
  86. package/src/db/{InternalTable.res.js → InternalTable.res.mjs} +68 -71
  87. package/src/db/{Schema.res.js → Schema.res.mjs} +10 -9
  88. package/src/db/Table.res +86 -22
  89. package/src/db/{Table.res.js → Table.res.mjs} +108 -40
  90. package/src/sources/{EventRouter.res.js → EventRouter.res.mjs} +17 -16
  91. package/src/sources/{Fuel.res.js → Fuel.res.mjs} +6 -5
  92. package/src/sources/{HyperFuel.res.js → HyperFuel.res.mjs} +14 -13
  93. package/src/sources/{HyperFuelClient.res.js → HyperFuelClient.res.mjs} +7 -6
  94. package/src/sources/{HyperFuelSource.res.js → HyperFuelSource.res.mjs} +28 -27
  95. package/src/sources/{HyperSync.res.js → HyperSync.res.mjs} +21 -20
  96. package/src/sources/HyperSyncClient.gen.ts +1 -1
  97. package/src/sources/HyperSyncClient.res +78 -20
  98. package/src/sources/{HyperSyncClient.res.js → HyperSyncClient.res.mjs} +32 -15
  99. package/src/sources/{HyperSyncJsonApi.res.js → HyperSyncJsonApi.res.mjs} +10 -9
  100. package/src/sources/HyperSyncSource.res +77 -9
  101. package/src/sources/{HyperSyncSource.res.js → HyperSyncSource.res.mjs} +99 -38
  102. package/src/sources/{Rpc.res.js → Rpc.res.mjs} +16 -15
  103. package/src/sources/{RpcSource.res.js → RpcSource.res.mjs} +40 -39
  104. package/src/sources/Source.res +1 -1
  105. package/src/sources/{Source.res.js → Source.res.mjs} +4 -3
  106. package/src/sources/SourceManager.res +12 -1
  107. package/src/sources/{SourceManager.res.js → SourceManager.res.mjs} +32 -21
  108. package/src/sources/vendored-fuel-abi-coder.js +94 -149
  109. package/src/vendored/{Rest.res.js → Rest.res.mjs} +12 -11
  110. package/src/Internal.res.js +0 -62
  111. package/src/Persistence.res.js +0 -159
  112. package/src/bindings/NodeJs.res.js +0 -35
  113. package/src/db/EntityHistory.res.js +0 -195
  114. /package/src/{Indexer.res.js → Change.res.mjs} +0 -0
  115. /package/src/{bindings/Express.res.js → Indexer.res.mjs} +0 -0
@@ -1,9 +1,8 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
- 'use strict';
3
2
 
4
- var Utils = require("./Utils.res.js");
5
- var Belt_Array = require("rescript/lib/js/belt_Array.js");
6
- var Caml_js_exceptions = require("rescript/lib/js/caml_js_exceptions.js");
3
+ import * as Utils from "./Utils.res.mjs";
4
+ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
5
+ import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
7
6
 
8
7
  var Call = {};
9
8
 
@@ -123,10 +122,12 @@ function call(loadManager, input, key, load, hasher, shouldGroup, hasInMemory, g
123
122
  return promise;
124
123
  }
125
124
 
126
- exports.Call = Call;
127
- exports.Group = Group;
128
- exports.make = make;
129
- exports.schedule = schedule;
130
- exports.noopHasher = noopHasher;
131
- exports.call = call;
125
+ export {
126
+ Call ,
127
+ Group ,
128
+ make ,
129
+ schedule ,
130
+ noopHasher ,
131
+ call ,
132
+ }
132
133
  /* Utils Not a pure module */
@@ -1,12 +1,11 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
- 'use strict';
3
2
 
4
- var Utils = require("./Utils.res.js");
5
- var Js_exn = require("rescript/lib/js/js_exn.js");
6
- var Belt_Array = require("rescript/lib/js/belt_Array.js");
7
- var Belt_Option = require("rescript/lib/js/belt_Option.js");
8
- var Caml_option = require("rescript/lib/js/caml_option.js");
9
- var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
3
+ import * as Utils from "./Utils.res.mjs";
4
+ import * as Js_exn from "rescript/lib/es6/js_exn.js";
5
+ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
6
+ import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
7
+ import * as Caml_option from "rescript/lib/es6/caml_option.js";
8
+ import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js";
10
9
 
11
10
  var MissingRequiredTopic0 = /* @__PURE__ */Caml_exceptions.create("LogSelection.MissingRequiredTopic0");
12
11
 
@@ -194,10 +193,12 @@ function parseEventFiltersOrThrow(eventFilters, sighash, params, topic1Opt, topi
194
193
  };
195
194
  }
196
195
 
197
- exports.MissingRequiredTopic0 = MissingRequiredTopic0;
198
- exports.makeTopicSelection = makeTopicSelection;
199
- exports.hasFilters = hasFilters;
200
- exports.compressTopicSelections = compressTopicSelections;
201
- exports.make = make;
202
- exports.parseEventFiltersOrThrow = parseEventFiltersOrThrow;
196
+ export {
197
+ MissingRequiredTopic0 ,
198
+ makeTopicSelection ,
199
+ hasFilters ,
200
+ compressTopicSelections ,
201
+ make ,
202
+ parseEventFiltersOrThrow ,
203
+ }
203
204
  /* Utils Not a pure module */
@@ -1,13 +1,12 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
- 'use strict';
3
2
 
4
- var Pino = require("./bindings/Pino.res.js");
5
- var Pino$1 = require("pino");
6
- var Utils = require("./Utils.res.js");
7
- var Js_exn = require("rescript/lib/js/js_exn.js");
8
- var Js_dict = require("rescript/lib/js/js_dict.js");
9
- var Caml_obj = require("rescript/lib/js/caml_obj.js");
10
- var Caml_option = require("rescript/lib/js/caml_option.js");
3
+ import * as Pino from "./bindings/Pino.res.mjs";
4
+ import * as Pino$1 from "pino";
5
+ import * as Utils from "./Utils.res.mjs";
6
+ import * as Js_exn from "rescript/lib/es6/js_exn.js";
7
+ import * as Js_dict from "rescript/lib/es6/js_dict.js";
8
+ import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
9
+ import * as Caml_option from "rescript/lib/es6/caml_option.js";
11
10
 
12
11
  var logLevels = Js_dict.fromArray([
13
12
  [
@@ -75,14 +74,14 @@ function makeLogger(logStrategy, logFilePath, defaultFileLogLevel, userLogLevel)
75
74
  switch (logStrategy) {
76
75
  case "ecs-file" :
77
76
  var newrecord = Caml_obj.obj_dup(Pino.ECS.make());
78
- return Pino$1((newrecord.customLevels = logLevels, newrecord), Pino$1.transport(pinoFile));
77
+ return Pino$1.pino((newrecord.customLevels = logLevels, newrecord), Pino$1.transport(pinoFile));
79
78
  case "ecs-console" :
80
79
  var newrecord$1 = Caml_obj.obj_dup(Pino.ECS.make());
81
- return Pino$1((newrecord$1.customLevels = logLevels, newrecord$1.level = userLogLevel, newrecord$1));
80
+ return Pino$1.pino((newrecord$1.customLevels = logLevels, newrecord$1.level = userLogLevel, newrecord$1));
82
81
  case "ecs-console-multistream" :
83
82
  return makeMultiStreamLogger(undefined, Pino.ECS.make());
84
83
  case "file-only" :
85
- return Pino$1({
84
+ return Pino$1.pino({
86
85
  level: defaultFileLogLevel,
87
86
  customLevels: logLevels
88
87
  }, Pino$1.transport(pinoFile));
@@ -262,29 +261,31 @@ function getUserLogger(item) {
262
261
  };
263
262
  }
264
263
 
265
- exports.logLevels = logLevels;
266
- exports.makeLogger = makeLogger;
267
- exports.setLogger = setLogger;
268
- exports.getLogger = getLogger;
269
- exports.setLogLevel = setLogLevel;
270
- exports.trace = trace;
271
- exports.debug = debug;
272
- exports.info = info;
273
- exports.warn = warn;
274
- exports.error = error;
275
- exports.errorWithExn = errorWithExn;
276
- exports.fatal = fatal;
277
- exports.childTrace = childTrace;
278
- exports.childDebug = childDebug;
279
- exports.childInfo = childInfo;
280
- exports.childWarn = childWarn;
281
- exports.childError = childError;
282
- exports.childErrorWithExn = childErrorWithExn;
283
- exports.childFatal = childFatal;
284
- exports.createChild = createChild;
285
- exports.createChildFrom = createChildFrom;
286
- exports.getItemLogger = getItemLogger;
287
- exports.logForItem = logForItem;
288
- exports.noopLogger = noopLogger;
289
- exports.getUserLogger = getUserLogger;
264
+ export {
265
+ logLevels ,
266
+ makeLogger ,
267
+ setLogger ,
268
+ getLogger ,
269
+ setLogLevel ,
270
+ trace ,
271
+ debug ,
272
+ info ,
273
+ warn ,
274
+ error ,
275
+ errorWithExn ,
276
+ fatal ,
277
+ childTrace ,
278
+ childDebug ,
279
+ childInfo ,
280
+ childWarn ,
281
+ childError ,
282
+ childErrorWithExn ,
283
+ childFatal ,
284
+ createChild ,
285
+ createChildFrom ,
286
+ getItemLogger ,
287
+ logForItem ,
288
+ noopLogger ,
289
+ getUserLogger ,
290
+ }
290
291
  /* logLevels Not a pure module */
@@ -29,13 +29,24 @@ type initialState = {
29
29
  cleanRun: bool,
30
30
  cache: dict<effectCacheRecord>,
31
31
  chains: array<initialChainState>,
32
- checkpointId: int,
32
+ checkpointId: Internal.checkpointId,
33
33
  // Needed to keep reorg detection logic between restarts
34
34
  reorgCheckpoints: array<Internal.reorgCheckpoint>,
35
35
  }
36
36
 
37
37
  type operator = [#">" | #"=" | #"<"]
38
38
 
39
+ type updatedEffectCache = {
40
+ effect: Internal.effect,
41
+ items: array<Internal.effectCacheItem>,
42
+ shouldInitialize: bool,
43
+ }
44
+
45
+ type updatedEntity = {
46
+ entityConfig: Internal.entityConfig,
47
+ updates: array<Internal.inMemoryStoreEntityUpdate<Internal.entity>>,
48
+ }
49
+
39
50
  type storage = {
40
51
  // Should return true if we already have persisted data
41
52
  // and we can skip initialization
@@ -45,7 +56,7 @@ type storage = {
45
56
  initialize: (
46
57
  ~chainConfigs: array<Config.chain>=?,
47
58
  ~entities: array<Internal.entityConfig>=?,
48
- ~enums: array<Internal.enumConfig<Internal.enum>>=?,
59
+ ~enums: array<Table.enumConfig<Table.enum>>=?,
49
60
  ) => promise<initialState>,
50
61
  resumeInitialState: unit => promise<initialState>,
51
62
  @raises("StorageError")
@@ -77,10 +88,53 @@ type storage = {
77
88
  ) => promise<unit>,
78
89
  // This is to download cache from the database to .envio/cache
79
90
  dumpEffectCache: unit => promise<unit>,
91
+ // Execute raw SQL query
92
+ executeUnsafe: string => promise<unknown>,
93
+ // Check if entity history has rows
94
+ hasEntityHistoryRows: unit => promise<bool>,
95
+ // Update chain metadata
96
+ setChainMeta: dict<InternalTable.Chains.metaFields> => promise<unknown>,
97
+ // Prune old checkpoints
98
+ pruneStaleCheckpoints: (~safeCheckpointId: Internal.checkpointId) => promise<unit>,
99
+ // Prune stale entity history
100
+ pruneStaleEntityHistory: (
101
+ ~entityName: string,
102
+ ~entityIndex: int,
103
+ ~safeCheckpointId: Internal.checkpointId,
104
+ ) => promise<unit>,
105
+ // Get rollback target checkpoint
106
+ getRollbackTargetCheckpoint: (
107
+ ~reorgChainId: int,
108
+ ~lastKnownValidBlockNumber: int,
109
+ ) => promise<array<{"id": Internal.checkpointId}>>,
110
+ // Get rollback progress diff
111
+ getRollbackProgressDiff: (
112
+ ~rollbackTargetCheckpointId: Internal.checkpointId,
113
+ ) => promise<
114
+ array<{
115
+ "chain_id": int,
116
+ "events_processed_diff": string,
117
+ "new_progress_block_number": int,
118
+ }>,
119
+ >,
120
+ // Get rollback data for entity
121
+ getRollbackData: (
122
+ ~entityConfig: Internal.entityConfig,
123
+ ~rollbackTargetCheckpointId: Internal.checkpointId,
124
+ ) => promise<(array<{"id": string}>, array<unknown>)>,
125
+ // Write batch to storage
126
+ writeBatch: (
127
+ ~batch: Batch.t,
128
+ ~rawEvents: array<InternalTable.RawEvents.t>,
129
+ ~rollbackTargetCheckpointId: option<Internal.checkpointId>,
130
+ ~isInReorgThreshold: bool,
131
+ ~config: Config.t,
132
+ ~allEntities: array<Internal.entityConfig>,
133
+ ~updatedEffectsCache: array<updatedEffectCache>,
134
+ ~updatedEntities: array<updatedEntity>,
135
+ ) => promise<unit>,
80
136
  }
81
137
 
82
- exception StorageError({message: string, reason: exn})
83
-
84
138
  type storageStatus =
85
139
  | Unknown
86
140
  | Initializing(promise<unit>)
@@ -89,38 +143,28 @@ type storageStatus =
89
143
  type t = {
90
144
  userEntities: array<Internal.entityConfig>,
91
145
  allEntities: array<Internal.entityConfig>,
92
- allEnums: array<Internal.enumConfig<Internal.enum>>,
146
+ allEnums: array<Table.enumConfig<Table.enum>>,
93
147
  mutable storageStatus: storageStatus,
94
148
  mutable storage: storage,
95
- // FIXME: This is temporary to move it library
96
- // Should be a part of the storage interface and db agnostic
97
- mutable sql: Postgres.sql,
98
149
  }
99
150
 
100
- let entityHistoryActionEnumConfig: Internal.enumConfig<EntityHistory.RowAction.t> = {
101
- name: EntityHistory.RowAction.name,
102
- variants: EntityHistory.RowAction.variants,
103
- schema: EntityHistory.RowAction.schema,
104
- default: SET,
105
- }
151
+ exception StorageError({message: string, reason: exn})
106
152
 
107
153
  let make = (
108
154
  ~userEntities,
109
155
  // TODO: Should only pass userEnums and create internal config in runtime
110
156
  ~allEnums,
111
157
  ~storage,
112
- ~sql,
113
158
  ) => {
114
159
  let allEntities = userEntities->Js.Array2.concat([InternalTable.DynamicContractRegistry.config])
115
160
  let allEnums =
116
- allEnums->Js.Array2.concat([entityHistoryActionEnumConfig->Internal.fromGenericEnumConfig])
161
+ allEnums->Js.Array2.concat([EntityHistory.RowAction.config->Table.fromGenericEnumConfig])
117
162
  {
118
163
  userEntities,
119
164
  allEntities,
120
165
  allEnums,
121
166
  storageStatus: Unknown,
122
167
  storage,
123
- sql,
124
168
  }
125
169
  }
126
170
 
@@ -197,32 +241,140 @@ let getInitializedState = persistence => {
197
241
  }
198
242
  }
199
243
 
200
- let setEffectCacheOrThrow = async (
244
+ let writeBatch = (
201
245
  persistence,
202
- ~effect: Internal.effect,
203
- ~items,
204
- ~invalidationsCount,
205
- ) => {
246
+ ~batch,
247
+ ~config,
248
+ ~inMemoryStore: InMemoryStore.t,
249
+ ~isInReorgThreshold,
250
+ ) =>
206
251
  switch persistence.storageStatus {
207
252
  | Unknown
208
253
  | Initializing(_) =>
209
254
  Js.Exn.raiseError(`Failed to access the indexer storage. The Persistence layer is not initialized.`)
210
- | Ready({cache}) => {
211
- let storage = persistence.storage
212
- let effectName = effect.name
213
- let effectCacheRecord = switch cache->Utils.Dict.dangerouslyGetNonOption(effectName) {
214
- | Some(c) => c
215
- | None => {
216
- let c = {effectName, count: 0}
217
- cache->Js.Dict.set(effectName, c)
218
- c
219
- }
255
+ | Ready({cache}) =>
256
+ let updatedEntities = persistence.allEntities->Belt.Array.keepMapU(entityConfig => {
257
+ let updates =
258
+ inMemoryStore
259
+ ->InMemoryStore.getInMemTable(~entityConfig)
260
+ ->InMemoryTable.Entity.updates
261
+ if updates->Utils.Array.isEmpty {
262
+ None
263
+ } else {
264
+ Some({entityConfig, updates})
220
265
  }
221
- let initialize = effectCacheRecord.count === 0
222
- await storage.setEffectCacheOrThrow(~effect, ~items, ~initialize)
223
- effectCacheRecord.count =
224
- effectCacheRecord.count + items->Js.Array2.length - invalidationsCount
225
- Prometheus.EffectCacheCount.set(~count=effectCacheRecord.count, ~effectName)
226
- }
266
+ })
267
+ persistence.storage.writeBatch(
268
+ ~batch,
269
+ ~rawEvents=inMemoryStore.rawEvents->InMemoryTable.values,
270
+ ~rollbackTargetCheckpointId=inMemoryStore.rollbackTargetCheckpointId,
271
+ ~isInReorgThreshold,
272
+ ~config,
273
+ ~allEntities=persistence.allEntities,
274
+ ~updatedEntities,
275
+ ~updatedEffectsCache={
276
+ inMemoryStore.effects
277
+ ->Js.Dict.keys
278
+ ->Belt.Array.keepMapU(effectName => {
279
+ let inMemTable = inMemoryStore.effects->Js.Dict.unsafeGet(effectName)
280
+ let {idsToStore, dict, effect, invalidationsCount} = inMemTable
281
+ switch idsToStore {
282
+ | [] => None
283
+ | ids => {
284
+ let items = Belt.Array.makeUninitializedUnsafe(ids->Belt.Array.length)
285
+ ids->Belt.Array.forEachWithIndex((index, id) => {
286
+ items->Js.Array2.unsafe_set(
287
+ index,
288
+ (
289
+ {
290
+ id,
291
+ output: dict->Js.Dict.unsafeGet(id),
292
+ }: Internal.effectCacheItem
293
+ ),
294
+ )
295
+ })
296
+ Some({
297
+ let effectName = effect.name
298
+ let effectCacheRecord = switch cache->Utils.Dict.dangerouslyGetNonOption(
299
+ effectName,
300
+ ) {
301
+ | Some(c) => c
302
+ | None => {
303
+ let c = {effectName, count: 0}
304
+ cache->Js.Dict.set(effectName, c)
305
+ c
306
+ }
307
+ }
308
+ let shouldInitialize = effectCacheRecord.count === 0
309
+ effectCacheRecord.count =
310
+ effectCacheRecord.count + items->Js.Array2.length - invalidationsCount
311
+ Prometheus.EffectCacheCount.set(~count=effectCacheRecord.count, ~effectName)
312
+ {effect, items, shouldInitialize}
313
+ })
314
+ }
315
+ }
316
+ })
317
+ },
318
+ )
319
+ }
320
+
321
+ let prepareRollbackDiff = async (
322
+ persistence: t,
323
+ ~rollbackTargetCheckpointId,
324
+ ~rollbackDiffCheckpointId,
325
+ ) => {
326
+ let inMemStore = InMemoryStore.make(
327
+ ~entities=persistence.allEntities,
328
+ ~rollbackTargetCheckpointId,
329
+ )
330
+
331
+ let deletedEntities = Js.Dict.empty()
332
+ let setEntities = Js.Dict.empty()
333
+
334
+ let _ =
335
+ await persistence.allEntities
336
+ ->Belt.Array.map(async entityConfig => {
337
+ let entityTable = inMemStore->InMemoryStore.getInMemTable(~entityConfig)
338
+
339
+ let (removedIdsResult, restoredEntitiesResult) = await persistence.storage.getRollbackData(
340
+ ~entityConfig,
341
+ ~rollbackTargetCheckpointId,
342
+ )
343
+
344
+ // Process removed IDs
345
+ removedIdsResult->Js.Array2.forEach(data => {
346
+ deletedEntities->Utils.Dict.push(entityConfig.name, data["id"])
347
+ entityTable->InMemoryTable.Entity.set(
348
+ Delete({
349
+ entityId: data["id"],
350
+ checkpointId: rollbackDiffCheckpointId,
351
+ }),
352
+ ~shouldSaveHistory=false,
353
+ ~containsRollbackDiffChange=true,
354
+ )
355
+ })
356
+
357
+ let restoredEntities = restoredEntitiesResult->S.parseOrThrow(entityConfig.rowsSchema)
358
+
359
+ // Process restored entities
360
+ restoredEntities->Belt.Array.forEach((entity: Internal.entity) => {
361
+ setEntities->Utils.Dict.push(entityConfig.name, entity.id)
362
+ entityTable->InMemoryTable.Entity.set(
363
+ Set({
364
+ entityId: entity.id,
365
+ checkpointId: rollbackDiffCheckpointId,
366
+ entity,
367
+ }),
368
+ ~shouldSaveHistory=false,
369
+ ~containsRollbackDiffChange=true,
370
+ )
371
+ })
372
+ })
373
+ ->Promise.all
374
+
375
+ {
376
+ "inMemStore": inMemStore,
377
+ "deletedEntities": deletedEntities,
378
+ "setEntities": setEntities,
227
379
  }
228
380
  }
@@ -0,0 +1,213 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Utils from "./Utils.res.mjs";
4
+ import * as Js_exn from "rescript/lib/es6/js_exn.js";
5
+ import * as Logging from "./Logging.res.mjs";
6
+ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
7
+ import * as Prometheus from "./Prometheus.res.mjs";
8
+ import * as EntityHistory from "./db/EntityHistory.res.mjs";
9
+ import * as ErrorHandling from "./ErrorHandling.res.mjs";
10
+ import * as InMemoryStore from "./InMemoryStore.res.mjs";
11
+ import * as InMemoryTable from "./InMemoryTable.res.mjs";
12
+ import * as InternalTable from "./db/InternalTable.res.mjs";
13
+ import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js";
14
+ import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
15
+ import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
16
+
17
+ var StorageError = /* @__PURE__ */Caml_exceptions.create("Persistence.StorageError");
18
+
19
+ function make(userEntities, allEnums, storage) {
20
+ var allEntities = userEntities.concat([InternalTable.DynamicContractRegistry.config]);
21
+ var allEnums$1 = allEnums.concat([EntityHistory.RowAction.config]);
22
+ return {
23
+ userEntities: userEntities,
24
+ allEntities: allEntities,
25
+ allEnums: allEnums$1,
26
+ storageStatus: "Unknown",
27
+ storage: storage
28
+ };
29
+ }
30
+
31
+ async function init(persistence, chainConfigs, resetOpt) {
32
+ var reset = resetOpt !== undefined ? resetOpt : false;
33
+ try {
34
+ var promise = persistence.storageStatus;
35
+ var shouldRun;
36
+ if (typeof promise !== "object") {
37
+ shouldRun = true;
38
+ } else if (promise.TAG === "Initializing") {
39
+ await promise._0;
40
+ shouldRun = reset;
41
+ } else {
42
+ shouldRun = reset;
43
+ }
44
+ if (!shouldRun) {
45
+ return ;
46
+ }
47
+ var resolveRef = {
48
+ contents: null
49
+ };
50
+ var promise$1 = new Promise((function (resolve, param) {
51
+ resolveRef.contents = resolve;
52
+ }));
53
+ persistence.storageStatus = {
54
+ TAG: "Initializing",
55
+ _0: promise$1
56
+ };
57
+ if (reset || !await persistence.storage.isInitialized()) {
58
+ Logging.info("Initializing the indexer storage...");
59
+ var initialState = await persistence.storage.initialize(chainConfigs, persistence.allEntities, persistence.allEnums);
60
+ Logging.info("The indexer storage is ready. Starting indexing!");
61
+ persistence.storageStatus = {
62
+ TAG: "Ready",
63
+ _0: initialState
64
+ };
65
+ } else {
66
+ var match = persistence.storageStatus;
67
+ var tmp;
68
+ tmp = typeof match !== "object" || match.TAG !== "Initializing" ? false : true;
69
+ if (tmp) {
70
+ Logging.info("Found existing indexer storage. Resuming indexing state...");
71
+ var initialState$1 = await persistence.storage.resumeInitialState();
72
+ persistence.storageStatus = {
73
+ TAG: "Ready",
74
+ _0: initialState$1
75
+ };
76
+ var progress = {};
77
+ initialState$1.chains.forEach(function (c) {
78
+ progress[c.id] = c.progressBlockNumber;
79
+ });
80
+ Logging.info({
81
+ msg: "Successfully resumed indexing state! Continuing from the last checkpoint.",
82
+ progress: progress
83
+ });
84
+ }
85
+
86
+ }
87
+ return resolveRef.contents();
88
+ }
89
+ catch (raw_exn){
90
+ var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
91
+ return ErrorHandling.mkLogAndRaise(undefined, "EE800: Failed to initialize the indexer storage.", exn);
92
+ }
93
+ }
94
+
95
+ function getInitializedStorageOrThrow(persistence) {
96
+ var match = persistence.storageStatus;
97
+ if (typeof match !== "object" || match.TAG === "Initializing") {
98
+ return Js_exn.raiseError("Failed to access the indexer storage. The Persistence layer is not initialized.");
99
+ } else {
100
+ return persistence.storage;
101
+ }
102
+ }
103
+
104
+ function getInitializedState(persistence) {
105
+ var initialState = persistence.storageStatus;
106
+ if (typeof initialState !== "object" || initialState.TAG === "Initializing") {
107
+ return Js_exn.raiseError("Failed to access the initial state. The Persistence layer is not initialized.");
108
+ } else {
109
+ return initialState._0;
110
+ }
111
+ }
112
+
113
+ function writeBatch(persistence, batch, config, inMemoryStore, isInReorgThreshold) {
114
+ var match = persistence.storageStatus;
115
+ if (typeof match !== "object") {
116
+ return Js_exn.raiseError("Failed to access the indexer storage. The Persistence layer is not initialized.");
117
+ }
118
+ if (match.TAG === "Initializing") {
119
+ return Js_exn.raiseError("Failed to access the indexer storage. The Persistence layer is not initialized.");
120
+ }
121
+ var cache = match._0.cache;
122
+ var updatedEntities = Belt_Array.keepMapU(persistence.allEntities, (function (entityConfig) {
123
+ var updates = InMemoryTable.Entity.updates(InMemoryStore.getInMemTable(inMemoryStore, entityConfig));
124
+ if (Utils.$$Array.isEmpty(updates)) {
125
+ return ;
126
+ } else {
127
+ return {
128
+ entityConfig: entityConfig,
129
+ updates: updates
130
+ };
131
+ }
132
+ }));
133
+ return persistence.storage.writeBatch(batch, InMemoryTable.values(inMemoryStore.rawEvents), inMemoryStore.rollbackTargetCheckpointId, isInReorgThreshold, config, persistence.allEntities, Belt_Array.keepMapU(Object.keys(inMemoryStore.effects), (function (effectName) {
134
+ var inMemTable = inMemoryStore.effects[effectName];
135
+ var idsToStore = inMemTable.idsToStore;
136
+ var invalidationsCount = inMemTable.invalidationsCount;
137
+ var effect = inMemTable.effect;
138
+ var dict = inMemTable.dict;
139
+ if (idsToStore.length === 0) {
140
+ return ;
141
+ }
142
+ var items = new Array(idsToStore.length);
143
+ Belt_Array.forEachWithIndex(idsToStore, (function (index, id) {
144
+ items[index] = {
145
+ id: id,
146
+ output: dict[id]
147
+ };
148
+ }));
149
+ var effectName$1 = effect.name;
150
+ var c = cache[effectName$1];
151
+ var effectCacheRecord;
152
+ if (c !== undefined) {
153
+ effectCacheRecord = c;
154
+ } else {
155
+ var c$1 = {
156
+ effectName: effectName$1,
157
+ count: 0
158
+ };
159
+ cache[effectName$1] = c$1;
160
+ effectCacheRecord = c$1;
161
+ }
162
+ var shouldInitialize = effectCacheRecord.count === 0;
163
+ return effectCacheRecord.count = (effectCacheRecord.count + items.length | 0) - invalidationsCount | 0, Prometheus.EffectCacheCount.set(effectCacheRecord.count, effectName$1), {
164
+ effect: effect,
165
+ items: items,
166
+ shouldInitialize: shouldInitialize
167
+ };
168
+ })), updatedEntities);
169
+ }
170
+
171
+ async function prepareRollbackDiff(persistence, rollbackTargetCheckpointId, rollbackDiffCheckpointId) {
172
+ var inMemStore = InMemoryStore.make(persistence.allEntities, rollbackTargetCheckpointId);
173
+ var deletedEntities = {};
174
+ var setEntities = {};
175
+ await Promise.all(Belt_Array.map(persistence.allEntities, (async function (entityConfig) {
176
+ var entityTable = InMemoryStore.getInMemTable(inMemStore, entityConfig);
177
+ var match = await persistence.storage.getRollbackData(entityConfig, rollbackTargetCheckpointId);
178
+ match[0].forEach(function (data) {
179
+ Utils.Dict.push(deletedEntities, entityConfig.name, data.id);
180
+ InMemoryTable.Entity.set(entityTable, {
181
+ type: "DELETE",
182
+ entityId: data.id,
183
+ checkpointId: rollbackDiffCheckpointId
184
+ }, false, true);
185
+ });
186
+ var restoredEntities = S$RescriptSchema.parseOrThrow(match[1], entityConfig.rowsSchema);
187
+ return Belt_Array.forEach(restoredEntities, (function (entity) {
188
+ Utils.Dict.push(setEntities, entityConfig.name, entity.id);
189
+ InMemoryTable.Entity.set(entityTable, {
190
+ type: "SET",
191
+ entityId: entity.id,
192
+ entity: entity,
193
+ checkpointId: rollbackDiffCheckpointId
194
+ }, false, true);
195
+ }));
196
+ })));
197
+ return {
198
+ inMemStore: inMemStore,
199
+ deletedEntities: deletedEntities,
200
+ setEntities: setEntities
201
+ };
202
+ }
203
+
204
+ export {
205
+ StorageError ,
206
+ make ,
207
+ init ,
208
+ getInitializedStorageOrThrow ,
209
+ getInitializedState ,
210
+ writeBatch ,
211
+ prepareRollbackDiff ,
212
+ }
213
+ /* Utils Not a pure module */