envio 3.0.0-alpha.2 → 3.0.0-alpha.21

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.
Files changed (184) hide show
  1. package/README.md +164 -30
  2. package/bin.mjs +49 -0
  3. package/evm.schema.json +79 -169
  4. package/fuel.schema.json +50 -21
  5. package/index.d.ts +578 -1
  6. package/index.js +4 -0
  7. package/package.json +47 -31
  8. package/rescript.json +4 -1
  9. package/src/Batch.res +11 -8
  10. package/src/Batch.res.mjs +11 -9
  11. package/src/ChainFetcher.res +531 -0
  12. package/src/ChainFetcher.res.mjs +339 -0
  13. package/src/ChainManager.res +190 -0
  14. package/src/ChainManager.res.mjs +166 -0
  15. package/src/Change.res +3 -3
  16. package/src/Config.gen.ts +19 -0
  17. package/src/Config.res +725 -25
  18. package/src/Config.res.mjs +692 -26
  19. package/src/{Indexer.res → Ctx.res} +1 -1
  20. package/src/Ecosystem.res +9 -124
  21. package/src/Ecosystem.res.mjs +19 -160
  22. package/src/Env.res +33 -73
  23. package/src/Env.res.mjs +29 -85
  24. package/src/Envio.gen.ts +3 -1
  25. package/src/Envio.res +77 -9
  26. package/src/Envio.res.mjs +39 -1
  27. package/src/EventConfigBuilder.res +408 -0
  28. package/src/EventConfigBuilder.res.mjs +376 -0
  29. package/src/EventProcessing.res +469 -0
  30. package/src/EventProcessing.res.mjs +337 -0
  31. package/src/EvmTypes.gen.ts +6 -0
  32. package/src/EvmTypes.res +1 -0
  33. package/src/FetchState.res +1256 -639
  34. package/src/FetchState.res.mjs +1135 -612
  35. package/src/GlobalState.res +1224 -0
  36. package/src/GlobalState.res.mjs +1291 -0
  37. package/src/GlobalStateManager.res +68 -0
  38. package/src/GlobalStateManager.res.mjs +75 -0
  39. package/src/GlobalStateManager.resi +7 -0
  40. package/src/HandlerLoader.res +89 -0
  41. package/src/HandlerLoader.res.mjs +79 -0
  42. package/src/HandlerRegister.res +357 -0
  43. package/src/HandlerRegister.res.mjs +299 -0
  44. package/src/HandlerRegister.resi +30 -0
  45. package/src/Hasura.res +111 -175
  46. package/src/Hasura.res.mjs +88 -150
  47. package/src/InMemoryStore.res +1 -1
  48. package/src/InMemoryStore.res.mjs +3 -3
  49. package/src/InMemoryTable.res +1 -1
  50. package/src/InMemoryTable.res.mjs +1 -1
  51. package/src/Internal.gen.ts +6 -0
  52. package/src/Internal.res +265 -12
  53. package/src/Internal.res.mjs +115 -1
  54. package/src/LoadLayer.res +444 -0
  55. package/src/LoadLayer.res.mjs +296 -0
  56. package/src/LoadLayer.resi +32 -0
  57. package/src/LogSelection.res +33 -27
  58. package/src/LogSelection.res.mjs +6 -0
  59. package/src/Logging.res +21 -7
  60. package/src/Logging.res.mjs +16 -8
  61. package/src/Main.res +390 -0
  62. package/src/Main.res.mjs +341 -0
  63. package/src/Persistence.res +7 -21
  64. package/src/Persistence.res.mjs +3 -3
  65. package/src/PgStorage.gen.ts +10 -0
  66. package/src/PgStorage.res +116 -69
  67. package/src/PgStorage.res.d.mts +5 -0
  68. package/src/PgStorage.res.mjs +93 -50
  69. package/src/Prometheus.res +294 -224
  70. package/src/Prometheus.res.mjs +353 -340
  71. package/src/ReorgDetection.res +6 -10
  72. package/src/ReorgDetection.res.mjs +6 -6
  73. package/src/SafeCheckpointTracking.res +4 -4
  74. package/src/SafeCheckpointTracking.res.mjs +2 -2
  75. package/src/SimulateItems.res +353 -0
  76. package/src/SimulateItems.res.mjs +335 -0
  77. package/src/Sink.res +4 -2
  78. package/src/Sink.res.mjs +2 -1
  79. package/src/TableIndices.res +0 -1
  80. package/src/TestIndexer.res +913 -0
  81. package/src/TestIndexer.res.mjs +698 -0
  82. package/src/TestIndexerProxyStorage.res +205 -0
  83. package/src/TestIndexerProxyStorage.res.mjs +151 -0
  84. package/src/TopicFilter.res +1 -1
  85. package/src/Types.ts +1 -1
  86. package/src/UserContext.res +424 -0
  87. package/src/UserContext.res.mjs +279 -0
  88. package/src/Utils.res +97 -26
  89. package/src/Utils.res.mjs +91 -44
  90. package/src/bindings/BigInt.res +10 -0
  91. package/src/bindings/BigInt.res.mjs +15 -0
  92. package/src/bindings/ClickHouse.res +120 -23
  93. package/src/bindings/ClickHouse.res.mjs +118 -28
  94. package/src/bindings/DateFns.res +74 -0
  95. package/src/bindings/DateFns.res.mjs +22 -0
  96. package/src/bindings/EventSource.res +11 -2
  97. package/src/bindings/EventSource.res.mjs +8 -1
  98. package/src/bindings/Express.res +1 -0
  99. package/src/bindings/Hrtime.res +14 -1
  100. package/src/bindings/Hrtime.res.mjs +22 -2
  101. package/src/bindings/Hrtime.resi +4 -0
  102. package/src/bindings/Lodash.res +0 -1
  103. package/src/bindings/NodeJs.res +49 -3
  104. package/src/bindings/NodeJs.res.mjs +11 -3
  105. package/src/bindings/Pino.res +24 -10
  106. package/src/bindings/Pino.res.mjs +14 -8
  107. package/src/bindings/Postgres.gen.ts +8 -0
  108. package/src/bindings/Postgres.res +5 -1
  109. package/src/bindings/Postgres.res.d.mts +5 -0
  110. package/src/bindings/PromClient.res +0 -10
  111. package/src/bindings/PromClient.res.mjs +0 -3
  112. package/src/bindings/Vitest.res +144 -0
  113. package/src/bindings/Vitest.res.mjs +9 -0
  114. package/src/bindings/WebSocket.res +27 -0
  115. package/src/bindings/WebSocket.res.mjs +2 -0
  116. package/src/bindings/Yargs.res +8 -0
  117. package/src/bindings/Yargs.res.mjs +2 -0
  118. package/src/db/EntityHistory.res +7 -7
  119. package/src/db/EntityHistory.res.mjs +9 -9
  120. package/src/db/InternalTable.res +59 -111
  121. package/src/db/InternalTable.res.mjs +73 -104
  122. package/src/db/Table.res +27 -8
  123. package/src/db/Table.res.mjs +25 -14
  124. package/src/sources/Evm.res +84 -0
  125. package/src/sources/Evm.res.mjs +105 -0
  126. package/src/sources/EvmChain.res +94 -0
  127. package/src/sources/EvmChain.res.mjs +60 -0
  128. package/src/sources/Fuel.res +19 -34
  129. package/src/sources/Fuel.res.mjs +34 -16
  130. package/src/sources/FuelSDK.res +38 -0
  131. package/src/sources/FuelSDK.res.mjs +29 -0
  132. package/src/sources/HyperFuel.res +2 -2
  133. package/src/sources/HyperFuel.resi +1 -1
  134. package/src/sources/HyperFuelClient.res +2 -2
  135. package/src/sources/HyperFuelSource.res +35 -13
  136. package/src/sources/HyperFuelSource.res.mjs +26 -16
  137. package/src/sources/HyperSync.res +61 -60
  138. package/src/sources/HyperSync.res.mjs +53 -67
  139. package/src/sources/HyperSync.resi +6 -4
  140. package/src/sources/HyperSyncClient.res +29 -2
  141. package/src/sources/HyperSyncClient.res.mjs +9 -0
  142. package/src/sources/HyperSyncHeightStream.res +76 -118
  143. package/src/sources/HyperSyncHeightStream.res.mjs +68 -75
  144. package/src/sources/HyperSyncSource.res +122 -143
  145. package/src/sources/HyperSyncSource.res.mjs +106 -121
  146. package/src/sources/Rpc.res +86 -14
  147. package/src/sources/Rpc.res.mjs +101 -9
  148. package/src/sources/RpcSource.res +731 -364
  149. package/src/sources/RpcSource.res.mjs +845 -410
  150. package/src/sources/RpcWebSocketHeightStream.res +181 -0
  151. package/src/sources/RpcWebSocketHeightStream.res.mjs +196 -0
  152. package/src/sources/SimulateSource.res +59 -0
  153. package/src/sources/SimulateSource.res.mjs +50 -0
  154. package/src/sources/Source.res +7 -5
  155. package/src/sources/SourceManager.res +358 -221
  156. package/src/sources/SourceManager.res.mjs +346 -171
  157. package/src/sources/SourceManager.resi +17 -6
  158. package/src/sources/Svm.res +81 -0
  159. package/src/sources/Svm.res.mjs +90 -0
  160. package/src/tui/Tui.res +247 -0
  161. package/src/tui/Tui.res.mjs +337 -0
  162. package/src/tui/bindings/Ink.res +371 -0
  163. package/src/tui/bindings/Ink.res.mjs +72 -0
  164. package/src/tui/bindings/Style.res +123 -0
  165. package/src/tui/bindings/Style.res.mjs +2 -0
  166. package/src/tui/components/BufferedProgressBar.res +40 -0
  167. package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
  168. package/src/tui/components/CustomHooks.res +122 -0
  169. package/src/tui/components/CustomHooks.res.mjs +179 -0
  170. package/src/tui/components/Messages.res +41 -0
  171. package/src/tui/components/Messages.res.mjs +75 -0
  172. package/src/tui/components/SyncETA.res +174 -0
  173. package/src/tui/components/SyncETA.res.mjs +263 -0
  174. package/src/tui/components/TuiData.res +47 -0
  175. package/src/tui/components/TuiData.res.mjs +34 -0
  176. package/svm.schema.json +112 -0
  177. package/bin.js +0 -48
  178. package/src/EventRegister.res +0 -241
  179. package/src/EventRegister.res.mjs +0 -240
  180. package/src/EventRegister.resi +0 -30
  181. package/src/bindings/Ethers.gen.ts +0 -14
  182. package/src/bindings/Ethers.res +0 -204
  183. package/src/bindings/Ethers.res.mjs +0 -130
  184. /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
@@ -0,0 +1,181 @@
1
+ /*
2
+ WebSocket-based implementation for real-time block height tracking.
3
+ Uses eth_subscribe("newHeads") for low-latency block detection.
4
+ Falls back behavior is handled by SourceManager when subscription fails.
5
+ */
6
+
7
+ let retryCount = 9
8
+ let baseDuration = 125
9
+ // Close and reconnect if no new block head arrives within this period.
10
+ // Detects silently dropped server-side subscriptions.
11
+ let staleTimeMillis = 60_000
12
+
13
+ type wsMessage =
14
+ | NewHead(int)
15
+ | SubscriptionConfirmed(string)
16
+ | ErrorResponse
17
+
18
+ let subscribeRequestJson =
19
+ {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
20
+ ->(Utils.magic: {
21
+ "jsonrpc": string,
22
+ "id": int,
23
+ "method": string,
24
+ "params": array<string>,
25
+ } => Js.Json.t)
26
+ ->Js.Json.serializeExn
27
+
28
+ let wsMessageSchema = S.union([
29
+ S.object(s => {
30
+ let _ = s.field("method", S.literal("eth_subscription"))
31
+ NewHead(
32
+ s.field(
33
+ "params",
34
+ S.object(s => {
35
+ s.field(
36
+ "result",
37
+ S.object(
38
+ s => {
39
+ s.field("number", Rpc.hexIntSchema)
40
+ },
41
+ ),
42
+ )
43
+ }),
44
+ ),
45
+ )
46
+ }),
47
+ S.object(s => {
48
+ SubscriptionConfirmed(s.field("result", S.string))
49
+ }),
50
+ S.object(s => {
51
+ let _ = s.field("error", S.unknown)
52
+ ErrorResponse
53
+ }),
54
+ ])
55
+
56
+ let subscribe = (~wsUrl, ~chainId, ~onHeight: int => unit): (unit => unit) => {
57
+ let wsRef: ref<option<WebSocket.t>> = ref(None)
58
+ let isUnsubscribed = ref(false)
59
+ let errorCount = ref(0)
60
+ let staleTimeoutId: ref<option<Js.Global.timeoutId>> = ref(None)
61
+
62
+ let clearStaleTimeout = () => {
63
+ switch staleTimeoutId.contents {
64
+ | Some(id) =>
65
+ Js.Global.clearTimeout(id)
66
+ staleTimeoutId := None
67
+ | None => ()
68
+ }
69
+ }
70
+
71
+ let resetStaleTimeout = () => {
72
+ clearStaleTimeout()
73
+ staleTimeoutId := Some(Js.Global.setTimeout(() => {
74
+ // Connection went stale - close to trigger reconnect
75
+ switch wsRef.contents {
76
+ | Some(ws) => ws->WebSocket.close
77
+ | None => ()
78
+ }
79
+ }, staleTimeMillis))
80
+ }
81
+
82
+ let rec scheduleReconnect = () => {
83
+ if !isUnsubscribed.contents && errorCount.contents < retryCount {
84
+ let duration =
85
+ baseDuration *
86
+ Js.Math.pow_float(~base=2.0, ~exp=errorCount.contents->Belt.Int.toFloat)->Belt.Float.toInt
87
+ let _ = Js.Global.setTimeout(() => {
88
+ if !isUnsubscribed.contents {
89
+ startConnection()
90
+ }
91
+ }, duration)
92
+ }
93
+ }
94
+ and startConnection = () => {
95
+ if isUnsubscribed.contents || errorCount.contents >= retryCount {
96
+ ()
97
+ } else {
98
+ let ws = WebSocket.create(wsUrl)
99
+ wsRef := Some(ws)
100
+
101
+ ws->WebSocket.onopen(() => {
102
+ ws->WebSocket.send(subscribeRequestJson)
103
+ resetStaleTimeout()
104
+ })
105
+
106
+ ws->WebSocket.onmessage(event => {
107
+ try {
108
+ switch event.data->Js.Json.parseExn->S.parseOrThrow(wsMessageSchema) {
109
+ | NewHead(blockNumber) =>
110
+ errorCount := 0
111
+ resetStaleTimeout()
112
+ Prometheus.SourceRequestCount.increment(
113
+ ~sourceName="WebSocket",
114
+ ~chainId,
115
+ ~method="eth_subscribe",
116
+ )
117
+ onHeight(blockNumber)
118
+ | SubscriptionConfirmed(_) => resetStaleTimeout()
119
+ | ErrorResponse =>
120
+ if errorCount.contents < retryCount {
121
+ errorCount := errorCount.contents + 1
122
+ }
123
+ switch wsRef.contents {
124
+ | Some(ws) => ws->WebSocket.close
125
+ | None => ()
126
+ }
127
+ }
128
+ } catch {
129
+ | S.Raised(_) =>
130
+ Logging.warn({
131
+ "msg": "WebSocket height stream received unrecognized message",
132
+ "chainId": chainId,
133
+ "data": event.data,
134
+ })
135
+ | Js.Exn.Error(_) as e =>
136
+ Logging.warn({
137
+ "msg": "WebSocket height stream failed to parse message",
138
+ "chainId": chainId,
139
+ "err": e->Utils.prettifyExn,
140
+ "data": event.data,
141
+ })
142
+ | e =>
143
+ Logging.error({
144
+ "msg": "Unexpected error in WebSocket height stream message handler",
145
+ "chainId": chainId,
146
+ "err": e->Utils.prettifyExn,
147
+ "data": event.data,
148
+ })
149
+ raise(e)
150
+ }
151
+ })
152
+
153
+ ws->WebSocket.onerror(_error => {
154
+ if errorCount.contents < retryCount {
155
+ errorCount := errorCount.contents + 1
156
+ }
157
+ switch wsRef.contents {
158
+ | Some(ws) if ws->WebSocket.readyState === Open => ws->WebSocket.close
159
+ | _ => ()
160
+ }
161
+ })
162
+
163
+ ws->WebSocket.onclose(() => {
164
+ wsRef := None
165
+ clearStaleTimeout()
166
+ scheduleReconnect()
167
+ })
168
+ }
169
+ }
170
+
171
+ startConnection()
172
+
173
+ () => {
174
+ isUnsubscribed := true
175
+ clearStaleTimeout()
176
+ switch wsRef.contents {
177
+ | Some(ws) => ws->WebSocket.close
178
+ | None => ()
179
+ }
180
+ }
181
+ }
@@ -0,0 +1,196 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Rpc from "./Rpc.res.mjs";
4
+ import * as Utils from "../Utils.res.mjs";
5
+ import * as Js_exn from "rescript/lib/es6/js_exn.js";
6
+ import * as Js_json from "rescript/lib/es6/js_json.js";
7
+ import * as Logging from "../Logging.res.mjs";
8
+ import * as Prometheus from "../Prometheus.res.mjs";
9
+ import * as Caml_option from "rescript/lib/es6/caml_option.js";
10
+ import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
11
+ import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
12
+
13
+ var subscribeRequestJson = Js_json.serializeExn({
14
+ jsonrpc: "2.0",
15
+ id: 1,
16
+ method: "eth_subscribe",
17
+ params: ["newHeads"]
18
+ });
19
+
20
+ var wsMessageSchema = S$RescriptSchema.union([
21
+ S$RescriptSchema.object(function (s) {
22
+ s.f("method", S$RescriptSchema.literal("eth_subscription"));
23
+ return {
24
+ TAG: "NewHead",
25
+ _0: s.f("params", S$RescriptSchema.object(function (s) {
26
+ return s.f("result", S$RescriptSchema.object(function (s) {
27
+ return s.f("number", Rpc.hexIntSchema);
28
+ }));
29
+ }))
30
+ };
31
+ }),
32
+ S$RescriptSchema.object(function (s) {
33
+ return {
34
+ TAG: "SubscriptionConfirmed",
35
+ _0: s.f("result", S$RescriptSchema.string)
36
+ };
37
+ }),
38
+ S$RescriptSchema.object(function (s) {
39
+ s.f("error", S$RescriptSchema.unknown);
40
+ return "ErrorResponse";
41
+ })
42
+ ]);
43
+
44
+ function subscribe(wsUrl, chainId, onHeight) {
45
+ var wsRef = {
46
+ contents: undefined
47
+ };
48
+ var isUnsubscribed = {
49
+ contents: false
50
+ };
51
+ var errorCount = {
52
+ contents: 0
53
+ };
54
+ var staleTimeoutId = {
55
+ contents: undefined
56
+ };
57
+ var clearStaleTimeout = function () {
58
+ var id = staleTimeoutId.contents;
59
+ if (id !== undefined) {
60
+ clearTimeout(Caml_option.valFromOption(id));
61
+ staleTimeoutId.contents = undefined;
62
+ return ;
63
+ }
64
+
65
+ };
66
+ var resetStaleTimeout = function () {
67
+ clearStaleTimeout();
68
+ staleTimeoutId.contents = Caml_option.some(setTimeout((function () {
69
+ var ws = wsRef.contents;
70
+ if (ws !== undefined) {
71
+ Caml_option.valFromOption(ws).close();
72
+ return ;
73
+ }
74
+
75
+ }), 60000));
76
+ };
77
+ var scheduleReconnect = function () {
78
+ if (!(!isUnsubscribed.contents && errorCount.contents < 9)) {
79
+ return ;
80
+ }
81
+ var duration = Math.imul(125, Math.pow(2.0, errorCount.contents) | 0);
82
+ setTimeout((function () {
83
+ if (!isUnsubscribed.contents) {
84
+ return startConnection();
85
+ }
86
+
87
+ }), duration);
88
+ };
89
+ var startConnection = function () {
90
+ if (isUnsubscribed.contents || errorCount.contents >= 9) {
91
+ return ;
92
+ }
93
+ var ws = new WebSocket(wsUrl);
94
+ wsRef.contents = Caml_option.some(ws);
95
+ ws.onopen = (function () {
96
+ ws.send(subscribeRequestJson);
97
+ resetStaleTimeout();
98
+ });
99
+ ws.onmessage = (function ($$event) {
100
+ try {
101
+ var blockNumber = S$RescriptSchema.parseOrThrow(JSON.parse($$event.data), wsMessageSchema);
102
+ if (typeof blockNumber !== "object") {
103
+ if (errorCount.contents < 9) {
104
+ errorCount.contents = errorCount.contents + 1 | 0;
105
+ }
106
+ var ws = wsRef.contents;
107
+ if (ws !== undefined) {
108
+ Caml_option.valFromOption(ws).close();
109
+ return ;
110
+ } else {
111
+ return ;
112
+ }
113
+ }
114
+ if (blockNumber.TAG !== "NewHead") {
115
+ return resetStaleTimeout();
116
+ }
117
+ errorCount.contents = 0;
118
+ resetStaleTimeout();
119
+ Prometheus.SourceRequestCount.increment("WebSocket", chainId, "eth_subscribe");
120
+ return onHeight(blockNumber._0);
121
+ }
122
+ catch (raw_e){
123
+ var e = Caml_js_exceptions.internalToOCamlException(raw_e);
124
+ if (e.RE_EXN_ID === S$RescriptSchema.Raised) {
125
+ return Logging.warn({
126
+ msg: "WebSocket height stream received unrecognized message",
127
+ chainId: chainId,
128
+ data: $$event.data
129
+ });
130
+ }
131
+ if (e.RE_EXN_ID === Js_exn.$$Error) {
132
+ return Logging.warn({
133
+ msg: "WebSocket height stream failed to parse message",
134
+ chainId: chainId,
135
+ err: Utils.prettifyExn(e),
136
+ data: $$event.data
137
+ });
138
+ }
139
+ Logging.error({
140
+ msg: "Unexpected error in WebSocket height stream message handler",
141
+ chainId: chainId,
142
+ err: Utils.prettifyExn(e),
143
+ data: $$event.data
144
+ });
145
+ throw e;
146
+ }
147
+ });
148
+ ws.onerror = (function (_error) {
149
+ if (errorCount.contents < 9) {
150
+ errorCount.contents = errorCount.contents + 1 | 0;
151
+ }
152
+ var ws = wsRef.contents;
153
+ if (ws === undefined) {
154
+ return ;
155
+ }
156
+ var ws$1 = Caml_option.valFromOption(ws);
157
+ if (ws$1.readyState === 1) {
158
+ ws$1.close();
159
+ return ;
160
+ }
161
+
162
+ });
163
+ ws.onclose = (function () {
164
+ wsRef.contents = undefined;
165
+ clearStaleTimeout();
166
+ scheduleReconnect();
167
+ });
168
+ };
169
+ startConnection();
170
+ return function () {
171
+ isUnsubscribed.contents = true;
172
+ clearStaleTimeout();
173
+ var ws = wsRef.contents;
174
+ if (ws !== undefined) {
175
+ Caml_option.valFromOption(ws).close();
176
+ return ;
177
+ }
178
+
179
+ };
180
+ }
181
+
182
+ var retryCount = 9;
183
+
184
+ var baseDuration = 125;
185
+
186
+ var staleTimeMillis = 60000;
187
+
188
+ export {
189
+ retryCount ,
190
+ baseDuration ,
191
+ staleTimeMillis ,
192
+ subscribeRequestJson ,
193
+ wsMessageSchema ,
194
+ subscribe ,
195
+ }
196
+ /* subscribeRequestJson Not a pure module */
@@ -0,0 +1,59 @@
1
+ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain.t): Source.t => {
2
+ // getItemsOrThrow might be called multiple times with different partition ids.
3
+ // Return all items on the first call and empty on subsequent calls to prevent
4
+ // duplicate event processing.
5
+ let delivered = ref(false)
6
+
7
+ {
8
+ name: "SimulateSource",
9
+ sourceFor: Sync,
10
+ chain,
11
+ poweredByHyperSync: false,
12
+ pollingInterval: 0,
13
+ getBlockHashes: (~blockNumbers as _, ~logger as _) => {
14
+ Promise.resolve(Ok([]))
15
+ },
16
+ getHeightOrThrow: () => {
17
+ // Report at least height 1 so the engine doesn't treat 0 as "no blocks available"
18
+ Promise.resolve(max(endBlock, 1))
19
+ },
20
+ getItemsOrThrow: (
21
+ ~fromBlock as _,
22
+ ~toBlock as _,
23
+ ~addressesByContractName as _,
24
+ ~indexingContracts as _,
25
+ ~knownHeight as _,
26
+ ~partitionId as _,
27
+ ~selection as _,
28
+ ~retry as _,
29
+ ~logger as _,
30
+ ) => {
31
+ // Return all items on first call, empty on subsequent calls
32
+ let result = if delivered.contents {
33
+ []
34
+ } else {
35
+ delivered := true
36
+ items
37
+ }
38
+
39
+ let reportedHeight = max(endBlock, 1)
40
+ Promise.resolve({
41
+ Source.knownHeight: reportedHeight,
42
+ reorgGuard: {
43
+ rangeLastBlock: {
44
+ blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
45
+ blockNumber: reportedHeight,
46
+ },
47
+ prevRangeLastBlock: None,
48
+ },
49
+ parsedQueueItems: result,
50
+ fromBlockQueried: 0,
51
+ latestFetchedBlockNumber: reportedHeight,
52
+ latestFetchedBlockTimestamp: 0,
53
+ stats: {
54
+ totalTimeElapsed: 0.,
55
+ },
56
+ })
57
+ },
58
+ }
59
+ }
@@ -0,0 +1,50 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ function make(items, endBlock, chain) {
5
+ var delivered = {
6
+ contents: false
7
+ };
8
+ return {
9
+ name: "SimulateSource",
10
+ sourceFor: "Sync",
11
+ chain: chain,
12
+ poweredByHyperSync: false,
13
+ pollingInterval: 0,
14
+ getBlockHashes: (function (param, param$1) {
15
+ return Promise.resolve({
16
+ TAG: "Ok",
17
+ _0: []
18
+ });
19
+ }),
20
+ getHeightOrThrow: (function () {
21
+ return Promise.resolve(endBlock > 1 ? endBlock : 1);
22
+ }),
23
+ getItemsOrThrow: (function (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) {
24
+ var result = delivered.contents ? [] : (delivered.contents = true, items);
25
+ var reportedHeight = endBlock > 1 ? endBlock : 1;
26
+ return Promise.resolve({
27
+ knownHeight: reportedHeight,
28
+ reorgGuard: {
29
+ rangeLastBlock: {
30
+ blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
31
+ blockNumber: reportedHeight
32
+ },
33
+ prevRangeLastBlock: undefined
34
+ },
35
+ parsedQueueItems: result,
36
+ fromBlockQueried: 0,
37
+ latestFetchedBlockNumber: reportedHeight,
38
+ latestFetchedBlockTimestamp: 0,
39
+ stats: {
40
+ "total time elapsed (s)": 0
41
+ }
42
+ });
43
+ })
44
+ };
45
+ }
46
+
47
+ export {
48
+ make ,
49
+ }
50
+ /* No side effect */
@@ -2,16 +2,16 @@
2
2
  A set of stats for logging about the block range fetch
3
3
  */
4
4
  type blockRangeFetchStats = {
5
- @as("total time elapsed (ms)") totalTimeElapsed: int,
6
- @as("parsing time (ms)") parsingTimeElapsed?: int,
7
- @as("page fetch time (ms)") pageFetchTime?: int,
5
+ @as("total time elapsed (s)") totalTimeElapsed: float,
6
+ @as("parsing time (s)") parsingTimeElapsed?: float,
7
+ @as("page fetch time (s)") pageFetchTime?: float,
8
8
  }
9
9
 
10
10
  /**
11
11
  Thes response returned from a block range fetch
12
12
  */
13
13
  type blockRangeFetchResponse = {
14
- currentBlockHeight: int,
14
+ knownHeight: int,
15
15
  reorgGuard: ReorgDetection.reorgGuard,
16
16
  parsedQueueItems: array<Internal.item>,
17
17
  fromBlockQueried: int,
@@ -33,6 +33,7 @@ type getItemsError =
33
33
  exception GetItemsError(getItemsError)
34
34
 
35
35
  type sourceFor = Sync | Fallback | Live
36
+
36
37
  type t = {
37
38
  name: string,
38
39
  sourceFor: sourceFor,
@@ -50,10 +51,11 @@ type t = {
50
51
  ~toBlock: option<int>,
51
52
  ~addressesByContractName: dict<array<Address.t>>,
52
53
  ~indexingContracts: dict<Internal.indexingContract>,
53
- ~currentBlockHeight: int,
54
+ ~knownHeight: int,
54
55
  ~partitionId: string,
55
56
  ~selection: FetchState.selection,
56
57
  ~retry: int,
57
58
  ~logger: Pino.t,
58
59
  ) => promise<blockRangeFetchResponse>,
60
+ createHeightSubscription?: (~onHeight: int => unit) => unit => unit,
59
61
  }