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.
- package/bin.mjs +2 -48
- package/evm.schema.json +67 -0
- package/fuel.schema.json +67 -0
- package/index.d.ts +822 -38
- package/index.js +5 -3
- package/package.json +10 -8
- package/rescript.json +5 -9
- package/src/Address.res +4 -5
- package/src/Address.res.mjs +9 -12
- package/src/Api.res +15 -0
- package/src/Api.res.mjs +20 -0
- package/src/Batch.res +32 -34
- package/src/Batch.res.mjs +172 -187
- package/src/Bin.res +89 -0
- package/src/Bin.res.mjs +97 -0
- package/src/ChainFetcher.res +33 -57
- package/src/ChainFetcher.res.mjs +197 -227
- package/src/ChainManager.res +6 -14
- package/src/ChainManager.res.mjs +74 -85
- package/src/ChainMap.res +14 -16
- package/src/ChainMap.res.mjs +38 -38
- package/src/Config.res +193 -135
- package/src/Config.res.mjs +566 -592
- package/src/Core.res +182 -0
- package/src/Core.res.mjs +207 -0
- package/src/Ecosystem.res +25 -4
- package/src/Ecosystem.res.mjs +12 -13
- package/src/Env.res +20 -13
- package/src/Env.res.mjs +124 -113
- package/src/EnvSafe.res +269 -0
- package/src/EnvSafe.res.mjs +296 -0
- package/src/EnvSafe.resi +18 -0
- package/src/Envio.res +37 -26
- package/src/Envio.res.mjs +59 -60
- package/src/ErrorHandling.res +2 -2
- package/src/ErrorHandling.res.mjs +15 -15
- package/src/EventConfigBuilder.res +219 -81
- package/src/EventConfigBuilder.res.mjs +259 -202
- package/src/EventProcessing.res +27 -38
- package/src/EventProcessing.res.mjs +165 -183
- package/src/EventUtils.res +11 -11
- package/src/EventUtils.res.mjs +21 -22
- package/src/EvmTypes.res +0 -1
- package/src/EvmTypes.res.mjs +5 -5
- package/src/FetchState.res +360 -256
- package/src/FetchState.res.mjs +958 -914
- package/src/GlobalState.res +365 -351
- package/src/GlobalState.res.mjs +958 -992
- package/src/GlobalStateManager.res +1 -2
- package/src/GlobalStateManager.res.mjs +36 -44
- package/src/HandlerLoader.res +107 -23
- package/src/HandlerLoader.res.mjs +128 -38
- package/src/HandlerRegister.res +127 -103
- package/src/HandlerRegister.res.mjs +164 -164
- package/src/HandlerRegister.resi +12 -4
- package/src/Hasura.res +35 -22
- package/src/Hasura.res.mjs +158 -167
- package/src/InMemoryStore.res +20 -27
- package/src/InMemoryStore.res.mjs +64 -80
- package/src/InMemoryTable.res +34 -39
- package/src/InMemoryTable.res.mjs +165 -170
- package/src/Internal.res +52 -33
- package/src/Internal.res.mjs +84 -81
- package/src/LazyLoader.res.mjs +55 -61
- package/src/LoadLayer.res +77 -78
- package/src/LoadLayer.res.mjs +160 -189
- package/src/LoadManager.res +16 -21
- package/src/LoadManager.res.mjs +79 -84
- package/src/LogSelection.res +236 -68
- package/src/LogSelection.res.mjs +211 -141
- package/src/Logging.res +13 -9
- package/src/Logging.res.mjs +130 -143
- package/src/Main.res +428 -51
- package/src/Main.res.mjs +528 -271
- package/src/Persistence.res +77 -84
- package/src/Persistence.res.mjs +131 -132
- package/src/PgStorage.res +291 -167
- package/src/PgStorage.res.mjs +797 -817
- package/src/Prometheus.res +50 -58
- package/src/Prometheus.res.mjs +345 -373
- package/src/ReorgDetection.res +22 -24
- package/src/ReorgDetection.res.mjs +100 -106
- package/src/SafeCheckpointTracking.res +7 -7
- package/src/SafeCheckpointTracking.res.mjs +40 -43
- package/src/SimulateItems.res +41 -49
- package/src/SimulateItems.res.mjs +257 -272
- package/src/Sink.res +2 -2
- package/src/Sink.res.mjs +22 -26
- package/src/TableIndices.res +1 -2
- package/src/TableIndices.res.mjs +42 -48
- package/src/TestIndexer.res +196 -189
- package/src/TestIndexer.res.mjs +536 -536
- package/src/TestIndexerProxyStorage.res +15 -16
- package/src/TestIndexerProxyStorage.res.mjs +98 -122
- package/src/TestIndexerWorker.res +4 -0
- package/src/TestIndexerWorker.res.mjs +7 -0
- package/src/Throttler.res +3 -3
- package/src/Throttler.res.mjs +23 -24
- package/src/Time.res +1 -1
- package/src/Time.res.mjs +18 -21
- package/src/TopicFilter.res +3 -3
- package/src/TopicFilter.res.mjs +29 -30
- package/src/UserContext.res +93 -54
- package/src/UserContext.res.mjs +197 -182
- package/src/Utils.res +141 -86
- package/src/Utils.res.mjs +334 -295
- package/src/bindings/BigDecimal.res +0 -2
- package/src/bindings/BigDecimal.res.mjs +19 -23
- package/src/bindings/ClickHouse.res +28 -27
- package/src/bindings/ClickHouse.res.mjs +243 -240
- package/src/bindings/DateFns.res +11 -11
- package/src/bindings/DateFns.res.mjs +7 -7
- package/src/bindings/EventSource.res.mjs +2 -2
- package/src/bindings/Express.res +2 -5
- package/src/bindings/Hrtime.res +2 -2
- package/src/bindings/Hrtime.res.mjs +30 -32
- package/src/bindings/Lodash.res.mjs +1 -1
- package/src/bindings/NodeJs.res +14 -9
- package/src/bindings/NodeJs.res.mjs +20 -20
- package/src/bindings/Pino.res +8 -10
- package/src/bindings/Pino.res.mjs +40 -43
- package/src/bindings/Postgres.res +2 -5
- package/src/bindings/Postgres.res.mjs +9 -9
- package/src/bindings/PromClient.res +17 -2
- package/src/bindings/PromClient.res.mjs +30 -7
- package/src/bindings/SDSL.res.mjs +2 -2
- package/src/bindings/Viem.res +4 -4
- package/src/bindings/Viem.res.mjs +20 -22
- package/src/bindings/Vitest.res +1 -1
- package/src/bindings/Vitest.res.mjs +2 -2
- package/src/bindings/WebSocket.res +1 -1
- package/src/db/EntityHistory.res +9 -3
- package/src/db/EntityHistory.res.mjs +84 -59
- package/src/db/InternalTable.res +62 -60
- package/src/db/InternalTable.res.mjs +271 -203
- package/src/db/Schema.res +1 -2
- package/src/db/Schema.res.mjs +28 -32
- package/src/db/Table.res +28 -27
- package/src/db/Table.res.mjs +276 -292
- package/src/sources/EventRouter.res +21 -16
- package/src/sources/EventRouter.res.mjs +55 -57
- package/src/sources/Evm.res +17 -1
- package/src/sources/Evm.res.mjs +16 -8
- package/src/sources/EvmChain.res +15 -17
- package/src/sources/EvmChain.res.mjs +40 -42
- package/src/sources/Fuel.res +14 -1
- package/src/sources/Fuel.res.mjs +16 -8
- package/src/sources/FuelSDK.res +1 -1
- package/src/sources/FuelSDK.res.mjs +6 -8
- package/src/sources/HyperFuel.res +8 -10
- package/src/sources/HyperFuel.res.mjs +113 -123
- package/src/sources/HyperFuelClient.res.mjs +6 -7
- package/src/sources/HyperFuelSource.res +19 -20
- package/src/sources/HyperFuelSource.res.mjs +339 -356
- package/src/sources/HyperSync.res +11 -13
- package/src/sources/HyperSync.res.mjs +206 -220
- package/src/sources/HyperSyncClient.res +5 -7
- package/src/sources/HyperSyncClient.res.mjs +70 -75
- package/src/sources/HyperSyncHeightStream.res +8 -9
- package/src/sources/HyperSyncHeightStream.res.mjs +78 -86
- package/src/sources/HyperSyncJsonApi.res +18 -15
- package/src/sources/HyperSyncJsonApi.res.mjs +201 -231
- package/src/sources/HyperSyncSource.res +17 -21
- package/src/sources/HyperSyncSource.res.mjs +268 -290
- package/src/sources/Rpc.res +5 -5
- package/src/sources/Rpc.res.mjs +168 -192
- package/src/sources/RpcSource.res +166 -167
- package/src/sources/RpcSource.res.mjs +972 -1046
- package/src/sources/RpcWebSocketHeightStream.res +10 -11
- package/src/sources/RpcWebSocketHeightStream.res.mjs +131 -145
- package/src/sources/SimulateSource.res +1 -1
- package/src/sources/SimulateSource.res.mjs +35 -38
- package/src/sources/Source.res +1 -1
- package/src/sources/Source.res.mjs +3 -3
- package/src/sources/SourceManager.res +39 -20
- package/src/sources/SourceManager.res.mjs +340 -371
- package/src/sources/SourceManager.resi +2 -1
- package/src/sources/Svm.res +12 -5
- package/src/sources/Svm.res.mjs +44 -41
- package/src/tui/Tui.res +23 -12
- package/src/tui/Tui.res.mjs +292 -290
- package/src/tui/bindings/Ink.res +2 -4
- package/src/tui/bindings/Ink.res.mjs +35 -41
- package/src/tui/components/BufferedProgressBar.res +7 -7
- package/src/tui/components/BufferedProgressBar.res.mjs +46 -46
- package/src/tui/components/CustomHooks.res +1 -2
- package/src/tui/components/CustomHooks.res.mjs +102 -122
- package/src/tui/components/Messages.res +1 -2
- package/src/tui/components/Messages.res.mjs +38 -42
- package/src/tui/components/SyncETA.res +10 -11
- package/src/tui/components/SyncETA.res.mjs +178 -196
- package/src/tui/components/TuiData.res +1 -1
- package/src/tui/components/TuiData.res.mjs +7 -6
- package/src/vendored/Rest.res +52 -66
- package/src/vendored/Rest.res.mjs +324 -364
- package/svm.schema.json +67 -0
- package/src/Address.gen.ts +0 -8
- package/src/Config.gen.ts +0 -19
- package/src/Envio.gen.ts +0 -55
- package/src/EvmTypes.gen.ts +0 -6
- package/src/InMemoryStore.gen.ts +0 -6
- package/src/Internal.gen.ts +0 -64
- package/src/PgStorage.gen.ts +0 -10
- package/src/PgStorage.res.d.mts +0 -5
- package/src/Types.ts +0 -56
- package/src/bindings/BigDecimal.gen.ts +0 -14
- package/src/bindings/BigDecimal.res.d.mts +0 -5
- package/src/bindings/BigInt.gen.ts +0 -10
- package/src/bindings/BigInt.res +0 -70
- package/src/bindings/BigInt.res.d.mts +0 -5
- package/src/bindings/BigInt.res.mjs +0 -154
- package/src/bindings/Ethers.res.d.mts +0 -5
- package/src/bindings/Pino.gen.ts +0 -17
- package/src/bindings/Postgres.gen.ts +0 -8
- package/src/bindings/Postgres.res.d.mts +0 -5
- package/src/bindings/Promise.res +0 -67
- package/src/bindings/Promise.res.mjs +0 -26
- package/src/db/InternalTable.gen.ts +0 -36
- 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
|
+
}
|
package/src/Core.res.mjs
ADDED
|
@@ -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:
|
|
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 =
|
|
21
|
-
blockEvent->
|
|
22
|
-
{block: blockEvent->(Utils.magic:
|
|
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
|
}
|
package/src/Ecosystem.res.mjs
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
4
4
|
|
|
5
5
|
function makeOnBlockArgs(blockNumber, ecosystem, context) {
|
|
6
|
-
|
|
6
|
+
let match = ecosystem.name;
|
|
7
7
|
switch (match) {
|
|
8
8
|
case "evm" :
|
|
9
9
|
case "fuel" :
|
|
10
|
-
|
|
10
|
+
break;
|
|
11
11
|
case "svm" :
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
return {
|
|
13
|
+
slot: blockNumber,
|
|
14
|
+
context: context
|
|
15
|
+
};
|
|
17
16
|
}
|
|
18
|
-
|
|
17
|
+
let blockEvent = {};
|
|
19
18
|
blockEvent[ecosystem.blockNumberName] = blockNumber;
|
|
20
19
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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->
|
|
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->
|
|
175
|
+
switch string->String.split("&") {
|
|
169
176
|
| []
|
|
170
177
|
| [_] =>
|
|
171
178
|
s.fail(`Provide an array of entities in the JSON format.`)
|