Remove page's prev & weird reverse handling

This commit is contained in:
Zoe Roux
2025-01-09 22:34:32 +01:00
parent 371d9148f4
commit 6e293efc2b
4 changed files with 42 additions and 45 deletions
+5 -16
View File
@@ -3,7 +3,7 @@ import { eq, or, type Column, and, gt, lt } from "drizzle-orm";
type Table<Name extends string> = Record<Name, Column>;
type After = [boolean, ...[string | number | boolean | undefined]];
type After = (string | number | boolean | undefined)[];
// Create a filter (where) expression on the query to skip everything before/after the referenceID.
// The generalized expression for this in pseudocode is:
@@ -29,7 +29,7 @@ export const keysetPaginate = <
sort: Sort<T, Remap>;
}) => {
if (!after) return undefined;
const [reverse, ...cursor]: After = JSON.parse(
const cursor: After = JSON.parse(
Buffer.from(after, "base64").toString("utf-8"),
);
@@ -40,7 +40,7 @@ export const keysetPaginate = <
let where = undefined;
let previous = undefined;
for (const [i, by] of [...sort, pkSort].entries()) {
const cmp = by.desc !== reverse ? lt : gt;
const cmp = by.desc ? lt : gt;
where = or(where, and(previous, cmp(table[by.key], cursor[i])));
previous = and(previous, eq(table[by.key], cursor[i]));
}
@@ -48,18 +48,7 @@ export const keysetPaginate = <
return where;
};
export const generateAfter = (
cursor: any,
sort: Sort<any, any>,
reverse?: boolean,
) => {
const ret = [
reverse ?? false,
...sort.map((by) => cursor[by.key]),
cursor.pk,
];
export const generateAfter = (cursor: any, sort: Sort<any, any>) => {
const ret = [...sort.map((by) => cursor[by.key]), cursor.pk];
return Buffer.from(JSON.stringify(ret), "utf-8").toString("base64url");
};
const reverseStart = Buffer.from("[true,", "utf-8").toString("base64url");
export const isReverse = (x: string) => x.startsWith(reverseStart);
+4 -20
View File
@@ -1,14 +1,13 @@
import type { ObjectOptions } from "@sinclair/typebox";
import { t, type TSchema } from "elysia";
import type { Sort } from "./sort";
import { generateAfter, isReverse } from "./keyset-paginate";
import { generateAfter } from "./keyset-paginate";
export const Page = <T extends TSchema>(schema: T, options?: ObjectOptions) =>
t.Object(
{
items: t.Array(schema),
this: t.String({ format: "uri" }),
prev: t.Nullable(t.String({ format: "uri" })),
next: t.Nullable(t.String({ format: "uri" })),
},
options,
@@ -18,27 +17,12 @@ export const createPage = <T>(
items: T[],
{ url, sort, limit }: { url: string; sort: Sort<any, any>; limit: number },
) => {
let prev: string | null = null;
let next: string | null = null;
const uri = new URL(url);
const after = uri.searchParams.get("after");
const reverse = after && isReverse(after) ? 1 : 0;
const has = [
// prev
items.length > 0 && after,
// next
items.length === limit && limit > 0,
];
if (has[0 + reverse]) {
uri.searchParams.set("after", generateAfter(items[0], sort, true));
prev = uri.toString();
}
if (has[1 - reverse]) {
if (items.length === limit && limit > 0) {
const uri = new URL(url);
uri.searchParams.set("after", generateAfter(items[items.length - 1], sort));
next = uri.toString();
}
return { items, this: url, prev, next };
return { items, this: url, next };
};