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.
@@ -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, chain) {
19
+ function getSelectionConfig(selection) {
20
20
  let capitalizedBlockFields = new Set();
21
21
  let capitalizedTransactionFields = new Set();
22
- let staticTopicSelectionsByContract = {};
23
- let dynamicEventFiltersByContract = {};
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
- if (eventFilters.TAG === "Static") {
43
- return Utils.Dict.pushMany(staticTopicSelectionsByContract, contractName, eventFilters._0);
44
- } else {
45
- return Utils.Dict.push(reg.isWildcard ? dynamicWildcardEventFiltersByContract : dynamicEventFiltersByContract, contractName, eventFilters._0);
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 = staticTopicSelectionsByContract[contractName];
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 fns$1 = dynamicWildcardEventFiltersByContract[contractName];
91
- if (fns$1 !== undefined) {
92
- logSelections.push(LogSelection.make([], fns$1.flatMap(fn => fn(addresses))));
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(chain) {
105
- return Utils.$$WeakMap.memoize(selection => getSelectionConfig(selection, chain));
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 = memoGetSelectionConfig(chain);
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, ~chain) => {
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 staticByContract = Dict.make()
440
- let dynamicByContract = Dict.make()
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, getEventFiltersOrThrow} = reg
447
- let eventFilters = getEventFiltersOrThrow(chain)
445
+ let {isWildcard, dependsOnAddresses, resolvedWhere} = reg
448
446
  if dependsOnAddresses {
449
447
  contractNames->Utils.Set.add(contractName)->ignore
450
- switch eventFilters {
451
- | Internal.Static(topicSelections) =>
452
- staticByContract->Utils.Dict.pushMany(contractName, topicSelections)
453
- | Dynamic(fn) =>
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
- switch eventFilters {
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
- // Static + dynamic non-wildcard filters, scoped to this contract's addresses.
495
- let addressedTopicSelections = []
496
- switch staticByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
497
- | Some(s) => addressedTopicSelections->Array.pushMany(s)->ignore
498
- | None => ()
499
- }
500
- switch dynamicByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
501
- | Some(fns) =>
502
- fns->Array.forEach(fn =>
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
- // Dynamic wildcard-by-address filters fold the address into the topics,
498
+ // Wildcard-by-address filters fold the address into the topics,
512
499
  // so they still match any address.
513
- switch dynamicWildcardByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
514
- | Some(fns) =>
500
+ switch wildcardByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
501
+ | Some(topicSelections) =>
515
502
  logSelections
516
503
  ->Array.pushMany(
517
- toLogSelections(~addresses=None, fns->Array.flatMap(fn => fn(addresses))),
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 = (~chain) =>
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(~chain)
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, chain) {
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 staticByContract = {};
373
- let dynamicByContract = {};
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 eventFilters = reg.getEventFiltersOrThrow(chain);
377
+ let resolvedWhere = reg.resolvedWhere;
379
378
  if (reg.dependsOnAddresses) {
380
379
  contractNames.add(contractName);
381
- if (eventFilters.TAG === "Static") {
382
- return Utils.Dict.pushMany(staticByContract, contractName, eventFilters._0);
383
- } else {
384
- return Utils.Dict.push(reg.isWildcard ? dynamicWildcardByContract : dynamicByContract, contractName, eventFilters._0);
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 addressedTopicSelections = [];
407
- let s = staticByContract[contractName];
408
- if (s !== undefined) {
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
- logSelections.push(...toLogSelections(addresses, addressedTopicSelections));
418
- let fns$1 = dynamicWildcardByContract[contractName];
419
- if (fns$1 !== undefined) {
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(chain) {
432
- return Utils.$$WeakMap.memoize(selection => getSelectionConfig(selection, chain));
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 = memoGetSelectionConfig(chain);
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
- // Ceil (not truncate) so a sub-1 target from a sparse partition over a
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 target = Math.ceil(query.itemsTarget) | 0;
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;