envio 3.5.1 → 3.6.1-subgraph
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/evm.schema.json +7 -0
- package/fuel.schema.json +7 -0
- package/index.d.ts +33 -10
- package/package.json +6 -6
- package/src/ChainState.res +22 -4
- package/src/ChainState.res.mjs +20 -3
- package/src/ChainState.resi +3 -0
- package/src/Config.res +72 -2
- package/src/Config.res.mjs +57 -15
- package/src/Core.res +15 -0
- package/src/Core.res.mjs +11 -0
- package/src/EffectState.res +2 -2
- package/src/EffectState.res.mjs +2 -2
- package/src/EntityTables.res +32 -0
- package/src/EntityTables.res.mjs +44 -0
- package/src/Envio.res +7 -7
- package/src/Envio.res.mjs +5 -6
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +8 -6
- package/src/HandlerLoader.res +20 -8
- package/src/HandlerLoader.res.mjs +11 -2
- package/src/Hasura.res +37 -3
- package/src/Hasura.res.mjs +23 -5
- package/src/InMemoryStore.res +48 -8
- package/src/InMemoryStore.res.mjs +37 -7
- package/src/IndexerState.res +30 -24
- package/src/IndexerState.res.mjs +20 -35
- package/src/IndexerState.resi +8 -6
- package/src/Internal.res +29 -11
- package/src/Internal.res.mjs +27 -10
- package/src/LoadLayer.res +39 -8
- package/src/LoadLayer.res.mjs +36 -9
- package/src/LoadLayer.resi +2 -0
- package/src/Metrics.res +5 -5
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +12 -1
- package/src/PgStorage.res +183 -37
- package/src/PgStorage.res.mjs +149 -34
- package/src/PruneStaleHistory.res +1 -0
- package/src/PruneStaleHistory.res.mjs +2 -1
- package/src/Sink.res +3 -3
- package/src/Sink.res.mjs +2 -2
- package/src/TestIndexer.res +128 -17
- package/src/TestIndexer.res.mjs +75 -9
- package/src/UserContext.res +375 -53
- package/src/UserContext.res.mjs +281 -39
- package/src/Writing.res +8 -16
- package/src/Writing.res.mjs +10 -10
- package/src/bindings/ClickHouse.res +40 -4
- package/src/bindings/ClickHouse.res.mjs +37 -5
- package/src/db/EntityHistory.res +64 -21
- package/src/db/EntityHistory.res.mjs +43 -22
- package/src/db/InternalTable.res.mjs +31 -31
- package/src/db/Table.res +24 -1
- package/src/db/Table.res.mjs +26 -4
- package/src/sources/SourceManager.res +6 -12
- package/src/sources/SourceManager.res.mjs +8 -5
- package/src/subgraph/blocks.ts +176 -0
- package/src/subgraph/calls.ts +213 -0
- package/src/subgraph/conformance.ts +99 -0
- package/src/subgraph/division.ts +100 -0
- package/src/subgraph/errors.ts +90 -0
- package/src/subgraph/graph-ts-types/VERSION +2 -0
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
- package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
- package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
- package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
- package/src/subgraph/graph-ts-types/index.d.ts +102 -0
- package/src/subgraph/graph-ts.ts +1695 -0
- package/src/subgraph/hosts.ts +148 -0
- package/src/subgraph/runtime.ts +827 -0
- package/src/subgraph/scope.ts +63 -0
- package/svm.schema.json +7 -0
package/src/Internal.res.mjs
CHANGED
|
@@ -166,21 +166,36 @@ let fuelTransferParamsSchema = S$RescriptSchema.schema(s => ({
|
|
|
166
166
|
amount: s.m(Utils.$$BigInt.schema)
|
|
167
167
|
}));
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
function chainScopeToString(scope) {
|
|
170
|
+
if (scope === "crossChain") {
|
|
171
|
+
return "crossChain";
|
|
172
|
+
} else {
|
|
173
|
+
return ChainId.toString(scope);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
170
176
|
|
|
171
|
-
function
|
|
177
|
+
function chainScopeChainId(scope) {
|
|
172
178
|
if (scope === "crossChain") {
|
|
173
|
-
return
|
|
179
|
+
return;
|
|
174
180
|
} else {
|
|
175
|
-
return
|
|
181
|
+
return Primitive_option.some(scope);
|
|
176
182
|
}
|
|
177
183
|
}
|
|
178
184
|
|
|
179
|
-
function
|
|
185
|
+
function stampChainId(entity, fieldName, chainId) {
|
|
186
|
+
return Utils.Dict.merge(entity, Object.fromEntries([[
|
|
187
|
+
fieldName,
|
|
188
|
+
chainId
|
|
189
|
+
]]));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let cacheTablePrefix = "envio_effect_";
|
|
193
|
+
|
|
194
|
+
function toTableName(effectName, scope) {
|
|
180
195
|
if (scope === "crossChain") {
|
|
181
|
-
return
|
|
196
|
+
return cacheTablePrefix + effectName;
|
|
182
197
|
} else {
|
|
183
|
-
return ChainId.toString(scope);
|
|
198
|
+
return `envio_` + ChainId.toString(scope) + `_effect_` + effectName;
|
|
184
199
|
}
|
|
185
200
|
}
|
|
186
201
|
|
|
@@ -260,7 +275,6 @@ function toCachePath(effectName, scope) {
|
|
|
260
275
|
|
|
261
276
|
let EffectCache = {
|
|
262
277
|
toTableName: toTableName,
|
|
263
|
-
scopeToString: scopeToString,
|
|
264
278
|
parseChainId: parseChainId,
|
|
265
279
|
chainScopedRe: chainScopedRe,
|
|
266
280
|
crossChainRe: crossChainRe,
|
|
@@ -272,8 +286,8 @@ let cacheOutputSchema = S$RescriptSchema.json(false);
|
|
|
272
286
|
|
|
273
287
|
function makeCacheTable(effectName, scope) {
|
|
274
288
|
return Table.mkTable(toTableName(effectName, scope), undefined, [
|
|
275
|
-
Table.mkField("id", "String", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined),
|
|
276
|
-
Table.mkField("output", "Json", cacheOutputSchema, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
289
|
+
Table.mkField("id", "String", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
290
|
+
Table.mkField("output", "Json", cacheOutputSchema, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
277
291
|
], undefined);
|
|
278
292
|
}
|
|
279
293
|
|
|
@@ -296,6 +310,9 @@ export {
|
|
|
296
310
|
getItemChainId,
|
|
297
311
|
fuelSupplyParamsSchema,
|
|
298
312
|
fuelTransferParamsSchema,
|
|
313
|
+
chainScopeToString,
|
|
314
|
+
chainScopeChainId,
|
|
315
|
+
stampChainId,
|
|
299
316
|
cacheTablePrefix,
|
|
300
317
|
EffectCache,
|
|
301
318
|
cacheOutputSchema,
|
package/src/LoadLayer.res
CHANGED
|
@@ -1,15 +1,41 @@
|
|
|
1
|
+
// A per-chain entity's rows must never dedup or merge across chains, so both
|
|
2
|
+
// the load-group key and the storage query carry the scope.
|
|
3
|
+
let scopeKeySuffix = (scope: Internal.chainScope) =>
|
|
4
|
+
switch scope {
|
|
5
|
+
| CrossChain => ""
|
|
6
|
+
| Chain(chainId) => `.${chainId->ChainId.toString}`
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Narrows a query to the scope's chain. Cross-chain entities have no chain-id
|
|
10
|
+
// column, so their filter is left untouched.
|
|
11
|
+
let scopeFilter = (filter: EntityFilter.t, ~table: Table.table, ~scope: Internal.chainScope) =>
|
|
12
|
+
switch (scope, table->Table.getChainIdField) {
|
|
13
|
+
| (Chain(chainId), Some(field)) =>
|
|
14
|
+
EntityFilter.And({
|
|
15
|
+
filters: [
|
|
16
|
+
filter,
|
|
17
|
+
Eq({
|
|
18
|
+
fieldName: field.fieldName,
|
|
19
|
+
fieldValue: chainId->(Utils.magic: ChainId.t => unknown),
|
|
20
|
+
}),
|
|
21
|
+
],
|
|
22
|
+
})
|
|
23
|
+
| _ => filter
|
|
24
|
+
}
|
|
25
|
+
|
|
1
26
|
let loadById = (
|
|
2
27
|
~loadManager,
|
|
3
28
|
~persistence: Persistence.t,
|
|
4
29
|
~entityConfig: Internal.entityConfig,
|
|
30
|
+
~scope: Internal.chainScope,
|
|
5
31
|
~indexerState,
|
|
6
32
|
~shouldGroup,
|
|
7
33
|
~item,
|
|
8
34
|
~ecosystem,
|
|
9
35
|
~entityId,
|
|
10
36
|
) => {
|
|
11
|
-
let key = `${entityConfig.name}.get`
|
|
12
|
-
let inMemTable = indexerState->InMemoryStore.getInMemTable(~entityConfig)
|
|
37
|
+
let key = `${entityConfig.name}.get${scope->scopeKeySuffix}`
|
|
38
|
+
let inMemTable = indexerState->InMemoryStore.getInMemTable(~entityConfig, ~scope)
|
|
13
39
|
|
|
14
40
|
let load = async (idsToLoad, ~onError as _) => {
|
|
15
41
|
let storage = persistence->Persistence.getInitializedStorageOrThrow
|
|
@@ -25,7 +51,7 @@ let loadById = (
|
|
|
25
51
|
~filter=EntityFilter.In({
|
|
26
52
|
fieldName: Table.idFieldName,
|
|
27
53
|
fieldValue: idsToLoad->(Utils.magic: array<string> => array<unknown>),
|
|
28
|
-
}),
|
|
54
|
+
})->scopeFilter(~table=entityConfig.table, ~scope),
|
|
29
55
|
)
|
|
30
56
|
)->(Utils.magic: array<unknown> => array<Internal.entity>)
|
|
31
57
|
} catch {
|
|
@@ -327,14 +353,16 @@ let loadByFilter = (
|
|
|
327
353
|
~loadManager,
|
|
328
354
|
~persistence: Persistence.t,
|
|
329
355
|
~entityConfig: Internal.entityConfig,
|
|
356
|
+
~scope: Internal.chainScope,
|
|
330
357
|
~indexerState,
|
|
331
358
|
~shouldGroup,
|
|
332
359
|
~item,
|
|
333
360
|
~ecosystem,
|
|
334
361
|
~filter: EntityFilter.t,
|
|
335
362
|
) => {
|
|
336
|
-
let key =
|
|
337
|
-
|
|
363
|
+
let key =
|
|
364
|
+
filter->EntityFilter.toOperationKey(~entityName=entityConfig.name) ++ scope->scopeKeySuffix
|
|
365
|
+
let inMemTable = indexerState->InMemoryStore.getInMemTable(~entityConfig, ~scope)
|
|
338
366
|
|
|
339
367
|
let load = async (filters: array<EntityFilter.t>, ~onError as _) => {
|
|
340
368
|
let storage = persistence->Persistence.getInitializedStorageOrThrow
|
|
@@ -362,9 +390,12 @@ let loadByFilter = (
|
|
|
362
390
|
->Array.map(async filter => {
|
|
363
391
|
try {
|
|
364
392
|
let entities =
|
|
365
|
-
(
|
|
366
|
-
|
|
367
|
-
|
|
393
|
+
(
|
|
394
|
+
await storage.loadOrThrow(
|
|
395
|
+
~table=entityConfig.table,
|
|
396
|
+
~filter=filter->scopeFilter(~table=entityConfig.table, ~scope),
|
|
397
|
+
)
|
|
398
|
+
)->(Utils.magic: array<unknown> => array<Internal.entity>)
|
|
368
399
|
|
|
369
400
|
entities->Array.forEach(entity => {
|
|
370
401
|
inMemTable->InMemoryTable.Entity.initValue(
|
package/src/LoadLayer.res.mjs
CHANGED
|
@@ -18,19 +18,46 @@ import * as InMemoryTable from "./InMemoryTable.res.mjs";
|
|
|
18
18
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
19
19
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
20
20
|
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
function scopeKeySuffix(scope) {
|
|
22
|
+
if (scope === "crossChain") {
|
|
23
|
+
return "";
|
|
24
|
+
} else {
|
|
25
|
+
return `.` + ChainId.toString(scope);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function scopeFilter(filter, table, scope) {
|
|
30
|
+
let match = Table.getChainIdField(table);
|
|
31
|
+
if (scope === "crossChain" || match === undefined) {
|
|
32
|
+
return filter;
|
|
33
|
+
} else {
|
|
34
|
+
return {
|
|
35
|
+
operator: "and",
|
|
36
|
+
filters: [
|
|
37
|
+
filter,
|
|
38
|
+
{
|
|
39
|
+
operator: "=",
|
|
40
|
+
fieldName: match.fieldName,
|
|
41
|
+
fieldValue: scope
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function loadById(loadManager, persistence, entityConfig, scope, indexerState, shouldGroup, item, ecosystem, entityId) {
|
|
49
|
+
let key = entityConfig.name + `.get` + scopeKeySuffix(scope);
|
|
50
|
+
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
24
51
|
let load = async (idsToLoad, param) => {
|
|
25
52
|
let storage = Persistence.getInitializedStorageOrThrow(persistence);
|
|
26
53
|
let timerRef = IndexerState.startStorageLoad(indexerState, storage.name, key);
|
|
27
54
|
let dbEntities;
|
|
28
55
|
try {
|
|
29
|
-
dbEntities = await storage.loadOrThrow({
|
|
56
|
+
dbEntities = await storage.loadOrThrow(scopeFilter({
|
|
30
57
|
operator: "in",
|
|
31
58
|
fieldName: Table.idFieldName,
|
|
32
59
|
fieldValue: idsToLoad
|
|
33
|
-
}, entityConfig.table);
|
|
60
|
+
}, entityConfig.table, scope), entityConfig.table);
|
|
34
61
|
} catch (raw_exn) {
|
|
35
62
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
36
63
|
if (exn.RE_EXN_ID === Persistence.StorageError) {
|
|
@@ -181,9 +208,9 @@ function loadEffect(loadManager, persistence, effect, effectArgs, scope, indexer
|
|
|
181
208
|
return LoadManager.call(loadManager, effectArgs, key, load, args => args.cacheKey, shouldGroup, hash => InMemoryStore.hasEffectOutput(inMemTable, hash), hash => InMemoryStore.getEffectOutputUnsafe(inMemTable, hash));
|
|
182
209
|
}
|
|
183
210
|
|
|
184
|
-
function loadByFilter(loadManager, persistence, entityConfig, indexerState, shouldGroup, item, ecosystem, filter) {
|
|
185
|
-
let key = EntityFilter.toOperationKey(filter, entityConfig.name);
|
|
186
|
-
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig);
|
|
211
|
+
function loadByFilter(loadManager, persistence, entityConfig, scope, indexerState, shouldGroup, item, ecosystem, filter) {
|
|
212
|
+
let key = EntityFilter.toOperationKey(filter, entityConfig.name) + scopeKeySuffix(scope);
|
|
213
|
+
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
187
214
|
let load = async (filters, param) => {
|
|
188
215
|
let storage = Persistence.getInitializedStorageOrThrow(persistence);
|
|
189
216
|
let timerRef = IndexerState.startStorageLoad(indexerState, storage.name, key);
|
|
@@ -195,7 +222,7 @@ function loadByFilter(loadManager, persistence, entityConfig, indexerState, shou
|
|
|
195
222
|
let queries = EntityFilter.merge(filters);
|
|
196
223
|
await Promise.all(queries.map(async filter => {
|
|
197
224
|
try {
|
|
198
|
-
let entities = await storage.loadOrThrow(filter, entityConfig.table);
|
|
225
|
+
let entities = await storage.loadOrThrow(scopeFilter(filter, entityConfig.table, scope), entityConfig.table);
|
|
199
226
|
entities.forEach(entity => InMemoryTable.Entity.initValue(inMemTable, IndexerState.committedCheckpointId(indexerState), entity.id, entity));
|
|
200
227
|
size.contents = size.contents + entities.length | 0;
|
|
201
228
|
return;
|
package/src/LoadLayer.resi
CHANGED
|
@@ -2,6 +2,7 @@ let loadById: (
|
|
|
2
2
|
~loadManager: LoadManager.t,
|
|
3
3
|
~persistence: Persistence.t,
|
|
4
4
|
~entityConfig: Internal.entityConfig,
|
|
5
|
+
~scope: Internal.chainScope,
|
|
5
6
|
~indexerState: IndexerState.t,
|
|
6
7
|
~shouldGroup: bool,
|
|
7
8
|
~item: Internal.item,
|
|
@@ -13,6 +14,7 @@ let loadByFilter: (
|
|
|
13
14
|
~loadManager: LoadManager.t,
|
|
14
15
|
~persistence: Persistence.t,
|
|
15
16
|
~entityConfig: Internal.entityConfig,
|
|
17
|
+
~scope: Internal.chainScope,
|
|
16
18
|
~indexerState: IndexerState.t,
|
|
17
19
|
~shouldGroup: bool,
|
|
18
20
|
~item: Internal.item,
|
package/src/Metrics.res
CHANGED
|
@@ -445,15 +445,15 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
445
445
|
~entries=chains,
|
|
446
446
|
~value=m => m.endBlock->Option.map(Int.toFloat),
|
|
447
447
|
)
|
|
448
|
-
b->
|
|
448
|
+
b->seriesOpt(
|
|
449
449
|
~name="envio_source_request_total",
|
|
450
|
-
~help="The number of requests made to data sources.",
|
|
450
|
+
~help="The number of requests made to data sources. Heights pushed by a subscription stream are counted here too, under the heightPush and heightPushIgnored methods.",
|
|
451
451
|
~kind="counter",
|
|
452
452
|
~entries=sourceRequests,
|
|
453
|
-
~value=s => s.count->Int.toFloat,
|
|
453
|
+
~value=s => s.count > 0 ? Some(s.count->Int.toFloat) : None,
|
|
454
454
|
)
|
|
455
|
-
// Skips a method's seconds line when it has no timing (e.g.
|
|
456
|
-
//
|
|
455
|
+
// Skips a method's seconds line when it has no timing (e.g. heightPush, which
|
|
456
|
+
// only ever records a count).
|
|
457
457
|
b->seriesOpt(
|
|
458
458
|
~name="envio_source_request_seconds_total",
|
|
459
459
|
~help="Cumulative time spent on data source requests.",
|
package/src/Metrics.res.mjs
CHANGED
|
@@ -144,7 +144,11 @@ function renderMetrics(b, metrics) {
|
|
|
144
144
|
single(b, "envio_indexing_target_buffer_size", "The indexer-wide target buffer size shared across all chains. The actual number of items in the queue may exceed this value, but the indexer always tries to keep the buffer filled up to this target.", "gauge", metrics.targetBufferSize);
|
|
145
145
|
series(b, "envio_indexing_buffer_block", "The highest block number that has been fully fetched by the indexer.", "gauge", chains, m => m.bufferBlockNumber);
|
|
146
146
|
seriesOpt(b, "envio_indexing_end_block", "The block number to stop indexing at. (inclusive)", "gauge", chains, m => Stdlib_Option.map(m.endBlock, prim => prim));
|
|
147
|
-
|
|
147
|
+
seriesOpt(b, "envio_source_request_total", "The number of requests made to data sources. Heights pushed by a subscription stream are counted here too, under the heightPush and heightPushIgnored methods.", "counter", sourceRequests, s => {
|
|
148
|
+
if (s.count > 0) {
|
|
149
|
+
return s.count;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
148
152
|
seriesOpt(b, "envio_source_request_seconds_total", "Cumulative time spent on data source requests.", "counter", sourceRequests, s => {
|
|
149
153
|
if (s.seconds !== 0) {
|
|
150
154
|
return s.seconds;
|
package/src/Persistence.res
CHANGED
|
@@ -63,11 +63,21 @@ type rollback = {
|
|
|
63
63
|
progressBlockNumberByChainId: dict<int>,
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
// One flush group: the changes an entity accumulated within a single chain
|
|
67
|
+
// scope. A per-chain entity contributes one group per chain, and the scope is
|
|
68
|
+
// what stamps the chain id onto the rows — it's never re-derived downstream.
|
|
66
69
|
type updatedEntity = {
|
|
67
70
|
entityConfig: Internal.entityConfig,
|
|
71
|
+
scope: Internal.chainScope,
|
|
68
72
|
changes: array<Change.t<Internal.entity>>,
|
|
69
73
|
}
|
|
70
74
|
|
|
75
|
+
// An id the rollback must delete, together with the scope its row lives in.
|
|
76
|
+
type rollbackRemoval = {
|
|
77
|
+
entityId: EntityId.t,
|
|
78
|
+
scope: Internal.chainScope,
|
|
79
|
+
}
|
|
80
|
+
|
|
71
81
|
type storage = {
|
|
72
82
|
// Identifier used as the `storage` label on Prometheus metrics.
|
|
73
83
|
name: string,
|
|
@@ -119,6 +129,7 @@ type storage = {
|
|
|
119
129
|
pruneStaleEntityHistory: (
|
|
120
130
|
~entityName: string,
|
|
121
131
|
~entityIndex: int,
|
|
132
|
+
~chainIdColumn: option<string>,
|
|
122
133
|
~safeCheckpointId: Internal.checkpointId,
|
|
123
134
|
) => promise<unit>,
|
|
124
135
|
// Get rollback target checkpoint
|
|
@@ -140,7 +151,7 @@ type storage = {
|
|
|
140
151
|
getRollbackData: (
|
|
141
152
|
~entityConfig: Internal.entityConfig,
|
|
142
153
|
~rollbackTargetCheckpointId: Internal.checkpointId,
|
|
143
|
-
) => promise<(array<
|
|
154
|
+
) => promise<(array<rollbackRemoval>, array<unknown>)>,
|
|
144
155
|
// Write batch to storage
|
|
145
156
|
writeBatch: (
|
|
146
157
|
~batch: Batch.t,
|