envio 3.14.0-subgraph → 3.14.1
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/evm.schema.json +1 -1
- package/package.json +6 -6
- package/src/Config.res +0 -9
- package/src/Config.res.mjs +2 -6
- package/src/Core.res +0 -21
- package/src/Core.res.mjs +0 -17
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +6 -8
- package/src/HandlerLoader.res +22 -48
- package/src/HandlerLoader.res.mjs +15 -41
- package/src/HandlerTypeCheck.res +207 -0
- package/src/HandlerTypeCheck.res.mjs +262 -0
- package/src/LoadLayer.res +7 -39
- package/src/LoadLayer.res.mjs +38 -65
- package/src/LoadLayer.resi +0 -28
- package/src/PgStorage.res +5 -24
- package/src/PgStorage.res.mjs +1 -18
- package/src/UserContext.res +62 -377
- package/src/UserContext.res.mjs +39 -297
- package/src/bindings/NodeJs.res +31 -0
- package/src/bindings/NodeJs.res.mjs +3 -0
- package/src/db/Table.res +0 -10
- package/src/db/Table.res.mjs +11 -22
- package/src/sources/EvmRpcClient.res +2 -0
- package/src/sources/RpcSource.res +17 -4
- package/src/sources/RpcSource.res.mjs +23 -5
- package/src/sources/SourceManager.res +63 -40
- package/src/sources/SourceManager.res.mjs +32 -20
- package/src/HandlerTypeCheck.mjs +0 -14
- package/src/HandlerTypeCheckWorker.mjs +0 -68
- package/src/SyncWrites.res +0 -86
- package/src/SyncWrites.res.mjs +0 -85
- package/src/subgraph/abi-types.ts +0 -63
- package/src/subgraph/assemblyscript.ts +0 -85
- package/src/subgraph/blocks.ts +0 -183
- package/src/subgraph/calls.ts +0 -149
- package/src/subgraph/conformance.ts +0 -83
- package/src/subgraph/errors.ts +0 -96
- package/src/subgraph/graph-cli-worker.mjs +0 -26
- package/src/subgraph/graph-cli.ts +0 -190
- 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 -2285
- package/src/subgraph/hosts.ts +0 -158
- package/src/subgraph/rpc.ts +0 -65
- package/src/subgraph/runtime.ts +0 -595
- package/src/subgraph/scope.ts +0 -68
package/src/UserContext.res.mjs
CHANGED
|
@@ -1,83 +1,19 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Utils from "./Utils.res.mjs";
|
|
4
|
-
import * as ChainId from "./ChainId.res.mjs";
|
|
5
4
|
import * as Logging from "./Logging.res.mjs";
|
|
6
5
|
import * as Internal from "./Internal.res.mjs";
|
|
7
6
|
import * as Ecosystem from "./Ecosystem.res.mjs";
|
|
8
7
|
import * as LoadLayer from "./LoadLayer.res.mjs";
|
|
9
|
-
import * as SyncWrites from "./SyncWrites.res.mjs";
|
|
10
8
|
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
9
|
+
import * as IndexerState from "./IndexerState.res.mjs";
|
|
11
10
|
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
12
11
|
import * as InMemoryStore from "./InMemoryStore.res.mjs";
|
|
13
12
|
import * as InMemoryTable from "./InMemoryTable.res.mjs";
|
|
14
13
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
15
14
|
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
15
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
18
16
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
19
|
-
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
20
|
-
|
|
21
|
-
let Suspend = /* @__PURE__ */Primitive_exceptions.create("UserContext.Suspend");
|
|
22
|
-
|
|
23
|
-
function isSuspend(exn) {
|
|
24
|
-
return exn.RE_EXN_ID === Suspend;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function makeSyncState() {
|
|
28
|
-
return {
|
|
29
|
-
status: "Active",
|
|
30
|
-
pending: undefined,
|
|
31
|
-
memo: undefined,
|
|
32
|
-
writes: undefined
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function getPending(sync) {
|
|
37
|
-
let pending = sync.pending;
|
|
38
|
-
if (pending !== undefined) {
|
|
39
|
-
return pending;
|
|
40
|
-
}
|
|
41
|
-
let pending$1 = [];
|
|
42
|
-
sync.pending = pending$1;
|
|
43
|
-
return pending$1;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function getMemo(sync) {
|
|
47
|
-
let memo = sync.memo;
|
|
48
|
-
if (memo !== undefined) {
|
|
49
|
-
return memo;
|
|
50
|
-
}
|
|
51
|
-
let memo$1 = {};
|
|
52
|
-
sync.memo = memo$1;
|
|
53
|
-
return memo$1;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function checkStatusOrThrow(params, access) {
|
|
57
|
-
let exn = params.sync.status;
|
|
58
|
-
if (typeof exn !== "object") {
|
|
59
|
-
if (exn === "Active") {
|
|
60
|
-
return;
|
|
61
|
-
} else {
|
|
62
|
-
return ErrorHandling.mkLogAndRaise(Ecosystem.getItemLogger(params.item, params.config.ecosystem), undefined, new Error(`Impossible to access ` + access + ` after the handler is resolved. Make sure you didn't miss an await in the handler.`));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
throw exn._0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function scheduleAndSuspend(params, promise) {
|
|
69
|
-
getPending(params.sync).push(promise);
|
|
70
|
-
params.sync.status = {
|
|
71
|
-
TAG: "Aborted",
|
|
72
|
-
_0: {
|
|
73
|
-
RE_EXN_ID: Suspend
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
throw {
|
|
77
|
-
RE_EXN_ID: Suspend,
|
|
78
|
-
Error: new Error()
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
17
|
|
|
82
18
|
let paramsByThis = new WeakMap();
|
|
83
19
|
|
|
@@ -111,71 +47,29 @@ var EffectContext = function(params, chainId, effectName, defaultShouldCache, ca
|
|
|
111
47
|
EffectContext.prototype = effectContextPrototype;
|
|
112
48
|
;
|
|
113
49
|
|
|
114
|
-
function prepareEffectCall(params, effect, input, caller) {
|
|
115
|
-
let isCrossChain = effect => Stdlib_Option.getOr(effect.crossChain, params.config.defaultCrossChain);
|
|
116
|
-
let scope = isCrossChain(effect) ? "crossChain" : Internal.getItemChainId(params.item);
|
|
117
|
-
if (caller !== undefined && isCrossChain(caller) && !isCrossChain(effect)) {
|
|
118
|
-
Stdlib_JsError.throwWithMessage(`The cross-chain effect "` + caller.name + `" cannot call the chain-scoped effect "` + effect.name + `", because a cross-chain effect isn't tied to a single chain. Make "` + effect.name + `" cross-chain (\`crossChain: true\`), or make "` + caller.name + `" chain-scoped (\`crossChain: false\`).`);
|
|
119
|
-
}
|
|
120
|
-
let tmp;
|
|
121
|
-
tmp = scope === "crossChain" ? undefined : Primitive_option.some(scope);
|
|
122
|
-
let effectContext = new EffectContext(params, tmp, effect.name, effect.defaultShouldCache, (nested, nestedInput) => callEffectAsync(params, nested, nestedInput, effect));
|
|
123
|
-
let effectArgs_cacheKey = Utils.Hash.makeOrThrow(S$RescriptSchema.reverseConvertOrThrow(input, effect.input));
|
|
124
|
-
let effectArgs_chainId = Internal.getItemChainId(params.item);
|
|
125
|
-
let effectArgs_checkpointId = params.checkpointId;
|
|
126
|
-
let effectArgs = {
|
|
127
|
-
input: input,
|
|
128
|
-
context: effectContext,
|
|
129
|
-
cacheKey: effectArgs_cacheKey,
|
|
130
|
-
chainId: effectArgs_chainId,
|
|
131
|
-
checkpointId: effectArgs_checkpointId
|
|
132
|
-
};
|
|
133
|
-
return [
|
|
134
|
-
scope,
|
|
135
|
-
effectArgs
|
|
136
|
-
];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function callEffectAsync(params, effect, input, caller) {
|
|
140
|
-
let match = prepareEffectCall(params, effect, input, caller);
|
|
141
|
-
return LoadLayer.loadEffect(params.loadManager, params.persistence, effect, match[1], match[0], params.indexerState, params.isPreload, params.item, params.config.ecosystem);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
50
|
function initEffect(params) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
function effectMemoKey(effect, scope, cacheKey) {
|
|
152
|
-
if (scope === "crossChain") {
|
|
153
|
-
return effect.name + `.` + cacheKey;
|
|
154
|
-
} else {
|
|
155
|
-
return effect.name + `.` + ChainId.toString(scope) + `.` + cacheKey;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function initEffectSync(params) {
|
|
160
|
-
return (effect, input) => {
|
|
161
|
-
checkStatusOrThrow(params, "context.effectSync");
|
|
162
|
-
let match = prepareEffectCall(params, effect, input, undefined);
|
|
163
|
-
let effectArgs = match[1];
|
|
164
|
-
let scope = match[0];
|
|
165
|
-
let memo = getMemo(params.sync);
|
|
166
|
-
let memoKey = effectMemoKey(effect, scope, effectArgs.cacheKey);
|
|
167
|
-
let output = memo[memoKey];
|
|
168
|
-
if (output !== undefined) {
|
|
169
|
-
return Primitive_option.valFromOption(output);
|
|
170
|
-
}
|
|
171
|
-
let inMemTable = InMemoryStore.getEffectInMemTable(params.indexerState, effect, scope);
|
|
172
|
-
if (!InMemoryStore.hasEffectOutput(inMemTable, effectArgs.cacheKey)) {
|
|
173
|
-
return scheduleAndSuspend(params, LoadLayer.loadEffect(params.loadManager, params.persistence, effect, effectArgs, scope, params.indexerState, params.isPreload, params.item, params.config.ecosystem));
|
|
51
|
+
let handlerChainId = Internal.getItemChainId(params.item);
|
|
52
|
+
let isCrossChain = effect => Stdlib_Option.getOr(effect.crossChain, params.config.defaultCrossChain);
|
|
53
|
+
let makeCaller = caller => ((effect, input) => {
|
|
54
|
+
let scope = isCrossChain(effect) ? "crossChain" : handlerChainId;
|
|
55
|
+
if (caller !== undefined && isCrossChain(caller) && !isCrossChain(effect)) {
|
|
56
|
+
Stdlib_JsError.throwWithMessage(`The cross-chain effect "` + caller.name + `" cannot call the chain-scoped effect "` + effect.name + `", because a cross-chain effect isn't tied to a single chain. Make "` + effect.name + `" cross-chain (\`crossChain: true\`), or make "` + caller.name + `" chain-scoped (\`crossChain: false\`).`);
|
|
174
57
|
}
|
|
175
|
-
let
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
58
|
+
let tmp;
|
|
59
|
+
tmp = scope === "crossChain" ? undefined : Primitive_option.some(scope);
|
|
60
|
+
let effectContext = new EffectContext(params, tmp, effect.name, effect.defaultShouldCache, makeCaller(effect));
|
|
61
|
+
let effectArgs_cacheKey = Utils.Hash.makeOrThrow(S$RescriptSchema.reverseConvertOrThrow(input, effect.input));
|
|
62
|
+
let effectArgs_checkpointId = params.checkpointId;
|
|
63
|
+
let effectArgs = {
|
|
64
|
+
input: input,
|
|
65
|
+
context: effectContext,
|
|
66
|
+
cacheKey: effectArgs_cacheKey,
|
|
67
|
+
chainId: handlerChainId,
|
|
68
|
+
checkpointId: effectArgs_checkpointId
|
|
69
|
+
};
|
|
70
|
+
return LoadLayer.loadEffect(params.loadManager, params.persistence, effect, effectArgs, scope, params.indexerState, params.isPreload, params.item, params.config.ecosystem);
|
|
71
|
+
});
|
|
72
|
+
return makeCaller(undefined);
|
|
179
73
|
}
|
|
180
74
|
|
|
181
75
|
function entityScope(params) {
|
|
@@ -198,88 +92,26 @@ function throwClickHouseReadOnly(entityConfig, op) {
|
|
|
198
92
|
return Stdlib_JsError.throwWithMessage(`context.` + entityConfig.name + `.` + op + `() is unavailable: ClickHouse storage is currently write-only. Follow Envio releases to be notified when ClickHouse supports both reads and writes from handlers.`);
|
|
199
93
|
}
|
|
200
94
|
|
|
201
|
-
function writeChange(params, change) {
|
|
202
|
-
let scope = entityScope(params);
|
|
203
|
-
let writes = params.sync.writes;
|
|
204
|
-
if (writes !== undefined) {
|
|
205
|
-
return SyncWrites.record(writes, params.entityConfig, scope, change);
|
|
206
|
-
} else {
|
|
207
|
-
return SyncWrites.write(params.indexerState, params.entityConfig, scope, change);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function getRoundWrite(params, entityId) {
|
|
212
|
-
let writes = params.sync.writes;
|
|
213
|
-
if (writes !== undefined) {
|
|
214
|
-
return SyncWrites.getById(writes, params.entityConfig, entityId);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function getSyncHandler(params, entityId) {
|
|
219
|
-
let entity = getRoundWrite(params, entityId);
|
|
220
|
-
if (entity !== undefined) {
|
|
221
|
-
return Primitive_option.valFromOption(entity);
|
|
222
|
-
}
|
|
223
|
-
let entity$1 = LoadLayer.getByIdInMemory(params.entityConfig, entityScope(params), params.indexerState, entityId);
|
|
224
|
-
if (entity$1 !== undefined) {
|
|
225
|
-
return Primitive_option.valFromOption(entity$1);
|
|
226
|
-
} else {
|
|
227
|
-
return scheduleAndSuspend(params, LoadLayer.loadById(params.loadManager, params.persistence, params.entityConfig, entityScope(params), params.indexerState, params.isPreload, params.item, params.config.ecosystem, entityId));
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function getWhereSyncHandler(params, filter) {
|
|
232
|
-
let entityConfig = params.entityConfig;
|
|
233
|
-
let filter$1 = EntityFilter.parseOrThrow(filter, entityConfig.name, entityConfig.table);
|
|
234
|
-
let entities = LoadLayer.getByFilterInMemory(entityConfig, entityScope(params), params.indexerState, filter$1);
|
|
235
|
-
if (entities === undefined) {
|
|
236
|
-
return scheduleAndSuspend(params, LoadLayer.loadByParsedFilter(params.loadManager, params.persistence, entityConfig, entityScope(params), params.indexerState, params.isPreload, params.item, params.config.ecosystem, filter$1));
|
|
237
|
-
}
|
|
238
|
-
let writes = params.sync.writes;
|
|
239
|
-
if (writes !== undefined) {
|
|
240
|
-
return SyncWrites.overlayFilter(writes, entities, entityConfig, filter$1);
|
|
241
|
-
} else {
|
|
242
|
-
return entities;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function getInBlockSyncHandler(params, entityId) {
|
|
247
|
-
let entity = getRoundWrite(params, entityId);
|
|
248
|
-
if (entity !== undefined) {
|
|
249
|
-
return Primitive_option.valFromOption(entity);
|
|
250
|
-
}
|
|
251
|
-
let inMemTable = InMemoryStore.getInMemTable(params.indexerState, params.entityConfig, entityScope(params));
|
|
252
|
-
let change = inMemTable.latestEntityChangeById[entityId];
|
|
253
|
-
if (change !== undefined && change.checkpointId === params.checkpointId) {
|
|
254
|
-
return InMemoryTable.Entity.mapChangeToEntity(change);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
95
|
let entityTraps_get = (params, prop) => {
|
|
259
|
-
checkStatusOrThrow(params, `context.` + params.entityConfig.name + `.` + prop);
|
|
260
96
|
let isClickHouseOnly = !params.entityConfig.storage.postgres;
|
|
261
|
-
let
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
};
|
|
97
|
+
let scope = entityScope(params);
|
|
98
|
+
let committedCheckpointId = IndexerState.committedCheckpointIdFor(params.indexerState, scope);
|
|
99
|
+
let set = params.isPreload ? noopSet : entity => InMemoryTable.Entity.set(InMemoryStore.getInMemTable(params.indexerState, params.entityConfig, scope), committedCheckpointId, {
|
|
100
|
+
type: "SET",
|
|
101
|
+
entityId: entity.id,
|
|
102
|
+
entity: entity,
|
|
103
|
+
checkpointId: params.checkpointId
|
|
104
|
+
});
|
|
270
105
|
switch (prop) {
|
|
271
106
|
case "deleteUnsafe" :
|
|
272
107
|
if (params.isPreload) {
|
|
273
108
|
return noopDeleteUnsafe;
|
|
274
109
|
} else {
|
|
275
|
-
return entityId => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
checkpointId: params.checkpointId
|
|
281
|
-
});
|
|
282
|
-
};
|
|
110
|
+
return entityId => InMemoryTable.Entity.set(InMemoryStore.getInMemTable(params.indexerState, params.entityConfig, scope), committedCheckpointId, {
|
|
111
|
+
type: "DELETE",
|
|
112
|
+
entityId: entityId,
|
|
113
|
+
checkpointId: params.checkpointId
|
|
114
|
+
});
|
|
283
115
|
}
|
|
284
116
|
case "get" :
|
|
285
117
|
if (isClickHouseOnly) {
|
|
@@ -287,8 +119,6 @@ let entityTraps_get = (params, prop) => {
|
|
|
287
119
|
} else {
|
|
288
120
|
return entityId => LoadLayer.loadById(params.loadManager, params.persistence, params.entityConfig, entityScope(params), params.indexerState, params.isPreload, params.item, params.config.ecosystem, entityId);
|
|
289
121
|
}
|
|
290
|
-
case "getInBlockSync" :
|
|
291
|
-
return entityId => getInBlockSyncHandler(params, entityId);
|
|
292
122
|
case "getOrCreate" :
|
|
293
123
|
if (isClickHouseOnly) {
|
|
294
124
|
return _entity => throwClickHouseReadOnly(params.entityConfig, "getOrCreate");
|
|
@@ -314,16 +144,12 @@ let entityTraps_get = (params, prop) => {
|
|
|
314
144
|
}
|
|
315
145
|
});
|
|
316
146
|
}
|
|
317
|
-
case "getSync" :
|
|
318
|
-
return entityId => getSyncHandler(params, entityId);
|
|
319
147
|
case "getWhere" :
|
|
320
148
|
if (isClickHouseOnly) {
|
|
321
149
|
return _filter => throwClickHouseReadOnly(params.entityConfig, "getWhere");
|
|
322
150
|
} else {
|
|
323
151
|
return filter => getWhereHandler(params, filter);
|
|
324
152
|
}
|
|
325
|
-
case "getWhereSync" :
|
|
326
|
-
return filter => getWhereSyncHandler(params, filter);
|
|
327
153
|
case "set" :
|
|
328
154
|
return set;
|
|
329
155
|
default:
|
|
@@ -335,78 +161,16 @@ let entityTraps = {
|
|
|
335
161
|
get: entityTraps_get
|
|
336
162
|
};
|
|
337
163
|
|
|
338
|
-
async function runSyncRound(params, fn, round) {
|
|
339
|
-
if (round > 10000) {
|
|
340
|
-
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.`);
|
|
341
|
-
}
|
|
342
|
-
params.sync.status = "Active";
|
|
343
|
-
params.sync.pending = undefined;
|
|
344
|
-
let writes = SyncWrites.make();
|
|
345
|
-
params.sync.writes = writes;
|
|
346
|
-
let suspended;
|
|
347
|
-
let exit = 0;
|
|
348
|
-
let val;
|
|
349
|
-
try {
|
|
350
|
-
val = fn();
|
|
351
|
-
exit = 1;
|
|
352
|
-
} catch (raw_exn) {
|
|
353
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
354
|
-
params.sync.writes = undefined;
|
|
355
|
-
if (exn.RE_EXN_ID === Suspend) {
|
|
356
|
-
suspended = true;
|
|
357
|
-
} else {
|
|
358
|
-
let pending = params.sync.pending;
|
|
359
|
-
if (pending !== undefined) {
|
|
360
|
-
params.sync.pending = undefined;
|
|
361
|
-
pending.forEach(promise => {
|
|
362
|
-
Utils.$$Promise.silentCatch(promise);
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
throw exn;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
if (exit === 1) {
|
|
369
|
-
params.sync.writes = undefined;
|
|
370
|
-
let match = params.sync.status;
|
|
371
|
-
if (typeof match !== "object") {
|
|
372
|
-
if (match === "Active") {
|
|
373
|
-
SyncWrites.commit(writes, params.indexerState);
|
|
374
|
-
suspended = false;
|
|
375
|
-
} else {
|
|
376
|
-
SyncWrites.commit(writes, params.indexerState);
|
|
377
|
-
suspended = false;
|
|
378
|
-
}
|
|
379
|
-
} else {
|
|
380
|
-
suspended = true;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
if (!suspended) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
let pending$1 = Stdlib_Option.getOr(params.sync.pending, []);
|
|
387
|
-
params.sync.pending = undefined;
|
|
388
|
-
let errors = [];
|
|
389
|
-
await Promise.all(pending$1.map(promise => Stdlib_Promise.$$catch(promise, exn => {
|
|
390
|
-
errors.push(exn);
|
|
391
|
-
return Promise.resolve();
|
|
392
|
-
})));
|
|
393
|
-
let exn$1 = errors[0];
|
|
394
|
-
if (exn$1 !== undefined) {
|
|
395
|
-
throw exn$1;
|
|
396
|
-
}
|
|
397
|
-
return await runSyncRound(params, fn, round + 1 | 0);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
164
|
let handlerTraps_get = (params, prop) => {
|
|
401
|
-
|
|
165
|
+
if (params.isResolved) {
|
|
166
|
+
ErrorHandling.mkLogAndRaise(Ecosystem.getItemLogger(params.item, params.config.ecosystem), undefined, new Error(`Impossible to access context.` + prop + ` after the handler is resolved. Make sure you didn't miss an await in the handler.`));
|
|
167
|
+
}
|
|
402
168
|
switch (prop) {
|
|
403
169
|
case "chain" :
|
|
404
170
|
let chainId = Internal.getItemChainId(params.item);
|
|
405
171
|
return params.chains[chainId];
|
|
406
172
|
case "effect" :
|
|
407
173
|
return initEffect(params);
|
|
408
|
-
case "effectSync" :
|
|
409
|
-
return initEffectSync(params);
|
|
410
174
|
case "isPreload" :
|
|
411
175
|
return params.isPreload;
|
|
412
176
|
case "log" :
|
|
@@ -415,8 +179,6 @@ let handlerTraps_get = (params, prop) => {
|
|
|
415
179
|
} else {
|
|
416
180
|
return Ecosystem.getItemUserLogger(params.item, params.config.ecosystem);
|
|
417
181
|
}
|
|
418
|
-
case "runSync" :
|
|
419
|
-
return fn => runSyncRound(params, fn, 1);
|
|
420
182
|
default:
|
|
421
183
|
let entityConfig = params.config.userEntitiesByName[prop];
|
|
422
184
|
if (entityConfig !== undefined) {
|
|
@@ -429,7 +191,7 @@ let handlerTraps_get = (params, prop) => {
|
|
|
429
191
|
isPreload: params.isPreload,
|
|
430
192
|
chains: params.chains,
|
|
431
193
|
config: params.config,
|
|
432
|
-
|
|
194
|
+
isResolved: params.isResolved,
|
|
433
195
|
entityConfig: entityConfig
|
|
434
196
|
}, entityTraps);
|
|
435
197
|
} else {
|
|
@@ -446,36 +208,16 @@ function getHandlerContext(params) {
|
|
|
446
208
|
return new Proxy(params, handlerTraps);
|
|
447
209
|
}
|
|
448
210
|
|
|
449
|
-
let maxSyncRounds = 10000;
|
|
450
|
-
|
|
451
211
|
export {
|
|
452
|
-
Suspend,
|
|
453
|
-
isSuspend,
|
|
454
|
-
makeSyncState,
|
|
455
|
-
getPending,
|
|
456
|
-
getMemo,
|
|
457
|
-
checkStatusOrThrow,
|
|
458
|
-
scheduleAndSuspend,
|
|
459
212
|
paramsByThis,
|
|
460
213
|
effectContextPrototype,
|
|
461
|
-
prepareEffectCall,
|
|
462
|
-
callEffectAsync,
|
|
463
214
|
initEffect,
|
|
464
|
-
effectMemoKey,
|
|
465
|
-
initEffectSync,
|
|
466
215
|
entityScope,
|
|
467
216
|
getWhereHandler,
|
|
468
217
|
noopSet,
|
|
469
218
|
noopDeleteUnsafe,
|
|
470
219
|
throwClickHouseReadOnly,
|
|
471
|
-
writeChange,
|
|
472
|
-
getRoundWrite,
|
|
473
|
-
getSyncHandler,
|
|
474
|
-
getWhereSyncHandler,
|
|
475
|
-
getInBlockSyncHandler,
|
|
476
220
|
entityTraps,
|
|
477
|
-
maxSyncRounds,
|
|
478
|
-
runSyncRound,
|
|
479
221
|
handlerTraps,
|
|
480
222
|
getHandlerContext,
|
|
481
223
|
}
|
package/src/bindings/NodeJs.res
CHANGED
|
@@ -39,6 +39,15 @@ module Util = {
|
|
|
39
39
|
@module("util") external inspect: ('a, inspectOptions) => string = "inspect"
|
|
40
40
|
|
|
41
41
|
let inspectObj = a => inspect(a, {showHidden: false, depth: Null, colors: true})
|
|
42
|
+
|
|
43
|
+
@module("util") external stripVTControlCharacters: string => string = "stripVTControlCharacters"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module Module = {
|
|
47
|
+
type require
|
|
48
|
+
|
|
49
|
+
@module("module") external createRequire: string => require = "createRequire"
|
|
50
|
+
@send external resolve: (require, string) => string = "resolve"
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
module Process = {
|
|
@@ -165,6 +174,23 @@ module ChildProcess = {
|
|
|
165
174
|
@module("child_process")
|
|
166
175
|
external execWithOptions: (string, execOptions, callback) => unit = "exec"
|
|
167
176
|
|
|
177
|
+
type execFileOptions = {
|
|
178
|
+
cwd?: string,
|
|
179
|
+
timeout?: int,
|
|
180
|
+
maxBuffer?: float,
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// `killed` is set when the timeout stopped the child.
|
|
184
|
+
type execFileError = {killed: bool}
|
|
185
|
+
|
|
186
|
+
@module("child_process")
|
|
187
|
+
external execFile: (
|
|
188
|
+
string,
|
|
189
|
+
array<string>,
|
|
190
|
+
execFileOptions,
|
|
191
|
+
(Null.t<execFileError>, string, string) => unit,
|
|
192
|
+
) => unit = "execFile"
|
|
193
|
+
|
|
168
194
|
// One of a child's stdio slots, present only for a slot the parent asked to
|
|
169
195
|
// pipe rather than inherit.
|
|
170
196
|
module Stream = {
|
|
@@ -225,6 +251,8 @@ module Path = {
|
|
|
225
251
|
|
|
226
252
|
@module("path") external join: (t, string) => t = "join"
|
|
227
253
|
@module("path") external dirname: string => t = "dirname"
|
|
254
|
+
@module("path") external relative: (string, string) => string = "relative"
|
|
255
|
+
@module("path") external isAbsolute: string => bool = "isAbsolute"
|
|
228
256
|
|
|
229
257
|
external toString: t => string = "%identity"
|
|
230
258
|
|
|
@@ -275,6 +303,9 @@ module Fs = {
|
|
|
275
303
|
mode?: int,
|
|
276
304
|
}
|
|
277
305
|
|
|
306
|
+
@module("fs") external existsSync: string => bool = "existsSync"
|
|
307
|
+
@module("fs") external readFileSync: (string, @as("utf8") _) => string = "readFileSync"
|
|
308
|
+
|
|
278
309
|
module Promises = {
|
|
279
310
|
@module("fs") @scope("promises")
|
|
280
311
|
external writeFile: (
|
|
@@ -16,6 +16,8 @@ let Util$1 = {
|
|
|
16
16
|
inspectObj: inspectObj
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
let Module = {};
|
|
20
|
+
|
|
19
21
|
let Process = {};
|
|
20
22
|
|
|
21
23
|
let empty = globalThis.Buffer.alloc(0);
|
|
@@ -59,6 +61,7 @@ let Fs = {
|
|
|
59
61
|
|
|
60
62
|
export {
|
|
61
63
|
Util$1 as Util,
|
|
64
|
+
Module,
|
|
62
65
|
Process,
|
|
63
66
|
Buffer,
|
|
64
67
|
V8,
|
package/src/db/Table.res
CHANGED
|
@@ -454,7 +454,6 @@ type sqlParams<'entity> = {
|
|
|
454
454
|
quotedNonPrimaryFieldNames: array<string>,
|
|
455
455
|
arrayFieldTypes: array<string>,
|
|
456
456
|
byteaColumnIndexes: array<int>,
|
|
457
|
-
booleanArrayColumnIndexes: array<int>,
|
|
458
457
|
hasArrayField: bool,
|
|
459
458
|
}
|
|
460
459
|
|
|
@@ -465,10 +464,6 @@ let toSqlParams = (table: table, ~schema, ~pgSchema, ~chainIdMode: ChainId.mode=
|
|
|
465
464
|
// Positions of the bytea columns among the unnest parameters, which the
|
|
466
465
|
// caller binds as array literals (see `Utils.Bytes.toPgArrayLiteral`).
|
|
467
466
|
let byteaColumnIndexes = []
|
|
468
|
-
// postgres binds a JS array of booleans as a single `boolean`, whatever the
|
|
469
|
-
// column (https://github.com/porsager/postgres/issues/471), so the VALUES
|
|
470
|
-
// insert binds these columns as integer arrays and casts them back.
|
|
471
|
-
let booleanArrayColumnIndexes = []
|
|
472
467
|
let hasArrayField = ref(false)
|
|
473
468
|
|
|
474
469
|
let dbSchema: S.t<dict<unknown>> = S.schema(s =>
|
|
@@ -504,10 +499,6 @@ let toSqlParams = (table: table, ~schema, ~pgSchema, ~chainIdMode: ChainId.mode=
|
|
|
504
499
|
| None => throw(NonExistingTableField(location))
|
|
505
500
|
}
|
|
506
501
|
switch field {
|
|
507
|
-
| Field({isArray: true, fieldType: Boolean}) => {
|
|
508
|
-
hasArrayField := true
|
|
509
|
-
booleanArrayColumnIndexes->Array.push(arrayFieldTypes->Array.length)->ignore
|
|
510
|
-
}
|
|
511
502
|
| Field({isArray: true}) => hasArrayField := true
|
|
512
503
|
| Field({fieldType: Bytea}) =>
|
|
513
504
|
byteaColumnIndexes->Array.push(arrayFieldTypes->Array.length)->ignore
|
|
@@ -563,7 +554,6 @@ let toSqlParams = (table: table, ~schema, ~pgSchema, ~chainIdMode: ChainId.mode=
|
|
|
563
554
|
quotedNonPrimaryFieldNames,
|
|
564
555
|
arrayFieldTypes,
|
|
565
556
|
byteaColumnIndexes,
|
|
566
|
-
booleanArrayColumnIndexes,
|
|
567
557
|
hasArrayField: hasArrayField.contents,
|
|
568
558
|
}
|
|
569
559
|
}
|
package/src/db/Table.res.mjs
CHANGED
|
@@ -384,7 +384,6 @@ function toSqlParams(table, schema, pgSchema, chainIdModeOpt) {
|
|
|
384
384
|
let quotedNonPrimaryFieldNames = [];
|
|
385
385
|
let arrayFieldTypes = [];
|
|
386
386
|
let byteaColumnIndexes = [];
|
|
387
|
-
let booleanArrayColumnIndexes = [];
|
|
388
387
|
let hasArrayField = {
|
|
389
388
|
contents: false
|
|
390
389
|
};
|
|
@@ -442,20 +441,11 @@ function toSqlParams(table, schema, pgSchema, chainIdModeOpt) {
|
|
|
442
441
|
}
|
|
443
442
|
if (field$1.TAG === "Field") {
|
|
444
443
|
let match = field$1._0;
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
if (typeof match$1 !== "object" && match$1 === "Boolean") {
|
|
448
|
-
if (match.isArray) {
|
|
449
|
-
hasArrayField.contents = true;
|
|
450
|
-
booleanArrayColumnIndexes.push(arrayFieldTypes.length);
|
|
451
|
-
}
|
|
444
|
+
if (match.isArray) {
|
|
445
|
+
hasArrayField.contents = true;
|
|
452
446
|
} else {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
if (exit === 1) {
|
|
456
|
-
if (match.isArray) {
|
|
457
|
-
hasArrayField.contents = true;
|
|
458
|
-
} else if (typeof match$1 !== "object" && match$1 === "Bytea") {
|
|
447
|
+
let tmp = match.fieldType;
|
|
448
|
+
if (typeof tmp !== "object" && tmp === "Bytea") {
|
|
459
449
|
byteaColumnIndexes.push(arrayFieldTypes.length);
|
|
460
450
|
}
|
|
461
451
|
}
|
|
@@ -469,20 +459,20 @@ function toSqlParams(table, schema, pgSchema, chainIdModeOpt) {
|
|
|
469
459
|
quotedNonPrimaryFieldNames.push(quotedDbName);
|
|
470
460
|
}
|
|
471
461
|
}
|
|
472
|
-
let tmp;
|
|
462
|
+
let tmp$1;
|
|
473
463
|
if (field$1.TAG === "Field") {
|
|
474
464
|
let f = field$1._0;
|
|
475
465
|
let pgFieldType = getPgFieldType(f.fieldType, pgSchema, true, false, f.isNullable, chainIdMode);
|
|
476
|
-
let match$
|
|
477
|
-
tmp = typeof match$
|
|
478
|
-
match$
|
|
466
|
+
let match$1 = f.fieldType;
|
|
467
|
+
tmp$1 = typeof match$1 !== "object" ? (
|
|
468
|
+
match$1 === "Boolean" ? "INTEGER" + `[]::` + pgFieldType : pgFieldType
|
|
479
469
|
) : (
|
|
480
|
-
match$
|
|
470
|
+
match$1.type === "Enum" ? "TEXT" + `[]::` + pgFieldType : pgFieldType
|
|
481
471
|
);
|
|
482
472
|
} else {
|
|
483
|
-
tmp = "TEXT[]";
|
|
473
|
+
tmp$1 = "TEXT[]";
|
|
484
474
|
}
|
|
485
|
-
arrayFieldTypes.push(tmp);
|
|
475
|
+
arrayFieldTypes.push(tmp$1);
|
|
486
476
|
dict[location] = s.m(coerceSchema(param.schema));
|
|
487
477
|
});
|
|
488
478
|
return dict;
|
|
@@ -493,7 +483,6 @@ function toSqlParams(table, schema, pgSchema, chainIdModeOpt) {
|
|
|
493
483
|
quotedNonPrimaryFieldNames: quotedNonPrimaryFieldNames,
|
|
494
484
|
arrayFieldTypes: arrayFieldTypes,
|
|
495
485
|
byteaColumnIndexes: byteaColumnIndexes,
|
|
496
|
-
booleanArrayColumnIndexes: booleanArrayColumnIndexes,
|
|
497
486
|
hasArrayField: hasArrayField.contents
|
|
498
487
|
};
|
|
499
488
|
}
|
|
@@ -28,6 +28,7 @@ type pageOutcome =
|
|
|
28
28
|
| @as("SuggestedToBlock") SuggestedToBlock
|
|
29
29
|
| @as("Backoff") Backoff
|
|
30
30
|
| @as("FieldSelection") FieldSelection
|
|
31
|
+
| @as("BehindHead") BehindHead
|
|
31
32
|
|
|
32
33
|
type nextPageResult = {
|
|
33
34
|
kind: pageOutcome,
|
|
@@ -45,6 +46,7 @@ type nextPageResult = {
|
|
|
45
46
|
// alongside it is empty.
|
|
46
47
|
type blockHashResult = {
|
|
47
48
|
message: option<string>,
|
|
49
|
+
behindHeadBlock: option<int>,
|
|
48
50
|
requestStats: array<Source.requestStat>,
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -99,7 +99,8 @@ let make = (
|
|
|
99
99
|
|
|
100
100
|
// The cause travels as a real error so it reaches the logs the way every
|
|
101
101
|
// other source's does. Absent where the message is the whole story.
|
|
102
|
-
let exn =
|
|
102
|
+
let exn =
|
|
103
|
+
result.providerMessage->Option.map(message => JsError.make(message)->JsExn.anyToExnInternal)
|
|
103
104
|
|
|
104
105
|
let failedGettingItems = (decision): exn => Source.GetItemsError(
|
|
105
106
|
FailedGettingItems({
|
|
@@ -134,6 +135,16 @@ let make = (
|
|
|
134
135
|
}),
|
|
135
136
|
),
|
|
136
137
|
)
|
|
138
|
+
| BehindHead =>
|
|
139
|
+
throw(
|
|
140
|
+
Source.SourceBehindHead({
|
|
141
|
+
blockNumber: switch result.blockNumber {
|
|
142
|
+
| Some(blockNumber) => blockNumber
|
|
143
|
+
| None => missing("blockNumber")
|
|
144
|
+
},
|
|
145
|
+
requestStats: result.requestStats,
|
|
146
|
+
}),
|
|
147
|
+
)
|
|
137
148
|
| SuggestedToBlock =>
|
|
138
149
|
throw(
|
|
139
150
|
failedGettingItems(
|
|
@@ -185,9 +196,11 @@ let make = (
|
|
|
185
196
|
let getBlockHashes = async (~blockNumbers, ~logger as _) => {
|
|
186
197
|
let (result, pageBlockStore) = await rpcClient.getBlockHashes(blockNumbers)
|
|
187
198
|
{
|
|
188
|
-
Source.result: switch result.message {
|
|
189
|
-
| None => Ok(pageBlockStore)
|
|
190
|
-
| Some(
|
|
199
|
+
Source.result: switch (result.message, result.behindHeadBlock) {
|
|
200
|
+
| (None, _) => Ok(pageBlockStore)
|
|
201
|
+
| (Some(_), Some(blockNumber)) =>
|
|
202
|
+
Error(Source.SourceBehindHead({blockNumber, requestStats: result.requestStats}))
|
|
203
|
+
| (Some(message), None) => Error(JsError.make(message)->JsExn.anyToExnInternal)
|
|
191
204
|
},
|
|
192
205
|
requestStats: result.requestStats,
|
|
193
206
|
}
|