ponder 0.11.21 → 0.11.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.
Files changed (123) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/esm/bin/commands/createViews.js +9 -20
  3. package/dist/esm/bin/commands/createViews.js.map +1 -1
  4. package/dist/esm/bin/commands/dev.js +1 -1
  5. package/dist/esm/bin/commands/dev.js.map +1 -1
  6. package/dist/esm/bin/commands/list.js +4 -7
  7. package/dist/esm/bin/commands/list.js.map +1 -1
  8. package/dist/esm/bin/commands/prune.js +9 -21
  9. package/dist/esm/bin/commands/prune.js.map +1 -1
  10. package/dist/esm/bin/commands/serve.js +1 -1
  11. package/dist/esm/bin/commands/serve.js.map +1 -1
  12. package/dist/esm/bin/commands/start.js +3 -3
  13. package/dist/esm/bin/commands/start.js.map +1 -1
  14. package/dist/esm/bin/utils/run.js +159 -180
  15. package/dist/esm/bin/utils/run.js.map +1 -1
  16. package/dist/esm/build/index.js +1 -48
  17. package/dist/esm/build/index.js.map +1 -1
  18. package/dist/esm/build/plugin.js +1 -1
  19. package/dist/esm/client/index.js +9 -13
  20. package/dist/esm/client/index.js.map +1 -1
  21. package/dist/esm/database/index.js +429 -141
  22. package/dist/esm/database/index.js.map +1 -1
  23. package/dist/esm/drizzle/index.js.map +1 -1
  24. package/dist/esm/drizzle/kit/index.js.map +1 -1
  25. package/dist/esm/drizzle/onchain.js +1 -8
  26. package/dist/esm/drizzle/onchain.js.map +1 -1
  27. package/dist/esm/graphql/index.js +16 -19
  28. package/dist/esm/graphql/index.js.map +1 -1
  29. package/dist/esm/graphql/middleware.js +7 -3
  30. package/dist/esm/graphql/middleware.js.map +1 -1
  31. package/dist/esm/indexing-store/cache.js +32 -26
  32. package/dist/esm/indexing-store/cache.js.map +1 -1
  33. package/dist/esm/indexing-store/historical.js +32 -23
  34. package/dist/esm/indexing-store/historical.js.map +1 -1
  35. package/dist/esm/indexing-store/index.js +18 -1
  36. package/dist/esm/indexing-store/index.js.map +1 -1
  37. package/dist/esm/indexing-store/realtime.js +140 -89
  38. package/dist/esm/indexing-store/realtime.js.map +1 -1
  39. package/dist/esm/internal/errors.js +0 -12
  40. package/dist/esm/internal/errors.js.map +1 -1
  41. package/dist/esm/server/index.js +2 -10
  42. package/dist/esm/server/index.js.map +1 -1
  43. package/dist/esm/sync-store/index.js +432 -403
  44. package/dist/esm/sync-store/index.js.map +1 -1
  45. package/dist/esm/utils/wait.js +0 -2
  46. package/dist/esm/utils/wait.js.map +1 -1
  47. package/dist/types/bin/commands/createViews.d.ts.map +1 -1
  48. package/dist/types/bin/commands/list.d.ts.map +1 -1
  49. package/dist/types/bin/commands/prune.d.ts.map +1 -1
  50. package/dist/types/bin/commands/start.d.ts +0 -2
  51. package/dist/types/bin/commands/start.d.ts.map +1 -1
  52. package/dist/types/bin/utils/run.d.ts +1 -1
  53. package/dist/types/bin/utils/run.d.ts.map +1 -1
  54. package/dist/types/build/index.d.ts +1 -1
  55. package/dist/types/build/index.d.ts.map +1 -1
  56. package/dist/types/client/index.d.ts.map +1 -1
  57. package/dist/types/database/index.d.ts +73 -25
  58. package/dist/types/database/index.d.ts.map +1 -1
  59. package/dist/types/drizzle/index.d.ts +3 -2
  60. package/dist/types/drizzle/index.d.ts.map +1 -1
  61. package/dist/types/drizzle/kit/index.d.ts +4 -3
  62. package/dist/types/drizzle/kit/index.d.ts.map +1 -1
  63. package/dist/types/drizzle/onchain.d.ts +5 -12
  64. package/dist/types/drizzle/onchain.d.ts.map +1 -1
  65. package/dist/types/graphql/index.d.ts +4 -2
  66. package/dist/types/graphql/index.d.ts.map +1 -1
  67. package/dist/types/graphql/middleware.d.ts +1 -1
  68. package/dist/types/graphql/middleware.d.ts.map +1 -1
  69. package/dist/types/indexing-store/cache.d.ts +12 -5
  70. package/dist/types/indexing-store/cache.d.ts.map +1 -1
  71. package/dist/types/indexing-store/historical.d.ts +7 -2
  72. package/dist/types/indexing-store/historical.d.ts.map +1 -1
  73. package/dist/types/indexing-store/index.d.ts +2 -4
  74. package/dist/types/indexing-store/index.d.ts.map +1 -1
  75. package/dist/types/indexing-store/realtime.d.ts +3 -1
  76. package/dist/types/indexing-store/realtime.d.ts.map +1 -1
  77. package/dist/types/internal/errors.d.ts +0 -4
  78. package/dist/types/internal/errors.d.ts.map +1 -1
  79. package/dist/types/server/index.d.ts +1 -1
  80. package/dist/types/server/index.d.ts.map +1 -1
  81. package/dist/types/sync/index.d.ts +1 -1
  82. package/dist/types/sync-store/index.d.ts.map +1 -1
  83. package/dist/types/utils/wait.d.ts.map +1 -1
  84. package/package.json +2 -2
  85. package/src/bin/commands/createViews.ts +26 -37
  86. package/src/bin/commands/dev.ts +1 -1
  87. package/src/bin/commands/list.ts +4 -7
  88. package/src/bin/commands/prune.ts +17 -31
  89. package/src/bin/commands/serve.ts +1 -1
  90. package/src/bin/commands/start.ts +3 -4
  91. package/src/bin/utils/run.ts +210 -256
  92. package/src/build/index.ts +2 -53
  93. package/src/build/plugin.ts +1 -1
  94. package/src/client/index.ts +10 -21
  95. package/src/database/index.ts +742 -331
  96. package/src/drizzle/index.ts +3 -2
  97. package/src/drizzle/kit/index.ts +5 -2
  98. package/src/drizzle/onchain.ts +2 -26
  99. package/src/graphql/index.ts +26 -31
  100. package/src/graphql/middleware.ts +7 -5
  101. package/src/indexing-store/cache.ts +52 -35
  102. package/src/indexing-store/historical.ts +40 -28
  103. package/src/indexing-store/index.ts +27 -2
  104. package/src/indexing-store/realtime.ts +220 -176
  105. package/src/internal/errors.ts +0 -9
  106. package/src/server/index.ts +3 -14
  107. package/src/sync-store/index.ts +997 -870
  108. package/src/utils/wait.ts +0 -1
  109. package/dist/esm/database/queryBuilder.js +0 -206
  110. package/dist/esm/database/queryBuilder.js.map +0 -1
  111. package/dist/esm/database/utils.js +0 -100
  112. package/dist/esm/database/utils.js.map +0 -1
  113. package/dist/esm/drizzle/json.js +0 -119
  114. package/dist/esm/drizzle/json.js.map +0 -1
  115. package/dist/types/database/queryBuilder.d.ts +0 -37
  116. package/dist/types/database/queryBuilder.d.ts.map +0 -1
  117. package/dist/types/database/utils.d.ts +0 -25
  118. package/dist/types/database/utils.d.ts.map +0 -1
  119. package/dist/types/drizzle/json.d.ts +0 -51
  120. package/dist/types/drizzle/json.d.ts.map +0 -1
  121. package/src/database/queryBuilder.ts +0 -319
  122. package/src/database/utils.ts +0 -140
  123. package/src/drizzle/json.ts +0 -154
@@ -1,319 +0,0 @@
1
- import type { Common } from "@/internal/common.js";
2
- import {
3
- NonRetryableError,
4
- ShutdownError,
5
- TransactionError,
6
- } from "@/internal/errors.js";
7
- import {
8
- BigIntSerializationError,
9
- CheckConstraintError,
10
- NotNullConstraintError,
11
- UniqueConstraintError,
12
- getBaseError,
13
- } from "@/internal/errors.js";
14
- import type { Schema } from "@/internal/types.js";
15
- import type { Drizzle } from "@/types/db.js";
16
- import { startClock } from "@/utils/timer.js";
17
- import { wait } from "@/utils/wait.js";
18
- import type { PGlite } from "@electric-sql/pglite";
19
- import {
20
- type PgDatabase,
21
- PgDialect,
22
- type PgQueryResultHKT,
23
- type PgTransactionConfig,
24
- } from "drizzle-orm/pg-core";
25
- import pg from "pg";
26
-
27
- const RETRY_COUNT = 9;
28
- const BASE_DURATION = 125;
29
- const SQL_LENGTH_LIMIT = 50;
30
-
31
- /**
32
- * Query builder with built-in retry logic, logging, and metrics.
33
- */
34
- export type QB<
35
- TSchema extends Schema = Schema,
36
- TClient extends PGlite | pg.Pool | pg.PoolClient =
37
- | PGlite
38
- | pg.Pool
39
- | pg.PoolClient,
40
- > = ((label?: string) => Omit<Drizzle<TSchema>, "transaction"> & {
41
- transaction<T>(
42
- transaction: (tx: QB<TSchema, TClient>) => Promise<T>,
43
- config?: PgTransactionConfig,
44
- ): Promise<T>;
45
- }) &
46
- (
47
- | { $dialect: "pglite"; $client: PGlite }
48
- | { $dialect: "postgres"; $client: pg.Pool | pg.PoolClient }
49
- );
50
-
51
- export const parseSqlError = (e: any): Error => {
52
- let error = getBaseError(e);
53
-
54
- if (error?.message?.includes("violates not-null constraint")) {
55
- error = new NotNullConstraintError(error.message);
56
- } else if (error?.message?.includes("violates unique constraint")) {
57
- error = new UniqueConstraintError(error.message);
58
- } else if (error?.message?.includes("violates check constraint")) {
59
- error = new CheckConstraintError(error.message);
60
- } else if (
61
- error?.message?.includes("Do not know how to serialize a BigInt")
62
- ) {
63
- error = new BigIntSerializationError(error.message);
64
- error.meta.push(
65
- "Hint:\n The JSON column type does not support BigInt values. Use the replaceBigInts() helper function before inserting into the database. Docs: https://ponder.sh/docs/api-reference/ponder-utils#replacebigints",
66
- );
67
- } else if (error?.message?.includes("does not exist")) {
68
- error = new NonRetryableError(error.message);
69
- }
70
-
71
- return error;
72
- };
73
-
74
- /**
75
- * Create a query builder.
76
- *
77
- * @example
78
- * ```ts
79
- * const qb = createQB(common, drizzle(pool, { casing: "snake_case" }));
80
- * const result = await qb.label("test").select().from(accounts);
81
- * ```
82
- */
83
- export const createQB = <
84
- TSchema extends Schema = { [name: string]: never },
85
- TClient extends PGlite | pg.Pool | pg.PoolClient =
86
- | PGlite
87
- | pg.Pool
88
- | pg.PoolClient,
89
- >(
90
- createDb: () => PgDatabase<PgQueryResultHKT, TSchema> & { $client: TClient },
91
- { common, isAdmin }: { common: Common; isAdmin?: boolean },
92
- ): QB<TSchema, TClient> => {
93
- const dialect = new PgDialect({ casing: "snake_case" });
94
- let txLabel: string | undefined = undefined;
95
-
96
- const wrap = async <T>(
97
- label: string | undefined,
98
- fn: () => Promise<T>,
99
- sql: string,
100
- ): Promise<T> => {
101
- // First error thrown is often the most useful
102
- let firstError: any;
103
- let hasError = false;
104
-
105
- for (let i = 0; i <= RETRY_COUNT; i++) {
106
- const endClock = startClock();
107
- const id = crypto.randomUUID().slice(0, 8);
108
-
109
- if (label) {
110
- common.logger.trace({
111
- service: "database",
112
- msg: `Started '${label}' database method (id=${id})`,
113
- });
114
- }
115
-
116
- try {
117
- if (common.shutdown.isKilled && isAdmin === false) {
118
- throw new ShutdownError();
119
- }
120
-
121
- const result = await fn();
122
- if (label) {
123
- common.metrics.ponder_database_method_duration.observe(
124
- { method: label },
125
- endClock(),
126
- );
127
- }
128
-
129
- if (common.shutdown.isKilled && isAdmin === false) {
130
- throw new ShutdownError();
131
- }
132
-
133
- return result;
134
- } catch (e) {
135
- const error = parseSqlError(e);
136
-
137
- if (common.shutdown.isKilled) {
138
- throw new ShutdownError();
139
- }
140
-
141
- if (label) {
142
- common.metrics.ponder_database_method_duration.observe(
143
- { method: label },
144
- endClock(),
145
- );
146
- common.metrics.ponder_database_method_error_total.inc({
147
- method: label,
148
- });
149
- }
150
-
151
- if (!hasError) {
152
- hasError = true;
153
- firstError = error;
154
- }
155
-
156
- if (
157
- error instanceof NonRetryableError &&
158
- error instanceof TransactionError === false
159
- ) {
160
- common.logger.warn({
161
- service: "database",
162
- msg: `Failed '${label ?? sql}' database query (id=${id})`,
163
- error,
164
- });
165
- throw error;
166
- }
167
-
168
- if (i === RETRY_COUNT) {
169
- common.logger.warn({
170
- service: "database",
171
- msg: `Failed '${label ?? sql}' database query after '${i + 1}' attempts (id=${id})`,
172
- error,
173
- });
174
- throw firstError;
175
- }
176
-
177
- const duration = BASE_DURATION * 2 ** i;
178
- common.logger.debug({
179
- service: "database",
180
- msg: `Failed '${label ?? sql}' database query, retrying after ${duration} milliseconds (id=${id})`,
181
- error,
182
- });
183
- await wait(duration);
184
- } finally {
185
- if (label) {
186
- common.logger.trace({
187
- service: "database",
188
- msg: `Completed '${label}' database method in ${Math.round(endClock())}ms (id=${id})`,
189
- });
190
- }
191
- }
192
- }
193
-
194
- throw "unreachable";
195
- };
196
-
197
- const assignClient = (qb: QB<TSchema, TClient>, client: TClient) => {
198
- if (client instanceof pg.Pool || client instanceof pg.Client) {
199
- Object.assign(qb, { $dialect: "postgres" });
200
- } else {
201
- Object.assign(qb, { $dialect: "pglite" });
202
- }
203
-
204
- Object.assign(qb, { $client: client });
205
- };
206
-
207
- const wrapTx = (db: PgDatabase<PgQueryResultHKT, TSchema>) => {
208
- const _transaction = db.transaction.bind(db);
209
- db.transaction = async (...args) => {
210
- const callback = args[0];
211
- args[0] = async (_tx) => {
212
- wrapTx(_tx);
213
-
214
- const previousLabel = txLabel;
215
-
216
- const tx = (label?: string) => {
217
- txLabel = label;
218
- return _tx;
219
- };
220
-
221
- // @ts-expect-error
222
- assignClient(tx, _tx.session.client);
223
- // @ts-expect-error
224
- const result = await callback(tx);
225
-
226
- txLabel = previousLabel;
227
- return result;
228
- };
229
- return _transaction(...args);
230
- };
231
- };
232
-
233
- const qb = ((label: string | undefined) => {
234
- const db = createDb();
235
- const isClient = db.$client instanceof pg.Client;
236
-
237
- // non-transaction queries (retryable)
238
-
239
- const execute = db._.session.execute.bind(db._.session);
240
- db._.session.execute = async (...args) => {
241
- return wrap(
242
- label,
243
- () => execute(...args),
244
- dialect.sqlToQuery(args[0]).sql.slice(0, SQL_LENGTH_LIMIT),
245
- );
246
- };
247
-
248
- const prepareQuery = db._.session.prepareQuery.bind(db._.session);
249
- db._.session.prepareQuery = (...args) => {
250
- const result = prepareQuery(...args);
251
- const execute = result.execute.bind(result);
252
- result.execute = async (..._args) => {
253
- return wrap(
254
- label,
255
- () => execute(..._args),
256
- args[0].sql.slice(0, SQL_LENGTH_LIMIT),
257
- );
258
- };
259
- return result;
260
- };
261
-
262
- // transaction queries (non-retryable)
263
-
264
- wrapTx(db);
265
- txLabel = label;
266
-
267
- const transaction = db._.session.transaction.bind(db._.session);
268
- db._.session.transaction = async (...args) => {
269
- const callback = args[0];
270
- args[0] = async (..._args) => {
271
- const tx = _args[0] as PgDatabase<PgQueryResultHKT, TSchema>;
272
- const txExecute = isClient
273
- ? execute
274
- : tx._.session.execute.bind(tx._.session);
275
- // @ts-expect-error
276
- tx._.session.execute = async (...args) => {
277
- return wrap(
278
- txLabel,
279
- () =>
280
- txExecute(...args).catch((error) => {
281
- throw new TransactionError(error.message);
282
- }),
283
- dialect.sqlToQuery(args[0]).sql.slice(0, SQL_LENGTH_LIMIT),
284
- );
285
- };
286
-
287
- const txPrepareQuery = isClient
288
- ? prepareQuery
289
- : tx._.session.prepareQuery.bind(tx._.session);
290
- // @ts-ignore
291
- tx._.session.prepareQuery = (...args) => {
292
- const result = txPrepareQuery(...args);
293
- const execute = result.execute.bind(result);
294
- result.execute = async (..._args) => {
295
- return wrap(
296
- txLabel,
297
- () =>
298
- execute(..._args).catch((error) => {
299
- throw new TransactionError(error.message);
300
- }),
301
- args[0].sql.slice(0, SQL_LENGTH_LIMIT),
302
- );
303
- };
304
- return result;
305
- };
306
-
307
- return callback(..._args);
308
- };
309
-
310
- return wrap(label, () => transaction(...args), "begin");
311
- };
312
-
313
- return db;
314
- }) as unknown as QB<TSchema, TClient>;
315
-
316
- assignClient(qb, createDb().$client);
317
-
318
- return qb;
319
- };
@@ -1,140 +0,0 @@
1
- import { getPrimaryKeyColumns } from "@/drizzle/index.js";
2
- import { getTableNames } from "@/drizzle/index.js";
3
- import { getColumnCasing, getReorgTable } from "@/drizzle/kit/index.js";
4
- import type { SchemaBuild } from "@/internal/types.js";
5
- import { MAX_CHECKPOINT_STRING } from "@/utils/checkpoint.js";
6
- import { eq, getTableColumns, getTableName, lte, sql } from "drizzle-orm";
7
- import { type PgTable, getTableConfig } from "drizzle-orm/pg-core";
8
- import type { QB } from "./queryBuilder.js";
9
-
10
- export const createIndexes = async (
11
- qb: QB,
12
- { statements }: { statements: SchemaBuild["statements"] },
13
- ) => {
14
- for (const statement of statements.indexes.sql) {
15
- await qb("create_indexes").transaction(async (tx) => {
16
- // 60 minutes
17
- await tx().execute("SET statement_timeout = 3600000;");
18
- await tx().execute(statement);
19
- });
20
- }
21
- };
22
-
23
- export const createTrigger = async (qb: QB, { table }: { table: PgTable }) => {
24
- const schema = getTableConfig(table).schema ?? "public";
25
- const columns = getTableColumns(table);
26
-
27
- const columnNames = Object.values(columns).map(
28
- (column) => `"${getColumnCasing(column, "snake_case")}"`,
29
- );
30
-
31
- await qb("create_trigger_function").execute(
32
- sql.raw(`
33
- CREATE OR REPLACE FUNCTION "${schema}".${getTableNames(table).triggerFn}
34
- RETURNS TRIGGER AS $$
35
- BEGIN
36
- IF TG_OP = 'INSERT' THEN
37
- INSERT INTO "${schema}"."${getTableName(getReorgTable(table))}" (${columnNames.join(",")}, operation, checkpoint)
38
- VALUES (${columnNames.map((name) => `NEW.${name}`).join(",")}, 0, '${MAX_CHECKPOINT_STRING}');
39
- ELSIF TG_OP = 'UPDATE' THEN
40
- INSERT INTO "${schema}"."${getTableName(getReorgTable(table))}" (${columnNames.join(",")}, operation, checkpoint)
41
- VALUES (${columnNames.map((name) => `OLD.${name}`).join(",")}, 1, '${MAX_CHECKPOINT_STRING}');
42
- ELSIF TG_OP = 'DELETE' THEN
43
- INSERT INTO "${schema}"."${getTableName(getReorgTable(table))}" (${columnNames.join(",")}, operation, checkpoint)
44
- VALUES (${columnNames.map((name) => `OLD.${name}`).join(",")}, 2, '${MAX_CHECKPOINT_STRING}');
45
- END IF;
46
- RETURN NULL;
47
- END;
48
- $$ LANGUAGE plpgsql`),
49
- );
50
-
51
- await qb("create_trigger").execute(
52
- sql.raw(`
53
- CREATE OR REPLACE TRIGGER "${getTableNames(table).trigger}"
54
- AFTER INSERT OR UPDATE OR DELETE ON "${schema}"."${getTableName(table)}"
55
- FOR EACH ROW EXECUTE FUNCTION "${schema}".${getTableNames(table).triggerFn};
56
- `),
57
- );
58
- };
59
-
60
- export const dropTrigger = async (qb: QB, { table }: { table: PgTable }) => {
61
- const schema = getTableConfig(table).schema ?? "public";
62
-
63
- await qb("drop_trigger").execute(
64
- sql.raw(
65
- `DROP TRIGGER IF EXISTS "${getTableNames(table).trigger}" ON "${schema}"."${getTableName(table)}"`,
66
- ),
67
- );
68
- };
69
-
70
- export const revert = async (
71
- qb: QB,
72
- { checkpoint, table }: { checkpoint: string; table: PgTable },
73
- ): Promise<number> => {
74
- const primaryKeyColumns = getPrimaryKeyColumns(table);
75
- const schema = getTableConfig(table).schema ?? "public";
76
-
77
- const result = await qb("revert").execute(
78
- sql.raw(`
79
- WITH reverted1 AS (
80
- DELETE FROM "${schema}"."${getTableName(getReorgTable(table))}"
81
- WHERE checkpoint > '${checkpoint}' RETURNING *
82
- ), reverted2 AS (
83
- SELECT ${primaryKeyColumns.map(({ sql }) => `"${sql}"`).join(", ")}, MIN(operation_id) AS operation_id FROM reverted1
84
- GROUP BY ${primaryKeyColumns.map(({ sql }) => `"${sql}"`).join(", ")}
85
- ), reverted3 AS (
86
- SELECT ${Object.values(getTableColumns(table))
87
- .map((column) => `reverted1."${getColumnCasing(column, "snake_case")}"`)
88
- .join(", ")}, reverted1.operation FROM reverted2
89
- INNER JOIN reverted1
90
- ON ${primaryKeyColumns.map(({ sql }) => `reverted2."${sql}" = reverted1."${sql}"`).join("AND ")}
91
- AND reverted2.operation_id = reverted1.operation_id
92
- ), inserted AS (
93
- DELETE FROM "${schema}"."${getTableName(table)}" as t
94
- WHERE EXISTS (
95
- SELECT * FROM reverted3
96
- WHERE ${primaryKeyColumns.map(({ sql }) => `t."${sql}" = reverted3."${sql}"`).join("AND ")}
97
- AND OPERATION = 0
98
- )
99
- RETURNING *
100
- ), updated_or_deleted AS (
101
- INSERT INTO "${schema}"."${getTableName(table)}"
102
- SELECT ${Object.values(getTableColumns(table))
103
- .map((column) => `"${getColumnCasing(column, "snake_case")}"`)
104
- .join(", ")} FROM reverted3
105
- WHERE operation = 1 OR operation = 2
106
- ON CONFLICT (${primaryKeyColumns.map(({ sql }) => `"${sql}"`).join(", ")})
107
- DO UPDATE SET
108
- ${Object.values(getTableColumns(table))
109
- .map(
110
- (column) =>
111
- `"${getColumnCasing(column, "snake_case")}" = EXCLUDED."${getColumnCasing(column, "snake_case")}"`,
112
- )
113
- .join(", ")}
114
- RETURNING *
115
- ) SELECT COUNT(*) FROM reverted1 as count;
116
- `),
117
- );
118
-
119
- return result.rows[0]!.count as number;
120
- };
121
-
122
- export const finalize = async (
123
- qb: QB,
124
- { checkpoint, table }: { checkpoint: string; table: PgTable },
125
- ) => {
126
- await qb("finalize")
127
- .delete(getReorgTable(table))
128
- .where(lte(getReorgTable(table).checkpoint, checkpoint));
129
- };
130
-
131
- export const commitBlock = async (
132
- qb: QB,
133
- { checkpoint, table }: { checkpoint: string; table: PgTable },
134
- ) => {
135
- const reorgTable = getReorgTable(table);
136
- await qb("commit_block")
137
- .update(reorgTable)
138
- .set({ checkpoint })
139
- .where(eq(reorgTable.checkpoint, MAX_CHECKPOINT_STRING));
140
- };
@@ -1,154 +0,0 @@
1
- import { BigIntSerializationError, getBaseError } from "@/internal/errors.js";
2
- import { type ColumnBaseConfig, entityKind } from "drizzle-orm";
3
- import type {
4
- ColumnBuilderBaseConfig,
5
- ColumnBuilderRuntimeConfig,
6
- MakeColumnConfig,
7
- } from "drizzle-orm/column-builder";
8
- import {
9
- type AnyPgTable,
10
- PgColumn,
11
- PgColumnBuilder,
12
- } from "drizzle-orm/pg-core";
13
-
14
- export type PgJsonBuilderInitial<TName extends string> = PgJsonBuilder<{
15
- name: TName;
16
- dataType: "json";
17
- columnType: "PgJson";
18
- data: unknown;
19
- driverParam: string;
20
- enumValues: undefined;
21
- }>;
22
-
23
- export class PgJsonBuilder<
24
- T extends ColumnBuilderBaseConfig<"json", "PgJson">,
25
- > extends PgColumnBuilder<T> {
26
- static readonly [entityKind]: string = "PgJsonBuilder";
27
-
28
- constructor(name: T["name"]) {
29
- super(name, "json", "PgJson");
30
- }
31
-
32
- /** @internal */
33
- // @ts-ignore
34
- override build<TTableName extends string>(
35
- table: AnyPgTable<{ name: TTableName }>,
36
- ): PgJson<MakeColumnConfig<T, TTableName>> {
37
- return new PgJson<MakeColumnConfig<T, TTableName>>(
38
- table,
39
- this.config as ColumnBuilderRuntimeConfig<any, any>,
40
- );
41
- }
42
- }
43
-
44
- export class PgJson<
45
- T extends ColumnBaseConfig<"json", "PgJson">,
46
- > extends PgColumn<T> {
47
- static readonly [entityKind]: string = "PgJson";
48
-
49
- getSQLType(): string {
50
- return "json";
51
- }
52
-
53
- override mapToDriverValue(value: T["data"]): string {
54
- try {
55
- return JSON.stringify(value);
56
- } catch (_error) {
57
- let error = getBaseError(_error);
58
- if (error?.message?.includes("Do not know how to serialize a BigInt")) {
59
- error = new BigIntSerializationError(error.message);
60
- error.meta.push(
61
- "Hint:\n The JSON column type does not support BigInt values. Use the replaceBigInts() helper function before inserting into the database. Docs: https://ponder.sh/docs/api-reference/ponder-utils#replacebigints",
62
- );
63
- }
64
-
65
- throw error;
66
- }
67
- }
68
-
69
- override mapFromDriverValue(value: T["data"] | string): T["data"] {
70
- if (typeof value === "string") {
71
- try {
72
- return JSON.parse(value);
73
- } catch {
74
- return value as T["data"];
75
- }
76
- }
77
- return value;
78
- }
79
- }
80
-
81
- export type PgJsonbBuilderInitial<TName extends string> = PgJsonbBuilder<{
82
- name: TName;
83
- dataType: "json";
84
- columnType: "PgJsonb";
85
- data: unknown;
86
- driverParam: unknown;
87
- enumValues: undefined;
88
- }>;
89
-
90
- export class PgJsonbBuilder<
91
- T extends ColumnBuilderBaseConfig<"json", "PgJsonb">,
92
- > extends PgColumnBuilder<T> {
93
- static override readonly [entityKind]: string = "PgJsonbBuilder";
94
-
95
- constructor(name: T["name"]) {
96
- super(name, "json", "PgJsonb");
97
- }
98
-
99
- /** @internal */
100
- // @ts-ignore
101
- override build<TTableName extends string>(
102
- table: AnyPgTable<{ name: TTableName }>,
103
- ): PgJsonb<MakeColumnConfig<T, TTableName>> {
104
- return new PgJsonb<MakeColumnConfig<T, TTableName>>(
105
- table,
106
- this.config as ColumnBuilderRuntimeConfig<any, any>,
107
- );
108
- }
109
- }
110
-
111
- export class PgJsonb<
112
- T extends ColumnBaseConfig<"json", "PgJsonb">,
113
- > extends PgColumn<T> {
114
- static override readonly [entityKind]: string = "PgJsonb";
115
-
116
- // biome-ignore lint/complexity/noUselessConstructor: <explanation>
117
- constructor(
118
- table: AnyPgTable<{ name: T["tableName"] }>,
119
- config: PgJsonbBuilder<T>["config"],
120
- ) {
121
- super(table, config);
122
- }
123
-
124
- getSQLType(): string {
125
- return "jsonb";
126
- }
127
-
128
- override mapToDriverValue(value: T["data"]): string {
129
- try {
130
- return JSON.stringify(value);
131
- } catch (_error) {
132
- let error = getBaseError(_error);
133
- if (error?.message?.includes("Do not know how to serialize a BigInt")) {
134
- error = new BigIntSerializationError(error.message);
135
- error.meta.push(
136
- "Hint:\n The JSON column type does not support BigInt values. Use the replaceBigInts() helper function before inserting into the database. Docs: https://ponder.sh/docs/api-reference/ponder-utils#replacebigints",
137
- );
138
- }
139
-
140
- throw error;
141
- }
142
- }
143
-
144
- override mapFromDriverValue(value: T["data"] | string): T["data"] {
145
- if (typeof value === "string") {
146
- try {
147
- return JSON.parse(value);
148
- } catch {
149
- return value as T["data"];
150
- }
151
- }
152
- return value;
153
- }
154
- }