envio 3.15.0 → 3.16.0-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/README.md +40 -34
- package/evm.schema.json +11 -2
- package/fuel.schema.json +10 -1
- package/index.d.ts +6 -0
- package/licenses/README.md +1 -1
- package/package.json +10 -9
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/Bin.res +7 -0
- package/src/Bin.res.mjs +8 -0
- package/src/ChainFetching.res +450 -16
- package/src/ChainFetching.res.mjs +403 -32
- package/src/ChainState.res +124 -7
- package/src/ChainState.res.mjs +128 -67
- package/src/ChainState.resi +26 -0
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +31 -3
- package/src/Config.res.mjs +15 -4
- package/src/ContractRegisterContext.res +3 -6
- package/src/ContractRegisterContext.res.mjs +4 -2
- package/src/Core.res +95 -36
- package/src/Core.res.mjs +90 -1
- package/src/CrossChainState.res +12 -2
- package/src/CrossChainState.res.mjs +3 -3
- package/src/Ecosystem.res +7 -4
- package/src/Ecosystem.res.mjs +8 -8
- package/src/EffectCacheLookup.res +98 -0
- package/src/EffectCacheLookup.res.mjs +116 -0
- package/src/EffectState.res +10 -2
- package/src/EffectState.res.mjs +8 -4
- package/src/EffectState.resi +3 -1
- package/src/EntityId.res +2 -7
- package/src/EntityId.res.mjs +1 -8
- package/src/EntityTables.res +4 -1
- package/src/EntityTables.res.mjs +1 -1
- package/src/Env.res +20 -0
- package/src/Env.res.mjs +16 -0
- package/src/EventProcessing.res +38 -1
- package/src/EventProcessing.res.mjs +28 -1
- package/src/FetchState.res +408 -73
- package/src/FetchState.res.mjs +361 -91
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/HandlerLoader.res +39 -15
- package/src/HandlerLoader.res.mjs +27 -8
- package/src/HandlerRegister.res +4 -0
- package/src/HandlerRegister.res.mjs +5 -2
- package/src/HandlerRegister.resi +2 -0
- package/src/InMemoryTable.res +17 -16
- package/src/InMemoryTable.res.mjs +14 -15
- package/src/IndexerState.res +28 -4
- package/src/IndexerState.res.mjs +19 -6
- package/src/IndexerState.resi +4 -0
- package/src/Internal.res +61 -49
- package/src/Internal.res.mjs +36 -80
- package/src/LoadLayer.res +54 -15
- package/src/LoadLayer.res.mjs +75 -45
- package/src/LoadLayer.resi +26 -0
- package/src/Main.res +14 -1
- package/src/Main.res.mjs +4 -3
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/PreloadLookahead.res +202 -0
- package/src/PreloadLookahead.res.mjs +218 -0
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/RunScope.res +3 -0
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/SimulateItems.res +42 -26
- package/src/SimulateItems.res.mjs +40 -16
- package/src/StagedRows.res +106 -0
- package/src/StagedRows.res.mjs +102 -0
- package/src/Staging.res +32 -14
- package/src/Staging.res.mjs +17 -20
- package/src/Storage.res +303 -948
- package/src/Storage.res.mjs +229 -708
- package/src/SubgraphLog.res +19 -0
- package/src/SubgraphLog.res.mjs +26 -0
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/SyncWrites.res +107 -0
- package/src/SyncWrites.res.mjs +98 -0
- package/src/TestIndexer.res +22 -27
- package/src/TestIndexer.res.mjs +20 -17
- package/src/Throttler.res +15 -8
- package/src/Throttler.res.mjs +9 -6
- package/src/Throttler.resi +1 -1
- package/src/UserContext.res +419 -46
- package/src/UserContext.res.mjs +318 -30
- package/src/Utils.res +17 -6
- package/src/Utils.res.mjs +12 -6
- package/src/Writing.res +0 -1
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +0 -322
- package/src/bindings/ClickHouse.res.mjs +0 -338
- package/src/bindings/StorageClient.res +108 -174
- package/src/bindings/StorageClient.res.mjs +19 -8
- package/src/bindings/Vitest.res +0 -26
- package/src/bindings/Vitest.res.mjs +0 -3
- package/src/db/Table.res +24 -150
- package/src/db/Table.res.mjs +38 -272
- package/src/sources/AddressSet.res +2 -0
- package/src/sources/AddressStore.res +3 -0
- package/src/sources/CallSource.res +274 -0
- package/src/sources/CallSource.res.mjs +196 -0
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +10 -1
- package/src/sources/EvmChain.res.mjs +6 -3
- package/src/sources/EvmHyperSyncSource.res +2 -2
- package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
- package/src/sources/EvmRpcClient.res +13 -3
- package/src/sources/EvmRpcClient.res.mjs +4 -3
- package/src/sources/EvmRpcWs.res +4 -3
- package/src/sources/EvmRpcWs.res.mjs +2 -2
- package/src/sources/HeightFeed.res +31 -10
- package/src/sources/HeightFeed.res.mjs +10 -6
- package/src/sources/HeightStream.res +32 -17
- package/src/sources/HeightStream.res.mjs +10 -10
- package/src/sources/HyperSync.res +2 -1
- package/src/sources/HyperSync.res.mjs +2 -1
- package/src/sources/HyperSyncSSE.res +4 -6
- package/src/sources/HyperSyncSSE.res.mjs +2 -2
- package/src/sources/RpcSource.res +10 -1
- package/src/sources/RpcSource.res.mjs +4 -3
- package/src/sources/Source.res +3 -0
- package/src/sources/SourceManager.res +84 -77
- package/src/sources/SourceManager.res.mjs +17 -20
- package/src/sources/SourceManager.resi +3 -4
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/subgraph/abi-types.ts +84 -0
- package/src/subgraph/aggregations.ts +745 -0
- package/src/subgraph/as-package.ts +143 -0
- package/src/subgraph/assemblyscript-regex.ts +67 -0
- package/src/subgraph/assemblyscript.ts +731 -0
- package/src/subgraph/blocks.ts +398 -0
- package/src/subgraph/calls-source.ts +702 -0
- package/src/subgraph/calls.ts +258 -0
- package/src/subgraph/conformance.ts +106 -0
- package/src/subgraph/errors.ts +85 -0
- package/src/subgraph/graft.ts +73 -0
- package/src/subgraph/graph-cli-worker.mjs +35 -0
- package/src/subgraph/graph-cli.ts +900 -0
- package/src/subgraph/graph-node-decimal.ts +199 -0
- package/src/subgraph/graph-ts-enums.ts +28 -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 +4339 -0
- package/src/subgraph/hosts.ts +554 -0
- package/src/subgraph/log.ts +28 -0
- package/src/subgraph/receipts.ts +184 -0
- package/src/subgraph/register-slots.ts +93 -0
- package/src/subgraph/rollup.ts +109 -0
- package/src/subgraph/rpc.ts +337 -0
- package/src/subgraph/runtime.ts +2059 -0
- package/src/subgraph/scope.ts +176 -0
- package/src/subgraph/stats.ts +42 -0
- package/src/subgraph/template-instances.ts +66 -0
- package/src/subgraph/toolchain.ts +327 -0
- package/src/subgraph/transient.ts +176 -0
- package/svm.schema.json +11 -2
- package/src/PgWriting.res +0 -36
- package/src/PgWriting.res.mjs +0 -34
- package/src/db/IndexDefinition.res +0 -47
- package/src/db/IndexDefinition.res.mjs +0 -67
package/src/Internal.res
CHANGED
|
@@ -724,6 +724,12 @@ type onBlockArgs = {
|
|
|
724
724
|
context: handlerContext,
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
+
type onBlockContractRegisterArgs = {
|
|
728
|
+
slot?: int,
|
|
729
|
+
block?: eventBlock,
|
|
730
|
+
context: contractRegisterContext,
|
|
731
|
+
}
|
|
732
|
+
|
|
727
733
|
type onBlockRegistration = {
|
|
728
734
|
// When there are multiple onBlock handlers per chain,
|
|
729
735
|
// we want to use the order they are defined for sorting
|
|
@@ -738,6 +744,14 @@ type onBlockRegistration = {
|
|
|
738
744
|
// `None` when the handler reads only the block's key, which needs nothing
|
|
739
745
|
// from a source: its items are generated locally, block by block.
|
|
740
746
|
blockFieldMask: option<float>,
|
|
747
|
+
// Subgraph mode only: a `once` block handler, whose trigger graph-node runs
|
|
748
|
+
// ahead of everything else in its block (`EthereumBlockTriggerType::Start`).
|
|
749
|
+
runsFirst?: bool,
|
|
750
|
+
// Subgraph mode only: the register pass of a block handler that can create a
|
|
751
|
+
// data source. It runs for each of the handler's blocks at fetch time, and no
|
|
752
|
+
// block item is processed until every pass up to its block has run and what
|
|
753
|
+
// they registered is fetched, as an event's contractRegister.
|
|
754
|
+
contractRegister?: onBlockContractRegisterArgs => promise<unit>,
|
|
741
755
|
}
|
|
742
756
|
|
|
743
757
|
@tag("kind")
|
|
@@ -785,6 +799,53 @@ external getItemOrderPath: item => Nullable.t<array<int>> = "orderPath"
|
|
|
785
799
|
// block ahead of that block's handlers without a `switch`.
|
|
786
800
|
@get
|
|
787
801
|
external getItemKind: item => int = "kind"
|
|
802
|
+
// Set only in subgraph mode, on an event of an address registered in the very
|
|
803
|
+
// block it was logged in: graph-node runs a new data source's creation-block
|
|
804
|
+
// events after everything else in that block. The value is the round, as
|
|
805
|
+
// graph-node counts them: 1 for a data source a block's own triggers created,
|
|
806
|
+
// 2 for one that round-1 handlers created, and so on.
|
|
807
|
+
@get
|
|
808
|
+
external getItemCreationRound: item => option<int> = "runsAfterBlock"
|
|
809
|
+
@set
|
|
810
|
+
external markItemCreationRound: (item, int) => unit = "runsAfterBlock"
|
|
811
|
+
|
|
812
|
+
let itemRunsFirst = (item: item) =>
|
|
813
|
+
switch item {
|
|
814
|
+
| Block({onBlockRegistration: {runsFirst: true}}) => true
|
|
815
|
+
| _ => false
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// Subgraph mode only. A call trigger travels through fetch and batching as an
|
|
819
|
+
// event item (see `subgraph/calls-source.ts`), and graph-node orders it by its
|
|
820
|
+
// transaction among the logs, so its item carries a rank: 1 for a call
|
|
821
|
+
// handler's, 2 for the `filter: call` block handler's. Absent on every log.
|
|
822
|
+
@get
|
|
823
|
+
external getItemCallRank: item => option<int> = "callRank"
|
|
824
|
+
@set
|
|
825
|
+
external setItemCallRank: (item, int) => unit = "callRank"
|
|
826
|
+
@get
|
|
827
|
+
external getItemTransactionIndex: item => int = "transactionIndex"
|
|
828
|
+
|
|
829
|
+
// Flips on when the first call item is built, so a run without call triggers
|
|
830
|
+
// compares items exactly as before.
|
|
831
|
+
let callOrderingActive = ref(false)
|
|
832
|
+
|
|
833
|
+
// The call trigger an event of this name is, if it is one: the subgraph
|
|
834
|
+
// translator names them `__envio_call_<selector>_<function>`, and the block
|
|
835
|
+
// handler's `__envio_call_any`. No log carries either name.
|
|
836
|
+
let callRankOfEventName = (name: string): option<int> =>
|
|
837
|
+
if name->String.startsWith("__envio_call_any") {
|
|
838
|
+
Some(2)
|
|
839
|
+
} else if name->String.startsWith("__envio_call_") {
|
|
840
|
+
Some(1)
|
|
841
|
+
} else {
|
|
842
|
+
None
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
let markItemCall = (item, ~rank) => {
|
|
846
|
+
item->setItemCallRank(rank)
|
|
847
|
+
callOrderingActive := true
|
|
848
|
+
}
|
|
788
849
|
|
|
789
850
|
let getItemChainId = item =>
|
|
790
851
|
switch item {
|
|
@@ -950,55 +1011,6 @@ module EffectCache = {
|
|
|
950
1011
|
| CrossChain => cacheTablePrefix ++ effectName
|
|
951
1012
|
| Chain(chainId) => `envio_${chainId->ChainId.toString}_effect_${effectName}`
|
|
952
1013
|
}
|
|
953
|
-
|
|
954
|
-
// Only accepts a canonical decimal chain id ("7", not "007" or "1foo") —
|
|
955
|
-
// the schema's parser follows parseFloat semantics and accepts both.
|
|
956
|
-
let parseChainId = str =>
|
|
957
|
-
switch try Some(str->ChainId.normalizeOrThrow) catch {
|
|
958
|
-
| _ => None
|
|
959
|
-
} {
|
|
960
|
-
| Some(chainId) if chainId->ChainId.toString === str => Some(chainId)
|
|
961
|
-
| _ => None
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
let chainScopedRe = /^envio_([0-9]+)_effect_(.+)$/
|
|
965
|
-
let crossChainRe = /^envio_effect_(.+)$/
|
|
966
|
-
|
|
967
|
-
// Inverse of toTableName. Returns None for any table name that isn't a cache
|
|
968
|
-
// table. Chain-scoped is tried first: the `_effect_` separator keeps effect
|
|
969
|
-
// names that themselves start with digits unambiguous.
|
|
970
|
-
let fromTableName = (tableName): option<(string, chainScope)> =>
|
|
971
|
-
switch RegExp.exec(chainScopedRe, tableName) {
|
|
972
|
-
| Some(result) =>
|
|
973
|
-
switch (
|
|
974
|
-
RegExp.Result.matches(result)->Array.get(0),
|
|
975
|
-
RegExp.Result.matches(result)->Array.get(1),
|
|
976
|
-
) {
|
|
977
|
-
| (Some(Some(chainIdStr)), Some(Some(effectName))) =>
|
|
978
|
-
switch parseChainId(chainIdStr) {
|
|
979
|
-
| Some(chainId) => Some((effectName, Chain(chainId)))
|
|
980
|
-
| None => None
|
|
981
|
-
}
|
|
982
|
-
| _ => None
|
|
983
|
-
}
|
|
984
|
-
| None =>
|
|
985
|
-
switch RegExp.exec(crossChainRe, tableName) {
|
|
986
|
-
| Some(result) =>
|
|
987
|
-
switch RegExp.Result.matches(result)->Array.get(0) {
|
|
988
|
-
| Some(Some(effectName)) => Some((effectName, CrossChain))
|
|
989
|
-
| _ => None
|
|
990
|
-
}
|
|
991
|
-
| None => None
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
// Relative posix path within .envio/cache. Chain-scoped caches live one
|
|
996
|
-
// directory level deep, named by chain id.
|
|
997
|
-
let toCachePath = (~effectName, ~scope) =>
|
|
998
|
-
switch scope {
|
|
999
|
-
| CrossChain => effectName ++ ".tsv"
|
|
1000
|
-
| Chain(chainId) => `${chainId->ChainId.toString}/${effectName}.tsv`
|
|
1001
|
-
}
|
|
1002
1014
|
}
|
|
1003
1015
|
|
|
1004
1016
|
let cacheOutputSchema = S.json(~validate=false)->(Utils.magic: S.t<JSON.t> => S.t<effectOutput>)
|
package/src/Internal.res.mjs
CHANGED
|
@@ -188,6 +188,37 @@ function eventItemFieldsJson(eventItem, address) {
|
|
|
188
188
|
return `{` + contractAndEventJson(eventItem.onEventRegistration.eventConfig) + `,"block":` + eventItem.blockNumber.toString() + `,"logIndex":` + eventItem.logIndex.toString() + `,"address":` + JSON.stringify(address) + `}`;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
function itemRunsFirst(item) {
|
|
192
|
+
if (item.kind === 0) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
let match = item.onBlockRegistration.runsFirst;
|
|
196
|
+
if (match !== undefined) {
|
|
197
|
+
return match;
|
|
198
|
+
} else {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
let callOrderingActive = {
|
|
204
|
+
contents: false
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
function callRankOfEventName(name) {
|
|
208
|
+
if (name.startsWith("__envio_call_any")) {
|
|
209
|
+
return 2;
|
|
210
|
+
} else if (name.startsWith("__envio_call_")) {
|
|
211
|
+
return 1;
|
|
212
|
+
} else {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function markItemCall(item, rank) {
|
|
218
|
+
item.callRank = rank;
|
|
219
|
+
callOrderingActive.contents = true;
|
|
220
|
+
}
|
|
221
|
+
|
|
191
222
|
function getItemChainId(item) {
|
|
192
223
|
if (item.kind === 0) {
|
|
193
224
|
return item.chainId;
|
|
@@ -240,87 +271,8 @@ function toTableName(effectName, scope) {
|
|
|
240
271
|
}
|
|
241
272
|
}
|
|
242
273
|
|
|
243
|
-
function parseChainId(str) {
|
|
244
|
-
let chainId;
|
|
245
|
-
try {
|
|
246
|
-
chainId = Primitive_option.some(ChainId.normalizeOrThrow(str));
|
|
247
|
-
} catch (exn) {
|
|
248
|
-
chainId = undefined;
|
|
249
|
-
}
|
|
250
|
-
if (chainId === undefined) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
let chainId$1 = Primitive_option.valFromOption(chainId);
|
|
254
|
-
if (ChainId.toString(chainId$1) === str) {
|
|
255
|
-
return Primitive_option.some(chainId$1);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
let chainScopedRe = /^envio_([0-9]+)_effect_(.+)$/;
|
|
260
|
-
|
|
261
|
-
let crossChainRe = /^envio_effect_(.+)$/;
|
|
262
|
-
|
|
263
|
-
function fromTableName(tableName) {
|
|
264
|
-
let result = chainScopedRe.exec(tableName);
|
|
265
|
-
if (result == null) {
|
|
266
|
-
let result$1 = crossChainRe.exec(tableName);
|
|
267
|
-
if (result$1 == null) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
let match = result$1.slice(1)[0];
|
|
271
|
-
if (match === undefined) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
let effectName = Primitive_option.valFromOption(match);
|
|
275
|
-
if (effectName !== undefined) {
|
|
276
|
-
return [
|
|
277
|
-
effectName,
|
|
278
|
-
"crossChain"
|
|
279
|
-
];
|
|
280
|
-
} else {
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
let match$1 = result.slice(1)[0];
|
|
285
|
-
let match$2 = result.slice(1)[1];
|
|
286
|
-
if (match$1 === undefined) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
let chainIdStr = Primitive_option.valFromOption(match$1);
|
|
290
|
-
if (chainIdStr === undefined) {
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
if (match$2 === undefined) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
let effectName$1 = Primitive_option.valFromOption(match$2);
|
|
297
|
-
if (effectName$1 === undefined) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
let chainId = parseChainId(chainIdStr);
|
|
301
|
-
if (chainId !== undefined) {
|
|
302
|
-
return [
|
|
303
|
-
effectName$1,
|
|
304
|
-
Primitive_option.valFromOption(chainId)
|
|
305
|
-
];
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function toCachePath(effectName, scope) {
|
|
310
|
-
if (scope === "crossChain") {
|
|
311
|
-
return effectName + ".tsv";
|
|
312
|
-
} else {
|
|
313
|
-
return ChainId.toString(scope) + `/` + effectName + `.tsv`;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
274
|
let EffectCache = {
|
|
318
|
-
toTableName: toTableName
|
|
319
|
-
parseChainId: parseChainId,
|
|
320
|
-
chainScopedRe: chainScopedRe,
|
|
321
|
-
crossChainRe: crossChainRe,
|
|
322
|
-
fromTableName: fromTableName,
|
|
323
|
-
toCachePath: toCachePath
|
|
275
|
+
toTableName: toTableName
|
|
324
276
|
};
|
|
325
277
|
|
|
326
278
|
let cacheOutputSchema = S$RescriptSchema.json(false);
|
|
@@ -356,6 +308,10 @@ export {
|
|
|
356
308
|
dependsOnAddresses,
|
|
357
309
|
svmAccountSlotName,
|
|
358
310
|
eventItemFieldsJson,
|
|
311
|
+
itemRunsFirst,
|
|
312
|
+
callOrderingActive,
|
|
313
|
+
callRankOfEventName,
|
|
314
|
+
markItemCall,
|
|
359
315
|
getItemChainId,
|
|
360
316
|
fuelSupplyParamsSchema,
|
|
361
317
|
fuelTransferParamsSchema,
|
package/src/LoadLayer.res
CHANGED
|
@@ -16,7 +16,12 @@ let loadById = (
|
|
|
16
16
|
~entityId,
|
|
17
17
|
) => {
|
|
18
18
|
let inMemTable = indexerState->InMemoryStore.getInMemTable(~entityConfig, ~scope)
|
|
19
|
-
|
|
19
|
+
// The ids here are typed as strings but hold whatever scalar the id is.
|
|
20
|
+
let entityIdToKey =
|
|
21
|
+
inMemTable.entityIdToKey->(Utils.magic: (EntityId.t => string) => string => string)
|
|
22
|
+
switch inMemTable.latestEntityChangeById->Utils.Dict.dangerouslyGetNonOption(
|
|
23
|
+
entityIdToKey(entityId),
|
|
24
|
+
) {
|
|
20
25
|
// A row already in memory is final, so even a grouped call skips the load
|
|
21
26
|
// manager: grouping it would only resolve it a tick later to the same value.
|
|
22
27
|
| Some(change) => Promise.resolve(change->InMemoryTable.Entity.mapChangeToEntity)
|
|
@@ -53,14 +58,14 @@ let loadById = (
|
|
|
53
58
|
//Set the entity in the in memory store
|
|
54
59
|
for idx in 0 to dbEntities->Array.length - 1 {
|
|
55
60
|
let entity = dbEntities->Array.getUnsafe(idx)
|
|
56
|
-
entitiesMap->Dict.set(entity.id, entity)
|
|
61
|
+
entitiesMap->Dict.set(entityIdToKey(entity.id), entity)
|
|
57
62
|
}
|
|
58
63
|
let committedCheckpointId = indexerState->IndexerState.committedCheckpointIdFor(~scope)
|
|
59
64
|
idsToLoad->Array.forEach(entityId => {
|
|
60
65
|
inMemTable->InMemoryTable.Entity.initValue(
|
|
61
66
|
~committedCheckpointId,
|
|
62
|
-
~
|
|
63
|
-
~entity=entitiesMap->Utils.Dict.dangerouslyGetNonOption(entityId),
|
|
67
|
+
~entityId=entityId->EntityId.unsafeOfString,
|
|
68
|
+
~entity=entitiesMap->Utils.Dict.dangerouslyGetNonOption(entityIdToKey(entityId)),
|
|
64
69
|
)
|
|
65
70
|
})
|
|
66
71
|
|
|
@@ -77,7 +82,7 @@ let loadById = (
|
|
|
77
82
|
~key,
|
|
78
83
|
~load,
|
|
79
84
|
~shouldGroup,
|
|
80
|
-
~hasher=
|
|
85
|
+
~hasher=entityIdToKey,
|
|
81
86
|
~getUnsafeInMemory=inMemTable->InMemoryTable.Entity.getUnsafe,
|
|
82
87
|
~hasInMemory=hash => inMemTable.latestEntityChangeById->Dict.has(hash),
|
|
83
88
|
~input=entityId,
|
|
@@ -140,7 +145,7 @@ let rec executeWithRateLimit = (
|
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
| Some(state) =>
|
|
143
|
-
let now =
|
|
148
|
+
let now = state.clock.now()
|
|
144
149
|
|
|
145
150
|
// Check if we need to reset the window
|
|
146
151
|
if now >= state.windowStartTime +. state.durationMs->Int.toFloat {
|
|
@@ -188,7 +193,8 @@ let rec executeWithRateLimit = (
|
|
|
188
193
|
| None =>
|
|
189
194
|
millisUntilReset :=
|
|
190
195
|
(state.windowStartTime +. state.durationMs->Int.toFloat -. now)->Float.toInt
|
|
191
|
-
let p =
|
|
196
|
+
let p =
|
|
197
|
+
state.clock->Clock.delay(~label="effect rate limit window", millisUntilReset.contents)
|
|
192
198
|
state.nextWindowPromise = Some(p)
|
|
193
199
|
p
|
|
194
200
|
}
|
|
@@ -335,6 +341,45 @@ let loadEffect = (
|
|
|
335
341
|
)
|
|
336
342
|
}
|
|
337
343
|
|
|
344
|
+
// Keying an _in walks every value, so it's computed once and handed on rather
|
|
345
|
+
// than recomputed by each reader. Before answering "not in memory", the rows
|
|
346
|
+
// already loaded for other filters are checked: they may cover this one.
|
|
347
|
+
let indexFilter = (inMemTable, ~filter, ~table) => {
|
|
348
|
+
let filterKey = filter->EntityFilter.toString(~table)
|
|
349
|
+
if !(inMemTable->InMemoryTable.Entity.hasIndex)(filterKey) {
|
|
350
|
+
inMemTable->InMemoryTable.Entity.tryIndexFromLoadedValues(~filter, ~table)
|
|
351
|
+
}
|
|
352
|
+
filterKey
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// A recorded absence is an answer too: `Some(None)` means the entity is known
|
|
356
|
+
// not to exist, so no load is needed to say so.
|
|
357
|
+
let getByIdInMemory = (
|
|
358
|
+
~entityConfig: Internal.entityConfig,
|
|
359
|
+
~scope,
|
|
360
|
+
~indexerState,
|
|
361
|
+
~entityId: string,
|
|
362
|
+
) => {
|
|
363
|
+
let inMemTable = indexerState->InMemoryStore.getInMemTable(~entityConfig, ~scope)
|
|
364
|
+
let entityKey = inMemTable.entityIdToKey(entityId->EntityId.unsafeOfString)
|
|
365
|
+
inMemTable.latestEntityChangeById->Dict.has(entityKey)
|
|
366
|
+
? Some((inMemTable->InMemoryTable.Entity.getUnsafe)(entityKey))
|
|
367
|
+
: None
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
let getByFilterInMemory = (
|
|
371
|
+
~entityConfig: Internal.entityConfig,
|
|
372
|
+
~scope,
|
|
373
|
+
~indexerState,
|
|
374
|
+
~filter: EntityFilter.t,
|
|
375
|
+
) => {
|
|
376
|
+
let inMemTable = indexerState->InMemoryStore.getInMemTable(~entityConfig, ~scope)
|
|
377
|
+
let filterKey = inMemTable->indexFilter(~filter, ~table=entityConfig.table)
|
|
378
|
+
(inMemTable->InMemoryTable.Entity.hasIndex)(filterKey)
|
|
379
|
+
? Some((inMemTable->InMemoryTable.Entity.getUnsafeOnIndex)(filterKey))
|
|
380
|
+
: None
|
|
381
|
+
}
|
|
382
|
+
|
|
338
383
|
let loadByParsedFilter = (
|
|
339
384
|
~loadManager,
|
|
340
385
|
~persistence: Persistence.t,
|
|
@@ -387,7 +432,7 @@ let loadByParsedFilter = (
|
|
|
387
432
|
entities->Array.forEach(entity => {
|
|
388
433
|
inMemTable->InMemoryTable.Entity.initValue(
|
|
389
434
|
~committedCheckpointId,
|
|
390
|
-
~
|
|
435
|
+
~entityId=entity.id->EntityId.unsafeOfString,
|
|
391
436
|
~entity=Some(entity),
|
|
392
437
|
)
|
|
393
438
|
})
|
|
@@ -425,13 +470,7 @@ let loadByParsedFilter = (
|
|
|
425
470
|
)
|
|
426
471
|
}
|
|
427
472
|
|
|
428
|
-
|
|
429
|
-
// the load manager rather than recomputed by the hasher.
|
|
430
|
-
let filterKey = filter->EntityFilter.toString(~table=entityConfig.table)
|
|
431
|
-
|
|
432
|
-
if !(inMemTable->InMemoryTable.Entity.hasIndex)(filterKey) {
|
|
433
|
-
inMemTable->InMemoryTable.Entity.tryIndexFromLoadedValues(~filter, ~table=entityConfig.table)
|
|
434
|
-
}
|
|
473
|
+
let filterKey = inMemTable->indexFilter(~filter, ~table=entityConfig.table)
|
|
435
474
|
|
|
436
475
|
loadManager->LoadManager.call(
|
|
437
476
|
~key,
|
package/src/LoadLayer.res.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Clock from "./Clock.res.mjs";
|
|
3
4
|
import * as Utils from "./Utils.res.mjs";
|
|
4
5
|
import * as Logger from "./Logger.res.mjs";
|
|
5
6
|
import * as ChainId from "./ChainId.res.mjs";
|
|
@@ -14,6 +15,7 @@ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
|
14
15
|
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
15
16
|
import * as InMemoryStore from "./InMemoryStore.res.mjs";
|
|
16
17
|
import * as InMemoryTable from "./InMemoryTable.res.mjs";
|
|
18
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
17
19
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
18
20
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
19
21
|
|
|
@@ -27,7 +29,8 @@ function scopeKeySuffix(scope) {
|
|
|
27
29
|
|
|
28
30
|
function loadById(loadManager, persistence, entityConfig, scope, indexerState, shouldGroup, entityId) {
|
|
29
31
|
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
30
|
-
let
|
|
32
|
+
let entityIdToKey = inMemTable.entityIdToKey;
|
|
33
|
+
let change = inMemTable.latestEntityChangeById[entityIdToKey(entityId)];
|
|
31
34
|
if (change !== undefined) {
|
|
32
35
|
return Promise.resolve(InMemoryTable.Entity.mapChangeToEntity(change));
|
|
33
36
|
}
|
|
@@ -50,13 +53,13 @@ function loadById(loadManager, persistence, entityConfig, scope, indexerState, s
|
|
|
50
53
|
let entitiesMap = {};
|
|
51
54
|
for (let idx = 0, idx_finish = dbEntities.length; idx < idx_finish; ++idx) {
|
|
52
55
|
let entity = dbEntities[idx];
|
|
53
|
-
entitiesMap[entity.id] = entity;
|
|
56
|
+
entitiesMap[entityIdToKey(entity.id)] = entity;
|
|
54
57
|
}
|
|
55
58
|
let committedCheckpointId = IndexerState.committedCheckpointIdFor(indexerState, scope);
|
|
56
|
-
idsToLoad.forEach(entityId => InMemoryTable.Entity.initValue(inMemTable, committedCheckpointId, entityId, entitiesMap[entityId]));
|
|
59
|
+
idsToLoad.forEach(entityId => InMemoryTable.Entity.initValue(inMemTable, committedCheckpointId, entityId, entitiesMap[entityIdToKey(entityId)]));
|
|
57
60
|
return IndexerState.endStorageLoad(indexerState, timerRef, storageName, key, idsToLoad.length, dbEntities.length);
|
|
58
61
|
};
|
|
59
|
-
return LoadManager.call(loadManager, entityId, key, load,
|
|
62
|
+
return LoadManager.call(loadManager, entityId, key, load, entityIdToKey, shouldGroup, hash => hash in inMemTable.latestEntityChangeById, InMemoryTable.Entity.getUnsafe(inMemTable));
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
function callEffect(effect, arg, inMemTable, timerRef, onError) {
|
|
@@ -69,7 +72,7 @@ function executeWithRateLimit(effect, effectArgs, inMemTable, onError, isFromQue
|
|
|
69
72
|
let promises = [];
|
|
70
73
|
let state = inMemTable.rateLimitState;
|
|
71
74
|
if (state !== undefined) {
|
|
72
|
-
let now =
|
|
75
|
+
let now = state.clock.now();
|
|
73
76
|
if (now >= state.windowStartTime + state.durationMs) {
|
|
74
77
|
state.availableCalls = state.callsPerDuration;
|
|
75
78
|
state.windowStartTime = now;
|
|
@@ -98,7 +101,7 @@ function executeWithRateLimit(effect, effectArgs, inMemTable, onError, isFromQue
|
|
|
98
101
|
nextWindowPromise = p;
|
|
99
102
|
} else {
|
|
100
103
|
millisUntilReset.contents = state.windowStartTime + state.durationMs - now | 0;
|
|
101
|
-
let p$1 =
|
|
104
|
+
let p$1 = Clock.delay(state.clock, "effect rate limit window", millisUntilReset.contents);
|
|
102
105
|
state.nextWindowPromise = p$1;
|
|
103
106
|
nextWindowPromise = p$1;
|
|
104
107
|
}
|
|
@@ -184,47 +187,71 @@ function loadEffect(loadManager, persistence, effect, effectArgs, scope, indexer
|
|
|
184
187
|
return LoadManager.call(loadManager, effectArgs, key, load, args => args.cacheKey, shouldGroup, hash => InMemoryStore.hasEffectOutput(inMemTable, hash), hash => InMemoryStore.getEffectOutputUnsafe(inMemTable, hash));
|
|
185
188
|
}
|
|
186
189
|
|
|
190
|
+
function indexFilter(inMemTable, filter, table) {
|
|
191
|
+
let filterKey = EntityFilter.toString(filter, table);
|
|
192
|
+
if (!InMemoryTable.Entity.hasIndex(inMemTable)(filterKey)) {
|
|
193
|
+
InMemoryTable.Entity.tryIndexFromLoadedValues(inMemTable, filter, table);
|
|
194
|
+
}
|
|
195
|
+
return filterKey;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function getByIdInMemory(entityConfig, scope, indexerState, entityId) {
|
|
199
|
+
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
200
|
+
let entityKey = inMemTable.entityIdToKey(entityId);
|
|
201
|
+
if (entityKey in inMemTable.latestEntityChangeById) {
|
|
202
|
+
return Primitive_option.some(InMemoryTable.Entity.getUnsafe(inMemTable)(entityKey));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function getByFilterInMemory(entityConfig, scope, indexerState, filter) {
|
|
207
|
+
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
208
|
+
let filterKey = indexFilter(inMemTable, filter, entityConfig.table);
|
|
209
|
+
if (InMemoryTable.Entity.hasIndex(inMemTable)(filterKey)) {
|
|
210
|
+
return InMemoryTable.Entity.getUnsafeOnIndex(inMemTable)(filterKey);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function loadByParsedFilter(loadManager, persistence, entityConfig, scope, indexerState, shouldGroup, filter) {
|
|
215
|
+
let key = EntityFilter.toOperationKey(filter, entityConfig.name) + scopeKeySuffix(scope);
|
|
216
|
+
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
217
|
+
let load = async (filters, param) => {
|
|
218
|
+
let storage = Persistence.getInitializedStorageOrThrow(persistence);
|
|
219
|
+
let storageName = storage.entityStoreName(entityConfig);
|
|
220
|
+
let timerRef = IndexerState.startStorageLoad(indexerState, storageName, key);
|
|
221
|
+
let size = {
|
|
222
|
+
contents: 0
|
|
223
|
+
};
|
|
224
|
+
filters.forEach(filter => InMemoryTable.Entity.addEmptyIndex(inMemTable, filter, entityConfig.table));
|
|
225
|
+
await storage.ensureQueryIndexes(entityConfig, scope, filters);
|
|
226
|
+
let queries = EntityFilter.merge(filters);
|
|
227
|
+
await Promise.all(queries.map(async filter => {
|
|
228
|
+
try {
|
|
229
|
+
let entities = await storage.loadOrThrow(EntityFilter.scoped(filter, entityConfig.table, scope), entityConfig.table);
|
|
230
|
+
let committedCheckpointId = IndexerState.committedCheckpointIdFor(indexerState, scope);
|
|
231
|
+
entities.forEach(entity => InMemoryTable.Entity.initValue(inMemTable, committedCheckpointId, entity.id, entity));
|
|
232
|
+
InMemoryTable.Entity.recordLoadedValues(inMemTable, filter, entityConfig.table);
|
|
233
|
+
size.contents = size.contents + entities.length | 0;
|
|
234
|
+
return;
|
|
235
|
+
} catch (raw_exn) {
|
|
236
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
237
|
+
if (exn.RE_EXN_ID === Persistence.StorageError) {
|
|
238
|
+
return ErrorHandling.mkLogAndRaise(Logger.withFields(IndexerState.loggerForScope(indexerState, scope), {
|
|
239
|
+
operation: key,
|
|
240
|
+
params: EntityFilter.getParams(filter)
|
|
241
|
+
}), exn.message, exn.reason);
|
|
242
|
+
}
|
|
243
|
+
throw exn;
|
|
244
|
+
}
|
|
245
|
+
}));
|
|
246
|
+
return IndexerState.endStorageLoad(indexerState, timerRef, storageName, key, Stdlib_Array.reduce(queries, 0, (acc, query) => acc + EntityFilter.valuesCount(query) | 0), size.contents);
|
|
247
|
+
};
|
|
248
|
+
let filterKey = indexFilter(inMemTable, filter, entityConfig.table);
|
|
249
|
+
return LoadManager.call(loadManager, filter, key, load, param => filterKey, shouldGroup, InMemoryTable.Entity.hasIndex(inMemTable), InMemoryTable.Entity.getUnsafeOnIndex(inMemTable));
|
|
250
|
+
}
|
|
251
|
+
|
|
187
252
|
function loadByFilter(loadManager, persistence, entityConfig, scope, indexerState, shouldGroup, filter) {
|
|
188
253
|
try {
|
|
189
|
-
|
|
190
|
-
let key = EntityFilter.toOperationKey(filter$1, entityConfig.name) + scopeKeySuffix(scope);
|
|
191
|
-
let inMemTable = InMemoryStore.getInMemTable(indexerState, entityConfig, scope);
|
|
192
|
-
let load = async (filters, param) => {
|
|
193
|
-
let storage = Persistence.getInitializedStorageOrThrow(persistence);
|
|
194
|
-
let storageName = storage.entityStoreName(entityConfig);
|
|
195
|
-
let timerRef = IndexerState.startStorageLoad(indexerState, storageName, key);
|
|
196
|
-
let size = {
|
|
197
|
-
contents: 0
|
|
198
|
-
};
|
|
199
|
-
filters.forEach(filter => InMemoryTable.Entity.addEmptyIndex(inMemTable, filter, entityConfig.table));
|
|
200
|
-
await storage.ensureQueryIndexes(entityConfig, scope, filters);
|
|
201
|
-
let queries = EntityFilter.merge(filters);
|
|
202
|
-
await Promise.all(queries.map(async filter => {
|
|
203
|
-
try {
|
|
204
|
-
let entities = await storage.loadOrThrow(EntityFilter.scoped(filter, entityConfig.table, scope), entityConfig.table);
|
|
205
|
-
let committedCheckpointId = IndexerState.committedCheckpointIdFor(indexerState, scope);
|
|
206
|
-
entities.forEach(entity => InMemoryTable.Entity.initValue(inMemTable, committedCheckpointId, entity.id, entity));
|
|
207
|
-
InMemoryTable.Entity.recordLoadedValues(inMemTable, filter, entityConfig.table);
|
|
208
|
-
size.contents = size.contents + entities.length | 0;
|
|
209
|
-
return;
|
|
210
|
-
} catch (raw_exn) {
|
|
211
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
212
|
-
if (exn.RE_EXN_ID === Persistence.StorageError) {
|
|
213
|
-
return ErrorHandling.mkLogAndRaise(Logger.withFields(IndexerState.loggerForScope(indexerState, scope), {
|
|
214
|
-
operation: key,
|
|
215
|
-
params: EntityFilter.getParams(filter)
|
|
216
|
-
}), exn.message, exn.reason);
|
|
217
|
-
}
|
|
218
|
-
throw exn;
|
|
219
|
-
}
|
|
220
|
-
}));
|
|
221
|
-
return IndexerState.endStorageLoad(indexerState, timerRef, storageName, key, Stdlib_Array.reduce(queries, 0, (acc, query) => acc + EntityFilter.valuesCount(query) | 0), size.contents);
|
|
222
|
-
};
|
|
223
|
-
let filterKey = EntityFilter.toString(filter$1, entityConfig.table);
|
|
224
|
-
if (!InMemoryTable.Entity.hasIndex(inMemTable)(filterKey)) {
|
|
225
|
-
InMemoryTable.Entity.tryIndexFromLoadedValues(inMemTable, filter$1, entityConfig.table);
|
|
226
|
-
}
|
|
227
|
-
return LoadManager.call(loadManager, filter$1, key, load, param => filterKey, shouldGroup, InMemoryTable.Entity.hasIndex(inMemTable), InMemoryTable.Entity.getUnsafeOnIndex(inMemTable));
|
|
254
|
+
return loadByParsedFilter(loadManager, persistence, entityConfig, scope, indexerState, shouldGroup, EntityFilter.parseOrThrow(filter, entityConfig.name, entityConfig.table));
|
|
228
255
|
} catch (raw_exn) {
|
|
229
256
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
230
257
|
return Promise.reject(Utils.prettifyExn(exn));
|
|
@@ -234,6 +261,9 @@ function loadByFilter(loadManager, persistence, entityConfig, scope, indexerStat
|
|
|
234
261
|
export {
|
|
235
262
|
loadById,
|
|
236
263
|
loadByFilter,
|
|
264
|
+
loadByParsedFilter,
|
|
265
|
+
getByIdInMemory,
|
|
266
|
+
getByFilterInMemory,
|
|
237
267
|
loadEffect,
|
|
238
268
|
}
|
|
239
269
|
/* Utils Not a pure module */
|
package/src/LoadLayer.resi
CHANGED
|
@@ -18,6 +18,32 @@ let loadByFilter: (
|
|
|
18
18
|
~filter: dict<dict<unknown>>,
|
|
19
19
|
) => promise<array<Internal.entity>>
|
|
20
20
|
|
|
21
|
+
let loadByParsedFilter: (
|
|
22
|
+
~loadManager: LoadManager.t,
|
|
23
|
+
~persistence: Persistence.t,
|
|
24
|
+
~entityConfig: Internal.entityConfig,
|
|
25
|
+
~scope: Internal.chainScope,
|
|
26
|
+
~indexerState: IndexerState.t,
|
|
27
|
+
~shouldGroup: bool,
|
|
28
|
+
~filter: EntityFilter.t,
|
|
29
|
+
) => promise<array<Internal.entity>>
|
|
30
|
+
|
|
31
|
+
// What a get or getWhere answers without a load, or None when it would need
|
|
32
|
+
// one. The sync context reads through these and suspends on None.
|
|
33
|
+
let getByIdInMemory: (
|
|
34
|
+
~entityConfig: Internal.entityConfig,
|
|
35
|
+
~scope: Internal.chainScope,
|
|
36
|
+
~indexerState: IndexerState.t,
|
|
37
|
+
~entityId: string,
|
|
38
|
+
) => option<option<Internal.entity>>
|
|
39
|
+
|
|
40
|
+
let getByFilterInMemory: (
|
|
41
|
+
~entityConfig: Internal.entityConfig,
|
|
42
|
+
~scope: Internal.chainScope,
|
|
43
|
+
~indexerState: IndexerState.t,
|
|
44
|
+
~filter: EntityFilter.t,
|
|
45
|
+
) => option<array<Internal.entity>>
|
|
46
|
+
|
|
21
47
|
let loadEffect: (
|
|
22
48
|
~loadManager: LoadManager.t,
|
|
23
49
|
~persistence: Persistence.t,
|
package/src/Main.res
CHANGED
|
@@ -303,12 +303,25 @@ let getGlobalIndexer = (): 'indexer => {
|
|
|
303
303
|
|
|
304
304
|
let onBlockFn = (rawOptions: 'a, handler: 'b) => {
|
|
305
305
|
HandlerRegister.throwIfFinishedRegistration(~methodName="onBlock")
|
|
306
|
-
let raw =
|
|
306
|
+
let raw =
|
|
307
|
+
rawOptions->(
|
|
308
|
+
Utils.magic: 'a => {
|
|
309
|
+
"name": string,
|
|
310
|
+
"where": unknown,
|
|
311
|
+
"fields": unknown,
|
|
312
|
+
"runsFirst": option<bool>,
|
|
313
|
+
"contractRegister": option<Internal.onBlockContractRegisterArgs => promise<unit>>,
|
|
314
|
+
}
|
|
315
|
+
)
|
|
307
316
|
HandlerRegister.registerOnBlock(
|
|
308
317
|
~name=raw["name"],
|
|
309
318
|
~where=raw["where"],
|
|
310
319
|
~fields=raw["fields"],
|
|
311
320
|
~handler=handler->(Utils.magic: 'b => Internal.onBlockArgs => promise<unit>),
|
|
321
|
+
// Not part of the public API: the subgraph runtime's `once` handlers, and
|
|
322
|
+
// the register passes of block handlers that create data sources.
|
|
323
|
+
~runsFirst=Env.subgraphMode.contents && raw["runsFirst"] === Some(true),
|
|
324
|
+
~contractRegister=?Env.subgraphMode.contents ? raw["contractRegister"] : None,
|
|
312
325
|
~getChainsObject=config => {
|
|
313
326
|
let (chains, _) = buildChainsObject(~config)
|
|
314
327
|
chains->(Utils.magic: {..} => dict<unknown>)
|
package/src/Main.res.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Env from "./Env.res.mjs";
|
|
3
4
|
import * as Tui from "./tui/Tui.res.mjs";
|
|
4
5
|
import * as Utils from "./Utils.res.mjs";
|
|
5
6
|
import * as Config from "./Config.res.mjs";
|
|
@@ -255,7 +256,7 @@ function getGlobalIndexer() {
|
|
|
255
256
|
};
|
|
256
257
|
let onBlockFn = (rawOptions, handler) => {
|
|
257
258
|
HandlerRegister.throwIfFinishedRegistration("onBlock");
|
|
258
|
-
HandlerRegister.registerOnBlock(rawOptions.name, rawOptions.where, rawOptions.fields, handler, config => buildChainsObject(config)[0]);
|
|
259
|
+
HandlerRegister.registerOnBlock(rawOptions.name, rawOptions.where, rawOptions.fields, handler, Env.subgraphMode.contents && rawOptions.runsFirst === true, Env.subgraphMode.contents ? rawOptions.contractRegister : undefined, config => buildChainsObject(config)[0]);
|
|
259
260
|
};
|
|
260
261
|
let keysMemo = {
|
|
261
262
|
contents: undefined
|
|
@@ -413,7 +414,7 @@ async function startIndexer(config, logger, persistence, resetOpt, isTestOpt, ex
|
|
|
413
414
|
Metrics.startRuntimeCollectors();
|
|
414
415
|
Server.startServer(logger, getMetrics, envioVersion, () => Persistence.getInitializedStorageOrThrow(persistence$1).dumpEffectCache().then(prim => {}), Metrics.collectRuntime, isDevelopmentMode);
|
|
415
416
|
}
|
|
416
|
-
let state = IndexerState.makeFromDbState(config$2, logger, persistence$1, Persistence.getInitializedState(persistence$1), registrationsByChainId, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, undefined, undefined, Stdlib_Option.mapOr(Worker.config, false, worker => worker.holdRealtime), onError, undefined);
|
|
417
|
+
let state = IndexerState.makeFromDbState(config$2, logger, persistence$1, Persistence.getInitializedState(persistence$1), registrationsByChainId, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, undefined, undefined, Stdlib_Option.mapOr(Worker.config, false, worker => worker.holdRealtime), onError, undefined, undefined);
|
|
417
418
|
if (shouldUseTui) {
|
|
418
419
|
Tui.start(config$2, logger, () => IndexerState.toMetrics(state));
|
|
419
420
|
}
|
|
@@ -454,4 +455,4 @@ export {
|
|
|
454
455
|
FatalError,
|
|
455
456
|
start,
|
|
456
457
|
}
|
|
457
|
-
/*
|
|
458
|
+
/* Env Not a pure module */
|