get windows running
CI / Build & Test (push) Has been cancelled

This commit is contained in:
Your Name
2026-03-06 17:17:35 -08:00
parent fe8930b1fd
commit 1ccd509217
10 changed files with 125 additions and 18 deletions
View File
View File
+6
View File
@@ -0,0 +1,6 @@
stderr (last 2000 chars):
Host reported ready: false
tt-native available (no disable msg): true
PASS: false
+1
View File
@@ -7,6 +7,7 @@
"": {
"name": "holesail-browser-host",
"version": "1.0.0",
"license": "AGPL-3.0",
"dependencies": {
"assert": "npm:bare-node-assert@^1.0.0",
"b4a": "^1.6.7",
View File
+1
View File
@@ -7,6 +7,7 @@
"": {
"name": "holesail-browser",
"version": "1.0.0",
"license": "AGPL-3.0",
"devDependencies": {
"archiver": "^7.0.1",
"bare-build": "^0.4.3",
@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID6TCCAtGgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhjEcMBoGA1UEAxMTSG9s
ZXNhaWwgQnJvd3NlciBDQTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYD
VQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBIb2xlc2FpbCBCcm93c2VyMRkw
FwYDVQQLExBIb2xlc2FpbCBSb290IENBMB4XDTI2MDMwNzAxMDg1MloXDTM2MDMw
NzAxMDg1MlowgYYxHDAaBgNVBAMTE0hvbGVzYWlsIEJyb3dzZXIgQ0ExCzAJBgNV
BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcG
A1UEChMQSG9sZXNhaWwgQnJvd3NlcjEZMBcGA1UECxMQSG9sZXNhaWwgUm9vdCBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMRA66qMT8eI9ur+CmCr
3+jnlTe9pCZ9cJ4glEH9eab4VQ/6u95PBkZMWx+JsIwd1TTuXZ4UExI3ESh3bN0k
4l3H1dBV6ipvcghUajxMuVuhpjp6k9DMtE+newfcS2Rf871LSnUndu/RetGDeL1b
wBaVowYuxTyiA/l4BBWxppJ0HZ/W/1u0YBolHlnsH7ZCVngSu/JHxU5jZkHtfYL7
ePmkPhSuTj7wtNmNR2Ckaxt4lmHCprFsjuGFneG8BIqZRIgeB21kVtkeKMFSj4Ab
oR8IWFS6sPiTfEUB/7Ixs7XnfaQRKFlW0TR1e9F7scavUVeU1uGCcd8tE+wHTfct
rlECAwEAAaNgMF4wDwYDVR0TBAgwBgEB/wIBADALBgNVHQ8EBAMCAQYwHQYDVR0O
BBYEFCBY+xanOwexpYFp4lTeWwpNbO29MB8GA1UdIwQYMBaAFCBY+xanOwexpYFp
4lTeWwpNbO29MA0GCSqGSIb3DQEBCwUAA4IBAQCbMD1+7sdx4FE75Iz0jaY0ij2N
PHxfzZ/1uwIXt0xpq1ajwphvMJ+9nDZKYQKnAQsMhUTy+vU4d3muCC3GFraMWpcS
gNH0L17zpv155TqLWeUYBkXaTygBkslpNyJUsRdrevzLp6U3fRYyDedEt8civyBW
vR0Q4+V4GdWDzzYqo45umX52PK//cyExKWa5t/9QBC3qfsKZUbh5pt+TqoXQN5ph
AdcJMZ5JnDO1pKASo3odgBlfEAWG/QxqbZQ4ggjSLB4SxIlRFLLp6EIVn2VlPwPc
op5QfQy3JCrXNcOctkbwAHbOsJUuFnVJWZSZguQcbz8IKVm1TSQ9G5cHaCNu
-----END CERTIFICATE-----
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxEDrqoxPx4j26v4KYKvf6OeVN72kJn1wniCUQf15pvhVD/q7
3k8GRkxbH4mwjB3VNO5dnhQTEjcRKHds3STiXcfV0FXqKm9yCFRqPEy5W6GmOnqT
0My0T6d7B9xLZF/zvUtKdSd279F60YN4vVvAFpWjBi7FPKID+XgEFbGmknQdn9b/
W7RgGiUeWewftkJWeBK78kfFTmNmQe19gvt4+aQ+FK5OPvC02Y1HYKRrG3iWYcKm
sWyO4YWd4bwEiplEiB4HbWRW2R4owVKPgBuhHwhYVLqw+JN8RQH/sjGzted9pBEo
WVbRNHV70Xuxxq9RV5TW4YJx3y0T7AdN9y2uUQIDAQABAoIBAEGC/mhXIEaWZP56
wRIWLc98huYtiv9CPna6n2ML7zEakqKb61zBenG7CWwUtXeAeeyKaXvcbaVV9odQ
nmmP53SwwaIjG+EAhMtdCn2IixOYeXnp8y/vNX2lhb9Q/WXLVfzphjhnbR+PCPWp
coObfhrL5rioojSkTLlZI9vuCpG2VW8GZoWIJ7T316TiETnhYKy4ms1bRnjsTlcN
M8kIPfesrIUMkIKiRBrKzYbU3V14wI7dZJQzkh4bjG3VMww+smiFgkME2c+KJwJA
OWHd1vZOzN/WtzSri3Y6ftcntm+r/uLkr3IXnqAVDRVgFldXtFarlq1jDy6DLmCg
gBzqoDECgYEA6P9USl0Nn+yO+fbpiylPo+XCmVxe7XEm8x7OKXCtlHPlPhGMq9Aj
DeargOoqJa+gyG8sASiM2DneeAvsKrr2fg1GF5elkB1enYhOmABMXQTLY4p7th9v
KcizbI12lr04rGCgdigFxgMjZ1g1WCv1aFFkD55EOY388h1GUqBWCkUCgYEA16Dy
CwnsiZB7y1PiD0qOhhSG+ao2E7duJOgUnIm1gBNFjn8WYe4lEUs+Qy9Kg43G3CV3
6ZvUOvWFQM2o/ZcGjH60wIq2SGV1rP1Gb+7YZTqAshsTNvSt2g2twZ2In+7uJBcJ
dXyC8YW9uQft5kc7wcufuwvZkPaTqzNYBRH6+p0CgYAYSgXPesPg2BhPlp3iE/xp
aZpPwoFi31jgH2X+i/CMeUh8n/e6MYh1+oYGemLKavSn8G717/Q+1kmK2jNUgQkR
OvEDpJtt2qHyajNHRUCwsb9CMT2UTtKX2IRb3KNwM2mlDq2ro6B2c/1M2LU26945
ccKsniMenN6xnrumAXD2wQKBgQClyE0vpYKhxV8YVbbhUM5BUfjwbShEgmwBnhly
vQG5pZd91kIMKv9+y13kY7CjclapHXmTN0a1ydyYlUZPKlVToXsw6bT59l/CD7yf
BICFW7RkuyJLx1T+6DNmP8syQ43+W2PfW0qFjPDwGKOUv8G23upA8fxlUt736nLK
+yb+lQKBgGQDmKZwtjFtC46Y04G/lL9BeGMnu8sOahRsEsAZ5tps8cl4dPofBkcW
oHMuYENz5qBGx1DCKYfGS5mv3t6Kifye+1K1MjyM7b+JLJ6cIVS80n2RvBOK1qQY
RWJhL2HIT7+nkpRcOKlih2yxTbeToNvNLO8FBFZn/qWI8xY2yY7E
-----END RSA PRIVATE KEY-----
+67 -18
View File
@@ -146,27 +146,54 @@ module.exports = async function sign() {}
* can be called as a plain constructor function via util.inherits.
*/
function patchBundle(bundle, hosts) {
// ── Fix 1: tt-native addon ──────────────────────────────────────────────────
const ttNativeBindingKey = '/node_modules/tt-native/binding.js'
const ttNativePkgKey = '/node_modules/tt-native/package.json'
// After unmount, keys may be relative (no leading slash) or with slash depending on bare-pack.
// Resolve the actual key used in the bundle for a given path suffix.
const bundleKeys = typeof bundle.keys === 'function' ? [...bundle.keys()] : Object.keys(bundle.files || {})
function resolveKey(pathSuffix) {
const normalized = pathSuffix.replace(/^\/+/, '').replace(/\\/g, '/')
const withSlash = '/' + normalized
if (bundleKeys.includes(withSlash)) return withSlash
if (bundleKeys.includes(normalized)) return normalized
return withSlash // default to slash form for writes
}
function readKey(k) {
let b = bundle.read(k)
if (b !== null) return b
const alt = k.startsWith('/') ? k.slice(1) : '/' + k.replace(/^\/+/, '')
return bundle.read(alt)
}
if (bundle.read(ttNativeBindingKey) !== null) {
// ── Fix 1: tt-native addon ──────────────────────────────────────────────────
const ttNativeBindingKey = resolveKey('node_modules/tt-native/binding.js')
const ttNativePkgKey = resolveKey('node_modules/tt-native/package.json')
if (readKey(ttNativeBindingKey) !== null) {
// Build host-specific resolution map so the runtime picks the correct prebuild
// per platform (addon → bare → node → platform → arch). Same format as
// bare-pack/bare-module-traverse so require.addon() resolves on Linux, etc.
const addonResolutions = { addon: { bare: { node: {} } } }
for (const host of hosts) {
const prebuiltKey = `/node_modules/tt-native/prebuilds/${host}/tt-native.bare`
const diskPath = path.join(NATIVE_HOST_DIR, prebuiltKey.slice(1))
const prebuiltKey = resolveKey(`node_modules/tt-native/prebuilds/${host}/tt-native.bare`)
const diskPath = path.join(NATIVE_HOST_DIR, prebuiltKey.replace(/^\/+/, '').replace(/\//g, path.sep))
if (!fs.existsSync(diskPath)) continue
bundle.write(prebuiltKey, fs.readFileSync(diskPath), { addon: true })
const prebuildData = fs.readFileSync(diskPath)
bundle.write(prebuiltKey, prebuildData, { addon: true })
// On Windows the runtime may look up addon paths with backslashes; write the same
// addon under the backslash key so require.addon() can find it.
if (host.startsWith('win32')) {
const winKey = prebuiltKey.replace(/\//g, '\\')
if (winKey !== prebuiltKey) bundle.write(winKey, prebuildData, { addon: true })
}
const [platform, arch] = host.split('-')
if (!addonResolutions.addon.bare.node[platform]) addonResolutions.addon.bare.node[platform] = {}
addonResolutions.addon.bare.node[platform][arch] = prebuiltKey
// On Windows the runtime looks up addon paths with backslashes; store the key
// we wrote so the runtime finds the addon.
const resolutionKey = host.startsWith('win32') ? prebuiltKey.replace(/\//g, '\\') : prebuiltKey
addonResolutions.addon.bare.node[platform][arch] = resolutionKey
}
if (Object.keys(addonResolutions.addon.bare.node).length > 0) {
@@ -183,24 +210,19 @@ function patchBundle(bundle, hosts) {
// Ensure tt-native package.json has content in the bundle. On Windows the runtime
// can end up reading empty content for this key (path/bundle handling), causing
// "Unexpected end of JSON input" when the .json loader runs. Explicitly write it.
// Write to both key shapes (with and without leading slash) so the runtime finds
// it regardless of how the bundle protocol normalizes keys after unmount.
const pkgPath = path.join(NATIVE_HOST_DIR, 'node_modules', 'tt-native', 'package.json')
if (fs.existsSync(pkgPath)) {
const pkgContent = fs.readFileSync(pkgPath)
bundle.write(ttNativePkgKey, pkgContent)
bundle.write(ttNativePkgKey.slice(1), pkgContent)
bundle.write(ttNativePkgKey.startsWith('/') ? ttNativePkgKey.slice(1) : '/' + ttNativePkgKey, pkgContent)
}
console.log(' Patched tt-native binding (host-specific resolutions)')
}
}
// ── Fix 2b: bunyan runtime detection ────────────────────────────────────────
// bunyan checks process.versions.node to detect Node.js. Bare doesn't set
// this, so bunyan falls through to the browser branch and tries window.location.
// Fix: patch bunyan.js to treat Bare as a node-like environment.
const bunyanKey = '/node_modules/bunyan/lib/bunyan.js'
const bunyanSrc = bundle.read(bunyanKey)
const bunyanKey = resolveKey('node_modules/bunyan/lib/bunyan.js')
const bunyanSrc = readKey(bunyanKey)
if (bunyanSrc !== null) {
let src = bunyanSrc.toString()
// Insert a Bare-compatibility shim right before the runtimeEnv detection block.
@@ -213,9 +235,9 @@ function patchBundle(bundle, hosts) {
// ── Fix 2: node-rdpjs-2 EventEmitter compatibility ──────────────────────────
// Find the events module key in the bundle (it's the bare-node-events wrapper)
const eventsKey = '/node_modules/events/index.js'
const eventsKey = resolveKey('node_modules/events/index.js')
if (bundle.read(eventsKey) !== null) {
if (readKey(eventsKey) !== null) {
// Replace with a shim that makes EventEmitter callable as a plain function.
// util.inherits does: SuperCtor.call(this) — which fails on ES6 classes.
// The shim wraps the class in a function so both `new EventEmitter()` and
@@ -258,6 +280,33 @@ module.exports = EventEmitter;
console.log(' Patched events module for node-rdpjs-2 compatibility')
}
// ── Fix 3: Windows JSON empty-content and path normalization ──────────────────
// On Windows the runtime can request .json keys with backslashes or get empty
// content for some keys. Ensure every .json entry has valid content and add
// backslash variants for win32 so the runtime finds them.
const hasWin32 = hosts.some((h) => h.startsWith('win32'))
let jsonFixed = 0
const keysToProcess = typeof bundle.keys === 'function' ? [...bundle.keys()] : Object.keys(bundle.files || {})
for (const key of keysToProcess) {
if (!key.endsWith('.json')) continue
let content = bundle.read(key)
const isEmpty = !content || content.length === 0
const invalidJson = content && content.length > 0 && (() => { try { JSON.parse(content.toString()); return false } catch (_) { return true } })()
if (isEmpty || invalidJson) {
const diskPath = path.join(NATIVE_HOST_DIR, key.replace(/^\/+/, '').replace(/\//g, path.sep))
if (fs.existsSync(diskPath)) {
content = fs.readFileSync(diskPath)
bundle.write(key, content)
jsonFixed++
}
}
if (hasWin32 && content && content.length > 0) {
const winKey = key.replace(/\//g, '\\')
if (winKey !== key) bundle.write(winKey, content)
}
}
if (jsonFixed > 0) console.log(` Patched ${jsonFixed} empty/invalid .json entries`)
if (hasWin32 && keysToProcess.some((k) => k.endsWith('.json'))) console.log(' Added Windows backslash path variants for .json entries')
}
async function build(hosts, doPackage) {
View File