Skip to content

Conversation

bgw
Copy link

@bgw bgw commented Sep 23, 2025

This is a PR against the v0.5 branch

This is a second attempt at #200, which was reverted due to a regression in esbuild (#201).

This is an attempted fix/mitigation for vercel/next.js#82881 (comment)

Apparently esbuild requires try/catch blocks to make failing non-dynamic requires throw a runtime instead of at build time. #201

Screenshot 2025-09-23 at 4 00 08 PM

This new implementation more closely matches the pattern used on the main branch:

libsql-js/index.js

Lines 31 to 311 in 31bed66

switch (platform) {
case 'android':
switch (arch) {
case 'arm64':
localFileExisted = existsSync(join(__dirname, 'libsql.android-arm64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./libsql.android-arm64.node')
} else {
nativeBinding = require('libsql-android-arm64')
}
} catch (e) {
loadError = e
}
break
case 'arm':
localFileExisted = existsSync(join(__dirname, 'libsql.android-arm-eabi.node'))
try {
if (localFileExisted) {
nativeBinding = require('./libsql.android-arm-eabi.node')
} else {
nativeBinding = require('libsql-android-arm-eabi')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Android ${arch}`)
}
break
case 'win32':
switch (arch) {
case 'x64':
localFileExisted = existsSync(
join(__dirname, 'libsql.win32-x64-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.win32-x64-msvc.node')
} else {
nativeBinding = require('libsql-win32-x64-msvc')
}
} catch (e) {
loadError = e
}
break
case 'ia32':
localFileExisted = existsSync(
join(__dirname, 'libsql.win32-ia32-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.win32-ia32-msvc.node')
} else {
nativeBinding = require('libsql-win32-ia32-msvc')
}
} catch (e) {
loadError = e
}
break
case 'arm64':
localFileExisted = existsSync(
join(__dirname, 'libsql.win32-arm64-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.win32-arm64-msvc.node')
} else {
nativeBinding = require('libsql-win32-arm64-msvc')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Windows: ${arch}`)
}
break
case 'darwin':
localFileExisted = existsSync(join(__dirname, 'libsql.darwin-universal.node'))
try {
if (localFileExisted) {
nativeBinding = require('./libsql.darwin-universal.node')
} else {
nativeBinding = require('libsql-darwin-universal')
}
break
} catch {}
switch (arch) {
case 'x64':
localFileExisted = existsSync(join(__dirname, 'libsql.darwin-x64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./libsql.darwin-x64.node')
} else {
nativeBinding = require('libsql-darwin-x64')
}
} catch (e) {
loadError = e
}
break
case 'arm64':
localFileExisted = existsSync(
join(__dirname, 'libsql.darwin-arm64.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.darwin-arm64.node')
} else {
nativeBinding = require('libsql-darwin-arm64')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on macOS: ${arch}`)
}
break
case 'freebsd':
if (arch !== 'x64') {
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
}
localFileExisted = existsSync(join(__dirname, 'libsql.freebsd-x64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./libsql.freebsd-x64.node')
} else {
nativeBinding = require('libsql-freebsd-x64')
}
} catch (e) {
loadError = e
}
break
case 'linux':
switch (arch) {
case 'x64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-x64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-x64-musl.node')
} else {
nativeBinding = require('libsql-linux-x64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-x64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-x64-gnu.node')
} else {
nativeBinding = require('libsql-linux-x64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 'arm64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-arm64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-arm64-musl.node')
} else {
nativeBinding = require('libsql-linux-arm64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-arm64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-arm64-gnu.node')
} else {
nativeBinding = require('libsql-linux-arm64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 'arm':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-arm-musleabihf.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-arm-musleabihf.node')
} else {
nativeBinding = require('libsql-linux-arm-musleabihf')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-arm-gnueabihf.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-arm-gnueabihf.node')
} else {
nativeBinding = require('libsql-linux-arm-gnueabihf')
}
} catch (e) {
loadError = e
}
}
break
case 'riscv64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-riscv64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-riscv64-musl.node')
} else {
nativeBinding = require('libsql-linux-riscv64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-riscv64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-riscv64-gnu.node')
} else {
nativeBinding = require('libsql-linux-riscv64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 's390x':
localFileExisted = existsSync(
join(__dirname, 'libsql.linux-s390x-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./libsql.linux-s390x-gnu.node')
} else {
nativeBinding = require('libsql-linux-s390x-gnu')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Linux: ${arch}`)
}
break
default:
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
}
if (!nativeBinding) {
if (loadError) {
throw loadError
}
throw new Error(`Failed to load native binding`)
}

I tested this against the minimal repro at https://github.com/RomanHotsiy/libsql-bug-repro

I can't get the code built by esbuild that repro to run (node dist/index.js):

  • I had to modify the output format from mjs to cjs to get node to run it
  • But then I get an error because the *.node file has to be handled somehow, which the repro doesn't do

However that repro now builds cleanly (npm run build), which is all I think it's really intended to show.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant