oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.21k stars 2.77k forks source link

TypeError: pool.subarray is not a function when using customAlphabet from nanoid #14094

Open Akumzy opened 1 month ago

Akumzy commented 1 month ago

What version of Bun is running?

1.1.28+cf4e9cb69

What platform is your computer?

Darwin 24.0.0 arm64 arm

What steps can reproduce the bug?

Code:

// bug.ts
export async function randomString(length: number, numbersOnly?: boolean) {
  const { customAlphabet } = await import('nanoid');
  const alphabets = numbersOnly ? '0123456789' : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  const nanoid = customAlphabet(alphabets, 10);
  return nanoid(length);
}

console.log(await randomString(10));
console.log(await randomString(10, true));

Build:

 bun build bug.ts --outfile bug.js --target bun

Run:

 bun run ./test.js

What is the expected behavior?

Something like this

➜  server git:(staging) ✗ bun run test.js
oVzv0Nnpgh
1411578744

What do you see instead?

➜  server git:(staging) ✗ bun run test.js                                 
35 |     poolOffset = 0;
36 |   }
37 |   poolOffset += bytes;
38 | }
39 | function random(bytes) {
40 |   return pool.subarray(poolOffset - bytes, poolOffset);
                           ^
TypeError: pool.subarray is not a function. (In 'pool.subarray(poolOffset - bytes, poolOffset)', 'pool.subarray' is undefined)
      at /Users/akuma/Github/server/test.js:40:23
      at /Users/akuma/Github/server/test.js:48:28
note: missing sourcemaps for /Users/akuma/Github/server/test.js
note: consider bundling with '--sourcemap' to get unminified traces

Bun v1.1.28 (macOS arm64)

Additional information

To be honest I can not remember why I was lazy loading the nanoid module but once you move the import outside the function it'll start behaving as expected

import { customAlphabet } from 'nanoid'
export async function randomString(length: number, numbersOnly?: boolean) {
  const alphabets = numbersOnly ? '0123456789' : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
  const nanoid = customAlphabet(alphabets, 10)
  return nanoid(length)
}

console.log(await randomString(10))
console.log(await randomString(10, true))
nektro commented 1 month ago

looked into this and it is specific to bun build

nanoid/index.js initializes its global variables like so

const POOL_SIZE_MULTIPLIER = 128
let pool, poolOffset

bug.js however does it like so

var POOL_SIZE_MULTIPLIER = 128,
  pool = 128,
  poolOffset = 128;

there is later a lazy check if (!pool to assign pool to a call to Buffer.allocUnsafe. since thats never true however the code continues and tries calling pool.subarray() on a number.