고빈도 저장 ID를 64비트로 확장하고 랭킹 갱신의 시퀀스 낭비를 막는다
This commit is contained in:
1 parent
087517821e
commit
bc54b157c1
25 files changed
+518
-86
No files matched your search
@@ -86,3 +86,17 @@ export const parseJson = <T>(raw: string | null): T | null => {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/** Preserve numeric API cursors beyond int4 without silently rounding a bigint. */
|
||||
export const toSafeInteger = (value: bigint | number): number => {
|
||||
const result = Number(value);
|
||||
if (!Number.isSafeInteger(result)) {
|
||||
throw new RangeError('Integer exceeds the exact numeric transport range');
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const withSafeIntegerId = <Row extends { id: bigint | number }>(row: Row): Omit<Row, 'id'> & { id: number } => ({
|
||||
...row,
|
||||
id: toSafeInteger(row.id),
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { toSafeInteger, withSafeIntegerId } from '../src/util/parse.js';
|
||||
|
||||
describe('exact numeric ID transport', () => {
|
||||
it('preserves IDs above int4 through the maximum exact JS integer', () => {
|
||||
expect(toSafeInteger(2_147_483_648n)).toBe(2_147_483_648);
|
||||
expect(toSafeInteger(9_007_199_254_740_991n)).toBe(Number.MAX_SAFE_INTEGER);
|
||||
expect(withSafeIntegerId({ id: 2_147_483_648n, text: 'record' })).toEqual({
|
||||
id: 2_147_483_648,
|
||||
text: 'record',
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects silent precision loss, fractional and nonfinite IDs', () => {
|
||||
for (const value of [9_007_199_254_740_992n, 9_007_199_254_740_993n, 1.5, NaN, Infinity]) {
|
||||
expect(() => toSafeInteger(value)).toThrow(RangeError);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user