envio 3.9.0 → 3.10.0

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 (110) hide show
  1. package/evm.schema.json +26 -0
  2. package/fuel.schema.json +26 -0
  3. package/index.d.ts +35 -3
  4. package/package.json +6 -7
  5. package/src/Batch.res +9 -0
  6. package/src/ChainState.res +35 -39
  7. package/src/ChainState.res.mjs +14 -11
  8. package/src/ChainState.resi +15 -7
  9. package/src/Config.res +52 -44
  10. package/src/Config.res.mjs +51 -17
  11. package/src/Core.res +4 -0
  12. package/src/CrossChainState.res +15 -23
  13. package/src/CrossChainState.res.mjs +10 -18
  14. package/src/CrossChainState.resi +4 -1
  15. package/src/Ecosystem.res +7 -2
  16. package/src/Envio.res +6 -4
  17. package/src/EventConfigBuilder.res +169 -26
  18. package/src/EventConfigBuilder.res.mjs +124 -15
  19. package/src/HandlerRegister.res +21 -4
  20. package/src/HandlerRegister.res.mjs +24 -5
  21. package/src/InMemoryStore.res +9 -7
  22. package/src/InMemoryStore.res.mjs +3 -3
  23. package/src/IndexerState.res +43 -6
  24. package/src/IndexerState.res.mjs +36 -7
  25. package/src/IndexerState.resi +4 -4
  26. package/src/Internal.res +16 -17
  27. package/src/Metrics.res +72 -6
  28. package/src/Metrics.res.mjs +30 -2
  29. package/src/Persistence.res +36 -30
  30. package/src/Persistence.res.mjs +1 -20
  31. package/src/PgStorage.res +104 -56
  32. package/src/PgStorage.res.mjs +57 -35
  33. package/src/PruneStaleHistory.res +85 -52
  34. package/src/PruneStaleHistory.res.mjs +63 -37
  35. package/src/Rollback.res +68 -45
  36. package/src/Rollback.res.mjs +38 -19
  37. package/src/RollbackCommit.res +7 -9
  38. package/src/RollbackCommit.res.mjs +5 -6
  39. package/src/SafeCheckpointTracking.res +11 -11
  40. package/src/SafeCheckpointTracking.res.mjs +7 -6
  41. package/src/SimulateItems.res +33 -18
  42. package/src/SimulateItems.res.mjs +26 -22
  43. package/src/Sink.res +38 -26
  44. package/src/Sink.res.mjs +21 -16
  45. package/src/TestIndexer.res +5 -5
  46. package/src/TestIndexer.res.mjs +1 -1
  47. package/src/Utils.res +170 -0
  48. package/src/Utils.res.mjs +153 -0
  49. package/src/Writing.res +2 -2
  50. package/src/Writing.res.mjs +1 -1
  51. package/src/bindings/ClickHouse.res +366 -698
  52. package/src/bindings/ClickHouse.res.mjs +371 -421
  53. package/src/bindings/ClickHouseSink.res +337 -0
  54. package/src/bindings/ClickHouseSink.res.mjs +246 -0
  55. package/src/bindings/EventSource.res +8 -2
  56. package/src/bindings/NodeJs.res +6 -0
  57. package/src/bindings/Vitest.res +23 -0
  58. package/src/bindings/Vitest.res.mjs +3 -0
  59. package/src/bindings/WebSocket.res +9 -10
  60. package/src/db/CheckpointBounds.res +53 -0
  61. package/src/db/CheckpointBounds.res.mjs +44 -0
  62. package/src/db/EntityFilter.res +36 -17
  63. package/src/db/EntityFilter.res.mjs +25 -14
  64. package/src/db/EntityHistory.res +47 -22
  65. package/src/db/EntityHistory.res.mjs +19 -12
  66. package/src/db/InternalTable.res +84 -35
  67. package/src/db/InternalTable.res.mjs +56 -23
  68. package/src/db/RollbackFloors.res +55 -0
  69. package/src/db/RollbackFloors.res.mjs +92 -0
  70. package/src/db/Table.res +22 -4
  71. package/src/db/Table.res.mjs +30 -9
  72. package/src/sources/Evm.res +2 -0
  73. package/src/sources/Evm.res.mjs +2 -0
  74. package/src/sources/EvmHyperSyncSource.res +3 -3
  75. package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
  76. package/src/sources/EvmRpcWs.res +124 -0
  77. package/src/sources/EvmRpcWs.res.mjs +117 -0
  78. package/src/sources/Fuel.res +2 -0
  79. package/src/sources/Fuel.res.mjs +2 -0
  80. package/src/sources/FuelHyperSyncSource.res +1 -1
  81. package/src/sources/FuelHyperSyncSource.res.mjs +2 -1
  82. package/src/sources/HeightFeed.res +568 -0
  83. package/src/sources/HeightFeed.res.mjs +452 -0
  84. package/src/sources/HeightStream.res +257 -0
  85. package/src/sources/HeightStream.res.mjs +194 -0
  86. package/src/sources/HyperSync.res +5 -0
  87. package/src/sources/HyperSync.res.mjs +3 -0
  88. package/src/sources/HyperSync.resi +4 -0
  89. package/src/sources/HyperSyncSSE.res +49 -0
  90. package/src/sources/HyperSyncSSE.res.mjs +79 -0
  91. package/src/sources/RpcSource.res +1 -1
  92. package/src/sources/RpcSource.res.mjs +2 -2
  93. package/src/sources/Source.res +54 -1
  94. package/src/sources/Source.res.mjs +25 -0
  95. package/src/sources/SourceManager.res +220 -227
  96. package/src/sources/SourceManager.res.mjs +139 -164
  97. package/src/sources/SourceManager.resi +8 -0
  98. package/src/sources/Svm.res +2 -0
  99. package/src/sources/Svm.res.mjs +2 -0
  100. package/src/sources/SvmHyperSyncClient.res +70 -127
  101. package/src/sources/SvmHyperSyncClient.res.mjs +51 -25
  102. package/src/sources/SvmHyperSyncSource.res +18 -15
  103. package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
  104. package/svm.schema.json +1 -75
  105. package/src/MemoryStorage.res +0 -729
  106. package/src/MemoryStorage.res.mjs +0 -586
  107. package/src/sources/HyperSyncHeightStream.res +0 -129
  108. package/src/sources/HyperSyncHeightStream.res.mjs +0 -110
  109. package/src/sources/RpcWebSocketHeightStream.res +0 -175
  110. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -180
@@ -1,110 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Utils from "../Utils.res.mjs";
4
- import * as Logging from "../Logging.res.mjs";
5
- import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
6
- import * as Eventsource from "eventsource";
7
- import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
8
- import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
9
-
10
- function subscribe(hyperSyncUrl, apiToken, chainId, onHeight) {
11
- let eventsourceRef = {
12
- contents: undefined
13
- };
14
- let errorCount = {
15
- contents: 0
16
- };
17
- let timeoutIdRef = {
18
- contents: setTimeout(() => {}, 0)
19
- };
20
- let updateTimeoutId = () => {
21
- clearTimeout(timeoutIdRef.contents);
22
- let newTimeoutId = setTimeout(() => {
23
- Logging.trace({
24
- msg: "Timeout fired for height stream",
25
- chainId: chainId,
26
- url: hyperSyncUrl,
27
- staleTimeMillis: 15000
28
- });
29
- refreshEventSource();
30
- }, 15000);
31
- timeoutIdRef.contents = newTimeoutId;
32
- };
33
- let scheduleReconnect = () => {
34
- clearTimeout(timeoutIdRef.contents);
35
- let delay = 50 * (Math.pow(2.0, errorCount.contents) | 0) | 0;
36
- timeoutIdRef.contents = setTimeout(() => refreshEventSource(), Primitive_int.min(delay, 60000));
37
- };
38
- let refreshEventSource = () => {
39
- let es = eventsourceRef.contents;
40
- if (es !== undefined) {
41
- Primitive_option.valFromOption(es).close();
42
- }
43
- let userAgent = `hyperindex/` + Utils.EnvioPackage.value.version;
44
- let es$1 = new Eventsource.EventSource(hyperSyncUrl + `/height/sse`, {
45
- fetch: (url, args) => {
46
- let newrecord = {...args};
47
- return fetch(url, (newrecord.headers = Object.fromEntries([
48
- [
49
- "Authorization",
50
- `Bearer ` + apiToken
51
- ],
52
- [
53
- "User-Agent",
54
- userAgent
55
- ]
56
- ]), newrecord));
57
- }
58
- });
59
- eventsourceRef.contents = Primitive_option.some(es$1);
60
- updateTimeoutId();
61
- es$1.onopen = () => {
62
- errorCount.contents = 0;
63
- Logging.trace({
64
- msg: "SSE connection opened for height stream",
65
- chainId: chainId,
66
- url: hyperSyncUrl
67
- });
68
- };
69
- es$1.onerror = error => {
70
- errorCount.contents = errorCount.contents + 1 | 0;
71
- Logging.trace({
72
- msg: "EventSource error on height stream, reconnecting",
73
- chainId: chainId,
74
- url: hyperSyncUrl,
75
- status: error.status,
76
- error: error.message,
77
- errorCount: errorCount.contents
78
- });
79
- scheduleReconnect();
80
- };
81
- es$1.addEventListener("ping", _event => updateTimeoutId());
82
- es$1.addEventListener("height", event => {
83
- let height = Stdlib_Int.fromString(event.data, undefined);
84
- if (height !== undefined) {
85
- updateTimeoutId();
86
- return onHeight(height);
87
- } else {
88
- return Logging.trace({
89
- msg: "Height was not a number in event.data",
90
- chainId: chainId,
91
- data: event.data
92
- });
93
- }
94
- });
95
- };
96
- refreshEventSource();
97
- return () => {
98
- clearTimeout(timeoutIdRef.contents);
99
- let es = eventsourceRef.contents;
100
- if (es !== undefined) {
101
- Primitive_option.valFromOption(es).close();
102
- return;
103
- }
104
- };
105
- }
106
-
107
- export {
108
- subscribe,
109
- }
110
- /* Utils Not a pure module */
@@ -1,175 +0,0 @@
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
- } => JSON.t)
26
- ->JSON.stringify
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<timeoutId>> = ref(None)
61
-
62
- let clearStaleTimeout = () => {
63
- switch staleTimeoutId.contents {
64
- | Some(id) =>
65
- clearTimeout(id)
66
- staleTimeoutId := None
67
- | None => ()
68
- }
69
- }
70
-
71
- let resetStaleTimeout = () => {
72
- clearStaleTimeout()
73
- staleTimeoutId := Some(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 * Math.pow(2.0, ~exp=errorCount.contents->Int.toFloat)->Float.toInt
86
- let _ = setTimeout(() => {
87
- if !isUnsubscribed.contents {
88
- startConnection()
89
- }
90
- }, duration)
91
- }
92
- }
93
- and startConnection = () => {
94
- if isUnsubscribed.contents || errorCount.contents >= retryCount {
95
- ()
96
- } else {
97
- let ws = WebSocket.create(wsUrl)
98
- wsRef := Some(ws)
99
-
100
- ws->WebSocket.onopen(() => {
101
- ws->WebSocket.send(subscribeRequestJson)
102
- resetStaleTimeout()
103
- })
104
-
105
- ws->WebSocket.onmessage(event => {
106
- try {
107
- switch event.data->JSON.parseOrThrow->S.parseOrThrow(wsMessageSchema) {
108
- | NewHead(blockNumber) =>
109
- errorCount := 0
110
- resetStaleTimeout()
111
- onHeight(blockNumber)
112
- | SubscriptionConfirmed(_) => resetStaleTimeout()
113
- | ErrorResponse =>
114
- if errorCount.contents < retryCount {
115
- errorCount := errorCount.contents + 1
116
- }
117
- switch wsRef.contents {
118
- | Some(ws) => ws->WebSocket.close
119
- | None => ()
120
- }
121
- }
122
- } catch {
123
- | S.Raised(_) =>
124
- Logging.warn({
125
- "msg": "WebSocket height stream received unrecognized message",
126
- "chainId": chainId,
127
- "data": event.data,
128
- })
129
- | JsExn(_) as e =>
130
- Logging.warn({
131
- "msg": "WebSocket height stream failed to parse message",
132
- "chainId": chainId,
133
- "err": e->Utils.prettifyExn,
134
- "data": event.data,
135
- })
136
- | e =>
137
- Logging.error({
138
- "msg": "Unexpected error in WebSocket height stream message handler",
139
- "chainId": chainId,
140
- "err": e->Utils.prettifyExn,
141
- "data": event.data,
142
- })
143
- throw(e)
144
- }
145
- })
146
-
147
- ws->WebSocket.onerror(_error => {
148
- if errorCount.contents < retryCount {
149
- errorCount := errorCount.contents + 1
150
- }
151
- switch wsRef.contents {
152
- | Some(ws) if ws->WebSocket.readyState === Open => ws->WebSocket.close
153
- | _ => ()
154
- }
155
- })
156
-
157
- ws->WebSocket.onclose(() => {
158
- wsRef := None
159
- clearStaleTimeout()
160
- scheduleReconnect()
161
- })
162
- }
163
- }
164
-
165
- startConnection()
166
-
167
- () => {
168
- isUnsubscribed := true
169
- clearStaleTimeout()
170
- switch wsRef.contents {
171
- | Some(ws) => ws->WebSocket.close
172
- | None => ()
173
- }
174
- }
175
- }
@@ -1,180 +0,0 @@
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 Logging from "../Logging.res.mjs";
6
- import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
7
- import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
8
- import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
9
-
10
- let subscribeRequestJson = JSON.stringify({
11
- jsonrpc: "2.0",
12
- id: 1,
13
- method: "eth_subscribe",
14
- params: ["newHeads"]
15
- });
16
-
17
- let wsMessageSchema = S$RescriptSchema.union([
18
- S$RescriptSchema.object(s => {
19
- s.f("method", S$RescriptSchema.literal("eth_subscription"));
20
- return {
21
- TAG: "NewHead",
22
- _0: s.f("params", S$RescriptSchema.object(s => s.f("result", S$RescriptSchema.object(s => s.f("number", Rpc.hexIntSchema)))))
23
- };
24
- }),
25
- S$RescriptSchema.object(s => ({
26
- TAG: "SubscriptionConfirmed",
27
- _0: s.f("result", S$RescriptSchema.string)
28
- })),
29
- S$RescriptSchema.object(s => {
30
- s.f("error", S$RescriptSchema.unknown);
31
- return "ErrorResponse";
32
- })
33
- ]);
34
-
35
- function subscribe(wsUrl, chainId, onHeight) {
36
- let wsRef = {
37
- contents: undefined
38
- };
39
- let isUnsubscribed = {
40
- contents: false
41
- };
42
- let errorCount = {
43
- contents: 0
44
- };
45
- let staleTimeoutId = {
46
- contents: undefined
47
- };
48
- let clearStaleTimeout = () => {
49
- let id = staleTimeoutId.contents;
50
- if (id !== undefined) {
51
- clearTimeout(Primitive_option.valFromOption(id));
52
- staleTimeoutId.contents = undefined;
53
- return;
54
- }
55
- };
56
- let resetStaleTimeout = () => {
57
- clearStaleTimeout();
58
- staleTimeoutId.contents = Primitive_option.some(setTimeout(() => {
59
- let ws = wsRef.contents;
60
- if (ws !== undefined) {
61
- Primitive_option.valFromOption(ws).close();
62
- return;
63
- }
64
- }, 60000));
65
- };
66
- let scheduleReconnect = () => {
67
- if (!(!isUnsubscribed.contents && errorCount.contents < 9)) {
68
- return;
69
- }
70
- let duration = 125 * (Math.pow(2.0, errorCount.contents) | 0) | 0;
71
- setTimeout(() => {
72
- if (!isUnsubscribed.contents) {
73
- return startConnection();
74
- }
75
- }, duration);
76
- };
77
- let startConnection = () => {
78
- if (isUnsubscribed.contents || errorCount.contents >= 9) {
79
- return;
80
- }
81
- let ws = new WebSocket(wsUrl);
82
- wsRef.contents = Primitive_option.some(ws);
83
- ws.onopen = () => {
84
- ws.send(subscribeRequestJson);
85
- resetStaleTimeout();
86
- };
87
- ws.onmessage = event => {
88
- try {
89
- let blockNumber = S$RescriptSchema.parseOrThrow(JSON.parse(event.data), wsMessageSchema);
90
- if (typeof blockNumber !== "object") {
91
- if (errorCount.contents < 9) {
92
- errorCount.contents = errorCount.contents + 1 | 0;
93
- }
94
- let ws = wsRef.contents;
95
- if (ws !== undefined) {
96
- Primitive_option.valFromOption(ws).close();
97
- return;
98
- } else {
99
- return;
100
- }
101
- }
102
- if (blockNumber.TAG !== "NewHead") {
103
- return resetStaleTimeout();
104
- }
105
- errorCount.contents = 0;
106
- resetStaleTimeout();
107
- return onHeight(blockNumber._0);
108
- } catch (raw_e) {
109
- let e = Primitive_exceptions.internalToException(raw_e);
110
- if (e.RE_EXN_ID === S$RescriptSchema.Raised) {
111
- return Logging.warn({
112
- msg: "WebSocket height stream received unrecognized message",
113
- chainId: chainId,
114
- data: event.data
115
- });
116
- }
117
- if (e.RE_EXN_ID === "JsExn") {
118
- return Logging.warn({
119
- msg: "WebSocket height stream failed to parse message",
120
- chainId: chainId,
121
- err: Utils.prettifyExn(e),
122
- data: event.data
123
- });
124
- }
125
- Logging.error({
126
- msg: "Unexpected error in WebSocket height stream message handler",
127
- chainId: chainId,
128
- err: Utils.prettifyExn(e),
129
- data: event.data
130
- });
131
- throw e;
132
- }
133
- };
134
- ws.onerror = _error => {
135
- if (errorCount.contents < 9) {
136
- errorCount.contents = errorCount.contents + 1 | 0;
137
- }
138
- let ws = wsRef.contents;
139
- if (ws === undefined) {
140
- return;
141
- }
142
- let ws$1 = Primitive_option.valFromOption(ws);
143
- if (ws$1.readyState === 1) {
144
- ws$1.close();
145
- return;
146
- }
147
- };
148
- ws.onclose = () => {
149
- wsRef.contents = undefined;
150
- clearStaleTimeout();
151
- scheduleReconnect();
152
- };
153
- };
154
- startConnection();
155
- return () => {
156
- isUnsubscribed.contents = true;
157
- clearStaleTimeout();
158
- let ws = wsRef.contents;
159
- if (ws !== undefined) {
160
- Primitive_option.valFromOption(ws).close();
161
- return;
162
- }
163
- };
164
- }
165
-
166
- let retryCount = 9;
167
-
168
- let baseDuration = 125;
169
-
170
- let staleTimeMillis = 60000;
171
-
172
- export {
173
- retryCount,
174
- baseDuration,
175
- staleTimeMillis,
176
- subscribeRequestJson,
177
- wsMessageSchema,
178
- subscribe,
179
- }
180
- /* subscribeRequestJson Not a pure module */