envio 3.5.0-alpha.1 → 3.5.0-alpha.3
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/index.d.ts +10 -6
- package/package.json +6 -6
- package/src/BatchProcessing.res +27 -0
- package/src/BatchProcessing.res.mjs +12 -0
- package/src/ChainFetching.res +5 -5
- package/src/ChainFetching.res.mjs +3 -4
- package/src/ChainState.res +48 -25
- package/src/ChainState.res.mjs +23 -29
- package/src/ChainState.resi +2 -6
- package/src/Change.res +3 -3
- package/src/Config.res +2 -6
- package/src/Config.res.mjs +2 -12
- package/src/Core.res +3 -0
- package/src/CrossChainState.res +33 -10
- package/src/CrossChainState.res.mjs +21 -6
- package/src/CrossChainState.resi +3 -0
- package/src/EntityId.res +15 -0
- package/src/EntityId.res.mjs +9 -0
- package/src/EventConfigBuilder.res +1 -58
- package/src/EventConfigBuilder.res.mjs +1 -33
- package/src/FetchState.res +510 -460
- package/src/FetchState.res.mjs +413 -428
- package/src/FinalizeBackfill.res +34 -0
- package/src/FinalizeBackfill.res.mjs +26 -0
- package/src/HandlerRegister.res +45 -0
- package/src/HandlerRegister.res.mjs +43 -0
- package/src/InMemoryStore.res +11 -4
- package/src/InMemoryTable.res +26 -24
- package/src/InMemoryTable.res.mjs +19 -18
- package/src/IndexerState.res +71 -2
- package/src/IndexerState.res.mjs +67 -3
- package/src/IndexerState.resi +5 -0
- package/src/Internal.res +17 -8
- package/src/LoadLayer.res +9 -1
- package/src/LoadLayer.res.mjs +1 -0
- package/src/LogSelection.res +2 -1
- package/src/Metrics.res +37 -6
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +12 -1
- package/src/PgStorage.res +411 -57
- package/src/PgStorage.res.mjs +262 -41
- package/src/SimulateItems.res +2 -2
- package/src/TestIndexer.res +9 -5
- package/src/TestIndexer.res.mjs +5 -2
- package/src/UserContext.res +3 -3
- package/src/Writing.res +12 -2
- package/src/Writing.res.mjs +13 -2
- package/src/bindings/ClickHouse.res +5 -3
- package/src/bindings/ClickHouse.res.mjs +2 -5
- package/src/bindings/Vitest.res +22 -1
- package/src/bindings/Vitest.res.mjs +15 -0
- package/src/db/EntityFilter.res +0 -4
- package/src/db/EntityFilter.res.mjs +1 -8
- package/src/db/EntityHistory.res +16 -7
- package/src/db/EntityHistory.res.mjs +7 -6
- package/src/db/IndexRegistry.res +219 -0
- package/src/db/IndexRegistry.res.mjs +195 -0
- package/src/db/InternalTable.res +7 -0
- package/src/db/InternalTable.res.mjs +7 -0
- package/src/db/Table.res +53 -22
- package/src/db/Table.res.mjs +56 -18
- package/src/sources/AddressSet.res +48 -0
- package/src/sources/AddressSet.res.mjs +11 -0
- package/src/sources/AddressStore.res +152 -0
- package/src/sources/AddressStore.res.mjs +97 -0
- package/src/sources/EvmChain.res +3 -0
- package/src/sources/EvmChain.res.mjs +4 -2
- package/src/sources/EvmHyperSyncSource.res +6 -3
- package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
- package/src/sources/EvmRpcClient.res +6 -3
- package/src/sources/EvmRpcClient.res.mjs +3 -3
- package/src/sources/FuelHyperSync.res +4 -3
- package/src/sources/FuelHyperSync.res.mjs +3 -3
- package/src/sources/FuelHyperSync.resi +2 -1
- package/src/sources/FuelHyperSyncClient.res +12 -6
- package/src/sources/FuelHyperSyncClient.res.mjs +2 -2
- package/src/sources/FuelHyperSyncSource.res +7 -4
- package/src/sources/FuelHyperSyncSource.res.mjs +3 -3
- package/src/sources/HyperSync.res +6 -4
- package/src/sources/HyperSync.res.mjs +2 -3
- package/src/sources/HyperSync.resi +1 -1
- package/src/sources/HyperSyncClient.res +18 -9
- package/src/sources/HyperSyncClient.res.mjs +4 -4
- package/src/sources/RpcSource.res +15 -10
- package/src/sources/RpcSource.res.mjs +3 -4
- package/src/sources/SimulateSource.res +26 -11
- package/src/sources/SimulateSource.res.mjs +13 -5
- package/src/sources/Source.res +4 -2
- package/src/sources/SourceManager.res +2 -3
- package/src/sources/SourceManager.res.mjs +2 -3
- package/src/sources/Svm.res +1 -2
- package/src/sources/Svm.res.mjs +1 -1
- package/src/sources/SvmHyperSyncClient.res +12 -3
- package/src/sources/SvmHyperSyncClient.res.mjs +2 -2
- package/src/sources/SvmHyperSyncSource.res +10 -5
- package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
- package/src/IndexingAddresses.res +0 -151
- package/src/IndexingAddresses.res.mjs +0 -130
- package/src/IndexingAddresses.resi +0 -39
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
type indexingAddress = Internal.indexingContract
|
|
2
|
-
|
|
3
|
-
type contractConfig = {startBlock: option<int>}
|
|
4
|
-
|
|
5
|
-
// Grouped by contract name, then by address string. Contracts are few, so
|
|
6
|
-
// per-contract operations (address count, the client-side filter's lookup
|
|
7
|
-
// dict) are direct, and whole-index scans (get by address, rollback) walk the
|
|
8
|
-
// small contract set. Address strings are globally unique across contracts
|
|
9
|
-
// (conflicting registrations are rejected before they reach here).
|
|
10
|
-
type t = dict<dict<indexingAddress>>
|
|
11
|
-
|
|
12
|
-
let deriveEffectiveStartBlock = (~registrationBlock: int, ~contractStartBlock: option<int>) => {
|
|
13
|
-
Pervasives.max(Pervasives.max(registrationBlock, 0), contractStartBlock->Option.getOr(0))
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let makeContractConfigs = (~onEventRegistrations: array<Internal.onEventRegistration>): dict<
|
|
17
|
-
contractConfig,
|
|
18
|
-
> => {
|
|
19
|
-
let contractConfigs: dict<contractConfig> = Dict.make()
|
|
20
|
-
onEventRegistrations->Array.forEach(reg => {
|
|
21
|
-
let contractName = reg.eventConfig.contractName
|
|
22
|
-
switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
23
|
-
| Some({startBlock}) =>
|
|
24
|
-
contractConfigs->Dict.set(
|
|
25
|
-
contractName,
|
|
26
|
-
{
|
|
27
|
-
startBlock: switch (startBlock, reg.startBlock) {
|
|
28
|
-
| (Some(a), Some(b)) => Some(Pervasives.min(a, b))
|
|
29
|
-
| (Some(_) as s, None) | (None, Some(_) as s) => s
|
|
30
|
-
| (None, None) => None
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
)
|
|
34
|
-
| None =>
|
|
35
|
-
contractConfigs->Dict.set(
|
|
36
|
-
contractName,
|
|
37
|
-
{
|
|
38
|
-
startBlock: reg.startBlock,
|
|
39
|
-
},
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
contractConfigs
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let makeIndexingAddress = (
|
|
47
|
-
~contract: Internal.indexingAddress,
|
|
48
|
-
~contractConfigs: dict<contractConfig>,
|
|
49
|
-
): indexingAddress => {
|
|
50
|
-
let contractStartBlock = switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(
|
|
51
|
-
contract.contractName,
|
|
52
|
-
) {
|
|
53
|
-
| Some({startBlock}) => startBlock
|
|
54
|
-
| None => None
|
|
55
|
-
}
|
|
56
|
-
{
|
|
57
|
-
address: contract.address,
|
|
58
|
-
contractName: contract.contractName,
|
|
59
|
-
registrationBlock: contract.registrationBlock,
|
|
60
|
-
effectiveStartBlock: deriveEffectiveStartBlock(
|
|
61
|
-
~registrationBlock=contract.registrationBlock,
|
|
62
|
-
~contractStartBlock,
|
|
63
|
-
),
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let insert = (indexingAddresses: t, indexingAddress: indexingAddress) => {
|
|
68
|
-
indexingAddresses
|
|
69
|
-
->Utils.Dict.getOrInsertEmptyDict(indexingAddress.contractName)
|
|
70
|
-
->Dict.set(indexingAddress.address->Address.toString, indexingAddress)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
let make = (
|
|
74
|
-
~contractConfigs: dict<contractConfig>,
|
|
75
|
-
~addresses: array<Internal.indexingAddress>,
|
|
76
|
-
): t => {
|
|
77
|
-
let indexingAddresses = Dict.make()
|
|
78
|
-
addresses->Array.forEach(contract => {
|
|
79
|
-
indexingAddresses->insert(makeIndexingAddress(~contract, ~contractConfigs))
|
|
80
|
-
})
|
|
81
|
-
indexingAddresses
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Address strings are globally unique, so the first inner dict holding the
|
|
85
|
-
// address owns it. for..in returns on the first hit without allocating a values
|
|
86
|
-
// array per lookup (get runs once per registration).
|
|
87
|
-
let get: (t, string) => option<indexingAddress> = %raw(`(index, address) => {
|
|
88
|
-
for (var contractName in index) {
|
|
89
|
-
var entry = index[contractName][address];
|
|
90
|
-
if (entry !== undefined) {
|
|
91
|
-
return entry;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return undefined;
|
|
95
|
-
}`)
|
|
96
|
-
|
|
97
|
-
let size = (indexingAddresses: t) => {
|
|
98
|
-
let total = ref(0)
|
|
99
|
-
indexingAddresses->Utils.Dict.forEach(inner => {
|
|
100
|
-
total := total.contents + inner->Utils.Dict.size
|
|
101
|
-
})
|
|
102
|
-
total.contents
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Number of registered addresses for a single contract — a for..in over that
|
|
106
|
-
// one contract's addresses. The trigger deciding when to switch a contract to
|
|
107
|
-
// client-side filtering reads this.
|
|
108
|
-
let contractCount = (indexingAddresses: t, ~contractName) =>
|
|
109
|
-
switch indexingAddresses->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
110
|
-
| Some(inner) => inner->Utils.Dict.size
|
|
111
|
-
| None => 0
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
let getContractAddresses = (indexingAddresses: t, ~contractName): array<Address.t> => {
|
|
115
|
-
switch indexingAddresses->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
116
|
-
| Some(inner) => inner->Dict.valuesToArray->Array.map(ia => ia.address)
|
|
117
|
-
| None => []
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
let emptyContractDict: dict<indexingAddress> = Dict.make()
|
|
122
|
-
|
|
123
|
-
// The address→entry dict for a single contract, passed to that contract's
|
|
124
|
-
// precompiled `clientAddressFilter` (which does raw `byAddr[srcAddress]` access
|
|
125
|
-
// in generated JS). Every leaf of a filter references the event's own contract
|
|
126
|
-
// — `chain.<Contract>.addresses` only exposes the event's contract — so one
|
|
127
|
-
// inner dict covers the srcAddress and param-address checks alike. Returns a
|
|
128
|
-
// shared empty dict when the contract has no registered addresses.
|
|
129
|
-
let forContract = (indexingAddresses: t, ~contractName): dict<indexingAddress> =>
|
|
130
|
-
switch indexingAddresses->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
131
|
-
| Some(inner) => inner
|
|
132
|
-
| None => emptyContractDict
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
let register = (indexingAddresses: t, additions: dict<indexingAddress>) => {
|
|
136
|
-
additions->Utils.Dict.forEach(indexingAddress => {
|
|
137
|
-
indexingAddresses->insert(indexingAddress)
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
let rollbackInPlace = (indexingAddresses: t, ~targetBlockNumber: int): unit => {
|
|
142
|
-
// forEachWithKey is a `for..in`, so deleting the key currently being visited is
|
|
143
|
-
// safe — it doesn't affect enumeration of the remaining keys.
|
|
144
|
-
indexingAddresses->Utils.Dict.forEach(inner => {
|
|
145
|
-
inner->Utils.Dict.forEachWithKey((indexingContract, address) => {
|
|
146
|
-
if indexingContract.registrationBlock > targetBlockNumber {
|
|
147
|
-
inner->Utils.Dict.deleteInPlace(address)
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Utils from "./Utils.res.mjs";
|
|
4
|
-
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
5
|
-
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
|
-
|
|
7
|
-
function deriveEffectiveStartBlock(registrationBlock, contractStartBlock) {
|
|
8
|
-
return Primitive_int.max(Primitive_int.max(registrationBlock, 0), Stdlib_Option.getOr(contractStartBlock, 0));
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function makeContractConfigs(onEventRegistrations) {
|
|
12
|
-
let contractConfigs = {};
|
|
13
|
-
onEventRegistrations.forEach(reg => {
|
|
14
|
-
let contractName = reg.eventConfig.contractName;
|
|
15
|
-
let match = contractConfigs[contractName];
|
|
16
|
-
if (match !== undefined) {
|
|
17
|
-
let startBlock = match.startBlock;
|
|
18
|
-
let match$1 = reg.startBlock;
|
|
19
|
-
contractConfigs[contractName] = {
|
|
20
|
-
startBlock: startBlock !== undefined ? (
|
|
21
|
-
match$1 !== undefined ? Primitive_int.min(startBlock, match$1) : startBlock
|
|
22
|
-
) : (
|
|
23
|
-
match$1 !== undefined ? match$1 : undefined
|
|
24
|
-
)
|
|
25
|
-
};
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
contractConfigs[contractName] = {
|
|
29
|
-
startBlock: reg.startBlock
|
|
30
|
-
};
|
|
31
|
-
});
|
|
32
|
-
return contractConfigs;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function makeIndexingAddress(contract, contractConfigs) {
|
|
36
|
-
let match = contractConfigs[contract.contractName];
|
|
37
|
-
let contractStartBlock = match !== undefined ? match.startBlock : undefined;
|
|
38
|
-
return {
|
|
39
|
-
address: contract.address,
|
|
40
|
-
contractName: contract.contractName,
|
|
41
|
-
registrationBlock: contract.registrationBlock,
|
|
42
|
-
effectiveStartBlock: deriveEffectiveStartBlock(contract.registrationBlock, contractStartBlock)
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function insert(indexingAddresses, indexingAddress) {
|
|
47
|
-
Utils.Dict.getOrInsertEmptyDict(indexingAddresses, indexingAddress.contractName)[indexingAddress.address] = indexingAddress;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function make(contractConfigs, addresses) {
|
|
51
|
-
let indexingAddresses = {};
|
|
52
|
-
addresses.forEach(contract => insert(indexingAddresses, makeIndexingAddress(contract, contractConfigs)));
|
|
53
|
-
return indexingAddresses;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let get = ((index, address) => {
|
|
57
|
-
for (var contractName in index) {
|
|
58
|
-
var entry = index[contractName][address];
|
|
59
|
-
if (entry !== undefined) {
|
|
60
|
-
return entry;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return undefined;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
function size(indexingAddresses) {
|
|
67
|
-
let total = {
|
|
68
|
-
contents: 0
|
|
69
|
-
};
|
|
70
|
-
Utils.Dict.forEach(indexingAddresses, inner => {
|
|
71
|
-
total.contents = total.contents + Utils.Dict.size(inner) | 0;
|
|
72
|
-
});
|
|
73
|
-
return total.contents;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function contractCount(indexingAddresses, contractName) {
|
|
77
|
-
let inner = indexingAddresses[contractName];
|
|
78
|
-
if (inner !== undefined) {
|
|
79
|
-
return Utils.Dict.size(inner);
|
|
80
|
-
} else {
|
|
81
|
-
return 0;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function getContractAddresses(indexingAddresses, contractName) {
|
|
86
|
-
let inner = indexingAddresses[contractName];
|
|
87
|
-
if (inner !== undefined) {
|
|
88
|
-
return Object.values(inner).map(ia => ia.address);
|
|
89
|
-
} else {
|
|
90
|
-
return [];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let emptyContractDict = {};
|
|
95
|
-
|
|
96
|
-
function forContract(indexingAddresses, contractName) {
|
|
97
|
-
let inner = indexingAddresses[contractName];
|
|
98
|
-
if (inner !== undefined) {
|
|
99
|
-
return inner;
|
|
100
|
-
} else {
|
|
101
|
-
return emptyContractDict;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function register(indexingAddresses, additions) {
|
|
106
|
-
Utils.Dict.forEach(additions, indexingAddress => insert(indexingAddresses, indexingAddress));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function rollbackInPlace(indexingAddresses, targetBlockNumber) {
|
|
110
|
-
Utils.Dict.forEach(indexingAddresses, inner => Utils.Dict.forEachWithKey(inner, (indexingContract, address) => {
|
|
111
|
-
if (indexingContract.registrationBlock > targetBlockNumber) {
|
|
112
|
-
return Utils.Dict.deleteInPlace(inner, address);
|
|
113
|
-
}
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export {
|
|
118
|
-
deriveEffectiveStartBlock,
|
|
119
|
-
makeContractConfigs,
|
|
120
|
-
makeIndexingAddress,
|
|
121
|
-
make,
|
|
122
|
-
get,
|
|
123
|
-
size,
|
|
124
|
-
contractCount,
|
|
125
|
-
getContractAddresses,
|
|
126
|
-
forContract,
|
|
127
|
-
register,
|
|
128
|
-
rollbackInPlace,
|
|
129
|
-
}
|
|
130
|
-
/* Utils Not a pure module */
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
type indexingAddress = Internal.indexingContract
|
|
2
|
-
|
|
3
|
-
type contractConfig = {startBlock: option<int>}
|
|
4
|
-
|
|
5
|
-
type t
|
|
6
|
-
|
|
7
|
-
let deriveEffectiveStartBlock: (~registrationBlock: int, ~contractStartBlock: option<int>) => int
|
|
8
|
-
|
|
9
|
-
let makeContractConfigs: (
|
|
10
|
-
~onEventRegistrations: array<Internal.onEventRegistration>,
|
|
11
|
-
) => dict<contractConfig>
|
|
12
|
-
|
|
13
|
-
let makeIndexingAddress: (
|
|
14
|
-
~contract: Internal.indexingAddress,
|
|
15
|
-
~contractConfigs: dict<contractConfig>,
|
|
16
|
-
) => indexingAddress
|
|
17
|
-
|
|
18
|
-
let make: (~contractConfigs: dict<contractConfig>, ~addresses: array<Internal.indexingAddress>) => t
|
|
19
|
-
|
|
20
|
-
let get: (t, string) => option<indexingAddress>
|
|
21
|
-
|
|
22
|
-
let size: t => int
|
|
23
|
-
|
|
24
|
-
// Number of registered addresses for a single contract (scans just that
|
|
25
|
-
// contract's addresses).
|
|
26
|
-
let contractCount: (t, ~contractName: string) => int
|
|
27
|
-
|
|
28
|
-
let getContractAddresses: (t, ~contractName: string) => array<Address.t>
|
|
29
|
-
|
|
30
|
-
// The address→entry dict for a single contract, passed to that contract's
|
|
31
|
-
// precompiled `clientAddressFilter` (raw `byAddr[srcAddress]` access in
|
|
32
|
-
// generated JS). Don't use elsewhere — prefer the domain accessors so the
|
|
33
|
-
// opaque type stays enforced.
|
|
34
|
-
let forContract: (t, ~contractName: string) => dict<indexingAddress>
|
|
35
|
-
|
|
36
|
-
let register: (t, dict<indexingAddress>) => unit
|
|
37
|
-
|
|
38
|
-
// Deletes addresses registered after `targetBlockNumber` from the index in place.
|
|
39
|
-
let rollbackInPlace: (t, ~targetBlockNumber: int) => unit
|