envio 3.15.0-subgraph → 3.16.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/README.md +40 -34
- package/evm.schema.json +3 -3
- package/fuel.schema.json +2 -2
- package/index.d.ts +3 -3
- package/licenses/README.md +1 -1
- package/package.json +9 -10
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/Bin.res +0 -7
- package/src/Bin.res.mjs +0 -8
- package/src/ChainFetching.res +17 -456
- package/src/ChainFetching.res.mjs +33 -404
- package/src/ChainState.res +48 -83
- package/src/ChainState.res.mjs +83 -115
- package/src/ChainState.resi +0 -26
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +7 -16
- package/src/Config.res.mjs +4 -11
- package/src/ContractRegisterContext.res +6 -3
- package/src/ContractRegisterContext.res.mjs +2 -4
- package/src/Core.res +5 -136
- package/src/Core.res.mjs +1 -90
- package/src/CrossChainState.res +2 -8
- package/src/CrossChainState.res.mjs +3 -3
- package/src/Ecosystem.res +4 -7
- package/src/Ecosystem.res.mjs +8 -8
- package/src/EffectState.res +10 -2
- package/src/EffectState.res.mjs +8 -4
- package/src/EffectState.resi +3 -1
- package/src/EntityId.res +2 -7
- package/src/EntityId.res.mjs +1 -8
- package/src/EntityTables.res +4 -1
- package/src/EntityTables.res.mjs +1 -1
- package/src/Env.res +0 -16
- package/src/Env.res.mjs +0 -11
- package/src/EventProcessing.res +1 -38
- package/src/EventProcessing.res.mjs +1 -28
- package/src/FetchState.res +160 -319
- package/src/FetchState.res.mjs +182 -292
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/HandlerLoader.res +15 -39
- package/src/HandlerLoader.res.mjs +8 -27
- package/src/HandlerRegister.res +0 -4
- package/src/HandlerRegister.res.mjs +2 -5
- package/src/HandlerRegister.resi +0 -2
- package/src/InMemoryTable.res +17 -16
- package/src/InMemoryTable.res.mjs +14 -15
- package/src/IndexerState.res +28 -4
- package/src/IndexerState.res.mjs +19 -6
- package/src/IndexerState.resi +4 -0
- package/src/Internal.res +0 -110
- package/src/Internal.res.mjs +1 -115
- package/src/LoadLayer.res +21 -47
- package/src/LoadLayer.res.mjs +47 -72
- package/src/LoadLayer.resi +0 -26
- package/src/Main.res +1 -14
- package/src/Main.res.mjs +3 -4
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/RunScope.res +0 -3
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/SimulateItems.res +26 -42
- package/src/SimulateItems.res.mjs +16 -40
- package/src/StagedRows.res +106 -0
- package/src/StagedRows.res.mjs +102 -0
- package/src/Staging.res +32 -14
- package/src/Staging.res.mjs +17 -20
- package/src/Storage.res +277 -998
- package/src/Storage.res.mjs +216 -731
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/TestIndexer.res +22 -27
- package/src/TestIndexer.res.mjs +20 -17
- package/src/Throttler.res +15 -8
- package/src/Throttler.res.mjs +9 -6
- package/src/Throttler.resi +1 -1
- package/src/UserContext.res +46 -410
- package/src/UserContext.res.mjs +30 -318
- package/src/Utils.res +0 -23
- package/src/Utils.res.mjs +1 -17
- package/src/Writing.res +0 -1
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +0 -322
- package/src/bindings/ClickHouse.res.mjs +0 -338
- package/src/bindings/StorageClient.res +107 -175
- package/src/bindings/StorageClient.res.mjs +19 -8
- package/src/bindings/Vitest.res +0 -26
- package/src/bindings/Vitest.res.mjs +0 -3
- package/src/db/Table.res +24 -150
- package/src/db/Table.res.mjs +38 -272
- package/src/sources/AddressSet.res +0 -2
- package/src/sources/AddressStore.res +0 -3
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +4 -7
- package/src/sources/EvmChain.res.mjs +5 -4
- package/src/sources/EvmHyperSyncSource.res +2 -2
- package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
- package/src/sources/EvmRpcClient.res +13 -3
- package/src/sources/EvmRpcClient.res.mjs +4 -3
- package/src/sources/EvmRpcWs.res +4 -3
- package/src/sources/EvmRpcWs.res.mjs +2 -2
- package/src/sources/HeightFeed.res +31 -10
- package/src/sources/HeightFeed.res.mjs +10 -6
- package/src/sources/HeightStream.res +32 -17
- package/src/sources/HeightStream.res.mjs +10 -10
- package/src/sources/HyperSync.res +1 -2
- package/src/sources/HyperSync.res.mjs +1 -2
- package/src/sources/HyperSyncSSE.res +4 -6
- package/src/sources/HyperSyncSSE.res.mjs +2 -2
- package/src/sources/RpcSource.res +10 -1
- package/src/sources/RpcSource.res.mjs +4 -3
- package/src/sources/Source.res +3 -0
- package/src/sources/SourceManager.res +85 -104
- package/src/sources/SourceManager.res.mjs +18 -37
- package/src/sources/SourceManager.resi +3 -5
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +4 -3
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/svm.schema.json +3 -3
- package/src/EffectCacheLookup.res +0 -98
- package/src/EffectCacheLookup.res.mjs +0 -116
- package/src/PgWriting.res +0 -36
- package/src/PgWriting.res.mjs +0 -34
- package/src/PreloadLookahead.res +0 -184
- package/src/PreloadLookahead.res.mjs +0 -197
- package/src/SubgraphLog.res +0 -19
- package/src/SubgraphLog.res.mjs +0 -26
- package/src/SyncWrites.res +0 -101
- package/src/SyncWrites.res.mjs +0 -98
- package/src/db/IndexDefinition.res +0 -47
- package/src/db/IndexDefinition.res.mjs +0 -60
- package/src/sources/CallSource.res +0 -274
- package/src/sources/CallSource.res.mjs +0 -196
- package/src/subgraph/abi-types.ts +0 -84
- package/src/subgraph/aggregations.ts +0 -745
- package/src/subgraph/as-package.ts +0 -143
- package/src/subgraph/assemblyscript-regex.ts +0 -67
- package/src/subgraph/assemblyscript.ts +0 -731
- package/src/subgraph/blocks.ts +0 -398
- package/src/subgraph/calls-source.ts +0 -702
- package/src/subgraph/calls.ts +0 -258
- package/src/subgraph/conformance.ts +0 -106
- package/src/subgraph/errors.ts +0 -85
- package/src/subgraph/graft.ts +0 -73
- package/src/subgraph/graph-cli-worker.mjs +0 -35
- package/src/subgraph/graph-cli.ts +0 -900
- package/src/subgraph/graph-node-decimal.ts +0 -199
- package/src/subgraph/graph-ts-enums.ts +0 -28
- package/src/subgraph/graph-ts-types/VERSION +0 -2
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +0 -70
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +0 -327
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +0 -233
- package/src/subgraph/graph-ts-types/chain/near.d.ts +0 -253
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +0 -32
- package/src/subgraph/graph-ts-types/common/collections.d.ts +0 -136
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +0 -11
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +0 -30
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +0 -17
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +0 -120
- package/src/subgraph/graph-ts-types/common/value.d.ts +0 -120
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +0 -90
- package/src/subgraph/graph-ts-types/global/global.d.ts +0 -194
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +0 -22
- package/src/subgraph/graph-ts-types/index.d.ts +0 -102
- package/src/subgraph/graph-ts.ts +0 -4280
- package/src/subgraph/hosts.ts +0 -554
- package/src/subgraph/log.ts +0 -28
- package/src/subgraph/receipts.ts +0 -184
- package/src/subgraph/register-slots.ts +0 -93
- package/src/subgraph/rollup.ts +0 -109
- package/src/subgraph/rpc.ts +0 -337
- package/src/subgraph/runtime.ts +0 -2060
- package/src/subgraph/scope.ts +0 -177
- package/src/subgraph/stats.ts +0 -42
- package/src/subgraph/template-instances.ts +0 -66
- package/src/subgraph/toolchain.ts +0 -327
- package/src/subgraph/transient.ts +0 -176
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
// A cached effect's stored outputs, read straight from storage. For the
|
|
2
|
-
// subgraph register pass: it runs at fetch time, outside any handler context,
|
|
3
|
-
// so its contract calls can't go through the effect machinery, and after
|
|
4
|
-
// `envio start -r` (which keeps the subgraph call caches) it would otherwise ask
|
|
5
|
-
// the RPC again for every call it makes.
|
|
6
|
-
//
|
|
7
|
-
// Only a chain-scoped effect's table that held rows when the run started is
|
|
8
|
-
// read: rows this run writes are already in the register pass's own cache.
|
|
9
|
-
// The calls of one turn share one storage query.
|
|
10
|
-
|
|
11
|
-
type batch = {
|
|
12
|
-
effect: Internal.effect,
|
|
13
|
-
table: Table.table,
|
|
14
|
-
keys: array<string>,
|
|
15
|
-
resolvers: array<option<Internal.effectOutput> => unit>,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
let startupTables: ref<option<Utils.Set.t<string>>> = ref(None)
|
|
19
|
-
|
|
20
|
-
// Reset between test indexers, which each bring their own storage.
|
|
21
|
-
let resetStartupTables = () => startupTables := None
|
|
22
|
-
|
|
23
|
-
let tablesWithRowsAtStart = (cache: dict<Persistence.effectCacheRecord>) =>
|
|
24
|
-
switch startupTables.contents {
|
|
25
|
-
| Some(tables) => tables
|
|
26
|
-
| None =>
|
|
27
|
-
let tables = Utils.Set.make()
|
|
28
|
-
cache
|
|
29
|
-
->Dict.valuesToArray
|
|
30
|
-
->Array.forEach(record =>
|
|
31
|
-
if record.count > 0 {
|
|
32
|
-
tables->Utils.Set.add(record.tableName)->ignore
|
|
33
|
-
}
|
|
34
|
-
)
|
|
35
|
-
startupTables := Some(tables)
|
|
36
|
-
tables
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
let pending: dict<batch> = Dict.make()
|
|
40
|
-
|
|
41
|
-
let load = async (storage: Persistence.storage, batch: batch) => {
|
|
42
|
-
let rows =
|
|
43
|
-
(await storage.loadOrThrow(~table=batch.table, ~filter=EntityFilter.byIds(batch.keys)))->(
|
|
44
|
-
Utils.magic: array<unknown> => array<Internal.effectCacheItem>
|
|
45
|
-
)
|
|
46
|
-
let byId = Dict.make()
|
|
47
|
-
rows->Array.forEach(row =>
|
|
48
|
-
switch row.output->S.parseOrThrow(batch.effect.storageMeta.outputSchema) {
|
|
49
|
-
| output => byId->Dict.set(row.id, output)
|
|
50
|
-
| exception _ => ()
|
|
51
|
-
}
|
|
52
|
-
)
|
|
53
|
-
batch.keys->Array.map(key => byId->Utils.Dict.dangerouslyGetNonOption(key))
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let flush = async (storage: Persistence.storage, tableName) => {
|
|
57
|
-
let batch = pending->Dict.getUnsafe(tableName)
|
|
58
|
-
pending->Utils.Dict.deleteInPlace(tableName)
|
|
59
|
-
let outputs = switch await load(storage, batch) {
|
|
60
|
-
| outputs => outputs
|
|
61
|
-
| exception _ => batch.keys->Array.map(_ => None)
|
|
62
|
-
}
|
|
63
|
-
batch.resolvers->Array.forEachWithIndex((resolve, idx) => resolve(outputs->Array.getUnsafe(idx)))
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let cached = (effect: Internal.effect, chainId: int, input: Internal.effectInput): promise<
|
|
67
|
-
option<Internal.effectOutput>,
|
|
68
|
-
> =>
|
|
69
|
-
switch (
|
|
70
|
-
effect.crossChain,
|
|
71
|
-
EnvioGlobal.value.persistence->(Utils.magic: option<unknown> => option<Persistence.t>),
|
|
72
|
-
) {
|
|
73
|
-
| (Some(false), Some({storageStatus: Ready({cache}), storage})) =>
|
|
74
|
-
let table = Internal.makeCacheTable(
|
|
75
|
-
~effectName=effect.name,
|
|
76
|
-
~scope=Chain(chainId->ChainId.fromInt),
|
|
77
|
-
)
|
|
78
|
-
if cache->tablesWithRowsAtStart->Utils.Set.has(table.tableName) {
|
|
79
|
-
let key =
|
|
80
|
-
input
|
|
81
|
-
->S.reverseConvertOrThrow(effect.input)
|
|
82
|
-
->Utils.Hash.makeOrThrow
|
|
83
|
-
->Utils.Hash.boundCacheKey
|
|
84
|
-
Promise.make((resolve, _) => {
|
|
85
|
-
switch pending->Utils.Dict.dangerouslyGetNonOption(table.tableName) {
|
|
86
|
-
| Some(batch) =>
|
|
87
|
-
batch.keys->Array.push(key)
|
|
88
|
-
batch.resolvers->Array.push(resolve)
|
|
89
|
-
| None =>
|
|
90
|
-
pending->Dict.set(table.tableName, {effect, table, keys: [key], resolvers: [resolve]})
|
|
91
|
-
let _ = setTimeout(() => storage->flush(table.tableName)->ignore, 0)
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
} else {
|
|
95
|
-
Promise.resolve(None)
|
|
96
|
-
}
|
|
97
|
-
| _ => Promise.resolve(None)
|
|
98
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Utils from "./Utils.res.mjs";
|
|
4
|
-
import * as Internal from "./Internal.res.mjs";
|
|
5
|
-
import * as EnvioGlobal from "./EnvioGlobal.res.mjs";
|
|
6
|
-
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
7
|
-
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
8
|
-
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
9
|
-
|
|
10
|
-
let startupTables = {
|
|
11
|
-
contents: undefined
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
function resetStartupTables() {
|
|
15
|
-
startupTables.contents = undefined;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function tablesWithRowsAtStart(cache) {
|
|
19
|
-
let tables = startupTables.contents;
|
|
20
|
-
if (tables !== undefined) {
|
|
21
|
-
return Primitive_option.valFromOption(tables);
|
|
22
|
-
}
|
|
23
|
-
let tables$1 = new Set();
|
|
24
|
-
Object.values(cache).forEach(record => {
|
|
25
|
-
if (record.count > 0) {
|
|
26
|
-
tables$1.add(record.tableName);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
startupTables.contents = Primitive_option.some(tables$1);
|
|
31
|
-
return tables$1;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let pending = {};
|
|
35
|
-
|
|
36
|
-
async function load(storage, batch) {
|
|
37
|
-
let rows = await storage.loadOrThrow(EntityFilter.byIds(batch.keys), batch.table);
|
|
38
|
-
let byId = {};
|
|
39
|
-
rows.forEach(row => {
|
|
40
|
-
let output;
|
|
41
|
-
try {
|
|
42
|
-
output = S$RescriptSchema.parseOrThrow(row.output, batch.effect.storageMeta.outputSchema);
|
|
43
|
-
} catch (exn) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
byId[row.id] = output;
|
|
47
|
-
});
|
|
48
|
-
return batch.keys.map(key => byId[key]);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function flush(storage, tableName) {
|
|
52
|
-
let batch = pending[tableName];
|
|
53
|
-
Utils.Dict.deleteInPlace(pending, tableName);
|
|
54
|
-
let outputs;
|
|
55
|
-
try {
|
|
56
|
-
outputs = await load(storage, batch);
|
|
57
|
-
} catch (exn) {
|
|
58
|
-
outputs = batch.keys.map(param => {});
|
|
59
|
-
}
|
|
60
|
-
batch.resolvers.forEach((resolve, idx) => resolve(outputs[idx]));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function cached(effect, chainId, input) {
|
|
64
|
-
let match = effect.crossChain;
|
|
65
|
-
let match$1 = EnvioGlobal.value.persistence;
|
|
66
|
-
if (match === undefined) {
|
|
67
|
-
return Promise.resolve(undefined);
|
|
68
|
-
}
|
|
69
|
-
if (match) {
|
|
70
|
-
return Promise.resolve(undefined);
|
|
71
|
-
}
|
|
72
|
-
if (match$1 === undefined) {
|
|
73
|
-
return Promise.resolve(undefined);
|
|
74
|
-
}
|
|
75
|
-
let match$2 = match$1.storageStatus;
|
|
76
|
-
if (typeof match$2 !== "object") {
|
|
77
|
-
return Promise.resolve(undefined);
|
|
78
|
-
}
|
|
79
|
-
if (match$2.TAG === "Initializing") {
|
|
80
|
-
return Promise.resolve(undefined);
|
|
81
|
-
}
|
|
82
|
-
let storage = match$1.storage;
|
|
83
|
-
let table = Internal.makeCacheTable(effect.name, chainId);
|
|
84
|
-
if (!tablesWithRowsAtStart(match$2._0.cache).has(table.tableName)) {
|
|
85
|
-
return Promise.resolve(undefined);
|
|
86
|
-
}
|
|
87
|
-
let key = Utils.Hash.boundCacheKey(Utils.Hash.makeOrThrow(S$RescriptSchema.reverseConvertOrThrow(input, effect.input)));
|
|
88
|
-
return new Promise((resolve, param) => {
|
|
89
|
-
let batch = pending[table.tableName];
|
|
90
|
-
if (batch !== undefined) {
|
|
91
|
-
batch.keys.push(key);
|
|
92
|
-
batch.resolvers.push(resolve);
|
|
93
|
-
} else {
|
|
94
|
-
pending[table.tableName] = {
|
|
95
|
-
effect: effect,
|
|
96
|
-
table: table,
|
|
97
|
-
keys: [key],
|
|
98
|
-
resolvers: [resolve]
|
|
99
|
-
};
|
|
100
|
-
setTimeout(() => {
|
|
101
|
-
flush(storage, table.tableName);
|
|
102
|
-
}, 0);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export {
|
|
108
|
-
startupTables,
|
|
109
|
-
resetStartupTables,
|
|
110
|
-
tablesWithRowsAtStart,
|
|
111
|
-
pending,
|
|
112
|
-
load,
|
|
113
|
-
flush,
|
|
114
|
-
cached,
|
|
115
|
-
}
|
|
116
|
-
/* Utils Not a pure module */
|
package/src/PgWriting.res
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
let columns = (fields: array<Table.field>, ~kinds: array<Staging.kind>): array<Staging.column> =>
|
|
2
|
-
fields->Array.mapWithIndex((field, index) => {
|
|
3
|
-
Staging.name: field->Table.getPgDbFieldName,
|
|
4
|
-
kind: kinds->Array.getUnsafe(index),
|
|
5
|
-
isNullable: field.isNullable,
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
// Lays a batch into the arena, column by column. The values are the ones the
|
|
9
|
-
// table's own schema produced — a bigint as its digits, a date as its text, a
|
|
10
|
-
// boolean as the number the statement's cast expects — so nothing here has to
|
|
11
|
-
// know what a column means, only where its values go.
|
|
12
|
-
//
|
|
13
|
-
// The rows of a column are written in order because a variable-width slot's row
|
|
14
|
-
// starts where the row before it ended.
|
|
15
|
-
let stage = (
|
|
16
|
-
arena,
|
|
17
|
-
~table,
|
|
18
|
-
~columns: array<Staging.column>,
|
|
19
|
-
~values: array<array<unknown>>,
|
|
20
|
-
~rows,
|
|
21
|
-
) => {
|
|
22
|
-
let stage = arena->Staging.begin(~table, ~rows, ~columns)
|
|
23
|
-
try {
|
|
24
|
-
for column in 0 to columns->Array.length - 1 {
|
|
25
|
-
let values = values->Array.getUnsafe(column)
|
|
26
|
-
for row in 0 to rows - 1 {
|
|
27
|
-
stage->Staging.writeValue(~column, ~row, values->Array.getUnsafe(row))
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
stage->Staging.commit
|
|
31
|
-
} catch {
|
|
32
|
-
| exn =>
|
|
33
|
-
stage->Staging.abort
|
|
34
|
-
throw(exn)
|
|
35
|
-
}
|
|
36
|
-
}
|
package/src/PgWriting.res.mjs
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Table from "./db/Table.res.mjs";
|
|
4
|
-
import * as Staging from "./Staging.res.mjs";
|
|
5
|
-
|
|
6
|
-
function columns(fields, kinds) {
|
|
7
|
-
return fields.map((field, index) => ({
|
|
8
|
-
name: Table.getPgDbFieldName(field),
|
|
9
|
-
kind: kinds[index],
|
|
10
|
-
isNullable: field.isNullable
|
|
11
|
-
}));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function stage(arena, table, columns, values, rows) {
|
|
15
|
-
let stage$1 = Staging.begin(arena, table, rows, columns);
|
|
16
|
-
try {
|
|
17
|
-
for (let column = 0, column_finish = columns.length; column < column_finish; ++column) {
|
|
18
|
-
let values$1 = values[column];
|
|
19
|
-
for (let row = 0; row < rows; ++row) {
|
|
20
|
-
Staging.writeValue(stage$1, column, row, values$1[row]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return Staging.commit(stage$1);
|
|
24
|
-
} catch (exn) {
|
|
25
|
-
Staging.abort(stage$1);
|
|
26
|
-
throw exn;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export {
|
|
31
|
-
columns,
|
|
32
|
-
stage,
|
|
33
|
-
}
|
|
34
|
-
/* Table Not a pure module */
|
package/src/PreloadLookahead.res
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
// Preload runs a batch's handlers against the store as it was before the batch,
|
|
2
|
-
// so a handler reading an entity an earlier event of the batch creates (a v3
|
|
3
|
-
// pool's Mint after its PoolCreated) reads it as absent and makes none of the
|
|
4
|
-
// contract calls after that read. The execute pass then asks them one event
|
|
5
|
-
// at a time, a round trip each.
|
|
6
|
-
//
|
|
7
|
-
// So preload reads that find an entity absent are remembered per item, and once
|
|
8
|
-
// execute creates that entity, the items that read it are preloaded again, as
|
|
9
|
-
// long as they are within `window` items of the one executing. Preload only
|
|
10
|
-
// warms the store and the effect cache, and every value it fetches is keyed by
|
|
11
|
-
// its full input, so what execute computes is the same with or without it.
|
|
12
|
-
//
|
|
13
|
-
// Preload also sees what earlier items of the batch wrote in their own preload
|
|
14
|
-
// (`overlay`): agent0's URIUpdated(n), the log right after the Registered(n)
|
|
15
|
-
// that creates agent n, would otherwise find no agent and return before its
|
|
16
|
-
// call, and preloading it again once agent n exists is too late — it executes
|
|
17
|
-
// right after. Those writes are a guess at the store execute will see; they
|
|
18
|
-
// are held here, never in the store, and only an item before the reader that
|
|
19
|
-
// execute hasn't run yet is taken: once it has, the store is the answer.
|
|
20
|
-
//
|
|
21
|
-
// Preloading again costs the handler's CPU time once more, and an item whose
|
|
22
|
-
// preloads have already spent `maxPreloadMs` (a v3 Mint computing 1.0001^tick
|
|
23
|
-
// a step at a time) isn't preloaded again: its calls would land later than the
|
|
24
|
-
// CPU it takes away from execute.
|
|
25
|
-
|
|
26
|
-
type t = {
|
|
27
|
-
items: array<Internal.item>,
|
|
28
|
-
indexOf: Utils.Map.t<Internal.item, int>,
|
|
29
|
-
absentReaders: dict<array<int>>,
|
|
30
|
-
dirty: array<bool>,
|
|
31
|
-
// Milliseconds the item's preload rounds have run for, all runs together.
|
|
32
|
-
preloadMs: array<float>,
|
|
33
|
-
// By entity key, the writes items' preloads made: (item, entity or deleted).
|
|
34
|
-
overlay: dict<array<(int, option<Internal.entity>)>>,
|
|
35
|
-
window: int,
|
|
36
|
-
// The last item execute finished; reads and writes at or before it are history.
|
|
37
|
-
mutable executed: int,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
let active: ref<option<t>> = ref(None)
|
|
41
|
-
|
|
42
|
-
// Subgraph mappings make their contract calls in the middle of a handler, after
|
|
43
|
-
// the reads, so a read that misses is the difference between preloading the
|
|
44
|
-
// calls and not. Native handlers are left as they are.
|
|
45
|
-
let start = (~items: array<Internal.item>) => {
|
|
46
|
-
let window = Env.subgraphPreloadLookahead
|
|
47
|
-
if Env.subgraphMode.contents && window > 0 {
|
|
48
|
-
let indexOf = Utils.Map.make()
|
|
49
|
-
items->Array.forEachWithIndex((item, idx) => indexOf->Utils.Map.set(item, idx)->ignore)
|
|
50
|
-
active :=
|
|
51
|
-
Some({
|
|
52
|
-
items,
|
|
53
|
-
indexOf,
|
|
54
|
-
absentReaders: Dict.make(),
|
|
55
|
-
dirty: Array.make(~length=items->Array.length, false),
|
|
56
|
-
preloadMs: Array.make(~length=items->Array.length, 0.),
|
|
57
|
-
overlay: Dict.make(),
|
|
58
|
-
window,
|
|
59
|
-
executed: -1,
|
|
60
|
-
})
|
|
61
|
-
} else {
|
|
62
|
-
active := None
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let stop = () => active := None
|
|
67
|
-
|
|
68
|
-
let maxPreloadMs = 20.
|
|
69
|
-
|
|
70
|
-
let roundStarted = (~isPreload) =>
|
|
71
|
-
switch active.contents {
|
|
72
|
-
| Some(_) if isPreload => Performance.now()
|
|
73
|
-
| _ => 0.
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let roundEnded = (~item: Internal.item, ~startedAt) =>
|
|
77
|
-
if startedAt > 0. {
|
|
78
|
-
switch active.contents {
|
|
79
|
-
| None => ()
|
|
80
|
-
| Some(t) =>
|
|
81
|
-
switch t.indexOf->Utils.Map.get(item) {
|
|
82
|
-
| Some(idx) =>
|
|
83
|
-
t.preloadMs->Array.setUnsafe(
|
|
84
|
-
idx,
|
|
85
|
-
t.preloadMs->Array.getUnsafe(idx) +. startedAt->Performance.secondsSince *. 1000.,
|
|
86
|
-
)
|
|
87
|
-
| None => ()
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
let entityKey = (~entityName, ~scope: Internal.chainScope, ~entityId) =>
|
|
93
|
-
switch scope {
|
|
94
|
-
| CrossChain => `${entityName}..${entityId}`
|
|
95
|
-
| Chain(chainId) => `${entityName}.${chainId->ChainId.toString}.${entityId}`
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
let recordAbsent = (~item: Internal.item, ~entityName, ~scope, ~entityId) =>
|
|
99
|
-
switch active.contents {
|
|
100
|
-
| None => ()
|
|
101
|
-
| Some(t) =>
|
|
102
|
-
switch t.indexOf->Utils.Map.get(item) {
|
|
103
|
-
| Some(idx) if idx > t.executed =>
|
|
104
|
-
let key = entityKey(~entityName, ~scope, ~entityId)
|
|
105
|
-
switch t.absentReaders->Utils.Dict.dangerouslyGetNonOption(key) {
|
|
106
|
-
| Some(readers) => readers->Array.push(idx)
|
|
107
|
-
| None => t.absentReaders->Dict.set(key, [idx])
|
|
108
|
-
}
|
|
109
|
-
| _ => ()
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
let onSet = (~entityName, ~scope, ~entityId) =>
|
|
114
|
-
switch active.contents {
|
|
115
|
-
| None => ()
|
|
116
|
-
| Some(t) =>
|
|
117
|
-
let key = entityKey(~entityName, ~scope, ~entityId)
|
|
118
|
-
switch t.absentReaders->Utils.Dict.dangerouslyGetNonOption(key) {
|
|
119
|
-
| None => ()
|
|
120
|
-
| Some(readers) =>
|
|
121
|
-
t.absentReaders->Utils.Dict.deleteInPlace(key)
|
|
122
|
-
readers->Array.forEach(idx =>
|
|
123
|
-
if idx > t.executed {
|
|
124
|
-
t.dirty->Array.setUnsafe(idx, true)
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
let isActive = () => active.contents->Option.isSome
|
|
131
|
-
|
|
132
|
-
let overlaySet = (~item: Internal.item, ~entityName, ~scope, ~entityId, ~entity) =>
|
|
133
|
-
switch active.contents {
|
|
134
|
-
| None => ()
|
|
135
|
-
| Some(t) =>
|
|
136
|
-
switch t.indexOf->Utils.Map.get(item) {
|
|
137
|
-
| Some(writer) =>
|
|
138
|
-
let key = entityKey(~entityName, ~scope, ~entityId)
|
|
139
|
-
let writes = switch t.overlay->Utils.Dict.dangerouslyGetNonOption(key) {
|
|
140
|
-
| Some(writes) => writes->Array.filter(((idx, _)) => idx !== writer)
|
|
141
|
-
| None => []
|
|
142
|
-
}
|
|
143
|
-
writes->Array.push((writer, entity))
|
|
144
|
-
t.overlay->Dict.set(key, writes)
|
|
145
|
-
| None => ()
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// `Some(entity or None for deleted)` when an item before the reader that execute
|
|
150
|
-
// hasn't run yet wrote the entity in its preload: the latest such write.
|
|
151
|
-
let overlayGet = (~item: Internal.item, ~entityName, ~scope, ~entityId) =>
|
|
152
|
-
switch active.contents {
|
|
153
|
-
| None => None
|
|
154
|
-
| Some(t) =>
|
|
155
|
-
switch (
|
|
156
|
-
t.indexOf->Utils.Map.get(item),
|
|
157
|
-
t.overlay->Utils.Dict.dangerouslyGetNonOption(entityKey(~entityName, ~scope, ~entityId)),
|
|
158
|
-
) {
|
|
159
|
-
| (Some(reader), Some(writes)) =>
|
|
160
|
-
let found = ref(None)
|
|
161
|
-
let foundAt = ref(t.executed)
|
|
162
|
-
writes->Array.forEach(((writer, entity)) =>
|
|
163
|
-
if writer > foundAt.contents && writer < reader {
|
|
164
|
-
foundAt := writer
|
|
165
|
-
found := Some(entity)
|
|
166
|
-
}
|
|
167
|
-
)
|
|
168
|
-
found.contents
|
|
169
|
-
| _ => None
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Called once execute has finished the item at `index`: the dirty items in the
|
|
174
|
-
// window ahead of it are preloaded again against the store as it is now.
|
|
175
|
-
let afterItem = (t: t, ~index, ~preload: (Internal.item, int) => unit) => {
|
|
176
|
-
t.executed = index
|
|
177
|
-
let last = Math.Int.min(t.items->Array.length - 1, index + t.window)
|
|
178
|
-
for idx in index + 1 to last {
|
|
179
|
-
if t.dirty->Array.getUnsafe(idx) && t.preloadMs->Array.getUnsafe(idx) < maxPreloadMs {
|
|
180
|
-
t.dirty->Array.setUnsafe(idx, false)
|
|
181
|
-
preload(t.items->Array.getUnsafe(idx), idx)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Env from "./Env.res.mjs";
|
|
4
|
-
import * as Utils from "./Utils.res.mjs";
|
|
5
|
-
import * as ChainId from "./ChainId.res.mjs";
|
|
6
|
-
import * as Performance from "./bindings/Performance.res.mjs";
|
|
7
|
-
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
8
|
-
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
|
-
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
10
|
-
|
|
11
|
-
let active = {
|
|
12
|
-
contents: undefined
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
function start(items) {
|
|
16
|
-
if (!(Env.subgraphMode.contents && Env.subgraphPreloadLookahead > 0)) {
|
|
17
|
-
active.contents = undefined;
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
let indexOf = new Map();
|
|
21
|
-
items.forEach((item, idx) => {
|
|
22
|
-
indexOf.set(item, idx);
|
|
23
|
-
});
|
|
24
|
-
active.contents = {
|
|
25
|
-
items: items,
|
|
26
|
-
indexOf: indexOf,
|
|
27
|
-
absentReaders: {},
|
|
28
|
-
dirty: Stdlib_Array.make(items.length, false),
|
|
29
|
-
preloadMs: Stdlib_Array.make(items.length, 0),
|
|
30
|
-
overlay: {},
|
|
31
|
-
window: Env.subgraphPreloadLookahead,
|
|
32
|
-
executed: -1
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function stop() {
|
|
37
|
-
active.contents = undefined;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function roundStarted(isPreload) {
|
|
41
|
-
let match = active.contents;
|
|
42
|
-
if (match !== undefined) {
|
|
43
|
-
if (isPreload) {
|
|
44
|
-
return Performance.now();
|
|
45
|
-
} else {
|
|
46
|
-
return 0;
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
return 0;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function roundEnded(item, startedAt) {
|
|
54
|
-
if (startedAt <= 0) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
let t = active.contents;
|
|
58
|
-
if (t === undefined) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
let idx = t.indexOf.get(item);
|
|
62
|
-
if (idx !== undefined) {
|
|
63
|
-
t.preloadMs[idx] = t.preloadMs[idx] + Performance.secondsSince(startedAt) * 1000;
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function entityKey(entityName, scope, entityId) {
|
|
69
|
-
if (scope === "crossChain") {
|
|
70
|
-
return entityName + `..` + entityId;
|
|
71
|
-
} else {
|
|
72
|
-
return entityName + `.` + ChainId.toString(scope) + `.` + entityId;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function recordAbsent(item, entityName, scope, entityId) {
|
|
77
|
-
let t = active.contents;
|
|
78
|
-
if (t === undefined) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
let idx = t.indexOf.get(item);
|
|
82
|
-
if (idx === undefined) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (idx <= t.executed) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
let key = entityKey(entityName, scope, entityId);
|
|
89
|
-
let readers = t.absentReaders[key];
|
|
90
|
-
if (readers !== undefined) {
|
|
91
|
-
readers.push(idx);
|
|
92
|
-
} else {
|
|
93
|
-
t.absentReaders[key] = [idx];
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function onSet(entityName, scope, entityId) {
|
|
98
|
-
let t = active.contents;
|
|
99
|
-
if (t === undefined) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
let key = entityKey(entityName, scope, entityId);
|
|
103
|
-
let readers = t.absentReaders[key];
|
|
104
|
-
if (readers !== undefined) {
|
|
105
|
-
Utils.Dict.deleteInPlace(t.absentReaders, key);
|
|
106
|
-
readers.forEach(idx => {
|
|
107
|
-
if (idx > t.executed) {
|
|
108
|
-
t.dirty[idx] = true;
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function isActive() {
|
|
117
|
-
return Stdlib_Option.isSome(active.contents);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function overlaySet(item, entityName, scope, entityId, entity) {
|
|
121
|
-
let t = active.contents;
|
|
122
|
-
if (t === undefined) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
let writer = t.indexOf.get(item);
|
|
126
|
-
if (writer === undefined) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
let key = entityKey(entityName, scope, entityId);
|
|
130
|
-
let writes = t.overlay[key];
|
|
131
|
-
let writes$1 = writes !== undefined ? writes.filter(param => param[0] !== writer) : [];
|
|
132
|
-
writes$1.push([
|
|
133
|
-
writer,
|
|
134
|
-
entity
|
|
135
|
-
]);
|
|
136
|
-
t.overlay[key] = writes$1;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function overlayGet(item, entityName, scope, entityId) {
|
|
140
|
-
let t = active.contents;
|
|
141
|
-
if (t === undefined) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
let match = t.indexOf.get(item);
|
|
145
|
-
let match$1 = t.overlay[entityKey(entityName, scope, entityId)];
|
|
146
|
-
if (match === undefined) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
if (match$1 === undefined) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
let found = {
|
|
153
|
-
contents: undefined
|
|
154
|
-
};
|
|
155
|
-
let foundAt = {
|
|
156
|
-
contents: t.executed
|
|
157
|
-
};
|
|
158
|
-
match$1.forEach(param => {
|
|
159
|
-
let writer = param[0];
|
|
160
|
-
if (writer > foundAt.contents && writer < match) {
|
|
161
|
-
foundAt.contents = writer;
|
|
162
|
-
found.contents = Primitive_option.some(param[1]);
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
return found.contents;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function afterItem(t, index, preload) {
|
|
170
|
-
t.executed = index;
|
|
171
|
-
let last = Math.min(t.items.length - 1 | 0, index + t.window | 0);
|
|
172
|
-
for (let idx = index + 1 | 0; idx <= last; ++idx) {
|
|
173
|
-
if (t.dirty[idx] && t.preloadMs[idx] < 20) {
|
|
174
|
-
t.dirty[idx] = false;
|
|
175
|
-
preload(t.items[idx], idx);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
let maxPreloadMs = 20;
|
|
181
|
-
|
|
182
|
-
export {
|
|
183
|
-
active,
|
|
184
|
-
start,
|
|
185
|
-
stop,
|
|
186
|
-
maxPreloadMs,
|
|
187
|
-
roundStarted,
|
|
188
|
-
roundEnded,
|
|
189
|
-
entityKey,
|
|
190
|
-
recordAbsent,
|
|
191
|
-
onSet,
|
|
192
|
-
isActive,
|
|
193
|
-
overlaySet,
|
|
194
|
-
overlayGet,
|
|
195
|
-
afterItem,
|
|
196
|
-
}
|
|
197
|
-
/* Env Not a pure module */
|
package/src/SubgraphLog.res
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Every line the subgraph runtime logs, and every line a mapping logs through
|
|
2
|
-
// graph-ts (`uinfo`, `uwarn`, ...), as it is logged. A test indexer's own logger
|
|
3
|
-
// is silent, so this is how a test reads them. Compiled to JavaScript so a test
|
|
4
|
-
// can import it from an installed envio, where TypeScript isn't stripped.
|
|
5
|
-
|
|
6
|
-
type listener = (string, string) => unit
|
|
7
|
-
|
|
8
|
-
let listeners: array<listener> = []
|
|
9
|
-
|
|
10
|
-
let onLog = (listener: listener) => {
|
|
11
|
-
listeners->Array.push(listener)
|
|
12
|
-
() =>
|
|
13
|
-
switch listeners->Array.indexOf(listener) {
|
|
14
|
-
| -1 => ()
|
|
15
|
-
| index => listeners->Array.splice(~start=index, ~remove=1, ~insert=[])
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let notify = (level, message) => listeners->Array.forEach(listener => listener(level, message))
|