ponder 0.9.0-next.9 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/ponder.js +102 -63
- package/dist/bin/ponder.js.map +1 -1
- package/dist/{chunk-KZYYPB5L.js → chunk-IFTUFVCL.js} +2 -2
- package/dist/{chunk-KZYYPB5L.js.map → chunk-IFTUFVCL.js.map} +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +1003 -29
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/build/configAndIndexingFunctions.ts +7 -2
- package/src/build/index.ts +10 -5
- package/src/client/index.ts +21 -35
- package/src/client/validate.ts +1276 -0
- package/src/database/index.ts +4 -27
- package/src/graphql/middleware.ts +5 -3
- package/src/index.ts +2 -0
- package/src/indexing-store/metadata.ts +1 -1
- package/src/internal/options.ts +2 -0
- package/src/utils/pg.ts +79 -0
- package/src/utils/requestQueue.ts +20 -27
package/dist/bin/ponder.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
never,
|
|
7
7
|
promiseWithResolvers,
|
|
8
8
|
serialize
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-IFTUFVCL.js";
|
|
10
10
|
import {
|
|
11
11
|
onchain
|
|
12
12
|
} from "../chunk-K2TLRLX3.js";
|
|
@@ -606,6 +606,7 @@ var buildOptions = ({ cliOptions }) => {
|
|
|
606
606
|
rootDir,
|
|
607
607
|
configFile: path2.join(rootDir, cliOptions.config),
|
|
608
608
|
schemaFile: path2.join(rootDir, "ponder.schema.ts"),
|
|
609
|
+
apiDir: path2.join(rootDir, "src", "api"),
|
|
609
610
|
apiFile: path2.join(rootDir, "src", "api", "index.ts"),
|
|
610
611
|
indexingDir: path2.join(rootDir, "src"),
|
|
611
612
|
generatedDir: path2.join(rootDir, "generated"),
|
|
@@ -1983,6 +1984,13 @@ async function buildConfigAndIndexingFunctions({
|
|
|
1983
1984
|
const excludedRegisteredEventSelectors = registeredEventSelectors.filter(
|
|
1984
1985
|
(s) => filteredEventSelectors.includes(s) === false
|
|
1985
1986
|
);
|
|
1987
|
+
for (const selector of filteredEventSelectors) {
|
|
1988
|
+
if (registeredEventSelectors.includes(selector) === false) {
|
|
1989
|
+
throw new Error(
|
|
1990
|
+
`Validation failed: Event selector '${abiEvents.bySelector[selector]?.safeName}' is used in a filter but does not have a corresponding indexing function.`
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1986
1994
|
if (excludedRegisteredEventSelectors.length > 0) {
|
|
1987
1995
|
topicsArray.push({
|
|
1988
1996
|
topic0: excludedRegisteredEventSelectors,
|
|
@@ -3344,6 +3352,7 @@ var createBuild = async ({
|
|
|
3344
3352
|
const escapedIndexingDir = common.options.indexingDir.replace(/\\/g, "/").replace(escapeRegex, "\\$&");
|
|
3345
3353
|
const indexingRegex = new RegExp(`^${escapedIndexingDir}/.*\\.(ts|js)$`);
|
|
3346
3354
|
const indexingPattern = path5.join(common.options.indexingDir, "**/*.{js,mjs,ts,mts}").replace(/\\/g, "/");
|
|
3355
|
+
const apiPattern = path5.join(common.options.apiDir, "**/*.{js,mjs,ts,mts}").replace(/\\/g, "/");
|
|
3347
3356
|
const viteLogger = {
|
|
3348
3357
|
warnedMessages: /* @__PURE__ */ new Set(),
|
|
3349
3358
|
loggedErrors: /* @__PURE__ */ new WeakSet(),
|
|
@@ -3445,7 +3454,7 @@ var createBuild = async ({
|
|
|
3445
3454
|
},
|
|
3446
3455
|
async executeIndexingFunctions() {
|
|
3447
3456
|
const files = glob.sync(indexingPattern, {
|
|
3448
|
-
ignore:
|
|
3457
|
+
ignore: glob.sync(apiPattern)
|
|
3449
3458
|
});
|
|
3450
3459
|
const executeResults = await Promise.all(
|
|
3451
3460
|
files.map(async (file) => ({
|
|
@@ -3504,6 +3513,8 @@ var createBuild = async ({
|
|
|
3504
3513
|
});
|
|
3505
3514
|
return { status: "error", error };
|
|
3506
3515
|
}
|
|
3516
|
+
viteNodeRunner.moduleCache.invalidateDepTree(glob.sync(apiPattern));
|
|
3517
|
+
viteNodeRunner.moduleCache.deleteByModuleId("ponder:api");
|
|
3507
3518
|
const executeResult = await executeFile({
|
|
3508
3519
|
file: common.options.apiFile
|
|
3509
3520
|
});
|
|
@@ -3713,12 +3724,10 @@ var createBuild = async ({
|
|
|
3713
3724
|
]);
|
|
3714
3725
|
viteNodeRunner.moduleCache.invalidateDepTree(
|
|
3715
3726
|
glob.sync(indexingPattern, {
|
|
3716
|
-
ignore:
|
|
3727
|
+
ignore: glob.sync(apiPattern)
|
|
3717
3728
|
})
|
|
3718
3729
|
);
|
|
3719
|
-
viteNodeRunner.moduleCache.invalidateDepTree(
|
|
3720
|
-
common.options.apiFile
|
|
3721
|
-
]);
|
|
3730
|
+
viteNodeRunner.moduleCache.invalidateDepTree(glob.sync(apiPattern));
|
|
3722
3731
|
viteNodeRunner.moduleCache.deleteByModuleId("ponder:registry");
|
|
3723
3732
|
viteNodeRunner.moduleCache.deleteByModuleId("ponder:api");
|
|
3724
3733
|
onReload("indexing");
|
|
@@ -4556,6 +4565,69 @@ function createPool(config, logger) {
|
|
|
4556
4565
|
});
|
|
4557
4566
|
return pool;
|
|
4558
4567
|
}
|
|
4568
|
+
function createReadonlyPool(config, logger, namespace) {
|
|
4569
|
+
class ReadonlyClient extends pg.Client {
|
|
4570
|
+
// @ts-expect-error
|
|
4571
|
+
connect(callback) {
|
|
4572
|
+
if (callback) {
|
|
4573
|
+
super.connect(() => {
|
|
4574
|
+
this.query(
|
|
4575
|
+
`
|
|
4576
|
+
SET search_path = "${namespace}";
|
|
4577
|
+
SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;
|
|
4578
|
+
SET work_mem = '512MB';
|
|
4579
|
+
SET statement_timeout = '500ms';
|
|
4580
|
+
SET lock_timeout = '500ms';
|
|
4581
|
+
`,
|
|
4582
|
+
callback
|
|
4583
|
+
);
|
|
4584
|
+
});
|
|
4585
|
+
} else {
|
|
4586
|
+
return super.connect().then(
|
|
4587
|
+
() => this.query(
|
|
4588
|
+
`
|
|
4589
|
+
SET search_path = "${namespace}";
|
|
4590
|
+
SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;
|
|
4591
|
+
SET work_mem = '512MB';
|
|
4592
|
+
SET statement_timeout = '500ms';
|
|
4593
|
+
SET lock_timeout = '500ms';
|
|
4594
|
+
`
|
|
4595
|
+
).then(() => {
|
|
4596
|
+
})
|
|
4597
|
+
);
|
|
4598
|
+
}
|
|
4599
|
+
}
|
|
4600
|
+
}
|
|
4601
|
+
const pool = new pg.Pool({
|
|
4602
|
+
// https://stackoverflow.com/questions/59155572/how-to-set-query-timeout-in-relation-to-statement-timeout
|
|
4603
|
+
statement_timeout: 2 * 60 * 1e3,
|
|
4604
|
+
// 2 minutes
|
|
4605
|
+
// @ts-expect-error: The custom Client is an undocumented option.
|
|
4606
|
+
Client: ReadonlyClient,
|
|
4607
|
+
...config
|
|
4608
|
+
});
|
|
4609
|
+
function onError2(error) {
|
|
4610
|
+
const client = error.client;
|
|
4611
|
+
const pid = client?.processID ?? "unknown";
|
|
4612
|
+
const applicationName = client?.connectionParameters?.application_name ?? "unknown";
|
|
4613
|
+
logger.error({
|
|
4614
|
+
service: "postgres",
|
|
4615
|
+
msg: `Pool error (application_name: ${applicationName}, pid: ${pid})`,
|
|
4616
|
+
error
|
|
4617
|
+
});
|
|
4618
|
+
}
|
|
4619
|
+
function onNotice(notice) {
|
|
4620
|
+
logger.debug({
|
|
4621
|
+
service: "postgres",
|
|
4622
|
+
msg: `notice: ${notice.message} (code: ${notice.code})`
|
|
4623
|
+
});
|
|
4624
|
+
}
|
|
4625
|
+
pool.on("error", onError2);
|
|
4626
|
+
pool.on("connect", (client) => {
|
|
4627
|
+
client.on("notice", onNotice);
|
|
4628
|
+
});
|
|
4629
|
+
return pool;
|
|
4630
|
+
}
|
|
4559
4631
|
|
|
4560
4632
|
// src/utils/pglite.ts
|
|
4561
4633
|
import { mkdirSync } from "node:fs";
|
|
@@ -4628,17 +4700,6 @@ var createDatabase = async ({
|
|
|
4628
4700
|
},
|
|
4629
4701
|
plugins: [new WithSchemaPlugin(namespace)]
|
|
4630
4702
|
}),
|
|
4631
|
-
readonly: new Kysely({
|
|
4632
|
-
dialect: kyselyDialect,
|
|
4633
|
-
log(event) {
|
|
4634
|
-
if (event.level === "query") {
|
|
4635
|
-
common.metrics.ponder_postgres_query_total.inc({
|
|
4636
|
-
pool: "readonly"
|
|
4637
|
-
});
|
|
4638
|
-
}
|
|
4639
|
-
},
|
|
4640
|
-
plugins: [new WithSchemaPlugin(namespace)]
|
|
4641
|
-
}),
|
|
4642
4703
|
sync: new Kysely({
|
|
4643
4704
|
dialect: kyselyDialect,
|
|
4644
4705
|
log(event) {
|
|
@@ -4684,13 +4745,14 @@ var createDatabase = async ({
|
|
|
4684
4745
|
},
|
|
4685
4746
|
common.logger
|
|
4686
4747
|
),
|
|
4687
|
-
readonly:
|
|
4748
|
+
readonly: createReadonlyPool(
|
|
4688
4749
|
{
|
|
4689
4750
|
...preBuild.databaseConfig.poolConfig,
|
|
4690
4751
|
application_name: `${namespace}_readonly`,
|
|
4691
4752
|
max: readonlyMax
|
|
4692
4753
|
},
|
|
4693
|
-
common.logger
|
|
4754
|
+
common.logger,
|
|
4755
|
+
namespace
|
|
4694
4756
|
),
|
|
4695
4757
|
sync: createPool(
|
|
4696
4758
|
{
|
|
@@ -4726,17 +4788,6 @@ var createDatabase = async ({
|
|
|
4726
4788
|
},
|
|
4727
4789
|
plugins: [new WithSchemaPlugin(namespace)]
|
|
4728
4790
|
}),
|
|
4729
|
-
readonly: new Kysely({
|
|
4730
|
-
dialect: new PostgresDialect({ pool: driver.readonly }),
|
|
4731
|
-
log(event) {
|
|
4732
|
-
if (event.level === "query") {
|
|
4733
|
-
common.metrics.ponder_postgres_query_total.inc({
|
|
4734
|
-
pool: "readonly"
|
|
4735
|
-
});
|
|
4736
|
-
}
|
|
4737
|
-
},
|
|
4738
|
-
plugins: [new WithSchemaPlugin(namespace)]
|
|
4739
|
-
}),
|
|
4740
4791
|
sync: new Kysely({
|
|
4741
4792
|
dialect: new PostgresDialect({ pool: driver.sync }),
|
|
4742
4793
|
log(event) {
|
|
@@ -5487,7 +5538,7 @@ var App = (ui) => {
|
|
|
5487
5538
|
}
|
|
5488
5539
|
]
|
|
5489
5540
|
}
|
|
5490
|
-
), /* @__PURE__ */ React3.createElement(Text3, null, " "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "row" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Progress "), app.mode === void 0 || app.progress === 0 ? null : /* @__PURE__ */ React3.createElement(Text3, null, "(", app.mode === "historical" ? /* @__PURE__ */ React3.createElement(Text3, { color: "yellowBright" }, "historical") : app.mode === "realtime" ? /* @__PURE__ */ React3.createElement(Text3, { color: "greenBright" }, "live") : /* @__PURE__ */ React3.createElement(Text3, { color: "greenBright" }, "complete"), ")")), /* @__PURE__ */ React3.createElement(Text3, null, " "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "row" }, /* @__PURE__ */ React3.createElement(ProgressBar, { current: app.progress, end: 1, width: 48 }), /* @__PURE__ */ React3.createElement(Text3, null, " ", formatPercentage(app.progress), app.eta === void 0 || app.eta === 0 ? null : ` (${formatEta(app.eta)} eta)`)), /* @__PURE__ */ React3.createElement(Text3, null, " "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "
|
|
5541
|
+
), /* @__PURE__ */ React3.createElement(Text3, null, " "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "row" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Progress "), app.mode === void 0 || app.progress === 0 ? null : /* @__PURE__ */ React3.createElement(Text3, null, "(", app.mode === "historical" ? /* @__PURE__ */ React3.createElement(Text3, { color: "yellowBright" }, "historical") : app.mode === "realtime" ? /* @__PURE__ */ React3.createElement(Text3, { color: "greenBright" }, "live") : /* @__PURE__ */ React3.createElement(Text3, { color: "greenBright" }, "complete"), ")")), /* @__PURE__ */ React3.createElement(Text3, null, " "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "row" }, /* @__PURE__ */ React3.createElement(ProgressBar, { current: app.progress, end: 1, width: 48 }), /* @__PURE__ */ React3.createElement(Text3, null, " ", formatPercentage(app.progress), app.eta === void 0 || app.eta === 0 ? null : ` (${formatEta(app.eta)} eta)`)), /* @__PURE__ */ React3.createElement(Text3, null, " "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "API functions "), /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "row" }, /* @__PURE__ */ React3.createElement(Text3, null, "Server live at http://", hostname, ":", port)))));
|
|
5491
5542
|
};
|
|
5492
5543
|
var setupInkApp = (ui) => {
|
|
5493
5544
|
const app = inkRender(/* @__PURE__ */ React3.createElement(App, { ...ui }));
|
|
@@ -10367,11 +10418,11 @@ import {
|
|
|
10367
10418
|
getLogsRetryHelper as getLogsRetryHelper2
|
|
10368
10419
|
} from "@ponder/utils";
|
|
10369
10420
|
import {
|
|
10370
|
-
BlockNotFoundError as BlockNotFoundError2,
|
|
10371
10421
|
HttpRequestError,
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10422
|
+
JsonRpcVersionUnsupportedError,
|
|
10423
|
+
MethodNotFoundRpcError,
|
|
10424
|
+
MethodNotSupportedRpcError,
|
|
10425
|
+
ParseRpcError,
|
|
10375
10426
|
isHex
|
|
10376
10427
|
} from "viem";
|
|
10377
10428
|
var RETRY_COUNT = 9;
|
|
@@ -10456,36 +10507,24 @@ var createRequestQueue = ({
|
|
|
10456
10507
|
};
|
|
10457
10508
|
function shouldRetry(error) {
|
|
10458
10509
|
if ("code" in error && typeof error.code === "number") {
|
|
10459
|
-
if (error.code ===
|
|
10460
|
-
return
|
|
10461
|
-
if (error.code ===
|
|
10462
|
-
return
|
|
10463
|
-
if (error.code ===
|
|
10464
|
-
return
|
|
10465
|
-
if (error.code ===
|
|
10466
|
-
return
|
|
10467
|
-
return false;
|
|
10510
|
+
if (error.code === ParseRpcError.code)
|
|
10511
|
+
return false;
|
|
10512
|
+
if (error.code === MethodNotFoundRpcError.code)
|
|
10513
|
+
return false;
|
|
10514
|
+
if (error.code === MethodNotSupportedRpcError.code)
|
|
10515
|
+
return false;
|
|
10516
|
+
if (error.code === JsonRpcVersionUnsupportedError.code)
|
|
10517
|
+
return false;
|
|
10468
10518
|
}
|
|
10469
|
-
if (error instanceof BlockNotFoundError2)
|
|
10470
|
-
return true;
|
|
10471
10519
|
if (error instanceof HttpRequestError && error.status) {
|
|
10472
|
-
if (error.status ===
|
|
10473
|
-
return
|
|
10474
|
-
if (error.status ===
|
|
10475
|
-
return
|
|
10476
|
-
if (error.status ===
|
|
10477
|
-
return
|
|
10478
|
-
if (error.status ===
|
|
10479
|
-
return
|
|
10480
|
-
if (error.status === 500)
|
|
10481
|
-
return true;
|
|
10482
|
-
if (error.status === 502)
|
|
10483
|
-
return true;
|
|
10484
|
-
if (error.status === 503)
|
|
10485
|
-
return true;
|
|
10486
|
-
if (error.status === 504)
|
|
10487
|
-
return true;
|
|
10488
|
-
return false;
|
|
10520
|
+
if (error.status === 405)
|
|
10521
|
+
return false;
|
|
10522
|
+
if (error.status === 404)
|
|
10523
|
+
return false;
|
|
10524
|
+
if (error.status === 501)
|
|
10525
|
+
return false;
|
|
10526
|
+
if (error.status === 505)
|
|
10527
|
+
return false;
|
|
10489
10528
|
}
|
|
10490
10529
|
return true;
|
|
10491
10530
|
}
|