gachore/src/lib/slug.ts

40 lines
1 KiB
TypeScript
Raw Normal View History

2025-05-15 07:42:32 -05:00
import Sqids from "sqids";
export type Slug = string & { readonly __tag: unique symbol };
export class Slugs {
private static instance: Slugs;
private sqids!: Sqids;
private constructor() {
if (Slugs.instance) return Slugs.instance;
Slugs.instance = this;
this.sqids = new Sqids({
alphabet: "dbnixSPYJNy5hvsqCWIHwEKTFutV6r4Xa32okL8RQUj7Am9DcpgfZezMBG",
});
}
static encode(num: number | bigint): Slug {
const sqids = new Slugs().sqids;
const thirtyTwoBitMax = BigInt(0xffffffff);
if (typeof num === "bigint" && num > thirtyTwoBitMax) {
const arr = [];
while (num > 0) {
arr.push(Number(num & thirtyTwoBitMax));
num >>= 32n;
}
return sqids.encode(arr) as Slug;
} else {
return sqids.encode([Number(num)]) as Slug;
}
}
static decode(slug: Slug): number | bigint {
const ns = new Slugs().sqids.decode(slug);
if (ns.length === 1) return ns[0];
return ns.reduceRight((big, each) => (big << 32n) + BigInt(each), 0n);
}
}