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.
- package/bin.js +5 -3
- package/evm.schema.json +23 -6
- package/fuel.schema.json +17 -5
- package/index.d.ts +1 -27
- package/index.js +9 -6
- package/package.json +12 -7
- package/rescript.json +4 -3
- package/src/{Address.res.js → Address.res.mjs} +7 -6
- package/src/Batch.res +4 -4
- package/src/{Batch.res.js → Batch.res.mjs} +19 -18
- package/src/{ChainMap.res.js → ChainMap.res.mjs} +20 -19
- package/src/Change.res +9 -0
- package/src/Config.res +5 -5
- package/src/{Config.res.js → Config.res.mjs} +13 -10
- package/src/Envio.gen.ts +4 -17
- package/src/Envio.res +13 -38
- package/src/{Envio.res.js → Envio.res.mjs} +5 -16
- package/src/{ErrorHandling.res.js → ErrorHandling.res.mjs} +10 -9
- package/src/EventRegister.res +10 -11
- package/src/{EventRegister.res.js → EventRegister.res.mjs} +33 -26
- package/src/EventRegister.resi +2 -1
- package/src/{EventUtils.res.js → EventUtils.res.mjs} +10 -9
- package/src/{EvmTypes.res.js → EvmTypes.res.mjs} +5 -4
- package/src/{FetchState.res.js → FetchState.res.mjs} +44 -43
- package/src/{Hasura.res.js → Hasura.res.mjs} +25 -24
- package/src/InMemoryStore.res +7 -15
- package/src/{InMemoryStore.res.js → InMemoryStore.res.mjs} +21 -22
- package/src/InMemoryTable.res +50 -35
- package/src/{InMemoryTable.res.js → InMemoryTable.res.mjs} +73 -104
- package/src/Internal.gen.ts +1 -5
- package/src/Internal.res +29 -40
- package/src/Internal.res.mjs +58 -0
- package/src/{LazyLoader.res.js → LazyLoader.res.mjs} +14 -13
- package/src/{LoadManager.res.js → LoadManager.res.mjs} +11 -10
- package/src/{LogSelection.res.js → LogSelection.res.mjs} +14 -13
- package/src/{Logging.res.js → Logging.res.mjs} +37 -36
- package/src/Persistence.res +190 -38
- package/src/Persistence.res.mjs +213 -0
- package/src/PgStorage.res +700 -14
- package/src/{PgStorage.res.js → PgStorage.res.mjs} +478 -65
- package/src/Platform.res +140 -0
- package/src/Platform.res.mjs +170 -0
- package/src/Prometheus.res +41 -0
- package/src/{Prometheus.res.js → Prometheus.res.mjs} +106 -60
- package/src/{ReorgDetection.res.js → ReorgDetection.res.mjs} +12 -11
- package/src/SafeCheckpointTracking.res +5 -4
- package/src/{SafeCheckpointTracking.res.js → SafeCheckpointTracking.res.mjs} +6 -5
- package/src/Sink.res +47 -0
- package/src/Sink.res.mjs +37 -0
- package/src/{TableIndices.res.js → TableIndices.res.mjs} +8 -7
- package/src/{Throttler.res.js → Throttler.res.mjs} +7 -6
- package/src/{Time.res.js → Time.res.mjs} +8 -7
- package/src/{TopicFilter.res.js → TopicFilter.res.mjs} +18 -17
- package/src/Utils.res +42 -0
- package/src/{Utils.res.js → Utils.res.mjs} +71 -34
- package/src/bindings/BigDecimal.gen.ts +2 -2
- package/src/bindings/BigDecimal.res +5 -5
- package/src/bindings/BigDecimal.res.d.mts +5 -0
- package/src/bindings/{BigDecimal.res.js → BigDecimal.res.mjs} +10 -9
- package/src/bindings/BigInt.gen.ts +2 -2
- package/src/bindings/BigInt.res.d.mts +5 -0
- package/src/bindings/{BigInt.res.js → BigInt.res.mjs} +25 -24
- package/src/bindings/ClickHouse.res +387 -0
- package/src/bindings/ClickHouse.res.mjs +275 -0
- package/src/bindings/Ethers.gen.ts +2 -2
- package/src/bindings/Ethers.res.d.mts +5 -0
- package/src/bindings/{Ethers.res.js → Ethers.res.mjs} +18 -17
- package/src/bindings/Express.res.mjs +2 -0
- package/src/bindings/{Hrtime.res.js → Hrtime.res.mjs} +13 -12
- package/src/bindings/{Lodash.res.js → Lodash.res.mjs} +4 -3
- package/src/bindings/NodeJs.res +13 -1
- package/src/bindings/NodeJs.res.mjs +48 -0
- package/src/bindings/Pino.res +4 -4
- package/src/bindings/{Pino.res.js → Pino.res.mjs} +16 -15
- package/src/bindings/Postgres.res +17 -2
- package/src/bindings/{Postgres.res.js → Postgres.res.mjs} +4 -3
- package/src/bindings/{PromClient.res.js → PromClient.res.mjs} +6 -5
- package/src/bindings/{Promise.res.js → Promise.res.mjs} +6 -5
- package/src/bindings/{SDSL.res.js → SDSL.res.mjs} +3 -2
- package/src/bindings/{Viem.res.js → Viem.res.mjs} +9 -8
- package/src/bindings/vendored-lodash-fns.js +3 -35
- package/src/db/EntityHistory.res +33 -156
- package/src/db/EntityHistory.res.mjs +121 -0
- package/src/db/InternalTable.gen.ts +2 -2
- package/src/db/InternalTable.res +55 -56
- package/src/db/{InternalTable.res.js → InternalTable.res.mjs} +68 -71
- package/src/db/{Schema.res.js → Schema.res.mjs} +10 -9
- package/src/db/Table.res +86 -22
- package/src/db/{Table.res.js → Table.res.mjs} +108 -40
- package/src/sources/{EventRouter.res.js → EventRouter.res.mjs} +17 -16
- package/src/sources/{Fuel.res.js → Fuel.res.mjs} +6 -5
- package/src/sources/{HyperFuel.res.js → HyperFuel.res.mjs} +14 -13
- package/src/sources/{HyperFuelClient.res.js → HyperFuelClient.res.mjs} +7 -6
- package/src/sources/{HyperFuelSource.res.js → HyperFuelSource.res.mjs} +28 -27
- package/src/sources/{HyperSync.res.js → HyperSync.res.mjs} +21 -20
- package/src/sources/HyperSyncClient.gen.ts +1 -1
- package/src/sources/HyperSyncClient.res +78 -20
- package/src/sources/{HyperSyncClient.res.js → HyperSyncClient.res.mjs} +32 -15
- package/src/sources/{HyperSyncJsonApi.res.js → HyperSyncJsonApi.res.mjs} +10 -9
- package/src/sources/HyperSyncSource.res +77 -9
- package/src/sources/{HyperSyncSource.res.js → HyperSyncSource.res.mjs} +99 -38
- package/src/sources/{Rpc.res.js → Rpc.res.mjs} +16 -15
- package/src/sources/{RpcSource.res.js → RpcSource.res.mjs} +40 -39
- package/src/sources/Source.res +1 -1
- package/src/sources/{Source.res.js → Source.res.mjs} +4 -3
- package/src/sources/SourceManager.res +12 -1
- package/src/sources/{SourceManager.res.js → SourceManager.res.mjs} +32 -21
- package/src/sources/vendored-fuel-abi-coder.js +94 -149
- package/src/vendored/{Rest.res.js → Rest.res.mjs} +12 -11
- package/src/Internal.res.js +0 -62
- package/src/Persistence.res.js +0 -159
- package/src/bindings/NodeJs.res.js +0 -35
- package/src/db/EntityHistory.res.js +0 -195
- /package/src/{Indexer.res.js → Change.res.mjs} +0 -0
- /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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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 */
|
package/src/Persistence.res
CHANGED
|
@@ -29,13 +29,24 @@ type initialState = {
|
|
|
29
29
|
cleanRun: bool,
|
|
30
30
|
cache: dict<effectCacheRecord>,
|
|
31
31
|
chains: array<initialChainState>,
|
|
32
|
-
checkpointId:
|
|
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<
|
|
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<
|
|
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
|
-
|
|
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([
|
|
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
|
|
244
|
+
let writeBatch = (
|
|
201
245
|
persistence,
|
|
202
|
-
~
|
|
203
|
-
~
|
|
204
|
-
~
|
|
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
|
-
|
|
212
|
-
let
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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 */
|