envio 3.13.0 → 3.14.0-subgraph
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.mjs +10 -1
- package/index.d.ts +11 -0
- package/package.json +8 -20
- package/rescript.json +1 -4
- package/src/Config.res +78 -100
- package/src/Config.res.mjs +55 -64
- package/src/Core.res +67 -6
- package/src/Core.res.mjs +58 -4
- package/src/EventConfigBuilder.res +4 -10
- package/src/EventConfigBuilder.res.mjs +1 -3
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +8 -6
- package/src/ExitOnCaughtUp.res +5 -1
- package/src/ExitOnCaughtUp.res.mjs +8 -3
- package/src/HandlerLoader.res +98 -36
- package/src/HandlerLoader.res.mjs +89 -24
- package/src/HandlerTypeCheck.mjs +14 -0
- package/src/HandlerTypeCheckWorker.mjs +68 -0
- package/src/Internal.res +1 -1
- package/src/LoadLayer.res +39 -7
- package/src/LoadLayer.res.mjs +65 -38
- package/src/LoadLayer.resi +28 -0
- package/src/Main.res +17 -12
- package/src/Main.res.mjs +9 -3
- package/src/NodeVersion.mjs +13 -0
- package/src/Persistence.res +79 -38
- package/src/Persistence.res.mjs +41 -10
- package/src/PgStorage.res +86 -39
- package/src/PgStorage.res.mjs +83 -32
- package/src/ResumePlan.res +172 -0
- package/src/ResumePlan.res.mjs +122 -0
- package/src/Supervisor.res +8 -8
- package/src/Supervisor.res.mjs +6 -1
- package/src/SyncWrites.res +86 -0
- package/src/SyncWrites.res.mjs +85 -0
- package/src/TestIndexer.res +14 -4
- package/src/TestIndexer.res.mjs +3 -2
- package/src/TsModuleHooks.mjs +121 -0
- package/src/UserContext.res +377 -62
- package/src/UserContext.res.mjs +297 -39
- package/src/Utils.res +0 -8
- package/src/Worker.res +8 -0
- package/src/Worker.res.mjs +11 -0
- package/src/bindings/NodeJs.res +8 -7
- package/src/bindings/NodeJs.res.mjs +0 -3
- package/src/bindings/Pino.res +2 -2
- package/src/db/InternalTable.res +52 -2
- package/src/db/InternalTable.res.mjs +32 -3
- package/src/db/Table.res +10 -0
- package/src/db/Table.res.mjs +22 -11
- package/src/sources/FuelHyperSync.res +2 -0
- package/src/sources/FuelHyperSync.res.mjs +1 -0
- package/src/sources/FuelHyperSync.resi +1 -0
- package/src/sources/FuelHyperSyncClient.res +25 -8
- package/src/sources/FuelHyperSyncClient.res.mjs +8 -2
- package/src/sources/FuelHyperSyncSource.res +24 -22
- package/src/sources/FuelHyperSyncSource.res.mjs +18 -13
- package/src/subgraph/abi-types.ts +63 -0
- package/src/subgraph/assemblyscript.ts +85 -0
- package/src/subgraph/blocks.ts +183 -0
- package/src/subgraph/calls.ts +149 -0
- package/src/subgraph/conformance.ts +83 -0
- package/src/subgraph/errors.ts +96 -0
- package/src/subgraph/graph-cli-worker.mjs +26 -0
- package/src/subgraph/graph-cli.ts +190 -0
- package/src/subgraph/graph-ts-enums.ts +28 -0
- package/src/subgraph/graph-ts-types/VERSION +2 -0
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
- package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
- package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
- package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
- package/src/subgraph/graph-ts-types/index.d.ts +102 -0
- package/src/subgraph/graph-ts.ts +2285 -0
- package/src/subgraph/hosts.ts +158 -0
- package/src/subgraph/rpc.ts +65 -0
- package/src/subgraph/runtime.ts +595 -0
- package/src/subgraph/scope.ts +68 -0
- package/src/tui/InitApi.res +85 -0
- package/src/tui/{components/CustomHooks.res.mjs → InitApi.res.mjs} +11 -64
- package/src/tui/Tui.res +142 -249
- package/src/tui/Tui.res.mjs +123 -332
- package/src/Js.shim.ts +0 -11
- package/src/bindings/DateFns.res +0 -74
- package/src/bindings/DateFns.res.mjs +0 -22
- package/src/sources/FuelSDK.res +0 -38
- package/src/sources/FuelSDK.res.mjs +0 -27
- package/src/sources/vendored-fuel-abi-coder.js +0 -1792
- package/src/tui/bindings/Ink.res +0 -369
- package/src/tui/bindings/Ink.res.mjs +0 -66
- package/src/tui/bindings/Style.res +0 -123
- package/src/tui/bindings/Style.res.mjs +0 -2
- package/src/tui/components/BufferedProgressBar.res +0 -40
- package/src/tui/components/BufferedProgressBar.res.mjs +0 -57
- package/src/tui/components/CustomHooks.res +0 -122
- package/src/tui/components/Messages.res +0 -40
- package/src/tui/components/Messages.res.mjs +0 -71
- package/src/tui/components/SyncETA.res +0 -179
- package/src/tui/components/SyncETA.res.mjs +0 -249
- package/src/tui/components/TuiData.res +0 -98
- package/src/tui/components/TuiData.res.mjs +0 -73
package/bin.mjs
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { unsupportedNodeMessage } from "./src/NodeVersion.mjs";
|
|
3
|
+
|
|
4
|
+
// Checked before the rest loads, which an older Node may not even parse.
|
|
5
|
+
const unsupported = unsupportedNodeMessage();
|
|
6
|
+
if (unsupported !== undefined) {
|
|
7
|
+
console.error(unsupported);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { run } = await import("./src/Bin.res.mjs");
|
|
3
12
|
await run(process.argv.slice(2));
|
package/index.d.ts
CHANGED
|
@@ -12,6 +12,17 @@ declare const bigintSchema: Sury.Schema<bigint>;
|
|
|
12
12
|
/** Ethereum address — a 20-byte hex string prefixed with `0x`. */
|
|
13
13
|
export type Address = `0x${string}`;
|
|
14
14
|
|
|
15
|
+
/** A value a `Json` entity field can hold. A `bigint` isn't JSON — store its
|
|
16
|
+
* decimal string with `.toString()`. Shadows the global `JSON` interface only
|
|
17
|
+
* where imported; the `JSON` object itself is unaffected. */
|
|
18
|
+
export type JSON =
|
|
19
|
+
| string
|
|
20
|
+
| number
|
|
21
|
+
| boolean
|
|
22
|
+
| null
|
|
23
|
+
| readonly JSON[]
|
|
24
|
+
| { readonly [key: string]: JSON };
|
|
25
|
+
|
|
15
26
|
/** Structured logger bound to an event or handler context. Messages are
|
|
16
27
|
* displayed in the console and the Envio Hosted Service. */
|
|
17
28
|
export type Logger = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.14.0-subgraph",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.mjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dapp"
|
|
28
28
|
],
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=22.
|
|
30
|
+
"node": ">=22.15.0"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"bin.mjs",
|
|
@@ -42,11 +42,6 @@
|
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@elastic/ecs-pino-format": "1.4.0",
|
|
45
|
-
"@fuel-ts/crypto": "0.96.1",
|
|
46
|
-
"@fuel-ts/errors": "0.96.1",
|
|
47
|
-
"@fuel-ts/hasher": "0.96.1",
|
|
48
|
-
"@fuel-ts/math": "0.96.1",
|
|
49
|
-
"@fuel-ts/utils": "0.96.1",
|
|
50
45
|
"bignumber.js": "9.3.1",
|
|
51
46
|
"eventsource": "4.1.0",
|
|
52
47
|
"express": "4.19.2",
|
|
@@ -56,20 +51,13 @@
|
|
|
56
51
|
"rescript-schema": "9.5.1",
|
|
57
52
|
"viem": "2.54.0",
|
|
58
53
|
"dotenv": "16.4.5",
|
|
59
|
-
"
|
|
60
|
-
"@rescript/react": "0.14.1",
|
|
61
|
-
"react": "19.2.5",
|
|
62
|
-
"ink": "6.8.0",
|
|
63
|
-
"ink-big-text": "2.0.0",
|
|
64
|
-
"ink-spinner": "5.0.0",
|
|
65
|
-
"postgres": "3.4.8",
|
|
66
|
-
"tsx": "4.21.0"
|
|
54
|
+
"postgres": "3.4.8"
|
|
67
55
|
},
|
|
68
56
|
"optionalDependencies": {
|
|
69
|
-
"envio-linux-x64": "3.
|
|
70
|
-
"envio-linux-x64-musl": "3.
|
|
71
|
-
"envio-linux-arm64": "3.
|
|
72
|
-
"envio-darwin-x64": "3.
|
|
73
|
-
"envio-darwin-arm64": "3.
|
|
57
|
+
"envio-linux-x64": "3.14.0-subgraph",
|
|
58
|
+
"envio-linux-x64-musl": "3.14.0-subgraph",
|
|
59
|
+
"envio-linux-arm64": "3.14.0-subgraph",
|
|
60
|
+
"envio-darwin-x64": "3.14.0-subgraph",
|
|
61
|
+
"envio-darwin-arm64": "3.14.0-subgraph"
|
|
74
62
|
}
|
|
75
63
|
}
|
package/rescript.json
CHANGED
|
@@ -12,10 +12,7 @@
|
|
|
12
12
|
"module": "esmodule",
|
|
13
13
|
"in-source": true
|
|
14
14
|
},
|
|
15
|
-
"
|
|
16
|
-
"version": 4
|
|
17
|
-
},
|
|
18
|
-
"dependencies": ["rescript-schema", "@rescript/react"],
|
|
15
|
+
"dependencies": ["rescript-schema"],
|
|
19
16
|
"compiler-flags": ["-open RescriptSchema"],
|
|
20
17
|
"warnings": {
|
|
21
18
|
"error": "+a"
|
package/src/Config.res
CHANGED
|
@@ -136,6 +136,9 @@ type t = {
|
|
|
136
136
|
reorgThresholdReadyTolerance: int,
|
|
137
137
|
lowercaseAddresses: bool,
|
|
138
138
|
isDev: bool,
|
|
139
|
+
// The operator's `-d` / `--config` flags, repeated in every command printed
|
|
140
|
+
// for them to run next. Empty when they gave neither.
|
|
141
|
+
projectFlags: string,
|
|
139
142
|
// An `envio start --chain` process: drives a subset of the schema's chains
|
|
140
143
|
// while sibling processes drive the rest, so it only touches what its own
|
|
141
144
|
// chains own — their partitions' indexes, their `ready_at`, their resume.
|
|
@@ -147,6 +150,10 @@ type t = {
|
|
|
147
150
|
// the schema alone: a cross-chain entity has rows any chain's reorg can
|
|
148
151
|
// reach, so its checkpoints have to be comparable across chains.
|
|
149
152
|
checkpointSequence: CheckpointSequence.t,
|
|
153
|
+
envioInfo: JSON.t,
|
|
154
|
+
// Set only in subgraph mode: the translated manifest, which is what makes
|
|
155
|
+
// the subgraph runtime take over handler registration.
|
|
156
|
+
subgraph: option<JSON.t>,
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
type rpcSourceFor = | @as("sync") Sync | @as("fallback") Fallback | @as("realtime") Realtime
|
|
@@ -595,6 +602,7 @@ let publicConfigSchema = S.schema(s =>
|
|
|
595
602
|
"handlers": s.matches(S.option(S.string)),
|
|
596
603
|
"isDev": s.matches(S.option(S.bool)),
|
|
597
604
|
"isolatedChains": s.matches(S.option(S.array(ChainId.schema))),
|
|
605
|
+
"projectFlags": s.matches(S.option(S.string)),
|
|
598
606
|
"fullBatchSize": s.matches(S.option(S.int)),
|
|
599
607
|
"rollbackOnReorg": s.matches(S.option(S.bool)),
|
|
600
608
|
"saveFullHistory": s.matches(S.option(S.bool)),
|
|
@@ -607,6 +615,7 @@ let publicConfigSchema = S.schema(s =>
|
|
|
607
615
|
"svm": s.matches(S.option(publicConfigEcosystemSchema)),
|
|
608
616
|
"enums": s.matches(S.option(S.dict(S.array(S.string)))),
|
|
609
617
|
"entities": s.matches(S.option(S.array(entityJsonSchema))),
|
|
618
|
+
"subgraph": s.matches(S.option(S.json(~validate=false))),
|
|
610
619
|
}
|
|
611
620
|
)
|
|
612
621
|
|
|
@@ -666,6 +675,45 @@ let isolate = (config: t, ~chainIds: array<ChainId.t>) => {
|
|
|
666
675
|
}
|
|
667
676
|
}
|
|
668
677
|
|
|
678
|
+
// What the command decided rather than the project's files: `envio dev` vs
|
|
679
|
+
// `envio start`, which chains this process drives, and how it found the
|
|
680
|
+
// project.
|
|
681
|
+
let commandFields = ["isDev", "isolatedChains", "projectFlags"]
|
|
682
|
+
|
|
683
|
+
let withProjectFlags = (command, ~config: t) =>
|
|
684
|
+
switch config.projectFlags {
|
|
685
|
+
| "" => command
|
|
686
|
+
| flags => `${command} ${flags}`
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
let ecosystemFields = ["evm", "fuel", "svm"]
|
|
690
|
+
|
|
691
|
+
// What `envio_info` records: the public config without the command's fields
|
|
692
|
+
// or its chains. A chain is recorded by its own `envio_chains` row and its
|
|
693
|
+
// config's `envio_addresses` rows instead, so adding one never rewrites this
|
|
694
|
+
// record. The rest of a chain's config — its sources, its block lag, a
|
|
695
|
+
// contract's start block — is read from config.yaml on every start.
|
|
696
|
+
let toEnvioInfo = (publicConfigJson: JSON.t): JSON.t => {
|
|
697
|
+
let envioInfo = publicConfigJson->JSON.stringify->JSON.parseOrThrow
|
|
698
|
+
switch envioInfo {
|
|
699
|
+
| Object(obj) => {
|
|
700
|
+
commandFields->Array.forEach(field => obj->Utils.Dict.deleteInPlace(field))
|
|
701
|
+
// The subgraph blob is how the runtime finds mappings. None of it
|
|
702
|
+
// describes stored data — that's already in `evm` / `entities` — so a
|
|
703
|
+
// specVersion bump or a mapping-path edit must not force a reset.
|
|
704
|
+
obj->Utils.Dict.deleteInPlace("subgraph")
|
|
705
|
+
ecosystemFields->Array.forEach(ecosystem =>
|
|
706
|
+
switch obj->Dict.get(ecosystem) {
|
|
707
|
+
| Some(Object(ecosystemDict)) => ecosystemDict->Utils.Dict.deleteInPlace("chains")
|
|
708
|
+
| _ => ()
|
|
709
|
+
}
|
|
710
|
+
)
|
|
711
|
+
}
|
|
712
|
+
| _ => ()
|
|
713
|
+
}
|
|
714
|
+
envioInfo
|
|
715
|
+
}
|
|
716
|
+
|
|
669
717
|
let fromPublic = (publicConfigJson: JSON.t) => {
|
|
670
718
|
let maxAddrInPartition = Env.maxAddrInPartition
|
|
671
719
|
// Parse public config
|
|
@@ -1136,11 +1184,14 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
1136
1184
|
reorgThresholdReadyTolerance: 100,
|
|
1137
1185
|
lowercaseAddresses,
|
|
1138
1186
|
isDev: publicConfig["isDev"]->Option.getOr(false),
|
|
1187
|
+
projectFlags: publicConfig["projectFlags"]->Option.getOr(""),
|
|
1139
1188
|
isolated: false,
|
|
1140
1189
|
userEntitiesByName,
|
|
1141
1190
|
userEntities,
|
|
1142
1191
|
allEnums,
|
|
1143
1192
|
checkpointSequence: CheckpointSequence.fromEntities(userEntities),
|
|
1193
|
+
envioInfo: publicConfigJson->toEnvioInfo,
|
|
1194
|
+
subgraph: publicConfig["subgraph"],
|
|
1144
1195
|
}
|
|
1145
1196
|
|
|
1146
1197
|
switch publicConfig["isolatedChains"] {
|
|
@@ -1255,49 +1306,6 @@ let getPublicConfigJson = () =>
|
|
|
1255
1306
|
| None => Core.getConfigJson()->JSON.parseOrThrow
|
|
1256
1307
|
}
|
|
1257
1308
|
|
|
1258
|
-
// Drops source URLs from each chain so RPC/hypersync edits don't trigger
|
|
1259
|
-
// the resume-time compat check (and don't end up in `envio_info`). Also
|
|
1260
|
-
// drops `isDev`, which toggles between `envio dev` and `envio start` and
|
|
1261
|
-
// has no bearing on schema/indexing compatibility.
|
|
1262
|
-
let stripSensitiveData = (json: JSON.t): JSON.t => {
|
|
1263
|
-
let cloned = json->JSON.stringify->JSON.parseOrThrow
|
|
1264
|
-
let stripChains = (ecosystem: option<JSON.t>) =>
|
|
1265
|
-
switch ecosystem {
|
|
1266
|
-
| Some(Object(ecosystemDict)) =>
|
|
1267
|
-
switch ecosystemDict->Dict.get("chains") {
|
|
1268
|
-
| Some(Object(chains)) =>
|
|
1269
|
-
chains
|
|
1270
|
-
->Dict.valuesToArray
|
|
1271
|
-
->Array.forEach(chainJson =>
|
|
1272
|
-
switch chainJson {
|
|
1273
|
-
| Object(chain) => {
|
|
1274
|
-
chain->Utils.Dict.deleteInPlace("rpcs")
|
|
1275
|
-
chain->Utils.Dict.deleteInPlace("hypersync")
|
|
1276
|
-
}
|
|
1277
|
-
| _ => ()
|
|
1278
|
-
}
|
|
1279
|
-
)
|
|
1280
|
-
| _ => ()
|
|
1281
|
-
}
|
|
1282
|
-
| _ => ()
|
|
1283
|
-
}
|
|
1284
|
-
switch cloned {
|
|
1285
|
-
| Object(obj) => {
|
|
1286
|
-
obj->Utils.Dict.deleteInPlace("isDev")
|
|
1287
|
-
obj->Utils.Dict.deleteInPlace("isolatedChains")
|
|
1288
|
-
stripChains(obj->Dict.get("evm"))
|
|
1289
|
-
stripChains(obj->Dict.get("fuel"))
|
|
1290
|
-
stripChains(obj->Dict.get("svm"))
|
|
1291
|
-
}
|
|
1292
|
-
| _ => ()
|
|
1293
|
-
}
|
|
1294
|
-
cloned
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
// What the storage layer records as the config this schema was built from,
|
|
1298
|
-
// and checks a resuming run against.
|
|
1299
|
-
let envioInfo = () => getPublicConfigJson()->stripSensitiveData
|
|
1300
|
-
|
|
1301
1309
|
// Postgres jsonb doesn't preserve key order, so canonicalize with sorted
|
|
1302
1310
|
// keys before string-comparing.
|
|
1303
1311
|
let rec canonicalJson = (json: JSON.t): JSON.t =>
|
|
@@ -1317,9 +1325,10 @@ let rec canonicalJson = (json: JSON.t): JSON.t =>
|
|
|
1317
1325
|
// Returns dotted leaf paths (`a.b[i].c`) where `stored` differs from
|
|
1318
1326
|
// `current`, restricted to the highest-priority top-level tier with any
|
|
1319
1327
|
// diff. Tiers in order: version → name → storage → ecosystem
|
|
1320
|
-
// (evm/fuel/svm
|
|
1321
|
-
// containing a diff is the only one
|
|
1322
|
-
// so a single noisy section doesn't bury
|
|
1328
|
+
// (evm/fuel/svm, and the chains a resume puts beside them) → entities →
|
|
1329
|
+
// other top-level keys. The first tier containing a diff is the only one
|
|
1330
|
+
// rendered; lower tiers are silenced so a single noisy section doesn't bury
|
|
1331
|
+
// the actionable change.
|
|
1323
1332
|
let diffPaths = (~stored: JSON.t, ~current: JSON.t): array<string> => {
|
|
1324
1333
|
let canonEq = (a: JSON.t, b: JSON.t) =>
|
|
1325
1334
|
JSON.stringify(canonicalJson(a)) === JSON.stringify(canonicalJson(b))
|
|
@@ -1387,7 +1396,7 @@ let diffPaths = (~stored: JSON.t, ~current: JSON.t): array<string> => {
|
|
|
1387
1396
|
["chainIdMode"],
|
|
1388
1397
|
["name"],
|
|
1389
1398
|
["storage"],
|
|
1390
|
-
["evm", "fuel", "svm"],
|
|
1399
|
+
["evm", "fuel", "svm", "chains"],
|
|
1391
1400
|
["entities"],
|
|
1392
1401
|
]
|
|
1393
1402
|
let firstHit = tiers->Array.reduce(None, (acc, tier) =>
|
|
@@ -1417,65 +1426,34 @@ let diffPaths = (~stored: JSON.t, ~current: JSON.t): array<string> => {
|
|
|
1417
1426
|
acc
|
|
1418
1427
|
}
|
|
1419
1428
|
|
|
1420
|
-
//
|
|
1421
|
-
//
|
|
1422
|
-
//
|
|
1423
|
-
//
|
|
1424
|
-
//
|
|
1425
|
-
//
|
|
1426
|
-
//
|
|
1427
|
-
let
|
|
1429
|
+
// The `incompatible config` error listing each path in `changedPaths`, plus
|
|
1430
|
+
// the remediation options. `~resetCommand` is rendered as-is for option 2
|
|
1431
|
+
// (the wipe-and-redo). `~runCommand` controls option 3 (parallel indexer
|
|
1432
|
+
// recipe): when `None`, option 3 is omitted — the migrate flow uses this
|
|
1433
|
+
// because running a second indexer doesn't apply. `~hasClickhouse` adds the
|
|
1434
|
+
// extra env line so users running both Postgres and Clickhouse get a complete
|
|
1435
|
+
// override.
|
|
1436
|
+
let incompatibleMessage = (
|
|
1428
1437
|
changedPaths: array<string>,
|
|
1429
1438
|
~resetCommand: string,
|
|
1430
1439
|
~runCommand: option<string>,
|
|
1431
1440
|
~hasClickhouse: bool,
|
|
1432
1441
|
) => {
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
`\n 3. Run a second indexer alongside this one — keep both datasets:\n ENVIO_PG_SCHEMA=<new_schema> \\\n${clickhouseLine} ENVIO_INDEXER_PORT=<new_port> \\\n ${cmd}`
|
|
1443
|
-
}
|
|
1444
|
-
JsError.throwWithMessage(
|
|
1445
|
-
`The following config changes are incompatible with the existing indexer data:\n\n${bullets}\n\nPick one:\n 1. ${option1->padTo(
|
|
1446
|
-
col,
|
|
1447
|
-
)}# resume indexing where it left off\n 2. ${resetCommand->padTo(
|
|
1448
|
-
col,
|
|
1449
|
-
)}# delete all indexed data and start over${option3}`,
|
|
1450
|
-
)
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
let throwIfResumeIncompatible = (
|
|
1455
|
-
~storedEnvioInfo: option<JSON.t>,
|
|
1456
|
-
~storedContractMapping: ContractMapping.t,
|
|
1457
|
-
~envioInfo: JSON.t,
|
|
1458
|
-
~contractMapping: ContractMapping.t,
|
|
1459
|
-
~resetCommand: string,
|
|
1460
|
-
~runCommand: option<string>,
|
|
1461
|
-
) => {
|
|
1462
|
-
let changedPaths = switch storedEnvioInfo {
|
|
1463
|
-
| None => ["storage was initialized by an older envio version"]
|
|
1464
|
-
| Some(stored) => diffPaths(~stored, ~current=envioInfo)
|
|
1465
|
-
}
|
|
1466
|
-
let changedPaths =
|
|
1467
|
-
storedContractMapping->ContractMapping.isEqual(contractMapping)
|
|
1468
|
-
? changedPaths
|
|
1469
|
-
: changedPaths->Array.concat(["contracts"])
|
|
1470
|
-
let hasClickhouse = switch envioInfo {
|
|
1471
|
-
| Object(d) =>
|
|
1472
|
-
switch d->Dict.get("storage") {
|
|
1473
|
-
| Some(Object(s)) => s->Dict.get("clickhouse") == Some(Boolean(true))
|
|
1474
|
-
| _ => false
|
|
1475
|
-
}
|
|
1476
|
-
| _ => false
|
|
1442
|
+
let bullets = changedPaths->Array.map(p => ` - ${p}`)->Array.joinUnsafe("\n")
|
|
1443
|
+
let option1 = "Revert the changes above"
|
|
1444
|
+
let padTo = (s, col) => s ++ " "->String.repeat(Math.Int.max(col - String.length(s), 1))
|
|
1445
|
+
let col = Math.Int.max(String.length(option1), String.length(resetCommand)) + 2
|
|
1446
|
+
let option3 = switch runCommand {
|
|
1447
|
+
| None => ""
|
|
1448
|
+
| Some(cmd) =>
|
|
1449
|
+
let clickhouseLine = hasClickhouse ? " ENVIO_CLICKHOUSE_DATABASE=<new_db> \\\n" : ""
|
|
1450
|
+
`\n 3. Run a second indexer alongside this one — keep both datasets:\n ENVIO_PG_SCHEMA=<new_schema> \\\n${clickhouseLine} ENVIO_INDEXER_PORT=<new_port> \\\n ${cmd}`
|
|
1477
1451
|
}
|
|
1478
|
-
|
|
1452
|
+
`The following config changes are incompatible with the existing indexer data:\n\n${bullets}\n\nPick one:\n 1. ${option1->padTo(
|
|
1453
|
+
col,
|
|
1454
|
+
)}# resume indexing where it left off\n 2. ${resetCommand->padTo(
|
|
1455
|
+
col,
|
|
1456
|
+
)}# delete all indexed data and start over${option3}`
|
|
1479
1457
|
}
|
|
1480
1458
|
|
|
1481
1459
|
// The returned value is a pure function of the JSON: it holds only event
|
package/src/Config.res.mjs
CHANGED
|
@@ -18,7 +18,6 @@ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
|
18
18
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
19
19
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
20
20
|
import * as ContractMapping from "./ContractMapping.res.mjs";
|
|
21
|
-
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
22
21
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
23
22
|
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
24
23
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
@@ -439,6 +438,7 @@ let publicConfigSchema = S$RescriptSchema.schema(s => ({
|
|
|
439
438
|
handlers: s.m(S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
440
439
|
isDev: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
441
440
|
isolatedChains: s.m(S$RescriptSchema.option(S$RescriptSchema.array(ChainId.schema))),
|
|
441
|
+
projectFlags: s.m(S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
442
442
|
fullBatchSize: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
443
443
|
rollbackOnReorg: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
444
444
|
saveFullHistory: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
@@ -450,7 +450,8 @@ let publicConfigSchema = S$RescriptSchema.schema(s => ({
|
|
|
450
450
|
fuel: s.m(S$RescriptSchema.option(publicConfigEcosystemSchema)),
|
|
451
451
|
svm: s.m(S$RescriptSchema.option(publicConfigEcosystemSchema)),
|
|
452
452
|
enums: s.m(S$RescriptSchema.option(S$RescriptSchema.dict(S$RescriptSchema.array(S$RescriptSchema.string)))),
|
|
453
|
-
entities: s.m(S$RescriptSchema.option(S$RescriptSchema.array(entityJsonSchema)))
|
|
453
|
+
entities: s.m(S$RescriptSchema.option(S$RescriptSchema.array(entityJsonSchema))),
|
|
454
|
+
subgraph: s.m(S$RescriptSchema.option(S$RescriptSchema.json(false)))
|
|
454
455
|
}));
|
|
455
456
|
|
|
456
457
|
function contractMappingOf(chainConfigs) {
|
|
@@ -495,6 +496,42 @@ function isolate(config, chainIds) {
|
|
|
495
496
|
return newrecord;
|
|
496
497
|
}
|
|
497
498
|
|
|
499
|
+
let commandFields = [
|
|
500
|
+
"isDev",
|
|
501
|
+
"isolatedChains",
|
|
502
|
+
"projectFlags"
|
|
503
|
+
];
|
|
504
|
+
|
|
505
|
+
function withProjectFlags(command, config) {
|
|
506
|
+
let flags = config.projectFlags;
|
|
507
|
+
if (flags === "") {
|
|
508
|
+
return command;
|
|
509
|
+
} else {
|
|
510
|
+
return command + ` ` + flags;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
let ecosystemFields = [
|
|
515
|
+
"evm",
|
|
516
|
+
"fuel",
|
|
517
|
+
"svm"
|
|
518
|
+
];
|
|
519
|
+
|
|
520
|
+
function toEnvioInfo(publicConfigJson) {
|
|
521
|
+
let envioInfo = JSON.parse(JSON.stringify(publicConfigJson));
|
|
522
|
+
if (typeof envioInfo === "object" && envioInfo !== null && !Array.isArray(envioInfo)) {
|
|
523
|
+
commandFields.forEach(field => Utils.Dict.deleteInPlace(envioInfo, field));
|
|
524
|
+
Utils.Dict.deleteInPlace(envioInfo, "subgraph");
|
|
525
|
+
ecosystemFields.forEach(ecosystem => {
|
|
526
|
+
let match = envioInfo[ecosystem];
|
|
527
|
+
if (typeof match === "object" && match !== null && !Array.isArray(match)) {
|
|
528
|
+
return Utils.Dict.deleteInPlace(match, "chains");
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
return envioInfo;
|
|
533
|
+
}
|
|
534
|
+
|
|
498
535
|
function fromPublic(publicConfigJson) {
|
|
499
536
|
let publicConfig;
|
|
500
537
|
try {
|
|
@@ -801,7 +838,10 @@ function fromPublic(publicConfigJson) {
|
|
|
801
838
|
let config_enableRawEvents = Stdlib_Option.getOr(publicConfig.rawEvents, false);
|
|
802
839
|
let config_batchSize = Stdlib_Option.getOr(publicConfig.fullBatchSize, 5000);
|
|
803
840
|
let config_isDev = Stdlib_Option.getOr(publicConfig.isDev, false);
|
|
841
|
+
let config_projectFlags = Stdlib_Option.getOr(publicConfig.projectFlags, "");
|
|
804
842
|
let config_checkpointSequence = CheckpointSequence.fromEntities(userEntities);
|
|
843
|
+
let config_envioInfo = toEnvioInfo(publicConfigJson);
|
|
844
|
+
let config_subgraph = publicConfig.subgraph;
|
|
805
845
|
let config = {
|
|
806
846
|
name: config_name,
|
|
807
847
|
description: config_description,
|
|
@@ -823,11 +863,14 @@ function fromPublic(publicConfigJson) {
|
|
|
823
863
|
reorgThresholdReadyTolerance: 100,
|
|
824
864
|
lowercaseAddresses: lowercaseAddresses,
|
|
825
865
|
isDev: config_isDev,
|
|
866
|
+
projectFlags: config_projectFlags,
|
|
826
867
|
isolated: false,
|
|
827
868
|
userEntitiesByName: userEntitiesByName,
|
|
828
869
|
userEntities: userEntities,
|
|
829
870
|
allEnums: allEnums,
|
|
830
|
-
checkpointSequence: config_checkpointSequence
|
|
871
|
+
checkpointSequence: config_checkpointSequence,
|
|
872
|
+
envioInfo: config_envioInfo,
|
|
873
|
+
subgraph: config_subgraph
|
|
831
874
|
};
|
|
832
875
|
let chainIds = publicConfig.isolatedChains;
|
|
833
876
|
if (chainIds !== undefined) {
|
|
@@ -933,44 +976,6 @@ function getPublicConfigJson() {
|
|
|
933
976
|
}
|
|
934
977
|
}
|
|
935
978
|
|
|
936
|
-
function stripSensitiveData(json) {
|
|
937
|
-
let cloned = JSON.parse(JSON.stringify(json));
|
|
938
|
-
let stripChains = ecosystem => {
|
|
939
|
-
if (ecosystem === undefined) {
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
if (typeof ecosystem !== "object" || ecosystem === null || Array.isArray(ecosystem)) {
|
|
943
|
-
return;
|
|
944
|
-
}
|
|
945
|
-
let match = ecosystem["chains"];
|
|
946
|
-
if (match === undefined) {
|
|
947
|
-
return;
|
|
948
|
-
}
|
|
949
|
-
if (typeof match !== "object" || match === null || Array.isArray(match)) {
|
|
950
|
-
return;
|
|
951
|
-
}
|
|
952
|
-
Object.values(match).forEach(chainJson => {
|
|
953
|
-
if (typeof chainJson !== "object" || chainJson === null || Array.isArray(chainJson)) {
|
|
954
|
-
return;
|
|
955
|
-
}
|
|
956
|
-
Utils.Dict.deleteInPlace(chainJson, "rpcs");
|
|
957
|
-
Utils.Dict.deleteInPlace(chainJson, "hypersync");
|
|
958
|
-
});
|
|
959
|
-
};
|
|
960
|
-
if (typeof cloned === "object" && cloned !== null && !Array.isArray(cloned)) {
|
|
961
|
-
Utils.Dict.deleteInPlace(cloned, "isDev");
|
|
962
|
-
Utils.Dict.deleteInPlace(cloned, "isolatedChains");
|
|
963
|
-
stripChains(cloned["evm"]);
|
|
964
|
-
stripChains(cloned["fuel"]);
|
|
965
|
-
stripChains(cloned["svm"]);
|
|
966
|
-
}
|
|
967
|
-
return cloned;
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
function envioInfo() {
|
|
971
|
-
return stripSensitiveData(getPublicConfigJson());
|
|
972
|
-
}
|
|
973
|
-
|
|
974
979
|
function canonicalJson(json) {
|
|
975
980
|
if (Array.isArray(json)) {
|
|
976
981
|
return json.map(canonicalJson);
|
|
@@ -1088,7 +1093,8 @@ function diffPaths(stored, current) {
|
|
|
1088
1093
|
[
|
|
1089
1094
|
"evm",
|
|
1090
1095
|
"fuel",
|
|
1091
|
-
"svm"
|
|
1096
|
+
"svm",
|
|
1097
|
+
"chains"
|
|
1092
1098
|
],
|
|
1093
1099
|
["entities"]
|
|
1094
1100
|
];
|
|
@@ -1113,10 +1119,7 @@ function diffPaths(stored, current) {
|
|
|
1113
1119
|
return acc;
|
|
1114
1120
|
}
|
|
1115
1121
|
|
|
1116
|
-
function
|
|
1117
|
-
if (changedPaths.length === 0) {
|
|
1118
|
-
return;
|
|
1119
|
-
}
|
|
1122
|
+
function incompatibleMessage(changedPaths, resetCommand, runCommand, hasClickhouse) {
|
|
1120
1123
|
let bullets = changedPaths.map(p => ` - ` + p).join("\n");
|
|
1121
1124
|
let option1 = "Revert the changes above";
|
|
1122
1125
|
let padTo = (s, col) => s + " ".repeat(Math.max(col - s.length | 0, 1));
|
|
@@ -1128,20 +1131,7 @@ function throwIfIncompatible(changedPaths, resetCommand, runCommand, hasClickhou
|
|
|
1128
1131
|
} else {
|
|
1129
1132
|
option3 = "";
|
|
1130
1133
|
}
|
|
1131
|
-
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
function throwIfResumeIncompatible(storedEnvioInfo, storedContractMapping, envioInfo, contractMapping, resetCommand, runCommand) {
|
|
1135
|
-
let changedPaths = storedEnvioInfo !== undefined ? diffPaths(storedEnvioInfo, envioInfo) : ["storage was initialized by an older envio version"];
|
|
1136
|
-
let changedPaths$1 = ContractMapping.isEqual(storedContractMapping, contractMapping) ? changedPaths : changedPaths.concat(["contracts"]);
|
|
1137
|
-
let hasClickhouse;
|
|
1138
|
-
if (typeof envioInfo === "object" && envioInfo !== null && !Array.isArray(envioInfo)) {
|
|
1139
|
-
let match = envioInfo["storage"];
|
|
1140
|
-
hasClickhouse = typeof match === "object" && match !== null && !Array.isArray(match) ? Primitive_object.equal(match["clickhouse"], true) : false;
|
|
1141
|
-
} else {
|
|
1142
|
-
hasClickhouse = false;
|
|
1143
|
-
}
|
|
1144
|
-
throwIfIncompatible(changedPaths$1, resetCommand, runCommand, hasClickhouse);
|
|
1134
|
+
return `The following config changes are incompatible with the existing indexer data:\n\n` + bullets + `\n\nPick one:\n 1. ` + padTo(option1, col) + `# resume indexing where it left off\n 2. ` + padTo(resetCommand, col) + `# delete all indexed data and start over` + option3;
|
|
1145
1135
|
}
|
|
1146
1136
|
|
|
1147
1137
|
function load() {
|
|
@@ -1195,6 +1185,10 @@ export {
|
|
|
1195
1185
|
getChain,
|
|
1196
1186
|
isPerChain,
|
|
1197
1187
|
isolate,
|
|
1188
|
+
commandFields,
|
|
1189
|
+
withProjectFlags,
|
|
1190
|
+
ecosystemFields,
|
|
1191
|
+
toEnvioInfo,
|
|
1198
1192
|
fromPublic,
|
|
1199
1193
|
normalizeUserAddress,
|
|
1200
1194
|
normalizeSimulateAddress,
|
|
@@ -1202,12 +1196,9 @@ export {
|
|
|
1202
1196
|
prime,
|
|
1203
1197
|
withCommandFields,
|
|
1204
1198
|
getPublicConfigJson,
|
|
1205
|
-
stripSensitiveData,
|
|
1206
|
-
envioInfo,
|
|
1207
1199
|
canonicalJson,
|
|
1208
1200
|
diffPaths,
|
|
1209
|
-
|
|
1210
|
-
throwIfResumeIncompatible,
|
|
1201
|
+
incompatibleMessage,
|
|
1211
1202
|
load,
|
|
1212
1203
|
getPgUserEntities,
|
|
1213
1204
|
}
|