envio 3.3.0-alpha.8 → 3.3.0-alpha.9
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 +6 -6
- package/src/ChainState.res +104 -37
- package/src/ChainState.res.mjs +80 -19
- package/src/ChainState.resi +4 -1
- package/src/CrossChainState.res +56 -29
- package/src/CrossChainState.res.mjs +11 -2
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +16 -17
- package/src/EventConfigBuilder.res.mjs +7 -6
- package/src/FetchState.res +151 -130
- package/src/FetchState.res.mjs +105 -88
- package/src/HandlerLoader.res +1 -1
- package/src/HandlerLoader.res.mjs +1 -1
- package/src/HandlerRegister.res +476 -305
- package/src/HandlerRegister.res.mjs +276 -209
- package/src/HandlerRegister.resi +11 -6
- package/src/Internal.res +23 -4
- package/src/LogSelection.res +102 -165
- package/src/LogSelection.res.mjs +101 -116
- package/src/Main.res +29 -143
- package/src/Main.res.mjs +25 -88
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateItems.res +1 -1
- package/src/sources/Evm.res +4 -1
- package/src/sources/Evm.res.mjs +1 -1
- package/src/sources/Fuel.res +3 -1
- package/src/sources/Fuel.res.mjs +1 -1
- package/src/sources/HyperSyncSource.res +22 -33
- package/src/sources/HyperSyncSource.res.mjs +17 -26
- package/src/sources/RpcSource.res +28 -39
- package/src/sources/RpcSource.res.mjs +18 -31
- package/src/sources/SourceManager.res +1 -7
- package/src/sources/SourceManager.res.mjs +1 -2
|
@@ -16,17 +16,17 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
|
|
|
16
16
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
17
17
|
import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
|
|
18
18
|
|
|
19
|
-
function getSelectionConfig(selection
|
|
19
|
+
function getSelectionConfig(selection) {
|
|
20
20
|
let capitalizedBlockFields = new Set();
|
|
21
21
|
let capitalizedTransactionFields = new Set();
|
|
22
|
-
let
|
|
23
|
-
let
|
|
24
|
-
let dynamicWildcardEventFiltersByContract = {};
|
|
22
|
+
let topicSelectionsByContract = {};
|
|
23
|
+
let wildcardTopicSelectionsByContract = {};
|
|
25
24
|
let noAddressesTopicSelections = [];
|
|
26
25
|
let contractNames = new Set();
|
|
27
26
|
selection.onEventRegistrations.forEach(reg => {
|
|
28
27
|
let eventConfig = reg.eventConfig;
|
|
29
28
|
let contractName = eventConfig.contractName;
|
|
29
|
+
let resolvedWhere = reg.resolvedWhere;
|
|
30
30
|
Array.from(eventConfig.selectedBlockFields).forEach(name => {
|
|
31
31
|
capitalizedBlockFields.add(Utils.$$String.capitalize(name));
|
|
32
32
|
});
|
|
@@ -36,18 +36,13 @@ function getSelectionConfig(selection, chain) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
let eventFilters = reg.getEventFiltersOrThrow(chain);
|
|
40
39
|
if (reg.dependsOnAddresses) {
|
|
41
40
|
contractNames.add(contractName);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
41
|
+
return Utils.Dict.pushMany(reg.isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract, contractName, resolvedWhere.topicSelections);
|
|
42
|
+
} else {
|
|
43
|
+
noAddressesTopicSelections.push(...LogSelection.materializeTopicSelections(resolvedWhere.topicSelections, []));
|
|
44
|
+
return;
|
|
47
45
|
}
|
|
48
|
-
let tmp;
|
|
49
|
-
tmp = eventFilters.TAG === "Static" ? eventFilters._0 : eventFilters._0([]);
|
|
50
|
-
noAddressesTopicSelections.push(...tmp);
|
|
51
46
|
});
|
|
52
47
|
let fieldSelection_block = Array.from(capitalizedBlockFields);
|
|
53
48
|
let fieldSelection_transaction = Array.from(capitalizedTransactionFields);
|
|
@@ -79,17 +74,13 @@ function getSelectionConfig(selection, chain) {
|
|
|
79
74
|
if (addresses.length === 0) {
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
82
|
-
let topicSelections =
|
|
77
|
+
let topicSelections = topicSelectionsByContract[contractName];
|
|
83
78
|
if (topicSelections !== undefined) {
|
|
84
|
-
logSelections.push(LogSelection.make(addresses, topicSelections));
|
|
85
|
-
}
|
|
86
|
-
let fns = dynamicEventFiltersByContract[contractName];
|
|
87
|
-
if (fns !== undefined) {
|
|
88
|
-
logSelections.push(LogSelection.make(addresses, fns.flatMap(fn => fn(addresses))));
|
|
79
|
+
logSelections.push(LogSelection.make(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
|
|
89
80
|
}
|
|
90
|
-
let
|
|
91
|
-
if (
|
|
92
|
-
logSelections.push(LogSelection.make([],
|
|
81
|
+
let topicSelections$1 = wildcardTopicSelectionsByContract[contractName];
|
|
82
|
+
if (topicSelections$1 !== undefined) {
|
|
83
|
+
logSelections.push(LogSelection.make([], LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
|
|
93
84
|
return;
|
|
94
85
|
}
|
|
95
86
|
});
|
|
@@ -101,8 +92,8 @@ function getSelectionConfig(selection, chain) {
|
|
|
101
92
|
};
|
|
102
93
|
}
|
|
103
94
|
|
|
104
|
-
function memoGetSelectionConfig(
|
|
105
|
-
return Utils.$$WeakMap.memoize(
|
|
95
|
+
function memoGetSelectionConfig() {
|
|
96
|
+
return Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
106
97
|
}
|
|
107
98
|
|
|
108
99
|
function isUnauthorizedError(message) {
|
|
@@ -115,7 +106,7 @@ function make(param) {
|
|
|
115
106
|
let endpointUrl = param.endpointUrl;
|
|
116
107
|
let chain = param.chain;
|
|
117
108
|
let name = "HyperSync";
|
|
118
|
-
let getSelectionConfig =
|
|
109
|
+
let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
119
110
|
let apiToken$1 = apiToken !== undefined ? apiToken : Stdlib_JsError.throwWithMessage(`An Envio API token is required for using HyperSync as a data-source.
|
|
120
111
|
Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
121
112
|
Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
@@ -148,7 +139,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
148
139
|
};
|
|
149
140
|
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, itemsTarget, retry, logger) => {
|
|
150
141
|
let totalTimeRef = Performance.now();
|
|
151
|
-
let selectionConfig = getSelectionConfig(selection);
|
|
142
|
+
let selectionConfig = getSelectionConfig$1(selection);
|
|
152
143
|
let logSelections;
|
|
153
144
|
try {
|
|
154
145
|
logSelections = selectionConfig.getLogSelectionOrThrow(addressesByContractName);
|
|
@@ -412,7 +412,7 @@ type selectionConfig = {
|
|
|
412
412
|
) => array<logSelection>,
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
-
let getSelectionConfig = (selection: FetchState.selection
|
|
415
|
+
let getSelectionConfig = (selection: FetchState.selection) => {
|
|
416
416
|
let evmOnEventRegistrations =
|
|
417
417
|
selection.onEventRegistrations->(
|
|
418
418
|
Utils.magic: array<Internal.onEventRegistration> => array<Internal.evmOnEventRegistration>
|
|
@@ -436,33 +436,23 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
436
436
|
// re-applies it). Pure-wildcard events carry no address constraint, so they're
|
|
437
437
|
// pooled and resolved once.
|
|
438
438
|
let noAddressTopicSelections = []
|
|
439
|
-
let
|
|
440
|
-
let
|
|
441
|
-
let dynamicWildcardByContract = Dict.make()
|
|
439
|
+
let byContract = Dict.make()
|
|
440
|
+
let wildcardByContract = Dict.make()
|
|
442
441
|
let contractNames = Utils.Set.make()
|
|
443
442
|
|
|
444
443
|
evmOnEventRegistrations->Array.forEach(reg => {
|
|
445
444
|
let contractName = reg.eventConfig.contractName
|
|
446
|
-
let {isWildcard, dependsOnAddresses,
|
|
447
|
-
let eventFilters = getEventFiltersOrThrow(chain)
|
|
445
|
+
let {isWildcard, dependsOnAddresses, resolvedWhere} = reg
|
|
448
446
|
if dependsOnAddresses {
|
|
449
447
|
contractNames->Utils.Set.add(contractName)->ignore
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
(isWildcard ? dynamicWildcardByContract : dynamicByContract)->Utils.Dict.push(
|
|
455
|
-
contractName,
|
|
456
|
-
fn,
|
|
457
|
-
)
|
|
458
|
-
}
|
|
448
|
+
(isWildcard ? wildcardByContract : byContract)->Utils.Dict.pushMany(
|
|
449
|
+
contractName,
|
|
450
|
+
resolvedWhere.topicSelections,
|
|
451
|
+
)
|
|
459
452
|
} else {
|
|
460
453
|
noAddressTopicSelections
|
|
461
454
|
->Array.pushMany(
|
|
462
|
-
|
|
463
|
-
| Static(s) => s
|
|
464
|
-
| Dynamic(fn) => fn([])
|
|
465
|
-
},
|
|
455
|
+
resolvedWhere.topicSelections->LogSelection.materializeTopicSelections(~addresses=[]),
|
|
466
456
|
)
|
|
467
457
|
->ignore
|
|
468
458
|
}
|
|
@@ -491,30 +481,30 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
491
481
|
| None
|
|
492
482
|
| Some([]) => ()
|
|
493
483
|
| Some(addresses) =>
|
|
494
|
-
//
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
addressedTopicSelections->Array.pushMany(fn(addresses))->ignore
|
|
484
|
+
// Non-wildcard filters, scoped to this contract's addresses.
|
|
485
|
+
switch byContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
486
|
+
| Some(topicSelections) =>
|
|
487
|
+
logSelections
|
|
488
|
+
->Array.pushMany(
|
|
489
|
+
toLogSelections(
|
|
490
|
+
~addresses=Some(addresses),
|
|
491
|
+
topicSelections->LogSelection.materializeTopicSelections(~addresses),
|
|
492
|
+
),
|
|
504
493
|
)
|
|
494
|
+
->ignore
|
|
505
495
|
| None => ()
|
|
506
496
|
}
|
|
507
|
-
logSelections
|
|
508
|
-
->Array.pushMany(toLogSelections(~addresses=Some(addresses), addressedTopicSelections))
|
|
509
|
-
->ignore
|
|
510
497
|
|
|
511
|
-
//
|
|
498
|
+
// Wildcard-by-address filters fold the address into the topics,
|
|
512
499
|
// so they still match any address.
|
|
513
|
-
switch
|
|
514
|
-
| Some(
|
|
500
|
+
switch wildcardByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
501
|
+
| Some(topicSelections) =>
|
|
515
502
|
logSelections
|
|
516
503
|
->Array.pushMany(
|
|
517
|
-
toLogSelections(
|
|
504
|
+
toLogSelections(
|
|
505
|
+
~addresses=None,
|
|
506
|
+
topicSelections->LogSelection.materializeTopicSelections(~addresses),
|
|
507
|
+
),
|
|
518
508
|
)
|
|
519
509
|
->ignore
|
|
520
510
|
| None => ()
|
|
@@ -530,8 +520,7 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
530
520
|
}
|
|
531
521
|
}
|
|
532
522
|
|
|
533
|
-
let memoGetSelectionConfig = (
|
|
534
|
-
Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
|
|
523
|
+
let memoGetSelectionConfig = () => Utils.WeakMap.memoize(getSelectionConfig)
|
|
535
524
|
|
|
536
525
|
// Type-erase a schema for storage in the field registry
|
|
537
526
|
external toFieldSchema: S.t<'a> => S.t<JSON.t> = "%identity"
|
|
@@ -1021,7 +1010,7 @@ let make = (
|
|
|
1021
1010
|
}
|
|
1022
1011
|
let name = `RPC (${urlHost})`
|
|
1023
1012
|
|
|
1024
|
-
let getSelectionConfig = memoGetSelectionConfig(
|
|
1013
|
+
let getSelectionConfig = memoGetSelectionConfig()
|
|
1025
1014
|
|
|
1026
1015
|
// Per-partition adaptive block interval (AIMD), keyed by partitionId. The
|
|
1027
1016
|
// `max` key holds a source-wide ceiling that only ever tightens, set by
|
|
@@ -356,7 +356,7 @@ function getNextPage(fromBlock, toBlock, logSelections, loadBlock, sc, rpcClient
|
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
function getSelectionConfig(selection
|
|
359
|
+
function getSelectionConfig(selection) {
|
|
360
360
|
let evmOnEventRegistrations = selection.onEventRegistrations;
|
|
361
361
|
if (Utils.$$Array.isEmpty(evmOnEventRegistrations)) {
|
|
362
362
|
throw {
|
|
@@ -369,24 +369,19 @@ function getSelectionConfig(selection, chain) {
|
|
|
369
369
|
};
|
|
370
370
|
}
|
|
371
371
|
let noAddressTopicSelections = [];
|
|
372
|
-
let
|
|
373
|
-
let
|
|
374
|
-
let dynamicWildcardByContract = {};
|
|
372
|
+
let byContract = {};
|
|
373
|
+
let wildcardByContract = {};
|
|
375
374
|
let contractNames = new Set();
|
|
376
375
|
evmOnEventRegistrations.forEach(reg => {
|
|
377
376
|
let contractName = reg.eventConfig.contractName;
|
|
378
|
-
let
|
|
377
|
+
let resolvedWhere = reg.resolvedWhere;
|
|
379
378
|
if (reg.dependsOnAddresses) {
|
|
380
379
|
contractNames.add(contractName);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
380
|
+
return Utils.Dict.pushMany(reg.isWildcard ? wildcardByContract : byContract, contractName, resolvedWhere.topicSelections);
|
|
381
|
+
} else {
|
|
382
|
+
noAddressTopicSelections.push(...LogSelection.materializeTopicSelections(resolvedWhere.topicSelections, []));
|
|
383
|
+
return;
|
|
386
384
|
}
|
|
387
|
-
let tmp;
|
|
388
|
-
tmp = eventFilters.TAG === "Static" ? eventFilters._0 : eventFilters._0([]);
|
|
389
|
-
noAddressTopicSelections.push(...tmp);
|
|
390
385
|
});
|
|
391
386
|
let toLogSelections = (addresses, topicSelections) => LogSelection.compressTopicSelections(topicSelections).map(topicSelection => ({
|
|
392
387
|
addresses: addresses,
|
|
@@ -403,21 +398,13 @@ function getSelectionConfig(selection, chain) {
|
|
|
403
398
|
if (addresses.length === 0) {
|
|
404
399
|
return;
|
|
405
400
|
}
|
|
406
|
-
let
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
addressedTopicSelections.push(...s);
|
|
410
|
-
}
|
|
411
|
-
let fns = dynamicByContract[contractName];
|
|
412
|
-
if (fns !== undefined) {
|
|
413
|
-
fns.forEach(fn => {
|
|
414
|
-
addressedTopicSelections.push(...fn(addresses));
|
|
415
|
-
});
|
|
401
|
+
let topicSelections = byContract[contractName];
|
|
402
|
+
if (topicSelections !== undefined) {
|
|
403
|
+
logSelections.push(...toLogSelections(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
|
|
416
404
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
logSelections.push(...toLogSelections(undefined, fns$1.flatMap(fn => fn(addresses))));
|
|
405
|
+
let topicSelections$1 = wildcardByContract[contractName];
|
|
406
|
+
if (topicSelections$1 !== undefined) {
|
|
407
|
+
logSelections.push(...toLogSelections(undefined, LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
|
|
421
408
|
return;
|
|
422
409
|
}
|
|
423
410
|
});
|
|
@@ -428,8 +415,8 @@ function getSelectionConfig(selection, chain) {
|
|
|
428
415
|
};
|
|
429
416
|
}
|
|
430
417
|
|
|
431
|
-
function memoGetSelectionConfig(
|
|
432
|
-
return Utils.$$WeakMap.memoize(
|
|
418
|
+
function memoGetSelectionConfig() {
|
|
419
|
+
return Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
433
420
|
}
|
|
434
421
|
|
|
435
422
|
let lowercaseAddressSchema = S$RescriptSchema.transform(S$RescriptSchema.string, param => ({
|
|
@@ -973,7 +960,7 @@ function make(param) {
|
|
|
973
960
|
let host = Utils.Url.getHostFromUrl(url);
|
|
974
961
|
let urlHost = host !== undefined ? host : Stdlib_JsError.throwWithMessage(`The RPC url for chain ` + chain.toString() + ` is in incorrect format. The RPC url needs to start with either http:// or https://`);
|
|
975
962
|
let name = `RPC (` + urlHost + `)`;
|
|
976
|
-
let getSelectionConfig =
|
|
963
|
+
let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
977
964
|
let mutSuggestedBlockIntervals = {};
|
|
978
965
|
let client = Rpc.makeClient(url, headers);
|
|
979
966
|
let rpcClient = EvmRpcClient.make(url, !lowercaseAddresses, undefined, headers, param.allEventParams);
|
|
@@ -1069,7 +1056,7 @@ function make(param) {
|
|
|
1069
1056
|
let toBlock$1 = toBlock !== undefined ? Primitive_int.min(toBlock, knownHeight) : knownHeight;
|
|
1070
1057
|
let suggestedToBlock = Primitive_int.max(Primitive_int.min((fromBlock + suggestedBlockInterval | 0) - 1 | 0, toBlock$1), fromBlock);
|
|
1071
1058
|
let firstBlockParentPromise = fromBlock > 0 ? LazyLoader.get(blockLoader.contents, fromBlock - 1 | 0).then(json => parseBlockInfo(json)) : Promise.resolve(undefined);
|
|
1072
|
-
let match = getSelectionConfig(selection);
|
|
1059
|
+
let match = getSelectionConfig$1(selection);
|
|
1073
1060
|
let logSelections = match.getLogSelectionsOrThrow(addressesByContractName);
|
|
1074
1061
|
let match$1 = await getNextPage(fromBlock, suggestedToBlock, logSelections, blockNumber => LazyLoader.get(blockLoader.contents, blockNumber).then(parseBlockInfo), syncConfig, rpcClient, mutSuggestedBlockIntervals, partitionId, recordRequest);
|
|
1075
1062
|
let latestFetchedBlockInfo = match$1.latestFetchedBlockInfo;
|
|
@@ -734,13 +734,7 @@ let executeQuery = async (
|
|
|
734
734
|
~partitionId=query.partitionId,
|
|
735
735
|
~knownHeight,
|
|
736
736
|
~selection=query.selection,
|
|
737
|
-
|
|
738
|
-
// small range doesn't round down to 0 and ask the backend to cap the
|
|
739
|
-
// response at nothing — 0 items is indistinguishable from "no signal".
|
|
740
|
-
~itemsTarget={
|
|
741
|
-
let target = query.itemsTarget->Math.ceil->Float.toInt
|
|
742
|
-
target > 0 ? target : FetchState.minItemsTarget->Float.toInt
|
|
743
|
-
},
|
|
737
|
+
~itemsTarget=query.itemsTarget,
|
|
744
738
|
~retry,
|
|
745
739
|
~logger,
|
|
746
740
|
)
|
|
@@ -543,8 +543,7 @@ async function executeQuery(sourceManager, query, knownHeight, isRealtime) {
|
|
|
543
543
|
retry: retry
|
|
544
544
|
});
|
|
545
545
|
try {
|
|
546
|
-
let
|
|
547
|
-
let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, target > 0 ? target : FetchState.minItemsTarget | 0, retry, logger$2);
|
|
546
|
+
let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, query.itemsTarget, retry, logger$2);
|
|
548
547
|
recordRequestStats(sourceState, response.requestStats);
|
|
549
548
|
sourceState.lastFailedAt = undefined;
|
|
550
549
|
responseRef = response;
|