envio 3.15.0 → 3.16.0-subgraph

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 (186) hide show
  1. package/README.md +40 -34
  2. package/evm.schema.json +11 -2
  3. package/fuel.schema.json +10 -1
  4. package/index.d.ts +6 -0
  5. package/licenses/README.md +1 -1
  6. package/package.json +10 -9
  7. package/src/Batch.res.mjs +5 -5
  8. package/src/BatchProcessing.res +1 -0
  9. package/src/BatchProcessing.res.mjs +1 -0
  10. package/src/Bin.res +7 -0
  11. package/src/Bin.res.mjs +8 -0
  12. package/src/ChainFetching.res +450 -16
  13. package/src/ChainFetching.res.mjs +403 -32
  14. package/src/ChainState.res +124 -7
  15. package/src/ChainState.res.mjs +128 -67
  16. package/src/ChainState.resi +26 -0
  17. package/src/Clock.res +57 -0
  18. package/src/Clock.res.mjs +72 -0
  19. package/src/Config.res +31 -3
  20. package/src/Config.res.mjs +15 -4
  21. package/src/ContractRegisterContext.res +3 -6
  22. package/src/ContractRegisterContext.res.mjs +4 -2
  23. package/src/Core.res +95 -36
  24. package/src/Core.res.mjs +90 -1
  25. package/src/CrossChainState.res +12 -2
  26. package/src/CrossChainState.res.mjs +3 -3
  27. package/src/Ecosystem.res +7 -4
  28. package/src/Ecosystem.res.mjs +8 -8
  29. package/src/EffectCacheLookup.res +98 -0
  30. package/src/EffectCacheLookup.res.mjs +116 -0
  31. package/src/EffectState.res +10 -2
  32. package/src/EffectState.res.mjs +8 -4
  33. package/src/EffectState.resi +3 -1
  34. package/src/EntityId.res +2 -7
  35. package/src/EntityId.res.mjs +1 -8
  36. package/src/EntityTables.res +4 -1
  37. package/src/EntityTables.res.mjs +1 -1
  38. package/src/Env.res +20 -0
  39. package/src/Env.res.mjs +16 -0
  40. package/src/EventProcessing.res +38 -1
  41. package/src/EventProcessing.res.mjs +28 -1
  42. package/src/FetchState.res +408 -73
  43. package/src/FetchState.res.mjs +361 -91
  44. package/src/FinalizeBackfill.res +2 -4
  45. package/src/FinalizeBackfill.res.mjs +3 -4
  46. package/src/HandlerLoader.res +39 -15
  47. package/src/HandlerLoader.res.mjs +27 -8
  48. package/src/HandlerRegister.res +4 -0
  49. package/src/HandlerRegister.res.mjs +5 -2
  50. package/src/HandlerRegister.resi +2 -0
  51. package/src/InMemoryTable.res +17 -16
  52. package/src/InMemoryTable.res.mjs +14 -15
  53. package/src/IndexerState.res +28 -4
  54. package/src/IndexerState.res.mjs +19 -6
  55. package/src/IndexerState.resi +4 -0
  56. package/src/Internal.res +61 -49
  57. package/src/Internal.res.mjs +36 -80
  58. package/src/LoadLayer.res +54 -15
  59. package/src/LoadLayer.res.mjs +75 -45
  60. package/src/LoadLayer.resi +26 -0
  61. package/src/Main.res +14 -1
  62. package/src/Main.res.mjs +4 -3
  63. package/src/Persistence.res +3 -23
  64. package/src/Persistence.res.mjs +3 -3
  65. package/src/PreloadLookahead.res +202 -0
  66. package/src/PreloadLookahead.res.mjs +218 -0
  67. package/src/Rollback.res +0 -1
  68. package/src/Rollback.res.mjs +1 -1
  69. package/src/RunScope.res +3 -0
  70. package/src/SafeCheckpointTracking.res +4 -4
  71. package/src/SafeCheckpointTracking.res.mjs +1 -1
  72. package/src/SimulateItems.res +42 -26
  73. package/src/SimulateItems.res.mjs +40 -16
  74. package/src/StagedRows.res +106 -0
  75. package/src/StagedRows.res.mjs +102 -0
  76. package/src/Staging.res +32 -14
  77. package/src/Staging.res.mjs +17 -20
  78. package/src/Storage.res +303 -948
  79. package/src/Storage.res.mjs +229 -708
  80. package/src/SubgraphLog.res +19 -0
  81. package/src/SubgraphLog.res.mjs +26 -0
  82. package/src/Supervisor.res +75 -56
  83. package/src/Supervisor.res.mjs +55 -26
  84. package/src/SyncWrites.res +107 -0
  85. package/src/SyncWrites.res.mjs +98 -0
  86. package/src/TestIndexer.res +22 -27
  87. package/src/TestIndexer.res.mjs +20 -17
  88. package/src/Throttler.res +15 -8
  89. package/src/Throttler.res.mjs +9 -6
  90. package/src/Throttler.resi +1 -1
  91. package/src/UserContext.res +419 -46
  92. package/src/UserContext.res.mjs +318 -30
  93. package/src/Utils.res +17 -6
  94. package/src/Utils.res.mjs +12 -6
  95. package/src/Writing.res +0 -1
  96. package/src/Writing.res.mjs +1 -1
  97. package/src/bindings/ClickHouse.res +0 -322
  98. package/src/bindings/ClickHouse.res.mjs +0 -338
  99. package/src/bindings/StorageClient.res +108 -174
  100. package/src/bindings/StorageClient.res.mjs +19 -8
  101. package/src/bindings/Vitest.res +0 -26
  102. package/src/bindings/Vitest.res.mjs +0 -3
  103. package/src/db/Table.res +24 -150
  104. package/src/db/Table.res.mjs +38 -272
  105. package/src/sources/AddressSet.res +2 -0
  106. package/src/sources/AddressStore.res +3 -0
  107. package/src/sources/CallSource.res +274 -0
  108. package/src/sources/CallSource.res.mjs +196 -0
  109. package/src/sources/ChainSources.res +2 -0
  110. package/src/sources/ChainSources.res.mjs +2 -2
  111. package/src/sources/EvmChain.res +10 -1
  112. package/src/sources/EvmChain.res.mjs +6 -3
  113. package/src/sources/EvmHyperSyncSource.res +2 -2
  114. package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
  115. package/src/sources/EvmRpcClient.res +13 -3
  116. package/src/sources/EvmRpcClient.res.mjs +4 -3
  117. package/src/sources/EvmRpcWs.res +4 -3
  118. package/src/sources/EvmRpcWs.res.mjs +2 -2
  119. package/src/sources/HeightFeed.res +31 -10
  120. package/src/sources/HeightFeed.res.mjs +10 -6
  121. package/src/sources/HeightStream.res +32 -17
  122. package/src/sources/HeightStream.res.mjs +10 -10
  123. package/src/sources/HyperSync.res +2 -1
  124. package/src/sources/HyperSync.res.mjs +2 -1
  125. package/src/sources/HyperSyncSSE.res +4 -6
  126. package/src/sources/HyperSyncSSE.res.mjs +2 -2
  127. package/src/sources/RpcSource.res +10 -1
  128. package/src/sources/RpcSource.res.mjs +4 -3
  129. package/src/sources/Source.res +3 -0
  130. package/src/sources/SourceManager.res +84 -77
  131. package/src/sources/SourceManager.res.mjs +17 -20
  132. package/src/sources/SourceManager.resi +3 -4
  133. package/src/sources/StartBlockResolver.res +1 -0
  134. package/src/sources/StartBlockResolver.res.mjs +3 -2
  135. package/src/sources/SvmHyperSyncSource.res +2 -2
  136. package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
  137. package/src/subgraph/abi-types.ts +84 -0
  138. package/src/subgraph/aggregations.ts +745 -0
  139. package/src/subgraph/as-package.ts +143 -0
  140. package/src/subgraph/assemblyscript-regex.ts +67 -0
  141. package/src/subgraph/assemblyscript.ts +731 -0
  142. package/src/subgraph/blocks.ts +398 -0
  143. package/src/subgraph/calls-source.ts +702 -0
  144. package/src/subgraph/calls.ts +258 -0
  145. package/src/subgraph/conformance.ts +106 -0
  146. package/src/subgraph/errors.ts +85 -0
  147. package/src/subgraph/graft.ts +73 -0
  148. package/src/subgraph/graph-cli-worker.mjs +35 -0
  149. package/src/subgraph/graph-cli.ts +900 -0
  150. package/src/subgraph/graph-node-decimal.ts +199 -0
  151. package/src/subgraph/graph-ts-enums.ts +28 -0
  152. package/src/subgraph/graph-ts-types/VERSION +2 -0
  153. package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
  154. package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
  155. package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
  156. package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
  157. package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
  158. package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
  159. package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
  160. package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
  161. package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
  162. package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
  163. package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
  164. package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
  165. package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
  166. package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
  167. package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
  168. package/src/subgraph/graph-ts-types/index.d.ts +102 -0
  169. package/src/subgraph/graph-ts.ts +4339 -0
  170. package/src/subgraph/hosts.ts +554 -0
  171. package/src/subgraph/log.ts +28 -0
  172. package/src/subgraph/receipts.ts +184 -0
  173. package/src/subgraph/register-slots.ts +93 -0
  174. package/src/subgraph/rollup.ts +109 -0
  175. package/src/subgraph/rpc.ts +337 -0
  176. package/src/subgraph/runtime.ts +2059 -0
  177. package/src/subgraph/scope.ts +176 -0
  178. package/src/subgraph/stats.ts +42 -0
  179. package/src/subgraph/template-instances.ts +66 -0
  180. package/src/subgraph/toolchain.ts +327 -0
  181. package/src/subgraph/transient.ts +176 -0
  182. package/svm.schema.json +11 -2
  183. package/src/PgWriting.res +0 -36
  184. package/src/PgWriting.res.mjs +0 -34
  185. package/src/db/IndexDefinition.res +0 -47
  186. package/src/db/IndexDefinition.res.mjs +0 -67
@@ -61,8 +61,8 @@ let wsMessageSchema = S$RescriptSchema.union([
61
61
  })
62
62
  ]);
63
63
 
64
- function subscribe(wsUrl, onHeight, onStatus) {
65
- return HeightStream.subscribe(60000, onHeight, onStatus, driver => {
64
+ function subscribe(clock, wsUrl, onHeight, onStatus) {
65
+ return HeightStream.subscribe(clock, 60000, onHeight, onStatus, driver => {
66
66
  let ws = new WebSocket(wsUrl);
67
67
  let subscribed = {
68
68
  contents: false
@@ -79,6 +79,7 @@ type t = {
79
79
  // than any healthy getHeight, so a merely slow endpoint answers first and
80
80
  // nothing here fires in normal running.
81
81
  pollTimeoutMillis: int,
82
+ clock: Clock.t,
82
83
  mutable knownHeight: int,
83
84
  mutable waiters: array<waiter>,
84
85
  mutable stream: streamState,
@@ -110,12 +111,14 @@ let make = (
110
111
  ~recordRequestStats,
111
112
  ~getHeightRetryInterval,
112
113
  ~pollTimeoutMillis,
114
+ ~clock,
113
115
  ): t => {
114
116
  source,
115
117
  logger: logger->Logger.withFields({"source": source.name}),
116
118
  recordRequestStats,
117
119
  getHeightRetryInterval,
118
120
  pollTimeoutMillis,
121
+ clock,
119
122
  knownHeight: 0,
120
123
  waiters: [],
121
124
  stream: NeverEnabled,
@@ -275,26 +278,43 @@ let heightWithin = (feed: t): promise<pollOutcome> => {
275
278
  request
276
279
  ->Promise.thenResolve(res => Answered(res))
277
280
  ->Promise.catch(exn => Promise.resolve(Failed(exn))),
278
- Promise.make((resolve, _reject) => timeoutId := Some(setTimeout(() => {
279
- timedOut := true
280
- resolve(TimedOut)
281
- }, feed.pollTimeoutMillis))),
281
+ Promise.make((resolve, _reject) =>
282
+ timeoutId :=
283
+ Some(
284
+ feed.clock.setTimeout(
285
+ ~label="height poll timeout",
286
+ () => {
287
+ timedOut := true
288
+ resolve(TimedOut)
289
+ },
290
+ feed.pollTimeoutMillis,
291
+ ),
292
+ )
293
+ ),
282
294
  ])->Promise.thenResolve(outcome => {
283
- timeoutId->Utils.clearTimeoutRef
295
+ feed.clock->Clock.clearRef(timeoutId)
284
296
  outcome
285
297
  })
286
298
  }
287
299
 
288
300
  let sleep = (feed: t, ~kind, millis) =>
289
301
  Promise.make((resolve, _reject) => {
290
- let timeoutId = setTimeout(() => {
291
- feed.sleeping = None
292
- resolve()
293
- }, millis)
302
+ let label = switch kind {
303
+ | Cadence => "height poll cadence"
304
+ | Backoff => "height poll backoff"
305
+ }
306
+ let timer = feed.clock.setTimeout(
307
+ ~label,
308
+ () => {
309
+ feed.sleeping = None
310
+ resolve()
311
+ },
312
+ millis,
313
+ )
294
314
  feed.sleeping = Some({
295
315
  kind,
296
316
  wake: () => {
297
- clearTimeout(timeoutId)
317
+ feed.clock.clearTimeout(timer)
298
318
  feed.sleeping = None
299
319
  resolve()
300
320
  },
@@ -521,6 +541,7 @@ let enableStream = (feed: t) =>
521
541
  }
522
542
  feed.closeStream = Some(
523
543
  createSubscription(
544
+ ~clock=feed.clock,
524
545
  ~onHeight=height => feed->handlePushedHeight(height),
525
546
  ~onStatus=status => feed->handleStatus(status),
526
547
  ),
@@ -1,5 +1,6 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Clock from "../Clock.res.mjs";
3
4
  import * as Utils from "../Utils.res.mjs";
4
5
  import * as Logger from "../Logger.res.mjs";
5
6
  import * as Source from "./Source.res.mjs";
@@ -10,7 +11,7 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
10
11
  import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
11
12
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
12
13
 
13
- function make(source, logger, recordRequestStats, getHeightRetryInterval, pollTimeoutMillis) {
14
+ function make(source, logger, recordRequestStats, getHeightRetryInterval, pollTimeoutMillis, clock) {
14
15
  return {
15
16
  source: source,
16
17
  logger: Logger.withFields(logger, {
@@ -19,6 +20,7 @@ function make(source, logger, recordRequestStats, getHeightRetryInterval, pollTi
19
20
  recordRequestStats: recordRequestStats,
20
21
  getHeightRetryInterval: getHeightRetryInterval,
21
22
  pollTimeoutMillis: pollTimeoutMillis,
23
+ clock: clock,
22
24
  knownHeight: 0,
23
25
  waiters: [],
24
26
  stream: "NeverEnabled",
@@ -157,27 +159,29 @@ function heightWithin(feed) {
157
159
  _0: exn
158
160
  })),
159
161
  new Promise((resolve, _reject) => {
160
- timeoutId.contents = Primitive_option.some(setTimeout(() => {
162
+ timeoutId.contents = Primitive_option.some(feed.clock.setTimeout("height poll timeout", () => {
161
163
  timedOut.contents = true;
162
164
  resolve("TimedOut");
163
165
  }, feed.pollTimeoutMillis));
164
166
  })
165
167
  ]).then(outcome => {
166
- Utils.clearTimeoutRef(timeoutId);
168
+ Clock.clearRef(feed.clock, timeoutId);
167
169
  return outcome;
168
170
  });
169
171
  }
170
172
 
171
173
  function sleep(feed, kind, millis) {
172
174
  return new Promise((resolve, _reject) => {
173
- let timeoutId = setTimeout(() => {
175
+ let label;
176
+ label = kind === "Cadence" ? "height poll cadence" : "height poll backoff";
177
+ let timer = feed.clock.setTimeout(label, () => {
174
178
  feed.sleeping = undefined;
175
179
  resolve();
176
180
  }, millis);
177
181
  feed.sleeping = {
178
182
  kind: kind,
179
183
  wake: () => {
180
- clearTimeout(timeoutId);
184
+ feed.clock.clearTimeout(timer);
181
185
  feed.sleeping = undefined;
182
186
  resolve();
183
187
  }
@@ -370,7 +374,7 @@ function enableStream(feed) {
370
374
  if (typeof match$2 !== "object" && match$2 === "NeverEnabled") {
371
375
  feed.stream = "Disconnected";
372
376
  }
373
- feed.closeStream = match(height => handlePushedHeight(feed, height), status => handleStatus(feed, status));
377
+ feed.closeStream = match(feed.clock, height => handlePushedHeight(feed, height), status => handleStatus(feed, status));
374
378
  }
375
379
 
376
380
  function stop(feed) {
@@ -58,6 +58,7 @@ let truncateDetail = detail =>
58
58
  : detail
59
59
 
60
60
  let subscribe = (
61
+ ~clock: Clock.t,
61
62
  ~staleTimeout: int,
62
63
  ~onHeight: int => unit,
63
64
  ~onStatus: Source.heightSubscriptionStatus => unit,
@@ -85,7 +86,7 @@ let subscribe = (
85
86
  let liveAt = ref(None)
86
87
  let minProvenMillis = staleTimeout / provenStaleFraction
87
88
 
88
- let clearPendingTimeout = () => timeoutId->Utils.clearTimeoutRef
89
+ let clearPendingTimeout = () => clock->Clock.clearRef(timeoutId)
89
90
 
90
91
  // A transport that throws while closing must not be able to stop the retry
91
92
  // that follows, nor escape a timer callback and take the process down. Every
@@ -106,15 +107,22 @@ let subscribe = (
106
107
 
107
108
  let rec armStaleTimeout = () => {
108
109
  clearPendingTimeout()
109
- timeoutId := Some(setTimeout(() => {
110
- timeoutId := None
111
- // Distinguishes a provider whose message shape we don't understand
112
- // from a chain that simply has nothing to report.
113
- switch unreadableDetail.contents {
114
- | Some(detail) => fail(~reason=Source.Unreadable, ~detail)
115
- | None => fail(~reason=Source.Stale)
116
- }
117
- }, staleTimeout))
110
+ timeoutId :=
111
+ Some(
112
+ clock.setTimeout(
113
+ ~label="height stream stale",
114
+ () => {
115
+ timeoutId := None
116
+ // Distinguishes a provider whose message shape we don't understand
117
+ // from a chain that simply has nothing to report.
118
+ switch unreadableDetail.contents {
119
+ | Some(detail) => fail(~reason=Source.Unreadable, ~detail)
120
+ | None => fail(~reason=Source.Stale)
121
+ }
122
+ },
123
+ staleTimeout,
124
+ ),
125
+ )
118
126
  }
119
127
  and fail = (~reason: Source.heightSubscriptionDownReason, ~detail=?) => {
120
128
  generation := generation.contents + 1
@@ -128,7 +136,7 @@ let subscribe = (
128
136
  // bar rises with the backoff, so an endpoint that always dies at the same
129
137
  // age keeps escalating rather than settling into a loop at a fixed delay.
130
138
  let servedMillis = switch liveAt.contents {
131
- | Some(since) => (Performance.now() -. since)->Float.toInt
139
+ | Some(since) => (clock.now() -. since)->Float.toInt
132
140
  | None => 0
133
141
  }
134
142
  // Against the schedule, not against the jittered wait actually served. The
@@ -143,7 +151,7 @@ let subscribe = (
143
151
  failureCount.contents + 1
144
152
  }
145
153
 
146
- let retryMillis = retryDelayFor(failureCount.contents)->Utils.jitter
154
+ let retryMillis = clock->Clock.jitter(retryDelayFor(failureCount.contents))
147
155
 
148
156
  // A clean end to a connection that had proven itself is a rotation: routine,
149
157
  // and worth telling apart from the same clean end arriving early, which is a
@@ -157,10 +165,17 @@ let subscribe = (
157
165
 
158
166
  // Scheduled before reporting, so a consumer that throws can't be what makes
159
167
  // the stream give up.
160
- timeoutId := Some(setTimeout(() => {
161
- timeoutId := None
162
- start()
163
- }, retryMillis))
168
+ timeoutId :=
169
+ Some(
170
+ clock.setTimeout(
171
+ ~label="height stream retry",
172
+ () => {
173
+ timeoutId := None
174
+ start()
175
+ },
176
+ retryMillis,
177
+ ),
178
+ )
164
179
 
165
180
  onStatus(Down({reason, detail: ?(detail->Option.map(truncateDetail))}))
166
181
  }
@@ -183,7 +198,7 @@ let subscribe = (
183
198
  let goLive = () => {
184
199
  armStaleTimeout()
185
200
  if liveAt.contents->Option.isNone {
186
- liveAt := Some(Performance.now())
201
+ liveAt := Some(clock.now())
187
202
  onStatus(Live)
188
203
  }
189
204
  }
@@ -1,7 +1,7 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Clock from "../Clock.res.mjs";
3
4
  import * as Utils from "../Utils.res.mjs";
4
- import * as Performance from "../bindings/Performance.res.mjs";
5
5
  import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
6
6
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
7
7
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
@@ -23,7 +23,7 @@ function truncateDetail(detail) {
23
23
  }
24
24
  }
25
25
 
26
- function subscribe(staleTimeout, onHeight, onStatus, connect) {
26
+ function subscribe(clock, staleTimeout, onHeight, onStatus, connect) {
27
27
  let closeConnectionRef = {
28
28
  contents: undefined
29
29
  };
@@ -58,8 +58,8 @@ function subscribe(staleTimeout, onHeight, onStatus, connect) {
58
58
  closeConnectionRef.contents = undefined;
59
59
  };
60
60
  let armStaleTimeout = () => {
61
- Utils.clearTimeoutRef(timeoutId);
62
- timeoutId.contents = Primitive_option.some(setTimeout(() => {
61
+ Clock.clearRef(clock, timeoutId);
62
+ timeoutId.contents = Primitive_option.some(clock.setTimeout("height stream stale", () => {
63
63
  timeoutId.contents = undefined;
64
64
  let detail = unreadableDetail.contents;
65
65
  if (detail !== undefined) {
@@ -71,16 +71,16 @@ function subscribe(staleTimeout, onHeight, onStatus, connect) {
71
71
  };
72
72
  let fail = (reason, detail) => {
73
73
  generation.contents = generation.contents + 1 | 0;
74
- Utils.clearTimeoutRef(timeoutId);
74
+ Clock.clearRef(clock, timeoutId);
75
75
  closeConnection();
76
76
  let since = liveAt.contents;
77
- let servedMillis = since !== undefined ? Performance.now() - since | 0 : 0;
77
+ let servedMillis = since !== undefined ? clock.now() - since | 0 : 0;
78
78
  let provenMillis = Primitive_int.max(retryDelayFor(failureCount.contents), minProvenMillis);
79
79
  failureCount.contents = servedMillis >= provenMillis ? 1 : failureCount.contents + 1 | 0;
80
- let retryMillis = Utils.jitter(retryDelayFor(failureCount.contents));
80
+ let retryMillis = Clock.jitter(clock, retryDelayFor(failureCount.contents));
81
81
  let reason$1;
82
82
  reason$1 = typeof reason !== "object" && reason === "Closed" && servedMillis >= provenMillis ? "Rotated" : reason;
83
- timeoutId.contents = Primitive_option.some(setTimeout(() => {
83
+ timeoutId.contents = Primitive_option.some(clock.setTimeout("height stream retry", () => {
84
84
  timeoutId.contents = undefined;
85
85
  start();
86
86
  }, retryMillis));
@@ -99,7 +99,7 @@ function subscribe(staleTimeout, onHeight, onStatus, connect) {
99
99
  let goLive = () => {
100
100
  armStaleTimeout();
101
101
  if (Stdlib_Option.isNone(liveAt.contents)) {
102
- liveAt.contents = Performance.now();
102
+ liveAt.contents = clock.now();
103
103
  return onStatus("Live");
104
104
  }
105
105
  };
@@ -169,7 +169,7 @@ function subscribe(staleTimeout, onHeight, onStatus, connect) {
169
169
  start();
170
170
  return () => {
171
171
  generation.contents = generation.contents + 1 | 0;
172
- Utils.clearTimeoutRef(timeoutId);
172
+ Clock.clearRef(clock, timeoutId);
173
173
  closeConnection();
174
174
  };
175
175
  }
@@ -15,7 +15,8 @@ let requireApiToken = apiToken =>
15
15
  | None =>
16
16
  JsError.throwWithMessage(`An Envio API token is required for using HyperSync as a data-source.
17
17
  Set the ENVIO_API_TOKEN environment variable in your .env file.
18
- Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
18
+ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens
19
+ Or, signed in to Envio Cloud, get one with: envio-cloud token hypersync -o json`)
19
20
  }
20
21
 
21
22
  let isUnauthorizedError = (message: string) => message->String.includes("401 Unauthorized")
@@ -21,7 +21,8 @@ function requireApiToken(apiToken) {
21
21
  } else {
22
22
  return Stdlib_JsError.throwWithMessage(`An Envio API token is required for using HyperSync as a data-source.
23
23
  Set the ENVIO_API_TOKEN environment variable in your .env file.
24
- Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
24
+ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens
25
+ Or, signed in to Envio Cloud, get one with: envio-cloud token hypersync -o json`);
25
26
  }
26
27
  }
27
28
 
@@ -14,8 +14,8 @@ let failure = (error: EventSource.errorEvent): (
14
14
  | (None, None) => (Closed, None)
15
15
  }
16
16
 
17
- let subscribe = (~hyperSyncUrl, ~apiToken, ~onHeight, ~onStatus) =>
18
- HeightStream.subscribe(~staleTimeout, ~onHeight, ~onStatus, ~connect=driver => {
17
+ let subscribe = (~clock, ~hyperSyncUrl, ~apiToken, ~onHeight, ~onStatus) =>
18
+ HeightStream.subscribe(~clock, ~staleTimeout, ~onHeight, ~onStatus, ~connect=driver => {
19
19
  let userAgent = `hyperindex/${Utils.EnvioPackage.value.version}`
20
20
  let es = EventSource.create(
21
21
  ~url=`${hyperSyncUrl}/height/sse`,
@@ -24,10 +24,8 @@ let subscribe = (~hyperSyncUrl, ~apiToken, ~onHeight, ~onStatus) =>
24
24
  let headers =
25
25
  args.headers
26
26
  ->Option.getOr(Dict.make())
27
- ->Utils.Dict.merge(
28
- dict{"Authorization": `Bearer ${apiToken}`, "User-Agent": userAgent},
29
- )
30
- EventSource.Fetch.fetch(url, ~args={...args, headers: headers})
27
+ ->Utils.Dict.merge(dict{"Authorization": `Bearer ${apiToken}`, "User-Agent": userAgent})
28
+ EventSource.Fetch.fetch(url, ~args={...args, headers})
31
29
  },
32
30
  },
33
31
  )
@@ -30,8 +30,8 @@ function failure(error) {
30
30
  }
31
31
  }
32
32
 
33
- function subscribe(hyperSyncUrl, apiToken, onHeight, onStatus) {
34
- return HeightStream.subscribe(15000, onHeight, onStatus, driver => {
33
+ function subscribe(clock, hyperSyncUrl, apiToken, onHeight, onStatus) {
34
+ return HeightStream.subscribe(clock, 15000, onHeight, onStatus, driver => {
35
35
  let userAgent = `hyperindex/` + Utils.EnvioPackage.value.version;
36
36
  let es = new Eventsource.EventSource(hyperSyncUrl + `/height/sse`, {
37
37
  fetch: (url, args) => {
@@ -17,6 +17,10 @@ type options = {
17
17
  transactionStore: TransactionStore.t,
18
18
  ws?: string,
19
19
  headers?: dict<string>,
20
+ // How many addresses one `eth_getLogs` may carry when an address-free query
21
+ // the provider couldn't answer is read again by address.
22
+ maxAddressesPerRequest: int,
23
+ logger: Logger.t,
20
24
  }
21
25
 
22
26
  let make = (
@@ -33,6 +37,8 @@ let make = (
33
37
  transactionStore,
34
38
  ?ws,
35
39
  ?headers,
40
+ maxAddressesPerRequest,
41
+ logger,
36
42
  }: options,
37
43
  ): t => {
38
44
  let urlHost = switch Utils.Url.getHostFromUrl(url) {
@@ -53,6 +59,8 @@ let make = (
53
59
  ~syncConfig,
54
60
  ~headers?,
55
61
  ~addressStore,
62
+ ~maxAddressesPerRequest,
63
+ ~logger,
56
64
  )
57
65
 
58
66
  let getItemsOrThrow = async (
@@ -99,6 +107,7 @@ let make = (
99
107
  clientFilteredContracts: selection.clientFilteredContracts,
100
108
  retry,
101
109
  ?reorgableFrom,
110
+ knownHeight,
102
111
  },
103
112
  addressSet,
104
113
  blockStore,
@@ -219,7 +228,7 @@ let make = (
219
228
 
220
229
  let createHeightSubscription =
221
230
  ws->Option.map(wsUrl =>
222
- (~onHeight, ~onStatus) => EvmRpcWs.subscribe(~wsUrl, ~onHeight, ~onStatus)
231
+ (~clock, ~onHeight, ~onStatus) => EvmRpcWs.subscribe(~clock, ~wsUrl, ~onHeight, ~onStatus)
223
232
  )
224
233
 
225
234
  {
@@ -26,7 +26,7 @@ function make(param) {
26
26
  let urlHost = host !== undefined ? host : Stdlib_JsError.throwWithMessage(`The RPC url for chain ` + ChainId.toString(chainId) + ` is in incorrect format. The RPC url needs to start with either http:// or https://`);
27
27
  let name = `RPC (` + urlHost + `)`;
28
28
  let onBlockRegistrations = Stdlib_Option.getOr(param.onBlockRegistrations, []);
29
- let rpcClient = EvmRpcClient.make(url, !param.lowercaseAddresses, syncConfig, undefined, param.headers, HyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations), onBlockRegistrations, param.addressStore);
29
+ let rpcClient = EvmRpcClient.make(url, !param.lowercaseAddresses, syncConfig, undefined, param.headers, HyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations), onBlockRegistrations, param.addressStore, param.maxAddressesPerRequest, param.logger);
30
30
  let getItemsOrThrow = async (fromBlock, toBlock, addressSet, reorgableFrom, knownHeight, partitionId, selection, param, retry, param$1) => {
31
31
  let totalTimeRef = Performance.now();
32
32
  let toBlock$1 = toBlock !== undefined ? Primitive_int.min(toBlock, knownHeight) : knownHeight;
@@ -49,7 +49,8 @@ function make(param) {
49
49
  onBlockRegistrationIndexes: selection.onBlockRegistrations.map(reg => reg.index),
50
50
  clientFilteredContracts: selection.clientFilteredContracts,
51
51
  retry: retry,
52
- reorgableFrom: reorgableFrom
52
+ reorgableFrom: reorgableFrom,
53
+ knownHeight: knownHeight
53
54
  }, addressSet, blockStore, transactionStore);
54
55
  let result = match[0];
55
56
  let pageFetchTime = Performance.secondsSince(pageFetchTimeRef);
@@ -148,7 +149,7 @@ function make(param) {
148
149
  requestStats: result.requestStats
149
150
  };
150
151
  };
151
- let createHeightSubscription = Stdlib_Option.map(param.ws, wsUrl => ((onHeight, onStatus) => EvmRpcWs.subscribe(wsUrl, onHeight, onStatus)));
152
+ let createHeightSubscription = Stdlib_Option.map(param.ws, wsUrl => ((clock, onHeight, onStatus) => EvmRpcWs.subscribe(clock, wsUrl, onHeight, onStatus)));
152
153
  return {
153
154
  name: name,
154
155
  sourceFor: param.sourceFor,
@@ -240,6 +240,9 @@ type t = {
240
240
  ~logger: Logger.t,
241
241
  ) => promise<blockRangeFetchResponse>,
242
242
  createHeightSubscription?: (
243
+ // The stream's staleness and reconnect timers run on the clock of the
244
+ // manager that subscribes, not one the source was built with.
245
+ ~clock: Clock.t,
243
246
  ~onHeight: int => unit,
244
247
  ~onStatus: heightSubscriptionStatus => unit,
245
248
  ) => unit => unit,