Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions crates/bindings-typescript/src/server/rng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,13 @@ export function makeRandom(seed: Timestamp): Random {
const random: Random = () => generateFloat64(rng);

random.fill = array => {
const elem = array.at(0);
if (typeof elem === 'bigint') {
if (isBigIntArray(array)) {
const upper = (1n << BigInt(array.BYTES_PER_ELEMENT * 8)) - 1n;
for (let i = 0; i < array.length; i++) {
array[i] = unsafeUniformBigIntDistribution(0n, upper, rng);
}
} else if (typeof elem === 'number') {
const upper = (1 << (array.BYTES_PER_ELEMENT * 8)) - 1;
} else {
const upper = Math.pow(2, array.BYTES_PER_ELEMENT * 8) - 1;
for (let i = 0; i < array.length; i++) {
array[i] = unsafeUniformIntDistribution(0, upper, rng);
}
Expand All @@ -111,3 +110,9 @@ export function makeRandom(seed: Timestamp): Random {

return random;
}

function isBigIntArray(
array: IntArray
): array is BigInt64Array | BigUint64Array {
return array instanceof BigInt64Array || array instanceof BigUint64Array;
}
46 changes: 46 additions & 0 deletions crates/bindings-typescript/tests/rng.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { describe, expect, test } from 'vitest';
import { Timestamp } from '../src';
import { makeRandom } from '../src/server/rng';

describe('Random', () => {
test('fill is available and returns the same typed array', () => {
const random = makeRandom(new Timestamp(1n));
const bytes = new Uint8Array(16);

expect(random.fill).toBeTypeOf('function');
expect(random.fill(bytes)).toBe(bytes);
expect(bytes.some(byte => byte !== 0)).toBe(true);
});

test('fill supports all integer typed arrays', () => {
const random = makeRandom(new Timestamp(1n));
const arrays = [
new Int8Array(8),
new Uint8Array(8),
new Uint8ClampedArray(8),
new Int16Array(8),
new Uint16Array(8),
new Int32Array(8),
new Uint32Array(8),
new BigInt64Array(8),
new BigUint64Array(8),
] as const;

for (const array of arrays) {
random.fill(array);
expect(Array.from(array).some(isNonZero)).toBe(true);
}
});

test('fill handles empty typed arrays', () => {
const random = makeRandom(new Timestamp(1n));
const bytes = new Uint8Array();

expect(random.fill(bytes)).toBe(bytes);
expect(bytes).toHaveLength(0);
});
});

function isNonZero(value: number | bigint): boolean {
return typeof value === 'bigint' ? value !== 0n : value !== 0;
}