chore(vendor): import pi 1.3.0

Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
2026-10-15 17:58:48 -04:00
parent 719370c8f7
commit 6081e3e325
1743 changed files with 205460 additions and 131705 deletions

View File

@@ -0,0 +1,40 @@
import { StorageRequestError } from "../errors.ts";
import type { Id, ScanOrder } from "../types.ts";
/** Where a built-in storage scan starts: its order and the last ID a previous page returned. */
export type ScanStart = {
readonly order: ScanOrder;
readonly after: number | undefined;
};
/**
* Resolve a scan's order and position. A cursor continues in the order it was created with, whether the query repeats
* that order or omits it; a different `order` throws. A cursor without an order, written before scans had one,
* continues in the scan's default order.
*/
export function scanStart(
requested: ScanOrder | undefined,
cursor: Readonly<Record<string, unknown>> | undefined,
fallback: ScanOrder,
): ScanStart {
if (requested !== undefined && requested !== "ascending" && requested !== "descending") {
throw new StorageRequestError(`Invalid scan order: ${String(requested)}`);
}
if (cursor === undefined) return { order: requested ?? fallback, after: undefined };
const { after, order: stored } = cursor;
if (typeof after !== "number" || !Number.isSafeInteger(after))
throw new StorageRequestError("Invalid storage cursor");
if (stored !== undefined && stored !== "ascending" && stored !== "descending") {
throw new StorageRequestError("Invalid storage cursor");
}
const order = stored ?? fallback;
if (requested !== undefined && requested !== order) {
throw new StorageRequestError(`The cursor continues a ${order} scan; the query asks for ${requested}`);
}
return { order, after };
}
/** The continuation of a scan whose last returned item has `id`. */
export function nextCursor(id: Id<string>, order: ScanOrder): { readonly after: number; readonly order: ScanOrder } {
return { after: id, order };
}