@lokalise/prisma-utils 7.0.0 → 7.1.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/README.md CHANGED
@@ -143,6 +143,38 @@ errors, providing a robust and efficient way to ensure your transactions succeed
143
143
  By automatically retrying failed transactions with an intelligent backoff strategy, you can significantly improve the
144
144
  reliability and performance of your application when using distributed databases.
145
145
 
146
+ ### Retry On Serialization Failure
147
+
148
+ Retries a single statement while it fails with a serialization failure, without opening a transaction around it.
149
+
150
+ ```typescript
151
+ import { retryOnSerializationFailure } from '@lokalise/prisma-utils'
152
+
153
+ const rows = await retryOnSerializationFailure(() =>
154
+ prisma.$queryRaw<Row[]>`SELECT ... FROM "segment" WHERE "project_id" = ${projectId}`,
155
+ )
156
+ ```
157
+
158
+ Retries when the error is Prisma's `P2034` or a CockroachDB transaction retry error (SQLSTATE `40001`), in both the query-engine and the driver-adapter shape. Anything else is rethrown immediately, and the last error is rethrown once the retries are exhausted.
159
+
160
+ #### Options
161
+
162
+ ```typescript
163
+ const rows = await retryOnSerializationFailure(query, {
164
+ retriesAllowed: 2, // Default: 2 (total 3 attempts)
165
+ baseRetryDelayMs: 100, // Default: 100ms
166
+ maxRetryDelayMs: 30000, // Default: 30s
167
+ })
168
+ ```
169
+
170
+ The backoff is the same as `prismaTransaction`'s: `2^(retry-1) × baseRetryDelayMs`, capped at `maxRetryDelayMs`.
171
+
172
+ #### When To Use It Instead Of `prismaTransaction`
173
+
174
+ For a single read, wrapping the statement in an explicit transaction costs a BEGIN/COMMIT round trip and takes away CockroachDB's own ability to refresh and retry the implicit single-statement transaction server-side, which it can no longer do once the client has opened the transaction.
175
+
176
+ It is only safe around a **single read-only statement**. A write, or a statement that runs inside an interactive transaction, has to be retried at the transaction boundary (`prismaTransaction`) instead — replaying it alone would either duplicate its effects or re-run it against an aborted transaction.
177
+
146
178
  ### Prisma Bulk Update
147
179
 
148
180
  Updates many rows in a single atomic SQL statement (`UPDATE ... FROM (VALUES ...)`), instead of issuing one `UPDATE` per row. Because it is a single statement, it either fully applies or fully rolls back, so no surrounding transaction is required. Works on both CockroachDB and PostgreSQL.
@@ -154,10 +186,10 @@ import { prismaBulkUpdate } from '@lokalise/prisma-utils'
154
186
 
155
187
  await prismaBulkUpdate(prisma, 'segment', {
156
188
  dbDriver: 'CockroachDb',
157
- typeByColumn: { id: 'uuid', value: 'text', words_count: 'int4' },
189
+ typeByColumn: { project_id: 'uuid', id: 'uuid', value: 'text', words_count: 'int4' },
158
190
  }, [
159
- { where: { id: id1 }, data: { value: 'a', words_count: 1 } },
160
- { where: { id: id2 }, data: { value: 'b', words_count: 2 } },
191
+ { where: { project_id: projectId, id: id1 }, data: { value: 'a', words_count: 1 } },
192
+ { where: { project_id: projectId, id: id2 }, data: { value: 'b', words_count: 2 } },
161
193
  ])
162
194
  ```
163
195
 
@@ -168,9 +200,11 @@ UPDATE "segment"
168
200
  SET "value" = updates."value"::text, "words_count" = updates."words_count"::int4
169
201
  FROM (VALUES ($1::uuid, $2::text, $3::int4), ($4::uuid, $5::text, $6::int4))
170
202
  AS updates("id", "value", "words_count")
171
- WHERE "segment"."id" = updates."id"::uuid
203
+ WHERE "segment"."project_id" = $7::uuid AND "segment"."id" = updates."id"::uuid
172
204
  ```
173
205
 
206
+ `project_id` has the same value on every entry, so it is emitted as a constant predicate instead of a `VALUES` column (see "Constant `where` columns" below).
207
+
174
208
  #### Parameters
175
209
 
176
210
  - **`prisma`** — a Prisma client or a transaction client (e.g. the `tx` passed to `prismaTransaction`'s callback).
@@ -200,5 +234,6 @@ const updated = await prismaBulkUpdate<{ id: string; value: string }>(
200
234
  )
201
235
  ```
202
236
 
203
- - **Limits** — at most 1000 entries per call, and the total bound parameters (`entries × (where columns + data columns)`) must not exceed 65535 — the shared protocol limit for PostgreSQL and CockroachDB. Both are validated up front. A column may not appear in both `where` and `data`.
237
+ - **Constant `where` columns**: a `where` column whose value is the same on every entry becomes `"tbl"."col" = $n::type` instead of a `VALUES` column. With a tenant column such as `project_id` joined from `VALUES`, CockroachDB can pick a lookup join on a primary key that starts with it and read every row of the tenant; as a constant, the planner uses the index on the other key. A value counts as the same only when it is a string, number, boolean or bigint and is `===` to the first entry's value; `null`, `Date`, `Buffer` and objects stay in `VALUES`. When every `where` column is constant, `VALUES` holds only the `data` columns.
238
+ - **Limits**: at most 1000 entries per call, and the total bound parameters (`entries × (VALUES where columns + data columns) + constant where columns`) must not exceed 65535, the shared protocol limit for PostgreSQL and CockroachDB. Both are validated up front. A column may not appear in both `where` and `data`.
204
239
  - **Trusted identifiers** — `tableName`, all column names, the column types, and the `returning` keys/aliases are interpolated as raw SQL identifiers (only row values are bound). They must be static, trusted configuration, never end-user input.
@@ -9,18 +9,27 @@ import type { BulkUpdateEntry, PrismaBulkUpdateOptions } from './types.ts';
9
9
  *
10
10
  * The executed query follows the below structure for provided example data:
11
11
  * [
12
- * { where: { id: 1 }, data: { col1: 11, col2: 12 } },
13
- * { where: { id: 2 }, data: { col1: 21, col2: 22 } },
12
+ * { where: { tenant_id: 7, id: 1 }, data: { col1: 11, col2: 12 } },
13
+ * { where: { tenant_id: 7, id: 2 }, data: { col1: 21, col2: 22 } },
14
14
  * ]
15
15
  *
16
16
  * UPDATE "tbl"
17
- * SET "col1" = updates."col1", "col2" = updates."col2"
17
+ * SET "col1" = updates."col1"::int4, "col2" = updates."col2"::int4
18
18
  * FROM (
19
19
  * VALUES
20
- * (1, 11, 12),
21
- * (2, 21, 22)
20
+ * ($1::int4, $2::int4, $3::int4),
21
+ * ($4::int4, $5::int4, $6::int4)
22
22
  * ) AS updates("id", "col1", "col2")
23
- * WHERE "tbl"."id" = updates."id"
23
+ * WHERE "tbl"."tenant_id" = $7::int4 AND "tbl"."id" = updates."id"::int4
24
+ *
25
+ * A "where" column whose value is the same on every entry (`tenant_id` above) is
26
+ * emitted as a constant predicate instead of a `VALUES` column. Joining a tenant
27
+ * column from `VALUES` lets CockroachDB plan a lookup join on a primary key that
28
+ * starts with it and read every row of the tenant; a constant lets it use the
29
+ * index on the other key. A value counts as the same only when it is a string,
30
+ * number, boolean or bigint and is `===` to the first entry's value. Anything else
31
+ * (`null`, `Date`, `Buffer`, objects) stays in `VALUES`. When every "where" column
32
+ * is constant, `VALUES` holds only the "data" columns.
24
33
  *
25
34
  * "data" values follow Prisma's convention: an `undefined` value leaves the
26
35
  * column untouched (it is dropped from the statement), while `null` sets it to
@@ -1,13 +1,15 @@
1
1
  import { join, raw, sqltag as sql } from '@prisma/client/runtime/client';
2
2
  const JSON_COLUMN_TYPES = new Set(['json', 'jsonb']);
3
+ // `typeof` results for which `a === b` guarantees both bind to the same SQL value.
4
+ const COMPARABLE_VALUE_TYPES = new Set(['string', 'number', 'boolean', 'bigint']);
3
5
  const ENTRIES_LIMIT = 1000;
4
6
  /**
5
- * Every value (each "where" and each defined "data" cell) becomes one bound
6
- * placeholder in the `VALUES` list, so the statement uses
7
- * `entries × (whereColumns + dataColumns)` parameters. PostgreSQL caps a single
8
- * statement at 65535 bound parameters and CockroachDB has its own ceiling, so we
9
- * guard the total up front to fail with a clear message instead of an opaque
10
- * driver error. The effective row cap therefore shrinks as the statement widens.
7
+ * Every "data" cell and every "where" cell in the `VALUES` list is one bound
8
+ * placeholder, and each constant "where" predicate adds one more, so the
9
+ * statement uses `entries × (valuesWhereColumns + dataColumns) + constantWhereColumns`
10
+ * parameters. PostgreSQL caps a single statement at 65535 bound parameters and
11
+ * CockroachDB has its own ceiling, so we guard the total up front to fail with a
12
+ * clear message instead of an opaque driver error.
11
13
  */
12
14
  const BIND_PARAMETERS_LIMIT = 65535;
13
15
  /**
@@ -18,18 +20,27 @@ const BIND_PARAMETERS_LIMIT = 65535;
18
20
  *
19
21
  * The executed query follows the below structure for provided example data:
20
22
  * [
21
- * { where: { id: 1 }, data: { col1: 11, col2: 12 } },
22
- * { where: { id: 2 }, data: { col1: 21, col2: 22 } },
23
+ * { where: { tenant_id: 7, id: 1 }, data: { col1: 11, col2: 12 } },
24
+ * { where: { tenant_id: 7, id: 2 }, data: { col1: 21, col2: 22 } },
23
25
  * ]
24
26
  *
25
27
  * UPDATE "tbl"
26
- * SET "col1" = updates."col1", "col2" = updates."col2"
28
+ * SET "col1" = updates."col1"::int4, "col2" = updates."col2"::int4
27
29
  * FROM (
28
30
  * VALUES
29
- * (1, 11, 12),
30
- * (2, 21, 22)
31
+ * ($1::int4, $2::int4, $3::int4),
32
+ * ($4::int4, $5::int4, $6::int4)
31
33
  * ) AS updates("id", "col1", "col2")
32
- * WHERE "tbl"."id" = updates."id"
34
+ * WHERE "tbl"."tenant_id" = $7::int4 AND "tbl"."id" = updates."id"::int4
35
+ *
36
+ * A "where" column whose value is the same on every entry (`tenant_id` above) is
37
+ * emitted as a constant predicate instead of a `VALUES` column. Joining a tenant
38
+ * column from `VALUES` lets CockroachDB plan a lookup join on a primary key that
39
+ * starts with it and read every row of the tenant; a constant lets it use the
40
+ * index on the other key. A value counts as the same only when it is a string,
41
+ * number, boolean or bigint and is `===` to the first entry's value. Anything else
42
+ * (`null`, `Date`, `Buffer`, objects) stays in `VALUES`. When every "where" column
43
+ * is constant, `VALUES` holds only the "data" columns.
33
44
  *
34
45
  * "data" values follow Prisma's convention: an `undefined` value leaves the
35
46
  * column untouched (it is dropped from the statement), while `null` sets it to
@@ -88,10 +99,14 @@ export const prismaBulkUpdate = (prisma, tableName, options, entries) => {
88
99
  if (overlappingColumn) {
89
100
  throw new Error(`Column "${overlappingColumn.name}" must not appear in both "where" and "data"`);
90
101
  }
91
- const bindParametersCount = entries.length * (whereColumns.length + dataColumns.length);
102
+ const constantWhereColumns = resolveConstantWhereColumns(whereColumns, entries);
103
+ const valuesWhereColumns = whereColumns.filter((column) => !constantWhereColumns.has(column));
104
+ const valuesColumns = [...valuesWhereColumns, ...dataColumns];
105
+ const bindParametersCount = entries.length * valuesColumns.length + constantWhereColumns.size;
92
106
  if (bindParametersCount > BIND_PARAMETERS_LIMIT) {
107
+ const constantsBreakdown = constantWhereColumns.size > 0 ? ` + ${constantWhereColumns.size} constant "where" values` : '';
93
108
  throw new Error(`Bulk update would use ${bindParametersCount} bind parameters ` +
94
- `(${entries.length} entries × ${whereColumns.length + dataColumns.length} columns), ` +
109
+ `(${entries.length} entries × ${valuesColumns.length} columns${constantsBreakdown}), ` +
95
110
  `exceeding the limit of ${BIND_PARAMETERS_LIMIT}`);
96
111
  }
97
112
  // Quote each part of a (possibly schema-qualified) table name separately,
@@ -104,12 +119,15 @@ export const prismaBulkUpdate = (prisma, tableName, options, entries) => {
104
119
  const sqlSetExpressions = dataColumns.map((column) => {
105
120
  return sql([`"${column.name}" = updates."${column.name}"::${column.type}`]);
106
121
  });
107
- const sqlValuesExpressions = entries.map((entry, index) => prepareSqlValuesExpression(entry, index, whereColumns, dataColumns));
108
- const sqlValuesColumnAliases = [...whereColumns, ...dataColumns].map((column) => {
122
+ const sqlValuesExpressions = entries.map((entry, index) => prepareSqlValuesExpression(entry, index, whereColumns, valuesWhereColumns, dataColumns));
123
+ const sqlValuesColumnAliases = valuesColumns.map((column) => {
109
124
  return sql([`"${column.name}"`]);
110
125
  });
111
126
  const sqlWhereConditions = whereColumns.map((column) => {
112
- return sql([`${quotedTableName}."${column.name}" = updates."${column.name}"::${column.type}`]);
127
+ const qualifiedColumn = `${quotedTableName}."${column.name}"`;
128
+ return constantWhereColumns.has(column)
129
+ ? sql `${raw(qualifiedColumn)} = ${renderTypedValue(firstEntry.where[column.name], column.type)}`
130
+ : sql([`${qualifiedColumn} = updates."${column.name}"::${column.type}`]);
113
131
  });
114
132
  const updateStatement = sql `
115
133
  UPDATE ${sql([quotedTableName])}
@@ -128,23 +146,22 @@ export const prismaBulkUpdate = (prisma, tableName, options, entries) => {
128
146
  return prisma.$queryRaw(sql `${updateStatement} RETURNING ${join(sqlReturningExpressions, ', ')}`);
129
147
  };
130
148
  /**
131
- * Builds the parenthesized `(where..., set...)` tuple for a single entry — one
132
- * row of the `VALUES` source. The entry must supply exactly the given `where`
133
- * columns and the same set of defined `data` columns (the shape established by
134
- * the first entry); a mismatch throws so the generated `VALUES` list stays
135
- * rectangular and aligned with the column aliases.
149
+ * Builds the parenthesized `(where..., set...)` tuple for a single entry: one row
150
+ * of the `VALUES` source, holding the `valuesWhereColumns` subset of the "where"
151
+ * columns. The entry must supply exactly the given `where` columns and the same
152
+ * set of defined `data` columns (the shape established by the first entry); a
153
+ * mismatch throws so the generated `VALUES` list stays rectangular and aligned
154
+ * with the column aliases.
136
155
  */
137
- const prepareSqlValuesExpression = (entry, index, whereColumns, dataColumns) => {
156
+ const prepareSqlValuesExpression = (entry, index, whereColumns, valuesWhereColumns, dataColumns) => {
138
157
  if (whereColumns.length !== Object.keys(entry.where).length) {
139
158
  throw new Error(`Entry "where" columns are not the same (at index ${index})`);
140
159
  }
141
- const sqlWhereValues = whereColumns.map((whereConditionColumn) => {
142
- const whereConditionValue = entry.where[whereConditionColumn.name];
143
- if (whereConditionValue === undefined) {
144
- throw new Error(`Entry "where" column "${whereConditionColumn.name}" was not found (at index ${index})`);
145
- }
146
- return renderTypedValue(whereConditionValue, whereConditionColumn.type);
147
- });
160
+ const missingWhereColumn = whereColumns.find((column) => entry.where[column.name] === undefined);
161
+ if (missingWhereColumn) {
162
+ throw new Error(`Entry "where" column "${missingWhereColumn.name}" was not found (at index ${index})`);
163
+ }
164
+ const sqlWhereValues = valuesWhereColumns.map((column) => renderTypedValue(entry.where[column.name], column.type));
148
165
  if (dataColumns.length !== definedColumnNames(entry.data).length) {
149
166
  throw new Error(`Entry "data" columns are not the same (at index ${index})`);
150
167
  }
@@ -155,8 +172,17 @@ const prepareSqlValuesExpression = (entry, index, whereColumns, dataColumns) =>
155
172
  }
156
173
  return renderTypedValue(setExpressionValue, setExpressionColumn.type);
157
174
  });
158
- return sql `(${join(sqlWhereValues, ',')},${join(sqlSetValues, ',')})`;
175
+ return sql `(${join([...sqlWhereValues, ...sqlSetValues], ',')})`;
159
176
  };
177
+ /**
178
+ * Picks the "where" columns to emit as constant predicates, following the rule in
179
+ * the `prismaBulkUpdate` docblock.
180
+ */
181
+ const resolveConstantWhereColumns = (whereColumns, entries) => new Set(whereColumns.filter((column) => {
182
+ const firstValue = entries[0]?.where[column.name];
183
+ return (COMPARABLE_VALUE_TYPES.has(typeof firstValue) &&
184
+ entries.every((entry) => entry.where[column.name] === firstValue));
185
+ }));
160
186
  /**
161
187
  * Pairs each requested column name with its SQL type from `typeByColumn`,
162
188
  * throwing when a column has no type mapping (it would otherwise produce an
@@ -1 +1 @@
1
- {"version":3,"file":"prismaBulkUpdate.js","sourceRoot":"","sources":["../../src/bulk-update/prismaBulkUpdate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prismaBulkUpdate.js","sourceRoot":"","sources":["../../src/bulk-update/prismaBulkUpdate.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,11 @@ import type { PrismaClientKnownRequestError } from '@prisma/client/runtime/clien
2
2
  /**
3
3
  * Check if the error is a CockroachDB transaction retry error
4
4
  *
5
+ * Two shapes carry the SQLSTATE, depending on how the query reached the database:
6
+ * - the Rust query engine reports it flat, as `meta.code`
7
+ * - a driver adapter (e.g. `@prisma/adapter-pg`) reports a `P2010` whose SQLSTATE is nested
8
+ * under `meta.driverAdapterError.cause.originalCode`, with no `meta.code` at all
9
+ *
5
10
  * @param error
6
11
  */
7
12
  export declare const isCockroachDBRetryTransaction: (error: PrismaClientKnownRequestError) => boolean;
@@ -4,15 +4,29 @@
4
4
  * All transaction retry errors use the SQLSTATE error code 40001
5
5
  */
6
6
  const COCKROACHDB_RETRY_TRANSACTION_CODE = '40001';
7
+ const isRecord = (value) => typeof value === 'object' && value !== null;
7
8
  /**
8
9
  * Check if the error is a CockroachDB transaction retry error
9
10
  *
11
+ * Two shapes carry the SQLSTATE, depending on how the query reached the database:
12
+ * - the Rust query engine reports it flat, as `meta.code`
13
+ * - a driver adapter (e.g. `@prisma/adapter-pg`) reports a `P2010` whose SQLSTATE is nested
14
+ * under `meta.driverAdapterError.cause.originalCode`, with no `meta.code` at all
15
+ *
10
16
  * @param error
11
17
  */
12
18
  export const isCockroachDBRetryTransaction = (error) => {
13
19
  const meta = error.meta;
14
- if (!meta)
20
+ if (!isRecord(meta))
21
+ return false;
22
+ if (meta.code === COCKROACHDB_RETRY_TRANSACTION_CODE)
23
+ return true;
24
+ const driverAdapterError = meta.driverAdapterError;
25
+ if (!isRecord(driverAdapterError))
26
+ return false;
27
+ const cause = driverAdapterError.cause;
28
+ if (!isRecord(cause))
15
29
  return false;
16
- return meta.code === COCKROACHDB_RETRY_TRANSACTION_CODE;
30
+ return cause.originalCode === COCKROACHDB_RETRY_TRANSACTION_CODE;
17
31
  };
18
32
  //# sourceMappingURL=cockroachdbError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cockroachdbError.js","sourceRoot":"","sources":["../../src/errors/cockroachdbError.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,kCAAkC,GAAG,OAAO,CAAA;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,KAAoC,EAAW,EAAE;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;IACvB,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IAEvB,OAAO,IAAI,CAAC,IAAI,KAAK,kCAAkC,CAAA;AACzD,CAAC,CAAA"}
1
+ {"version":3,"file":"cockroachdbError.js","sourceRoot":"","sources":["../../src/errors/cockroachdbError.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,kCAAkC,GAAG,OAAO,CAAA;AAElD,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAA;AAE7C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,KAAoC,EAAW,EAAE;IAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;IACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAEjC,IAAI,IAAI,CAAC,IAAI,KAAK,kCAAkC;QAAE,OAAO,IAAI,CAAA;IAEjE,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAA;IAClD,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAAE,OAAO,KAAK,CAAA;IAE/C,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAA;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAElC,OAAO,KAAK,CAAC,YAAY,KAAK,kCAAkC,CAAA;AAClE,CAAC,CAAA"}
@@ -1 +1,2 @@
1
+ export * from './cockroachdbError.ts';
1
2
  export * from './prismaError.ts';
@@ -1,2 +1,3 @@
1
+ export * from './cockroachdbError.js';
1
2
  export * from './prismaError.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA"}
@@ -8,6 +8,13 @@ import type { PrismaClientKnownRequestError } from '@prisma/client/runtime/clien
8
8
  */
9
9
  export declare const isPrismaClientKnownRequestError: (error: unknown) => error is PrismaClientKnownRequestError;
10
10
  export declare const isPrismaTransactionClosedError: (error: PrismaClientKnownRequestError) => boolean;
11
+ /**
12
+ * Check if the error is a serialization failure, and therefore safe to retry.
13
+ *
14
+ * Covers both Prisma's own `P2034` and the SQLSTATE 40001 reported by CockroachDB, whose shape
15
+ * depends on whether the query went through the Rust query engine or a driver adapter.
16
+ */
17
+ export declare const isSerializationFailure: (error: unknown) => boolean;
11
18
  /**
12
19
  * Prisma error code P2025 indicates that the operation failed because it depends on one or more
13
20
  * records that were required but not found
@@ -1,4 +1,5 @@
1
1
  import { isError } from '@lokalise/node-core';
2
+ import { isCockroachDBRetryTransaction } from './cockroachdbError.js';
2
3
  /**
3
4
  * What is checked?
4
5
  * 1. error is defined and not null
@@ -13,6 +14,14 @@ export const isPrismaClientKnownRequestError = (error) => !!error &&
13
14
  error.code.startsWith('P');
14
15
  export const isPrismaTransactionClosedError = (error) => error.code === PRISMA_TRANSACTION_ERROR &&
15
16
  error.message.toLowerCase().includes('transaction already closed');
17
+ /**
18
+ * Check if the error is a serialization failure, and therefore safe to retry.
19
+ *
20
+ * Covers both Prisma's own `P2034` and the SQLSTATE 40001 reported by CockroachDB, whose shape
21
+ * depends on whether the query went through the Rust query engine or a driver adapter.
22
+ */
23
+ export const isSerializationFailure = (error) => isPrismaClientKnownRequestError(error) &&
24
+ (error.code === PRISMA_SERIALIZATION_ERROR || isCockroachDBRetryTransaction(error));
16
25
  /**
17
26
  * Prisma error code P2025 indicates that the operation failed because it depends on one or more
18
27
  * records that were required but not found
@@ -1 +1 @@
1
- {"version":3,"file":"prismaError.js","sourceRoot":"","sources":["../../src/errors/prismaError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAC7C,KAAc,EAC0B,EAAE,CAC1C,CAAC,CAAC,KAAK;IACP,OAAO,CAAC,KAAK,CAAC;IACd,MAAM,IAAI,KAAK;IACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;IAC9B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAoC,EAAW,EAAE,CAC9F,KAAK,CAAC,IAAI,KAAK,wBAAwB;IACvC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAA;AAEpE;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAA;AAE7C;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAA;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,OAAO,CAAA;AAErD;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAA;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,OAAO,CAAA"}
1
+ {"version":3,"file":"prismaError.js","sourceRoot":"","sources":["../../src/errors/prismaError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAA;AAErE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAC7C,KAAc,EAC0B,EAAE,CAC1C,CAAC,CAAC,KAAK;IACP,OAAO,CAAC,KAAK,CAAC;IACd,MAAM,IAAI,KAAK;IACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;IAC9B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAoC,EAAW,EAAE,CAC9F,KAAK,CAAC,IAAI,KAAK,wBAAwB;IACvC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAA;AAEpE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAc,EAAW,EAAE,CAChE,+BAA+B,CAAC,KAAK,CAAC;IACtC,CAAC,KAAK,CAAC,IAAI,KAAK,0BAA0B,IAAI,6BAA6B,CAAC,KAAK,CAAC,CAAC,CAAA;AAErF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAA;AAE7C;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAA;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,OAAO,CAAA;AAErD;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAA;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,OAAO,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './bulk-update/index.ts';
2
2
  export * from './errors/index.ts';
3
3
  export * from './factory/index.ts';
4
+ export * from './retry/index.ts';
4
5
  export * from './transaction/index.ts';
5
6
  export type * from './types.ts';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './bulk-update/index.js';
2
2
  export * from './errors/index.js';
3
3
  export * from './factory/index.js';
4
+ export * from './retry/index.js';
4
5
  export * from './transaction/index.js';
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const calculateRetryDelay: (retries: number, baseRetryDelayMs: number, maxDelayMs: number) => number;
@@ -0,0 +1,6 @@
1
+ export const calculateRetryDelay = (retries, baseRetryDelayMs, maxDelayMs) => {
2
+ // exponential backoff -> 2^(retry-1) * baseRetryDelayMs
3
+ const expDelay = Math.pow(2, retries - 1) * baseRetryDelayMs;
4
+ return Math.min(expDelay, maxDelayMs);
5
+ };
6
+ //# sourceMappingURL=calculateRetryDelay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculateRetryDelay.js","sourceRoot":"","sources":["../../src/retry/calculateRetryDelay.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAe,EACf,gBAAwB,EACxB,UAAkB,EACV,EAAE;IACV,wDAAwD;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,gBAAgB,CAAA;IAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;AACvC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { retryOnSerializationFailure } from './retryOnSerializationFailure.ts';
2
+ export type * from './types.ts';
@@ -0,0 +1,2 @@
1
+ export { retryOnSerializationFailure } from './retryOnSerializationFailure.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/retry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { RetryOnSerializationFailureOptions } from './types.ts';
2
+ /**
3
+ * Run a single statement, retrying it with exponential backoff while it fails with a
4
+ * serialization failure. Any other error is rethrown immediately, and the last serialization
5
+ * failure is rethrown once the retries are exhausted.
6
+ *
7
+ * Use this instead of {@link prismaTransaction} when the statement is a single read: wrapping one
8
+ * statement in an explicit transaction costs a BEGIN/COMMIT round trip and takes away
9
+ * CockroachDB's own ability to refresh and retry the implicit single-statement transaction
10
+ * server-side, which it can no longer do once the client has opened the transaction.
11
+ *
12
+ * Only safe around a single read-only statement. A write, or a statement that runs inside an
13
+ * interactive transaction, has to be retried at the transaction boundary instead - replaying it
14
+ * alone would either duplicate its effects or re-run it against an aborted transaction.
15
+ *
16
+ * @param {() => Promise<T>} query function issuing the statement, called once per attempt
17
+ * @param {RetryOnSerializationFailureOptions} options retry configuration
18
+ * @return {Promise<T>}
19
+ */
20
+ export declare const retryOnSerializationFailure: <T>(query: () => Promise<T>, options?: RetryOnSerializationFailureOptions) => Promise<T>;
@@ -0,0 +1,43 @@
1
+ import { setTimeout } from 'node:timers/promises';
2
+ import { isSerializationFailure } from '../errors/index.js';
3
+ import { calculateRetryDelay } from './calculateRetryDelay.js';
4
+ const DEFAULT_OPTIONS = {
5
+ retriesAllowed: 2, // first try + 2 retries = 3 tries
6
+ baseRetryDelayMs: 100,
7
+ maxRetryDelayMs: 30000, // 30s
8
+ };
9
+ /**
10
+ * Run a single statement, retrying it with exponential backoff while it fails with a
11
+ * serialization failure. Any other error is rethrown immediately, and the last serialization
12
+ * failure is rethrown once the retries are exhausted.
13
+ *
14
+ * Use this instead of {@link prismaTransaction} when the statement is a single read: wrapping one
15
+ * statement in an explicit transaction costs a BEGIN/COMMIT round trip and takes away
16
+ * CockroachDB's own ability to refresh and retry the implicit single-statement transaction
17
+ * server-side, which it can no longer do once the client has opened the transaction.
18
+ *
19
+ * Only safe around a single read-only statement. A write, or a statement that runs inside an
20
+ * interactive transaction, has to be retried at the transaction boundary instead - replaying it
21
+ * alone would either duplicate its effects or re-run it against an aborted transaction.
22
+ *
23
+ * @param {() => Promise<T>} query function issuing the statement, called once per attempt
24
+ * @param {RetryOnSerializationFailureOptions} options retry configuration
25
+ * @return {Promise<T>}
26
+ */
27
+ export const retryOnSerializationFailure = async (query, options) => {
28
+ // resolved per option, as spreading `options` would let an explicit `undefined` erase a default
29
+ const retriesAllowed = options?.retriesAllowed ?? DEFAULT_OPTIONS.retriesAllowed;
30
+ const baseRetryDelayMs = options?.baseRetryDelayMs ?? DEFAULT_OPTIONS.baseRetryDelayMs;
31
+ const maxRetryDelayMs = options?.maxRetryDelayMs ?? DEFAULT_OPTIONS.maxRetryDelayMs;
32
+ for (let retries = 0;; retries++) {
33
+ try {
34
+ return await query();
35
+ }
36
+ catch (error) {
37
+ if (retries >= retriesAllowed || !isSerializationFailure(error))
38
+ throw error;
39
+ await setTimeout(calculateRetryDelay(retries + 1, baseRetryDelayMs, maxRetryDelayMs));
40
+ }
41
+ }
42
+ };
43
+ //# sourceMappingURL=retryOnSerializationFailure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryOnSerializationFailure.js","sourceRoot":"","sources":["../../src/retry/retryOnSerializationFailure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAG9D,MAAM,eAAe,GAAG;IACtB,cAAc,EAAE,CAAC,EAAE,kCAAkC;IACrD,gBAAgB,EAAE,GAAG;IACrB,eAAe,EAAE,KAAK,EAAE,MAAM;CACwB,CAAA;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,EAC9C,KAAuB,EACvB,OAA4C,EAChC,EAAE;IACd,gGAAgG;IAChG,MAAM,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,eAAe,CAAC,cAAc,CAAA;IAChF,MAAM,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,IAAI,eAAe,CAAC,gBAAgB,CAAA;IACtF,MAAM,eAAe,GAAG,OAAO,EAAE,eAAe,IAAI,eAAe,CAAC,eAAe,CAAA;IAEnF,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,EAAE,CAAA;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,IAAI,cAAc,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAA;YAC5E,MAAM,UAAU,CAAC,mBAAmB,CAAC,OAAO,GAAG,CAAC,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAAA;QACvF,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export type RetryOnSerializationFailureOptions = {
2
+ retriesAllowed?: number;
3
+ baseRetryDelayMs?: number;
4
+ maxRetryDelayMs?: number;
5
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/retry/types.ts"],"names":[],"mappings":""}
@@ -2,6 +2,7 @@ import { setTimeout } from 'node:timers/promises';
2
2
  import { deepClone } from '@lokalise/node-core';
3
3
  import { isCockroachDBRetryTransaction } from '../errors/cockroachdbError.js';
4
4
  import { isPrismaClientKnownRequestError, isPrismaTransactionClosedError, PRISMA_SERIALIZATION_ERROR, PRISMA_SERVER_CLOSED_CONNECTION_ERROR, PRISMA_TRANSACTION_ERROR, } from '../errors/index.js';
5
+ import { calculateRetryDelay } from '../retry/calculateRetryDelay.js';
5
6
  const DEFAULT_OPTIONS = {
6
7
  retriesAllowed: 2, // first try + 2 retries = 3 tries
7
8
  baseRetryDelayMs: 100,
@@ -51,11 +52,6 @@ const executeTransactionTry = async (prisma, arg, options) => {
51
52
  return { error };
52
53
  }
53
54
  };
54
- const calculateRetryDelay = (retries, baseRetryDelayMs, maxDelayMs) => {
55
- // exponential backoff -> 2^(retry-1) * baseRetryDelayMs
56
- const expDelay = Math.pow(2, retries - 1) * baseRetryDelayMs;
57
- return Math.min(expDelay, maxDelayMs);
58
- };
59
55
  const PrismaCodesToRetry = [
60
56
  PRISMA_SERIALIZATION_ERROR,
61
57
  PRISMA_SERVER_CLOSED_CONNECTION_ERROR,
@@ -1 +1 @@
1
- {"version":3,"file":"prismaTransaction.js","sourceRoot":"","sources":["../../src/transaction/prismaTransaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prismaTransaction.js","sourceRoot":"","sources":["../../src/transaction/prismaTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAG/C,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAA;AAC7E,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,0BAA0B,EAC1B,qCAAqC,EACrC,wBAAwB,GACzB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAQrE,MAAM,eAAe,GAAG;IACtB,cAAc,EAAE,CAAC,EAAE,kCAAkC;IACrD,gBAAgB,EAAE,GAAG;IACrB,eAAe,EAAE,KAAK,EAAE,MAAM;IAC9B,OAAO,EAAE,IAAI,EAAE,KAAK;IACpB,UAAU,EAAE,KAAK,EAAE,MAAM;CACkB,CAAA;AAE7C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EACrC,MAAS,EACT,OAAiC,EACjC,GAAuE,EAC9B,EAAE;IAC3C,IAAI,mBAAmB,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAA;IAC5D,IAAI,MAAkD,CAAA;IAEtD,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,GAAG,CAAC;QACF,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,UAAU,CACd,mBAAmB,CACjB,OAAO,EACP,mBAAmB,CAAC,gBAAgB,EACpC,mBAAmB,CAAC,eAAe,CACpC,CACF,CAAA;QACH,CAAC;QAED,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAA;QACtE,IAAI,MAAM,CAAC,MAAM;YAAE,MAAK;QAExB,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAA;QACzE,IAAI,CAAC,YAAY;YAAE,MAAK;QAExB,IAAI,YAAY,KAAK,kBAAkB,EAAE,CAAC;YACxC,mBAAmB,GAAG,SAAS,CAAC,mBAAmB,CAAC,CAAA;YACpD,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CACpC,mBAAmB,CAAC,OAAO,GAAG,CAAC,EAC/B,mBAAmB,CAAC,UAAU,CAC/B,CAAA;QACH,CAAC;QAED,OAAO,EAAE,CAAA;IACX,CAAC,QAAQ,OAAO,IAAI,mBAAmB,CAAC,cAAc,EAAC;IAEvD,OAAO,MAAM,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAA;AAClE,CAAC,CAWA,CAAA;AAED,MAAM,qBAAqB,GAAG,KAAK,EACjC,MAAS,EACT,GAAuE,EACvE,OAAkC,EACO,EAAE;IAC3C,IAAI,CAAC;QACH,OAAO;YACL,mBAAmB;YACnB,MAAM,EAAE,MAAM,MAAM,CAAC,YAAY,CAAI,GAAG,EAAE,OAAO,CAAC;SACnD,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG;IACzB,0BAA0B;IAC1B,qCAAqC;IACrC,wBAAwB;CACzB,CAAA;AAGD,MAAM,cAAc,GAAG,CACrB,MAAsC,EACtC,QAAkB,EACI,EAAE;IACxB,IAAI,+BAA+B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;QAC1B,wEAAwE;QACxE,8GAA8G;QAC9G,IAAI,8BAA8B,CAAC,KAAK,CAAC;YAAE,OAAO,kBAAkB,CAAA;QACpE,2DAA2D;QAC3D,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACxD,8DAA8D;QAC9D,IAAI,QAAQ,KAAK,aAAa,IAAI,6BAA6B,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;IACrF,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lokalise/prisma-utils",
3
- "version": "7.0.0",
3
+ "version": "7.1.0",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "files": [
@@ -26,18 +26,18 @@
26
26
  "prisma": "^7.0.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@biomejs/biome": "^2.5.9",
30
- "dotenv": "^17.0.0",
31
- "@prisma/adapter-pg": "^7.4.0",
32
- "@prisma/client": "^7.4.0",
29
+ "@biomejs/biome": "^2.5.12",
30
+ "dotenv": "^18.0.8",
31
+ "@lokalise/biome-config": "^4.0.0",
32
+ "@lokalise/tsconfig": "^5.0.0",
33
+ "@prisma/adapter-pg": "^7.10.1",
34
+ "@prisma/client": "^7.10.0",
33
35
  "@vitest/coverage-v8": "^4.1.11",
34
36
  "cross-env": "^10.0.0",
35
37
  "prisma": "^7.10.0",
36
38
  "rimraf": "^6.1.3",
37
39
  "typescript": "7.0.2",
38
- "vitest": "^4.1.11",
39
- "@lokalise/biome-config": "^3.1.1",
40
- "@lokalise/tsconfig": "^5.0.0"
40
+ "vitest": "^4.1.11"
41
41
  },
42
42
  "scripts": {
43
43
  "build": "rimraf dist && pnpm run db:update-client && tsc --project tsconfig.build.json",
@@ -51,6 +51,8 @@
51
51
  "pretest:ci": "docker compose up -d --wait && pnpm run test:migrate",
52
52
  "test:ci": "pnpm run test",
53
53
  "posttest:ci": "docker compose down",
54
+ "bench:seed": "vitest run --config vitest.bench.config.ts",
55
+ "bench": "vitest bench --run --config vitest.bench.config.ts",
54
56
  "package-version": "echo $npm_package_version",
55
57
  "postversion": "biome check --write package.json"
56
58
  }