UNPKG

fraci

Version:

Fractional indexing that's robust, performant, and secure, with first-class support for Drizzle ORM and Prisma ORM.

714 lines (705 loc) 15 kB
"use strict"; var K = Object.defineProperty; var dn = Object.getOwnPropertyDescriptor; var En = Object.getOwnPropertyNames; var mn = Object.prototype.hasOwnProperty; var hn = (n, r) => { for (var e in r) K(n, e, { get: r[e], enumerable: !0 }); }, An = (n, r, e, t) => { if (r && typeof r == "object" || typeof r == "function") for (let o of En(r)) !mn.call(n, o) && o !== e && K(n, o, { get: () => r[o], enumerable: !(t = dn(r, o)) || t.enumerable }); return n; }; var In = (n) => An(K({}, "__esModule", { value: !0 }), n); // src/index.ts var $n = {}; hn($n, { BASE10: () => xn, BASE16L: () => Fn, BASE16U: () => _n, BASE26L: () => Bn, BASE26U: () => bn, BASE36L: () => Mn, BASE36U: () => Un, BASE52: () => wn, BASE62: () => Tn, BASE64URL: () => Rn, BASE88: () => Sn, BASE95: () => Nn, DEFAULT_MAX_LENGTH: () => W, DEFAULT_MAX_RETRIES: () => z, FraciError: () => c, createFraciCache: () => Xn, fraci: () => Cn, fraciBinary: () => gn, fraciString: () => yn, getFraciErrorCode: () => Dn, isFraciError: () => Ln }); module.exports = In($n); // src/bases.ts var xn = "0123456789", Fn = "0123456789abcdef", _n = "0123456789ABCDEF", Bn = "abcdefghijklmnopqrstuvwxyz", bn = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", Mn = "0123456789abcdefghijklmnopqrstuvwxyz", Un = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", wn = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", Tn = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", Rn = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz", Sn = "!#$%()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~", Nn = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; // src/lib/errors.ts var c = class extends Error { constructor(e, t) { super(`[${e}] ${t}`); this.code = e; this.message = t; this.name = "FraciError"; } name; }; function Ln(n) { return n instanceof c; } function Dn(n) { return n instanceof c ? n.code : void 0; } // src/lib/decimal-binary.ts var k = new Uint8Array([128, 0]), On = new Uint8Array([127, 255]); function B(n, r) { let e = Math.min(n.length, r.length), t = 0; for (let o = 0; !t && o < e; o++) t = n[o] - r[o]; return t || n.length - r.length; } function A(n, r) { let e = new Uint8Array(n.length + r.length); return e.set(n), e.set(r, n.length), e; } function P(n) { let [r] = n; return r - (r >= 128 ? 127 : 128); } function J(n) { return n + (n < 0 ? 128 : 127); } function T(n) { return n.length === 129 && n.every((r) => r === 0); } function b(n) { let r = Math.abs(P(n)) + 1; if (!(Number.isNaN(r) || n.length < r)) return [n.subarray(0, r), n.subarray(r)]; } function G(n) { if (!n.length) return; let r = P(n), e = n.slice(0, Math.abs(r) + 1); for (let i = e.length - 1; i >= 1; i--) if (e[i]++ < 255) return e; if (r === -1) return k.slice(); let t = r + 1; if (t > 128) return null; let o = new Uint8Array(Math.abs(t) + 1); return o[0] = J(t), o; } function Q(n) { let r = P(n); if (Number.isNaN(r)) return; let e = n.slice(0, Math.abs(r) + 1); for (let i = e.length - 1; i >= 1; i--) if (e[i]--) return e; if (r === 1) return On.slice(); let t = r - 1; if (t < -128) return null; let o = new Uint8Array(Math.abs(t) + 1).fill(255); return o[0] = J(t), o; } function F(n, r) { if (r != null && B(n, r) >= 0) return; if (r) { let a = r.findIndex((l, s) => l !== (n[s] ?? 0)); if (a > 0) { let l = F( n.subarray(a), r.subarray(a) ); return l ? A(r.subarray(0, a), l) : void 0; } } let e = n[0] ?? 0, t = r ? r[0] : 256; if (t == null) return; if (e + 1 !== t) { let a = e + t >> 1; return new Uint8Array([a]); } if (r && r.length > 1) return new Uint8Array([r[0]]); let o = F(n.subarray(1), null); if (!o) return; let i = new Uint8Array(1 + o.length); return i[0] = e, i.set(o, 1), i; } // src/lib/decimal-string.ts function V(n, r) { return r.get(n[0]); } function M(n, r) { let e = Math.abs(V(n, r) ?? 0) + 1; if (!(e < 2 || n.length < e)) return [n.slice(0, e), n.slice(e)]; } function Y(n, r) { return r.get(1) + n[0]; } function nn(n, r) { let e = Math.min(...Array.from(r.keys())); return `${r.get(e)}${n[0].repeat(Math.abs(e))}`; } function Z(n, r, e, t, o) { let i = V(n, o); if (!i) return; let a = r[0], [l, ...s] = n.slice(0, Math.abs(i) + 1); for (let g = s.length - 1; g >= 0; g--) { let p = e.get(s[g]); if (p == null) return; if (p < r.length - 1) return s[g] = r[p + 1], `${l}${s.join("")}`; s[g] = a; } if (i === -1) return `${t.get(1)}${a}`; let u = i + 1, f = t.get(u); return f ? `${f}${a.repeat(Math.abs(u))}` : null; } function rn(n, r, e, t, o) { let i = V(n, o); if (!i) return; let a = r[r.length - 1], [l, ...s] = n.slice(0, Math.abs(i) + 1); for (let g = s.length - 1; g >= 0; g--) { let p = e.get(s[g]); if (p == null) return; if (p > 0) return s[g] = r[p - 1], `${l}${s.join("")}`; s[g] = a; } if (i === 1) return `${t.get(-1)}${a}`; let u = i - 1, f = t.get(u); return f ? `${f}${a.repeat(Math.abs(u))}` : null; } function _(n, r, e, t) { if (r != null && r <= n) return; if (r) { let a = n.padEnd(r.length, e[0]), l = Array.prototype.findIndex.call( r, (s, u) => s !== a[u] ); if (l > 0) return `${r.slice(0, l)}${_( n.slice(l), r.slice(l), e, t )}`; } let o = n ? t.get(n[0]) : 0, i = r ? t.get(r[0]) : e.length; if (!(o == null || i == null)) { if (o + 1 !== i) { let a = o + i >> 1; return e[a]; } return r && r.length > 1 ? r[0] : `${e[o]}${_( n.slice(1), null, e, t )}`; } } // src/lib/fractional-indexing-binary.ts function R(n) { return n?.constructor.name === "Buffer" ? new Uint8Array(n.buffer, n.byteOffset, n.length) : n; } function S(n) { if (!n.length || T(n)) return !1; let r = b(n); if (!r) return !1; let [, e] = r; return e?.at(-1) !== 0; } function E(n) { if (n === void 0) throw new c("INTERNAL_ERROR", "Unexpected undefined"); return n; } function U(n, r) { if (!n) { if (!r) return k.slice(); let [l, s] = E(b(r)); if (T(l)) return A( l, E(F(new Uint8Array(), s)) ); if (s.length) return l.slice(); let u = E( Q(l) ); if (!T(u)) return u; let f = new Uint8Array(u.length + 1); return f.set(u), f[u.length] = 255, f; } if (!r) { let l = E(b(n)), [s, u] = l, f = E(G(s)); return f || A(s, E(F(u, null))); } let [e, t] = E(b(n)), [o, i] = E(b(r)); if (!B(e, o)) return A( e, E(F(t, i)) ); let a = E(G(e)); return a && B(a, o) ? ( // 1. If incrementing a's integer doesn't reach b's integer, // we can use the incremented value (shorter key) a ) : ( // 2. If incrementing a's integer equals b's integer or we can't increment, // we need to use a's integer with a fractional part that sorts after a's fractional part A(e, E(F(t, null))) ); } function en(n, r) { return n != null && !S(n) || r != null && !S(r) || n != null && r != null && B(n, r) >= 0 ? void 0 : U(R(n), R(r)); } function j(n, r, e) { if (e < 1) return []; if (e === 1) return [U(n, r)]; if (r == null) { let i = n; return Array.from( { length: e }, () => i = U(i, r) ); } if (n == null) { let i = r; return Array.from( { length: e }, () => i = U(n, i) ).reverse(); } let t = e >> 1, o = U(n, r); return [ ...j(n, o, t), o, ...j(o, r, e - t - 1) ]; } function tn(n, r, e) { return n != null && !S(n) || r != null && !S(r) || n != null && r != null && B(n, r) >= 0 ? void 0 : j(R(n), R(r), e); } function H(n) { let r = []; for (; n > 0; ) r.push(n & 255), n >>= 8; return new Uint8Array(r); } // src/lib/fractional-indexing-string.ts function N(n, r, e, t, o) { if (!n || n === o) return !1; let i = M(n, t); if (!i) return !1; let [a, l] = i; if (l.endsWith(r[0])) return !1; for (let s of a.slice(1)) if (!e.has(s)) return !1; for (let s of l) if (!e.has(s)) return !1; return !0; } function m(n) { if (n === void 0) throw new c("INTERNAL_ERROR", "Unexpected undefined"); return n; } function w(n, r, e, t, o, i, a) { if (!n) { if (!r) return Y(e, o); let [y, h] = m(M(r, i)); if (y === a) return `${y}${m( _("", h, e, t) )}`; if (h) return y; let d = m( rn( y, e, t, o, i ) ); return d === a ? `${d}${e[e.length - 1]}` : d; } if (!r) { let y = m(M(n, i)), [h, d] = y, x = m( Z( h, e, t, o, i ) ); return x !== null ? x : `${h}${m( _(d, null, e, t) )}`; } let l = m(M(n, i)), s = m(M(r, i)), [u, f] = l, [g, p] = s; if (u === g) return `${u}${m( _(f, p, e, t) )}`; let I = m( Z( u, e, t, o, i ) ); return I !== null && I !== g ? ( // 1. If incrementing a's integer doesn't reach b's integer, // we can use the incremented value (shorter key) I ) : ( // 2. If incrementing a's integer equals b's integer or we can't increment, // we need to use a's integer with a fractional part that sorts after a's fractional part `${u}${m( _(f, null, e, t) )}` ); } function on(n, r, e, t, o, i, a) { return n != null && !N( n, e, t, i, a ) || r != null && !N( r, e, t, i, a ) || n != null && r != null && r <= n ? void 0 : w( n, r, e, t, o, i, a ); } function v(n, r, e, ...t) { if (e < 1) return []; if (e === 1) return [w(n, r, ...t)]; if (r == null) { let a = n; return Array.from( { length: e }, () => a = w(a, r, ...t) ); } if (n == null) { let a = r; return Array.from( { length: e }, () => a = w(n, a, ...t) ).reverse(); } let o = e >> 1, i = w(n, r, ...t); return [ ...v(n, i, o, ...t), i, ...v(i, r, e - o - 1, ...t) ]; } function an(n, r, e, t, o, i, a, l) { return n != null && !N( n, t, o, a, l ) || r != null && !N( r, t, o, a, l ) || n != null && r != null && r <= n ? void 0 : v( n, r, e, t, o, i, a, l ); } function q(n, r) { let e = r.length, t = ""; for (; n > 0; ) t += r[n % e], n = Math.floor(n / e); return t; } // src/lib/utils.ts var ln = "INITIALIZATION_FAILED"; function sn(n) { let r = n.split(""); if (r.length < 4) throw new c( ln, "Base string must have at least 4 unique characters" ); let e = -1; for (let t of r) { let o = t.charCodeAt(0); if (o <= e) throw new c( ln, "Base string characters must be unique and in ascending order" ); e = o; } return r; } function un(n) { let r = sn(n); return [r, new Map(r.map((e, t) => [e, t]))]; } function cn(n) { let r = sn(n), e = r.length >> 1, t = r.map( (o, i) => [ i < e ? ( // For characters in the first half, assign negative values starting from -1 i - e ) : ( // For characters in the second half, assign positive values starting from 1 i - e + 1 ), // This maps to 1, 2, 3, etc. (skipping 0) o ] ); return [ new Map(t), new Map(t.map(([o, i]) => [i, o])) ]; } // src/factory.ts var W = 50, z = 5, L = "INVALID_FRACTIONAL_INDEX", D = "Invalid indices provided", O = "MAX_LENGTH_EXCEEDED", X = "Exceeded maximum length", C = "MAX_RETRIES_EXCEEDED", $ = "Exceeded maximum retries"; function Xn() { return /* @__PURE__ */ new Map(); } function fn(n, r, e) { if (!n) return e(); let t = n.get(r); return t === void 0 && (t = e(), n.set(r, t)), t; } function gn({ maxLength: n = W, maxRetries: r = z } = {}) { return { base: { type: "binary" }, *generateKeyBetween(e, t, o = 0) { let i = en(e, t); if (!i) throw new c( L, D ); for (let a = 0; a < r; a++) { let l = A(i, H(a + o)); if (l.length > n) throw new c( O, X ); yield l; } throw new c( C, $ ); }, *generateNKeysBetween(e, t, o, i = 0) { let a = tn(e, t, o); if (!a) throw new c( L, D ); let l = a.reduce((s, u) => Math.max(s, u.length), 0); for (let s = 0; s < r; s++) { let u = H(s + i); if (l + u.length > n) throw new c( O, X ); yield a.map((f) => A(f, u)); } throw new c( C, $ ); } }; } function yn({ lengthBase: n, digitBase: r, maxLength: e = W, maxRetries: t = z }, o) { let [i, a] = fn( o, `L${n}`, cn.bind(null, n) ), [l, s] = fn( o, `D${r}`, un.bind(null, r) ), u = nn(l, i); return { base: { type: "string", lengthBase: n, digitBase: r }, *generateKeyBetween(f, g, p = 0) { let I = on( f, g, l, s, i, a, u ); if (!I) throw new c( L, D ); for (let y = 0; y < t; y++) { let h = `${I}${q(y + p, l)}`; if (h.length > e) throw new c( O, X ); yield h; } throw new c( C, $ ); }, *generateNKeysBetween(f, g, p, I = 0) { let y = an( f, g, p, l, s, i, a, u ); if (!y) throw new c( L, D ); let h = y.reduce((d, x) => Math.max(d, x.length), 0); for (let d = 0; d < t; d++) { let x = q(d + I, l); if (h + x.length > e) throw new c( O, X ); yield y.map((pn) => `${pn}${x}`); } throw new c( C, $ ); } }; } function Cn(n, r) { return n.type === "binary" ? gn(n) : yn(n, r); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { BASE10, BASE16L, BASE16U, BASE26L, BASE26U, BASE36L, BASE36U, BASE52, BASE62, BASE64URL, BASE88, BASE95, DEFAULT_MAX_LENGTH, DEFAULT_MAX_RETRIES, FraciError, createFraciCache, fraci, fraciBinary, fraciString, getFraciErrorCode, isFraciError }); //# sourceMappingURL=index.cjs.map