From 1ba98bcff24a6583d9aab4ad128953289fb47921 Mon Sep 17 00:00:00 2001 From: indrajeetor Date: Wed, 9 Sep 2026 05:24:04 -0400 Subject: [PATCH 1/3] chore: develop on Bun 1.4.2 - pin, bun-types 1.4, and a dlopen that keeps pointer returns typed as Pointer --- .bun-version | 2 +- bun.lock | 4 +-- src/main/platform/dlopen.ts | 32 +++++++++++++++++++ src/main/platform/linux/gdbus-ffi.ts | 3 +- src/main/platform/linux/gdk-ffi.ts | 3 +- src/main/platform/linux/gdk-pixbuf-ffi.ts | 3 +- src/main/platform/linux/gio-ffi.ts | 3 +- src/main/platform/linux/glib-ffi.ts | 3 +- src/main/platform/linux/gobject-ffi.ts | 3 +- src/main/platform/linux/gtk-dialog-ffi.ts | 3 +- src/main/platform/linux/gtk-ffi.ts | 3 +- src/main/platform/linux/gtk-menu-ffi.ts | 3 +- src/main/platform/linux/jsc-ffi.ts | 3 +- src/main/platform/linux/libnotify-ffi.ts | 3 +- src/main/platform/linux/libsecret-ffi.ts | 3 +- src/main/platform/linux/soup-ffi.ts | 3 +- src/main/platform/linux/webkitgtk-ffi.ts | 3 +- src/main/platform/linux/x11-ffi.ts | 3 +- src/main/platform/macos/carbon-ffi.ts | 3 +- src/main/platform/macos/cocoa-block.ts | 3 +- src/main/platform/macos/cocoa-ffi.ts | 3 +- .../platform/macos/cocoa-msgsend-variants.ts | 3 +- .../macos/cocoa-power-save-blocker.ts | 3 +- src/main/platform/macos/cocoa-run-loop.ts | 3 +- .../platform/macos/cocoa-runtime-class.ts | 3 +- src/main/platform/macos/cocoa-screen.ts | 3 +- src/main/platform/macos/cocoa-shell.ts | 3 +- .../platform/macos/cocoa-window-bounds.ts | 3 +- .../platform/macos/core-graphics-image-ffi.ts | 3 +- src/main/platform/macos/security-ffi.ts | 3 +- src/main/platform/windows/webkit2-ffi.ts | 3 +- src/main/platform/windows/win32-crypt-ffi.ts | 3 +- src/main/platform/windows/win32-dialog-ffi.ts | 3 +- src/main/platform/windows/win32-ffi.ts | 3 +- .../platform/windows/win32-gdiplus-ffi.ts | 3 +- .../platform/windows/win32-registry-ffi.ts | 3 +- src/main/platform/windows/win32-shcore-ffi.ts | 3 +- src/main/platform/windows/win32-shell-ffi.ts | 3 +- src/main/platform/windows/win32-wts-ffi.ts | 3 +- 39 files changed, 107 insertions(+), 39 deletions(-) create mode 100644 src/main/platform/dlopen.ts diff --git a/.bun-version b/.bun-version index 085c0f2..9df886c 100644 --- a/.bun-version +++ b/.bun-version @@ -1 +1 @@ -1.3.14 +1.4.2 diff --git a/bun.lock b/bun.lock index 977cb8e..925ef19 100644 --- a/bun.lock +++ b/bun.lock @@ -30,11 +30,11 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.15", "", { "os": "win32", "cpu": "x64" }, "sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ=="], - "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + "@types/bun": ["@types/bun@1.4.2", "", { "dependencies": { "bun-types": "1.4.2" } }, "sha512-GimotNn7+ZV0uVArItBbriZsR1oNf0+WTzPkdcFrzShI7k2norL0uzEaJT8T33dWr7O/c9ZDuAFQrctKCi72oQ=="], "@types/node": ["@types/node@26.0.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA=="], - "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], + "bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="], "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], diff --git a/src/main/platform/dlopen.ts b/src/main/platform/dlopen.ts new file mode 100644 index 0000000..0d7c52b --- /dev/null +++ b/src/main/platform/dlopen.ts @@ -0,0 +1,32 @@ +import { dlopen as bunDlopen, type FFIFunction, type Library, type Pointer } from 'bun:ffi'; + +/** + * `dlopen` with pointer returns typed as `Pointer | null`. bun-types 1.4 widens a + * `FFIType.ptr` return to `Pointer | bigint | null`, but the runtime hands back a + * number (probed on Bun 1.4.2: `malloc` returns `typeof "number"`), and every + * backend already treats a pointer as one. Narrowing here keeps the `bigint` + * branch out of all the call sites. `u64` returns stay `bigint`. + */ +type NarrowReturn = [R] extends [bigint] + ? R + : [Pointer] extends [Extract] + ? Exclude + : R; + +type NarrowSymbols = { + [K in keyof S]: S[K] extends (...args: infer A) => infer R + ? (...args: A) => NarrowReturn + : S[K]; +}; + +export type NarrowLibrary> = Omit< + Library, + 'symbols' +> & { + readonly symbols: NarrowSymbols['symbols']>; +}; + +export const dlopen = >( + path: string, + fns: Fns, +): NarrowLibrary => bunDlopen(path, fns) as unknown as NarrowLibrary; diff --git a/src/main/platform/linux/gdbus-ffi.ts b/src/main/platform/linux/gdbus-ffi.ts index a3d7a6a..041c142 100644 --- a/src/main/platform/linux/gdbus-ffi.ts +++ b/src/main/platform/linux/gdbus-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/gdk-ffi.ts b/src/main/platform/linux/gdk-ffi.ts index 73437f6..082c8d4 100644 --- a/src/main/platform/linux/gdk-ffi.ts +++ b/src/main/platform/linux/gdk-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/gdk-pixbuf-ffi.ts b/src/main/platform/linux/gdk-pixbuf-ffi.ts index 0b8c0e7..6cf224a 100644 --- a/src/main/platform/linux/gdk-pixbuf-ffi.ts +++ b/src/main/platform/linux/gdk-pixbuf-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/gio-ffi.ts b/src/main/platform/linux/gio-ffi.ts index 6a4018a..601b6b3 100644 --- a/src/main/platform/linux/gio-ffi.ts +++ b/src/main/platform/linux/gio-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/glib-ffi.ts b/src/main/platform/linux/glib-ffi.ts index ef5a98d..38d0ab1 100644 --- a/src/main/platform/linux/glib-ffi.ts +++ b/src/main/platform/linux/glib-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/gobject-ffi.ts b/src/main/platform/linux/gobject-ffi.ts index f9a2f5d..ab18646 100644 --- a/src/main/platform/linux/gobject-ffi.ts +++ b/src/main/platform/linux/gobject-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/gtk-dialog-ffi.ts b/src/main/platform/linux/gtk-dialog-ffi.ts index d9af440..53969ad 100644 --- a/src/main/platform/linux/gtk-dialog-ffi.ts +++ b/src/main/platform/linux/gtk-dialog-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/gtk-ffi.ts b/src/main/platform/linux/gtk-ffi.ts index 4a00b8c..8ba1b74 100644 --- a/src/main/platform/linux/gtk-ffi.ts +++ b/src/main/platform/linux/gtk-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; import { engineLibPath, prepareEngineForLoad, resolveEngine } from '../../engine/resolve'; diff --git a/src/main/platform/linux/gtk-menu-ffi.ts b/src/main/platform/linux/gtk-menu-ffi.ts index b015116..d0d3fe3 100644 --- a/src/main/platform/linux/gtk-menu-ffi.ts +++ b/src/main/platform/linux/gtk-menu-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/jsc-ffi.ts b/src/main/platform/linux/jsc-ffi.ts index d62b474..c64406f 100644 --- a/src/main/platform/linux/jsc-ffi.ts +++ b/src/main/platform/linux/jsc-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/libnotify-ffi.ts b/src/main/platform/linux/libnotify-ffi.ts index 35850d3..270556a 100644 --- a/src/main/platform/linux/libnotify-ffi.ts +++ b/src/main/platform/linux/libnotify-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/linux/libsecret-ffi.ts b/src/main/platform/linux/libsecret-ffi.ts index 249eaff..dec2cb9 100644 --- a/src/main/platform/linux/libsecret-ffi.ts +++ b/src/main/platform/linux/libsecret-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType, type Pointer } from 'bun:ffi'; +import { FFIType, type Pointer } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; import { cstr } from '../cstr'; diff --git a/src/main/platform/linux/soup-ffi.ts b/src/main/platform/linux/soup-ffi.ts index fb23384..d13ee6e 100644 --- a/src/main/platform/linux/soup-ffi.ts +++ b/src/main/platform/linux/soup-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; import { engineLibPath, prepareEngineForLoad, resolveEngine } from '../../engine/resolve'; diff --git a/src/main/platform/linux/webkitgtk-ffi.ts b/src/main/platform/linux/webkitgtk-ffi.ts index d76200f..dae1b9d 100644 --- a/src/main/platform/linux/webkitgtk-ffi.ts +++ b/src/main/platform/linux/webkitgtk-ffi.ts @@ -1,4 +1,5 @@ -import { CString, dlopen, FFIType, type Pointer } from 'bun:ffi'; +import { CString, FFIType, type Pointer } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; import { engineLibPath, prepareEngineForLoad, resolveEngine } from '../../engine/resolve'; diff --git a/src/main/platform/linux/x11-ffi.ts b/src/main/platform/linux/x11-ffi.ts index 5c4c9cd..ee3cb88 100644 --- a/src/main/platform/linux/x11-ffi.ts +++ b/src/main/platform/linux/x11-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; diff --git a/src/main/platform/macos/carbon-ffi.ts b/src/main/platform/macos/carbon-ffi.ts index 3e9d94e..167faa6 100644 --- a/src/main/platform/macos/carbon-ffi.ts +++ b/src/main/platform/macos/carbon-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { macOSLibraryAccessor } from './objc'; /** diff --git a/src/main/platform/macos/cocoa-block.ts b/src/main/platform/macos/cocoa-block.ts index 4447757..370ebb4 100644 --- a/src/main/platform/macos/cocoa-block.ts +++ b/src/main/platform/macos/cocoa-block.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType, JSCallback, type Pointer, ptr } from 'bun:ffi'; +import { FFIType, JSCallback, type Pointer, ptr } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { cstr } from '../cstr'; import type { Handle } from './objc'; diff --git a/src/main/platform/macos/cocoa-ffi.ts b/src/main/platform/macos/cocoa-ffi.ts index 7763c18..b22c378 100644 --- a/src/main/platform/macos/cocoa-ffi.ts +++ b/src/main/platform/macos/cocoa-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; import { LIBOBJC_PATH } from './objc'; diff --git a/src/main/platform/macos/cocoa-msgsend-variants.ts b/src/main/platform/macos/cocoa-msgsend-variants.ts index e00826f..2726a76 100644 --- a/src/main/platform/macos/cocoa-msgsend-variants.ts +++ b/src/main/platform/macos/cocoa-msgsend-variants.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { cstr } from '../cstr'; import { type Handle, LIBOBJC_PATH, macOSLibraryAccessor } from './objc'; diff --git a/src/main/platform/macos/cocoa-power-save-blocker.ts b/src/main/platform/macos/cocoa-power-save-blocker.ts index dc4dc4c..e5df537 100644 --- a/src/main/platform/macos/cocoa-power-save-blocker.ts +++ b/src/main/platform/macos/cocoa-power-save-blocker.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType, ptr } from 'bun:ffi'; +import { FFIType, ptr } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import type { NativeBlocker, PowerSaveBlockerBackend, diff --git a/src/main/platform/macos/cocoa-run-loop.ts b/src/main/platform/macos/cocoa-run-loop.ts index 42ab057..a18d23a 100644 --- a/src/main/platform/macos/cocoa-run-loop.ts +++ b/src/main/platform/macos/cocoa-run-loop.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { cstr } from '../cstr'; import { bigIntOut, LIBOBJC_PATH, macOSLibraryAccessor, ptrIn } from './objc'; diff --git a/src/main/platform/macos/cocoa-runtime-class.ts b/src/main/platform/macos/cocoa-runtime-class.ts index 084f437..4a25138 100644 --- a/src/main/platform/macos/cocoa-runtime-class.ts +++ b/src/main/platform/macos/cocoa-runtime-class.ts @@ -1,5 +1,6 @@ import { BunmaskaError } from '../../../common/errors'; -import { dlopen, FFIType, JSCallback } from 'bun:ffi'; +import { FFIType, JSCallback } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { cstr } from '../cstr'; import { cocoa } from './cocoa-runtime'; import { type Handle, LIBOBJC_PATH, macOSLibraryAccessor } from './objc'; diff --git a/src/main/platform/macos/cocoa-screen.ts b/src/main/platform/macos/cocoa-screen.ts index 1eab5d6..0adee22 100644 --- a/src/main/platform/macos/cocoa-screen.ts +++ b/src/main/platform/macos/cocoa-screen.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType, ptr } from 'bun:ffi'; +import { FFIType, ptr } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { UnsupportedPlatformError } from '../../../common/errors'; import { currentPlatform } from '../../../common/platform'; import type { Point, RawDisplay, ScreenBackend } from '../../api/screen'; diff --git a/src/main/platform/macos/cocoa-shell.ts b/src/main/platform/macos/cocoa-shell.ts index 818e9b6..86b06c2 100644 --- a/src/main/platform/macos/cocoa-shell.ts +++ b/src/main/platform/macos/cocoa-shell.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { nsString } from './cocoa-foundation'; import { msgSendPtr, msgSendPtrReturnsU8 } from './cocoa-msgsend-variants'; import { cocoa } from './cocoa-runtime'; diff --git a/src/main/platform/macos/cocoa-window-bounds.ts b/src/main/platform/macos/cocoa-window-bounds.ts index d816ef4..448f00d 100644 --- a/src/main/platform/macos/cocoa-window-bounds.ts +++ b/src/main/platform/macos/cocoa-window-bounds.ts @@ -6,7 +6,8 @@ * exactly Electron's `getBounds` contract, so no coordinate flip on reads. */ -import { dlopen, FFIType, ptr } from 'bun:ffi'; +import { FFIType, ptr } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import type { Rect } from '../native'; import { nsString } from './cocoa-foundation'; import { msgSendI64, msgSendPtr, msgSendReturnsI64 } from './cocoa-msgsend-variants'; diff --git a/src/main/platform/macos/core-graphics-image-ffi.ts b/src/main/platform/macos/core-graphics-image-ffi.ts index 6b6ab73..454f9bd 100644 --- a/src/main/platform/macos/core-graphics-image-ffi.ts +++ b/src/main/platform/macos/core-graphics-image-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { macOSLibraryAccessor } from './objc'; /** diff --git a/src/main/platform/macos/security-ffi.ts b/src/main/platform/macos/security-ffi.ts index a50b5e4..49bda13 100644 --- a/src/main/platform/macos/security-ffi.ts +++ b/src/main/platform/macos/security-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType, read } from 'bun:ffi'; +import { FFIType, read } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { cstr } from '../cstr'; import { macOSLibraryAccessor } from './objc'; diff --git a/src/main/platform/windows/webkit2-ffi.ts b/src/main/platform/windows/webkit2-ffi.ts index ca0e25a..a3c7995 100644 --- a/src/main/platform/windows/webkit2-ffi.ts +++ b/src/main/platform/windows/webkit2-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType, ptr } from 'bun:ffi'; +import { FFIType, ptr } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { existsSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { FFIError } from '../../../common/errors'; diff --git a/src/main/platform/windows/win32-crypt-ffi.ts b/src/main/platform/windows/win32-crypt-ffi.ts index e5a594b..b9eb397 100644 --- a/src/main/platform/windows/win32-crypt-ffi.ts +++ b/src/main/platform/windows/win32-crypt-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-dialog-ffi.ts b/src/main/platform/windows/win32-dialog-ffi.ts index 9db25d7..614f1e5 100644 --- a/src/main/platform/windows/win32-dialog-ffi.ts +++ b/src/main/platform/windows/win32-dialog-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-ffi.ts b/src/main/platform/windows/win32-ffi.ts index 763d6f5..1f3c6f9 100644 --- a/src/main/platform/windows/win32-ffi.ts +++ b/src/main/platform/windows/win32-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-gdiplus-ffi.ts b/src/main/platform/windows/win32-gdiplus-ffi.ts index 86b9b46..6ad0be2 100644 --- a/src/main/platform/windows/win32-gdiplus-ffi.ts +++ b/src/main/platform/windows/win32-gdiplus-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-registry-ffi.ts b/src/main/platform/windows/win32-registry-ffi.ts index cec9153..e1d47cd 100644 --- a/src/main/platform/windows/win32-registry-ffi.ts +++ b/src/main/platform/windows/win32-registry-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-shcore-ffi.ts b/src/main/platform/windows/win32-shcore-ffi.ts index 708c9a2..66e3ab7 100644 --- a/src/main/platform/windows/win32-shcore-ffi.ts +++ b/src/main/platform/windows/win32-shcore-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-shell-ffi.ts b/src/main/platform/windows/win32-shell-ffi.ts index 21d2c42..3fbdc90 100644 --- a/src/main/platform/windows/win32-shell-ffi.ts +++ b/src/main/platform/windows/win32-shell-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** diff --git a/src/main/platform/windows/win32-wts-ffi.ts b/src/main/platform/windows/win32-wts-ffi.ts index 235a885..1c17ecb 100644 --- a/src/main/platform/windows/win32-wts-ffi.ts +++ b/src/main/platform/windows/win32-wts-ffi.ts @@ -1,4 +1,5 @@ -import { dlopen, FFIType } from 'bun:ffi'; +import { FFIType } from 'bun:ffi'; +import { dlopen } from '../dlopen'; import { winLibraryAccessor } from './win32'; /** From d9025996b641bc6b41d59546ff9071efe209e23b Mon Sep 17 00:00:00 2001 From: indrajeetor Date: Wed, 9 Sep 2026 05:24:04 -0400 Subject: [PATCH 2/3] fix: the renderer build defines NODE_ENV per command so packaged apps ship production React --- src/cli/index.ts | 4 ++-- src/cli/renderer-build.ts | 23 +++++++++++++++-------- tests/unit/cli/renderer-build.test.ts | 11 ++++++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/cli/index.ts b/src/cli/index.ts index 9c82ea0..a72aef4 100755 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -257,7 +257,7 @@ const runBuild = async ( let rendererDir: string | undefined; const rendererConfig = config.renderer; if (rendererConfig !== undefined) { - const rendererResult = await buildRenderer(process.cwd(), rendererConfig); + const rendererResult = await buildRenderer(process.cwd(), rendererConfig, 'production'); rendererDir = rendererResult.outDir; out(`renderer built (${rendererResult.written.join(', ')})`); } @@ -432,7 +432,7 @@ const runDevCommand = async (command: Extract): Promis const rebuild = async (): Promise => { // A broken renderer edit must never take the dev loop down with it. try { - const result = await buildRenderer(dir, rendererConfig); + const result = await buildRenderer(dir, rendererConfig, 'development'); log(`renderer rebuilt (${result.written.join(', ')})`); } catch (error) { err(error instanceof Error ? error.message : String(error)); diff --git a/src/cli/renderer-build.ts b/src/cli/renderer-build.ts index f49e53c..0ece842 100644 --- a/src/cli/renderer-build.ts +++ b/src/cli/renderer-build.ts @@ -1,9 +1,9 @@ /** * The renderer build Bunmaska owns (`config.renderer`). One recipe, deliberately: * a classic IIFE bundle, because `loadFile` serves `file://` where an ES module - * fails the CORS null-origin check, built with `NODE_ENV=development` because - * Bun's bundler emits `jsxDEV` regardless of tsconfig and the production React - * runtime stubs it out. See .admin/RENDERER-BUILD.md for the derivation. + * fails the CORS null-origin check. `NODE_ENV` is defined per mode: `bunmaska dev` + * builds the development React runtime (warnings, jsxDEV), `bunmaska build` the + * production one. See .admin/RENDERER-BUILD.md for the derivation. */ import { cpSync, existsSync, mkdirSync } from 'node:fs'; @@ -20,17 +20,23 @@ export type RendererBuildResult = { readonly written: readonly string[]; }; +export type RendererMode = 'development' | 'production'; + /** The bundler seam: builds `entry` into `outDir`, returns written file names. */ -export type RendererBundler = (entry: string, outDir: string) => Promise; +export type RendererBundler = ( + entry: string, + outDir: string, + mode: RendererMode, +) => Promise; -const defaultBundler: RendererBundler = async (entry, outDir) => { +const defaultBundler: RendererBundler = async (entry, outDir, mode) => { const result = await Bun.build({ entrypoints: [entry], outdir: outDir, target: 'browser', format: 'iife', - // Dev React: Bun transpiles JSX to jsxDEV; the prod runtime stubs it out. - define: { 'process.env.NODE_ENV': JSON.stringify('development') }, + // The define picks the JSX runtime too: development emits jsxDEV, production jsx. + define: { 'process.env.NODE_ENV': JSON.stringify(mode) }, naming: '[dir]/[name].[ext]', }); if (!result.success) { @@ -48,6 +54,7 @@ const defaultBundler: RendererBundler = async (entry, outDir) => { export const buildRenderer = async ( projectDir: string, renderer: BunmaskaRendererConfig, + mode: RendererMode = 'production', bundler: RendererBundler = defaultBundler, ): Promise => { const entry = resolve(projectDir, renderer.entry); @@ -56,7 +63,7 @@ export const buildRenderer = async ( } const outDir = resolve(projectDir, rendererOutDir(renderer)); mkdirSync(outDir, { recursive: true }); - const written = [...(await bundler(entry, outDir))]; + const written = [...(await bundler(entry, outDir, mode))]; for (const relPath of renderer.copy ?? []) { const from = resolve(projectDir, relPath); if (!existsSync(from)) { diff --git a/tests/unit/cli/renderer-build.test.ts b/tests/unit/cli/renderer-build.test.ts index aba4bc1..c9d127e 100644 --- a/tests/unit/cli/renderer-build.test.ts +++ b/tests/unit/cli/renderer-build.test.ts @@ -21,7 +21,7 @@ describe('rendererOutDir', () => { }); describe('buildRenderer', () => { - test('bundles the entry as a classic IIFE with dev NODE_ENV', async () => { + test('bundles the entry as a classic IIFE', async () => { const dir = makeProject(); const result = await buildRenderer(dir, { entry: 'src/renderer/main.ts' }); expect(result.written).toContain('main.js'); @@ -31,6 +31,15 @@ describe('buildRenderer', () => { expect(bundle).not.toMatch(/^import /m); }); + test('defines NODE_ENV from the mode: production by default, development for dev', async () => { + const dir = makeProject(); + writeFileSync(join(dir, 'src', 'renderer', 'main.ts'), 'console.log(process.env.NODE_ENV);\n'); + const prod = await buildRenderer(dir, { entry: 'src/renderer/main.ts' }); + expect(readFileSync(join(prod.outDir, 'main.js'), 'utf8')).toContain('"production"'); + const dev = await buildRenderer(dir, { entry: 'src/renderer/main.ts' }, 'development'); + expect(readFileSync(join(dev.outDir, 'main.js'), 'utf8')).toContain('"development"'); + }); + test('copies the configured static files into the output', async () => { const dir = makeProject(); const result = await buildRenderer(dir, { From 0a569c538dc200c69a37ed5ed940ad1063fa9301 Mon Sep 17 00:00:00 2001 From: indrajeetor Date: Wed, 9 Sep 2026 05:24:05 -0400 Subject: [PATCH 3/3] docs: renderer NODE_ENV per command, Bun 1.4.2 in the changelog --- website/src/content/docs/building.md | 2 +- website/src/content/docs/changelog.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/website/src/content/docs/building.md b/website/src/content/docs/building.md index 3f2054b..55f36d5 100644 --- a/website/src/content/docs/building.md +++ b/website/src/content/docs/building.md @@ -96,7 +96,7 @@ With that block in place: Two deliberate choices, both forced by how a desktop renderer actually loads. If you bring your own bundler instead, you will need the same two settings: - **A classic IIFE bundle, not ES modules.** `loadFile` serves your page over `file://`, and browsers treat `file://` as a null origin - a `