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.
- package/README.md +40 -34
- package/evm.schema.json +11 -2
- package/fuel.schema.json +10 -1
- package/index.d.ts +6 -0
- package/licenses/README.md +1 -1
- package/package.json +10 -9
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/Bin.res +7 -0
- package/src/Bin.res.mjs +8 -0
- package/src/ChainFetching.res +450 -16
- package/src/ChainFetching.res.mjs +403 -32
- package/src/ChainState.res +124 -7
- package/src/ChainState.res.mjs +128 -67
- package/src/ChainState.resi +26 -0
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +31 -3
- package/src/Config.res.mjs +15 -4
- package/src/ContractRegisterContext.res +3 -6
- package/src/ContractRegisterContext.res.mjs +4 -2
- package/src/Core.res +95 -36
- package/src/Core.res.mjs +90 -1
- package/src/CrossChainState.res +12 -2
- package/src/CrossChainState.res.mjs +3 -3
- package/src/Ecosystem.res +7 -4
- package/src/Ecosystem.res.mjs +8 -8
- package/src/EffectCacheLookup.res +98 -0
- package/src/EffectCacheLookup.res.mjs +116 -0
- 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 +20 -0
- package/src/Env.res.mjs +16 -0
- package/src/EventProcessing.res +38 -1
- package/src/EventProcessing.res.mjs +28 -1
- package/src/FetchState.res +408 -73
- package/src/FetchState.res.mjs +361 -91
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/HandlerLoader.res +39 -15
- package/src/HandlerLoader.res.mjs +27 -8
- package/src/HandlerRegister.res +4 -0
- package/src/HandlerRegister.res.mjs +5 -2
- package/src/HandlerRegister.resi +2 -0
- 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 +61 -49
- package/src/Internal.res.mjs +36 -80
- package/src/LoadLayer.res +54 -15
- package/src/LoadLayer.res.mjs +75 -45
- package/src/LoadLayer.resi +26 -0
- package/src/Main.res +14 -1
- package/src/Main.res.mjs +4 -3
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/PreloadLookahead.res +202 -0
- package/src/PreloadLookahead.res.mjs +218 -0
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/RunScope.res +3 -0
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/SimulateItems.res +42 -26
- package/src/SimulateItems.res.mjs +40 -16
- 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 +303 -948
- package/src/Storage.res.mjs +229 -708
- package/src/SubgraphLog.res +19 -0
- package/src/SubgraphLog.res.mjs +26 -0
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/SyncWrites.res +107 -0
- package/src/SyncWrites.res.mjs +98 -0
- 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 +419 -46
- package/src/UserContext.res.mjs +318 -30
- package/src/Utils.res +17 -6
- package/src/Utils.res.mjs +12 -6
- 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 +108 -174
- 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 +2 -0
- package/src/sources/AddressStore.res +3 -0
- package/src/sources/CallSource.res +274 -0
- package/src/sources/CallSource.res.mjs +196 -0
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +10 -1
- package/src/sources/EvmChain.res.mjs +6 -3
- 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 +2 -1
- package/src/sources/HyperSync.res.mjs +2 -1
- 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 +84 -77
- package/src/sources/SourceManager.res.mjs +17 -20
- package/src/sources/SourceManager.resi +3 -4
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/subgraph/abi-types.ts +84 -0
- package/src/subgraph/aggregations.ts +745 -0
- package/src/subgraph/as-package.ts +143 -0
- package/src/subgraph/assemblyscript-regex.ts +67 -0
- package/src/subgraph/assemblyscript.ts +731 -0
- package/src/subgraph/blocks.ts +398 -0
- package/src/subgraph/calls-source.ts +702 -0
- package/src/subgraph/calls.ts +258 -0
- package/src/subgraph/conformance.ts +106 -0
- package/src/subgraph/errors.ts +85 -0
- package/src/subgraph/graft.ts +73 -0
- package/src/subgraph/graph-cli-worker.mjs +35 -0
- package/src/subgraph/graph-cli.ts +900 -0
- package/src/subgraph/graph-node-decimal.ts +199 -0
- package/src/subgraph/graph-ts-enums.ts +28 -0
- package/src/subgraph/graph-ts-types/VERSION +2 -0
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
- package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
- package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
- package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
- package/src/subgraph/graph-ts-types/index.d.ts +102 -0
- package/src/subgraph/graph-ts.ts +4339 -0
- package/src/subgraph/hosts.ts +554 -0
- package/src/subgraph/log.ts +28 -0
- package/src/subgraph/receipts.ts +184 -0
- package/src/subgraph/register-slots.ts +93 -0
- package/src/subgraph/rollup.ts +109 -0
- package/src/subgraph/rpc.ts +337 -0
- package/src/subgraph/runtime.ts +2059 -0
- package/src/subgraph/scope.ts +176 -0
- package/src/subgraph/stats.ts +42 -0
- package/src/subgraph/template-instances.ts +66 -0
- package/src/subgraph/toolchain.ts +327 -0
- package/src/subgraph/transient.ts +176 -0
- package/svm.schema.json +11 -2
- package/src/PgWriting.res +0 -36
- package/src/PgWriting.res.mjs +0 -34
- package/src/db/IndexDefinition.res +0 -47
- package/src/db/IndexDefinition.res.mjs +0 -67
package/src/UserContext.res.mjs
CHANGED
|
@@ -1,18 +1,84 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Env from "./Env.res.mjs";
|
|
3
4
|
import * as Utils from "./Utils.res.mjs";
|
|
4
5
|
import * as Logger from "./Logger.res.mjs";
|
|
6
|
+
import * as ChainId from "./ChainId.res.mjs";
|
|
5
7
|
import * as Internal from "./Internal.res.mjs";
|
|
6
8
|
import * as RunScope from "./RunScope.res.mjs";
|
|
7
9
|
import * as LoadLayer from "./LoadLayer.res.mjs";
|
|
10
|
+
import * as SyncWrites from "./SyncWrites.res.mjs";
|
|
8
11
|
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
9
|
-
import * as IndexerState from "./IndexerState.res.mjs";
|
|
10
12
|
import * as InMemoryStore from "./InMemoryStore.res.mjs";
|
|
11
13
|
import * as InMemoryTable from "./InMemoryTable.res.mjs";
|
|
12
14
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
13
15
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
16
|
+
import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
17
|
+
import * as PreloadLookahead from "./PreloadLookahead.res.mjs";
|
|
14
18
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
15
19
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
20
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
21
|
+
|
|
22
|
+
let Suspend = /* @__PURE__ */Primitive_exceptions.create("UserContext.Suspend");
|
|
23
|
+
|
|
24
|
+
function isSuspend(exn) {
|
|
25
|
+
return exn.RE_EXN_ID === Suspend;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let suspend = {
|
|
29
|
+
RE_EXN_ID: Suspend
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
let currentSync = {
|
|
33
|
+
contents: undefined
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function syncOf(run) {
|
|
37
|
+
let sync = currentSync.contents;
|
|
38
|
+
if (sync !== undefined && sync.run === run) {
|
|
39
|
+
return sync;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function currentRunOrThrow(prop) {
|
|
44
|
+
let run = RunScope.currentHandlerRunOrThrow(prop);
|
|
45
|
+
let match = syncOf(run);
|
|
46
|
+
if (match !== undefined) {
|
|
47
|
+
let exn = match.status;
|
|
48
|
+
if (typeof exn === "object") {
|
|
49
|
+
throw exn._0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return run;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function syncOrThrow(run, prop) {
|
|
56
|
+
let sync = syncOf(run);
|
|
57
|
+
if (sync !== undefined) {
|
|
58
|
+
return sync;
|
|
59
|
+
} else {
|
|
60
|
+
return Stdlib_JsError.throwWithMessage(`context.` + prop + ` is only available inside context.runSync.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function scheduleAndSuspend(sync, promise) {
|
|
65
|
+
sync.pending.push(promise);
|
|
66
|
+
sync.status = {
|
|
67
|
+
TAG: "Aborted",
|
|
68
|
+
_0: suspend
|
|
69
|
+
};
|
|
70
|
+
throw suspend;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function missOrSuspend(sync, promise, absent) {
|
|
74
|
+
if (sync.run.isPreload && sync.speculated < 32) {
|
|
75
|
+
sync.pending.push(promise);
|
|
76
|
+
sync.speculated = sync.speculated + 1 | 0;
|
|
77
|
+
return absent;
|
|
78
|
+
} else {
|
|
79
|
+
return scheduleAndSuspend(sync, promise);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
16
82
|
|
|
17
83
|
let effectContextPrototype = (Object.create(null));
|
|
18
84
|
|
|
@@ -46,7 +112,7 @@ function isCrossChain(params, effect) {
|
|
|
46
112
|
return Stdlib_Option.getOr(effect.crossChain, params.config.defaultCrossChain);
|
|
47
113
|
}
|
|
48
114
|
|
|
49
|
-
function
|
|
115
|
+
function prepareEffectCall(params, run, caller, effect, input) {
|
|
50
116
|
let handlerChainId = Internal.getItemChainId(run.item);
|
|
51
117
|
let scope = isCrossChain(params, effect) ? "crossChain" : handlerChainId;
|
|
52
118
|
if (caller !== undefined && scope !== "crossChain") {
|
|
@@ -61,13 +127,59 @@ function callEffect(params, run, caller, effect, input) {
|
|
|
61
127
|
caller: run,
|
|
62
128
|
effectName: effect.name
|
|
63
129
|
});
|
|
64
|
-
|
|
130
|
+
let effectArgs_cacheKey = Utils.Hash.boundCacheKey(Utils.Hash.makeOrThrow(S$RescriptSchema.reverseConvertOrThrow(input, effect.input)));
|
|
131
|
+
let effectArgs_checkpointId = run.checkpointId;
|
|
132
|
+
let effectArgs = {
|
|
65
133
|
input: input,
|
|
66
134
|
context: effectContext,
|
|
67
|
-
cacheKey:
|
|
135
|
+
cacheKey: effectArgs_cacheKey,
|
|
68
136
|
chainId: handlerChainId,
|
|
69
|
-
checkpointId:
|
|
70
|
-
}
|
|
137
|
+
checkpointId: effectArgs_checkpointId
|
|
138
|
+
};
|
|
139
|
+
return [
|
|
140
|
+
scope,
|
|
141
|
+
effectArgs
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function callEffect(params, run, caller, effect, input) {
|
|
146
|
+
let match = prepareEffectCall(params, run, caller, effect, input);
|
|
147
|
+
return LoadLayer.loadEffect(params.loadManager, params.persistence, effect, match[1], match[0], params.indexerState, run.isPreload);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function effectMemoKey(effect, scope, cacheKey) {
|
|
151
|
+
if (scope === "crossChain") {
|
|
152
|
+
return effect.name + `.` + cacheKey;
|
|
153
|
+
} else {
|
|
154
|
+
return effect.name + `.` + ChainId.toString(scope) + `.` + cacheKey;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function effectSync(params, effect, input) {
|
|
159
|
+
let run = currentRunOrThrow("effectSync");
|
|
160
|
+
let sync = syncOrThrow(run, "effectSync");
|
|
161
|
+
let match = prepareEffectCall(params, run, undefined, effect, input);
|
|
162
|
+
let effectArgs = match[1];
|
|
163
|
+
let scope = match[0];
|
|
164
|
+
let memoKey = effectMemoKey(effect, scope, effectArgs.cacheKey);
|
|
165
|
+
let output = sync.memo[memoKey];
|
|
166
|
+
if (output !== undefined) {
|
|
167
|
+
return Primitive_option.valFromOption(output);
|
|
168
|
+
}
|
|
169
|
+
let inMemTable = InMemoryStore.getEffectInMemTable(params.indexerState, effect, scope);
|
|
170
|
+
if (InMemoryStore.hasEffectOutput(inMemTable, effectArgs.cacheKey)) {
|
|
171
|
+
let output$1 = InMemoryStore.getEffectOutputUnsafe(inMemTable, effectArgs.cacheKey);
|
|
172
|
+
sync.memo[memoKey] = output$1;
|
|
173
|
+
return output$1;
|
|
174
|
+
}
|
|
175
|
+
if (sync.speculated <= 0) {
|
|
176
|
+
return scheduleAndSuspend(sync, LoadLayer.loadEffect(params.loadManager, params.persistence, effect, effectArgs, scope, params.indexerState, run.isPreload));
|
|
177
|
+
}
|
|
178
|
+
sync.status = {
|
|
179
|
+
TAG: "Aborted",
|
|
180
|
+
_0: suspend
|
|
181
|
+
};
|
|
182
|
+
throw suspend;
|
|
71
183
|
}
|
|
72
184
|
|
|
73
185
|
function expiresUnread(entityConfig) {
|
|
@@ -85,35 +197,43 @@ function throwExpiresUnread(entityConfig, op) {
|
|
|
85
197
|
|
|
86
198
|
function makeEntityContext(params, entityConfig) {
|
|
87
199
|
let prop = entityConfig.name;
|
|
200
|
+
let entityName = entityConfig.name;
|
|
88
201
|
let scopeOf = run => InMemoryStore.entityScope(entityConfig, Internal.getItemChainId(run.item));
|
|
89
202
|
let loadById = entityId => {
|
|
90
|
-
let run =
|
|
203
|
+
let run = currentRunOrThrow(prop);
|
|
91
204
|
return LoadLayer.loadById(params.loadManager, params.persistence, entityConfig, scopeOf(run), params.indexerState, run.isPreload, entityId);
|
|
92
205
|
};
|
|
93
206
|
let write = (run, change) => {
|
|
94
|
-
let
|
|
95
|
-
|
|
207
|
+
let match = syncOf(run);
|
|
208
|
+
let match$1 = run.isPreload;
|
|
209
|
+
if (match !== undefined) {
|
|
210
|
+
if (match$1 && !PreloadLookahead.isActive()) {
|
|
211
|
+
return;
|
|
212
|
+
} else {
|
|
213
|
+
return SyncWrites.record(match.writes, entityConfig, scopeOf(run), change);
|
|
214
|
+
}
|
|
215
|
+
} else if (match$1) {
|
|
216
|
+
return;
|
|
217
|
+
} else {
|
|
218
|
+
return SyncWrites.write(params.indexerState, entityConfig, scopeOf(run), change);
|
|
219
|
+
}
|
|
96
220
|
};
|
|
97
221
|
let set = entity => {
|
|
98
|
-
let run =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
}
|
|
222
|
+
let run = currentRunOrThrow(prop);
|
|
223
|
+
write(run, {
|
|
224
|
+
type: "SET",
|
|
225
|
+
entityId: entity.id,
|
|
226
|
+
entity: entity,
|
|
227
|
+
checkpointId: run.checkpointId
|
|
228
|
+
});
|
|
107
229
|
};
|
|
108
230
|
let deleteUnsafe = entityId => {
|
|
109
|
-
let run =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
116
|
-
}
|
|
231
|
+
let run = currentRunOrThrow(prop);
|
|
232
|
+
write(run, {
|
|
233
|
+
type: "DELETE",
|
|
234
|
+
entityId: entityId,
|
|
235
|
+
checkpointId: run.checkpointId
|
|
236
|
+
});
|
|
117
237
|
};
|
|
118
238
|
let entityContext = expiresUnread(entityConfig) ? ({
|
|
119
239
|
get: param => throwExpiresUnread(entityConfig, "get"),
|
|
@@ -125,7 +245,7 @@ function makeEntityContext(params, entityConfig) {
|
|
|
125
245
|
}) : ({
|
|
126
246
|
get: loadById,
|
|
127
247
|
getWhere: filter => {
|
|
128
|
-
let run =
|
|
248
|
+
let run = currentRunOrThrow(prop);
|
|
129
249
|
return LoadLayer.loadByFilter(params.loadManager, params.persistence, entityConfig, scopeOf(run), params.indexerState, run.isPreload, filter);
|
|
130
250
|
},
|
|
131
251
|
getOrThrow: (entityId, message) => loadById(entityId).then(entity => {
|
|
@@ -146,7 +266,136 @@ function makeEntityContext(params, entityConfig) {
|
|
|
146
266
|
set: set,
|
|
147
267
|
deleteUnsafe: deleteUnsafe
|
|
148
268
|
});
|
|
149
|
-
|
|
269
|
+
let object = Object.assign(Object.create(Utils.StrictObject.makePrototype(op => Stdlib_JsError.throwWithMessage(`Invalid context.` + entityConfig.name + `.` + op + ` operation.`))), entityContext);
|
|
270
|
+
if (!Env.subgraphMode.contents) {
|
|
271
|
+
return object;
|
|
272
|
+
}
|
|
273
|
+
let syncEntityContext_getSync = entityId => {
|
|
274
|
+
let run = currentRunOrThrow(prop);
|
|
275
|
+
let sync = syncOrThrow(run, prop + `.getSync`);
|
|
276
|
+
let scope = scopeOf(run);
|
|
277
|
+
let entityKey = entityConfig.table.entityIdToKey(entityId);
|
|
278
|
+
let entity = SyncWrites.getById(sync.writes, entityConfig, entityId);
|
|
279
|
+
if (entity !== undefined) {
|
|
280
|
+
return Primitive_option.valFromOption(entity);
|
|
281
|
+
}
|
|
282
|
+
let entity$1 = run.isPreload ? PreloadLookahead.overlayGet(run.item, entityName, scope, entityKey) : undefined;
|
|
283
|
+
if (entity$1 !== undefined) {
|
|
284
|
+
return Primitive_option.valFromOption(entity$1);
|
|
285
|
+
}
|
|
286
|
+
let entity$2 = LoadLayer.getByIdInMemory(entityConfig, scope, params.indexerState, entityId);
|
|
287
|
+
if (entity$2 === undefined) {
|
|
288
|
+
return missOrSuspend(sync, LoadLayer.loadById(params.loadManager, params.persistence, entityConfig, scope, params.indexerState, run.isPreload, entityId), undefined);
|
|
289
|
+
}
|
|
290
|
+
let entity$3 = Primitive_option.valFromOption(entity$2);
|
|
291
|
+
if (run.isPreload && Stdlib_Option.isNone(entity$3)) {
|
|
292
|
+
PreloadLookahead.recordAbsent(run.item, entityName, scope, entityKey);
|
|
293
|
+
}
|
|
294
|
+
return entity$3;
|
|
295
|
+
};
|
|
296
|
+
let syncEntityContext_getWhereSync = filter => {
|
|
297
|
+
let run = currentRunOrThrow(prop);
|
|
298
|
+
let sync = syncOrThrow(run, prop + `.getWhereSync`);
|
|
299
|
+
let scope = scopeOf(run);
|
|
300
|
+
let filter$1 = EntityFilter.parseOrThrow(filter, entityName, entityConfig.table);
|
|
301
|
+
let entities = LoadLayer.getByFilterInMemory(entityConfig, scope, params.indexerState, filter$1);
|
|
302
|
+
if (entities !== undefined) {
|
|
303
|
+
return SyncWrites.overlayFilter(sync.writes, entities, entityConfig, filter$1);
|
|
304
|
+
} else {
|
|
305
|
+
return missOrSuspend(sync, LoadLayer.loadByParsedFilter(params.loadManager, params.persistence, entityConfig, scope, params.indexerState, run.isPreload, filter$1), []);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
let syncEntityContext_getInBlockSync = entityId => {
|
|
309
|
+
let run = currentRunOrThrow(prop);
|
|
310
|
+
let sync = syncOrThrow(run, prop + `.getInBlockSync`);
|
|
311
|
+
let entity = SyncWrites.getById(sync.writes, entityConfig, entityId);
|
|
312
|
+
if (entity !== undefined) {
|
|
313
|
+
return Primitive_option.valFromOption(entity);
|
|
314
|
+
}
|
|
315
|
+
let inMemTable = InMemoryStore.getInMemTable(params.indexerState, entityConfig, scopeOf(run));
|
|
316
|
+
let change = inMemTable.latestEntityChangeById[inMemTable.entityIdToKey(entityId)];
|
|
317
|
+
if (change !== undefined && change.checkpointId === run.checkpointId) {
|
|
318
|
+
return InMemoryTable.Entity.mapChangeToEntity(change);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
let syncEntityContext = {
|
|
322
|
+
getSync: syncEntityContext_getSync,
|
|
323
|
+
getWhereSync: syncEntityContext_getWhereSync,
|
|
324
|
+
getInBlockSync: syncEntityContext_getInBlockSync
|
|
325
|
+
};
|
|
326
|
+
return Object.assign(object, syncEntityContext);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function runSyncRound(params, sync, fn, round) {
|
|
330
|
+
if (round > 10000) {
|
|
331
|
+
Stdlib_JsError.throwWithMessage(`The handler suspended on a synchronous read too many times: gave up after ` + (10000).toString() + ` rounds. This usually means the code isn't deterministic across reruns.`);
|
|
332
|
+
}
|
|
333
|
+
let run = sync.run;
|
|
334
|
+
sync.status = "Active";
|
|
335
|
+
sync.pending = [];
|
|
336
|
+
sync.speculated = 0;
|
|
337
|
+
sync.writes = SyncWrites.make();
|
|
338
|
+
let startedAt = PreloadLookahead.roundStarted(run.isPreload);
|
|
339
|
+
let previous = currentSync.contents;
|
|
340
|
+
currentSync.contents = sync;
|
|
341
|
+
let outcome;
|
|
342
|
+
try {
|
|
343
|
+
fn();
|
|
344
|
+
outcome = {
|
|
345
|
+
TAG: "Ok",
|
|
346
|
+
_0: undefined
|
|
347
|
+
};
|
|
348
|
+
} catch (raw_exn) {
|
|
349
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
350
|
+
outcome = {
|
|
351
|
+
TAG: "Error",
|
|
352
|
+
_0: exn
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
currentSync.contents = previous;
|
|
356
|
+
PreloadLookahead.roundEnded(run.item, startedAt);
|
|
357
|
+
let writes = sync.writes;
|
|
358
|
+
sync.writes = SyncWrites.make();
|
|
359
|
+
let suspended;
|
|
360
|
+
if (outcome.TAG === "Ok") {
|
|
361
|
+
let match = sync.status;
|
|
362
|
+
if (typeof match !== "object" && sync.speculated <= 0) {
|
|
363
|
+
if (run.isPreload) {
|
|
364
|
+
SyncWrites.forEachChange(writes, (entityConfig, scope, change) => PreloadLookahead.overlaySet(run.item, entityConfig.name, scope, entityConfig.table.entityIdToKey(change.entityId), InMemoryTable.Entity.mapChangeToEntity(change)));
|
|
365
|
+
} else {
|
|
366
|
+
SyncWrites.commit(writes, params.indexerState);
|
|
367
|
+
}
|
|
368
|
+
suspended = false;
|
|
369
|
+
} else {
|
|
370
|
+
suspended = true;
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
let exn$1 = outcome._0;
|
|
374
|
+
if (exn$1.RE_EXN_ID === Suspend || sync.speculated > 0) {
|
|
375
|
+
suspended = true;
|
|
376
|
+
} else {
|
|
377
|
+
sync.pending.forEach(promise => {
|
|
378
|
+
promise.catch(param => {});
|
|
379
|
+
});
|
|
380
|
+
sync.pending = [];
|
|
381
|
+
throw exn$1;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (!suspended) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
let pending = sync.pending;
|
|
388
|
+
sync.pending = [];
|
|
389
|
+
let errors = [];
|
|
390
|
+
await Promise.all(pending.map(promise => Stdlib_Promise.$$catch(promise, exn => {
|
|
391
|
+
errors.push(exn);
|
|
392
|
+
return Promise.resolve();
|
|
393
|
+
})));
|
|
394
|
+
let exn$2 = errors[0];
|
|
395
|
+
if (exn$2 !== undefined) {
|
|
396
|
+
throw exn$2;
|
|
397
|
+
}
|
|
398
|
+
return await runSyncRound(params, sync, fn, round + 1 | 0);
|
|
150
399
|
}
|
|
151
400
|
|
|
152
401
|
function makeHandlerContext(params) {
|
|
@@ -154,7 +403,7 @@ function makeHandlerContext(params) {
|
|
|
154
403
|
let define = (name, get) => {
|
|
155
404
|
Object.defineProperty(context, name, {
|
|
156
405
|
enumerable: true,
|
|
157
|
-
get: () => get(
|
|
406
|
+
get: () => get(currentRunOrThrow(name))
|
|
158
407
|
});
|
|
159
408
|
};
|
|
160
409
|
define("log", run => {
|
|
@@ -164,11 +413,31 @@ function makeHandlerContext(params) {
|
|
|
164
413
|
return Logger.asContextLog(RunScope.handlerLogger(run));
|
|
165
414
|
}
|
|
166
415
|
});
|
|
167
|
-
let effect = (effect$1, input) => callEffect(params,
|
|
416
|
+
let effect = (effect$1, input) => callEffect(params, currentRunOrThrow("effect"), undefined, effect$1, input);
|
|
168
417
|
Object.defineProperty(context, "effect", {
|
|
169
418
|
enumerable: true,
|
|
170
419
|
value: effect
|
|
171
420
|
});
|
|
421
|
+
if (Env.subgraphMode.contents) {
|
|
422
|
+
Object.defineProperty(context, "effectSync", {
|
|
423
|
+
enumerable: true,
|
|
424
|
+
value: (effect, input) => effectSync(params, effect, input)
|
|
425
|
+
});
|
|
426
|
+
Object.defineProperty(context, "runSync", {
|
|
427
|
+
enumerable: true,
|
|
428
|
+
value: fn => {
|
|
429
|
+
let run = currentRunOrThrow("runSync");
|
|
430
|
+
return runSyncRound(params, {
|
|
431
|
+
run: run,
|
|
432
|
+
status: "Active",
|
|
433
|
+
pending: [],
|
|
434
|
+
memo: {},
|
|
435
|
+
writes: SyncWrites.make(),
|
|
436
|
+
speculated: 0
|
|
437
|
+
}, fn, 1);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
172
441
|
define("isPreload", run => run.isPreload);
|
|
173
442
|
define("chain", run => params.chains[Internal.getItemChainId(run.item)]);
|
|
174
443
|
Utils.Dict.forEachWithKey(params.config.userEntitiesByName, (entityConfig, name) => {
|
|
@@ -178,13 +447,32 @@ function makeHandlerContext(params) {
|
|
|
178
447
|
return context;
|
|
179
448
|
}
|
|
180
449
|
|
|
450
|
+
let maxSpeculatedReads = 32;
|
|
451
|
+
|
|
452
|
+
let maxSyncRounds = 10000;
|
|
453
|
+
|
|
181
454
|
export {
|
|
455
|
+
Suspend,
|
|
456
|
+
isSuspend,
|
|
457
|
+
suspend,
|
|
458
|
+
currentSync,
|
|
459
|
+
syncOf,
|
|
460
|
+
currentRunOrThrow,
|
|
461
|
+
syncOrThrow,
|
|
462
|
+
scheduleAndSuspend,
|
|
463
|
+
maxSpeculatedReads,
|
|
464
|
+
missOrSuspend,
|
|
182
465
|
effectContextPrototype,
|
|
183
466
|
isCrossChain,
|
|
467
|
+
prepareEffectCall,
|
|
184
468
|
callEffect,
|
|
469
|
+
effectMemoKey,
|
|
470
|
+
effectSync,
|
|
185
471
|
expiresUnread,
|
|
186
472
|
throwExpiresUnread,
|
|
187
473
|
makeEntityContext,
|
|
474
|
+
maxSyncRounds,
|
|
475
|
+
runSyncRound,
|
|
188
476
|
makeHandlerContext,
|
|
189
477
|
}
|
|
190
478
|
/* effectContextPrototype Not a pure module */
|
package/src/Utils.res
CHANGED
|
@@ -10,12 +10,6 @@ external toMethod: 'a => 'a = "%unsafe_to_method"
|
|
|
10
10
|
|
|
11
11
|
@val external importPath: string => promise<unknown> = "import"
|
|
12
12
|
|
|
13
|
-
// Half the delay fixed, half spread across it. Every indexer pointed at one
|
|
14
|
-
// provider loses its stream, or gives up on a quiet chain, in the same instant
|
|
15
|
-
// that provider blinks, and putting them all back on the same schedule is how a
|
|
16
|
-
// blip becomes a stampede.
|
|
17
|
-
let jitter = delay => delay / 2 + (Math.random() *. (delay / 2)->Int.toFloat)->Float.toInt
|
|
18
|
-
|
|
19
13
|
// Clearing a pending timer and forgetting it are one action. A ref left holding
|
|
20
14
|
// a spent id reads as a timer still pending, and the next clear looks like it
|
|
21
15
|
// did something.
|
|
@@ -887,6 +881,23 @@ module Hash = {
|
|
|
887
881
|
(any->magic)["toString"]()
|
|
888
882
|
}
|
|
889
883
|
}
|
|
884
|
+
|
|
885
|
+
type sha256
|
|
886
|
+
@module("node:crypto") external createSha256: (@as("sha256") _, unit) => sha256 = "createHash"
|
|
887
|
+
@send external update: (sha256, string) => sha256 = "update"
|
|
888
|
+
@send external digestHex: (sha256, @as("hex") _) => string = "digest"
|
|
889
|
+
@val @scope("Buffer") external byteLength: string => int = "byteLength"
|
|
890
|
+
|
|
891
|
+
// A cache row is keyed by its effect's input, and a Postgres btree key takes
|
|
892
|
+
// at most 2704 bytes: a contract call with a large argument (calldata of a
|
|
893
|
+
// few kB) failed the batch write. Such inputs are keyed by their sha256;
|
|
894
|
+
// every shorter input keeps the key it always had.
|
|
895
|
+
let maxRawCacheKeyBytes = 2000
|
|
896
|
+
|
|
897
|
+
let boundCacheKey = (key: string) =>
|
|
898
|
+
key->byteLength > maxRawCacheKeyBytes
|
|
899
|
+
? "sha256:" ++ createSha256()->update(key)->digestHex
|
|
900
|
+
: key
|
|
890
901
|
}
|
|
891
902
|
|
|
892
903
|
let prettifyExn = exn => {
|
package/src/Utils.res.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import packageJson from '../package.json' with { type: 'json' }
|
|
|
2
2
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
3
3
|
|
|
4
4
|
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
5
|
+
import * as Nodecrypto from "node:crypto";
|
|
5
6
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
7
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
7
8
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
@@ -13,10 +14,6 @@ import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js
|
|
|
13
14
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
14
15
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
15
16
|
|
|
16
|
-
function jitter(delay) {
|
|
17
|
-
return (delay / 2 | 0) + (Math.random() * (delay / 2 | 0) | 0) | 0;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
17
|
function clearTimeoutRef(timeoutId) {
|
|
21
18
|
let id = timeoutId.contents;
|
|
22
19
|
if (id !== undefined) {
|
|
@@ -748,9 +745,19 @@ function makeOrThrow(any) {
|
|
|
748
745
|
return hash$1 + "}";
|
|
749
746
|
}
|
|
750
747
|
|
|
748
|
+
function boundCacheKey(key) {
|
|
749
|
+
if (Buffer.byteLength(key) > 2000) {
|
|
750
|
+
return "sha256:" + Nodecrypto.createHash("sha256").update(key).digest("hex");
|
|
751
|
+
} else {
|
|
752
|
+
return key;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
751
756
|
let Hash = {
|
|
752
757
|
fail: fail,
|
|
753
|
-
makeOrThrow: makeOrThrow
|
|
758
|
+
makeOrThrow: makeOrThrow,
|
|
759
|
+
maxRawCacheKeyBytes: 2000,
|
|
760
|
+
boundCacheKey: boundCacheKey
|
|
754
761
|
};
|
|
755
762
|
|
|
756
763
|
function prettifyExn(exn) {
|
|
@@ -813,7 +820,6 @@ function replaceLoneSurrogateEscapes(json) {
|
|
|
813
820
|
let maxBackoffExponent = 20;
|
|
814
821
|
|
|
815
822
|
export {
|
|
816
|
-
jitter,
|
|
817
823
|
clearTimeoutRef,
|
|
818
824
|
maxBackoffExponent,
|
|
819
825
|
expBackoff,
|
package/src/Writing.res
CHANGED
package/src/Writing.res.mjs
CHANGED
|
@@ -121,7 +121,7 @@ async function runOneWrite(state) {
|
|
|
121
121
|
});
|
|
122
122
|
let pruneTargets = PruneStaleHistory.select(state, writtenEntityNames, Stdlib_Option.isSome(rollback));
|
|
123
123
|
await Promise.all([
|
|
124
|
-
persistence.storage.writeBatch(batch, rollback, config,
|
|
124
|
+
persistence.storage.writeBatch(batch, rollback, config, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, (storage, timeSeconds) => IndexerState.recordStorageWrite(state, storage, timeSeconds)),
|
|
125
125
|
PruneStaleHistory.runConcurrent(state, pruneTargets)
|
|
126
126
|
]);
|
|
127
127
|
IndexerState.markCommitted(state, writtenFrontier);
|