envio 3.0.0-alpha.21 → 3.0.0-alpha.23

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 (220) hide show
  1. package/README.md +3 -3
  2. package/bin.mjs +2 -48
  3. package/evm.schema.json +67 -0
  4. package/fuel.schema.json +67 -0
  5. package/index.d.ts +822 -38
  6. package/index.js +5 -3
  7. package/package.json +10 -8
  8. package/rescript.json +5 -9
  9. package/src/Address.res +4 -5
  10. package/src/Address.res.mjs +9 -12
  11. package/src/Api.res +15 -0
  12. package/src/Api.res.mjs +20 -0
  13. package/src/Batch.res +32 -34
  14. package/src/Batch.res.mjs +172 -187
  15. package/src/Bin.res +89 -0
  16. package/src/Bin.res.mjs +97 -0
  17. package/src/ChainFetcher.res +33 -57
  18. package/src/ChainFetcher.res.mjs +197 -227
  19. package/src/ChainManager.res +6 -14
  20. package/src/ChainManager.res.mjs +74 -85
  21. package/src/ChainMap.res +14 -16
  22. package/src/ChainMap.res.mjs +38 -38
  23. package/src/Config.res +193 -135
  24. package/src/Config.res.mjs +566 -592
  25. package/src/Core.res +182 -0
  26. package/src/Core.res.mjs +207 -0
  27. package/src/Ecosystem.res +25 -4
  28. package/src/Ecosystem.res.mjs +12 -13
  29. package/src/Env.res +20 -13
  30. package/src/Env.res.mjs +124 -113
  31. package/src/EnvSafe.res +269 -0
  32. package/src/EnvSafe.res.mjs +296 -0
  33. package/src/EnvSafe.resi +18 -0
  34. package/src/Envio.res +37 -26
  35. package/src/Envio.res.mjs +59 -60
  36. package/src/ErrorHandling.res +2 -2
  37. package/src/ErrorHandling.res.mjs +15 -15
  38. package/src/EventConfigBuilder.res +219 -81
  39. package/src/EventConfigBuilder.res.mjs +259 -202
  40. package/src/EventProcessing.res +27 -38
  41. package/src/EventProcessing.res.mjs +165 -183
  42. package/src/EventUtils.res +11 -11
  43. package/src/EventUtils.res.mjs +21 -22
  44. package/src/EvmTypes.res +0 -1
  45. package/src/EvmTypes.res.mjs +5 -5
  46. package/src/FetchState.res +360 -256
  47. package/src/FetchState.res.mjs +958 -914
  48. package/src/GlobalState.res +365 -351
  49. package/src/GlobalState.res.mjs +958 -992
  50. package/src/GlobalStateManager.res +1 -2
  51. package/src/GlobalStateManager.res.mjs +36 -44
  52. package/src/HandlerLoader.res +107 -23
  53. package/src/HandlerLoader.res.mjs +128 -38
  54. package/src/HandlerRegister.res +127 -103
  55. package/src/HandlerRegister.res.mjs +164 -164
  56. package/src/HandlerRegister.resi +12 -4
  57. package/src/Hasura.res +35 -22
  58. package/src/Hasura.res.mjs +158 -167
  59. package/src/InMemoryStore.res +20 -27
  60. package/src/InMemoryStore.res.mjs +64 -80
  61. package/src/InMemoryTable.res +34 -39
  62. package/src/InMemoryTable.res.mjs +165 -170
  63. package/src/Internal.res +52 -33
  64. package/src/Internal.res.mjs +84 -81
  65. package/src/LazyLoader.res.mjs +55 -61
  66. package/src/LoadLayer.res +77 -78
  67. package/src/LoadLayer.res.mjs +160 -189
  68. package/src/LoadManager.res +16 -21
  69. package/src/LoadManager.res.mjs +79 -84
  70. package/src/LogSelection.res +236 -68
  71. package/src/LogSelection.res.mjs +211 -141
  72. package/src/Logging.res +13 -9
  73. package/src/Logging.res.mjs +130 -143
  74. package/src/Main.res +430 -51
  75. package/src/Main.res.mjs +530 -271
  76. package/src/Persistence.res +80 -84
  77. package/src/Persistence.res.mjs +131 -132
  78. package/src/PgStorage.res +294 -167
  79. package/src/PgStorage.res.mjs +799 -817
  80. package/src/Prometheus.res +50 -58
  81. package/src/Prometheus.res.mjs +345 -373
  82. package/src/ReorgDetection.res +22 -24
  83. package/src/ReorgDetection.res.mjs +100 -106
  84. package/src/SafeCheckpointTracking.res +7 -7
  85. package/src/SafeCheckpointTracking.res.mjs +40 -43
  86. package/src/SimulateItems.res +41 -49
  87. package/src/SimulateItems.res.mjs +257 -272
  88. package/src/Sink.res +2 -2
  89. package/src/Sink.res.mjs +22 -26
  90. package/src/TableIndices.res +1 -2
  91. package/src/TableIndices.res.mjs +42 -48
  92. package/src/TestIndexer.res +196 -189
  93. package/src/TestIndexer.res.mjs +536 -536
  94. package/src/TestIndexerProxyStorage.res +16 -16
  95. package/src/TestIndexerProxyStorage.res.mjs +99 -122
  96. package/src/TestIndexerWorker.res +4 -0
  97. package/src/TestIndexerWorker.res.mjs +7 -0
  98. package/src/Throttler.res +3 -3
  99. package/src/Throttler.res.mjs +23 -24
  100. package/src/Time.res +1 -1
  101. package/src/Time.res.mjs +18 -21
  102. package/src/TopicFilter.res +3 -3
  103. package/src/TopicFilter.res.mjs +29 -30
  104. package/src/UserContext.res +93 -54
  105. package/src/UserContext.res.mjs +197 -182
  106. package/src/Utils.res +141 -86
  107. package/src/Utils.res.mjs +334 -295
  108. package/src/bindings/BigDecimal.res +0 -2
  109. package/src/bindings/BigDecimal.res.mjs +19 -23
  110. package/src/bindings/ClickHouse.res +28 -27
  111. package/src/bindings/ClickHouse.res.mjs +243 -240
  112. package/src/bindings/DateFns.res +11 -11
  113. package/src/bindings/DateFns.res.mjs +7 -7
  114. package/src/bindings/EventSource.res.mjs +2 -2
  115. package/src/bindings/Express.res +2 -5
  116. package/src/bindings/Hrtime.res +2 -2
  117. package/src/bindings/Hrtime.res.mjs +30 -32
  118. package/src/bindings/Lodash.res.mjs +1 -1
  119. package/src/bindings/NodeJs.res +14 -9
  120. package/src/bindings/NodeJs.res.mjs +20 -20
  121. package/src/bindings/Pino.res +8 -10
  122. package/src/bindings/Pino.res.mjs +40 -43
  123. package/src/bindings/Postgres.res +7 -5
  124. package/src/bindings/Postgres.res.mjs +9 -9
  125. package/src/bindings/PromClient.res +17 -2
  126. package/src/bindings/PromClient.res.mjs +30 -7
  127. package/src/bindings/SDSL.res.mjs +2 -2
  128. package/src/bindings/Viem.res +4 -4
  129. package/src/bindings/Viem.res.mjs +20 -22
  130. package/src/bindings/Vitest.res +1 -1
  131. package/src/bindings/Vitest.res.mjs +2 -2
  132. package/src/bindings/WebSocket.res +1 -1
  133. package/src/db/EntityHistory.res +9 -3
  134. package/src/db/EntityHistory.res.mjs +84 -59
  135. package/src/db/InternalTable.res +62 -60
  136. package/src/db/InternalTable.res.mjs +271 -203
  137. package/src/db/Schema.res +1 -2
  138. package/src/db/Schema.res.mjs +28 -32
  139. package/src/db/Table.res +28 -27
  140. package/src/db/Table.res.mjs +276 -292
  141. package/src/sources/EventRouter.res +21 -16
  142. package/src/sources/EventRouter.res.mjs +55 -57
  143. package/src/sources/Evm.res +17 -1
  144. package/src/sources/Evm.res.mjs +16 -8
  145. package/src/sources/EvmChain.res +15 -17
  146. package/src/sources/EvmChain.res.mjs +40 -42
  147. package/src/sources/Fuel.res +14 -1
  148. package/src/sources/Fuel.res.mjs +16 -8
  149. package/src/sources/FuelSDK.res +1 -1
  150. package/src/sources/FuelSDK.res.mjs +6 -8
  151. package/src/sources/HyperFuel.res +8 -10
  152. package/src/sources/HyperFuel.res.mjs +113 -123
  153. package/src/sources/HyperFuelClient.res.mjs +6 -7
  154. package/src/sources/HyperFuelSource.res +19 -20
  155. package/src/sources/HyperFuelSource.res.mjs +339 -356
  156. package/src/sources/HyperSync.res +11 -13
  157. package/src/sources/HyperSync.res.mjs +206 -220
  158. package/src/sources/HyperSyncClient.res +5 -7
  159. package/src/sources/HyperSyncClient.res.mjs +70 -75
  160. package/src/sources/HyperSyncHeightStream.res +8 -9
  161. package/src/sources/HyperSyncHeightStream.res.mjs +78 -86
  162. package/src/sources/HyperSyncJsonApi.res +18 -15
  163. package/src/sources/HyperSyncJsonApi.res.mjs +201 -231
  164. package/src/sources/HyperSyncSource.res +17 -21
  165. package/src/sources/HyperSyncSource.res.mjs +268 -290
  166. package/src/sources/Rpc.res +5 -5
  167. package/src/sources/Rpc.res.mjs +168 -192
  168. package/src/sources/RpcSource.res +166 -167
  169. package/src/sources/RpcSource.res.mjs +972 -1046
  170. package/src/sources/RpcWebSocketHeightStream.res +10 -11
  171. package/src/sources/RpcWebSocketHeightStream.res.mjs +131 -145
  172. package/src/sources/SimulateSource.res +1 -1
  173. package/src/sources/SimulateSource.res.mjs +35 -38
  174. package/src/sources/Source.res +1 -1
  175. package/src/sources/Source.res.mjs +3 -3
  176. package/src/sources/SourceManager.res +39 -20
  177. package/src/sources/SourceManager.res.mjs +340 -371
  178. package/src/sources/SourceManager.resi +2 -1
  179. package/src/sources/Svm.res +12 -5
  180. package/src/sources/Svm.res.mjs +44 -41
  181. package/src/tui/Tui.res +23 -12
  182. package/src/tui/Tui.res.mjs +292 -290
  183. package/src/tui/bindings/Ink.res +2 -4
  184. package/src/tui/bindings/Ink.res.mjs +35 -41
  185. package/src/tui/components/BufferedProgressBar.res +7 -7
  186. package/src/tui/components/BufferedProgressBar.res.mjs +46 -46
  187. package/src/tui/components/CustomHooks.res +1 -2
  188. package/src/tui/components/CustomHooks.res.mjs +102 -122
  189. package/src/tui/components/Messages.res +1 -2
  190. package/src/tui/components/Messages.res.mjs +38 -42
  191. package/src/tui/components/SyncETA.res +10 -11
  192. package/src/tui/components/SyncETA.res.mjs +178 -196
  193. package/src/tui/components/TuiData.res +1 -1
  194. package/src/tui/components/TuiData.res.mjs +7 -6
  195. package/src/vendored/Rest.res +52 -66
  196. package/src/vendored/Rest.res.mjs +324 -364
  197. package/svm.schema.json +67 -0
  198. package/src/Address.gen.ts +0 -8
  199. package/src/Config.gen.ts +0 -19
  200. package/src/Envio.gen.ts +0 -55
  201. package/src/EvmTypes.gen.ts +0 -6
  202. package/src/InMemoryStore.gen.ts +0 -6
  203. package/src/Internal.gen.ts +0 -64
  204. package/src/PgStorage.gen.ts +0 -10
  205. package/src/PgStorage.res.d.mts +0 -5
  206. package/src/Types.ts +0 -56
  207. package/src/bindings/BigDecimal.gen.ts +0 -14
  208. package/src/bindings/BigDecimal.res.d.mts +0 -5
  209. package/src/bindings/BigInt.gen.ts +0 -10
  210. package/src/bindings/BigInt.res +0 -70
  211. package/src/bindings/BigInt.res.d.mts +0 -5
  212. package/src/bindings/BigInt.res.mjs +0 -154
  213. package/src/bindings/Ethers.res.d.mts +0 -5
  214. package/src/bindings/Pino.gen.ts +0 -17
  215. package/src/bindings/Postgres.gen.ts +0 -8
  216. package/src/bindings/Postgres.res.d.mts +0 -5
  217. package/src/bindings/Promise.res +0 -67
  218. package/src/bindings/Promise.res.mjs +0 -26
  219. package/src/db/InternalTable.gen.ts +0 -36
  220. 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.`)