envio 2.29.0-alpha.0 → 2.29.0-alpha.2
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/index.d.ts +3 -0
- package/package.json +5 -5
- package/src/Batch.res +4 -14
- package/src/Batch.res.js +3 -14
- package/src/Envio.gen.ts +14 -0
- package/src/Envio.res +18 -0
- package/src/EventRegister.res +173 -31
- package/src/EventRegister.res.js +138 -33
- package/src/EventRegister.resi +11 -0
- package/src/EventUtils.res +52 -58
- package/src/EventUtils.res.js +15 -51
- package/src/FetchState.res +90 -57
- package/src/FetchState.res.js +84 -56
- package/src/Internal.gen.ts +2 -0
- package/src/Internal.res +47 -3
- package/src/InternalConfig.res +18 -0
- package/src/Logging.res +36 -24
- package/src/Logging.res.js +35 -21
- package/src/sources/HyperFuelSource.res +506 -0
- package/src/sources/HyperFuelSource.res.js +451 -0
- package/src/sources/HyperSync.res +1 -1
- package/src/sources/HyperSync.resi +1 -1
- package/src/sources/HyperSyncSource.res +569 -0
- package/src/sources/HyperSyncSource.res.js +413 -0
- package/src/sources/RpcSource.res +18 -20
- package/src/sources/RpcSource.res.js +1 -0
- package/src/sources/Source.res +1 -1
package/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ export type {
|
|
|
4
4
|
effectContext as EffectContext,
|
|
5
5
|
effectArgs as EffectArgs,
|
|
6
6
|
effectOptions as EffectOptions,
|
|
7
|
+
blockEvent as BlockEvent,
|
|
8
|
+
onBlockArgs as OnBlockArgs,
|
|
9
|
+
onBlockOptions as OnBlockOptions,
|
|
7
10
|
} from "./src/Envio.gen.ts";
|
|
8
11
|
export type { EffectCaller } from "./src/Types.ts";
|
|
9
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "v2.29.0-alpha.
|
|
3
|
+
"version": "v2.29.0-alpha.2",
|
|
4
4
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
5
5
|
"bin": "./bin.js",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://envio.dev",
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"envio-linux-x64": "v2.29.0-alpha.
|
|
29
|
-
"envio-linux-arm64": "v2.29.0-alpha.
|
|
30
|
-
"envio-darwin-x64": "v2.29.0-alpha.
|
|
31
|
-
"envio-darwin-arm64": "v2.29.0-alpha.
|
|
28
|
+
"envio-linux-x64": "v2.29.0-alpha.2",
|
|
29
|
+
"envio-linux-arm64": "v2.29.0-alpha.2",
|
|
30
|
+
"envio-darwin-x64": "v2.29.0-alpha.2",
|
|
31
|
+
"envio-darwin-arm64": "v2.29.0-alpha.2"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@envio-dev/hypersync-client": "0.6.6",
|
package/src/Batch.res
CHANGED
|
@@ -7,7 +7,7 @@ type progressedChain = {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
type t = {
|
|
10
|
-
items: array<Internal.
|
|
10
|
+
items: array<Internal.item>,
|
|
11
11
|
progressedChains: array<progressedChain>,
|
|
12
12
|
fetchStates: ChainMap.t<FetchState.t>,
|
|
13
13
|
dcsToStoreByChainId: dict<array<FetchState.indexingContract>>,
|
|
@@ -18,19 +18,9 @@ type multiChainEventComparitor = {
|
|
|
18
18
|
earliestEvent: FetchState.queueItem,
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
let getComparitorFromItem = (queueItem: Internal.eventItem) => {
|
|
22
|
-
let {timestamp, chain, blockNumber, logIndex} = queueItem
|
|
23
|
-
EventUtils.getEventComparator({
|
|
24
|
-
timestamp,
|
|
25
|
-
chainId: chain->ChainMap.Chain.toChainId,
|
|
26
|
-
blockNumber,
|
|
27
|
-
logIndex,
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
21
|
let getQueueItemComparitor = (earliestQueueItem: FetchState.queueItem, ~chain) => {
|
|
32
22
|
switch earliestQueueItem {
|
|
33
|
-
| Item({item}) => item->
|
|
23
|
+
| Item({item}) => item->EventUtils.getOrderedBatchItemComparator
|
|
34
24
|
| NoItem({latestFetchedBlock: {blockTimestamp, blockNumber}}) => (
|
|
35
25
|
blockTimestamp,
|
|
36
26
|
chain->ChainMap.Chain.toChainId,
|
|
@@ -78,13 +68,13 @@ let popOrderedBatchItems = (
|
|
|
78
68
|
let rec loop = () =>
|
|
79
69
|
if items->Array.length < maxBatchSize {
|
|
80
70
|
switch fetchStates->getOrderedNextItem {
|
|
81
|
-
| Some({earliestEvent}) =>
|
|
71
|
+
| Some({earliestEvent, chain}) =>
|
|
82
72
|
switch earliestEvent {
|
|
83
73
|
| NoItem(_) => ()
|
|
84
74
|
| Item({item, popItemOffQueue}) => {
|
|
85
75
|
popItemOffQueue()
|
|
86
76
|
items->Js.Array2.push(item)->ignore
|
|
87
|
-
sizePerChain->Utils.Dict.incrementByInt(
|
|
77
|
+
sizePerChain->Utils.Dict.incrementByInt(chain->ChainMap.Chain.toChainId)
|
|
88
78
|
loop()
|
|
89
79
|
}
|
|
90
80
|
}
|
package/src/Batch.res.js
CHANGED
|
@@ -8,18 +8,9 @@ var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
|
8
8
|
var EventUtils = require("./EventUtils.res.js");
|
|
9
9
|
var FetchState = require("./FetchState.res.js");
|
|
10
10
|
|
|
11
|
-
function getComparitorFromItem(queueItem) {
|
|
12
|
-
return EventUtils.getEventComparator({
|
|
13
|
-
timestamp: queueItem.timestamp,
|
|
14
|
-
chainId: queueItem.chain,
|
|
15
|
-
blockNumber: queueItem.blockNumber,
|
|
16
|
-
logIndex: queueItem.logIndex
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
11
|
function getQueueItemComparitor(earliestQueueItem, chain) {
|
|
21
12
|
if (earliestQueueItem.TAG === "Item") {
|
|
22
|
-
return
|
|
13
|
+
return EventUtils.getOrderedBatchItemComparator(earliestQueueItem._0.item);
|
|
23
14
|
}
|
|
24
15
|
var match = earliestQueueItem.latestFetchedBlock;
|
|
25
16
|
return [
|
|
@@ -70,10 +61,9 @@ function popOrderedBatchItems(maxBatchSize, fetchStates, sizePerChain) {
|
|
|
70
61
|
return ;
|
|
71
62
|
}
|
|
72
63
|
var match$1 = earliestEvent._0;
|
|
73
|
-
var item = match$1.item;
|
|
74
64
|
match$1.popItemOffQueue();
|
|
75
|
-
items.push(item);
|
|
76
|
-
Utils.Dict.incrementByInt(sizePerChain,
|
|
65
|
+
items.push(match$1.item);
|
|
66
|
+
Utils.Dict.incrementByInt(sizePerChain, match.chain);
|
|
77
67
|
continue ;
|
|
78
68
|
};
|
|
79
69
|
};
|
|
@@ -120,7 +110,6 @@ function popUnorderedBatchItems(maxBatchSize, fetchStates, sizePerChain) {
|
|
|
120
110
|
return items;
|
|
121
111
|
}
|
|
122
112
|
|
|
123
|
-
exports.getComparitorFromItem = getComparitorFromItem;
|
|
124
113
|
exports.getQueueItemComparitor = getQueueItemComparitor;
|
|
125
114
|
exports.isQueueItemEarlier = isQueueItemEarlier;
|
|
126
115
|
exports.getOrderedNextItem = getOrderedNextItem;
|
package/src/Envio.gen.ts
CHANGED
|
@@ -11,6 +11,20 @@ import type {Logger as $$logger} from './Types.ts';
|
|
|
11
11
|
|
|
12
12
|
import type {S_t as RescriptSchema_S_t} from 'rescript-schema/RescriptSchema.gen';
|
|
13
13
|
|
|
14
|
+
import type {blockEvent as Internal_blockEvent} from './Internal.gen';
|
|
15
|
+
|
|
16
|
+
export type blockEvent = Internal_blockEvent;
|
|
17
|
+
|
|
18
|
+
export type onBlockArgs<context> = { readonly block: blockEvent; readonly context: context };
|
|
19
|
+
|
|
20
|
+
export type onBlockOptions<chain> = {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly chain: chain;
|
|
23
|
+
readonly interval?: number;
|
|
24
|
+
readonly startBlock?: number;
|
|
25
|
+
readonly endBlock?: number
|
|
26
|
+
};
|
|
27
|
+
|
|
14
28
|
export type logger = $$logger;
|
|
15
29
|
|
|
16
30
|
export type effect<input,output> = $$effect<input,output>;
|
package/src/Envio.res
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
// Should be an entry point after we get rid of the generated project.
|
|
3
3
|
// Don't forget to keep index.d.ts in sync with this file.
|
|
4
4
|
|
|
5
|
+
@genType
|
|
6
|
+
type blockEvent = Internal.blockEvent
|
|
7
|
+
|
|
8
|
+
@genType
|
|
9
|
+
type onBlockArgs<'context> = {
|
|
10
|
+
block: blockEvent,
|
|
11
|
+
context: 'context,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@genType
|
|
15
|
+
type onBlockOptions<'chain> = {
|
|
16
|
+
name: string,
|
|
17
|
+
chain: 'chain,
|
|
18
|
+
interval?: int,
|
|
19
|
+
startBlock?: int,
|
|
20
|
+
endBlock?: int,
|
|
21
|
+
}
|
|
22
|
+
|
|
5
23
|
@genType.import(("./Types.ts", "Logger"))
|
|
6
24
|
type logger = {
|
|
7
25
|
debug: 'params. (string, ~params: {..} as 'params=?) => unit,
|
package/src/EventRegister.res
CHANGED
|
@@ -1,3 +1,141 @@
|
|
|
1
|
+
type registrations = {onBlockByChainId: dict<array<Internal.onBlockConfig>>}
|
|
2
|
+
|
|
3
|
+
type activeRegistration = {
|
|
4
|
+
ecosystem: InternalConfig.ecosystem,
|
|
5
|
+
multichain: InternalConfig.multichain,
|
|
6
|
+
preloadHandlers: bool,
|
|
7
|
+
registrations: registrations,
|
|
8
|
+
mutable finished: bool,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let activeRegistration = ref(None)
|
|
12
|
+
|
|
13
|
+
// Might happen for tests when the handler file
|
|
14
|
+
// is imported by a non-envio process (eg mocha)
|
|
15
|
+
// and initialized before we started registration.
|
|
16
|
+
// So we track them here to register when the startRegistration is called.
|
|
17
|
+
// Theoretically we could keep preRegistration without an explicit start
|
|
18
|
+
// but I want it to be this way, so for the actual indexer run
|
|
19
|
+
// an error is thrown with the exact stack trace where the handler was registered.
|
|
20
|
+
let preRegistered = []
|
|
21
|
+
|
|
22
|
+
let withRegistration = (fn: activeRegistration => unit) => {
|
|
23
|
+
switch activeRegistration.contents {
|
|
24
|
+
| None => preRegistered->Belt.Array.push(fn)
|
|
25
|
+
| Some(r) =>
|
|
26
|
+
if r.finished {
|
|
27
|
+
Js.Exn.raiseError(
|
|
28
|
+
"The indexer finished initializing, so no more handlers can be registered. Make sure the handlers are registered on the top level of the file.",
|
|
29
|
+
)
|
|
30
|
+
} else {
|
|
31
|
+
fn(r)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let startRegistration = (~ecosystem, ~multichain, ~preloadHandlers) => {
|
|
37
|
+
let r = {
|
|
38
|
+
ecosystem,
|
|
39
|
+
multichain,
|
|
40
|
+
preloadHandlers,
|
|
41
|
+
registrations: {
|
|
42
|
+
onBlockByChainId: Js.Dict.empty(),
|
|
43
|
+
},
|
|
44
|
+
finished: false,
|
|
45
|
+
}
|
|
46
|
+
activeRegistration.contents = Some(r)
|
|
47
|
+
while preRegistered->Js.Array2.length > 0 {
|
|
48
|
+
// Loop + cleanup in one go
|
|
49
|
+
switch preRegistered->Js.Array2.pop {
|
|
50
|
+
| Some(fn) => fn(r)
|
|
51
|
+
| None => ()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let finishRegistration = () => {
|
|
57
|
+
switch activeRegistration.contents {
|
|
58
|
+
| Some(r) => {
|
|
59
|
+
r.finished = true
|
|
60
|
+
r.registrations
|
|
61
|
+
}
|
|
62
|
+
| None =>
|
|
63
|
+
Js.Exn.raiseError("The indexer has not started registering handlers, so can't finish it.")
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let onBlockOptionsSchema = S.schema(s =>
|
|
68
|
+
{
|
|
69
|
+
"name": s.matches(S.string),
|
|
70
|
+
"chain": s.matches(S.int),
|
|
71
|
+
"interval": s.matches(S.option(S.int->S.intMin(1))->S.Option.getOr(1)),
|
|
72
|
+
"startBlock": s.matches(S.option(S.int)),
|
|
73
|
+
"endBlock": s.matches(S.option(S.int)),
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
let onBlock = (rawOptions: unknown, handler: Internal.onBlockArgs => promise<unit>) => {
|
|
78
|
+
withRegistration(registration => {
|
|
79
|
+
// There's no big reason for this. It's just more work
|
|
80
|
+
switch registration.ecosystem {
|
|
81
|
+
| Evm => ()
|
|
82
|
+
| Fuel =>
|
|
83
|
+
Js.Exn.raiseError(
|
|
84
|
+
"Block Handlers are not supported for non-EVM ecosystems. Please reach out to the Envio team if you need this feature.",
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
// We need to get timestamp for ordered multichain mode
|
|
88
|
+
switch registration.multichain {
|
|
89
|
+
| Unordered => ()
|
|
90
|
+
| Ordered =>
|
|
91
|
+
Js.Exn.raiseError(
|
|
92
|
+
"Block Handlers are not supported for ordered multichain mode. Please reach out to the Envio team if you need this feature or enable unordered multichain mode with `unordered_multichain_mode: true` in your config.",
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
// So we encourage users to upgrade to preload optimization
|
|
96
|
+
// otherwise block handlers will be extremely slow
|
|
97
|
+
switch registration.preloadHandlers {
|
|
98
|
+
| true => ()
|
|
99
|
+
| false =>
|
|
100
|
+
Js.Exn.raiseError(
|
|
101
|
+
"Block Handlers require the Preload Optimization feature. Enable it by setting the `preload_handlers` option to `true` in your config.",
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let options = rawOptions->S.parseOrThrow(onBlockOptionsSchema)
|
|
106
|
+
let chainId = switch options["chain"] {
|
|
107
|
+
| chainId => chainId
|
|
108
|
+
// Dmitry: I want to add names for chains in the future
|
|
109
|
+
// and to be able to use them as a lookup.
|
|
110
|
+
// To do so, we'll need to pass a config during reigstration
|
|
111
|
+
// instead of isInitialized check.
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let onBlockByChainId = registration.registrations.onBlockByChainId
|
|
115
|
+
|
|
116
|
+
switch onBlockByChainId->Utils.Dict.dangerouslyGetNonOption(chainId->Belt.Int.toString) {
|
|
117
|
+
| None =>
|
|
118
|
+
onBlockByChainId->Utils.Dict.setByInt(
|
|
119
|
+
chainId,
|
|
120
|
+
[
|
|
121
|
+
(
|
|
122
|
+
{
|
|
123
|
+
index: 0,
|
|
124
|
+
name: options["name"],
|
|
125
|
+
startBlock: options["startBlock"],
|
|
126
|
+
endBlock: options["endBlock"],
|
|
127
|
+
interval: options["interval"],
|
|
128
|
+
chainId,
|
|
129
|
+
handler,
|
|
130
|
+
}: Internal.onBlockConfig
|
|
131
|
+
),
|
|
132
|
+
],
|
|
133
|
+
)
|
|
134
|
+
| Some(_) => Js.Exn.raiseError("Currently only one onBlock handler per chain is supported")
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
1
139
|
type t = {
|
|
2
140
|
contractName: string,
|
|
3
141
|
eventName: string,
|
|
@@ -54,39 +192,43 @@ let setEventOptions = (t: t, ~eventOptions, ~logger=Logging.getLogger()) => {
|
|
|
54
192
|
}
|
|
55
193
|
|
|
56
194
|
let setHandler = (t: t, handler, ~eventOptions, ~logger=Logging.getLogger()) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
handler
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
195
|
+
withRegistration(_ => {
|
|
196
|
+
switch t.handler {
|
|
197
|
+
| None =>
|
|
198
|
+
t.handler =
|
|
199
|
+
handler
|
|
200
|
+
->(Utils.magic: Internal.genericHandler<'args> => Internal.handler)
|
|
201
|
+
->Some
|
|
202
|
+
| Some(_) =>
|
|
203
|
+
let eventNamespace = {contractName: t.contractName, eventName: t.eventName}
|
|
204
|
+
DuplicateEventRegistration(eventNamespace)->ErrorHandling.mkLogAndRaise(
|
|
205
|
+
~logger=Logging.createChildFrom(~logger, ~params=eventNamespace),
|
|
206
|
+
~msg="Duplicate registration of event handlers not allowed",
|
|
207
|
+
)
|
|
208
|
+
}
|
|
70
209
|
|
|
71
|
-
|
|
210
|
+
t->setEventOptions(~eventOptions, ~logger)
|
|
211
|
+
})
|
|
72
212
|
}
|
|
73
213
|
|
|
74
214
|
let setContractRegister = (t: t, contractRegister, ~eventOptions, ~logger=Logging.getLogger()) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
contractRegister
|
|
79
|
-
|
|
80
|
-
Internal.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
215
|
+
withRegistration(_ => {
|
|
216
|
+
switch t.contractRegister {
|
|
217
|
+
| None =>
|
|
218
|
+
t.contractRegister = Some(
|
|
219
|
+
contractRegister->(
|
|
220
|
+
Utils.magic: Internal.genericContractRegister<
|
|
221
|
+
Internal.genericContractRegisterArgs<'event, 'context>,
|
|
222
|
+
> => Internal.contractRegister
|
|
223
|
+
),
|
|
224
|
+
)
|
|
225
|
+
| Some(_) =>
|
|
226
|
+
let eventNamespace = {contractName: t.contractName, eventName: t.eventName}
|
|
227
|
+
DuplicateEventRegistration(eventNamespace)->ErrorHandling.mkLogAndRaise(
|
|
228
|
+
~logger=Logging.createChildFrom(~logger, ~params=eventNamespace),
|
|
229
|
+
~msg="Duplicate contractRegister handlers not allowed",
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
t->setEventOptions(~eventOptions, ~logger)
|
|
233
|
+
})
|
|
92
234
|
}
|
package/src/EventRegister.res.js
CHANGED
|
@@ -1,10 +1,108 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var Js_exn = require("rescript/lib/js/js_exn.js");
|
|
4
5
|
var Logging = require("./Logging.res.js");
|
|
5
6
|
var Belt_Option = require("rescript/lib/js/belt_Option.js");
|
|
6
7
|
var ErrorHandling = require("./ErrorHandling.res.js");
|
|
7
8
|
var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
|
|
9
|
+
var S$RescriptSchema = require("rescript-schema/src/S.res.js");
|
|
10
|
+
|
|
11
|
+
var activeRegistration = {
|
|
12
|
+
contents: undefined
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
var preRegistered = [];
|
|
16
|
+
|
|
17
|
+
function withRegistration(fn) {
|
|
18
|
+
var r = activeRegistration.contents;
|
|
19
|
+
if (r !== undefined) {
|
|
20
|
+
if (r.finished) {
|
|
21
|
+
return Js_exn.raiseError("The indexer finished initializing, so no more handlers can be registered. Make sure the handlers are registered on the top level of the file.");
|
|
22
|
+
} else {
|
|
23
|
+
return fn(r);
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
preRegistered.push(fn);
|
|
27
|
+
return ;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function startRegistration(ecosystem, multichain, preloadHandlers) {
|
|
32
|
+
var r = {
|
|
33
|
+
ecosystem: ecosystem,
|
|
34
|
+
multichain: multichain,
|
|
35
|
+
preloadHandlers: preloadHandlers,
|
|
36
|
+
registrations: {
|
|
37
|
+
onBlockByChainId: {}
|
|
38
|
+
},
|
|
39
|
+
finished: false
|
|
40
|
+
};
|
|
41
|
+
activeRegistration.contents = r;
|
|
42
|
+
while(preRegistered.length > 0) {
|
|
43
|
+
var fn = preRegistered.pop();
|
|
44
|
+
if (fn !== undefined) {
|
|
45
|
+
fn(r);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function finishRegistration() {
|
|
52
|
+
var r = activeRegistration.contents;
|
|
53
|
+
if (r !== undefined) {
|
|
54
|
+
r.finished = true;
|
|
55
|
+
return r.registrations;
|
|
56
|
+
} else {
|
|
57
|
+
return Js_exn.raiseError("The indexer has not started registering handlers, so can't finish it.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var onBlockOptionsSchema = S$RescriptSchema.schema(function (s) {
|
|
62
|
+
return {
|
|
63
|
+
name: s.m(S$RescriptSchema.string),
|
|
64
|
+
chain: s.m(S$RescriptSchema.$$int),
|
|
65
|
+
interval: s.m(S$RescriptSchema.$$Option.getOr(S$RescriptSchema.option(S$RescriptSchema.intMin(S$RescriptSchema.$$int, 1, undefined)), 1)),
|
|
66
|
+
startBlock: s.m(S$RescriptSchema.option(S$RescriptSchema.$$int)),
|
|
67
|
+
endBlock: s.m(S$RescriptSchema.option(S$RescriptSchema.$$int))
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
function onBlock(rawOptions, handler) {
|
|
72
|
+
withRegistration(function (registration) {
|
|
73
|
+
var match = registration.ecosystem;
|
|
74
|
+
if (match !== "evm") {
|
|
75
|
+
Js_exn.raiseError("Block Handlers are not supported for non-EVM ecosystems. Please reach out to the Envio team if you need this feature.");
|
|
76
|
+
}
|
|
77
|
+
var match$1 = registration.multichain;
|
|
78
|
+
if (match$1 === "ordered") {
|
|
79
|
+
Js_exn.raiseError("Block Handlers are not supported for ordered multichain mode. Please reach out to the Envio team if you need this feature or enable unordered multichain mode with `unordered_multichain_mode: true` in your config.");
|
|
80
|
+
}
|
|
81
|
+
if (registration.preloadHandlers) {
|
|
82
|
+
|
|
83
|
+
} else {
|
|
84
|
+
Js_exn.raiseError("Block Handlers require the Preload Optimization feature. Enable it by setting the `preload_handlers` option to `true` in your config.");
|
|
85
|
+
}
|
|
86
|
+
var options = S$RescriptSchema.parseOrThrow(rawOptions, onBlockOptionsSchema);
|
|
87
|
+
var chainId = options.chain;
|
|
88
|
+
var onBlockByChainId = registration.registrations.onBlockByChainId;
|
|
89
|
+
var match$2 = onBlockByChainId[String(chainId)];
|
|
90
|
+
if (match$2 !== undefined) {
|
|
91
|
+
return Js_exn.raiseError("Currently only one onBlock handler per chain is supported");
|
|
92
|
+
} else {
|
|
93
|
+
onBlockByChainId[chainId] = [{
|
|
94
|
+
index: 0,
|
|
95
|
+
name: options.name,
|
|
96
|
+
chainId: chainId,
|
|
97
|
+
startBlock: options.startBlock,
|
|
98
|
+
endBlock: options.endBlock,
|
|
99
|
+
interval: options.interval,
|
|
100
|
+
handler: handler
|
|
101
|
+
}];
|
|
102
|
+
return ;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
8
106
|
|
|
9
107
|
function getHandler(t) {
|
|
10
108
|
return t.handler;
|
|
@@ -75,44 +173,50 @@ function setEventOptions(t, eventOptions, loggerOpt) {
|
|
|
75
173
|
|
|
76
174
|
function setHandler(t, handler, eventOptions, loggerOpt) {
|
|
77
175
|
var logger = loggerOpt !== undefined ? loggerOpt : Logging.getLogger();
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
176
|
+
withRegistration(function (param) {
|
|
177
|
+
var match = t.handler;
|
|
178
|
+
if (match !== undefined) {
|
|
179
|
+
var eventNamespace_contractName = t.contractName;
|
|
180
|
+
var eventNamespace_eventName = t.eventName;
|
|
181
|
+
var eventNamespace = {
|
|
182
|
+
contractName: eventNamespace_contractName,
|
|
183
|
+
eventName: eventNamespace_eventName
|
|
184
|
+
};
|
|
185
|
+
ErrorHandling.mkLogAndRaise(Logging.createChildFrom(logger, eventNamespace), "Duplicate registration of event handlers not allowed", {
|
|
186
|
+
RE_EXN_ID: DuplicateEventRegistration,
|
|
187
|
+
_1: eventNamespace
|
|
188
|
+
});
|
|
189
|
+
} else {
|
|
190
|
+
t.handler = handler;
|
|
191
|
+
}
|
|
192
|
+
setEventOptions(t, eventOptions, logger);
|
|
193
|
+
});
|
|
94
194
|
}
|
|
95
195
|
|
|
96
196
|
function setContractRegister(t, contractRegister, eventOptions, loggerOpt) {
|
|
97
197
|
var logger = loggerOpt !== undefined ? loggerOpt : Logging.getLogger();
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
198
|
+
withRegistration(function (param) {
|
|
199
|
+
var match = t.contractRegister;
|
|
200
|
+
if (match !== undefined) {
|
|
201
|
+
var eventNamespace_contractName = t.contractName;
|
|
202
|
+
var eventNamespace_eventName = t.eventName;
|
|
203
|
+
var eventNamespace = {
|
|
204
|
+
contractName: eventNamespace_contractName,
|
|
205
|
+
eventName: eventNamespace_eventName
|
|
206
|
+
};
|
|
207
|
+
ErrorHandling.mkLogAndRaise(Logging.createChildFrom(logger, eventNamespace), "Duplicate contractRegister handlers not allowed", {
|
|
208
|
+
RE_EXN_ID: DuplicateEventRegistration,
|
|
209
|
+
_1: eventNamespace
|
|
210
|
+
});
|
|
211
|
+
} else {
|
|
212
|
+
t.contractRegister = contractRegister;
|
|
213
|
+
}
|
|
214
|
+
setEventOptions(t, eventOptions, logger);
|
|
215
|
+
});
|
|
114
216
|
}
|
|
115
217
|
|
|
218
|
+
exports.startRegistration = startRegistration;
|
|
219
|
+
exports.finishRegistration = finishRegistration;
|
|
116
220
|
exports.make = make;
|
|
117
221
|
exports.setHandler = setHandler;
|
|
118
222
|
exports.setContractRegister = setContractRegister;
|
|
@@ -121,4 +225,5 @@ exports.getContractRegister = getContractRegister;
|
|
|
121
225
|
exports.getEventFilters = getEventFilters;
|
|
122
226
|
exports.isWildcard = isWildcard;
|
|
123
227
|
exports.hasRegistration = hasRegistration;
|
|
124
|
-
|
|
228
|
+
exports.onBlock = onBlock;
|
|
229
|
+
/* onBlockOptionsSchema Not a pure module */
|
package/src/EventRegister.resi
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
type registrations = {onBlockByChainId: dict<array<Internal.onBlockConfig>>}
|
|
2
|
+
|
|
3
|
+
let startRegistration: (
|
|
4
|
+
~ecosystem: InternalConfig.ecosystem,
|
|
5
|
+
~multichain: InternalConfig.multichain,
|
|
6
|
+
~preloadHandlers: bool,
|
|
7
|
+
) => unit
|
|
8
|
+
let finishRegistration: unit => registrations
|
|
9
|
+
|
|
1
10
|
type t
|
|
2
11
|
let make: (~contractName: string, ~eventName: string) => t
|
|
3
12
|
let setHandler: (
|
|
@@ -19,3 +28,5 @@ let getContractRegister: t => option<Internal.contractRegister>
|
|
|
19
28
|
let getEventFilters: t => option<Js.Json.t>
|
|
20
29
|
let isWildcard: t => bool
|
|
21
30
|
let hasRegistration: t => bool
|
|
31
|
+
|
|
32
|
+
let onBlock: (unknown, Internal.onBlockArgs => promise<unit>) => unit
|