envio 3.0.0-alpha.21 → 3.0.0-alpha.22

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 (219) hide show
  1. package/bin.mjs +2 -48
  2. package/evm.schema.json +67 -0
  3. package/fuel.schema.json +67 -0
  4. package/index.d.ts +822 -38
  5. package/index.js +5 -3
  6. package/package.json +10 -8
  7. package/rescript.json +5 -9
  8. package/src/Address.res +4 -5
  9. package/src/Address.res.mjs +9 -12
  10. package/src/Api.res +15 -0
  11. package/src/Api.res.mjs +20 -0
  12. package/src/Batch.res +32 -34
  13. package/src/Batch.res.mjs +172 -187
  14. package/src/Bin.res +89 -0
  15. package/src/Bin.res.mjs +97 -0
  16. package/src/ChainFetcher.res +33 -57
  17. package/src/ChainFetcher.res.mjs +197 -227
  18. package/src/ChainManager.res +6 -14
  19. package/src/ChainManager.res.mjs +74 -85
  20. package/src/ChainMap.res +14 -16
  21. package/src/ChainMap.res.mjs +38 -38
  22. package/src/Config.res +193 -135
  23. package/src/Config.res.mjs +566 -592
  24. package/src/Core.res +182 -0
  25. package/src/Core.res.mjs +207 -0
  26. package/src/Ecosystem.res +25 -4
  27. package/src/Ecosystem.res.mjs +12 -13
  28. package/src/Env.res +20 -13
  29. package/src/Env.res.mjs +124 -113
  30. package/src/EnvSafe.res +269 -0
  31. package/src/EnvSafe.res.mjs +296 -0
  32. package/src/EnvSafe.resi +18 -0
  33. package/src/Envio.res +37 -26
  34. package/src/Envio.res.mjs +59 -60
  35. package/src/ErrorHandling.res +2 -2
  36. package/src/ErrorHandling.res.mjs +15 -15
  37. package/src/EventConfigBuilder.res +219 -81
  38. package/src/EventConfigBuilder.res.mjs +259 -202
  39. package/src/EventProcessing.res +27 -38
  40. package/src/EventProcessing.res.mjs +165 -183
  41. package/src/EventUtils.res +11 -11
  42. package/src/EventUtils.res.mjs +21 -22
  43. package/src/EvmTypes.res +0 -1
  44. package/src/EvmTypes.res.mjs +5 -5
  45. package/src/FetchState.res +360 -256
  46. package/src/FetchState.res.mjs +958 -914
  47. package/src/GlobalState.res +365 -351
  48. package/src/GlobalState.res.mjs +958 -992
  49. package/src/GlobalStateManager.res +1 -2
  50. package/src/GlobalStateManager.res.mjs +36 -44
  51. package/src/HandlerLoader.res +107 -23
  52. package/src/HandlerLoader.res.mjs +128 -38
  53. package/src/HandlerRegister.res +127 -103
  54. package/src/HandlerRegister.res.mjs +164 -164
  55. package/src/HandlerRegister.resi +12 -4
  56. package/src/Hasura.res +35 -22
  57. package/src/Hasura.res.mjs +158 -167
  58. package/src/InMemoryStore.res +20 -27
  59. package/src/InMemoryStore.res.mjs +64 -80
  60. package/src/InMemoryTable.res +34 -39
  61. package/src/InMemoryTable.res.mjs +165 -170
  62. package/src/Internal.res +52 -33
  63. package/src/Internal.res.mjs +84 -81
  64. package/src/LazyLoader.res.mjs +55 -61
  65. package/src/LoadLayer.res +77 -78
  66. package/src/LoadLayer.res.mjs +160 -189
  67. package/src/LoadManager.res +16 -21
  68. package/src/LoadManager.res.mjs +79 -84
  69. package/src/LogSelection.res +236 -68
  70. package/src/LogSelection.res.mjs +211 -141
  71. package/src/Logging.res +13 -9
  72. package/src/Logging.res.mjs +130 -143
  73. package/src/Main.res +428 -51
  74. package/src/Main.res.mjs +528 -271
  75. package/src/Persistence.res +77 -84
  76. package/src/Persistence.res.mjs +131 -132
  77. package/src/PgStorage.res +291 -167
  78. package/src/PgStorage.res.mjs +797 -817
  79. package/src/Prometheus.res +50 -58
  80. package/src/Prometheus.res.mjs +345 -373
  81. package/src/ReorgDetection.res +22 -24
  82. package/src/ReorgDetection.res.mjs +100 -106
  83. package/src/SafeCheckpointTracking.res +7 -7
  84. package/src/SafeCheckpointTracking.res.mjs +40 -43
  85. package/src/SimulateItems.res +41 -49
  86. package/src/SimulateItems.res.mjs +257 -272
  87. package/src/Sink.res +2 -2
  88. package/src/Sink.res.mjs +22 -26
  89. package/src/TableIndices.res +1 -2
  90. package/src/TableIndices.res.mjs +42 -48
  91. package/src/TestIndexer.res +196 -189
  92. package/src/TestIndexer.res.mjs +536 -536
  93. package/src/TestIndexerProxyStorage.res +15 -16
  94. package/src/TestIndexerProxyStorage.res.mjs +98 -122
  95. package/src/TestIndexerWorker.res +4 -0
  96. package/src/TestIndexerWorker.res.mjs +7 -0
  97. package/src/Throttler.res +3 -3
  98. package/src/Throttler.res.mjs +23 -24
  99. package/src/Time.res +1 -1
  100. package/src/Time.res.mjs +18 -21
  101. package/src/TopicFilter.res +3 -3
  102. package/src/TopicFilter.res.mjs +29 -30
  103. package/src/UserContext.res +93 -54
  104. package/src/UserContext.res.mjs +197 -182
  105. package/src/Utils.res +141 -86
  106. package/src/Utils.res.mjs +334 -295
  107. package/src/bindings/BigDecimal.res +0 -2
  108. package/src/bindings/BigDecimal.res.mjs +19 -23
  109. package/src/bindings/ClickHouse.res +28 -27
  110. package/src/bindings/ClickHouse.res.mjs +243 -240
  111. package/src/bindings/DateFns.res +11 -11
  112. package/src/bindings/DateFns.res.mjs +7 -7
  113. package/src/bindings/EventSource.res.mjs +2 -2
  114. package/src/bindings/Express.res +2 -5
  115. package/src/bindings/Hrtime.res +2 -2
  116. package/src/bindings/Hrtime.res.mjs +30 -32
  117. package/src/bindings/Lodash.res.mjs +1 -1
  118. package/src/bindings/NodeJs.res +14 -9
  119. package/src/bindings/NodeJs.res.mjs +20 -20
  120. package/src/bindings/Pino.res +8 -10
  121. package/src/bindings/Pino.res.mjs +40 -43
  122. package/src/bindings/Postgres.res +2 -5
  123. package/src/bindings/Postgres.res.mjs +9 -9
  124. package/src/bindings/PromClient.res +17 -2
  125. package/src/bindings/PromClient.res.mjs +30 -7
  126. package/src/bindings/SDSL.res.mjs +2 -2
  127. package/src/bindings/Viem.res +4 -4
  128. package/src/bindings/Viem.res.mjs +20 -22
  129. package/src/bindings/Vitest.res +1 -1
  130. package/src/bindings/Vitest.res.mjs +2 -2
  131. package/src/bindings/WebSocket.res +1 -1
  132. package/src/db/EntityHistory.res +9 -3
  133. package/src/db/EntityHistory.res.mjs +84 -59
  134. package/src/db/InternalTable.res +62 -60
  135. package/src/db/InternalTable.res.mjs +271 -203
  136. package/src/db/Schema.res +1 -2
  137. package/src/db/Schema.res.mjs +28 -32
  138. package/src/db/Table.res +28 -27
  139. package/src/db/Table.res.mjs +276 -292
  140. package/src/sources/EventRouter.res +21 -16
  141. package/src/sources/EventRouter.res.mjs +55 -57
  142. package/src/sources/Evm.res +17 -1
  143. package/src/sources/Evm.res.mjs +16 -8
  144. package/src/sources/EvmChain.res +15 -17
  145. package/src/sources/EvmChain.res.mjs +40 -42
  146. package/src/sources/Fuel.res +14 -1
  147. package/src/sources/Fuel.res.mjs +16 -8
  148. package/src/sources/FuelSDK.res +1 -1
  149. package/src/sources/FuelSDK.res.mjs +6 -8
  150. package/src/sources/HyperFuel.res +8 -10
  151. package/src/sources/HyperFuel.res.mjs +113 -123
  152. package/src/sources/HyperFuelClient.res.mjs +6 -7
  153. package/src/sources/HyperFuelSource.res +19 -20
  154. package/src/sources/HyperFuelSource.res.mjs +339 -356
  155. package/src/sources/HyperSync.res +11 -13
  156. package/src/sources/HyperSync.res.mjs +206 -220
  157. package/src/sources/HyperSyncClient.res +5 -7
  158. package/src/sources/HyperSyncClient.res.mjs +70 -75
  159. package/src/sources/HyperSyncHeightStream.res +8 -9
  160. package/src/sources/HyperSyncHeightStream.res.mjs +78 -86
  161. package/src/sources/HyperSyncJsonApi.res +18 -15
  162. package/src/sources/HyperSyncJsonApi.res.mjs +201 -231
  163. package/src/sources/HyperSyncSource.res +17 -21
  164. package/src/sources/HyperSyncSource.res.mjs +268 -290
  165. package/src/sources/Rpc.res +5 -5
  166. package/src/sources/Rpc.res.mjs +168 -192
  167. package/src/sources/RpcSource.res +166 -167
  168. package/src/sources/RpcSource.res.mjs +972 -1046
  169. package/src/sources/RpcWebSocketHeightStream.res +10 -11
  170. package/src/sources/RpcWebSocketHeightStream.res.mjs +131 -145
  171. package/src/sources/SimulateSource.res +1 -1
  172. package/src/sources/SimulateSource.res.mjs +35 -38
  173. package/src/sources/Source.res +1 -1
  174. package/src/sources/Source.res.mjs +3 -3
  175. package/src/sources/SourceManager.res +39 -20
  176. package/src/sources/SourceManager.res.mjs +340 -371
  177. package/src/sources/SourceManager.resi +2 -1
  178. package/src/sources/Svm.res +12 -5
  179. package/src/sources/Svm.res.mjs +44 -41
  180. package/src/tui/Tui.res +23 -12
  181. package/src/tui/Tui.res.mjs +292 -290
  182. package/src/tui/bindings/Ink.res +2 -4
  183. package/src/tui/bindings/Ink.res.mjs +35 -41
  184. package/src/tui/components/BufferedProgressBar.res +7 -7
  185. package/src/tui/components/BufferedProgressBar.res.mjs +46 -46
  186. package/src/tui/components/CustomHooks.res +1 -2
  187. package/src/tui/components/CustomHooks.res.mjs +102 -122
  188. package/src/tui/components/Messages.res +1 -2
  189. package/src/tui/components/Messages.res.mjs +38 -42
  190. package/src/tui/components/SyncETA.res +10 -11
  191. package/src/tui/components/SyncETA.res.mjs +178 -196
  192. package/src/tui/components/TuiData.res +1 -1
  193. package/src/tui/components/TuiData.res.mjs +7 -6
  194. package/src/vendored/Rest.res +52 -66
  195. package/src/vendored/Rest.res.mjs +324 -364
  196. package/svm.schema.json +67 -0
  197. package/src/Address.gen.ts +0 -8
  198. package/src/Config.gen.ts +0 -19
  199. package/src/Envio.gen.ts +0 -55
  200. package/src/EvmTypes.gen.ts +0 -6
  201. package/src/InMemoryStore.gen.ts +0 -6
  202. package/src/Internal.gen.ts +0 -64
  203. package/src/PgStorage.gen.ts +0 -10
  204. package/src/PgStorage.res.d.mts +0 -5
  205. package/src/Types.ts +0 -56
  206. package/src/bindings/BigDecimal.gen.ts +0 -14
  207. package/src/bindings/BigDecimal.res.d.mts +0 -5
  208. package/src/bindings/BigInt.gen.ts +0 -10
  209. package/src/bindings/BigInt.res +0 -70
  210. package/src/bindings/BigInt.res.d.mts +0 -5
  211. package/src/bindings/BigInt.res.mjs +0 -154
  212. package/src/bindings/Ethers.res.d.mts +0 -5
  213. package/src/bindings/Pino.gen.ts +0 -17
  214. package/src/bindings/Postgres.gen.ts +0 -8
  215. package/src/bindings/Postgres.res.d.mts +0 -5
  216. package/src/bindings/Promise.res +0 -67
  217. package/src/bindings/Promise.res.mjs +0 -26
  218. package/src/db/InternalTable.gen.ts +0 -36
  219. package/src/sources/HyperSyncClient.gen.ts +0 -19
package/src/Core.res ADDED
@@ -0,0 +1,182 @@
1
+ // Resolution order:
2
+ // 1. Production: require("envio-{os}-{arch}") — platform-specific npm package
3
+ // 2. Dev build: find repo → cargo build --lib → load from target/debug/
4
+
5
+ // NAPI encodes Rust `Option<T>` as `null | T` (never `undefined`), so the
6
+ // tighter `Null.t` captures the exact boundary shape.
7
+ type addon = {
8
+ getConfigJson: (~configPath: Null.t<string>, ~directory: Null.t<string>) => string,
9
+ runCli: (~args: array<string>, ~envioPackageDir: Null.t<string>) => promise<Null.t<string>>,
10
+ upsertPersistedState: (~json: string) => promise<unit>,
11
+ }
12
+
13
+ @module("node:module") external createRequire: string => {..} = "createRequire"
14
+ @module("node:url") external fileURLToPath: string => string = "fileURLToPath"
15
+ @val external importMetaUrl: string = "import.meta.url"
16
+ @module("node:path") external pathDirname: string => string = "dirname"
17
+ @module("node:path") @variadic external pathResolve: array<string> => string = "resolve"
18
+ @module("node:fs") external existsSync: string => bool = "existsSync"
19
+ @module("node:child_process")
20
+ external execSyncRaw: (string, {..}) => string = "execSync"
21
+ @val external processPlatform: string = "process.platform"
22
+ @val external processArch: string = "process.arch"
23
+
24
+ // Keeps `node:fs` / `node:child_process` imports alive for the %raw
25
+ // loadDevAddon block, which references them as Nodefs / Nodechild_process.
26
+ let _keepFs = existsSync
27
+ let _keepCp = execSyncRaw
28
+
29
+ let callRequire: ({..}, string) => addon = %raw(`(req, id) => req(id)`)
30
+
31
+ let envioPackageDir = pathDirname(pathDirname(fileURLToPath(importMetaUrl)))
32
+
33
+ // Runs `cargo build` on every invocation (like `cargo run`).
34
+ let loadDevAddon: ({..}, string) => addon = %raw(`function(req, envioDir) {
35
+ var cp = Nodechild_process;
36
+ var path = Nodepath;
37
+ var fs = Nodefs;
38
+
39
+ var repoRoot = null;
40
+ var dir = path.resolve(envioDir);
41
+ for (var i = 0; i < 10; i++) {
42
+ dir = path.dirname(dir);
43
+ if (dir === path.dirname(dir)) break;
44
+ if (fs.existsSync(path.join(dir, "packages", "cli", "Cargo.toml"))) {
45
+ repoRoot = dir;
46
+ break;
47
+ }
48
+ }
49
+
50
+ if (!repoRoot) {
51
+ var result;
52
+ try {
53
+ result = cp.execSync("pnpm list envio --json", {
54
+ encoding: "utf8", timeout: 10000,
55
+ stdio: ["ignore", "pipe", "ignore"],
56
+ });
57
+ } catch (e) { return null; }
58
+
59
+ var parsed;
60
+ try {
61
+ var s = result.trim();
62
+ if (s.startsWith(",")) s = s.slice(1);
63
+ if (s.endsWith(",")) s = s.slice(0, -1);
64
+ parsed = JSON.parse(s);
65
+ } catch (e) { return null; }
66
+
67
+ var ver;
68
+ try {
69
+ var pkg = Array.isArray(parsed) ? parsed[0] : parsed;
70
+ ver = (pkg.dependencies || pkg.devDependencies || {}).envio.version;
71
+ } catch (e) { return null; }
72
+
73
+ if (!ver || !ver.startsWith("file:")) return null;
74
+ repoRoot = path.resolve(path.resolve(ver.replace("file:", "")), "..", "..");
75
+ if (!fs.existsSync(path.join(repoRoot, "packages", "cli", "Cargo.toml"))) return null;
76
+ }
77
+
78
+ var cliDir = path.join(repoRoot, "packages", "cli");
79
+ try {
80
+ cp.execSync("cargo build --lib", { cwd: cliDir, stdio: "inherit" });
81
+ } catch (e) {
82
+ throw new Error("Failed to build envio NAPI addon. Run 'cargo build --lib' in " + cliDir + " manually.");
83
+ }
84
+
85
+ var libName = process.platform === "darwin" ? "libenvio.dylib"
86
+ : process.platform === "win32" ? "envio.dll" : "libenvio.so";
87
+ var srcPath = path.join(repoRoot, "target", "debug", libName);
88
+ var nodePath = path.join(repoRoot, "target", "debug", "envio.node");
89
+ if (!fs.existsSync(srcPath)) {
90
+ throw new Error("cargo build succeeded but " + srcPath + " not found.");
91
+ }
92
+
93
+ if (!fs.existsSync(nodePath) || fs.statSync(nodePath).mtimeMs < fs.statSync(srcPath).mtimeMs) {
94
+ fs.copyFileSync(srcPath, nodePath);
95
+ }
96
+
97
+ return req(nodePath);
98
+ }`)
99
+
100
+ // Native `throw` so we can re-raise a caught JS error preserving its stack,
101
+ // `code`, and any other fields a diagnostic might rely on.
102
+ let rethrow: JsExn.t => 'a = %raw(`function(e) { throw e }`)
103
+
104
+ let loadAddon = () => {
105
+ let req = createRequire(importMetaUrl)
106
+
107
+ // npm's `libc` field installs only the matching package on Linux, so the
108
+ // wrong name throws MODULE_NOT_FOUND immediately and the next candidate
109
+ // wins. An empty list means the host isn't a publish target.
110
+ let candidates = switch (processPlatform, processArch) {
111
+ | ("linux", "x64") => [`envio-linux-x64`, `envio-linux-x64-musl`]
112
+ | ("linux", "arm64") => [`envio-linux-arm64`]
113
+ | ("darwin", "x64") => [`envio-darwin-x64`]
114
+ | ("darwin", "arm64") => [`envio-darwin-arm64`]
115
+ | _ => []
116
+ }
117
+
118
+ // Only swallow MODULE_NOT_FOUND (the optional package isn't installed on
119
+ // this host). Any other failure — corrupt .node, ABI mismatch, dlopen
120
+ // error — is a real load failure and must surface.
121
+ let rec tryRequire = i =>
122
+ switch candidates[i] {
123
+ | None => None
124
+ | Some(pkg) =>
125
+ try Some(callRequire(req, pkg)) catch {
126
+ | exn =>
127
+ switch exn->JsExn.anyToExnInternal {
128
+ | JsExn(e) if (e->(Utils.magic: JsExn.t => {..}))["code"] === "MODULE_NOT_FOUND" =>
129
+ tryRequire(i + 1)
130
+ | JsExn(e) => rethrow(e)
131
+ | _ => throw(exn)
132
+ }
133
+ }
134
+ }
135
+
136
+ switch tryRequire(0) {
137
+ | Some(addon) => addon
138
+ | None =>
139
+ // Dev build fallback (cargo build on every run)
140
+ switch loadDevAddon(req, envioPackageDir)->(Utils.magic: addon => option<addon>) {
141
+ | Some(addon) => addon
142
+ | None =>
143
+ let host = `${processPlatform}-${processArch}`
144
+ let msg = if candidates->Array.length === 0 {
145
+ `envio doesn't support ${host}. Supported: linux-x64 (glibc/musl), linux-arm64, darwin-x64, darwin-arm64.`
146
+ } else {
147
+ `Couldn't load the envio native addon for ${host}. Reinstall envio (ensure optional dependencies aren't skipped).`
148
+ }
149
+ JsError.throwWithMessage(msg)
150
+ }
151
+ }
152
+ }
153
+
154
+ let addonRef: ref<option<addon>> = ref(None)
155
+
156
+ let getAddon = () =>
157
+ switch addonRef.contents {
158
+ | Some(a) => a
159
+ | None => {
160
+ let a = loadAddon()
161
+ addonRef := Some(a)
162
+ a
163
+ }
164
+ }
165
+
166
+ let getConfigJson = (~configPath=?, ~directory=?) => {
167
+ let addon = getAddon()
168
+ addon.getConfigJson(
169
+ ~configPath=configPath->Null.fromOption,
170
+ ~directory=directory->Null.fromOption,
171
+ )
172
+ }
173
+
174
+ let runCli = args => {
175
+ let addon = getAddon()
176
+ addon.runCli(~args, ~envioPackageDir=Null.make(envioPackageDir))
177
+ }
178
+
179
+ let upsertPersistedState = json => {
180
+ let addon = getAddon()
181
+ addon.upsertPersistedState(~json)
182
+ }
@@ -0,0 +1,207 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Nodefs from "node:fs";
4
+ import * as Nodeurl from "node:url";
5
+ import * as Nodepath from "node:path";
6
+ import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
7
+ import * as Nodemodule from "node:module";
8
+ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
9
+ import * as Nodechild_process from "node:child_process";
10
+ import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
11
+
12
+ function _keepFs(prim) {
13
+ return Nodefs.existsSync(prim);
14
+ }
15
+
16
+ function _keepCp(prim0, prim1) {
17
+ return Nodechild_process.execSync(prim0, prim1);
18
+ }
19
+
20
+ let callRequire = ((req, id) => req(id));
21
+
22
+ let envioPackageDir = Nodepath.dirname(Nodepath.dirname(Nodeurl.fileURLToPath(import.meta.url)));
23
+
24
+ let loadDevAddon = (function(req, envioDir) {
25
+ var cp = Nodechild_process;
26
+ var path = Nodepath;
27
+ var fs = Nodefs;
28
+
29
+ var repoRoot = null;
30
+ var dir = path.resolve(envioDir);
31
+ for (var i = 0; i < 10; i++) {
32
+ dir = path.dirname(dir);
33
+ if (dir === path.dirname(dir)) break;
34
+ if (fs.existsSync(path.join(dir, "packages", "cli", "Cargo.toml"))) {
35
+ repoRoot = dir;
36
+ break;
37
+ }
38
+ }
39
+
40
+ if (!repoRoot) {
41
+ var result;
42
+ try {
43
+ result = cp.execSync("pnpm list envio --json", {
44
+ encoding: "utf8", timeout: 10000,
45
+ stdio: ["ignore", "pipe", "ignore"],
46
+ });
47
+ } catch (e) { return null; }
48
+
49
+ var parsed;
50
+ try {
51
+ var s = result.trim();
52
+ if (s.startsWith(",")) s = s.slice(1);
53
+ if (s.endsWith(",")) s = s.slice(0, -1);
54
+ parsed = JSON.parse(s);
55
+ } catch (e) { return null; }
56
+
57
+ var ver;
58
+ try {
59
+ var pkg = Array.isArray(parsed) ? parsed[0] : parsed;
60
+ ver = (pkg.dependencies || pkg.devDependencies || {}).envio.version;
61
+ } catch (e) { return null; }
62
+
63
+ if (!ver || !ver.startsWith("file:")) return null;
64
+ repoRoot = path.resolve(path.resolve(ver.replace("file:", "")), "..", "..");
65
+ if (!fs.existsSync(path.join(repoRoot, "packages", "cli", "Cargo.toml"))) return null;
66
+ }
67
+
68
+ var cliDir = path.join(repoRoot, "packages", "cli");
69
+ try {
70
+ cp.execSync("cargo build --lib", { cwd: cliDir, stdio: "inherit" });
71
+ } catch (e) {
72
+ throw new Error("Failed to build envio NAPI addon. Run 'cargo build --lib' in " + cliDir + " manually.");
73
+ }
74
+
75
+ var libName = process.platform === "darwin" ? "libenvio.dylib"
76
+ : process.platform === "win32" ? "envio.dll" : "libenvio.so";
77
+ var srcPath = path.join(repoRoot, "target", "debug", libName);
78
+ var nodePath = path.join(repoRoot, "target", "debug", "envio.node");
79
+ if (!fs.existsSync(srcPath)) {
80
+ throw new Error("cargo build succeeded but " + srcPath + " not found.");
81
+ }
82
+
83
+ if (!fs.existsSync(nodePath) || fs.statSync(nodePath).mtimeMs < fs.statSync(srcPath).mtimeMs) {
84
+ fs.copyFileSync(srcPath, nodePath);
85
+ }
86
+
87
+ return req(nodePath);
88
+ });
89
+
90
+ let rethrow = (function(e) { throw e });
91
+
92
+ function loadAddon() {
93
+ let req = Nodemodule.createRequire(import.meta.url);
94
+ let match = process.platform;
95
+ let match$1 = process.arch;
96
+ let candidates;
97
+ switch (match) {
98
+ case "darwin" :
99
+ switch (match$1) {
100
+ case "arm64" :
101
+ candidates = [`envio-darwin-arm64`];
102
+ break;
103
+ case "x64" :
104
+ candidates = [`envio-darwin-x64`];
105
+ break;
106
+ default:
107
+ candidates = [];
108
+ }
109
+ break;
110
+ case "linux" :
111
+ switch (match$1) {
112
+ case "arm64" :
113
+ candidates = [`envio-linux-arm64`];
114
+ break;
115
+ case "x64" :
116
+ candidates = [
117
+ `envio-linux-x64`,
118
+ `envio-linux-x64-musl`
119
+ ];
120
+ break;
121
+ default:
122
+ candidates = [];
123
+ }
124
+ break;
125
+ default:
126
+ candidates = [];
127
+ }
128
+ let tryRequire = _i => {
129
+ while (true) {
130
+ let i = _i;
131
+ let pkg = candidates[i];
132
+ if (pkg === undefined) {
133
+ return;
134
+ }
135
+ try {
136
+ return callRequire(req, pkg);
137
+ } catch (raw_exn) {
138
+ let exn = Primitive_exceptions.internalToException(raw_exn);
139
+ let e = Primitive_exceptions.internalToException(exn);
140
+ if (e.RE_EXN_ID === "JsExn") {
141
+ let e$1 = e._1;
142
+ if (e$1.code !== "MODULE_NOT_FOUND") {
143
+ return rethrow(e$1);
144
+ }
145
+ _i = i + 1 | 0;
146
+ continue;
147
+ }
148
+ throw exn;
149
+ }
150
+ };
151
+ };
152
+ let addon = tryRequire(0);
153
+ if (addon !== undefined) {
154
+ return addon;
155
+ }
156
+ let addon$1 = loadDevAddon(req, envioPackageDir);
157
+ if (addon$1 !== undefined) {
158
+ return addon$1;
159
+ }
160
+ let host = process.platform + `-` + process.arch;
161
+ return Stdlib_JsError.throwWithMessage(candidates.length === 0 ? `envio doesn't support ` + host + `. Supported: linux-x64 (glibc/musl), linux-arm64, darwin-x64, darwin-arm64.` : `Couldn't load the envio native addon for ` + host + `. Reinstall envio (ensure optional dependencies aren't skipped).`);
162
+ }
163
+
164
+ let addonRef = {
165
+ contents: undefined
166
+ };
167
+
168
+ function getAddon() {
169
+ let a = addonRef.contents;
170
+ if (a !== undefined) {
171
+ return a;
172
+ }
173
+ let a$1 = loadAddon();
174
+ addonRef.contents = a$1;
175
+ return a$1;
176
+ }
177
+
178
+ function getConfigJson(configPath, directory) {
179
+ let addon = getAddon();
180
+ return addon.getConfigJson(Stdlib_Null.fromOption(configPath), Stdlib_Null.fromOption(directory));
181
+ }
182
+
183
+ function runCli(args) {
184
+ let addon = getAddon();
185
+ return addon.runCli(args, envioPackageDir);
186
+ }
187
+
188
+ function upsertPersistedState(json) {
189
+ let addon = getAddon();
190
+ return addon.upsertPersistedState(json);
191
+ }
192
+
193
+ export {
194
+ _keepFs,
195
+ _keepCp,
196
+ callRequire,
197
+ envioPackageDir,
198
+ loadDevAddon,
199
+ rethrow,
200
+ loadAddon,
201
+ addonRef,
202
+ getAddon,
203
+ getConfigJson,
204
+ runCli,
205
+ upsertPersistedState,
206
+ }
207
+ /* envioPackageDir Not a pure module */
package/src/Ecosystem.res CHANGED
@@ -10,16 +10,37 @@ type t = {
10
10
  getNumber: Internal.eventBlock => int,
11
11
  getTimestamp: Internal.eventBlock => int,
12
12
  getId: Internal.eventBlock => string,
13
- cleanUpRawEventFieldsInPlace: Js.Json.t => unit,
13
+ cleanUpRawEventFieldsInPlace: JSON.t => unit,
14
+ /** Method name that the block handler is exposed under on the public
15
+ `indexer` object — `"onBlock"` for chain-based ecosystems, `"onSlot"`
16
+ for SVM. Centralised here so adding a new ecosystem only requires a
17
+ new ecosystem record, not another switch in `Main.res`. */
18
+ onBlockMethodName: string,
19
+ /** Schema that unwraps the ecosystem-specific outer wrapper around the
20
+ user's `where`-returned filter (`block.number` on EVM, `block.height`
21
+ on Fuel, `slot` on SVM) and surfaces the raw inner `{_gte?, _lte?,
22
+ _every?}` chunk as `option<unknown>`. The inner chunk is then parsed
23
+ a second time in `Main.res` by the shared `blockRangeSchema` — that
24
+ keeps range-field validation in one place for every ecosystem. */
25
+ onBlockFilterSchema: S.t<option<unknown>>,
26
+ /** Schema that unwraps the ecosystem-specific `block` wrapper from the
27
+ user's `onEvent` `where` value (`block.number` on EVM, `block.height`
28
+ on Fuel) and surfaces the raw inner `{_gte?}` chunk as
29
+ `option<unknown>`. Separate from `onBlockFilterSchema` because event
30
+ block filters support only `_gte` (→ per-event `startBlock`) — `_lte`
31
+ and `_every` are rejected by the inner `eventBlockRangeSchema` in
32
+ `LogSelection.res`. SVM does not support event handlers, so its
33
+ schema always surfaces `None`. */
34
+ onEventBlockFilterSchema: S.t<option<unknown>>,
14
35
  }
15
36
 
16
37
  let makeOnBlockArgs = (~blockNumber: int, ~ecosystem: t, ~context): Internal.onBlockArgs => {
17
38
  switch ecosystem.name {
18
39
  | Svm => {slot: blockNumber, context}
19
40
  | _ => {
20
- let blockEvent = Js.Dict.empty()
21
- blockEvent->Js.Dict.set(ecosystem.blockNumberName, blockNumber->(Utils.magic: int => unknown))
22
- {block: blockEvent->(Utils.magic: Js.Dict.t<unknown> => Internal.blockEvent), context}
41
+ let blockEvent = Dict.make()
42
+ blockEvent->Dict.set(ecosystem.blockNumberName, blockNumber->(Utils.magic: int => unknown))
43
+ {block: blockEvent->(Utils.magic: dict<unknown> => Internal.blockEvent), context}
23
44
  }
24
45
  }
25
46
  }
@@ -1,29 +1,28 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
- import * as Caml_option from "rescript/lib/es6/caml_option.js";
3
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
4
4
 
5
5
  function makeOnBlockArgs(blockNumber, ecosystem, context) {
6
- var match = ecosystem.name;
6
+ let match = ecosystem.name;
7
7
  switch (match) {
8
8
  case "evm" :
9
9
  case "fuel" :
10
- break;
10
+ break;
11
11
  case "svm" :
12
- return {
13
- slot: blockNumber,
14
- context: context
15
- };
16
-
12
+ return {
13
+ slot: blockNumber,
14
+ context: context
15
+ };
17
16
  }
18
- var blockEvent = {};
17
+ let blockEvent = {};
19
18
  blockEvent[ecosystem.blockNumberName] = blockNumber;
20
19
  return {
21
- block: Caml_option.some(blockEvent),
22
- context: context
23
- };
20
+ block: Primitive_option.some(blockEvent),
21
+ context: context
22
+ };
24
23
  }
25
24
 
26
25
  export {
27
- makeOnBlockArgs ,
26
+ makeOnBlockArgs,
28
27
  }
29
28
  /* No side effect */
package/src/Env.res CHANGED
@@ -121,17 +121,24 @@ module Db = {
121
121
  let maxConnections = envSafe->EnvSafe.get("ENVIO_PG_MAX_CONNECTIONS", S.int, ~fallback=2)
122
122
  }
123
123
 
124
- module ClickHouseSink = {
125
- let host = envSafe->EnvSafe.get("ENVIO_CLICKHOUSE_SINK_HOST", S.option(S.string))
126
- let database = envSafe->EnvSafe.get("ENVIO_CLICKHOUSE_SINK_DATABASE", S.option(S.string))
127
- let username = switch host {
128
- | None => ""
129
- | Some(_) => envSafe->EnvSafe.get("ENVIO_CLICKHOUSE_SINK_USERNAME", S.string)
130
- }
131
- let password = switch host {
132
- | None => ""
133
- | Some(_) => envSafe->EnvSafe.get("ENVIO_CLICKHOUSE_SINK_PASSWORD", S.string)
134
- }
124
+ // Required env vars are validated lazily in PgStorage when the user
125
+ // opts into ClickHouse via `storage.clickhouse: true` in config.yaml.
126
+ //
127
+ // Reads run at call time instead of module load. `envio dev` injects these
128
+ // vars into `process.env` after booting its ClickHouse container, and that
129
+ // happens strictly after this module has already been evaluated — caching
130
+ // at module load would lock in `None` and defeat the injection.
131
+ module ClickHouse = {
132
+ %%private(
133
+ let read: string => option<string> = %raw(`(k) => {
134
+ const v = process.env[k];
135
+ return v === undefined || v === "" ? undefined : v;
136
+ }`)
137
+ )
138
+ let host = () => read("ENVIO_CLICKHOUSE_HOST")
139
+ let database = () => read("ENVIO_CLICKHOUSE_DATABASE")
140
+ let username = () => read("ENVIO_CLICKHOUSE_USERNAME")
141
+ let password = () => read("ENVIO_CLICKHOUSE_PASSWORD")
135
142
  }
136
143
 
137
144
  module Hasura = {
@@ -151,7 +158,7 @@ module Hasura = {
151
158
  ~devFallback="http://localhost:8080/v1/metadata",
152
159
  )
153
160
 
154
- let url = graphqlEndpoint->Js.String2.slice(~from=0, ~to_=-("/v1/metadata"->Js.String2.length))
161
+ let url = graphqlEndpoint->String.slice(~start=0, ~end=-("/v1/metadata"->String.length))
155
162
 
156
163
  let role = envSafe->EnvSafe.get("HASURA_GRAPHQL_ROLE", S.string, ~devFallback="admin")
157
164
 
@@ -165,7 +172,7 @@ module Hasura = {
165
172
  // Will be removed once comma support is added — don't rely on this.
166
173
  S.string->S.transform(s => {
167
174
  parser: string =>
168
- switch string->Js.String2.split("&") {
175
+ switch string->String.split("&") {
169
176
  | []
170
177
  | [_] =>
171
178
  s.fail(`Provide an array of entities in the JSON format.`)