pglite
pglite copied to clipboard
pglite parsers "could not be cloned"
The above code throws an error however when doing the same thing except when passing the parsers next to the queries, the error does not occur. This leads me to think there is some error with pglite handling the parsers.
Code that works fine:
const res = await db.query(itemFiltersOptions.query, itemFiltersOptions.params, {
parsers: {
[types.NUMERIC]: (value: string) => {
console.log("Parsing numeric value:", value);
return new BigDecimal(value)
},
},
});
I'm not sure I understand which code throws that error?
@tdrz
this is the code that throws the error.
export class BigDecimal {
// Configuration: private constants
private static readonly DECIMALS: number = 18; // Number of decimals on all instances
private static readonly ROUNDED: boolean = true; // Numbers are truncated (false) or rounded (true)
private static readonly SHIFT: bigint = 10n ** BigInt(BigDecimal.DECIMALS); // Derived constant
private static readonly fromBigInt: unique symbol = Symbol(); // Secret to allow construction with given #n value
public static get ZERO(): BigDecimal {
return new BigDecimal(0);
}
#n: bigint; // the BigInt that holds the BigDecimal's value multiplied by SHIFT
constructor(
value: string | number | BigDecimal | bigint,
convert?: typeof BigDecimal.fromBigInt,
) {
if (value instanceof BigDecimal) {
this.#n = value.#n;
return;
}
if (convert === BigDecimal.fromBigInt) {
this.#n = BigInt(value);
return;
}
const str = String(value);
const [ints, decis = ""] = str.split(".");
const padded = decis
.padEnd(BigDecimal.DECIMALS, "0")
.slice(0, BigDecimal.DECIMALS);
const base = BigInt(ints + padded);
const roundIncrement =
// @ts-expect-error
BigDecimal.ROUNDED && decis[BigDecimal.DECIMALS] >= "5" ? 1n : 0n;
this.#n = base + roundIncrement;
}
add(num: string | number | BigDecimal): BigDecimal {
const other = new BigDecimal(num);
const sum = this.#n + other.#n;
return new BigDecimal(sum, BigDecimal.fromBigInt);
}
subtract(num: string | number | BigDecimal): BigDecimal {
const other = new BigDecimal(num);
const diff = this.#n - other.#n;
return new BigDecimal(diff, BigDecimal.fromBigInt);
}
private static divRound(dividend: bigint, divisor: bigint): BigDecimal {
const quotient = dividend / divisor;
const remainder = dividend % divisor;
const shouldRound = BigDecimal.ROUNDED && remainder * 2n >= divisor;
return new BigDecimal(
quotient + (shouldRound ? 1n : 0n),
BigDecimal.fromBigInt,
);
}
multiply(num: string | number | BigDecimal): BigDecimal {
const other = new BigDecimal(num);
const product = this.#n * other.#n;
return BigDecimal.divRound(product, BigDecimal.SHIFT);
}
divide(num: string | number | BigDecimal): BigDecimal {
const other = new BigDecimal(num);
const scaled = this.#n * BigDecimal.SHIFT;
return BigDecimal.divRound(scaled, other.#n);
}
toString(): string {
const negative = this.#n < 0n;
let s = this.#n
.toString()
.replace("-", "")
.padStart(BigDecimal.DECIMALS + 1, "0");
s = s
.slice(0, -BigDecimal.DECIMALS)
.concat(".")
.concat(s.slice(-BigDecimal.DECIMALS))
.replace(/(\.0*|0+)$/, "");
return negative ? "-" + s : s;
}
toNumber(): number {
return Number(this.toString());
}
}
const pg = await PGliteWorker.create(workerInstance, PGLITE_OPTIONS);
export const PGLITE_OPTIONS = {
relaxedDurability: true,
parsers: {
[types.NUMERIC]: (value: string) => {
console.log("Parsing numeric value:", value);
// Parse numeric as float
return new BigDecimal(value);
},
[types.DATE]: (value: string) => {
return new Date(value);
},
},
fs: indexedDbFS,
debug: 5 as DebugLevel,
extensions: {
live,
electric: electricSync({}),
},
};
when calling PGliteWorker.create, then trying to use it, it fails, but using it directly in the query, it works fine