envio 3.15.0-subgraph → 3.16.0-subgraph

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +40 -34
  2. package/evm.schema.json +3 -3
  3. package/fuel.schema.json +2 -2
  4. package/index.d.ts +3 -3
  5. package/licenses/README.md +1 -1
  6. package/package.json +8 -8
  7. package/src/Batch.res.mjs +5 -5
  8. package/src/BatchProcessing.res +1 -0
  9. package/src/BatchProcessing.res.mjs +1 -0
  10. package/src/ChainFetching.res +1 -6
  11. package/src/ChainFetching.res.mjs +1 -1
  12. package/src/ChainState.res +48 -7
  13. package/src/ChainState.res.mjs +21 -8
  14. package/src/Clock.res +57 -0
  15. package/src/Clock.res.mjs +72 -0
  16. package/src/Config.res +16 -4
  17. package/src/Config.res.mjs +5 -3
  18. package/src/Core.res +4 -40
  19. package/src/CrossChainState.res +10 -6
  20. package/src/CrossChainState.res.mjs +1 -1
  21. package/src/EffectState.res +10 -2
  22. package/src/EffectState.res.mjs +8 -4
  23. package/src/EffectState.resi +3 -1
  24. package/src/EntityId.res +2 -7
  25. package/src/EntityId.res.mjs +1 -8
  26. package/src/EntityTables.res +4 -1
  27. package/src/EntityTables.res.mjs +1 -1
  28. package/src/Env.res +4 -0
  29. package/src/Env.res.mjs +5 -0
  30. package/src/FetchState.res +157 -69
  31. package/src/FetchState.res.mjs +112 -47
  32. package/src/FinalizeBackfill.res +2 -4
  33. package/src/FinalizeBackfill.res.mjs +3 -4
  34. package/src/InMemoryTable.res +17 -16
  35. package/src/InMemoryTable.res.mjs +14 -15
  36. package/src/IndexerState.res +28 -4
  37. package/src/IndexerState.res.mjs +19 -6
  38. package/src/IndexerState.resi +4 -0
  39. package/src/Internal.res +0 -49
  40. package/src/Internal.res.mjs +1 -80
  41. package/src/LoadLayer.res +17 -10
  42. package/src/LoadLayer.res.mjs +11 -8
  43. package/src/Main.res.mjs +1 -1
  44. package/src/Persistence.res +3 -23
  45. package/src/Persistence.res.mjs +3 -3
  46. package/src/PreloadLookahead.res +42 -24
  47. package/src/PreloadLookahead.res.mjs +51 -30
  48. package/src/Rollback.res +0 -1
  49. package/src/Rollback.res.mjs +1 -1
  50. package/src/SafeCheckpointTracking.res +4 -4
  51. package/src/SafeCheckpointTracking.res.mjs +1 -1
  52. package/src/StagedRows.res +106 -0
  53. package/src/StagedRows.res.mjs +102 -0
  54. package/src/Staging.res +32 -14
  55. package/src/Staging.res.mjs +17 -20
  56. package/src/Storage.res +278 -973
  57. package/src/Storage.res.mjs +218 -720
  58. package/src/Supervisor.res +75 -56
  59. package/src/Supervisor.res.mjs +55 -26
  60. package/src/SyncWrites.res +24 -18
  61. package/src/SyncWrites.res.mjs +11 -11
  62. package/src/TestIndexer.res +22 -27
  63. package/src/TestIndexer.res.mjs +20 -17
  64. package/src/Throttler.res +15 -8
  65. package/src/Throttler.res.mjs +9 -6
  66. package/src/Throttler.resi +1 -1
  67. package/src/UserContext.res +13 -4
  68. package/src/UserContext.res.mjs +5 -5
  69. package/src/Utils.res +0 -6
  70. package/src/Utils.res.mjs +0 -5
  71. package/src/Writing.res +0 -1
  72. package/src/Writing.res.mjs +1 -1
  73. package/src/bindings/ClickHouse.res +0 -322
  74. package/src/bindings/ClickHouse.res.mjs +0 -338
  75. package/src/bindings/StorageClient.res +107 -174
  76. package/src/bindings/StorageClient.res.mjs +19 -8
  77. package/src/bindings/Vitest.res +0 -26
  78. package/src/bindings/Vitest.res.mjs +0 -3
  79. package/src/db/Table.res +24 -150
  80. package/src/db/Table.res.mjs +38 -272
  81. package/src/sources/ChainSources.res +2 -0
  82. package/src/sources/ChainSources.res.mjs +2 -2
  83. package/src/sources/EvmChain.res +3 -0
  84. package/src/sources/EvmChain.res.mjs +4 -2
  85. package/src/sources/EvmHyperSyncSource.res +2 -2
  86. package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
  87. package/src/sources/EvmRpcClient.res +13 -3
  88. package/src/sources/EvmRpcClient.res.mjs +4 -3
  89. package/src/sources/EvmRpcWs.res +4 -3
  90. package/src/sources/EvmRpcWs.res.mjs +2 -2
  91. package/src/sources/HeightFeed.res +31 -10
  92. package/src/sources/HeightFeed.res.mjs +10 -6
  93. package/src/sources/HeightStream.res +32 -17
  94. package/src/sources/HeightStream.res.mjs +10 -10
  95. package/src/sources/HyperSyncSSE.res +4 -6
  96. package/src/sources/HyperSyncSSE.res.mjs +2 -2
  97. package/src/sources/RpcSource.res +10 -1
  98. package/src/sources/RpcSource.res.mjs +4 -3
  99. package/src/sources/Source.res +3 -0
  100. package/src/sources/SourceManager.res +85 -104
  101. package/src/sources/SourceManager.res.mjs +18 -37
  102. package/src/sources/SourceManager.resi +3 -5
  103. package/src/sources/StartBlockResolver.res +1 -0
  104. package/src/sources/StartBlockResolver.res.mjs +4 -3
  105. package/src/sources/SvmHyperSyncSource.res +2 -2
  106. package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
  107. package/src/subgraph/graph-ts.ts +87 -28
  108. package/src/subgraph/runtime.ts +0 -1
  109. package/src/subgraph/scope.ts +0 -1
  110. package/svm.schema.json +3 -3
  111. package/src/PgWriting.res +0 -36
  112. package/src/PgWriting.res.mjs +0 -34
  113. package/src/db/IndexDefinition.res +0 -47
  114. package/src/db/IndexDefinition.res.mjs +0 -60
@@ -0,0 +1,72 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Performance from "./bindings/Performance.res.mjs";
4
+ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
5
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
6
+
7
+ let refuseReal = {
8
+ contents: false
9
+ };
10
+
11
+ function refused(what) {
12
+ return Stdlib_JsError.throwWithMessage(`Clock.real ` + what + ` on virtual time. Use the clock the code was given, so advanceTime can see and move it.`);
13
+ }
14
+
15
+ function real_now() {
16
+ if (refuseReal.contents) {
17
+ return refused("read the time");
18
+ } else {
19
+ return Performance.now();
20
+ }
21
+ }
22
+
23
+ function real_setTimeout(label, callback, millis) {
24
+ if (refuseReal.contents && millis > 0) {
25
+ return refused(`armed "` + label + `"`);
26
+ } else {
27
+ return setTimeout(callback, millis);
28
+ }
29
+ }
30
+
31
+ function real_clearTimeout(timer) {
32
+ clearTimeout(timer);
33
+ }
34
+
35
+ function real_random(prim) {
36
+ return Math.random();
37
+ }
38
+
39
+ let real = {
40
+ now: real_now,
41
+ setTimeout: real_setTimeout,
42
+ clearTimeout: real_clearTimeout,
43
+ random: real_random
44
+ };
45
+
46
+ function delay(clock, label, millis) {
47
+ return new Promise((resolve, _reject) => {
48
+ clock.setTimeout(label, () => resolve(), millis);
49
+ });
50
+ }
51
+
52
+ function jitter(clock, delay) {
53
+ return (delay / 2 | 0) + (clock.random() * (delay / 2 | 0) | 0) | 0;
54
+ }
55
+
56
+ function clearRef(clock, timer) {
57
+ let timer$1 = timer.contents;
58
+ if (timer$1 !== undefined) {
59
+ clock.clearTimeout(Primitive_option.valFromOption(timer$1));
60
+ }
61
+ timer.contents = undefined;
62
+ }
63
+
64
+ export {
65
+ refuseReal,
66
+ refused,
67
+ real,
68
+ delay,
69
+ jitter,
70
+ clearRef,
71
+ }
72
+ /* No side effect */
package/src/Config.res CHANGED
@@ -1079,15 +1079,19 @@ let fromPublic = (publicConfigJson: JSON.t) => {
1079
1079
  startBlock: publicChainConfig["startBlock"],
1080
1080
  endBlock: ?publicChainConfig["endBlock"],
1081
1081
  maxReorgDepth: switch ecosystemName {
1082
- | Ecosystem.Evm => publicChainConfig["maxReorgDepth"]->Option.getOr(200)
1082
+ // One less than the 200 blocks behind the head a source checks for a
1083
+ // lagging node, so the backfill, which stops one block below the window,
1084
+ // ends exactly where those checks begin.
1085
+ | Ecosystem.Evm => publicChainConfig["maxReorgDepth"]->Option.getOr(199)
1083
1086
  // Tower BFT roots a block once 32 votes lock it in (MAX_LOCKOUT_HISTORY
1084
1087
  // is 31, plus the slot itself), which is what `finalized` waits for — so
1085
1088
  // 32 is the protocol's own bound on how far a fork can be replaced. That
1086
1089
  // bound counts *blocks* while the threshold here is measured in slot
1087
1090
  // numbers, and skipped slots make the slot distance the larger of the
1088
1091
  // two, so the default keeps a wide margin over it. Slots are ~0.4s, so
1089
- // even this spans well under two minutes of chain.
1090
- | Ecosystem.Svm => publicChainConfig["maxReorgDepth"]->Option.getOr(200)
1092
+ // even this spans well under two minutes of chain. One less than 200
1093
+ // for the same reason as EVM: the backfill stops one slot below it.
1094
+ | Ecosystem.Svm => publicChainConfig["maxReorgDepth"]->Option.getOr(199)
1091
1095
  | Ecosystem.Fuel => 0
1092
1096
  },
1093
1097
  blockLag: publicChainConfig["blockLag"]->Option.getOr(0),
@@ -1156,8 +1160,16 @@ let fromPublic = (publicConfigJson: JSON.t) => {
1156
1160
  | None => []
1157
1161
  }
1158
1162
 
1159
- if publicConfig["subgraph"]->Option.isSome {
1163
+ switch publicConfig["subgraph"] {
1164
+ | Some(subgraph) =>
1160
1165
  Env.subgraphMode := true
1166
+ Env.subgraphHasTemplates :=
1167
+ subgraph
1168
+ ->JSON.Decode.object
1169
+ ->Option.flatMap(manifest => manifest->Dict.get("templates"))
1170
+ ->Option.flatMap(JSON.Decode.array)
1171
+ ->Option.mapOr(false, templates => templates->Array.length > 0)
1172
+ | None => ()
1161
1173
  }
1162
1174
 
1163
1175
  let config = {
@@ -765,7 +765,7 @@ function fromPublic(publicConfigJson) {
765
765
  break;
766
766
  case "evm" :
767
767
  case "svm" :
768
- tmp = Stdlib_Option.getOr(publicChainConfig.maxReorgDepth, 200);
768
+ tmp = Stdlib_Option.getOr(publicChainConfig.maxReorgDepth, 199);
769
769
  break;
770
770
  }
771
771
  return {
@@ -810,8 +810,10 @@ function fromPublic(publicConfigJson) {
810
810
  name: Utils.$$String.capitalize(param[0]),
811
811
  handler: param[1].handler
812
812
  })) : [];
813
- if (Stdlib_Option.isSome(publicConfig.subgraph)) {
813
+ let subgraph = publicConfig.subgraph;
814
+ if (subgraph !== undefined) {
814
815
  Env.subgraphMode.contents = true;
816
+ Env.subgraphHasTemplates.contents = Stdlib_Option.mapOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(subgraph), manifest => manifest["templates"]), Stdlib_JSON.Decode.array), false, templates => templates.length !== 0);
815
817
  }
816
818
  let config_name = publicConfig.name;
817
819
  let config_description = publicConfig.description;
@@ -981,7 +983,7 @@ function diffPaths(stored, current) {
981
983
  }
982
984
  return;
983
985
  }
984
- } else {
986
+ } else if (s !== null) {
985
987
  switch (typeof s) {
986
988
  case "object" :
987
989
  if (typeof c === "object" && c !== null && !Array.isArray(c)) {
package/src/Core.res CHANGED
@@ -18,6 +18,8 @@ type loggerCtor
18
18
  type mockHyperSyncServerCtor
19
19
  // Test-only: the ledger behind envio-tests' MockSource.
20
20
  type mockSourceCtor
21
+ // Test-only: the virtual clock a scenario's source layer runs on.
22
+ type virtualClockCtor
21
23
  type fromUserApiOptions = {
22
24
  schema?: string,
23
25
  env?: dict<string>,
@@ -48,46 +50,6 @@ type filledGeneratedFile = {
48
50
  undeclared: bool,
49
51
  }
50
52
 
51
- // One column of a Postgres table, flattened for the boundary: napi carries no
52
- // tagged union, so the field type arrives as its name plus whichever of the
53
- // modifiers it takes.
54
- type pgColumnInput = {
55
- // The database column name, renames already resolved.
56
- name: string,
57
- fieldType: string,
58
- isArray: bool,
59
- isNullable: bool,
60
- isPrimaryKey: bool,
61
- defaultValue?: string,
62
- precision?: int,
63
- scale?: int,
64
- enumName?: string,
65
- }
66
-
67
- type pgTableInput = {
68
- // In the order the table declares them.
69
- columns: array<pgColumnInput>,
70
- // The columns a batch's rows carry, in the order they are laid out.
71
- writeColumns: array<string>,
72
- partitionByColumn?: string,
73
- appendOnly: bool,
74
- // An entity's history table, and the column its chain is in when it is
75
- // per-chain.
76
- historyTable?: string,
77
- chainIdColumn?: string,
78
- }
79
-
80
- type pgIndexColumnInput = {
81
- name: string,
82
- direction: string,
83
- }
84
-
85
- type pgIndexInput = {
86
- tableName: string,
87
- columns: array<pgIndexColumnInput>,
88
- method: string,
89
- }
90
-
91
53
  type addon = {
92
54
  getConfigJson: (
93
55
  ~configPath: Null.t<string>,
@@ -142,6 +104,8 @@ type addon = {
142
104
  mockHyperSyncServer: mockHyperSyncServerCtor,
143
105
  @as("MockSource")
144
106
  mockSource: mockSourceCtor,
107
+ @as("VirtualClock")
108
+ virtualClock: virtualClockCtor,
145
109
  encodeAddresses: (~ecosystem: string, ~addresses: array<Address.t>) => array<NodeJs.Buffer.t>,
146
110
  normalizeEvmAddress: (~address: string, ~shouldChecksum: bool) => Null.t<Address.t>,
147
111
  renderAddresses: (
@@ -25,16 +25,20 @@ type t = {
25
25
  }
26
26
 
27
27
  // The whole-indexer fetch buffer pool, independent of chain count. A subgraph
28
- // run keeps far more per fetched event than a handler run does: the payload
29
- // with its transaction and block fields, a register pass with its pending
30
- // contract calls, and (for a chain kept open by a template) responses well past
31
- // the block the handlers are at. Venus on BSC held 100k of them and its heap
32
- // passed 4 GB, so the default there is a tenth of that.
28
+ // with templates keeps far more per fetched event than a handler run does: a
29
+ // register pass with its pending contract calls, and (for a chain kept open by
30
+ // a template) responses well past the block the handlers are at. Venus on BSC
31
+ // held 100k of them and its heap passed 4 GB, so the default there is a tenth
32
+ // of that. Without templates there is neither, and a pool that small leaves
33
+ // one query in flight at a time: fetching stops overlapping processing.
33
34
  let defaultSubgraphTargetBufferSize = 10_000
34
35
  let calculateTargetBufferSize = () =>
35
36
  switch Env.targetBufferSize {
36
37
  | Some(size) => size
37
- | None => Env.subgraphMode.contents ? defaultSubgraphTargetBufferSize : 100_000
38
+ | None =>
39
+ Env.subgraphMode.contents && Env.subgraphHasTemplates.contents
40
+ ? defaultSubgraphTargetBufferSize
41
+ : 100_000
38
42
  }
39
43
 
40
44
  let make = (
@@ -15,7 +15,7 @@ import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
15
15
  function calculateTargetBufferSize() {
16
16
  if (Env.targetBufferSize !== undefined) {
17
17
  return Env.targetBufferSize;
18
- } else if (Env.subgraphMode.contents) {
18
+ } else if (Env.subgraphMode.contents && Env.subgraphHasTemplates.contents) {
19
19
  return 10000;
20
20
  } else {
21
21
  return 100000;
@@ -11,6 +11,8 @@ type effectRateLimitState = {
11
11
  mutable availableCalls: int,
12
12
  mutable windowStartTime: float,
13
13
  mutable nextWindowPromise: option<promise<unit>>,
14
+ // The run's clock: a test on virtual time opens the next window by advancing.
15
+ clock: Clock.t,
14
16
  }
15
17
 
16
18
  // Per-(effect, scope) counters rendered into the envio_effect_* metrics. Live
@@ -80,9 +82,14 @@ type t = {
80
82
  // rollback; stats and the rate-limit window survive because the table does.
81
83
  tables: dict<effectCacheInMemTable>,
82
84
  unregisteredCacheCounts: dict<unregisteredCacheCount>,
85
+ clock: Clock.t,
83
86
  }
84
87
 
85
- let make = (): t => {tables: Dict.make(), unregisteredCacheCounts: Dict.make()}
88
+ let make = (~clock=Clock.real, ()): t => {
89
+ tables: Dict.make(),
90
+ unregisteredCacheCounts: Dict.make(),
91
+ clock,
92
+ }
86
93
 
87
94
  let setUnregisteredCacheCount = (self: t, ~effectName, ~scope, ~count) => {
88
95
  let tableName = Internal.EffectCache.toTableName(~effectName, ~scope)
@@ -214,8 +221,9 @@ let getTable = (self: t, ~effect: Internal.effect, ~scope: Internal.chainScope)
214
221
  callsPerDuration,
215
222
  durationMs,
216
223
  availableCalls: callsPerDuration,
217
- windowStartTime: Date.now(),
224
+ windowStartTime: self.clock.now(),
218
225
  nextWindowPromise: None,
226
+ clock: self.clock,
219
227
  })
220
228
  }
221
229
  let inMemTable: effectCacheInMemTable = {
@@ -1,13 +1,16 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Clock from "./Clock.res.mjs";
3
4
  import * as Utils from "./Utils.res.mjs";
4
5
  import * as Internal from "./Internal.res.mjs";
5
6
  import * as Performance from "./bindings/Performance.res.mjs";
6
7
 
7
- function make() {
8
+ function make(clockOpt, param) {
9
+ let clock = clockOpt !== undefined ? clockOpt : Clock.real;
8
10
  return {
9
11
  tables: {},
10
- unregisteredCacheCounts: {}
12
+ unregisteredCacheCounts: {},
13
+ clock: clock
11
14
  };
12
15
  }
13
16
 
@@ -130,8 +133,9 @@ function getTable(self, effect, scope) {
130
133
  callsPerDuration: callsPerDuration,
131
134
  durationMs: match$1.durationMs,
132
135
  availableCalls: callsPerDuration,
133
- windowStartTime: Date.now(),
134
- nextWindowPromise: undefined
136
+ windowStartTime: self.clock.now(),
137
+ nextWindowPromise: undefined,
138
+ clock: self.clock
135
139
  };
136
140
  } else {
137
141
  rateLimitState = undefined;
@@ -4,6 +4,8 @@ type effectRateLimitState = {
4
4
  mutable availableCalls: int,
5
5
  mutable windowStartTime: float,
6
6
  mutable nextWindowPromise: option<promise<unit>>,
7
+ // The run's clock: a test on virtual time opens the next window by advancing.
8
+ clock: Clock.t,
7
9
  }
8
10
 
9
11
  // Per-(effect, scope) metric counters. Survive rollback so they stay monotonic.
@@ -32,7 +34,7 @@ type effectCacheInMemTable = {
32
34
  // Opaque store of all per-(effect, scope) runtime state.
33
35
  type t
34
36
 
35
- let make: unit => t
37
+ let make: (~clock: Clock.t=?, unit) => t
36
38
  // Get, or lazily create, the in-mem table for an (effect, scope). Reuses the
37
39
  // surviving rate-limit window when the table is recreated after a rollback.
38
40
  let getTable: (t, ~effect: Internal.effect, ~scope: Internal.chainScope) => effectCacheInMemTable
package/src/EntityId.res CHANGED
@@ -1,15 +1,10 @@
1
1
  // Opaque representation of an entity id. The generated per-entity types expose
2
- // the real scalar (string / int / bigint); the generic storage and in-memory
2
+ // the real scalar (string / int / bigint / Uint8Array); the generic storage and in-memory
3
3
  // layers work with any entity's id through this type without knowing which
4
4
  // scalar backs it. The runtime value is always the real id, never a stringified
5
- // form — `toKey` derives the string only where a JS object/dict key is needed.
5
+ // form — a table's `entityIdToKey` derives the string only where a dict or Set key is needed.
6
6
  type t
7
7
 
8
8
  external unsafeOfAny: 'a => t = "%identity"
9
9
  external unsafeToAny: t => 'a = "%identity"
10
10
  external unsafeOfString: string => t = "%identity"
11
-
12
- // Stringified id used as a JS object/dict key. `String` matches how JS coerces
13
- // a value used as an object key, so an id indexes the same whether the raw
14
- // value or its key form is used for lookup, across string/int/bigint.
15
- let toKey: t => string = %raw(`String`)
@@ -1,9 +1,2 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
-
4
- let toKey = String;
5
-
6
- export {
7
- toKey,
8
- }
9
- /* toKey Not a pure module */
2
+ /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
@@ -6,7 +6,10 @@ type t = dict<InMemoryTable.Entity.t>
6
6
  let make = (entities: array<Internal.entityConfig>): t => {
7
7
  let init = Dict.make()
8
8
  entities->Array.forEach(entityConfig => {
9
- init->Dict.set((entityConfig.name :> string), InMemoryTable.Entity.make())
9
+ init->Dict.set(
10
+ (entityConfig.name :> string),
11
+ InMemoryTable.Entity.make(~entityIdToKey=entityConfig.table.entityIdToKey),
12
+ )
10
13
  })
11
14
  init
12
15
  }
@@ -6,7 +6,7 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
6
6
  function make(entities) {
7
7
  let init = {};
8
8
  entities.forEach(entityConfig => {
9
- init[entityConfig.name] = InMemoryTable.Entity.make();
9
+ init[entityConfig.name] = InMemoryTable.Entity.make(entityConfig.table.entityIdToKey);
10
10
  });
11
11
  return init;
12
12
  }
package/src/Env.res CHANGED
@@ -11,6 +11,10 @@ let targetBufferSize = envSafe->EnvSafe.get("ENVIO_INDEXING_MAX_BUFFER_SIZE", S.
11
11
  // the pool of events ready to process is sized for that (CrossChainState).
12
12
  let subgraphMode = ref(false)
13
13
 
14
+ // Set with subgraphMode when the manifest declares templates: without one no
15
+ // event can create a data source, so none holds a register pass.
16
+ let subgraphHasTemplates = ref(false)
17
+
14
18
  // Most events with a register pass one subgraph response may hold before it is
15
19
  // cut after a block and the rest fetched again. 0 turns the cut off; unset, it
16
20
  // follows what the register passes cost (ChainFetching).
package/src/Env.res.mjs CHANGED
@@ -17,6 +17,10 @@ let subgraphMode = {
17
17
  contents: false
18
18
  };
19
19
 
20
+ let subgraphHasTemplates = {
21
+ contents: false
22
+ };
23
+
20
24
  let subgraphRegisterChunk = EnvSafe.get(envSafe, "ENVIO_SUBGRAPH_REGISTER_CHUNK", S$RescriptSchema.option(S$RescriptSchema.int), undefined, undefined, undefined, undefined);
21
25
 
22
26
  let subgraphPreloadLookahead = EnvSafe.get(envSafe, "ENVIO_SUBGRAPH_PRELOAD_LOOKAHEAD", S$RescriptSchema.int, undefined, 256, undefined, undefined);
@@ -225,6 +229,7 @@ let maxChainConcurrency = 100;
225
229
  export {
226
230
  targetBufferSize,
227
231
  subgraphMode,
232
+ subgraphHasTemplates,
228
233
  subgraphRegisterChunk,
229
234
  subgraphPreloadLookahead,
230
235
  maxAddrInPartition,