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.
Files changed (84) hide show
  1. package/evm.schema.json +7 -0
  2. package/fuel.schema.json +7 -0
  3. package/index.d.ts +33 -10
  4. package/package.json +6 -6
  5. package/src/ChainState.res +22 -4
  6. package/src/ChainState.res.mjs +20 -3
  7. package/src/ChainState.resi +3 -0
  8. package/src/Config.res +72 -2
  9. package/src/Config.res.mjs +57 -15
  10. package/src/Core.res +15 -0
  11. package/src/Core.res.mjs +11 -0
  12. package/src/EffectState.res +2 -2
  13. package/src/EffectState.res.mjs +2 -2
  14. package/src/EntityTables.res +32 -0
  15. package/src/EntityTables.res.mjs +44 -0
  16. package/src/Envio.res +7 -7
  17. package/src/Envio.res.mjs +5 -6
  18. package/src/EventProcessing.res +6 -6
  19. package/src/EventProcessing.res.mjs +8 -6
  20. package/src/HandlerLoader.res +20 -8
  21. package/src/HandlerLoader.res.mjs +11 -2
  22. package/src/Hasura.res +37 -3
  23. package/src/Hasura.res.mjs +23 -5
  24. package/src/InMemoryStore.res +48 -8
  25. package/src/InMemoryStore.res.mjs +37 -7
  26. package/src/IndexerState.res +30 -24
  27. package/src/IndexerState.res.mjs +20 -35
  28. package/src/IndexerState.resi +8 -6
  29. package/src/Internal.res +29 -11
  30. package/src/Internal.res.mjs +27 -10
  31. package/src/LoadLayer.res +39 -8
  32. package/src/LoadLayer.res.mjs +36 -9
  33. package/src/LoadLayer.resi +2 -0
  34. package/src/Metrics.res +5 -5
  35. package/src/Metrics.res.mjs +5 -1
  36. package/src/Persistence.res +12 -1
  37. package/src/PgStorage.res +183 -37
  38. package/src/PgStorage.res.mjs +149 -34
  39. package/src/PruneStaleHistory.res +1 -0
  40. package/src/PruneStaleHistory.res.mjs +2 -1
  41. package/src/Sink.res +3 -3
  42. package/src/Sink.res.mjs +2 -2
  43. package/src/TestIndexer.res +128 -17
  44. package/src/TestIndexer.res.mjs +75 -9
  45. package/src/UserContext.res +375 -53
  46. package/src/UserContext.res.mjs +281 -39
  47. package/src/Writing.res +8 -16
  48. package/src/Writing.res.mjs +10 -10
  49. package/src/bindings/ClickHouse.res +40 -4
  50. package/src/bindings/ClickHouse.res.mjs +37 -5
  51. package/src/db/EntityHistory.res +64 -21
  52. package/src/db/EntityHistory.res.mjs +43 -22
  53. package/src/db/InternalTable.res.mjs +31 -31
  54. package/src/db/Table.res +24 -1
  55. package/src/db/Table.res.mjs +26 -4
  56. package/src/sources/SourceManager.res +6 -12
  57. package/src/sources/SourceManager.res.mjs +8 -5
  58. package/src/subgraph/blocks.ts +176 -0
  59. package/src/subgraph/calls.ts +213 -0
  60. package/src/subgraph/conformance.ts +99 -0
  61. package/src/subgraph/division.ts +100 -0
  62. package/src/subgraph/errors.ts +90 -0
  63. package/src/subgraph/graph-ts-types/VERSION +2 -0
  64. package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
  65. package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
  66. package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
  67. package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
  68. package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
  69. package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
  70. package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
  71. package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
  72. package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
  73. package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
  74. package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
  75. package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
  76. package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
  77. package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
  78. package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
  79. package/src/subgraph/graph-ts-types/index.d.ts +102 -0
  80. package/src/subgraph/graph-ts.ts +1695 -0
  81. package/src/subgraph/hosts.ts +148 -0
  82. package/src/subgraph/runtime.ts +827 -0
  83. package/src/subgraph/scope.ts +63 -0
  84. package/svm.schema.json +7 -0
@@ -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 parseEntitiesFromJson(entitiesJson, enumConfigsByName, globalStorage) {
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 userEntities = parseEntitiesFromJson(Stdlib_Option.getOr(publicConfig.entities, []), enumConfigsByName, globalStorage);
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 */
@@ -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.EffectCache.scopeToString,
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.EffectCache.scopeToString,
155
+ scope: scope->Internal.chainScopeToString,
156
156
  callSeconds: 0.,
157
157
  callSecondsTotal: 0.,
158
158
  callCount: 0.,
@@ -68,7 +68,7 @@ function toMetrics(self) {
68
68
  let stats = t.stats;
69
69
  return {
70
70
  effect: stats.effectName,
71
- scope: Internal.EffectCache.scopeToString(stats.scope),
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.EffectCache.scopeToString(param.scope),
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 effects created with
200
- `crossChain: false`; accessing it on a cross-chain effect throws. */
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
- crossChain: switch options.crossChain {
263
- | Some(false) => false
264
- | _ => true
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.crossChain;
34
- let match$2 = options.rateLimit;
33
+ let match$1 = options.rateLimit;
35
34
  let tmp;
36
- tmp = match$2 === false ? undefined : ({
37
- callsPerDuration: match$2.calls,
38
- durationMs: durationToMs(match$2.per)
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: match$1 !== undefined ? match$1 : true,
47
+ crossChain: options.crossChain,
49
48
  output: outputSchema,
50
49
  input: S$RescriptSchema.schema(param => options.input),
51
50
  rateLimit: tmp
@@ -51,7 +51,7 @@ let runEventHandlerOrThrow = async (
51
51
  isPreload: false,
52
52
  chains,
53
53
  config,
54
- isResolved: false,
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.isResolved = true
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
- isResolved: false,
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.isResolved = true
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
- isResolved: false,
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
- isResolved: false,
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
- isResolved: false
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
- contextParams.isResolved = true;
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
- isResolved: false
93
+ sync: contextParams_sync
92
94
  };
93
95
  await item.onBlockRegistration.handler(Ecosystem.makeOnBlockArgs(item.blockNumber, config.ecosystem, UserContext.getHandlerContext(contextParams)));
94
- contextParams.isResolved = true;
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
- isResolved: false
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
- isResolved: false
156
+ sync: UserContext.makeSyncState()
155
157
  })))));
156
158
  } catch (exn$1) {
157
159
 
@@ -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
- // Auto-load all .js files from src/handlers directory
84
- await autoLoadFromSrcHandlers(~handlers=config.handlers)
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
- // Load contract-specific handlers
87
- let _ = await config.contractHandlers
88
- ->Array.map(({name, handler}) => {
89
- registerContractHandlers(~contractName=name, ~handler)
90
- })
91
- ->Promise.all
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
- await autoLoadFromSrcHandlers(config.handlers);
62
- await Promise.all(config.contractHandlers.map(param => registerContractHandlers(param.name, param.handler)));
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 */