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.
- package/evm.schema.json +26 -0
- package/fuel.schema.json +26 -0
- package/index.d.ts +35 -3
- package/package.json +6 -7
- package/src/Batch.res +9 -0
- package/src/ChainState.res +35 -39
- package/src/ChainState.res.mjs +14 -11
- package/src/ChainState.resi +15 -7
- package/src/Config.res +52 -44
- package/src/Config.res.mjs +51 -17
- package/src/Core.res +4 -0
- package/src/CrossChainState.res +15 -23
- package/src/CrossChainState.res.mjs +10 -18
- package/src/CrossChainState.resi +4 -1
- package/src/Ecosystem.res +7 -2
- package/src/Envio.res +6 -4
- package/src/EventConfigBuilder.res +169 -26
- package/src/EventConfigBuilder.res.mjs +124 -15
- package/src/HandlerRegister.res +21 -4
- package/src/HandlerRegister.res.mjs +24 -5
- package/src/InMemoryStore.res +9 -7
- package/src/InMemoryStore.res.mjs +3 -3
- package/src/IndexerState.res +43 -6
- package/src/IndexerState.res.mjs +36 -7
- package/src/IndexerState.resi +4 -4
- package/src/Internal.res +16 -17
- package/src/Metrics.res +72 -6
- package/src/Metrics.res.mjs +30 -2
- package/src/Persistence.res +36 -30
- package/src/Persistence.res.mjs +1 -20
- package/src/PgStorage.res +104 -56
- package/src/PgStorage.res.mjs +57 -35
- package/src/PruneStaleHistory.res +85 -52
- package/src/PruneStaleHistory.res.mjs +63 -37
- package/src/Rollback.res +68 -45
- package/src/Rollback.res.mjs +38 -19
- package/src/RollbackCommit.res +7 -9
- package/src/RollbackCommit.res.mjs +5 -6
- package/src/SafeCheckpointTracking.res +11 -11
- package/src/SafeCheckpointTracking.res.mjs +7 -6
- package/src/SimulateItems.res +33 -18
- package/src/SimulateItems.res.mjs +26 -22
- package/src/Sink.res +38 -26
- package/src/Sink.res.mjs +21 -16
- package/src/TestIndexer.res +5 -5
- package/src/TestIndexer.res.mjs +1 -1
- package/src/Utils.res +170 -0
- package/src/Utils.res.mjs +153 -0
- package/src/Writing.res +2 -2
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +366 -698
- package/src/bindings/ClickHouse.res.mjs +371 -421
- package/src/bindings/ClickHouseSink.res +337 -0
- package/src/bindings/ClickHouseSink.res.mjs +246 -0
- package/src/bindings/EventSource.res +8 -2
- package/src/bindings/NodeJs.res +6 -0
- package/src/bindings/Vitest.res +23 -0
- package/src/bindings/Vitest.res.mjs +3 -0
- package/src/bindings/WebSocket.res +9 -10
- package/src/db/CheckpointBounds.res +53 -0
- package/src/db/CheckpointBounds.res.mjs +44 -0
- package/src/db/EntityFilter.res +36 -17
- package/src/db/EntityFilter.res.mjs +25 -14
- package/src/db/EntityHistory.res +47 -22
- package/src/db/EntityHistory.res.mjs +19 -12
- package/src/db/InternalTable.res +84 -35
- package/src/db/InternalTable.res.mjs +56 -23
- package/src/db/RollbackFloors.res +55 -0
- package/src/db/RollbackFloors.res.mjs +92 -0
- package/src/db/Table.res +22 -4
- package/src/db/Table.res.mjs +30 -9
- package/src/sources/Evm.res +2 -0
- package/src/sources/Evm.res.mjs +2 -0
- package/src/sources/EvmHyperSyncSource.res +3 -3
- package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
- package/src/sources/EvmRpcWs.res +124 -0
- package/src/sources/EvmRpcWs.res.mjs +117 -0
- package/src/sources/Fuel.res +2 -0
- package/src/sources/Fuel.res.mjs +2 -0
- package/src/sources/FuelHyperSyncSource.res +1 -1
- package/src/sources/FuelHyperSyncSource.res.mjs +2 -1
- package/src/sources/HeightFeed.res +568 -0
- package/src/sources/HeightFeed.res.mjs +452 -0
- package/src/sources/HeightStream.res +257 -0
- package/src/sources/HeightStream.res.mjs +194 -0
- package/src/sources/HyperSync.res +5 -0
- package/src/sources/HyperSync.res.mjs +3 -0
- package/src/sources/HyperSync.resi +4 -0
- package/src/sources/HyperSyncSSE.res +49 -0
- package/src/sources/HyperSyncSSE.res.mjs +79 -0
- package/src/sources/RpcSource.res +1 -1
- package/src/sources/RpcSource.res.mjs +2 -2
- package/src/sources/Source.res +54 -1
- package/src/sources/Source.res.mjs +25 -0
- package/src/sources/SourceManager.res +220 -227
- package/src/sources/SourceManager.res.mjs +139 -164
- package/src/sources/SourceManager.resi +8 -0
- package/src/sources/Svm.res +2 -0
- package/src/sources/Svm.res.mjs +2 -0
- package/src/sources/SvmHyperSyncClient.res +70 -127
- package/src/sources/SvmHyperSyncClient.res.mjs +51 -25
- package/src/sources/SvmHyperSyncSource.res +18 -15
- package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
- package/svm.schema.json +1 -75
- package/src/MemoryStorage.res +0 -729
- package/src/MemoryStorage.res.mjs +0 -586
- package/src/sources/HyperSyncHeightStream.res +0 -129
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -110
- package/src/sources/RpcWebSocketHeightStream.res +0 -175
- 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 */
|