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
JavaScript
;
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