envio 3.4.0 → 3.5.0-alpha.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envio",
3
- "version": "3.4.0",
3
+ "version": "3.5.0-alpha.0",
4
4
  "type": "module",
5
5
  "description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
6
6
  "bin": "./bin.mjs",
@@ -69,10 +69,10 @@
69
69
  "tsx": "4.21.0"
70
70
  },
71
71
  "optionalDependencies": {
72
- "envio-linux-x64": "3.4.0",
73
- "envio-linux-x64-musl": "3.4.0",
74
- "envio-linux-arm64": "3.4.0",
75
- "envio-darwin-x64": "3.4.0",
76
- "envio-darwin-arm64": "3.4.0"
72
+ "envio-linux-x64": "3.5.0-alpha.0",
73
+ "envio-linux-x64-musl": "3.5.0-alpha.0",
74
+ "envio-linux-arm64": "3.5.0-alpha.0",
75
+ "envio-darwin-x64": "3.5.0-alpha.0",
76
+ "envio-darwin-arm64": "3.5.0-alpha.0"
77
77
  }
78
78
  }
package/src/Bin.res CHANGED
@@ -52,8 +52,8 @@ let applyEnv = (env: dict<JSON.t>) =>
52
52
  let run = async args => {
53
53
  try {
54
54
  switch (await Core.runCli(args))->Null.toOption {
55
- // Rust-only command (codegen / init / stop / docker / metrics / help /
56
- // version / scripts) — nothing for JS to do, exit cleanly.
55
+ // Rust-only command (codegen / init / serve / stop / docker / metrics /
56
+ // help / version / scripts) — nothing for JS to do, exit cleanly.
57
57
  | None => ()
58
58
  | Some(json) =>
59
59
  switch decodeCommand(json->JSON.parseOrThrow) {
package/src/Config.res CHANGED
@@ -995,10 +995,14 @@ let fromPublic = (publicConfigJson: JSON.t) => {
995
995
 
996
996
  let allEntities = userEntities->Array.concat([EnvioAddresses.entityConfig])
997
997
 
998
+ // Keyed by the capitalized entity name to match the handler-context
999
+ // accessor (`context.Pool_snapshots`) the generated types expose, while
1000
+ // entityConfig.name stays the original schema name used for the physical
1001
+ // Postgres/ClickHouse tables.
998
1002
  let userEntitiesByName =
999
1003
  userEntities
1000
1004
  ->Array.map(entityConfig => {
1001
- (entityConfig.name, entityConfig)
1005
+ (entityConfig.name->Utils.String.capitalize, entityConfig)
1002
1006
  })
1003
1007
  ->Dict.fromArray
1004
1008
 
@@ -704,7 +704,7 @@ function fromPublic(publicConfigJson) {
704
704
  let userEntities = parseEntitiesFromJson(Stdlib_Option.getOr(publicConfig.entities, []), enumConfigsByName, globalStorage);
705
705
  let allEntities = userEntities.concat([entityConfig]);
706
706
  let userEntitiesByName = Object.fromEntries(userEntities.map(entityConfig => [
707
- entityConfig.name,
707
+ Utils.$$String.capitalize(entityConfig.name),
708
708
  entityConfig
709
709
  ]));
710
710
  let contractHandlers = publicContractsConfig !== undefined ? Object.entries(publicContractsConfig).map(param => ({
package/src/Core.res CHANGED
@@ -27,6 +27,7 @@ type addon = {
27
27
  encodeIndexedTopic: (~abiType: string, ~value: unknown) => EvmTypes.Hex.t,
28
28
  fromUserApi: (string, fromUserApiOptions) => fromUserApiResult,
29
29
  runCli: (~args: array<string>, ~envioPackageDir: Null.t<string>) => promise<Null.t<string>>,
30
+ requestShutdown: unit => unit,
30
31
  @as("EvmHyperSyncClient")
31
32
  evmHyperSyncClient: evmHyperSyncClientCtor,
32
33
  @as("EvmRpcClient")
@@ -228,7 +229,40 @@ let fromUserApi = (~schema=?, ~env=?, ~files=?, ~withIndexerTypes=false, yaml) =
228
229
  )
229
230
  }
230
231
 
232
+ let runWithShutdownSignals = %raw(`function(run, requestShutdown) {
233
+ var onShutdown = function() { requestShutdown(); };
234
+ process.once("SIGINT", onShutdown);
235
+ process.once("SIGTERM", onShutdown);
236
+ return run().finally(function() {
237
+ process.off("SIGINT", onShutdown);
238
+ process.off("SIGTERM", onShutdown);
239
+ });
240
+ }`)
241
+
242
+ // True only when the parsed subcommand is `serve`. The subcommand is the
243
+ // first positional arg; global value-taking flags (`-d`/`--directory`/
244
+ // `--config`) consume the token after them, and other leading flags are
245
+ // skipped — so an unrelated arg value that happens to equal "serve" (e.g.
246
+ // `envio init --name serve`) does not trigger the serve-only shutdown wiring.
247
+ let isServeCommand: array<string> => bool = %raw(`function(args) {
248
+ var valueFlags = { "-d": true, "--directory": true, "--config": true };
249
+ for (var i = 0; i < args.length; i++) {
250
+ var a = args[i];
251
+ if (a[0] === "-") {
252
+ if (a.indexOf("=") === -1 && valueFlags[a]) { i++; }
253
+ continue;
254
+ }
255
+ return a === "serve";
256
+ }
257
+ return false;
258
+ }`)
259
+
231
260
  let runCli = args => {
232
261
  let addon = getAddon()
233
- addon.runCli(~args, ~envioPackageDir=Null.make(envioPackageDir))
262
+ let invoke = () => addon.runCli(~args, ~envioPackageDir=Null.make(envioPackageDir))
263
+ if isServeCommand(args) {
264
+ runWithShutdownSignals(invoke, () => addon.requestShutdown())
265
+ } else {
266
+ invoke()
267
+ }
234
268
  }
package/src/Core.res.mjs CHANGED
@@ -191,9 +191,37 @@ function fromUserApi(schema, env, files, withIndexerTypesOpt, yaml) {
191
191
  });
192
192
  }
193
193
 
194
+ let runWithShutdownSignals = (function(run, requestShutdown) {
195
+ var onShutdown = function() { requestShutdown(); };
196
+ process.once("SIGINT", onShutdown);
197
+ process.once("SIGTERM", onShutdown);
198
+ return run().finally(function() {
199
+ process.off("SIGINT", onShutdown);
200
+ process.off("SIGTERM", onShutdown);
201
+ });
202
+ });
203
+
204
+ let isServeCommand = (function(args) {
205
+ var valueFlags = { "-d": true, "--directory": true, "--config": true };
206
+ for (var i = 0; i < args.length; i++) {
207
+ var a = args[i];
208
+ if (a[0] === "-") {
209
+ if (a.indexOf("=") === -1 && valueFlags[a]) { i++; }
210
+ continue;
211
+ }
212
+ return a === "serve";
213
+ }
214
+ return false;
215
+ });
216
+
194
217
  function runCli(args) {
195
218
  let addon = getAddon();
196
- return addon.runCli(args, envioPackageDir);
219
+ let invoke = () => addon.runCli(args, envioPackageDir);
220
+ if (isServeCommand(args)) {
221
+ return runWithShutdownSignals(invoke, () => addon.requestShutdown());
222
+ } else {
223
+ return addon.runCli(args, envioPackageDir);
224
+ }
197
225
  }
198
226
 
199
227
  export {
@@ -208,6 +236,8 @@ export {
208
236
  getAddon,
209
237
  getConfigJson,
210
238
  fromUserApi,
239
+ runWithShutdownSignals,
240
+ isServeCommand,
211
241
  runCli,
212
242
  }
213
243
  /* envioPackageDir Not a pure module */
@@ -199,7 +199,11 @@ let handleWriteBatch = (
199
199
  if deleted->Array.length > 0 {
200
200
  entityObj->Dict.set("deleted", deleted->(Utils.magic: array<string> => unknown))
201
201
  }
202
- change->Dict.set(entityName, entityObj->(Utils.magic: dict<unknown> => unknown))
202
+ // Match the capitalized entity accessor the generated change types expose.
203
+ change->Dict.set(
204
+ entityName->Utils.String.capitalize,
205
+ entityObj->(Utils.magic: dict<unknown> => unknown),
206
+ )
203
207
  }
204
208
  })
205
209
  | None => ()
@@ -699,7 +703,9 @@ let createTestIndexer = (): t<'processConfig> => {
699
703
  entityOpsDict
700
704
  ->Dict.toArray
701
705
  ->Array.forEach(((name, ops)) => {
702
- result->Dict.set(name, ops->(Utils.magic: entityOperations => unknown))
706
+ // Expose the capitalized accessor (indexer.Pool_snapshots) the generated
707
+ // types declare, matching the handler-context keys.
708
+ result->Dict.set(name->Utils.String.capitalize, ops->(Utils.magic: entityOperations => unknown))
703
709
  })
704
710
 
705
711
  result->Dict.set(
@@ -146,7 +146,7 @@ function handleWriteBatch(state, updatedEntities, checkpointIds, checkpointChain
146
146
  if (deleted.length !== 0) {
147
147
  entityObj$1["deleted"] = deleted;
148
148
  }
149
- change[entityName] = entityObj$1;
149
+ change[Utils.$$String.capitalize(entityName)] = entityObj$1;
150
150
  });
151
151
  }
152
152
  state.processChanges.push(change);
@@ -470,7 +470,7 @@ function createTestIndexer() {
470
470
  result["chainIds"] = chainIds;
471
471
  result["chains"] = chains;
472
472
  Object.entries(entityOpsDict).forEach(param => {
473
- result[param[0]] = param[1];
473
+ result[Utils.$$String.capitalize(param[0])] = param[1];
474
474
  });
475
475
  result["process"] = processConfig => {
476
476
  if (state.processInProgress) {