envio 3.5.1 → 3.6.1-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/evm.schema.json +7 -0
- package/fuel.schema.json +7 -0
- package/index.d.ts +33 -10
- package/package.json +6 -6
- package/src/ChainState.res +22 -4
- package/src/ChainState.res.mjs +20 -3
- package/src/ChainState.resi +3 -0
- package/src/Config.res +72 -2
- package/src/Config.res.mjs +57 -15
- package/src/Core.res +15 -0
- package/src/Core.res.mjs +11 -0
- package/src/EffectState.res +2 -2
- package/src/EffectState.res.mjs +2 -2
- package/src/EntityTables.res +32 -0
- package/src/EntityTables.res.mjs +44 -0
- package/src/Envio.res +7 -7
- package/src/Envio.res.mjs +5 -6
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +8 -6
- package/src/HandlerLoader.res +20 -8
- package/src/HandlerLoader.res.mjs +11 -2
- package/src/Hasura.res +37 -3
- package/src/Hasura.res.mjs +23 -5
- package/src/InMemoryStore.res +48 -8
- package/src/InMemoryStore.res.mjs +37 -7
- package/src/IndexerState.res +30 -24
- package/src/IndexerState.res.mjs +20 -35
- package/src/IndexerState.resi +8 -6
- package/src/Internal.res +29 -11
- package/src/Internal.res.mjs +27 -10
- package/src/LoadLayer.res +39 -8
- package/src/LoadLayer.res.mjs +36 -9
- package/src/LoadLayer.resi +2 -0
- package/src/Metrics.res +5 -5
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +12 -1
- package/src/PgStorage.res +183 -37
- package/src/PgStorage.res.mjs +149 -34
- package/src/PruneStaleHistory.res +1 -0
- package/src/PruneStaleHistory.res.mjs +2 -1
- package/src/Sink.res +3 -3
- package/src/Sink.res.mjs +2 -2
- package/src/TestIndexer.res +128 -17
- package/src/TestIndexer.res.mjs +75 -9
- package/src/UserContext.res +375 -53
- package/src/UserContext.res.mjs +281 -39
- package/src/Writing.res +8 -16
- package/src/Writing.res.mjs +10 -10
- package/src/bindings/ClickHouse.res +40 -4
- package/src/bindings/ClickHouse.res.mjs +37 -5
- package/src/db/EntityHistory.res +64 -21
- package/src/db/EntityHistory.res.mjs +43 -22
- package/src/db/InternalTable.res.mjs +31 -31
- package/src/db/Table.res +24 -1
- package/src/db/Table.res.mjs +26 -4
- package/src/sources/SourceManager.res +6 -12
- package/src/sources/SourceManager.res.mjs +8 -5
- package/src/subgraph/blocks.ts +176 -0
- package/src/subgraph/calls.ts +213 -0
- package/src/subgraph/conformance.ts +99 -0
- package/src/subgraph/division.ts +100 -0
- package/src/subgraph/errors.ts +90 -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 +1695 -0
- package/src/subgraph/hosts.ts +148 -0
- package/src/subgraph/runtime.ts +827 -0
- package/src/subgraph/scope.ts +63 -0
- package/svm.schema.json +7 -0
package/src/Config.res.mjs
CHANGED
|
@@ -22,6 +22,16 @@ import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
|
22
22
|
import * as EventConfigBuilder from "./EventConfigBuilder.res.mjs";
|
|
23
23
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
24
24
|
|
|
25
|
+
let chainIdFieldName = "chainId";
|
|
26
|
+
|
|
27
|
+
function chainIdColumnName(format) {
|
|
28
|
+
if (format === "original") {
|
|
29
|
+
return chainIdFieldName;
|
|
30
|
+
} else {
|
|
31
|
+
return "chain_id";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
let name = "envio_addresses";
|
|
26
36
|
|
|
27
37
|
function makeId(chainId, address) {
|
|
@@ -42,11 +52,11 @@ let schema = S$RescriptSchema.schema(s => ({
|
|
|
42
52
|
}));
|
|
43
53
|
|
|
44
54
|
let table = Table.mkTable(name, undefined, [
|
|
45
|
-
Table.mkField("id", "String", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined),
|
|
46
|
-
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
47
|
-
Table.mkField("registration_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
48
|
-
Table.mkField("registration_log_index", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
49
|
-
Table.mkField("contract_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
55
|
+
Table.mkField("id", "String", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
56
|
+
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
57
|
+
Table.mkField("registration_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
58
|
+
Table.mkField("registration_log_index", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
59
|
+
Table.mkField("contract_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
50
60
|
], undefined);
|
|
51
61
|
|
|
52
62
|
let entityConfig_storage = {
|
|
@@ -59,7 +69,8 @@ let entityConfig = {
|
|
|
59
69
|
index: -1,
|
|
60
70
|
schema: schema,
|
|
61
71
|
table: table,
|
|
62
|
-
storage: entityConfig_storage
|
|
72
|
+
storage: entityConfig_storage,
|
|
73
|
+
crossChain: true
|
|
63
74
|
};
|
|
64
75
|
|
|
65
76
|
let EnvioAddresses = {
|
|
@@ -217,6 +228,7 @@ let entityStorageSchema = S$RescriptSchema.schema(s => ({
|
|
|
217
228
|
|
|
218
229
|
let entityJsonSchema = S$RescriptSchema.schema(s => ({
|
|
219
230
|
name: s.m(S$RescriptSchema.string),
|
|
231
|
+
crossChain: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
220
232
|
storage: s.m(S$RescriptSchema.option(entityStorageSchema)),
|
|
221
233
|
properties: s.m(S$RescriptSchema.array(propertySchema)),
|
|
222
234
|
derivedFields: s.m(S$RescriptSchema.option(S$RescriptSchema.array(derivedFieldSchema))),
|
|
@@ -324,19 +336,24 @@ function parseEnumsFromJson(enumsJson) {
|
|
|
324
336
|
return Object.entries(enumsJson).map(param => Table.makeEnumConfig(param[0], param[1]));
|
|
325
337
|
}
|
|
326
338
|
|
|
327
|
-
function
|
|
339
|
+
function makeChainIdField(globalStorage) {
|
|
340
|
+
return Table.mkField(chainIdFieldName, "ChainId", ChainId.schema, undefined, undefined, undefined, true, undefined, true, undefined, undefined, chainIdColumnName(globalStorage.postgresColumnNameFormat), chainIdColumnName(globalStorage.clickhouseColumnNameFormat));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function parseEntitiesFromJson(entitiesJson, enumConfigsByName, globalStorage, defaultCrossChain) {
|
|
328
344
|
return entitiesJson.map((entityJson, index) => {
|
|
329
345
|
let entityName = entityJson.name;
|
|
346
|
+
let crossChain = Stdlib_Option.getOr(entityJson.crossChain, defaultCrossChain);
|
|
330
347
|
let fields = entityJson.properties.map(prop => {
|
|
331
348
|
let match = getFieldTypeAndSchema(prop, enumConfigsByName);
|
|
332
|
-
return Table.mkField(prop.name, match[0], match[1], undefined, match[3], match[2], prop.name === "id", match[4], prop.linkedEntity, prop.description, prop.postgresDbName, prop.clickhouseDbName);
|
|
349
|
+
return Table.mkField(prop.name, match[0], match[1], undefined, match[3], match[2], prop.name === "id", match[4], undefined, prop.linkedEntity, prop.description, prop.postgresDbName, prop.clickhouseDbName);
|
|
333
350
|
});
|
|
334
351
|
let derivedFields = Stdlib_Option.getOr(entityJson.derivedFields, []).map(df => Table.mkDerivedFromField(df.fieldName, df.derivedFromEntity, df.derivedFromField, df.description));
|
|
335
352
|
let compositeIndexes = Stdlib_Option.getOr(entityJson.compositeIndices, []).map(ci => ci.map(f => ({
|
|
336
353
|
fieldName: f.fieldName,
|
|
337
354
|
direction: f.direction === "Asc" ? "Asc" : "Desc"
|
|
338
355
|
})));
|
|
339
|
-
let table = Table.mkTable(entityName, compositeIndexes, fields.concat(derivedFields), entityJson.description);
|
|
356
|
+
let table = Table.mkTable(entityName, compositeIndexes, fields.concat(crossChain ? [] : [makeChainIdField(globalStorage)], derivedFields), entityJson.description);
|
|
340
357
|
let getApiFieldName = prop => {
|
|
341
358
|
let match = prop.linkedEntity;
|
|
342
359
|
if (match !== undefined) {
|
|
@@ -382,14 +399,22 @@ function parseEntitiesFromJson(entitiesJson, enumConfigsByName, globalStorage) {
|
|
|
382
399
|
index: index,
|
|
383
400
|
schema: schema,
|
|
384
401
|
table: table,
|
|
385
|
-
storage: storage
|
|
402
|
+
storage: storage,
|
|
403
|
+
crossChain: crossChain
|
|
386
404
|
};
|
|
387
405
|
});
|
|
388
406
|
}
|
|
389
407
|
|
|
408
|
+
let columnNameFormatSchema = S$RescriptSchema.$$enum([
|
|
409
|
+
"original",
|
|
410
|
+
"snake_case"
|
|
411
|
+
]);
|
|
412
|
+
|
|
390
413
|
let publicConfigStorageSchema = S$RescriptSchema.schema(s => ({
|
|
391
414
|
postgres: s.m(S$RescriptSchema.bool),
|
|
392
|
-
clickhouse: s.m(S$RescriptSchema.option(S$RescriptSchema.bool))
|
|
415
|
+
clickhouse: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
416
|
+
postgresColumnNameFormat: s.m(S$RescriptSchema.option(columnNameFormatSchema)),
|
|
417
|
+
clickhouseColumnNameFormat: s.m(S$RescriptSchema.option(columnNameFormatSchema))
|
|
393
418
|
}));
|
|
394
419
|
|
|
395
420
|
let publicConfigSchema = S$RescriptSchema.schema(s => ({
|
|
@@ -402,12 +427,14 @@ let publicConfigSchema = S$RescriptSchema.schema(s => ({
|
|
|
402
427
|
saveFullHistory: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
403
428
|
rawEvents: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
404
429
|
chainIdMode: s.m(S$RescriptSchema.option(ChainId.modeSchema)),
|
|
430
|
+
defaultCrossChain: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
405
431
|
storage: s.m(publicConfigStorageSchema),
|
|
406
432
|
evm: s.m(S$RescriptSchema.option(publicConfigEvmSchema)),
|
|
407
433
|
fuel: s.m(S$RescriptSchema.option(publicConfigEcosystemSchema)),
|
|
408
434
|
svm: s.m(S$RescriptSchema.option(publicConfigEcosystemSchema)),
|
|
409
435
|
enums: s.m(S$RescriptSchema.option(S$RescriptSchema.dict(S$RescriptSchema.array(S$RescriptSchema.string)))),
|
|
410
|
-
entities: s.m(S$RescriptSchema.option(S$RescriptSchema.array(entityJsonSchema)))
|
|
436
|
+
entities: s.m(S$RescriptSchema.option(S$RescriptSchema.array(entityJsonSchema))),
|
|
437
|
+
subgraph: s.m(S$RescriptSchema.option(S$RescriptSchema.json(false)))
|
|
411
438
|
}));
|
|
412
439
|
|
|
413
440
|
function fromPublic(publicConfigJson) {
|
|
@@ -689,11 +716,16 @@ function fromPublic(publicConfigJson) {
|
|
|
689
716
|
]));
|
|
690
717
|
let globalStorage_postgres = publicConfig.storage.postgres;
|
|
691
718
|
let globalStorage_clickhouse = Stdlib_Option.getOr(publicConfig.storage.clickhouse, false);
|
|
719
|
+
let globalStorage_postgresColumnNameFormat = Stdlib_Option.getOr(publicConfig.storage.postgresColumnNameFormat, "original");
|
|
720
|
+
let globalStorage_clickhouseColumnNameFormat = Stdlib_Option.getOr(publicConfig.storage.clickhouseColumnNameFormat, "original");
|
|
692
721
|
let globalStorage = {
|
|
693
722
|
postgres: globalStorage_postgres,
|
|
694
|
-
clickhouse: globalStorage_clickhouse
|
|
723
|
+
clickhouse: globalStorage_clickhouse,
|
|
724
|
+
postgresColumnNameFormat: globalStorage_postgresColumnNameFormat,
|
|
725
|
+
clickhouseColumnNameFormat: globalStorage_clickhouseColumnNameFormat
|
|
695
726
|
};
|
|
696
|
-
let
|
|
727
|
+
let defaultCrossChain = Stdlib_Option.getOr(publicConfig.defaultCrossChain, true);
|
|
728
|
+
let userEntities = parseEntitiesFromJson(Stdlib_Option.getOr(publicConfig.entities, []), enumConfigsByName, globalStorage, defaultCrossChain);
|
|
697
729
|
let allEntities = userEntities.concat([entityConfig]);
|
|
698
730
|
let userEntitiesByName = Object.fromEntries(userEntities.map(entityConfig => [
|
|
699
731
|
Utils.$$String.capitalize(entityConfig.name),
|
|
@@ -710,6 +742,7 @@ function fromPublic(publicConfigJson) {
|
|
|
710
742
|
contractHandlers: contractHandlers,
|
|
711
743
|
shouldRollbackOnReorg: Stdlib_Option.getOr(publicConfig.rollbackOnReorg, true),
|
|
712
744
|
shouldSaveFullHistory: Stdlib_Option.getOr(publicConfig.saveFullHistory, false),
|
|
745
|
+
defaultCrossChain: defaultCrossChain,
|
|
713
746
|
storage: globalStorage,
|
|
714
747
|
chainIdMode: Stdlib_Option.getOr(publicConfig.chainIdMode, "int32"),
|
|
715
748
|
chainMap: chainMap,
|
|
@@ -725,7 +758,8 @@ function fromPublic(publicConfigJson) {
|
|
|
725
758
|
userEntitiesByName: userEntitiesByName,
|
|
726
759
|
userEntities: userEntities,
|
|
727
760
|
allEntities: allEntities,
|
|
728
|
-
allEnums: allEnums
|
|
761
|
+
allEnums: allEnums,
|
|
762
|
+
subgraph: publicConfig.subgraph
|
|
729
763
|
};
|
|
730
764
|
}
|
|
731
765
|
|
|
@@ -870,6 +904,10 @@ function stripSensitiveData(json) {
|
|
|
870
904
|
stripChains(cloned["evm"]);
|
|
871
905
|
stripChains(cloned["fuel"]);
|
|
872
906
|
stripChains(cloned["svm"]);
|
|
907
|
+
let match = cloned["subgraph"];
|
|
908
|
+
if (typeof match === "object" && match !== null && !Array.isArray(match)) {
|
|
909
|
+
Utils.Dict.deleteInPlace(match, "rpcUrls");
|
|
910
|
+
}
|
|
873
911
|
}
|
|
874
912
|
return cloned;
|
|
875
913
|
}
|
|
@@ -1049,6 +1087,8 @@ function getPgUserEntities(config) {
|
|
|
1049
1087
|
}
|
|
1050
1088
|
|
|
1051
1089
|
export {
|
|
1090
|
+
chainIdFieldName,
|
|
1091
|
+
chainIdColumnName,
|
|
1052
1092
|
EnvioAddresses,
|
|
1053
1093
|
rpcSourceForSchema,
|
|
1054
1094
|
rpcConfigSchema,
|
|
@@ -1069,7 +1109,9 @@ export {
|
|
|
1069
1109
|
entityJsonSchema,
|
|
1070
1110
|
getFieldTypeAndSchema,
|
|
1071
1111
|
parseEnumsFromJson,
|
|
1112
|
+
makeChainIdField,
|
|
1072
1113
|
parseEntitiesFromJson,
|
|
1114
|
+
columnNameFormatSchema,
|
|
1073
1115
|
publicConfigStorageSchema,
|
|
1074
1116
|
publicConfigSchema,
|
|
1075
1117
|
fromPublic,
|
package/src/Core.res
CHANGED
|
@@ -24,8 +24,16 @@ type fromUserApiResult = {
|
|
|
24
24
|
indexerCode: Null.t<string>,
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
type fromSubgraphOptions = {
|
|
28
|
+
name?: string,
|
|
29
|
+
env?: dict<string>,
|
|
30
|
+
files?: dict<string>,
|
|
31
|
+
root?: string,
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
type addon = {
|
|
28
35
|
getConfigJson: (~configPath: Null.t<string>, ~directory: Null.t<string>) => string,
|
|
36
|
+
fromSubgraph: (string, string, fromSubgraphOptions) => fromUserApiResult,
|
|
29
37
|
encodeIndexedTopic: (~abiType: string, ~value: unknown) => EvmTypes.Hex.t,
|
|
30
38
|
fromUserApi: (string, fromUserApiOptions) => fromUserApiResult,
|
|
31
39
|
runCli: (~args: array<string>, ~envioPackageDir: Null.t<string>) => promise<Null.t<string>>,
|
|
@@ -232,6 +240,13 @@ let fromUserApi = (~schema=?, ~env=?, ~files=?, ~withIndexerTypes=false, yaml) =
|
|
|
232
240
|
)
|
|
233
241
|
}
|
|
234
242
|
|
|
243
|
+
/// Parses a subgraph project without touching the filesystem: subgraph.yaml and
|
|
244
|
+
/// its schema inline, ABI bodies through `files`.
|
|
245
|
+
let fromSubgraph = (~name=?, ~env=?, ~files=?, ~root=?, ~manifest, ~schema) => {
|
|
246
|
+
let addon = getAddon()
|
|
247
|
+
addon.fromSubgraph(manifest, schema, {?name, ?env, ?files, ?root})
|
|
248
|
+
}
|
|
249
|
+
|
|
235
250
|
let runCli = args => {
|
|
236
251
|
let addon = getAddon()
|
|
237
252
|
addon.runCli(~args, ~envioPackageDir=Null.make(envioPackageDir))
|
package/src/Core.res.mjs
CHANGED
|
@@ -191,6 +191,16 @@ function fromUserApi(schema, env, files, withIndexerTypesOpt, yaml) {
|
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
function fromSubgraph(name, env, files, root, manifest, schema) {
|
|
195
|
+
let addon = getAddon();
|
|
196
|
+
return addon.fromSubgraph(manifest, schema, {
|
|
197
|
+
name: name,
|
|
198
|
+
env: env,
|
|
199
|
+
files: files,
|
|
200
|
+
root: root
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
194
204
|
function runCli(args) {
|
|
195
205
|
let addon = getAddon();
|
|
196
206
|
return addon.runCli(args, envioPackageDir);
|
|
@@ -208,6 +218,7 @@ export {
|
|
|
208
218
|
getAddon,
|
|
209
219
|
getConfigJson,
|
|
210
220
|
fromUserApi,
|
|
221
|
+
fromSubgraph,
|
|
211
222
|
runCli,
|
|
212
223
|
}
|
|
213
224
|
/* envioPackageDir Not a pure module */
|
package/src/EffectState.res
CHANGED
|
@@ -131,7 +131,7 @@ let commitCacheCount = (inMemTable: effectCacheInMemTable, ~count) => {
|
|
|
131
131
|
|
|
132
132
|
let statsToMetrics = (stats: effectStats): Metrics.effectMetrics => {
|
|
133
133
|
Metrics.effect: stats.effectName,
|
|
134
|
-
scope: stats.scope->Internal.
|
|
134
|
+
scope: stats.scope->Internal.chainScopeToString,
|
|
135
135
|
callSeconds: stats.callSeconds,
|
|
136
136
|
callSecondsTotal: stats.callSecondsTotal,
|
|
137
137
|
callCount: stats.callCount,
|
|
@@ -152,7 +152,7 @@ let toMetrics = (self: t): array<Metrics.effectMetrics> => {
|
|
|
152
152
|
metrics
|
|
153
153
|
->Array.push({
|
|
154
154
|
Metrics.effect: effectName,
|
|
155
|
-
scope: scope->Internal.
|
|
155
|
+
scope: scope->Internal.chainScopeToString,
|
|
156
156
|
callSeconds: 0.,
|
|
157
157
|
callSecondsTotal: 0.,
|
|
158
158
|
callCount: 0.,
|
package/src/EffectState.res.mjs
CHANGED
|
@@ -68,7 +68,7 @@ function toMetrics(self) {
|
|
|
68
68
|
let stats = t.stats;
|
|
69
69
|
return {
|
|
70
70
|
effect: stats.effectName,
|
|
71
|
-
scope: Internal.
|
|
71
|
+
scope: Internal.chainScopeToString(stats.scope),
|
|
72
72
|
callSeconds: stats.callSeconds,
|
|
73
73
|
callSecondsTotal: stats.callSecondsTotal,
|
|
74
74
|
callCount: stats.callCount,
|
|
@@ -82,7 +82,7 @@ function toMetrics(self) {
|
|
|
82
82
|
Utils.Dict.forEach(self.unregisteredCacheCounts, param => {
|
|
83
83
|
metrics.push({
|
|
84
84
|
effect: param.effectName,
|
|
85
|
-
scope: Internal.
|
|
85
|
+
scope: Internal.chainScopeToString(param.scope),
|
|
86
86
|
callSeconds: 0,
|
|
87
87
|
callSecondsTotal: 0,
|
|
88
88
|
callCount: 0,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// One in-memory table per entity, for a single chain scope. The indexer holds
|
|
2
|
+
// the cross-chain partition; each ChainState holds the per-chain one.
|
|
3
|
+
|
|
4
|
+
type t = dict<InMemoryTable.Entity.t>
|
|
5
|
+
|
|
6
|
+
exception UndefinedEntity({entityName: string})
|
|
7
|
+
|
|
8
|
+
let make = (entities: array<Internal.entityConfig>): t => {
|
|
9
|
+
let init = Dict.make()
|
|
10
|
+
entities->Array.forEach(entityConfig => {
|
|
11
|
+
init->Dict.set((entityConfig.name :> string), InMemoryTable.Entity.make())
|
|
12
|
+
})
|
|
13
|
+
init
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let get = (self: t, ~entityName: string) => {
|
|
17
|
+
switch self->Utils.Dict.dangerouslyGetNonOption(entityName) {
|
|
18
|
+
| Some(table) => table
|
|
19
|
+
| None =>
|
|
20
|
+
UndefinedEntity({entityName: entityName})->ErrorHandling.mkLogAndRaise(
|
|
21
|
+
~msg="Unexpected, entity InMemoryTable is undefined",
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Entities whose rows are shared by every chain, so their tables live on the
|
|
27
|
+
// indexer rather than on a ChainState.
|
|
28
|
+
let crossChain = (entities: array<Internal.entityConfig>) =>
|
|
29
|
+
entities->Array.filter((entityConfig: Internal.entityConfig) => entityConfig.crossChain)
|
|
30
|
+
|
|
31
|
+
let perChain = (entities: array<Internal.entityConfig>) =>
|
|
32
|
+
entities->Array.filter((entityConfig: Internal.entityConfig) => !entityConfig.crossChain)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
4
|
+
import * as InMemoryTable from "./InMemoryTable.res.mjs";
|
|
5
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
6
|
+
|
|
7
|
+
let UndefinedEntity = /* @__PURE__ */Primitive_exceptions.create("EntityTables.UndefinedEntity");
|
|
8
|
+
|
|
9
|
+
function make(entities) {
|
|
10
|
+
let init = {};
|
|
11
|
+
entities.forEach(entityConfig => {
|
|
12
|
+
init[entityConfig.name] = InMemoryTable.Entity.make();
|
|
13
|
+
});
|
|
14
|
+
return init;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function get(self, entityName) {
|
|
18
|
+
let table = self[entityName];
|
|
19
|
+
if (table !== undefined) {
|
|
20
|
+
return table;
|
|
21
|
+
} else {
|
|
22
|
+
return ErrorHandling.mkLogAndRaise(undefined, "Unexpected, entity InMemoryTable is undefined", {
|
|
23
|
+
RE_EXN_ID: UndefinedEntity,
|
|
24
|
+
entityName: entityName
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function crossChain(entities) {
|
|
30
|
+
return entities.filter(entityConfig => entityConfig.crossChain);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function perChain(entities) {
|
|
34
|
+
return entities.filter(entityConfig => !entityConfig.crossChain);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
UndefinedEntity,
|
|
39
|
+
make,
|
|
40
|
+
get,
|
|
41
|
+
crossChain,
|
|
42
|
+
perChain,
|
|
43
|
+
}
|
|
44
|
+
/* ErrorHandling Not a pure module */
|
package/src/Envio.res
CHANGED
|
@@ -186,7 +186,8 @@ and effectOptions<'input, 'output> = {
|
|
|
186
186
|
rateLimit: rateLimit,
|
|
187
187
|
/** Whether the effect should be cached. */
|
|
188
188
|
cache?: bool,
|
|
189
|
-
/** Whether the effect's cache is shared across all chains. Defaults to `true
|
|
189
|
+
/** Whether the effect's cache is shared across all chains. Defaults to `true`,
|
|
190
|
+
or to `false` when config.yaml sets `disable_default_cross_chain: true`.
|
|
190
191
|
Set to `false` to isolate the cache (and rate limiting) per chain and enable
|
|
191
192
|
`context.chain.id` inside the handler. */
|
|
192
193
|
crossChain?: bool,
|
|
@@ -196,8 +197,8 @@ and effectContext = {
|
|
|
196
197
|
log: logger,
|
|
197
198
|
effect: 'input 'output. (effect<'input, 'output>, 'input) => promise<'output>,
|
|
198
199
|
mutable cache: bool,
|
|
199
|
-
/** The chain the effect was called on. Only available on
|
|
200
|
-
|
|
200
|
+
/** The chain the effect was called on. Only available on chain-scoped
|
|
201
|
+
effects; accessing it on a cross-chain effect throws. */
|
|
201
202
|
chain: effectChain,
|
|
202
203
|
}
|
|
203
204
|
and effectArgs<'input> = {
|
|
@@ -259,10 +260,9 @@ let createEffect = (
|
|
|
259
260
|
| Some(true) => true
|
|
260
261
|
| _ => false
|
|
261
262
|
},
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
},
|
|
263
|
+
// Left unresolved: the config's `defaultCrossChain` fills it in when the
|
|
264
|
+
// effect didn't state one, and the config isn't available here.
|
|
265
|
+
crossChain: options.crossChain,
|
|
266
266
|
rateLimit: switch options.rateLimit {
|
|
267
267
|
| Disable => None
|
|
268
268
|
| Enable({calls, per}) =>
|
package/src/Envio.res.mjs
CHANGED
|
@@ -30,12 +30,11 @@ function createEffect(options, handler) {
|
|
|
30
30
|
output: s.m(outputSchema)
|
|
31
31
|
}));
|
|
32
32
|
let match = options.cache;
|
|
33
|
-
let match$1 = options.
|
|
34
|
-
let match$2 = options.rateLimit;
|
|
33
|
+
let match$1 = options.rateLimit;
|
|
35
34
|
let tmp;
|
|
36
|
-
tmp = match$
|
|
37
|
-
callsPerDuration: match$
|
|
38
|
-
durationMs: durationToMs(match$
|
|
35
|
+
tmp = match$1 === false ? undefined : ({
|
|
36
|
+
callsPerDuration: match$1.calls,
|
|
37
|
+
durationMs: durationToMs(match$1.per)
|
|
39
38
|
});
|
|
40
39
|
return {
|
|
41
40
|
name: options.name,
|
|
@@ -45,7 +44,7 @@ function createEffect(options, handler) {
|
|
|
45
44
|
outputSchema: outputSchema
|
|
46
45
|
},
|
|
47
46
|
defaultShouldCache: match !== undefined ? match : false,
|
|
48
|
-
crossChain:
|
|
47
|
+
crossChain: options.crossChain,
|
|
49
48
|
output: outputSchema,
|
|
50
49
|
input: S$RescriptSchema.schema(param => options.input),
|
|
51
50
|
rateLimit: tmp
|
package/src/EventProcessing.res
CHANGED
|
@@ -51,7 +51,7 @@ let runEventHandlerOrThrow = async (
|
|
|
51
51
|
isPreload: false,
|
|
52
52
|
chains,
|
|
53
53
|
config,
|
|
54
|
-
|
|
54
|
+
sync: UserContext.makeSyncState(),
|
|
55
55
|
}
|
|
56
56
|
await handler(
|
|
57
57
|
(
|
|
@@ -61,7 +61,7 @@ let runEventHandlerOrThrow = async (
|
|
|
61
61
|
}: Internal.handlerArgs
|
|
62
62
|
),
|
|
63
63
|
)
|
|
64
|
-
contextParams.
|
|
64
|
+
contextParams.sync.status = Resolved
|
|
65
65
|
} catch {
|
|
66
66
|
| exn =>
|
|
67
67
|
throw(
|
|
@@ -102,7 +102,7 @@ let runHandlerOrThrow = async (
|
|
|
102
102
|
isPreload: false,
|
|
103
103
|
chains,
|
|
104
104
|
config,
|
|
105
|
-
|
|
105
|
+
sync: UserContext.makeSyncState(),
|
|
106
106
|
}
|
|
107
107
|
await handler(
|
|
108
108
|
Ecosystem.makeOnBlockArgs(
|
|
@@ -111,7 +111,7 @@ let runHandlerOrThrow = async (
|
|
|
111
111
|
~context=UserContext.getHandlerContext(contextParams),
|
|
112
112
|
),
|
|
113
113
|
)
|
|
114
|
-
contextParams.
|
|
114
|
+
contextParams.sync.status = Resolved
|
|
115
115
|
} catch {
|
|
116
116
|
| exn =>
|
|
117
117
|
throw(
|
|
@@ -186,7 +186,7 @@ let preloadBatchOrThrow = async (
|
|
|
186
186
|
checkpointId,
|
|
187
187
|
isPreload: true,
|
|
188
188
|
chains,
|
|
189
|
-
|
|
189
|
+
sync: UserContext.makeSyncState(),
|
|
190
190
|
config,
|
|
191
191
|
}),
|
|
192
192
|
})
|
|
@@ -221,7 +221,7 @@ let preloadBatchOrThrow = async (
|
|
|
221
221
|
checkpointId,
|
|
222
222
|
isPreload: true,
|
|
223
223
|
chains,
|
|
224
|
-
|
|
224
|
+
sync: UserContext.makeSyncState(),
|
|
225
225
|
config,
|
|
226
226
|
}),
|
|
227
227
|
)
|
|
@@ -38,6 +38,7 @@ let ProcessingError = /* @__PURE__ */Primitive_exceptions.create("EventProcessin
|
|
|
38
38
|
async function runEventHandlerOrThrow(item, checkpointId, handler, indexerState, loadManager, persistence, chains, config) {
|
|
39
39
|
let timeBeforeHandler = Performance.now();
|
|
40
40
|
try {
|
|
41
|
+
let contextParams_sync = UserContext.makeSyncState();
|
|
41
42
|
let contextParams = {
|
|
42
43
|
item: item,
|
|
43
44
|
checkpointId: checkpointId,
|
|
@@ -47,13 +48,13 @@ async function runEventHandlerOrThrow(item, checkpointId, handler, indexerState,
|
|
|
47
48
|
isPreload: false,
|
|
48
49
|
chains: chains,
|
|
49
50
|
config: config,
|
|
50
|
-
|
|
51
|
+
sync: contextParams_sync
|
|
51
52
|
};
|
|
52
53
|
await handler({
|
|
53
54
|
event: Ecosystem.getItemEvent(item, config.ecosystem),
|
|
54
55
|
context: UserContext.getHandlerContext(contextParams)
|
|
55
56
|
});
|
|
56
|
-
|
|
57
|
+
contextParams_sync.status = "Resolved";
|
|
57
58
|
} catch (raw_exn) {
|
|
58
59
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
59
60
|
throw {
|
|
@@ -79,6 +80,7 @@ async function runHandlerOrThrow(item, checkpointId, indexerState, loadManager,
|
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
try {
|
|
83
|
+
let contextParams_sync = UserContext.makeSyncState();
|
|
82
84
|
let contextParams = {
|
|
83
85
|
item: item,
|
|
84
86
|
checkpointId: checkpointId,
|
|
@@ -88,10 +90,10 @@ async function runHandlerOrThrow(item, checkpointId, indexerState, loadManager,
|
|
|
88
90
|
isPreload: false,
|
|
89
91
|
chains: chains,
|
|
90
92
|
config: config,
|
|
91
|
-
|
|
93
|
+
sync: contextParams_sync
|
|
92
94
|
};
|
|
93
95
|
await item.onBlockRegistration.handler(Ecosystem.makeOnBlockArgs(item.blockNumber, config.ecosystem, UserContext.getHandlerContext(contextParams)));
|
|
94
|
-
|
|
96
|
+
contextParams_sync.status = "Resolved";
|
|
95
97
|
return;
|
|
96
98
|
} catch (raw_exn) {
|
|
97
99
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
@@ -133,7 +135,7 @@ async function preloadBatchOrThrow(batch, loadManager, persistence, config, inde
|
|
|
133
135
|
isPreload: true,
|
|
134
136
|
chains: chains,
|
|
135
137
|
config: config,
|
|
136
|
-
|
|
138
|
+
sync: UserContext.makeSyncState()
|
|
137
139
|
})
|
|
138
140
|
}).then(() => IndexerState.endPreloadHandler(indexerState, timerRef, contractName, eventName))));
|
|
139
141
|
} catch (exn) {
|
|
@@ -151,7 +153,7 @@ async function preloadBatchOrThrow(batch, loadManager, persistence, config, inde
|
|
|
151
153
|
isPreload: true,
|
|
152
154
|
chains: chains,
|
|
153
155
|
config: config,
|
|
154
|
-
|
|
156
|
+
sync: UserContext.makeSyncState()
|
|
155
157
|
})))));
|
|
156
158
|
} catch (exn$1) {
|
|
157
159
|
|
package/src/HandlerLoader.res
CHANGED
|
@@ -77,18 +77,30 @@ let autoLoadFromSrcHandlers = async (~handlers: string) => {
|
|
|
77
77
|
// `HandlerRegister.finishRegistration`. This loads the user handler files
|
|
78
78
|
// (populating the global `HandlerRegister` registry as a side effect) and
|
|
79
79
|
// returns the resulting per-chain registrations.
|
|
80
|
+
// The subgraph runtime lives in this package but is never exported: it's
|
|
81
|
+
// reached only from here, when the resolved config carries a translated
|
|
82
|
+
// manifest.
|
|
83
|
+
let registerSubgraph: (JSON.t, ~isDev: bool) => promise<unit> = %raw(`(subgraph, isDev) =>
|
|
84
|
+
import("./subgraph/runtime.ts").then((m) => m.registerSubgraph({ ...subgraph, isDev }))`)
|
|
85
|
+
|
|
80
86
|
let registerAllHandlers = async (~config: Config.t): HandlerRegister.registrationsByChainId => {
|
|
81
87
|
HandlerRegister.startRegistration(~config)
|
|
82
88
|
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
switch config.subgraph {
|
|
90
|
+
// A subgraph project's `src/` holds AssemblyScript mappings, not envio
|
|
91
|
+
// handlers, so the usual auto-load would import them without a scope.
|
|
92
|
+
| Some(subgraph) => await registerSubgraph(subgraph, ~isDev=config.isDev)
|
|
93
|
+
| None =>
|
|
94
|
+
// Auto-load all .js files from src/handlers directory
|
|
95
|
+
await autoLoadFromSrcHandlers(~handlers=config.handlers)
|
|
85
96
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
// Load contract-specific handlers
|
|
98
|
+
let _ = await config.contractHandlers
|
|
99
|
+
->Array.map(({name, handler}) => {
|
|
100
|
+
registerContractHandlers(~contractName=name, ~handler)
|
|
101
|
+
})
|
|
102
|
+
->Promise.all
|
|
103
|
+
}
|
|
92
104
|
|
|
93
105
|
HandlerRegister.finishRegistration(~config)
|
|
94
106
|
}
|
|
@@ -56,10 +56,18 @@ async function autoLoadFromSrcHandlers(handlers) {
|
|
|
56
56
|
})));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
let registerSubgraph = ((subgraph, isDev) =>
|
|
60
|
+
import("./subgraph/runtime.ts").then((m) => m.registerSubgraph({ ...subgraph, isDev })));
|
|
61
|
+
|
|
59
62
|
async function registerAllHandlers(config) {
|
|
60
63
|
HandlerRegister.startRegistration(config);
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
let subgraph = config.subgraph;
|
|
65
|
+
if (subgraph !== undefined) {
|
|
66
|
+
await registerSubgraph(subgraph, config.isDev);
|
|
67
|
+
} else {
|
|
68
|
+
await autoLoadFromSrcHandlers(config.handlers);
|
|
69
|
+
await Promise.all(config.contractHandlers.map(param => registerContractHandlers(param.name, param.handler)));
|
|
70
|
+
}
|
|
63
71
|
return HandlerRegister.finishRegistration(config);
|
|
64
72
|
}
|
|
65
73
|
|
|
@@ -67,6 +75,7 @@ export {
|
|
|
67
75
|
toImportUrl,
|
|
68
76
|
registerContractHandlers,
|
|
69
77
|
autoLoadFromSrcHandlers,
|
|
78
|
+
registerSubgraph,
|
|
70
79
|
registerAllHandlers,
|
|
71
80
|
}
|
|
72
81
|
/* Not a pure module */
|