ponder 0.9.0 → 0.9.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ponder",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "An open-source framework for crypto application backends",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -62,7 +62,6 @@
62
62
  "http-terminator": "^3.2.0",
63
63
  "ink": "^4.4.1",
64
64
  "kysely": "^0.26.3",
65
- "kysely-pglite": "^0.6.0",
66
65
  "pg": "^8.11.3",
67
66
  "pg-connection-string": "^2.6.2",
68
67
  "pg-query-emscripten": "5.1.0",
@@ -83,7 +82,6 @@
83
82
  "@types/glob": "^8.1.0",
84
83
  "@types/node": "^20.10.0",
85
84
  "@types/pg": "^8.10.9",
86
- "@types/pg-copy-streams": "^1.2.5",
87
85
  "@types/react": "^18.2.38",
88
86
  "@viem/anvil": "^0.0.6",
89
87
  "@wagmi/cli": "^1.5.2",
@@ -1,4 +1,4 @@
1
- import crypto from "node:crypto";
1
+ import { createHash } from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import type { CliOptions } from "@/bin/ponder.js";
@@ -180,8 +180,7 @@ export const createBuild = async ({
180
180
 
181
181
  const config = executeResult.exports.default as Config;
182
182
 
183
- const contentHash = crypto
184
- .createHash("sha256")
183
+ const contentHash = createHash("sha256")
185
184
  .update(serialize(config))
186
185
  .digest("hex");
187
186
 
@@ -213,16 +212,13 @@ export const createBuild = async ({
213
212
  status: "success",
214
213
  result: {
215
214
  schema,
216
- contentHash: crypto
217
- .createHash("sha256")
218
- .update(contents)
219
- .digest("hex"),
215
+ contentHash: createHash("sha256").update(contents).digest("hex"),
220
216
  },
221
217
  } as const;
222
218
  },
223
219
  async executeIndexingFunctions(): Promise<IndexingResult> {
224
220
  const files = glob.sync(indexingPattern, {
225
- ignore: glob.sync(apiPattern),
221
+ ignore: apiPattern,
226
222
  });
227
223
  const executeResults = await Promise.all(
228
224
  files.map(async (file) => ({
@@ -248,7 +244,7 @@ export const createBuild = async ({
248
244
 
249
245
  // Note that we are only hashing the file contents, not the exports. This is
250
246
  // different from the config/schema, where we include the serializable object itself.
251
- const hash = crypto.createHash("sha256");
247
+ const hash = createHash("sha256");
252
248
  for (const file of files) {
253
249
  try {
254
250
  const contents = fs.readFileSync(file, "utf-8");
@@ -424,8 +420,7 @@ export const createBuild = async ({
424
420
  common.logger[log.level]({ service: "build", msg: log.msg });
425
421
  }
426
422
 
427
- const buildId = crypto
428
- .createHash("sha256")
423
+ const buildId = createHash("sha256")
429
424
  .update(BUILD_ID_VERSION)
430
425
  .update(configResult.contentHash)
431
426
  .update(schemaResult.contentHash)
@@ -577,7 +572,7 @@ export const createBuild = async ({
577
572
  ]);
578
573
  viteNodeRunner.moduleCache.invalidateDepTree(
579
574
  glob.sync(indexingPattern, {
580
- ignore: glob.sync(apiPattern),
575
+ ignore: apiPattern,
581
576
  }),
582
577
  );
583
578
  viteNodeRunner.moduleCache.invalidateDepTree(glob.sync(apiPattern));
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import { getPrimaryKeyColumns, getTableNames } from "@/drizzle/index.js";
2
3
  import { getColumnCasing } from "@/drizzle/kit/index.js";
3
4
  import type { Common } from "@/internal/common.js";
@@ -23,7 +24,7 @@ import {
23
24
  } from "@/utils/checkpoint.js";
24
25
  import { formatEta } from "@/utils/format.js";
25
26
  import { createPool, createReadonlyPool } from "@/utils/pg.js";
26
- import { createPglite } from "@/utils/pglite.js";
27
+ import { createPglite, createPgliteKyselyDialect } from "@/utils/pglite.js";
27
28
  import { startClock } from "@/utils/timer.js";
28
29
  import { wait } from "@/utils/wait.js";
29
30
  import type { PGlite } from "@electric-sql/pglite";
@@ -39,7 +40,6 @@ import {
39
40
  WithSchemaPlugin,
40
41
  sql,
41
42
  } from "kysely";
42
- import { KyselyPGlite } from "kysely-pglite";
43
43
  import type { Pool, PoolClient } from "pg";
44
44
  import prometheus from "prom-client";
45
45
 
@@ -155,7 +155,7 @@ export const createDatabase = async ({
155
155
  : preBuild.databaseConfig.instance,
156
156
  };
157
157
 
158
- const kyselyDialect = new KyselyPGlite(driver.instance).dialect;
158
+ const kyselyDialect = createPgliteKyselyDialect(driver.instance);
159
159
 
160
160
  await driver.instance.query(`CREATE SCHEMA IF NOT EXISTS "${namespace}"`);
161
161
  await driver.instance.query(`SET search_path TO "${namespace}"`);
@@ -449,7 +449,7 @@ export const createDatabase = async ({
449
449
  for (let i = 0; i <= RETRY_COUNT; i++) {
450
450
  const endClock = startClock();
451
451
 
452
- const id = crypto.randomUUID().slice(0, 8);
452
+ const id = randomUUID().slice(0, 8);
453
453
  if (options.includeTraceLogs) {
454
454
  common.logger.trace({
455
455
  service: "database",
package/src/utils/pg.ts CHANGED
@@ -2,6 +2,12 @@ import type { Logger } from "@/internal/logger.js";
2
2
  import pg, { type PoolConfig } from "pg";
3
3
  import { prettyPrint } from "./print.js";
4
4
 
5
+ // The default parser for numeric[] (1231) seems to parse values as Number
6
+ // or perhaps through JSON.parse(). Use the int8[] (1016) parser instead,
7
+ // which properly returns an array of strings.
8
+ const bigIntArrayParser = pg.types.getTypeParser(1016);
9
+ pg.types.setTypeParser(1231, bigIntArrayParser);
10
+
5
11
  // Monkeypatch Pool.query to get more informative stack traces. I have no idea why this works.
6
12
  // https://stackoverflow.com/a/70601114
7
13
  const originalClientQuery = pg.Client.prototype.query;
@@ -1,6 +1,17 @@
1
1
  import { mkdirSync } from "node:fs";
2
2
  import type { Prettify } from "@/types/utils.js";
3
3
  import { type PGliteOptions as Options, PGlite } from "@electric-sql/pglite";
4
+ import {
5
+ CompiledQuery,
6
+ type DatabaseConnection,
7
+ type Dialect,
8
+ type Kysely,
9
+ PostgresAdapter,
10
+ PostgresIntrospector,
11
+ PostgresQueryCompiler,
12
+ type QueryResult,
13
+ type TransactionSettings,
14
+ } from "kysely";
4
15
 
5
16
  export type PGliteOptions = Prettify<Options & { dataDir: string }>;
6
17
 
@@ -16,3 +27,71 @@ export function createPglite(options: PGliteOptions) {
16
27
 
17
28
  return new PGlite(options);
18
29
  }
30
+
31
+ // Adapted from dnlsandiego/kysely-pglite
32
+ // https://github.com/dnlsandiego/kysely-pglite/blob/3891a0c4d9327a21bff26addf371784f0109260b/src/kysely-pglite.ts
33
+ export function createPgliteKyselyDialect(instance: PGlite) {
34
+ return {
35
+ createAdapter: () => new PostgresAdapter(),
36
+ createDriver: () => new PGliteDriver(instance),
37
+ createIntrospector: (db: Kysely<any>) => new PostgresIntrospector(db),
38
+ createQueryCompiler: () => new PostgresQueryCompiler(),
39
+ } satisfies Dialect;
40
+ }
41
+
42
+ // Adapted from dnlsandiego/kysely-pglite
43
+ // https://github.com/dnlsandiego/kysely-pglite/blob/3891a0c4d9327a21bff26addf371784f0109260b/src/pglite-driver.ts
44
+ export class PGliteDriver {
45
+ #client: PGlite;
46
+
47
+ constructor(client: PGlite) {
48
+ this.#client = client;
49
+ }
50
+
51
+ async acquireConnection(): Promise<DatabaseConnection> {
52
+ return new PGliteConnection(this.#client);
53
+ }
54
+
55
+ async beginTransaction(
56
+ connection: DatabaseConnection,
57
+ _settings: TransactionSettings,
58
+ ): Promise<void> {
59
+ await connection.executeQuery(CompiledQuery.raw("BEGIN"));
60
+ }
61
+
62
+ async commitTransaction(connection: DatabaseConnection): Promise<void> {
63
+ await connection.executeQuery(CompiledQuery.raw("COMMIT"));
64
+ }
65
+
66
+ async rollbackTransaction(connection: DatabaseConnection): Promise<void> {
67
+ await connection.executeQuery(CompiledQuery.raw("ROLLBACK"));
68
+ }
69
+
70
+ async destroy(): Promise<void> {
71
+ await this.#client.close();
72
+ }
73
+
74
+ async init(): Promise<void> {}
75
+ async releaseConnection(_connection: DatabaseConnection): Promise<void> {}
76
+ }
77
+
78
+ class PGliteConnection implements DatabaseConnection {
79
+ #client: PGlite;
80
+
81
+ constructor(client: PGlite) {
82
+ this.#client = client;
83
+ }
84
+
85
+ async executeQuery<R>(
86
+ compiledQuery: CompiledQuery<any>,
87
+ ): Promise<QueryResult<R>> {
88
+ return await this.#client.query<R>(compiledQuery.sql, [
89
+ ...compiledQuery.parameters,
90
+ ]);
91
+ }
92
+
93
+ // biome-ignore lint/correctness/useYield: <explanation>
94
+ async *streamQuery(): AsyncGenerator<never, void, unknown> {
95
+ throw new Error("PGlite does not support streaming.");
96
+ }
97
+ }