@getstrata/core 2.2.3 → 2.2.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @getstrata/core changelog
2
2
 
3
+ ## 2.2.4
4
+
5
+ - perf(database): seek Postgres composite keyset bounds
6
+
3
7
  ## 2.2.3
4
8
 
5
9
  - feat(database): add scoped composite keyset pagination
@@ -13,6 +13,13 @@ type WhereNode<TEntity extends object> = {
13
13
  } | {
14
14
  kind: "and" | "or";
15
15
  exists: ExistsClause;
16
+ } | {
17
+ kind: "and" | "or";
18
+ compareRow: {
19
+ columns: readonly string[];
20
+ operator: "lt" | "gt";
21
+ values: readonly unknown[];
22
+ };
16
23
  };
17
24
  declare class WhereBuilder<TEntity extends object, TWhere extends object = QueryWhere<TEntity>> {
18
25
  readonly nodes: WhereNode<TEntity>[];
@@ -149,6 +149,12 @@ function remapExistsSql(sql, existsParams, params) {
149
149
  return sql.replace(/\$(\d+)/g, (_match, index) => `$${offset + Number(index)}`);
150
150
  }
151
151
  function buildWhereNodeClause(tableName, node, params) {
152
+ if ("compareRow" in node) {
153
+ const { columns, operator, values } = node.compareRow;
154
+ if (!Array.isArray(columns) || !columns.length || !Array.isArray(values) || columns.length !== values.length || !["lt", "gt"].includes(operator) || Array.from(columns).some((column) => typeof column !== "string" || !column.length))
155
+ throw new TypeError("Invalid row comparison columns, values or operator.");
156
+ return `(${columns.map((column) => qualifyColumn(tableName, column)).join(", ")}) ${operator === "lt" ? "<" : ">"} (${values.map((value) => pushParam(params, value)).join(", ")})`;
157
+ }
152
158
  if ("exists" in node) {
153
159
  const body = remapExistsSql(node.exists.sql, node.exists.params, params);
154
160
  return `${node.exists.not ? "NOT " : ""}EXISTS (${body})`;
@@ -173,6 +173,12 @@ function remapExistsSql(sql, existsParams, params) {
173
173
  return sql.replace(/\$(\d+)/g, (_match, index) => `$${offset + Number(index)}`);
174
174
  }
175
175
  function buildWhereNodeClause(tableName, node, params) {
176
+ if ("compareRow" in node) {
177
+ const { columns, operator, values } = node.compareRow;
178
+ if (!Array.isArray(columns) || !columns.length || !Array.isArray(values) || columns.length !== values.length || !["lt", "gt"].includes(operator) || Array.from(columns).some((column) => typeof column !== "string" || !column.length))
179
+ throw new TypeError("Invalid row comparison columns, values or operator.");
180
+ return `(${columns.map((column) => qualifyColumn(tableName, column)).join(", ")}) ${operator === "lt" ? "<" : ">"} (${values.map((value) => pushParam(params, value)).join(", ")})`;
181
+ }
176
182
  if ("exists" in node) {
177
183
  const body = remapExistsSql(node.exists.sql, node.exists.params, params);
178
184
  return `${node.exists.not ? "NOT " : ""}EXISTS (${body})`;
package/dist/index.js CHANGED
@@ -4132,6 +4132,7 @@ init_connectionContext();
4132
4132
  init_dialect();
4133
4133
 
4134
4134
  // ../../src/core/database/keyset.ts
4135
+ init_dialect();
4135
4136
  var KEYSET_ALIAS_PREFIX = "__strata_keyset_";
4136
4137
  function validateKeyset(table, options) {
4137
4138
  if (!Number.isInteger(options.perPage) || options.perPage < 1 || options.perPage > 1000)
@@ -4159,6 +4160,18 @@ function validateKeyset(table, options) {
4159
4160
  function keysetBoundary(order, cursor) {
4160
4161
  if (!cursor)
4161
4162
  return [];
4163
+ if (currentSqlDialect().driver === "pgsql" && order.length > 1 && order.every((item) => item.direction === order[0]?.direction)) {
4164
+ return [
4165
+ {
4166
+ kind: "and",
4167
+ compareRow: {
4168
+ columns: order.map((item) => item.column),
4169
+ operator: order[0]?.direction === "asc" ? "gt" : "lt",
4170
+ values: [...cursor.values]
4171
+ }
4172
+ }
4173
+ ];
4174
+ }
4162
4175
  const branches = order.map((item, i) => {
4163
4176
  const where = {};
4164
4177
  order.slice(0, i).forEach((prefix, j) => {
@@ -4320,6 +4333,12 @@ function remapExistsSql(sql, existsParams, params) {
4320
4333
  return sql.replace(/\$(\d+)/g, (_match, index) => `$${offset + Number(index)}`);
4321
4334
  }
4322
4335
  function buildWhereNodeClause(tableName, node, params) {
4336
+ if ("compareRow" in node) {
4337
+ const { columns, operator, values } = node.compareRow;
4338
+ if (!Array.isArray(columns) || !columns.length || !Array.isArray(values) || columns.length !== values.length || !["lt", "gt"].includes(operator) || Array.from(columns).some((column) => typeof column !== "string" || !column.length))
4339
+ throw new TypeError("Invalid row comparison columns, values or operator.");
4340
+ return `(${columns.map((column) => qualifyColumn(tableName, column)).join(", ")}) ${operator === "lt" ? "<" : ">"} (${values.map((value) => pushParam(params, value)).join(", ")})`;
4341
+ }
4323
4342
  if ("exists" in node) {
4324
4343
  const body = remapExistsSql(node.exists.sql, node.exists.params, params);
4325
4344
  return `${node.exists.not ? "NOT " : ""}EXISTS (${body})`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/core",
3
- "version": "2.2.3",
3
+ "version": "2.2.4",
4
4
  "description": "Strata Bun framework public API",
5
5
  "type": "module",
6
6
  "license": "MIT",