envio 2.29.0-alpha.1 → 2.29.0-alpha.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envio",
3
- "version": "v2.29.0-alpha.1",
3
+ "version": "v2.29.0-alpha.3",
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,19 +25,21 @@
25
25
  },
26
26
  "homepage": "https://envio.dev",
27
27
  "optionalDependencies": {
28
- "envio-linux-x64": "v2.29.0-alpha.1",
29
- "envio-linux-arm64": "v2.29.0-alpha.1",
30
- "envio-darwin-x64": "v2.29.0-alpha.1",
31
- "envio-darwin-arm64": "v2.29.0-alpha.1"
28
+ "envio-linux-x64": "v2.29.0-alpha.3",
29
+ "envio-linux-arm64": "v2.29.0-alpha.3",
30
+ "envio-darwin-x64": "v2.29.0-alpha.3",
31
+ "envio-darwin-arm64": "v2.29.0-alpha.3"
32
32
  },
33
33
  "dependencies": {
34
34
  "@envio-dev/hypersync-client": "0.6.6",
35
+ "@envio-dev/hyperfuel-client": "1.2.2",
35
36
  "rescript": "11.1.3",
36
37
  "rescript-schema": "9.3.0",
37
38
  "viem": "2.21.0",
38
39
  "bignumber.js": "9.1.2",
39
40
  "pino": "8.16.1",
40
41
  "pino-pretty": "10.2.3",
42
+ "@elastic/ecs-pino-format": "1.4.0",
41
43
  "prom-client": "15.0.0"
42
44
  },
43
45
  "files": [
package/src/Batch.res CHANGED
@@ -58,6 +58,18 @@ let getOrderedNextItem = (fetchStates: ChainMap.t<FetchState.t>): option<
58
58
  })
59
59
  }
60
60
 
61
+ let hasUnorderedNextItem = (fetchStates: ChainMap.t<FetchState.t>) => {
62
+ fetchStates
63
+ ->ChainMap.values
64
+ ->Js.Array2.some(fetchState => {
65
+ fetchState->FetchState.isActivelyIndexing &&
66
+ switch fetchState->FetchState.getEarliestEvent {
67
+ | Item(_) => true
68
+ | NoItem(_) => false
69
+ }
70
+ })
71
+ }
72
+
61
73
  let popOrderedBatchItems = (
62
74
  ~maxBatchSize,
63
75
  ~fetchStates: ChainMap.t<FetchState.t>,
package/src/Batch.res.js CHANGED
@@ -45,6 +45,20 @@ function getOrderedNextItem(fetchStates) {
45
45
  }));
46
46
  }
47
47
 
48
+ function hasUnorderedNextItem(fetchStates) {
49
+ return ChainMap.values(fetchStates).some(function (fetchState) {
50
+ if (!FetchState.isActivelyIndexing(fetchState)) {
51
+ return false;
52
+ }
53
+ var match = FetchState.getEarliestEvent(fetchState);
54
+ if (match.TAG === "Item") {
55
+ return true;
56
+ } else {
57
+ return false;
58
+ }
59
+ });
60
+ }
61
+
48
62
  function popOrderedBatchItems(maxBatchSize, fetchStates, sizePerChain) {
49
63
  var items = [];
50
64
  var loop = function () {
@@ -113,6 +127,7 @@ function popUnorderedBatchItems(maxBatchSize, fetchStates, sizePerChain) {
113
127
  exports.getQueueItemComparitor = getQueueItemComparitor;
114
128
  exports.isQueueItemEarlier = isQueueItemEarlier;
115
129
  exports.getOrderedNextItem = getOrderedNextItem;
130
+ exports.hasUnorderedNextItem = hasUnorderedNextItem;
116
131
  exports.popOrderedBatchItems = popOrderedBatchItems;
117
132
  exports.popUnorderedBatchItems = popUnorderedBatchItems;
118
133
  /* Utils Not a pure module */
package/src/Envio.gen.ts CHANGED
@@ -17,9 +17,13 @@ export type blockEvent = Internal_blockEvent;
17
17
 
18
18
  export type onBlockArgs<context> = { readonly block: blockEvent; readonly context: context };
19
19
 
20
- export type chainReference = number;
21
-
22
- export type onBlockOptions = { readonly name: string; readonly chain: chainReference };
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
+ };
23
27
 
24
28
  export type logger = $$logger;
25
29
 
package/src/Envio.res CHANGED
@@ -11,16 +11,13 @@ type onBlockArgs<'context> = {
11
11
  context: 'context,
12
12
  }
13
13
 
14
- @unboxed
15
- type chainReference = Id(int) // | Name(string)
16
-
17
14
  @genType
18
- type onBlockOptions = {
15
+ type onBlockOptions<'chain> = {
19
16
  name: string,
20
- chain: chainReference,
21
- // interval?: int,
22
- // startBlock?: int,
23
- // endBlock?: int,
17
+ chain: 'chain,
18
+ interval?: int,
19
+ startBlock?: int,
20
+ endBlock?: int,
24
21
  }
25
22
 
26
23
  @genType.import(("./Types.ts", "Logger"))
@@ -10,11 +10,18 @@ type activeRegistration = {
10
10
 
11
11
  let activeRegistration = ref(None)
12
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
+
13
22
  let withRegistration = (fn: activeRegistration => unit) => {
14
23
  switch activeRegistration.contents {
15
- | None => // The file with handlers might run by a non-envio process (eg mocha)
16
- // So we just ignore handlers in this case
17
- ()
24
+ | None => preRegistered->Belt.Array.push(fn)
18
25
  | Some(r) =>
19
26
  if r.finished {
20
27
  Js.Exn.raiseError(
@@ -27,7 +34,7 @@ let withRegistration = (fn: activeRegistration => unit) => {
27
34
  }
28
35
 
29
36
  let startRegistration = (~ecosystem, ~multichain, ~preloadHandlers) => {
30
- activeRegistration.contents = Some({
37
+ let r = {
31
38
  ecosystem,
32
39
  multichain,
33
40
  preloadHandlers,
@@ -35,7 +42,15 @@ let startRegistration = (~ecosystem, ~multichain, ~preloadHandlers) => {
35
42
  onBlockByChainId: Js.Dict.empty(),
36
43
  },
37
44
  finished: false,
38
- })
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
+ }
39
54
  }
40
55
 
41
56
  let finishRegistration = () => {
@@ -49,12 +64,17 @@ let finishRegistration = () => {
49
64
  }
50
65
  }
51
66
 
52
- let onBlockOptionsSchema = S.schema((s): Envio.onBlockOptions => {
53
- name: s.matches(S.string),
54
- chain: Id(s.matches(S.int)),
55
- })
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
+ )
56
76
 
57
- let onBlock = (options: Envio.onBlockOptions, handler: Internal.onBlockArgs => promise<unit>) => {
77
+ let onBlock = (rawOptions: unknown, handler: Internal.onBlockArgs => promise<unit>) => {
58
78
  withRegistration(registration => {
59
79
  // There's no big reason for this. It's just more work
60
80
  switch registration.ecosystem {
@@ -82,9 +102,9 @@ let onBlock = (options: Envio.onBlockOptions, handler: Internal.onBlockArgs => p
82
102
  )
83
103
  }
84
104
 
85
- options->S.assertOrThrow(onBlockOptionsSchema)
86
- let chainId = switch options.chain {
87
- | Id(chainId) => chainId
105
+ let options = rawOptions->S.parseOrThrow(onBlockOptionsSchema)
106
+ let chainId = switch options["chain"] {
107
+ | chainId => chainId
88
108
  // Dmitry: I want to add names for chains in the future
89
109
  // and to be able to use them as a lookup.
90
110
  // To do so, we'll need to pass a config during reigstration
@@ -101,14 +121,30 @@ let onBlock = (options: Envio.onBlockOptions, handler: Internal.onBlockArgs => p
101
121
  (
102
122
  {
103
123
  index: 0,
104
- name: options.name,
124
+ name: options["name"],
125
+ startBlock: options["startBlock"],
126
+ endBlock: options["endBlock"],
127
+ interval: options["interval"],
105
128
  chainId,
106
129
  handler,
107
130
  }: Internal.onBlockConfig
108
131
  ),
109
132
  ],
110
133
  )
111
- | Some(_) => Js.Exn.raiseError("Currently only one onBlock handler per chain is supported")
134
+ | Some(onBlockConfigs) =>
135
+ onBlockConfigs->Belt.Array.push(
136
+ (
137
+ {
138
+ index: onBlockConfigs->Belt.Array.length,
139
+ name: options["name"],
140
+ startBlock: options["startBlock"],
141
+ endBlock: options["endBlock"],
142
+ interval: options["interval"],
143
+ chainId,
144
+ handler,
145
+ }: Internal.onBlockConfig
146
+ ),
147
+ )
112
148
  }
113
149
  })
114
150
  }
@@ -12,6 +12,8 @@ var activeRegistration = {
12
12
  contents: undefined
13
13
  };
14
14
 
15
+ var preRegistered = [];
16
+
15
17
  function withRegistration(fn) {
16
18
  var r = activeRegistration.contents;
17
19
  if (r !== undefined) {
@@ -20,12 +22,14 @@ function withRegistration(fn) {
20
22
  } else {
21
23
  return fn(r);
22
24
  }
25
+ } else {
26
+ preRegistered.push(fn);
27
+ return ;
23
28
  }
24
-
25
29
  }
26
30
 
27
31
  function startRegistration(ecosystem, multichain, preloadHandlers) {
28
- activeRegistration.contents = {
32
+ var r = {
29
33
  ecosystem: ecosystem,
30
34
  multichain: multichain,
31
35
  preloadHandlers: preloadHandlers,
@@ -34,6 +38,14 @@ function startRegistration(ecosystem, multichain, preloadHandlers) {
34
38
  },
35
39
  finished: false
36
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
+ };
37
49
  }
38
50
 
39
51
  function finishRegistration() {
@@ -49,11 +61,14 @@ function finishRegistration() {
49
61
  var onBlockOptionsSchema = S$RescriptSchema.schema(function (s) {
50
62
  return {
51
63
  name: s.m(S$RescriptSchema.string),
52
- chain: s.m(S$RescriptSchema.$$int)
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))
53
68
  };
54
69
  });
55
70
 
56
- function onBlock(options, handler) {
71
+ function onBlock(rawOptions, handler) {
57
72
  withRegistration(function (registration) {
58
73
  var match = registration.ecosystem;
59
74
  if (match !== "evm") {
@@ -68,20 +83,30 @@ function onBlock(options, handler) {
68
83
  } else {
69
84
  Js_exn.raiseError("Block Handlers require the Preload Optimization feature. Enable it by setting the `preload_handlers` option to `true` in your config.");
70
85
  }
71
- S$RescriptSchema.assertOrThrow(options, onBlockOptionsSchema);
86
+ var options = S$RescriptSchema.parseOrThrow(rawOptions, onBlockOptionsSchema);
72
87
  var chainId = options.chain;
73
88
  var onBlockByChainId = registration.registrations.onBlockByChainId;
74
- var match$2 = onBlockByChainId[String(chainId)];
75
- if (match$2 !== undefined) {
76
- return Js_exn.raiseError("Currently only one onBlock handler per chain is supported");
89
+ var onBlockConfigs = onBlockByChainId[String(chainId)];
90
+ if (onBlockConfigs !== undefined) {
91
+ onBlockConfigs.push({
92
+ index: onBlockConfigs.length,
93
+ name: options.name,
94
+ chainId: chainId,
95
+ startBlock: options.startBlock,
96
+ endBlock: options.endBlock,
97
+ interval: options.interval,
98
+ handler: handler
99
+ });
77
100
  } else {
78
101
  onBlockByChainId[chainId] = [{
79
102
  index: 0,
80
103
  name: options.name,
81
104
  chainId: chainId,
105
+ startBlock: options.startBlock,
106
+ endBlock: options.endBlock,
107
+ interval: options.interval,
82
108
  handler: handler
83
109
  }];
84
- return ;
85
110
  }
86
111
  });
87
112
  }
@@ -29,4 +29,4 @@ let getEventFilters: t => option<Js.Json.t>
29
29
  let isWildcard: t => bool
30
30
  let hasRegistration: t => bool
31
31
 
32
- let onBlock: (Envio.onBlockOptions, Internal.onBlockArgs => promise<unit>) => unit
32
+ let onBlock: (unknown, Internal.onBlockArgs => promise<unit>) => unit
@@ -16,6 +16,10 @@ let isEarlier = (item1: (int, int, int, int), item2: (int, int, int, int)) => {
16
16
  item1 < item2
17
17
  }
18
18
 
19
+ let isEarlierUnordered = (item1: (int, int, int), item2: (int, int, int)) => {
20
+ item1 < item2
21
+ }
22
+
19
23
  // type eventIndex = {
20
24
  // blockNumber: int,
21
25
  // logIndex: int,
@@ -20,6 +20,8 @@ function getOrderedBatchItemComparator(item) {
20
20
 
21
21
  var isEarlier = Caml_obj.lessthan;
22
22
 
23
+ var isEarlierUnordered = Caml_obj.lessthan;
24
+
23
25
  function packEventIndex(blockNumber, logIndex) {
24
26
  var blockNumber$1 = BigInt(blockNumber);
25
27
  var logIndex$1 = BigInt(logIndex);
@@ -34,6 +36,7 @@ function getEventIdKeyString(chainId, eventId) {
34
36
 
35
37
  exports.getOrderedBatchItemComparator = getOrderedBatchItemComparator;
36
38
  exports.isEarlier = isEarlier;
39
+ exports.isEarlierUnordered = isEarlierUnordered;
37
40
  exports.packEventIndex = packEventIndex;
38
41
  exports.getEventIdKeyString = getEventIdKeyString;
39
42
  /* BigInt Not a pure module */